source: MondoRescue/tags/3.2.2/mondo/src/mondoarchive/mondoarchive.c@ 3789

Last change on this file since 3789 was 3789, checked in by Bruno Cornec, 21 months ago

More fixes for global vars which should not be initialized when declared with extern

  • Property svn:keywords set to Id
File size: 13.1 KB
Line 
1/***************************************************************************
2$Id: mondoarchive.c 3789 2022-08-24 19:17:43Z bruno $
3* The main file for mondoarchive.
4*/
5
6/************************* #include statements *************************/
7#include <pthread.h>
8#include <stdio.h>
9#include <stdlib.h>
10#include "my-stuff.h"
11#include "mr_mem.h"
12#include "mr_str.h"
13#include "mr_msg.h"
14#include "../common/mondostructures.h"
15#include "../common/libmondo.h"
16#include "../common/libmondo-cli-EXT.h"
17#include "../common/libmondo-tools-EXT.h"
18#include "mondoarchive.h"
19
20// for CVS
21//static char cvsid[] = "$Id: mondoarchive.c 3789 2022-08-24 19:17:43Z bruno $";
22
23/************************* external variables *************************/
24extern void set_signals(int);
25extern int g_current_media_number;
26extern int g_currentY;
27extern bool g_text_mode;
28extern char *g_boot_mountpt;
29extern bool g_remount_floppy_at_end;
30extern char *g_cdrw_drive_is_here;
31static char *g_cdrom_drive_is_here = NULL;
32static char *g_dvd_drive_is_here = NULL;
33extern double g_kernel_version;
34
35/***************** global vars, used only by main.c ******************/
36long diffs = 0L;
37
38extern t_bkptype g_backup_media_type;
39extern int g_loglevel;
40
41extern char *g_magicdev_command;
42
43/**
44 * Whether we're restoring from ISOs. Obviously not, since this is the
45 * backup program.
46 * @note You @b MUST declare this variable somewhere in your program if
47 * you use libmondo. Otherwise the link will fail.
48 * @ingroup globalGroup
49 */
50bool g_ISO_restore_mode = FALSE;
51
52/* Whether we should fail immediately at first error */
53bool g_fail_immediately = FALSE;
54
55/* Do we use extended attributes and acl ?
56 * * By default no, use --acl & --attr options to force their usage */
57char *g_getfacl = NULL;
58char *g_getfattr = NULL;
59char *g_mondo_home = NULL;
60
61/* Reference to global bkpinfo */
62struct s_bkpinfo *bkpinfo;
63
64/* No cleanup for the moment */
65void (*mr_cleanup)(void) = NULL;
66
67/* To be coded */
68void free_MR_global_filenames(void) {
69}
70
71/****************** subroutines used only by main.c ******************/
72
73
74/**
75 * Print a "don't panic" message to the log and a message about the logfile to the screen.
76 */
77void welcome_to_mondoarchive(void)
78{
79 char *tmp = NULL;
80
81 log_msg(0, "Mondo Archive v%s --- http://www.mondorescue.org", PACKAGE_VERSION);
82 log_msg(0, "running %s binaries", get_architecture());
83 tmp = get_uname_m();
84 log_msg(0, "running on %s architecture", tmp);
85 mr_free(tmp);
86 log_msg(0, "-----------------------------------------------------------");
87 log_msg(0, "NB: Mondo logs almost everything, so don't panic if you see");
88 log_msg(0, "some error messages. Please read them carefully before you");
89 log_msg(0, "decide to break out in a cold sweat. Despite (or perhaps");
90 log_msg(0, "because of) the wealth of messages. some users are inclined");
91 log_msg(0, "to stop reading this log. If Mondo stopped for some reason,");
92 log_msg(0, "chances are it's detailed here. More than likely there's a");
93 log_msg(0, "message at the very end of this log that will tell you what");
94 log_msg(0, "is wrong. Please read it! -Devteam");
95 log_msg(0, "-----------------------------------------------------------");
96
97 log_msg(0, "Zero...");
98 log_msg(1, "One...");
99 log_msg(2, "Two...");
100 log_msg(3, "Three...");
101 log_msg(4, "Four...");
102 log_msg(5, "Five...");
103 log_msg(6, "Six...");
104 log_msg(7, "Seven...");
105 log_msg(8, "Eight...");
106 printf("See %s for details of backup run.\n", MONDO_LOGFILE);
107}
108
109
110/**
111 * Do whatever is necessary to insure a successful backup on the Linux distribution
112 * of the day.
113 */
114void distro_specific_kludges_at_start_of_mondoarchive(void)
115{
116 log_msg(2, "Unmounting old ramdisks if necessary");
117 stop_magicdev_if_necessary(); // for RH+Gnome users
118 /*
119 run_program_and_log_output
120 ("umount `mount | grep shm | grep mondo | cut -d' ' -f3`", 2);
121 */
122 unmount_supermounts_if_necessary(); // for Mandrake users whose CD-ROMs are supermounted
123 // stop_autofs_if_necessary(); // for Xandros users
124 mount_boot_if_necessary(); // for Gentoo users with non-mounted /boot partitions
125 clean_up_KDE_desktop_if_necessary(); // delete various misc ~/.* files that get in the way
126}
127
128
129
130/**
131 * Undo whatever was done by distro_specific_kludges_at_start_of_mondoarchive().
132 */
133void distro_specific_kludges_at_end_of_mondoarchive(void)
134{
135 log_msg(2, "Restarting magicdev if necessary");
136 sync();
137 restart_magicdev_if_necessary(); // for RH+Gnome users
138
139 log_msg(2, "Restarting autofs if necessary");
140 sync();
141 // restart_autofs_if_necessary(); // for Xandros users
142
143 log_msg(2, "Restarting supermounts if necessary");
144 sync();
145 remount_supermounts_if_necessary(); // for Mandrake users
146
147 log_msg(2, "Unmounting /boot if necessary");
148 sync();
149 unmount_boot_if_necessary(); // for Gentoo users
150
151// log_msg( 2, "Cleaning up KDE desktop");
152// clean_up_KDE_desktop_if_necessary();
153}
154
155
156/**
157 * Backup/verify the user's data.
158 * What did you think it did, anyway? :-)
159 */
160int main(int argc, char *argv[])
161{
162 char *tmp = NULL;
163 char *tmp1 = NULL;
164 int res = 0;
165 int retval = 0;
166 char *say_at_end = NULL;
167 FILE *fin = NULL;
168
169 /* If -V, -v or --version then echo version no. and quit */
170 if (argc == 2 && (!strcmp(argv[argc - 1], "-v") || !strcmp(argv[argc - 1], "-V") || !strcmp(argv[argc - 1], "--version"))) {
171 printf("mondoarchive v%s\nSee man page for help\n", PACKAGE_VERSION);
172 if (getuid() != 0) fprintf(stderr, "Please run the mondoarchive command as root.\n");
173 exit(0);
174 }
175
176 /* Make sure I'm root; abort if not */
177 if (getuid() != 0) {
178 fprintf(stderr, "Please run as root.\n");
179 exit(127);
180 }
181
182 /* initialize log file with time stamp */
183 unlink(MONDO_LOGFILE);
184 log_msg(0, "Time started: %s", mr_date());
185
186 /* Initialize variables */
187 if (!(bkpinfo = (struct s_bkpinfo *)malloc(sizeof(struct s_bkpinfo)))) {
188 fprintf(stderr, "Cannot malloc bkpinfo\n");
189 exit(-1);
190 }
191 /* Now on we can use finish to exit as bkpingo has been initialized */
192 log_msg(9, "reset_bkpinfo");
193 reset_bkpinfo();
194
195 /* Memory allocation is done in those functions */
196 malloc_libmondo_global_strings();
197
198 /* make sure PATH environmental variable allows access to mkfs, fdisk, etc. */
199 mr_asprintf(tmp1,"%s:/sbin:/usr/sbin:/usr/local/sbin",getenv("PATH"));
200 setenv("PATH", tmp1, 1);
201 mr_free(tmp1);
202
203 /* Add the ARCH environment variable for ia64 purposes */
204 mr_asprintf(tmp1,"%s",get_architecture());
205 setenv("ARCH", tmp1, 1);
206 mr_free(tmp1);
207
208 /* Add MONDO_SHARE environment variable for mindi */
209 setenv_mondo_share();
210
211 /* Configure the bkpinfo structure, global file paths, etc. */
212 g_main_pid = getpid();
213 log_msg(9, "This");
214
215 set_signals(TRUE); // catch SIGTERM, etc.
216 run_program_and_log_output("dmesg -n1", TRUE);
217
218 log_msg(9, "Next");
219 make_hole_for_dir(MONDO_CACHE);
220
221 welcome_to_mondoarchive();
222 distro_specific_kludges_at_start_of_mondoarchive();
223 g_kernel_version = get_kernel_version();
224
225 if (argc == 4 && !strcmp(argv[1], "getfattr")) {
226 g_loglevel = 10;
227 setup_newt_stuff();
228 if (!strstr(argv[2], "filelist")) {
229 printf("Sorry - filelist goes first\n");
230 finish(1);
231 } else {
232 finish(get_fattr_list(argv[2], argv[3]));
233 }
234 finish(0);
235 }
236 if (argc == 4 && !strcmp(argv[1], "setfattr")) {
237 g_loglevel = 10;
238 setup_newt_stuff();
239 finish(set_fattr_list(argv[2], argv[3]));
240 }
241
242 if (argc == 3 && !strcmp(argv[1], "wildcards")) {
243 g_loglevel = 10;
244 setup_newt_stuff();
245 tmp1 = mr_stresc(argv[2], "[]*?", '\\', '\'');
246 printf("in=%s; out=%s\n", argv[2], tmp1);
247 mr_free(tmp1);
248 finish(1);
249 }
250
251 if (argc == 4 && !strcmp(argv[1], "getfacl")) {
252 g_loglevel = 10;
253 setup_newt_stuff();
254 if (!strstr(argv[2], "filelist")) {
255 printf("Sorry - filelist goes first\n");
256 finish(1);
257 } else {
258 finish(get_acl_list(argv[2], argv[3]));
259 }
260 finish(0);
261 }
262 if (argc == 4 && !strcmp(argv[1], "setfacl")) {
263 g_loglevel = 10;
264 setup_newt_stuff();
265 finish(set_acl_list(argv[2], argv[3]));
266 }
267 if (argc >= 2 && !strcmp(argv[1], "mkraidtab")) {
268 g_loglevel = 10;
269 setup_newt_stuff();
270#undef MDSTAT_FILE
271#define MDSTAT_FILE "/tmp/mdstat"
272 if (!(fin = fopen(MDSTAT_FILE, "r"))) {
273 log_msg(1, "Could not open %s.", MDSTAT_FILE);
274 finish(1);
275 }
276
277 create_raidtab_from_mdstat(MDSTAT_FILE,"/tmp/raidtab");
278 finish(0);
279 }
280
281 if (argc > 2 && !strcmp(argv[1], "find-cd")) {
282 g_loglevel = 10;
283 setup_newt_stuff();
284 malloc_string(tmp);
285 if (find_cdrw_device(tmp)) {
286 printf("Failed to find CDR-RW drive\n");
287 } else {
288 printf("CD-RW is at %s\n", tmp);
289 }
290 tmp[0] = '\0';
291 if (find_cdrom_device(tmp, atoi(argv[2]))) {
292 printf("Failed to find CD-ROM drive\n");
293 } else {
294 printf("CD-ROM is at %s\n", tmp);
295 }
296 mr_free(tmp);
297 finish(0);
298 }
299
300 if (argc > 2 && !strcmp(argv[1], "find-dvd")) {
301 g_loglevel = 10;
302 setup_newt_stuff();
303 malloc_string(tmp);
304 if (find_dvd_device(tmp, atoi(argv[2]))) {
305 printf("Failed to find DVD drive\n");
306 } else {
307 printf("DVD is at %s\n", tmp);
308 }
309 mr_free(tmp);
310 finish(0);
311 }
312
313 if (argc > 2 && !strcmp(argv[1], "disksize")) {
314 printf("%s --> %ld\n", argv[2], get_phys_size_of_drive(argv[2]));
315 finish(0);
316 }
317 if (argc > 2 && !strcmp(argv[1], "test-dev")) {
318 if (is_dev_an_NTFS_dev(argv[2])) {
319 printf("%s is indeed an NTFS dev\n", argv[2]);
320 } else {
321 printf("%s is _not_ an NTFS dev\n", argv[2]);
322 }
323 finish(0);
324 }
325
326 /* setup log level for new log system as well */
327 mr_msg_init(MONDO_LOGFILE,g_loglevel);
328
329 if (pre_param_configuration()) {
330 fatal_error("Pre-param initialization phase failed. Please review the error messages above, make the specified changes, then try again. Exiting...");
331 }
332
333 /* Process command line, if there is one. If not, ask user for info. */
334 if (argc == 1) {
335 g_text_mode = FALSE;
336 setup_newt_stuff();
337 res = interactively_obtain_media_parameters_from_user(TRUE); /* yes, archiving */
338 if (res) {
339 fatal_error("Syntax error. Please review the parameters you have supplied and try again.");
340 }
341 } else {
342 res = handle_incoming_parameters(argc, argv);
343 if (res) {
344 printf("Errors were detected in the command line you supplied.\n");
345 printf("Please review the log file - %s\n", MONDO_LOGFILE );
346 log_msg(1, "Mondoarchive will now exit.");
347 finish(1);
348 }
349 setup_newt_stuff();
350 }
351
352 /* Finish configuring global structures */
353 if (post_param_configuration()) {
354 fatal_error("Post-param initialization phase failed. Perhaps bad parameters were supplied to mondoarchive? Please review the documentation, error messages and logs. Exiting...");
355 }
356
357 /* If we're meant to backup then backup */
358 if (bkpinfo->backup_data) {
359 res = backup_data();
360 retval += res;
361 if (res) {
362 mr_asprintf(say_at_end, "Data archived. Please check the logs, just as a precaution. ");
363 } else {
364 mr_asprintf(say_at_end, "Data archived OK. ");
365 }
366 }
367
368/* If we're meant to verify then verify */
369 if (bkpinfo->verify_data) {
370 res = verify_data();
371 if (res < 0) {
372 mr_asprintf(tmp, "%d difference%c found.", -res, (-res != 1) ? 's' : ' ');
373 mr_asprintf(say_at_end, "%s", tmp);
374 log_to_screen(tmp);
375 mr_free(tmp);
376 res = 0;
377 }
378 retval += res;
379 }
380
381/* Report result of entire operation (success? errors?) */
382 if (!retval) {
383 mvaddstr_and_log_it(g_currentY++, 0, "Backup and/or verify ran to completion. Everything appears to be fine.");
384 } else {
385 mvaddstr_and_log_it(g_currentY++, 0, "Backup and/or verify ran to completion. However, errors did occur.");
386 }
387
388 if (does_file_exist(MINDI_CACHE"/mindi.iso")) {
389 log_to_screen(MINDI_CACHE"/mindi.iso, a boot/utility CD, is available if you want it.");
390 }
391
392 if (length_of_file(MONDO_CACHE"/changed.files") > 2) {
393 if (g_text_mode) {
394 log_to_screen("Type 'less "MONDO_CACHE"/changed.files' to see which files don't match the archives");
395 } else {
396 log_msg(1, "Type 'less "MONDO_CACHE"/changed.files' to see which files don't match the archives");
397 log_msg(2, "Calling popup_changelist_from_file()");
398 popup_changelist_from_file(MONDO_CACHE"/changed.files");
399 log_msg(2, "Returned from popup_changelist_from_file()");
400 }
401 } else {
402 unlink(MONDO_CACHE"/changed.files");
403 }
404 if (say_at_end != NULL) {
405 log_to_screen(say_at_end);
406 mr_free(say_at_end);
407 }
408 mr_asprintf(tmp, "umount %s/tmpfs", bkpinfo->tmpdir);
409 run_program_and_log_output(tmp, TRUE);
410 mr_free(tmp);
411 if (bkpinfo->backup_media_type == usb) {
412 log_msg(1, "Unmounting USB device.");
413 if (bkpinfo->media_device == NULL) {
414 fatal_error("USB device set to NULL");
415 }
416 mr_asprintf(tmp, "umount %s1", bkpinfo->media_device);
417 run_program_and_log_output(tmp, TRUE);
418 mr_free(tmp);
419 }
420
421 run_program_and_log_output("mount", 2);
422
423 paranoid_system("rm -f "MONDO_CACHE"/last-backup.aborted");
424 if (!retval) {
425 printf("Mondoarchive ran OK.\n");
426 } else {
427 printf("Errors occurred during backup. Please check logfile.\n");
428 }
429 distro_specific_kludges_at_end_of_mondoarchive();
430 set_signals(FALSE);
431
432 free_libmondo_global_strings();
433
434
435 if (!g_cdrom_drive_is_here) {
436 log_msg(10, "FYI, g_cdrom_drive_is_here was never used");
437 }
438 if (!g_dvd_drive_is_here) {
439 log_msg(10, "FYI, g_dvd_drive_is_here was never used");
440 }
441
442 /* finalize log file with time stamp */
443 log_msg(0, "Time finished: %s", mr_date());
444
445 if (chdir("/tmp")) {
446 // FIXME
447 }
448
449 if (!g_text_mode) {
450 popup_and_OK("Mondo Archive has finished its run. Please press ENTER to return to the shell prompt.");
451 log_to_screen("See %s for details of backup run.", MONDO_LOGFILE);
452 } else {
453 printf("See %s for details of backup run.\n", MONDO_LOGFILE);
454 }
455 mr_msg_close();
456 finish(retval);
457
458 return EXIT_SUCCESS;
459}
Note: See TracBrowser for help on using the repository browser.