source: trunk/mondo/mondo/mondoarchive/main.c @ 688

Last change on this file since 688 was 688, checked in by bcornec, 13 years ago

Huge memory management patch.
Still not finished but a lot as been done.
What remains is around some functions returning strings, and some structure members.
(Could not finish due to laptop failure !)

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