1 /*
2    Copyright (c) 1991-1999 Thomas T. Wetmore IV
3 
4    Permission is hereby granted, free of charge, to any person
5    obtaining a copy of this software and associated documentation
6    files (the "Software"), to deal in the Software without
7    restriction, including without limitation the rights to use, copy,
8    modify, merge, publish, distribute, sublicense, and/or sell copies
9    of the Software, and to permit persons to whom the Software is
10    furnished to do so, subject to the following conditions:
11 
12    The above copyright notice and this permission notice shall be
13    included in all copies or substantial portions of the Software.
14 
15    THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
16    EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
17    MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
18    NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
19    BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
20    ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
21    CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
22    SOFTWARE.
23 */
24 /* modified 05 Jan 2000 by Paul B. McBride (pmcbride@tiac.net) */
25 /*=================================================================
26  * btedit.c -- Command that allows individual BTREE records to be
27  *   edited directly.  Can only be used on records that are in pure
28  *   ASCII format.
29  * Copyright(c) 1991-94 by T.T. Wetmore IV; all rights reserved
30  *   3.0.2 - 10 Dec 94
31  *===============================================================*/
32 
33 #include "llstdlib.h"
34 /* llstdlib.h pulls in standard.h, config.h, sys_inc.h */
35 #include "btree.h"
36 #include "version.h"
37 
38 /*********************************************
39  * required global variables
40  *********************************************/
41 /* defined in liflines/main.c */
42 STRING readpath_file = NULL;
43 STRING readpath = NULL;
44 int opt_finnish = 0;
45 int opt_mychar = 0;
46 /* defined in gedlib/codesets.c */
47 BOOLEAN uu8=0;            /* flag if internal codeset is UTF-8 */
48 STRING int_codeset=0;     /* internal codeset */
49 
50 /*********************************************
51  * local function prototypes
52  *********************************************/
53 
54 /* alphabetical */
55 static int llsystem(const char * cmd);
56 static void print_usage(void);
57 
58 /*********************************************
59  * local function definitions
60  * body of module
61  *********************************************/
62 
63 /*=========================================
64  * main -- Main procedure of btedit command
65  *=======================================*/
66 int
main(int argc,char ** argv)67 main (int argc,
68       char **argv)
69 {
70 	BTREE btree;
71 	char cmdbuf[512];
72 	char *editor;
73 	char *dbname, *key;
74 	RECORD_STATUS recstat;
75 	BOOLEAN cflag=FALSE; /* create new db if not found */
76 	BOOLEAN writ=1; /* request write access to database */
77 	BOOLEAN immut=FALSE; /* immutable access to database */
78 	INT lldberrnum=0;
79 	int rtn=0;
80 	int i=0;
81 
82 	/* TODO: needs locale & gettext initialization */
83 
84 #ifdef WIN32
85 	/* TO DO - research if this is necessary */
86 	_fmode = O_BINARY;	/* default to binary rather than TEXT mode */
87 #endif
88 
89 	/* handle conventional arguments --version and --help */
90 	/* needed for help2man to synthesize manual pages */
91 	for (i=1; i<argc; ++i) {
92 		if (!strcmp(argv[i], "--version")
93 			|| !strcmp(argv[i], "-v")) {
94 			print_version("btedit");
95 			return 0;
96 		}
97 		if (!strcmp(argv[i], "--help")
98 			|| !strcmp(argv[i], "-h")
99 			|| !strcmp(argv[i], "-?")) {
100 			print_usage();
101 			return 0;
102 		}
103 	}
104 
105 	/* Parse Command-Line Arguments */
106 	if (argc != 3) {
107 		printf(_("btedit requires 2 arguments (btree and key)."));
108 		puts("");
109 		printf(_("See `btedit --help' for more information."));
110 		puts("");
111 		return 10;
112 	}
113 	dbname = argv[1];
114 	key = argv[2];
115 	if (!(btree = bt_openbtree(dbname, cflag, writ, immut, &lldberrnum))) {
116 		printf(_("Failed to open btree: %s."), dbname);
117 		puts("");
118 		return 20;
119 	}
120 	recstat = write_record_to_file(btree, str2rkey(key), "btedit.tmp");
121 	if (recstat != RECORD_SUCCESS) {
122 		if (recstat == RECORD_NOT_FOUND)
123 			printf(_("There is no record with key: %s"), key);
124 		else
125 			printf(_("Error accessing record: %s"), key);
126 		puts("");
127 		rtn = 30;
128 		goto finish;
129 	}
130 
131 	editor = environ_determine_editor(PROGRAM_BTEDIT);
132 	sprintf(cmdbuf, "%s btedit.tmp", editor);
133 	if (llsystem(cmdbuf) != 0) {
134 		printf(_("Editor or system call failed."));
135 		puts("");
136 		printf(_("Database was not be modified."));
137 		puts("");
138 		rtn = 40;
139 		goto finish;
140 	}
141 	if (!bwrite(btree)) {
142 		printf(_("Readonly database can not be modified."));
143 		puts("");
144 		rtn = 50;
145 		goto finish;
146 	}
147 
148 	if (!addfile(btree, str2rkey(key), "btedit.tmp")) {
149 		printf(_("Error writing file 'btedit.tmp'."));
150 		puts("");
151 		rtn = 60;
152 		goto finish;
153 	}
154 	unlink("btedit.tmp");
155 	printf(_("Record %s modified."), key);
156 	puts("");
157 	rtn = 0;
158 
159 finish:
160 	closebtree(btree);
161 	btree = 0;
162 	return rtn;
163 }
164 /*=============================
165  * llsystem -- wrapper for system call
166  *  (handles Win32 version as well)
167  * return value of 0 is assumed successful
168  *===========================*/
169 static int
llsystem(const char * cmd)170 llsystem (const char * cmd)
171 {
172 	int rtn=-1;
173 #ifdef WIN32
174         /* use w32system, because it will wait for the editor to finish */
175         rtn = w32system(cmd);
176 #else
177         rtn = system(cmd);
178 #endif
179 	return rtn;
180 }
181 /*=============================
182  * __fatal -- Fatal error routine
183  *  handles null or empty details input
184  *===========================*/
185 void
__fatal(STRING file,int line,CNSTRING details)186 __fatal (STRING file, int line, CNSTRING details)
187 {
188 	printf("FATAL ERROR: ");
189 	if (details && details[0]) {
190 		printf(details);
191 		printf("\nAT: ");
192 	}
193 	printf("%s: line %d\n", file, line);
194 	exit(1);
195 }
196 /*===============================================
197  * print_usage -- display program help/usage
198  *  displays to stdout
199  *=============================================*/
200 void
print_usage(void)201 print_usage (void)
202 {
203 #ifdef WIN32
204 	char * fname = _("\"\\My Documents\\LifeLines\\Databases\\MyFamily\"");
205 #else
206 	char * fname = _("/home/users/myname/lifelines/databases/myfamily");
207 #endif
208 
209 	printf(_("lifelines `btedit' edits raw binary btree blocks\n"
210 		"in lifelines database files. Do NOT use this unless\n"
211 		"you know what you are doing and you have backed up\n"
212 		"your database."));
213 	printf("\n\n");
214 	printf(_("Usage btedit [database] [rkey]"));
215 	printf("\n\n");
216 	printf(_("Options:"));
217 	printf("\n");
218 	printf(_("\t--help\tdisplay this help and exit"));
219 	printf("\n");
220 	printf(_("\t--version\toutput version information and exit"));
221 	printf("\n\n");
222 	printf(_("Examples:"));
223 	printf("\n");
224 	printf(_("\tbtedit %s I34"), fname);
225 	printf("\n\t\t");
226 	printf(_("edit raw btree block for person I34"));
227 	printf("\n\n");
228 	printf(_("Report bugs to https://github.com/MarcNo/lifelines/issues"));
229 	printf("\n");
230 }
231