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

Last change on this file since 1102 was 1102, checked in by Bruno Cornec, 13 years ago

Other compiler warnings removed

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