source: MondoRescue/branches/stable/mondo/src/mondoarchive/main.c@ 928

Last change on this file since 928 was 928, checked in by Bruno Cornec, 17 years ago

ps (busybox) and ps (system) do not give PID in the same column. Adapted with a global variable.

  • Property svn:keywords set to Id
File size: 16.6 KB
Line 
1/***************************************************************************
2 main.c - description
3 -------------------
4 begin : Fri Apr 19 16:40:35 EDT 2002
5 copyright : (C) 2002 by Stan Benoit
6 email : troff@nakedsoul.org
7 cvsid : $Id: main.c 928 2006-11-13 09:17:07Z bruno $
8 ***************************************************************************/
9
10/***************************************************************************
11 * *
12 * This program is free software; you can redistribute it and/or modify *
13 * it under the terms of the GNU General Public License as published by *
14 * the Free Software Foundation; either version 2 of the License, or *
15 * (at your option) any later version. *
16 * *
17 ***************************************************************************/
18
19/** change log ****** MONDO-DEVEL
20
21
2212/10
23- disable stopping/starting of autofs
24
2510/01
26- update g_erase_tmpdir_and_scratchdir to delete user-specified tmpdir, scratchdir
27
2806/19
29- added AUX_VER
30
3106/14/2004
32- use mondorescue.iso, not mindi.iso
33
3402/10/2004
35- tell users where BusyBox's sources are
36
3711/14/2003
38- cleaned up logging at end#
39
4010/23
41- don't try to test-read tape ... That's already
42 handled by post_param_configuration()
43
4410/19
45- if your PATH var is too long, abort
46
4709/23
48- added some comments
49- malloc/free global strings in new subroutines - malloc_libmondo_global_strings()
50 and free_libmondo_global_strings() - which are in libmondo-tools.c
51- better magicdev support
52
53
5409/16
55- delete /var/log/partimagehack-debug.log at start of main()
56
5709/15
58- added askbootloader
59
6009/09
61- if your tape is weird, I'll pause between backup and verify
62- fixed silly bug in main() - re: say_at_end
63
6401/01 - 08/31
65- call 'dmesg -n1' at start, to shut the kernel logger up
66- moved g_erase_tmpdir_and_scratchdir to common/newt-specific.c
67- added 'don't panic' msg to start of logfile
68- added 'nice(20)' to main()
69- added lots of assert()'s and log_OS_error()'s
70- clean-up (Hugo)
71- make post_param_configuration() setup g_erase_tmpdir_and_scratchdir
72- if --version then print & exit quickly
73- re-run g_erase_tmpdir_and_scratchdir via system() at very end
74
75Year: 2002
76- if user goes root with 'su' instead of 'su -' then
77 workaround it by setting PATH correctly
78- wipe mondoarchive.log at very beginning
79- cleaned up code
80- if changed.files.N exists then copy to changes.files for display
81- run_program_and_log_output() now takes boolean operator to specify
82 whether it will log its activities in the event of _success_
83- added popup list of changed files
84- removed 'beta-quality' warnings
85- if kernel not found and mondo in graphics mode then popup and ask
86 for kernel path+filename
87- fixed tmp[] 'too small' bug
88- unmount and eject CD at end of verify cycle
89- moved interactively_obtain...() to libmondo-stream.c
90- wrote stuff to autodetect tape+cdrw+etc.
91- renamed from main.c to mondo-archive.c
92- fore+after warnings that this code is beta-quality
93- abort if running from ramdisk
94- remount floppy at end & unmount at start if Mandrake
95- took out #debug stuff
96- add 2> /dev/null to 'find' command
97- add support for bkpinfo->nonbootable_backup
98- add main function begin comment and debug conditional
99 compilation - Stan Benoit
100- add debug statements to build a run tree. Stan Benoit
101**** end change log **********/
102
103
104/**
105 * @file
106 * The main file for mondoarchive.
107 */
108
109/************************* #include statements *************************/
110#include <pthread.h>
111//#include <config.h>
112//#include "../../config.h"
113#include <stdio.h>
114#include <stdlib.h>
115#include "../common/my-stuff.h"
116#include "../common/mondostructures.h"
117#include "../common/libmondo.h"
118#include "mondo-cli-EXT.h"
119
120// for CVS
121//static char cvsid[] = "$Id: main.c 928 2006-11-13 09:17:07Z bruno $";
122
123/************************* external variables *************************/
124extern void set_signals(int);
125extern int g_current_media_number;
126extern void register_pid(pid_t, char *);
127extern int g_currentY;
128extern bool g_text_mode;
129extern char *g_boot_mountpt;
130extern bool g_remount_cdrom_at_end, g_remount_floppy_at_end;
131extern char *g_mondo_home;
132extern char *g_tmpfs_mountpt;
133extern char *g_erase_tmpdir_and_scratchdir;
134extern char *g_cdrw_drive_is_here;
135static char *g_cdrom_drive_is_here = NULL;
136static char *g_dvd_drive_is_here = NULL;
137extern double g_kernel_version;
138
139/***************** global vars, used only by main.c ******************/
140bool g_skip_floppies;
141long diffs;
142char *ps_options = "auxww";
143char *ps_proc_id = "$2";
144
145extern t_bkptype g_backup_media_type;
146extern int g_loglevel;
147
148/****************** subroutines used only by main.c ******************/
149
150
151/**
152 * Print a "don't panic" message to the log and a message about the logfile to the screen.
153 */
154void welcome_to_mondoarchive()
155{
156 log_msg(0, "Mondo Archive v%s --- http://www.mondorescue.org",
157 PACKAGE_VERSION);
158 log_msg(0, "running on %s architecture", get_architecture());
159 log_msg(0,
160 "-----------------------------------------------------------");
161 log_msg(0,
162 "NB: Mondo logs almost everything, so don't panic if you see");
163 log_msg(0,
164 "some error messages. Please read them carefully before you");
165 log_msg(0,
166 "decide to break out in a cold sweat. Despite (or perhaps");
167 log_msg(0,
168 "because of) the wealth of messages. some users are inclined");
169 log_msg(0,
170 "to stop reading this log. If Mondo stopped for some reason,");
171 log_msg(0,
172 "chances are it's detailed here. More than likely there's a");
173 log_msg(0,
174 "message at the very end of this log that will tell you what");
175 log_msg(0,
176 "is wrong. Please read it! -Devteam");
177 log_msg(0,
178 "-----------------------------------------------------------");
179
180 log_msg(0, "Zero...");
181 log_msg(1, "One...");
182 log_msg(2, "Two...");
183 log_msg(3, "Three...");
184 log_msg(4, "Four...");
185 log_msg(5, "Five...");
186 log_msg(6, "Six...");
187 log_msg(7, "Seven...");
188 log_msg(8, "Eight...");
189 printf("See %s for details of backup run.\n", MONDO_LOGFILE);
190}
191
192
193extern char *g_magicdev_command;
194
195/**
196 * Do whatever is necessary to insure a successful backup on the Linux distribution
197 * of the day.
198 */
199void distro_specific_kludges_at_start_of_mondoarchive()
200{
201 log_msg(2, "Unmounting old ramdisks if necessary");
202 stop_magicdev_if_necessary(); // for RH+Gnome users
203 run_program_and_log_output
204 ("umount `mount | grep shm | grep mondo | cut -d' ' -f3`", 2);
205 unmount_supermounts_if_necessary(); // for Mandrake users whose CD-ROMs are supermounted
206 // stop_autofs_if_necessary(); // for Xandros users
207 mount_boot_if_necessary(); // for Gentoo users with non-mounted /boot partitions
208 clean_up_KDE_desktop_if_necessary(); // delete various misc ~/.* files that get in the way
209}
210
211
212
213/**
214 * Undo whatever was done by distro_specific_kludges_at_start_of_mondoarchive().
215 */
216void distro_specific_kludges_at_end_of_mondoarchive()
217{
218// char tmp[500];
219 log_msg(2, "Restarting magicdev if necessary");
220 sync();
221 restart_magicdev_if_necessary(); // for RH+Gnome users
222
223 log_msg(2, "Restarting autofs if necessary");
224 sync();
225 // restart_autofs_if_necessary(); // for Xandros users
226
227 log_msg(2, "Restarting supermounts if necessary");
228 sync();
229 remount_supermounts_if_necessary(); // for Mandrake users
230
231 log_msg(2, "Unmounting /boot if necessary");
232 sync();
233 unmount_boot_if_necessary(); // for Gentoo users
234
235// log_msg( 2, "Cleaning up KDE desktop");
236// clean_up_KDE_desktop_if_necessary();
237}
238
239/* Return a string containing the date */
240char *mr_date(void) {
241
242 time_t tcurr;
243
244 tcurr = time(NULL);
245 return(ctime(&tcurr));
246}
247
248/*-----------------------------------------------------------*/
249
250
251
252/**
253 * Backup/verify the user's data.
254 * What did you think it did, anyway? :-)
255 */
256int main(int argc, char *argv[])
257{
258 struct s_bkpinfo *bkpinfo;
259 char *tmp;
260 int res, retval;
261 char *say_at_end;
262
263/* Make sure I'm root; abort if not */
264 if (getuid() != 0) {
265 fprintf(stderr, "Please run as root.\r\n");
266 exit(127);
267 }
268
269/* If -V, -v or --version then echo version no. and quit */
270 if (argc == 2
271 && (!strcmp(argv[argc - 1], "-v") || !strcmp(argv[argc - 1], "-V")
272 || !strcmp(argv[argc - 1], "--version"))) {
273 printf("mondoarchive v%s\nSee man page for help\n", PACKAGE_VERSION);
274 exit(0);
275 }
276
277/* Initialize variables */
278
279 malloc_libmondo_global_strings();
280 malloc_string(tmp);
281 malloc_string(say_at_end);
282
283 res = 0;
284 retval = 0;
285 diffs = 0;
286 say_at_end[0] = '\0';
287 printf("Initializing...\n");
288 if (!(bkpinfo = malloc(sizeof(struct s_bkpinfo)))) {
289 fatal_error("Cannot malloc bkpinfo");
290 }
291
292 /* initialize log file with time stamp */
293 unlink(MONDO_LOGFILE);
294 log_msg(0, "Time started: %s", mr_date());
295
296 /* make sure PATH environmental variable allows access to mkfs, fdisk, etc. */
297 strncpy(tmp, getenv("PATH"), MAX_STR_LEN - 1);
298 tmp[MAX_STR_LEN - 1] = '\0';
299 if (strlen(tmp) >= MAX_STR_LEN - 33) {
300 fatal_error
301 ("Your PATH environmental variable is too long. Please shorten it.");
302 }
303 strcat(tmp, ":/sbin:/usr/sbin:/usr/local/sbin");
304 setenv("PATH", tmp, 1);
305
306 /* Add the ARCH environment variable for ia64 purposes */
307 strncpy(tmp, get_architecture(), MAX_STR_LEN - 1);
308 tmp[MAX_STR_LEN - 1] = '\0';
309 setenv("ARCH", tmp, 1);
310
311 /* Add MONDO_SHARE environment variable for mindi */
312 setenv_mondo_share();
313
314 /* Configure the bkpinfo structure, global file paths, etc. */
315 g_main_pid = getpid();
316 log_msg(9, "This");
317
318 register_pid(g_main_pid, "mondo");
319 set_signals(TRUE); // catch SIGTERM, etc.
320 run_program_and_log_output("dmesg -n1", TRUE);
321
322 log_msg(9, "Next");
323 welcome_to_mondoarchive();
324 distro_specific_kludges_at_start_of_mondoarchive();
325 sprintf(g_erase_tmpdir_and_scratchdir, "rm -Rf %s %s", bkpinfo->tmpdir,
326 bkpinfo->scratchdir);
327 g_kernel_version = get_kernel_version();
328
329 if (argc == 4 && !strcmp(argv[1], "getfattr")) {
330 g_loglevel = 10;
331 g_text_mode = TRUE;
332 setup_newt_stuff();
333 if (!strstr(argv[2], "filelist")) {
334 printf("Sorry - filelist goes first\n");
335 finish(1);
336 } else {
337 finish(get_fattr_list(argv[2], argv[3]));
338 }
339 finish(0);
340 }
341 if (argc == 4 && !strcmp(argv[1], "setfattr")) {
342 g_loglevel = 10;
343// chdir("/tmp");
344 g_text_mode = TRUE;
345 setup_newt_stuff();
346 finish(set_fattr_list(argv[2], argv[3]));
347 }
348
349 if (argc == 3 && !strcmp(argv[1], "wildcards")) {
350 g_loglevel = 10;
351 g_text_mode = TRUE;
352 setup_newt_stuff();
353 turn_wildcard_chars_into_literal_chars(tmp, argv[2]);
354 printf("in=%s; out=%s\n", argv[2], tmp);
355 finish(1);
356 }
357
358 if (argc == 4 && !strcmp(argv[1], "getfacl")) {
359 g_loglevel = 10;
360 g_text_mode = TRUE;
361 setup_newt_stuff();
362 if (!strstr(argv[2], "filelist")) {
363 printf("Sorry - filelist goes first\n");
364 finish(1);
365 } else {
366 finish(get_acl_list(argv[2], argv[3]));
367 }
368 finish(0);
369 }
370 if (argc == 4 && !strcmp(argv[1], "setfacl")) {
371 g_loglevel = 10;
372// chdir("/tmp");
373 g_text_mode = TRUE;
374 setup_newt_stuff();
375 finish(set_acl_list(argv[2], argv[3]));
376 }
377
378 if (argc > 2 && !strcmp(argv[1], "find-cd")) {
379 g_loglevel = 10;
380 g_text_mode = TRUE;
381 setup_newt_stuff();
382 if (find_cdrw_device(tmp)) {
383 printf("Failed to find CDR-RW drive\n");
384 } else {
385 printf("CD-RW is at %s\n", tmp);
386 }
387 tmp[0] = '\0';
388 if (find_cdrom_device(tmp, atoi(argv[2]))) {
389 printf("Failed to find CD-ROM drive\n");
390 } else {
391 printf("CD-ROM is at %s\n", tmp);
392 }
393 finish(0);
394 }
395
396 if (argc > 2 && !strcmp(argv[1], "find-dvd")) {
397 g_loglevel = 10;
398 g_text_mode = TRUE;
399 setup_newt_stuff();
400 if (find_dvd_device(tmp, atoi(argv[2]))) {
401 printf("Failed to find DVD drive\n");
402 } else {
403 printf("DVD is at %s\n", tmp);
404 }
405 finish(0);
406 }
407
408 if (argc > 2 && !strcmp(argv[1], "disksize")) {
409 printf("%s --> %ld\n", argv[2], get_phys_size_of_drive(argv[2]));
410 finish(0);
411 }
412 if (argc > 2 && !strcmp(argv[1], "test-dev")) {
413 if (is_dev_an_NTFS_dev(argv[2])) {
414 printf("%s is indeed an NTFS dev\n", argv[2]);
415 } else {
416 printf("%s is _not_ an NTFS dev\n", argv[2]);
417 }
418 finish(0);
419 }
420
421 if (pre_param_configuration(bkpinfo)) {
422 fatal_error
423 ("Pre-param initialization phase failed. Please review the error messages above, make the specified changes, then try again. Exiting...");
424 }
425
426/* Process command line, if there is one. If not, ask user for info. */
427 if (argc == 1) {
428 g_text_mode = FALSE;
429 setup_newt_stuff();
430 res = interactively_obtain_media_parameters_from_user(bkpinfo, TRUE); /* yes, archiving */
431 if (res) {
432 fatal_error
433 ("Syntax error. Please review the parameters you have supplied and try again.");
434 }
435 } else {
436 res = handle_incoming_parameters(argc, argv, bkpinfo);
437 if (res) {
438 printf
439 ("Errors were detected in the command line you supplied.\n");
440 printf("Please review the log file - " MONDO_LOGFILE "\n");
441 log_msg(1, "Mondoarchive will now exit.");
442 finish(1);
443 }
444 setup_newt_stuff();
445 }
446
447/* Finish configuring global structures */
448 if (post_param_configuration(bkpinfo)) {
449 fatal_error
450 ("Post-param initialization phase failed. Perhaps bad parameters were supplied to mondoarchive? Please review the documentation, error messages and logs. Exiting...");
451 }
452
453 log_to_screen
454 ("BusyBox's sources are available from http://www.busybox.net");
455 sprintf(g_erase_tmpdir_and_scratchdir, "rm -Rf %s %s", bkpinfo->tmpdir,
456 bkpinfo->scratchdir);
457
458 /* If we're meant to backup then backup */
459 if (bkpinfo->backup_data) {
460/*
461 log_to_screen("INFERNAL PORPOISES");
462 res = archive_this_fileset_with_star(bkpinfo, "/tmp/filelist.0", "/tmp/0.star.bz2", 0);
463 log_to_screen("atfws returned %d", res);
464 finish(0);
465*/
466 res = backup_data(bkpinfo);
467 retval += res;
468 if (res) {
469 strcat(say_at_end,
470 "Data archived. Please check the logs, just as a precaution. ");
471 } else {
472 strcat(say_at_end, "Data archived OK. ");
473 }
474 }
475
476/* If we're meant to verify then verify */
477 if (bkpinfo->verify_data) {
478 res = verify_data(bkpinfo);
479 if (res < 0) {
480 sprintf(tmp, "%d difference%c found.", -res,
481 (-res != 1) ? 's' : ' ');
482 strcat(say_at_end, tmp);
483 log_to_screen(tmp);
484 res = 0;
485 }
486 retval += res;
487 }
488
489/* Offer to write floppy disk images to physical disks */
490 if (bkpinfo->backup_data && !g_skip_floppies) {
491 res = offer_to_write_boot_floppies_to_physical_disks(bkpinfo);
492 retval += res;
493// res = offer_to_write_boot_ISO_to_physical_CD(bkpinfo);
494// retval += res;
495 }
496
497/* Report result of entire operation (success? errors?) */
498 if (!retval) {
499 mvaddstr_and_log_it(g_currentY++, 0,
500 "Backup and/or verify ran to completion. Everything appears to be fine.");
501 } else {
502 mvaddstr_and_log_it(g_currentY++, 0,
503 "Backup and/or verify ran to completion. However, errors did occur.");
504 }
505
506 if (does_file_exist("/root/images/mindi/mondorescue.iso")) {
507 log_to_screen
508 ("/root/images/mindi/mondorescue.iso, a boot/utility CD, is available if you want it.");
509 }
510
511
512 if (length_of_file("/tmp/changed.files") > 2) {
513 if (g_text_mode) {
514 log_to_screen
515 ("Type 'less /tmp/changed.files' to see which files don't match the archives");
516 } else {
517 log_msg(1,
518 "Type 'less /tmp/changed.files' to see which files don't match the archives");
519 log_msg(2, "Calling popup_changelist_from_file()");
520 popup_changelist_from_file("/tmp/changed.files");
521 log_msg(2, "Returned from popup_changelist_from_file()");
522 }
523 } else {
524 unlink("/tmp/changed.files");
525 }
526 log_to_screen(say_at_end);
527 sprintf(tmp, "umount %s/tmpfs", bkpinfo->tmpdir);
528 run_program_and_log_output(tmp, TRUE);
529 run_program_and_log_output(g_erase_tmpdir_and_scratchdir, TRUE);
530
531 run_program_and_log_output("mount", 2);
532
533 system("rm -f /var/cache/mondo-archive/last-backup.aborted");
534 system("rm -Rf /tmp.mondo.* /mondo.scratch.*");
535 if (!retval) {
536 printf("Mondoarchive ran OK.\n");
537 } else {
538 printf("Errors occurred during backup. Please check logfile.\n");
539 }
540 distro_specific_kludges_at_end_of_mondoarchive();
541 register_pid(0, "mondo");
542 set_signals(FALSE);
543 chdir("/tmp"); // just in case there's something wrong with g_erase_tmpdir_and_scratchdir
544 system(g_erase_tmpdir_and_scratchdir);
545 free_libmondo_global_strings();
546 paranoid_free(say_at_end);
547 paranoid_free(tmp);
548 paranoid_free(bkpinfo);
549
550 unlink("/tmp/filelist.full");
551 unlink("/tmp/filelist.full.gz");
552
553 if (!g_cdrom_drive_is_here) {
554 log_msg(10, "FYI, g_cdrom_drive_is_here was never used");
555 }
556 if (!g_dvd_drive_is_here) {
557 log_msg(10, "FYI, g_dvd_drive_is_here was never used");
558 }
559
560 /* finalize log file with time stamp */
561 log_msg(0, "Time finished: %s", mr_date());
562
563 if (!g_text_mode) {
564 popup_and_OK
565 ("Mondo Archive has finished its run. Please press ENTER to return to the shell prompt.");
566 log_to_screen("See %s for details of backup run.", MONDO_LOGFILE);
567 finish(retval);
568 } else {
569 printf("See %s for details of backup run.\n", MONDO_LOGFILE);
570 exit(retval);
571 }
572
573 return EXIT_SUCCESS;
574}
Note: See TracBrowser for help on using the repository browser.