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

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

Try to fix some valgrind reports (note that this version still doesn't work)

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