source: branches/stable/mondo/src/mondoarchive/mondoarchive.c @ 1326

Last change on this file since 1326 was 1326, checked in by bruno, 13 years ago
  • MONDO_LOGFILE is rather a char* exported by each main program (consolidation of those mecanisms in .h files with ps_*)
  • One include has been created for each binary containing only the specific declarations
  • Log files are now consistent: mondoarchive.log for mondoarchive (containing also mindi.log) and mondorestore.log for mondorestore (copied from /tmp (ram) to /var/log (disk) at the end of the restore)
  • Doc updated accordingly
  • LOGFILE in restore process is now passed in the environment and not duplicated a nymore
  • LogIt? is not redifined either
  • LOGFILE should be put in environment by mondoarchive for mindi's usage but that's a step left for later.
  • label-partitions-as-necessary should now work correctly for LABEL and UUID (grep -w removed)
  • Remove useless script compare-me

(All coming from 2.2.2) (remains changes in my-stuff.h coming later on)

  • Property svn:keywords set to Id
File size: 16.3 KB
Line 
1/***************************************************************************
2* $Id: mondoarchive.c 1326 2007-04-16 22:08:14Z 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 "mondostructures.h"
21#include "libmondo.h"
22#include "mondo-cli-EXT.h"
23
24#include "mondoarchive.h"
25#include "mr_mem.h"
26#include "mr_str.h"
27#include "mr_msg.h"
28#include "mr_file.h"
29#include "mr_err.h"
30#include "mr_conf.h"
31
32// for CVS
33//static char cvsid[] = "$Id: mondoarchive.c 1326 2007-04-16 22:08:14Z bruno $";
34
35/************************* external variables *************************/
36extern void set_signals(int);
37extern int g_current_media_number;
38extern void register_pid(pid_t, char *);
39extern int g_currentY;
40extern bool g_text_mode;
41extern char *g_boot_mountpt;
42extern bool g_remount_cdrom_at_end, g_remount_floppy_at_end;
43extern char *g_tmpfs_mountpt;
44extern char *g_erase_tmpdir_and_scratchdir;
45extern char *g_cdrw_drive_is_here;
46extern double g_kernel_version;
47extern char *g_magicdev_command;
48extern t_bkptype g_backup_media_type;
49extern int g_loglevel;
50
51static char *g_cdrom_drive_is_here = NULL;
52static char *g_dvd_drive_is_here = NULL;
53
54struct mr_ar_conf mr_conf;
55
56/***************** global vars ******************/
57bool g_skip_floppies;
58long diffs;
59
60/****************** subroutines used only here ******************/
61
62
63/**
64 * Print a "don't panic" message to the log and a message about the logfile to the screen.
65 */
66static void welcome_to_mondoarchive(void)
67{
68    mr_msg(0, "Mondo Archive v%s --- http://www.mondorescue.org", PACKAGE_VERSION);
69    mr_msg(0, "running on %s architecture", get_architecture());
70    mr_msg(0, "-----------------------------------------------------------");
71    mr_msg(0, "NB: Mondo logs almost everything, so don't panic if you see");
72    mr_msg(0, "some error messages.  Please read them carefully before you");
73    mr_msg(0, "decide to break out in a cold sweat.    Despite (or perhaps");
74    mr_msg(0, "because of) the wealth of messages. some users are inclined");
75    mr_msg(0, "to stop reading this log. If Mondo stopped for some reason,");
76    mr_msg(0, "chances are it's detailed here.  More than likely there's a");
77    mr_msg(0, "message at the very end of this log that will tell you what");
78    mr_msg(0, "is wrong. Please read it!                          -Devteam");
79    mr_msg(0, "-----------------------------------------------------------");
80
81    mr_msg(0, "Zero...");
82    mr_msg(1, "One...");
83    mr_msg(2, "Two...");
84    mr_msg(3, "Three...");
85    mr_msg(4, "Four...");
86    mr_msg(5, "Five...");
87    mr_msg(6, "Six...");
88    mr_msg(7, "Seven...");
89    mr_msg(8, "Eight...");
90    printf("See %s for details of backup run.\n", MONDO_LOGFILE);
91}
92
93/**
94 * Do whatever is necessary to insure a successful backup on the Linux distribution
95 * of the day.
96 */
97static void distro_specific_kludges_at_start_of_mondoarchive(void)
98{
99    mr_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 */
112static void distro_specific_kludges_at_end_of_mondoarchive(void)
113{
114    mr_msg(2, "Restarting magicdev if necessary");
115    sync();
116    restart_magicdev_if_necessary();    // for RH+Gnome users
117
118    mr_msg(2, "Restarting supermounts if necessary");
119    sync();
120    remount_supermounts_if_necessary(); // for Mandrake users
121
122    mr_msg(2, "Unmounting /boot if necessary");
123    sync();
124    unmount_boot_if_necessary();    // for Gentoo users
125}
126
127/* create the mr_ar_conf structure from mondo's conf file */
128static void mr_ar_store_conf(struct mr_ar_conf *mr_cnf) {
129   
130    mr_asprintf(&mr_cnf->iso_creation_cmd, mr_conf_sread("mondo_iso_creation_cmd"));
131    mr_asprintf(&mr_cnf->iso_creation_options, mr_conf_sread("mondo_iso_creation_options"));
132    mr_asprintf(&mr_cnf->iso_burning_cmd, mr_conf_sread("mondo_iso_burning_cmd"));
133    mr_asprintf(&mr_cnf->iso_burning_options, mr_conf_sread("mondo_iso_burning_options"));
134    mr_cnf->iso_burning_speed = mr_conf_iread("mondo_iso_burning_speed");
135    mr_cnf->media_size = mr_conf_iread("mondo_media_size");
136    mr_asprintf(&mr_cnf->media_device, mr_conf_sread("mondo_media_device"));
137    mr_cnf->manual_tray = mr_conf_bread("mondo_manual_tray");
138    mr_cnf->log_level = mr_conf_iread("mondo_log_level");
139    mr_asprintf(&mr_cnf->prefix, mr_conf_sread("mondo_prefix"));
140    mr_cnf->external_tape_blocksize = mr_conf_iread("mondo_external_tape_blocksize");
141    mr_cnf->internal_tape_blocksize = mr_conf_iread("mondo_internal_tape_blocksize");
142    mr_cnf->slice_size = mr_conf_iread("mondo_slice_size");
143    mr_asprintf(&mr_cnf->deplist_file, mr_conf_sread("mondo_deplist_file"));
144    mr_cnf->write_boot_floppy = mr_conf_bread("mondo_write_boot_floppy");
145    mr_cnf->create_mindi_cd = mr_conf_bread("mondo_create_mindi_cd");
146    mr_asprintf(&mr_cnf->kernel, mr_conf_sread("mondo_kernel"));
147    mr_asprintf(&mr_cnf->additional_modules, mr_conf_sread("mondo_additional_modules"));
148    mr_asprintf(&mr_cnf->boot_loader, mr_conf_sread("mondo_boot_loader"));
149    mr_cnf->differential = mr_conf_bread("mondo_differential");
150    mr_asprintf(&mr_cnf->compression_tool, mr_conf_sread("mondo_compression_tool"));
151    mr_cnf->compression_level = mr_conf_iread("mondo_compression_level");
152    mr_asprintf(&mr_cnf->exclude_paths, mr_conf_sread("mondo_exclude_paths"));
153    mr_asprintf(&mr_cnf->include_paths, mr_conf_sread("mondo_include_paths"));
154    mr_asprintf(&mr_cnf->ui_mode, mr_conf_sread("mondo_ui_mode"));
155    mr_cnf->automatic_restore = mr_conf_bread("mondo_automatic_restore");
156    mr_asprintf(&mr_cnf->scratch_dir, mr_conf_sread("mondo_scratch_dir"));
157    mr_asprintf(&mr_cnf->tmp_dir, mr_conf_sread("mondo_tmp_dir"));
158    mr_asprintf(&mr_cnf->images_dir, mr_conf_sread("mondo_images_dir"));
159    mr_msg(5, "Directory for images is %s", mr_cnf->images_dir);
160}
161
162/* destroy the mr_ar_conf structure's content */
163static void mr_ar_clean_conf(struct mr_ar_conf *mr_cnf) {
164   
165    if (mr_cnf == NULL) {
166        return;
167    }
168    mr_free(mr_cnf->iso_creation_cmd);
169    mr_free(mr_cnf->iso_creation_options);
170    mr_free(mr_cnf->iso_burning_cmd);
171    mr_free(mr_cnf->iso_burning_options);
172    mr_free(mr_cnf->media_device);
173    mr_free(mr_cnf->prefix);
174    mr_free(mr_cnf->deplist_file);
175    mr_free(mr_cnf->kernel);
176    mr_free(mr_cnf->additional_modules);
177    mr_free(mr_cnf->boot_loader);
178    mr_free(mr_cnf->compression_tool);
179    mr_free(mr_cnf->exclude_paths);
180    mr_free(mr_cnf->include_paths);
181    mr_free(mr_cnf->ui_mode);
182    mr_free(mr_cnf->scratch_dir);
183    mr_free(mr_cnf->tmp_dir);
184    mr_free(mr_cnf->images_dir);
185}
186
187/* Create the pointer to the function called in mr_exit */
188void (*mr_cleanup)(void) = NULL;
189
190/* Cleanup all memory allocated in various structures */
191void mr_ar_cleanup(void) {
192    /* Highly incomplete function for the moment */
193    /* We have to free all allocated memory */
194    mr_ar_clean_conf(&mr_conf);
195    /* We have to remove all temporary files */
196    /* We have to unmount what has been mounted */
197    /* We have to properly end newt */
198    /* We have to remind people of log files */
199
200    mr_msg_close();
201}
202
203/*-----------------------------------------------------------*/
204
205
206
207/**
208 * Backup/verify the user's data.
209 * What did you think it did, anyway? :-)
210 */
211int main(int argc, char *argv[])
212{
213    struct s_bkpinfo *bkpinfo = NULL;
214    struct stat stbuf;
215    char *tmp = NULL;
216    int res = 0;
217    int retval = 0;
218    char *say_at_end = NULL;
219    char *say_at_end2 = NULL;
220
221#ifdef ENABLE_NLS
222    setlocale(LC_ALL, "");
223    (void) textdomain("mondo");
224#endif
225    printf(_("Initializing..."));
226
227    /* Reference the right cleanup function for mr_exit */
228    mr_cleanup = &mr_ar_cleanup;
229
230    /* initialize log file with time stamp */
231    /* We start with a loglevel of 4 - Adapted later on */
232    /* It's mandatory to set this up first as all mr_ functions rely on it */
233    unlink(MONDO_LOGFILE);
234    mr_msg_init(MONDO_LOGFILE,4);
235    mr_msg(0, _("Time started: %s"), mr_date());
236
237    /* Make sure I'm root; abort if not */
238    if (getuid() != 0) {
239        mr_log_exit(127, _("Please run as root."));
240    }
241
242    /* If -V, -v or --version then echo version no. and quit */
243    if (argc == 2
244        && (!strcmp(argv[argc - 1], "-v") || !strcmp(argv[argc - 1], "-V")
245            || !strcmp(argv[argc - 1], "--version"))) {
246        printf(_("mondoarchive v%s\nSee man page for help\n"), PACKAGE_VERSION);
247        mr_exit(0, NULL);
248    }
249
250    /* Conf file management */
251    /* Check md5 sum before */
252    /* Get content */
253    if (mr_conf_open(MONDO_CONF_DIR"/mondo.conf.dist") != 0) {
254            mr_log_exit(-1, "Unable to open "MONDO_CONF_DIR"/mondo.conf.dist");
255    }
256    mr_ar_store_conf(&mr_conf);
257    mr_conf_close();
258
259    /* Add MONDO_SHARE + other environment variables for mindi */
260    setenv_mondo_var();
261
262    /* Initialize variables */
263    malloc_libmondo_global_strings();
264    diffs = 0;
265    bkpinfo = mr_malloc(sizeof(struct s_bkpinfo));
266    if (stat(MONDO_CACHE, &stbuf) != 0) {
267        mr_mkdir(MONDO_CACHE,0x755);
268    }
269
270    /* BERLIOS: Hardcoded to be improved */
271    unlink(MONDO_CACHE"/mindi.conf");
272    unlink(MONDORESTORECFG);
273
274    /* Configure the bkpinfo structure, global file paths, etc. */
275    g_main_pid = getpid();
276    mr_msg(9, "This");
277
278    register_pid(g_main_pid, "mondo");
279    set_signals(TRUE);          // catch SIGTERM, etc.
280    run_program_and_log_output("dmesg -n1", TRUE);
281
282    mr_msg(9, "Next");
283    welcome_to_mondoarchive();
284    distro_specific_kludges_at_start_of_mondoarchive();
285    g_kernel_version = get_kernel_version();
286
287    if (argc == 4 && !strcmp(argv[1], "getfattr")) {
288        g_loglevel = 10;
289        g_text_mode = TRUE;
290        setup_newt_stuff();
291        if (!strstr(argv[2], "filelist")) {
292            mr_msg(1,_("Sorry - filelist goes first\n"));
293            finish(1);
294        } else {
295            finish(get_fattr_list(argv[2], argv[3]));
296        }
297        finish(0);
298    }
299    if (argc == 4 && !strcmp(argv[1], "setfattr")) {
300        g_loglevel = 10;
301        g_text_mode = TRUE;
302        setup_newt_stuff();
303        finish(set_fattr_list(argv[2], argv[3]));
304    }
305
306    if (argc == 3 && !strcmp(argv[1], "wildcards")) {
307        g_loglevel = 10;
308        g_text_mode = TRUE;
309        setup_newt_stuff();
310        tmp = mr_stresc(argv[2], WILDCHARS, BACKSLASH);
311        printf("in=%s; out=%s\n", argv[2], tmp);
312        mr_free(tmp);
313        finish(1);
314    }
315
316    if (argc == 4 && !strcmp(argv[1], "getfacl")) {
317        g_loglevel = 10;
318        g_text_mode = TRUE;
319        setup_newt_stuff();
320        if (!strstr(argv[2], "filelist")) {
321            mr_msg(1,_("Sorry - filelist goes first\n"));
322            finish(1);
323        } else {
324            finish(get_acl_list(argv[2], argv[3]));
325        }
326        finish(0);
327    }
328    if (argc == 4 && !strcmp(argv[1], "setfacl")) {
329        g_loglevel = 10;
330        g_text_mode = TRUE;
331        setup_newt_stuff();
332        finish(set_acl_list(argv[2], argv[3]));
333    }
334
335    if (argc > 2 && !strcmp(argv[1], "find-cd")) {
336        g_loglevel = 10;
337        g_text_mode = TRUE;
338        setup_newt_stuff();
339        malloc_string(tmp);
340        if (find_cdrw_device(tmp)) {
341            mr_msg(1,_("Failed to find CDR-RW drive\n"));
342        } else {
343            mr_msg(1,_("CD-RW is at %s\n"), tmp);
344        }
345        tmp[0] = '\0';
346        if (find_cdrom_device(tmp, atoi(argv[2]))) {
347            mr_msg(1,_("Failed to find CD-ROM drive\n"));
348        } else {
349            mr_msg(1,_("CD-ROM is at %s\n"), tmp);
350        }
351        mr_free(tmp);
352        finish(0);
353    }
354
355    if (argc > 2 && !strcmp(argv[1], "find-dvd")) {
356        g_loglevel = 10;
357        g_text_mode = TRUE;
358        setup_newt_stuff();
359        malloc_string(tmp);
360        if (find_dvd_device(tmp, atoi(argv[2]))) {
361            mr_msg(1,_("Failed to find DVD drive\n"));
362        } else {
363            mr_msg(1,_("DVD is at %s\n"), tmp);
364        }
365        mr_free(tmp);
366        finish(0);
367    }
368
369    if (argc > 2 && !strcmp(argv[1], "disksize")) {
370        printf("%s --> %ld\n", argv[2], get_phys_size_of_drive(argv[2]));
371        finish(0);
372    }
373    if (argc > 2 && !strcmp(argv[1], "test-dev")) {
374        if (is_dev_an_NTFS_dev(argv[2])) {
375            mr_msg(1,_("%s is indeed an NTFS dev\n"), argv[2]);
376        } else {
377            mr_msg(1,_("%s is _not_ an NTFS dev\n"), argv[2]);
378        }
379        finish(0);
380    }
381
382    if (pre_param_configuration(bkpinfo)) {
383        fatal_error
384            ("Pre-param initialization phase failed. Please review the error messages above, make the specified changes, then try again. Exiting...");
385    }
386    sprintf(g_erase_tmpdir_and_scratchdir, "rm -Rf %s %s", bkpinfo->tmpdir,
387            bkpinfo->scratchdir);
388
389    /* Process command line, if there is one. If not, ask user for info. */
390    if (argc == 1) {
391        g_text_mode = FALSE;
392        setup_newt_stuff();
393        res = interactively_obtain_media_parameters_from_user(bkpinfo, TRUE);   /* yes, archiving */
394        if (res) {
395            fatal_error
396                ("Syntax error. Please review the parameters you have supplied and try again.");
397        }
398    } else {
399        res = handle_incoming_parameters(argc, argv, bkpinfo);
400        if (res) {
401            mr_msg(1,
402                _("Errors were detected in the command line you supplied.\n"));
403            mr_msg(1,_("Please review the log file - %s \n"),MONDO_LOGFILE);
404            mr_msg(1, "Mondoarchive will now exit.");
405            finish(1);
406        }
407        setup_newt_stuff();
408    }
409
410/* Finish configuring global structures */
411    if (post_param_configuration(bkpinfo)) {
412        fatal_error
413            ("Post-param initialization phase failed. Perhaps bad parameters were supplied to mondoarchive? Please review the documentation, error messages and logs. Exiting...");
414    }
415
416    log_to_screen
417        (_("BusyBox's sources are available from http://www.busybox.net"));
418
419    sprintf(g_erase_tmpdir_and_scratchdir, "rm -Rf %s %s", bkpinfo->tmpdir,
420            bkpinfo->scratchdir);
421
422    /* If we're meant to backup then backup */
423    if (bkpinfo->backup_data) {
424        res = backup_data(bkpinfo);
425        retval += res;
426        if (res) {
427            mr_strcat(say_at_end,
428                   _("Data archived. Please check the logs, just as a precaution. "));
429        } else {
430            mr_strcat(say_at_end, _("Data archived OK. "));
431        }
432    }
433
434    /* If we're meant to verify then verify */
435    if (bkpinfo->verify_data) {
436        res = verify_data(bkpinfo);
437        if (res < 0) {
438            mr_asprintf(&say_at_end2, _("%d difference%c found."), -res,
439                    (-res != 1) ? 's' : ' ');
440            res = 0;
441        }
442        retval += res;
443    }
444
445    /* Offer to write floppy disk images to physical disks */
446    if (bkpinfo->backup_data && !g_skip_floppies) {
447        res = offer_to_write_boot_floppies_to_physical_disks(bkpinfo);
448        retval += res;
449    }
450
451    /* Report result of entire operation (success? errors?) */
452    if (!retval) {
453        mvaddstr_and_log_it(g_currentY++, 0,
454                            _("Backup and/or verify ran to completion. Everything appears to be fine."));
455    } else {
456        mvaddstr_and_log_it(g_currentY++, 0,
457                            _("Backup and/or verify ran to completion. However, errors did occur."));
458    }
459
460    if (does_file_exist("/var/cache/mindi/mondorescue.iso")) {
461        log_to_screen
462            (_("/var/cache/mindi/mondorescue.iso, a boot/utility CD, is available if you want it."));
463    }
464
465
466    if (length_of_file("/tmp/changed.files") > 2) {
467        if (g_text_mode) {
468            log_to_screen
469                (_("Type 'less /tmp/changed.files' to see which files don't match the archives"));
470        } else {
471            mr_msg(1,
472                    _("Type 'less /tmp/changed.files' to see which files don't match the archives"));
473            mr_msg(2, "Calling popup_changelist_from_file()");
474            popup_changelist_from_file("/tmp/changed.files");
475            mr_msg(2, "Returned from popup_changelist_from_file()");
476        }
477    } else {
478        unlink("/tmp/changed.files");
479    }
480    log_to_screen(say_at_end);
481    mr_free(say_at_end);
482    if (say_at_end2 != NULL) {
483        log_to_screen(say_at_end2);
484        mr_free(say_at_end2);
485    }
486
487    mr_asprintf(&tmp, "umount %s/tmpfs", bkpinfo->tmpdir);
488    run_program_and_log_output(tmp, TRUE);
489    mr_free(tmp);
490    run_program_and_log_output(g_erase_tmpdir_and_scratchdir, TRUE);
491
492    run_program_and_log_output("mount", 2);
493
494    system("rm -f /var/cache/mondo-archive/last-backup.aborted");
495    system("rm -Rf /tmp.mondo.* /mondo.scratch.*");
496    if (!retval) {
497        printf(_("Mondoarchive ran OK.\n"));
498    } else {
499        printf(_("Errors occurred during backup. Please check logfile.\n"));
500    }
501    distro_specific_kludges_at_end_of_mondoarchive();
502    register_pid(0, "mondo");
503    set_signals(FALSE);
504    chdir("/tmp");              // just in case there's something wrong with g_erase_tmpdir_and_scratchdir
505    system(g_erase_tmpdir_and_scratchdir);
506    free_libmondo_global_strings();
507    mr_free(bkpinfo);
508
509    unlink("/tmp/filelist.full");
510    unlink("/tmp/filelist.full.gz");
511
512    if (!g_cdrom_drive_is_here) {
513        mr_msg(10, "FYI, g_cdrom_drive_is_here was never used");
514    }
515    if (!g_dvd_drive_is_here) {
516        mr_msg(10, "FYI, g_dvd_drive_is_here was never used");
517    }
518
519    /* finalize log file with time stamp */
520    mr_msg(1, "Time finished: %s", mr_date());
521    mr_msg_close();
522
523    if (!g_text_mode) {
524        popup_and_OK
525            (_("Mondo Archive has finished its run. Please press ENTER to return to the shell prompt."));
526        log_to_screen(_("See %s for details of backup run."), MONDO_LOGFILE);
527        finish(retval);
528    } else {
529        printf(_("See %s for details of backup run.\n"), MONDO_LOGFILE);
530        mr_exit(retval, NULL);
531    }
532
533    return EXIT_SUCCESS;
534}
Note: See TracBrowser for help on using the repository browser.