source: MondoRescue/trunk/mondo/src/mondoarchive/main.c @ 900

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

Huge patch to introduce low level functions that will bw used everywhere (mr_free, mr_asprintf, ...)
Nearly linking now due to that.

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