/*************************************************************************** main.c - description ------------------- begin : Fri Apr 19 16:40:35 EDT 2002 copyright : (C) 2002 by Stan Benoit email : troff@nakedsoul.org cvsid : $Id: mondoarchive.c 2030 2008-10-02 23:50:44Z bruno $ ***************************************************************************/ /*************************************************************************** * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License as published by * * the Free Software Foundation; either version 2 of the License, or * * (at your option) any later version. * * * ***************************************************************************/ /** * @file * The main file for mondoarchive. */ /************************* #include statements *************************/ #include #include #include #include "my-stuff.h" #include "../common/mondostructures.h" #include "../common/libmondo.h" #include "../common/libmondo-cli-EXT.h" #include "../common/libmondo-tools-EXT.h" #include "mondoarchive.h" // for CVS //static char cvsid[] = "$Id: mondoarchive.c 2030 2008-10-02 23:50:44Z bruno $"; /************************* external variables *************************/ extern void set_signals(int); extern int g_current_media_number; extern void register_pid(pid_t, char *); extern int g_currentY; extern bool g_text_mode; extern char *g_boot_mountpt; extern bool g_remount_floppy_at_end; extern char *g_cdrw_drive_is_here; static char *g_cdrom_drive_is_here = NULL; static char *g_dvd_drive_is_here = NULL; extern double g_kernel_version; /***************** global vars, used only by main.c ******************/ long diffs; extern t_bkptype g_backup_media_type; extern int g_loglevel; /** * Whether we're restoring from ISOs. Obviously not, since this is the * backup program. * @note You @b MUST declare this variable somewhere in your program if * you use libmondo. Otherwise the link will fail. * @ingroup globalGroup */ bool g_ISO_restore_mode = FALSE; /* Do we use extended attributes and acl ? * * By default no, use --acl & --attr options to force their usage */ char *g_getfacl = NULL; char *g_getfattr = NULL; /* Reference to global bkpinfo */ struct s_bkpinfo *bkpinfo; /* To be coded */ void free_MR_global_filenames(void) { } /****************** subroutines used only by main.c ******************/ /** * Print a "don't panic" message to the log and a message about the logfile to the screen. */ void welcome_to_mondoarchive(void) { char *tmp = NULL; log_msg(0, "Mondo Archive v%s --- http://www.mondorescue.org", PACKAGE_VERSION); log_msg(0, "running %s binaries", get_architecture()); tmp = get_uname_m(); log_msg(0, "running on %s architecture", tmp); free(tmp); log_msg(0, "-----------------------------------------------------------"); log_msg(0, "NB: Mondo logs almost everything, so don't panic if you see"); log_msg(0, "some error messages. Please read them carefully before you"); log_msg(0, "decide to break out in a cold sweat. Despite (or perhaps"); log_msg(0, "because of) the wealth of messages. some users are inclined"); log_msg(0, "to stop reading this log. If Mondo stopped for some reason,"); log_msg(0, "chances are it's detailed here. More than likely there's a"); log_msg(0, "message at the very end of this log that will tell you what"); log_msg(0, "is wrong. Please read it! -Devteam"); log_msg(0, "-----------------------------------------------------------"); log_msg(0, "Zero..."); log_msg(1, "One..."); log_msg(2, "Two..."); log_msg(3, "Three..."); log_msg(4, "Four..."); log_msg(5, "Five..."); log_msg(6, "Six..."); log_msg(7, "Seven..."); log_msg(8, "Eight..."); printf("See %s for details of backup run.\n", MONDO_LOGFILE); } extern char *g_magicdev_command; /** * Do whatever is necessary to insure a successful backup on the Linux distribution * of the day. */ void distro_specific_kludges_at_start_of_mondoarchive(void) { log_msg(2, "Unmounting old ramdisks if necessary"); stop_magicdev_if_necessary(); // for RH+Gnome users /* run_program_and_log_output ("umount `mount | grep shm | grep mondo | cut -d' ' -f3`", 2); */ unmount_supermounts_if_necessary(); // for Mandrake users whose CD-ROMs are supermounted // stop_autofs_if_necessary(); // for Xandros users mount_boot_if_necessary(); // for Gentoo users with non-mounted /boot partitions clean_up_KDE_desktop_if_necessary(); // delete various misc ~/.* files that get in the way } /** * Undo whatever was done by distro_specific_kludges_at_start_of_mondoarchive(). */ void distro_specific_kludges_at_end_of_mondoarchive(void) { // char tmp[500]; log_msg(2, "Restarting magicdev if necessary"); sync(); restart_magicdev_if_necessary(); // for RH+Gnome users log_msg(2, "Restarting autofs if necessary"); sync(); // restart_autofs_if_necessary(); // for Xandros users log_msg(2, "Restarting supermounts if necessary"); sync(); remount_supermounts_if_necessary(); // for Mandrake users log_msg(2, "Unmounting /boot if necessary"); sync(); unmount_boot_if_necessary(); // for Gentoo users // log_msg( 2, "Cleaning up KDE desktop"); // clean_up_KDE_desktop_if_necessary(); } /** * Backup/verify the user's data. * What did you think it did, anyway? :-) */ int main(int argc, char *argv[]) { char *tmp; int res, retval; char *say_at_end; /* Make sure I'm root; abort if not */ if (getuid() != 0) { fprintf(stderr, "Please run as root.\r\n"); exit(127); } /* If -V, -v or --version then echo version no. and quit */ if (argc == 2 && (!strcmp(argv[argc - 1], "-v") || !strcmp(argv[argc - 1], "-V") || !strcmp(argv[argc - 1], "--version"))) { printf("mondoarchive v%s\nSee man page for help\n", PACKAGE_VERSION); exit(0); } /* Initialize variables */ printf("Initializing...\n"); if (!(bkpinfo = malloc(sizeof(struct s_bkpinfo)))) { fatal_error("Cannot malloc bkpinfo"); } reset_bkpinfo(); res = 0; retval = 0; diffs = 0; malloc_string(tmp); malloc_string(say_at_end); say_at_end[0] = '\0'; malloc_libmondo_global_strings(); /* initialize log file with time stamp */ unlink(MONDO_LOGFILE); log_msg(0, "Time started: %s", mr_date()); /* make sure PATH environmental variable allows access to mkfs, fdisk, etc. */ strncpy(tmp, getenv("PATH"), MAX_STR_LEN - 1); tmp[MAX_STR_LEN - 1] = '\0'; if (strlen(tmp) >= MAX_STR_LEN - 33) { fatal_error ("Your PATH environmental variable is too long. Please shorten it."); } strcat(tmp, ":/sbin:/usr/sbin:/usr/local/sbin"); setenv("PATH", tmp, 1); /* Add the ARCH environment variable for ia64 purposes */ strncpy(tmp, get_architecture(), MAX_STR_LEN - 1); tmp[MAX_STR_LEN - 1] = '\0'; setenv("ARCH", tmp, 1); /* Add MONDO_SHARE environment variable for mindi */ setenv_mondo_share(); /* Configure the bkpinfo structure, global file paths, etc. */ g_main_pid = getpid(); log_msg(9, "This"); register_pid(g_main_pid, "mondo"); set_signals(TRUE); // catch SIGTERM, etc. run_program_and_log_output("dmesg -n1", TRUE); log_msg(9, "Next"); make_hole_for_dir(MONDO_CACHE); welcome_to_mondoarchive(); distro_specific_kludges_at_start_of_mondoarchive(); g_kernel_version = get_kernel_version(); if (argc == 4 && !strcmp(argv[1], "getfattr")) { g_loglevel = 10; g_text_mode = TRUE; setup_newt_stuff(); if (!strstr(argv[2], "filelist")) { printf("Sorry - filelist goes first\n"); finish(1); } else { finish(get_fattr_list(argv[2], argv[3])); } finish(0); } if (argc == 4 && !strcmp(argv[1], "setfattr")) { g_loglevel = 10; // chdir("/tmp"); g_text_mode = TRUE; setup_newt_stuff(); finish(set_fattr_list(argv[2], argv[3])); } if (argc == 3 && !strcmp(argv[1], "wildcards")) { g_loglevel = 10; g_text_mode = TRUE; setup_newt_stuff(); turn_wildcard_chars_into_literal_chars(tmp, argv[2]); printf("in=%s; out=%s\n", argv[2], tmp); finish(1); } if (argc == 4 && !strcmp(argv[1], "getfacl")) { g_loglevel = 10; g_text_mode = TRUE; setup_newt_stuff(); if (!strstr(argv[2], "filelist")) { printf("Sorry - filelist goes first\n"); finish(1); } else { finish(get_acl_list(argv[2], argv[3])); } finish(0); } if (argc == 4 && !strcmp(argv[1], "setfacl")) { g_loglevel = 10; // chdir("/tmp"); g_text_mode = TRUE; setup_newt_stuff(); finish(set_acl_list(argv[2], argv[3])); } if (argc > 2 && !strcmp(argv[1], "find-cd")) { g_loglevel = 10; g_text_mode = TRUE; setup_newt_stuff(); if (find_cdrw_device(tmp)) { printf("Failed to find CDR-RW drive\n"); } else { printf("CD-RW is at %s\n", tmp); } tmp[0] = '\0'; if (find_cdrom_device(tmp, atoi(argv[2]))) { printf("Failed to find CD-ROM drive\n"); } else { printf("CD-ROM is at %s\n", tmp); } finish(0); } if (argc > 2 && !strcmp(argv[1], "find-dvd")) { g_loglevel = 10; g_text_mode = TRUE; setup_newt_stuff(); if (find_dvd_device(tmp, atoi(argv[2]))) { printf("Failed to find DVD drive\n"); } else { printf("DVD is at %s\n", tmp); } finish(0); } if (argc > 2 && !strcmp(argv[1], "disksize")) { printf("%s --> %ld\n", argv[2], get_phys_size_of_drive(argv[2])); finish(0); } if (argc > 2 && !strcmp(argv[1], "test-dev")) { if (is_dev_an_NTFS_dev(argv[2])) { printf("%s is indeed an NTFS dev\n", argv[2]); } else { printf("%s is _not_ an NTFS dev\n", argv[2]); } finish(0); } if (pre_param_configuration()) { fatal_error ("Pre-param initialization phase failed. Please review the error messages above, make the specified changes, then try again. Exiting..."); } /* Process command line, if there is one. If not, ask user for info. */ if (argc == 1) { g_text_mode = FALSE; setup_newt_stuff(); res = interactively_obtain_media_parameters_from_user(TRUE); /* yes, archiving */ if (res) { fatal_error ("Syntax error. Please review the parameters you have supplied and try again."); } } else { res = handle_incoming_parameters(argc, argv); if (res) { printf ("Errors were detected in the command line you supplied.\n"); printf("Please review the log file - %s\n", MONDO_LOGFILE ); log_msg(1, "Mondoarchive will now exit."); finish(1); } setup_newt_stuff(); } /* Finish configuring global structures */ if (post_param_configuration()) { fatal_error ("Post-param initialization phase failed. Perhaps bad parameters were supplied to mondoarchive? Please review the documentation, error messages and logs. Exiting..."); } log_to_screen ("BusyBox's sources are available from http://www.busybox.net"); /* If we're meant to backup then backup */ if (bkpinfo->backup_data) { res = backup_data(); retval += res; if (res) { strcat(say_at_end, "Data archived. Please check the logs, just as a precaution. "); } else { strcat(say_at_end, "Data archived OK. "); } } /* If we're meant to verify then verify */ if (bkpinfo->verify_data) { res = verify_data(); if (res < 0) { sprintf(tmp, "%d difference%c found.", -res, (-res != 1) ? 's' : ' '); strcat(say_at_end, tmp); log_to_screen(tmp); res = 0; } retval += res; } /* Report result of entire operation (success? errors?) */ if (!retval) { mvaddstr_and_log_it(g_currentY++, 0, "Backup and/or verify ran to completion. Everything appears to be fine."); } else { mvaddstr_and_log_it(g_currentY++, 0, "Backup and/or verify ran to completion. However, errors did occur."); } if (does_file_exist(MINDI_CACHE"/mondorescue.iso")) { log_to_screen (MINDI_CACHE"/mondorescue.iso, a boot/utility CD, is available if you want it."); } if (length_of_file(MONDO_CACHE"/changed.files") > 2) { if (g_text_mode) { log_to_screen("Type 'less "MONDO_CACHE"/changed.files' to see which files don't match the archives"); } else { log_msg(1, "Type 'less "MONDO_CACHE"/changed.files' to see which files don't match the archives"); log_msg(2, "Calling popup_changelist_from_file()"); popup_changelist_from_file(MONDO_CACHE"/changed.files"); log_msg(2, "Returned from popup_changelist_from_file()"); } } else { unlink(MONDO_CACHE"/changed.files"); } log_to_screen(say_at_end); sprintf(tmp, "umount %s/tmpfs", bkpinfo->tmpdir); run_program_and_log_output(tmp, TRUE); if (bkpinfo->backup_media_type == usb) { log_msg(1, "Unmounting USB device."); sprintf(tmp, "umount %s1", bkpinfo->media_device); run_program_and_log_output(tmp, TRUE); } run_program_and_log_output("mount", 2); system("rm -f "MONDO_CACHE"/last-backup.aborted"); if (!retval) { printf("Mondoarchive ran OK.\n"); } else { printf("Errors occurred during backup. Please check logfile.\n"); } distro_specific_kludges_at_end_of_mondoarchive(); register_pid(0, "mondo"); set_signals(FALSE); free_libmondo_global_strings(); paranoid_free(say_at_end); if (!g_cdrom_drive_is_here) { log_msg(10, "FYI, g_cdrom_drive_is_here was never used"); } if (!g_dvd_drive_is_here) { log_msg(10, "FYI, g_dvd_drive_is_here was never used"); } /* finalize log file with time stamp */ log_msg(0, "Time finished: %s", mr_date()); chdir("/tmp"); if (!g_text_mode) { popup_and_OK ("Mondo Archive has finished its run. Please press ENTER to return to the shell prompt."); log_to_screen("See %s for details of backup run.", MONDO_LOGFILE); } else { printf("See %s for details of backup run.\n", MONDO_LOGFILE); } finish(retval); return EXIT_SUCCESS; }