source: branches/2.2.6/mondo/src/mondoarchive/mondoarchive.c @ 1930

Last change on this file since 1930 was 1930, checked in by Bruno Cornec, 12 years ago

Renaming of files to be in conformity with stable and ease aplication of patches between branches.

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