source: MondoRescue/branches/2.2.4/mondo/src/mondoarchive/main.c @ 1437

Last change on this file since 1437 was 1437, checked in by andree, 13 years ago

New define 'MINDI_CACHE' set to '/var/cache/mindi' rather than
hardcoding this in the code. Makes it easy to change the location. Also
adjusted some of the messages related to boot floppies or CDs.

(Also added missing debug level to log_debug() call.)

  • Property svn:keywords set to Id
File size: 16.4 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 1437 2007-05-10 21:41:11Z andree $
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#include "../common/libmondo-tools-EXT.h"
120#include "mondoarchive.h"
121
122// for CVS
123//static char cvsid[] = "$Id: main.c 1437 2007-05-10 21:41:11Z andree $";
124
125/************************* external variables *************************/
126extern void set_signals(int);
127extern int g_current_media_number;
128extern void register_pid(pid_t, char *);
129extern int g_currentY;
130extern bool g_text_mode;
131extern char *g_boot_mountpt;
132extern bool g_remount_cdrom_at_end, g_remount_floppy_at_end;
133extern char *g_mondo_home;
134extern char *g_tmpfs_mountpt;
135extern char *g_erase_tmpdir_and_scratchdir;
136extern char *g_cdrw_drive_is_here;
137static char *g_cdrom_drive_is_here = NULL;
138static char *g_dvd_drive_is_here = NULL;
139extern double g_kernel_version;
140
141/***************** global vars, used only by main.c ******************/
142bool g_skip_floppies;
143long diffs;
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(void)
155{
156    char *tmp = NULL;
157
158    log_msg(0, "Mondo Archive v%s --- http://www.mondorescue.org",
159            PACKAGE_VERSION);
160    log_msg(0, "running %s binaries", get_architecture());
161    tmp = get_uname_m();
162    log_msg(0, "running on %s architecture", tmp);
163    free(tmp);
164    log_msg(0,
165            "-----------------------------------------------------------");
166    log_msg(0,
167            "NB: Mondo logs almost everything, so don't panic if you see");
168    log_msg(0,
169            "some error messages.  Please read them carefully before you");
170    log_msg(0,
171            "decide to break out in a cold sweat.    Despite (or perhaps");
172    log_msg(0,
173            "because of) the wealth of messages. some users are inclined");
174    log_msg(0,
175            "to stop reading this log. If Mondo stopped for some reason,");
176    log_msg(0,
177            "chances are it's detailed here.  More than likely there's a");
178    log_msg(0,
179            "message at the very end of this log that will tell you what");
180    log_msg(0,
181            "is wrong. Please read it!                          -Devteam");
182    log_msg(0,
183            "-----------------------------------------------------------");
184
185    log_msg(0, "Zero...");
186    log_msg(1, "One...");
187    log_msg(2, "Two...");
188    log_msg(3, "Three...");
189    log_msg(4, "Four...");
190    log_msg(5, "Five...");
191    log_msg(6, "Six...");
192    log_msg(7, "Seven...");
193    log_msg(8, "Eight...");
194    printf("See %s for details of backup run.\n", MONDO_LOGFILE);
195}
196
197
198extern char *g_magicdev_command;
199
200/**
201 * Do whatever is necessary to insure a successful backup on the Linux distribution
202 * of the day.
203 */
204void distro_specific_kludges_at_start_of_mondoarchive(void)
205{
206    log_msg(2, "Unmounting old ramdisks if necessary");
207    stop_magicdev_if_necessary();   // for RH+Gnome users
208    run_program_and_log_output
209        ("umount `mount | grep shm | grep mondo | cut -d' ' -f3`", 2);
210    unmount_supermounts_if_necessary(); // for Mandrake users whose CD-ROMs are supermounted
211    //  stop_autofs_if_necessary(); // for Xandros users
212    mount_boot_if_necessary();  // for Gentoo users with non-mounted /boot partitions
213    clean_up_KDE_desktop_if_necessary();    // delete various misc ~/.* files that get in the way
214}
215
216
217
218/**
219 * Undo whatever was done by distro_specific_kludges_at_start_of_mondoarchive().
220 */
221void distro_specific_kludges_at_end_of_mondoarchive(void)
222{
223//  char tmp[500];
224    log_msg(2, "Restarting magicdev if necessary");
225    sync();
226    restart_magicdev_if_necessary();    // for RH+Gnome users
227
228    log_msg(2, "Restarting autofs if necessary");
229    sync();
230    //  restart_autofs_if_necessary(); // for Xandros users
231
232    log_msg(2, "Restarting supermounts if necessary");
233    sync();
234    remount_supermounts_if_necessary(); // for Mandrake users
235
236    log_msg(2, "Unmounting /boot if necessary");
237    sync();
238    unmount_boot_if_necessary();    // for Gentoo users
239
240//  log_msg( 2, "Cleaning up KDE desktop");
241//  clean_up_KDE_desktop_if_necessary();
242}
243
244/* Return a string containing the date */
245char *mr_date(void) {
246   
247    time_t tcurr;
248
249    tcurr = time(NULL);
250    return(ctime(&tcurr));
251}
252
253/*-----------------------------------------------------------*/
254
255
256
257/**
258 * Backup/verify the user's data.
259 * What did you think it did, anyway? :-)
260 */
261int main(int argc, char *argv[])
262{
263    struct s_bkpinfo *bkpinfo;
264    char *tmp;
265    int res, retval;
266    char *say_at_end;
267
268/* Make sure I'm root; abort if not */
269    if (getuid() != 0) {
270        fprintf(stderr, "Please run as root.\r\n");
271        exit(127);
272    }
273
274/* If -V, -v or --version then echo version no. and quit */
275    if (argc == 2
276        && (!strcmp(argv[argc - 1], "-v") || !strcmp(argv[argc - 1], "-V")
277            || !strcmp(argv[argc - 1], "--version"))) {
278        printf("mondoarchive v%s\nSee man page for help\n", PACKAGE_VERSION);
279        exit(0);
280    }
281
282/* Initialize variables */
283
284    malloc_libmondo_global_strings();
285    malloc_string(tmp);
286    malloc_string(say_at_end);
287
288    res = 0;
289    retval = 0;
290    diffs = 0;
291    say_at_end[0] = '\0';
292    printf("Initializing...\n");
293    if (!(bkpinfo = malloc(sizeof(struct s_bkpinfo)))) {
294        fatal_error("Cannot malloc bkpinfo");
295    }
296
297    /* initialize log file with time stamp */
298    unlink(MONDO_LOGFILE);
299    log_msg(0, "Time started: %s", mr_date());
300
301    /* make sure PATH environmental variable allows access to mkfs, fdisk, etc. */
302    strncpy(tmp, getenv("PATH"), MAX_STR_LEN - 1);
303    tmp[MAX_STR_LEN - 1] = '\0';
304    if (strlen(tmp) >= MAX_STR_LEN - 33) {
305        fatal_error
306            ("Your PATH environmental variable is too long. Please shorten it.");
307    }
308    strcat(tmp, ":/sbin:/usr/sbin:/usr/local/sbin");
309    setenv("PATH", tmp, 1);
310
311    /* Add the ARCH environment variable for ia64 purposes */
312    strncpy(tmp, get_architecture(), MAX_STR_LEN - 1);
313    tmp[MAX_STR_LEN - 1] = '\0';
314    setenv("ARCH", tmp, 1);
315
316    /* Add MONDO_SHARE environment variable for mindi */
317    setenv_mondo_share();
318
319    /* Configure the bkpinfo structure, global file paths, etc. */
320    g_main_pid = getpid();
321    log_msg(9, "This");
322
323    register_pid(g_main_pid, "mondo");
324    set_signals(TRUE);          // catch SIGTERM, etc.
325    run_program_and_log_output("dmesg -n1", TRUE);
326
327    log_msg(9, "Next");
328    welcome_to_mondoarchive();
329    distro_specific_kludges_at_start_of_mondoarchive();
330    g_kernel_version = get_kernel_version();
331
332    if (argc == 4 && !strcmp(argv[1], "getfattr")) {
333        g_loglevel = 10;
334        g_text_mode = TRUE;
335        setup_newt_stuff();
336        if (!strstr(argv[2], "filelist")) {
337            printf("Sorry - filelist goes first\n");
338            finish(1);
339        } else {
340            finish(get_fattr_list(argv[2], argv[3]));
341        }
342        finish(0);
343    }
344    if (argc == 4 && !strcmp(argv[1], "setfattr")) {
345        g_loglevel = 10;
346//      chdir("/tmp");
347        g_text_mode = TRUE;
348        setup_newt_stuff();
349        finish(set_fattr_list(argv[2], argv[3]));
350    }
351
352    if (argc == 3 && !strcmp(argv[1], "wildcards")) {
353        g_loglevel = 10;
354        g_text_mode = TRUE;
355        setup_newt_stuff();
356        turn_wildcard_chars_into_literal_chars(tmp, argv[2]);
357        printf("in=%s; out=%s\n", argv[2], tmp);
358        finish(1);
359    }
360
361    if (argc == 4 && !strcmp(argv[1], "getfacl")) {
362        g_loglevel = 10;
363        g_text_mode = TRUE;
364        setup_newt_stuff();
365        if (!strstr(argv[2], "filelist")) {
366            printf("Sorry - filelist goes first\n");
367            finish(1);
368        } else {
369            finish(get_acl_list(argv[2], argv[3]));
370        }
371        finish(0);
372    }
373    if (argc == 4 && !strcmp(argv[1], "setfacl")) {
374        g_loglevel = 10;
375//      chdir("/tmp");
376        g_text_mode = TRUE;
377        setup_newt_stuff();
378        finish(set_acl_list(argv[2], argv[3]));
379    }
380
381    if (argc > 2 && !strcmp(argv[1], "find-cd")) {
382        g_loglevel = 10;
383        g_text_mode = TRUE;
384        setup_newt_stuff();
385        if (find_cdrw_device(tmp)) {
386            printf("Failed to find CDR-RW drive\n");
387        } else {
388            printf("CD-RW is at %s\n", tmp);
389        }
390        tmp[0] = '\0';
391        if (find_cdrom_device(tmp, atoi(argv[2]))) {
392            printf("Failed to find CD-ROM drive\n");
393        } else {
394            printf("CD-ROM is at %s\n", tmp);
395        }
396        finish(0);
397    }
398
399    if (argc > 2 && !strcmp(argv[1], "find-dvd")) {
400        g_loglevel = 10;
401        g_text_mode = TRUE;
402        setup_newt_stuff();
403        if (find_dvd_device(tmp, atoi(argv[2]))) {
404            printf("Failed to find DVD drive\n");
405        } else {
406            printf("DVD is at %s\n", tmp);
407        }
408        finish(0);
409    }
410
411    if (argc > 2 && !strcmp(argv[1], "disksize")) {
412        printf("%s --> %ld\n", argv[2], get_phys_size_of_drive(argv[2]));
413        finish(0);
414    }
415    if (argc > 2 && !strcmp(argv[1], "test-dev")) {
416        if (is_dev_an_NTFS_dev(argv[2])) {
417            printf("%s is indeed an NTFS dev\n", argv[2]);
418        } else {
419            printf("%s is _not_ an NTFS dev\n", argv[2]);
420        }
421        finish(0);
422    }
423
424    if (pre_param_configuration(bkpinfo)) {
425        fatal_error
426            ("Pre-param initialization phase failed. Please review the error messages above, make the specified changes, then try again. Exiting...");
427    }
428
429/* Process command line, if there is one. If not, ask user for info. */
430    if (argc == 1) {
431        g_text_mode = FALSE;
432        setup_newt_stuff();
433        res = interactively_obtain_media_parameters_from_user(bkpinfo, TRUE);   /* yes, archiving */
434        if (res) {
435            fatal_error
436                ("Syntax error. Please review the parameters you have supplied and try again.");
437        }
438    } else {
439        res = handle_incoming_parameters(argc, argv, bkpinfo);
440        if (res) {
441            printf
442                ("Errors were detected in the command line you supplied.\n");
443            printf("Please review the log file - %s\n", MONDO_LOGFILE );
444            log_msg(1, "Mondoarchive will now exit.");
445            finish(1);
446        }
447        setup_newt_stuff();
448    }
449
450/* Finish configuring global structures */
451    if (post_param_configuration(bkpinfo)) {
452        fatal_error
453            ("Post-param initialization phase failed. Perhaps bad parameters were supplied to mondoarchive? Please review the documentation, error messages and logs. Exiting...");
454    }
455
456    log_to_screen
457        ("BusyBox's sources are available from http://www.busybox.net");
458    sprintf(g_erase_tmpdir_and_scratchdir, "rm -Rf %s %s", bkpinfo->tmpdir,
459            bkpinfo->scratchdir);
460
461    /* If we're meant to backup then backup */
462    if (bkpinfo->backup_data) {
463        res = backup_data(bkpinfo);
464        retval += res;
465        if (res) {
466            strcat(say_at_end,
467                   "Data archived. Please check the logs, just as a precaution. ");
468        } else {
469            strcat(say_at_end, "Data archived OK. ");
470        }
471    }
472
473/* If we're meant to verify then verify */
474    if (bkpinfo->verify_data) {
475        res = verify_data(bkpinfo);
476        if (res < 0) {
477            sprintf(tmp, "%d difference%c found.", -res,
478                    (-res != 1) ? 's' : ' ');
479            strcat(say_at_end, tmp);
480            log_to_screen(tmp);
481            res = 0;
482        }
483        retval += res;
484    }
485
486/* Offer to write floppy disk images to physical disks */
487    if (bkpinfo->backup_data && !g_skip_floppies) {
488        res = offer_to_write_boot_floppies_to_physical_disks(bkpinfo);
489        retval += res;
490//      res = offer_to_write_boot_ISO_to_physical_CD(bkpinfo);
491//      retval += res;
492    }
493
494/* Report result of entire operation (success? errors?) */
495    if (!retval) {
496        mvaddstr_and_log_it(g_currentY++, 0,
497                            "Backup and/or verify ran to completion. Everything appears to be fine.");
498    } else {
499        mvaddstr_and_log_it(g_currentY++, 0,
500                            "Backup and/or verify ran to completion. However, errors did occur.");
501    }
502
503    if (does_file_exist(MINDI_CACHE"/mondorescue.iso")) {
504        log_to_screen
505            (MINDI_CACHE"/mondorescue.iso, a boot/utility CD, is available if you want it.");
506    }
507
508
509    if (length_of_file("/tmp/changed.files") > 2) {
510        if (g_text_mode) {
511            log_to_screen
512                ("Type 'less /tmp/changed.files' to see which files don't match the archives");
513        } else {
514            log_msg(1,
515                    "Type 'less /tmp/changed.files' to see which files don't match the archives");
516            log_msg(2, "Calling popup_changelist_from_file()");
517            popup_changelist_from_file("/tmp/changed.files");
518            log_msg(2, "Returned from popup_changelist_from_file()");
519        }
520    } else {
521        unlink("/tmp/changed.files");
522    }
523    log_to_screen(say_at_end);
524    sprintf(tmp, "umount %s/tmpfs", bkpinfo->tmpdir);
525    run_program_and_log_output(tmp, TRUE);
526    run_program_and_log_output(g_erase_tmpdir_and_scratchdir, TRUE);
527
528    run_program_and_log_output("mount", 2);
529
530    system("rm -f /var/cache/mondo-archive/last-backup.aborted");
531    system("rm -Rf /tmp.mondo.* /mondo.scratch.*");
532    if (!retval) {
533        printf("Mondoarchive ran OK.\n");
534    } else {
535        printf("Errors occurred during backup. Please check logfile.\n");
536    }
537    distro_specific_kludges_at_end_of_mondoarchive();
538    register_pid(0, "mondo");
539    set_signals(FALSE);
540    chdir("/tmp");              // just in case there's something wrong with g_erase_tmpdir_and_scratchdir
541    system(g_erase_tmpdir_and_scratchdir);
542    free_libmondo_global_strings();
543    paranoid_free(say_at_end);
544    paranoid_free(tmp);
545    paranoid_free(bkpinfo);
546
547    unlink("/tmp/filelist.full");
548    unlink("/tmp/filelist.full.gz");
549
550    if (!g_cdrom_drive_is_here) {
551        log_msg(10, "FYI, g_cdrom_drive_is_here was never used");
552    }
553    if (!g_dvd_drive_is_here) {
554        log_msg(10, "FYI, g_dvd_drive_is_here was never used");
555    }
556
557    /* finalize log file with time stamp */
558    log_msg(0, "Time finished: %s", mr_date());
559
560    if (!g_text_mode) {
561        popup_and_OK
562            ("Mondo Archive has finished its run. Please press ENTER to return to the shell prompt.");
563        log_to_screen("See %s for details of backup run.", MONDO_LOGFILE);
564        finish(retval);
565    } else {
566        printf("See %s for details of backup run.\n", MONDO_LOGFILE);
567        exit(retval);
568    }
569
570    return EXIT_SUCCESS;
571}
Note: See TracBrowser for help on using the repository browser.