source: trunk/mondo/src/mondorestore/mondo-restore.c @ 932

Last change on this file since 932 was 932, checked in by bruno, 13 years ago

merge -r913:931 $SVN_M/branches/stable

  • Property svn:keywords set to Id
File size: 98.9 KB
Line 
1/***************************************************************************
2 * $Id: mondo-restore.c 932 2006-11-15 11:40:15Z bruno $
3 */
4
5/**
6 * @file
7 * The main file for mondorestore.
8 */
9
10/**************************************************************************
11 * #include statements                                                    *
12 **************************************************************************/
13#include <unistd.h>
14
15#include "my-stuff.h"
16#include "../common/mondostructures.h"
17#include "../common/libmondo.h"
18#include "mr-externs.h"
19#include "mondo-restore.h"
20#include "mondo-rstr-compare-EXT.h"
21#include "mondo-rstr-tools-EXT.h"
22#ifndef S_SPLINT_S
23#include <pthread.h>
24#endif
25#include "mr_mem.h"
26
27extern void twenty_seconds_til_yikes(void);
28
29
30/* For use in other programs (ex. XMondo) */
31#ifdef MONDORESTORE_MODULE
32#define main __mondorestore_main
33#define g_ISO_restore_mode __mondorestore_g_ISO_restore_mode
34#endif
35
36//static char cvsid[] = "$Id: mondo-restore.c 932 2006-11-15 11:40:15Z bruno $";
37
38/**************************************************************************
39 * Globals                                                                *
40 **************************************************************************/
41extern char *g_tmpfs_mountpt;   // declared in libmondo-tools.c
42extern struct s_bkpinfo *g_bkpinfo_DONTUSETHIS; // used by finish() to free
43                                                // up global bkpinfo struct
44extern bool g_text_mode;
45extern FILE *g_fprep;
46extern double g_kernel_version;
47extern int g_partition_table_locked_up;
48extern int g_noof_rows;
49
50extern int partition_everything(struct mountlist_itself *mountlist);
51
52
53/**
54 * @name Restore-Time Globals
55 * @ingroup globalGroup
56 * @{
57 */
58/**
59 * If TRUE, then SIGPIPE was just caught.
60 * Set by the signal handler; cleared after it's handled.
61 */
62bool g_sigpipe_caught = FALSE;
63
64/**
65 * If TRUE, then we're restoring from ISOs or an NFS server.
66 * If FALSE, then we're restoring from some kind of real media (tape, CD, etc.)
67 */
68bool g_ISO_restore_mode = FALSE;    /* are we in Iso Mode? */
69
70/**
71 * If TRUE, then we have had a successful "nuke" restore.
72 */
73bool g_I_have_just_nuked = FALSE;
74
75/**
76 * The device to mount to get at the ISO images. Ignored unless @p g_ISO_restore_mode.
77 */
78char *g_isodir_device = NULL;
79
80/**
81 * The format of @p g_isodir_device. Ignored unless @p g_ISO_restore_mode.
82 */
83char *g_isodir_format = NULL;
84
85/**
86 * The location of 'biggielist.txt', containing the biggiefiles on the current archive set.
87 */
88char *g_biggielist_txt = NULL;
89
90/**
91 * The location of 'filelist.full', containing all files (<em>including biggiefiles</em>) on
92 * the current archive set.
93 */
94char *g_filelist_full = NULL;
95
96/**
97 * The location of a file containing a list of the devices that were archived
98 * as images, not as individual files.
99 */
100char *g_filelist_imagedevs = NULL;
101
102/**
103 * The location of a file containing a list of imagedevs to actually restore.
104 * @see g_filelist_imagedevs
105 */
106char *g_imagedevs_restthese = NULL;
107
108/**
109 * The location of 'mondo-restore.cfg', containing the metadata
110 * information for this backup.
111 */
112char *g_mondo_cfg_file = NULL;
113
114/**
115 * The location of 'mountlist.txt', containing the information on the
116 * user's partitions and hard drives.
117 */
118char *g_mountlist_fname = NULL;
119
120/**
121 * Mondo's home directory during backup. Unused in mondo-restore; included
122 * to avoid link errors.
123 */
124char *g_mondo_home = NULL;
125
126/* Busybox ps has no option and PID in first pos */
127char *ps_options = "";
128char *ps_proc_id = "$1";
129
130/* @} - end of "Restore-Time Globals" in globalGroup */
131
132extern int copy_from_src_to_dest(FILE * f_orig, FILE * f_archived,
133                                 char direction);
134
135/**************************************************************************
136 * COMPAQ PROLIANT Stuff:  needs some special help                        *
137**************************************************************************/
138
139/**
140 * The message to display if we detect that the user is using a Compaq Proliant.
141 */
142#define COMPAQ_PROLIANTS_SUCK _("Partition and format your disk using Compaq's disaster recovery CD. After you've done that, please reboot with your Mondo CD/floppy in Interactive Mode.")
143
144
145/**
146 * Allow the user to modify the mountlist before we partition & format their drives.
147 * @param bkpinfo The backup information structure. @c disaster_recovery is the only field used.
148 * @param mountlist The mountlist to let the user modify.
149 * @param raidlist The raidlist that goes with @p mountlist.
150 * @return 0 for success, nonzero for failure.
151 * @ingroup restoreGuiGroup
152 */
153int let_user_edit_the_mountlist(struct s_bkpinfo *bkpinfo,
154                                struct mountlist_itself *mountlist,
155                                struct raidlist_itself *raidlist)
156{
157    int retval = 0, res = 0;
158
159    log_msg(2, "let_user_edit_the_mountlist() --- starting");
160
161    assert(bkpinfo != NULL);
162    assert(mountlist != NULL);
163    assert(raidlist != NULL);
164    if (!bkpinfo->disaster_recovery) {
165        mr_allocstr(g_mountlist_fname, "/tmp/mountlist.txt");
166        log_msg(2, "I guess you're testing edit_mountlist()");
167    }
168    if (!does_file_exist(g_mountlist_fname)) {
169        log_to_screen(g_mountlist_fname);
170        log_to_screen(_("does not exist"));
171        return (1);
172    }
173
174    retval = load_mountlist(mountlist, g_mountlist_fname);
175    load_raidtab_into_raidlist(raidlist, RAIDTAB_FNAME);
176    if (retval) {
177        log_to_screen
178            (_("Warning - load_raidtab_into_raidlist returned an error"));
179    }
180    res = edit_mountlist(g_mountlist_fname, mountlist, raidlist);
181    if (res) {
182        return (1);
183    }
184
185    save_mountlist_to_disk(mountlist, g_mountlist_fname);
186    save_raidlist_to_raidtab(raidlist, RAIDTAB_FNAME);
187
188    log_to_screen(_("I have finished editing the mountlist for you."));
189
190    return (retval);
191}
192
193
194/**
195 * Determine whether @p mountlist contains a Compaq diagnostic partition.
196 * @param mountlist The mountlist to examine.
197 * @return TRUE if there's a Compaq diagnostic partition; FALSE if not.
198 * @ingroup restoreUtilityGroup
199 */
200bool
201partition_table_contains_Compaq_diagnostic_partition(struct
202                                                     mountlist_itself *
203                                                     mountlist)
204{
205    int i;
206
207    assert(mountlist != NULL);
208
209    for (i = 0; i < mountlist->entries; i++) {
210        if (strstr(mountlist->el[i].format, "ompaq")) {
211            log_msg(2, "mountlist[%d] (%s) is %s (Compaq alert!)",
212                    i, mountlist->el[i].device, mountlist->el[i].format);
213
214            return (TRUE);
215        }
216    }
217    return (FALSE);
218}
219
220/**************************************************************************
221 *END_PARTITION_TABLE_CONTAINS_COMPAQ_DIAGNOSTIC_PARTITION                *
222 **************************************************************************/
223
224
225/**
226 * Allow the user to abort the backup if we find that there is a Compaq diagnostic partition.
227 * @note This function does not actually check for the presence of a Compaq partition.
228 * @ingroup restoreUtilityGroup
229 */
230void offer_to_abort_because_Compaq_Proliants_suck(void)
231{
232    popup_and_OK(COMPAQ_PROLIANTS_SUCK);
233    if (ask_me_yes_or_no
234        (_
235         ("Would you like to reboot and use your Compaq CD to prep your hard drive?")))
236    {
237        fatal_error(_
238                    ("Aborting. Please reboot and prep your hard drive with your Compaq CD."));
239    }
240}
241
242/**************************************************************************
243 *END_OFFER_TO_ABORT_BECAUSE_COMPAQ_PROLIANTS_SUCK                        *
244 **************************************************************************/
245
246
247/**
248 * Call interactive_mode(), nuke_mode(), or compare_mode() depending on the user's choice.
249 * @param bkpinfo The backup information structure. Most fields are used.
250 * @param mountlist The mountlist containing information about the user's partitions.
251 * @param raidlist The raidlist to go with @p mountlist.
252 * @return The return code from the mode function called.
253 * @ingroup restoreGroup
254 */
255int
256catchall_mode(struct s_bkpinfo *bkpinfo,
257              struct mountlist_itself *mountlist,
258              struct raidlist_itself *raidlist)
259{
260    char c, *tmp;
261    int retval = 0;
262
263    iamhere("inside catchall");
264    assert(bkpinfo != NULL);
265    assert(mountlist != NULL);
266    assert(raidlist != NULL);
267    iamhere("pre wrm");
268    c = which_restore_mode();
269    iamhere("post wrm");
270    if (c == 'I' || c == 'N' || c == 'C') {
271        interactively_obtain_media_parameters_from_user(bkpinfo, FALSE);
272    } else {
273        popup_and_OK(_
274                     ("No restoring or comparing will take place today."));
275        if (is_this_device_mounted("/mnt/cdrom")) {
276            run_program_and_log_output("umount /mnt/cdrom", FALSE);
277        }
278        if (g_ISO_restore_mode) {
279            mr_asprintf(&tmp, "umount %s", bkpinfo->isodir);
280            run_program_and_log_output(tmp, FALSE);
281            mr_free(tmp);
282        }
283        paranoid_MR_finish(0);
284    }
285
286    iamhere("post int");
287
288    if (bkpinfo->backup_media_type == iso) {
289        if (iso_fiddly_bits(bkpinfo, (c == 'N') ? TRUE : FALSE)) {
290            log_msg(2,
291                    "catchall_mode --- iso_fiddly_bits returned w/ error");
292            return (1);
293        } else {
294            log_msg(2, "catchall_mode --- iso_fiddly_bits ok");
295        }
296    }
297
298    if (c == 'I') {
299        log_msg(2, "IM selected");
300        retval += interactive_mode(bkpinfo, mountlist, raidlist);
301    } else if (c == 'N') {
302        log_msg(2, "NM selected");
303        retval += nuke_mode(bkpinfo, mountlist, raidlist);
304    } else if (c == 'C') {
305        log_msg(2, "CM selected");
306        retval += compare_mode(bkpinfo, mountlist, raidlist);
307    }
308    return (retval);
309}
310
311/**************************************************************************
312 *END_CATCHALL_MODE                                                      *
313 **************************************************************************/
314
315/**************************************************************************
316 *END_  EXTRACT_CONFIG_FILE_FROM_RAMDISK                                  *
317 **************************************************************************/
318
319
320/**
321 * @addtogroup restoreGroup
322 * @{
323 */
324/**
325 * Restore the user's data, in a disaster recovery situation, prompting the
326 * user about whether or not to do every step.
327 * The user can edit the mountlist, choose files to restore, etc.
328 * @param bkpinfo The backup information structure. Most fields are used.
329 * @param mountlist The mountlist containing information about the user's partitions.
330 * @param raidlist The raidlist to go with @p mountlist.
331 * @return 0 for success, or the number of errors encountered.
332 */
333int
334interactive_mode(struct s_bkpinfo *bkpinfo,
335                 struct mountlist_itself *mountlist,
336                 struct raidlist_itself *raidlist)
337{
338    int retval = 0;
339    int res;
340    int ptn_errs = 0;
341    int fmt_errs = 0;
342
343    bool done;
344    bool restore_all;
345
346    char *tmp = NULL;
347    char *tmp1 = NULL;
348    char *fstab_fname = NULL;
349    char *old_restpath = NULL;
350
351    struct s_node *filelist = NULL;
352
353    /* try to partition and format */
354
355    log_msg(2, "interactive_mode --- starting (great, assertions OK)");
356
357    assert(bkpinfo != NULL);
358    assert(mountlist != NULL);
359    assert(raidlist != NULL);
360
361    log_msg(2, "interactive_mode --- assertions OK");
362
363    if (g_text_mode) {
364        if (!ask_me_yes_or_no
365            (_
366             ("Interactive Mode + textonly = experimental! Proceed anyway?")))
367        {
368            fatal_error("Wise move.");
369        }
370    }
371
372    iamhere("About to load config file");
373    get_cfg_file_from_archive_or_bust(bkpinfo);
374    read_cfg_file_into_bkpinfo(g_mondo_cfg_file, bkpinfo);
375    iamhere("Done loading config file; resizing ML");
376#ifdef __FreeBSD__
377    tmp = call_program_and_get_last_line_of_output("cat /tmp/cmdline");
378#else
379    tmp = call_program_and_get_last_line_of_output("cat /proc/cmdline");
380#endif
381    if (strstr(tmp,"noresize")) {
382        log_msg(1, "Not resizing mountlist.");
383    } else {
384        resize_mountlist_proportionately_to_suit_new_drives(mountlist);
385    }
386    for (done = FALSE; !done;) {
387        iamhere("About to edit mountlist");
388        if (g_text_mode) {
389            save_mountlist_to_disk(mountlist, g_mountlist_fname);
390            tmp1 = find_my_editor();
391            mr_asprintf(&tmp, "%s %s", tmp1, g_mountlist_fname);
392            mr_free(tmp1);
393
394            res = system(tmp);
395            mr_free(tmp);
396            load_mountlist(mountlist, g_mountlist_fname);
397        } else {
398            res = edit_mountlist(g_mountlist_fname, mountlist, raidlist);
399        }
400        iamhere("Finished editing mountlist");
401        if (res) {
402            paranoid_MR_finish(1);
403        }
404        log_msg(2, "Proceeding...");
405        save_mountlist_to_disk(mountlist, g_mountlist_fname);
406        save_raidlist_to_raidtab(raidlist, RAIDTAB_FNAME);
407        mvaddstr_and_log_it(1, 30, _("Restoring Interactively"));
408        if (bkpinfo->differential) {
409            log_to_screen(_
410                          ("Because this is a differential backup, disk"));
411            log_to_screen(_
412                          (" partitioning and formatting will not take place."));
413            done = TRUE;
414        } else {
415            if (ask_me_yes_or_no
416                (_
417                 ("Do you want to erase and partition your hard drives?")))
418            {
419                if (partition_table_contains_Compaq_diagnostic_partition
420                    (mountlist)) {
421                    offer_to_abort_because_Compaq_Proliants_suck();
422                    done = TRUE;
423                } else {
424                    twenty_seconds_til_yikes();
425                    g_fprep = fopen("/tmp/prep.sh", "w");
426                    ptn_errs = partition_everything(mountlist);
427                    if (ptn_errs) {
428                        log_to_screen
429                            (_
430                             ("Warning. Errors occurred during disk partitioning."));
431                    }
432
433                    fmt_errs =
434                        format_everything(mountlist, FALSE, raidlist);
435                    if (!fmt_errs) {
436                        log_to_screen
437                            (_
438                             ("Errors during disk partitioning were handled OK."));
439                        log_to_screen(_
440                                      ("Partitions were formatted OK despite those errors."));
441                        ptn_errs = 0;
442                    }
443                    if (!ptn_errs && !fmt_errs) {
444                        done = TRUE;
445                    }
446                }
447                paranoid_fclose(g_fprep);
448            } else {
449                mvaddstr_and_log_it(g_currentY++, 0,
450                                    _
451                                    ("User opted not to partition the devices"));
452                if (ask_me_yes_or_no
453                    (_("Do you want to format your hard drives?"))) {
454                    fmt_errs =
455                        format_everything(mountlist, TRUE, raidlist);
456                    if (!fmt_errs) {
457                        done = TRUE;
458                    }
459                } else {
460                    ptn_errs = fmt_errs = 0;
461                    done = TRUE;
462                }
463            }
464            if (fmt_errs) {
465                mvaddstr_and_log_it(g_currentY++,
466                                    0,
467                                    _
468                                    ("Errors occurred. Please repartition and format drives manually."));
469                done = FALSE;
470            }
471            if (ptn_errs & !fmt_errs) {
472                mvaddstr_and_log_it(g_currentY++,
473                                    0,
474                                    _
475                                    ("Errors occurred during partitioning. Formatting, however, went OK."));
476                done = TRUE;
477            }
478            if (!done) {
479                if (!ask_me_yes_or_no(_("Re-edit the mountlist?"))) {
480                    retval++;
481                    iamhere("Leaving interactive_mode()");
482                    return (retval);
483                }
484            }
485        }
486    }
487
488    /* mount */
489    if (mount_all_devices(mountlist, TRUE)) {
490        unmount_all_devices(mountlist);
491        retval++;
492        iamhere("Leaving interactive_mode()");
493        return (retval);
494    }
495    /* restore */
496    if ((restore_all =
497         ask_me_yes_or_no(_
498                          ("Do you want me to restore all of your data?"))))
499    {
500        log_msg(1, "Restoring all data");
501        retval += restore_everything(bkpinfo, NULL);
502    } else if ((restore_all =
503             ask_me_yes_or_no
504             (_("Do you want me to restore _some_ of your data?")))) {
505        mr_asprintf(&old_restpath,bkpinfo->restore_path);
506        for (done = FALSE; !done;) {
507            unlink("/tmp/filelist.full");
508            filelist = process_filelist_and_biggielist(bkpinfo);
509            /* Now you have /tmp/tmpfs/filelist.restore-these and /tmp/tmpfs/biggielist.restore-these;
510               the former is a list of regular files; the latter, biggiefiles and imagedevs.
511             */
512            if (filelist) {
513              gotos_suck:
514// (NB: %s is where your filesystem is mounted now, by default)", MNT_RESTORING);
515                if (popup_and_get_string
516                    (_("Restore path"), _("Restore files to where?"), bkpinfo->restore_path)) {
517                    if (!strcmp(bkpinfo->restore_path, "/")) {
518                        if (!ask_me_yes_or_no(_("Are you sure?"))) {
519                            mr_allocstr(bkpinfo->restore_path, old_restpath);
520                            goto gotos_suck;
521                        }
522                        mr_allocstr(bkpinfo->restore_path, ""); // so we restore to [blank]/file/name :)
523                    }
524                    log_msg(1, "Restoring subset");
525                    retval += restore_everything(bkpinfo, filelist);
526                    free_filelist(filelist);
527                } else {
528                    mr_allocstr(bkpinfo->restore_path,old_restpath);
529                    free_filelist(filelist);
530                }
531                if (!ask_me_yes_or_no
532                    (_("Restore another subset of your backup?"))) {
533                    done = TRUE;
534                }
535            } else {
536                done = TRUE;
537            }
538        }
539        mr_free(old_restpath);
540    } else {
541        mvaddstr_and_log_it(g_currentY++,
542                            0,
543                            _
544                            ("User opted not to restore any data.                                  "));
545    }
546    if (retval) {
547        mvaddstr_and_log_it(g_currentY++,
548                            0,
549                            _
550                            ("Errors occurred during the restore phase.            "));
551    }
552
553    if (ask_me_yes_or_no(_("Initialize the boot loader?"))) {
554        run_boot_loader(TRUE);
555    } else {
556        mvaddstr_and_log_it(g_currentY++,
557                            0,
558                            _
559                            ("User opted not to initialize the boot loader."));
560    }
561
562//  run_program_and_log_output("cp -af /etc/lvm " MNT_RESTORING "/etc/", 1);
563    protect_against_braindead_sysadmins();
564    retval += unmount_all_devices(mountlist);
565    /*  if (restore_some || restore_all || */
566    if (ask_me_yes_or_no
567        (_("Label your ext2 and ext3 partitions if necessary?"))) {
568        mvaddstr_and_log_it(g_currentY, 0,
569                            _
570                            ("Using e2label to label your ext2,3 partitions"));
571        if (does_file_exist("/tmp/fstab.new")) {
572            mr_asprintf(&fstab_fname, "/tmp/fstab.new");
573        } else {
574            mr_asprintf(&fstab_fname, "/tmp/fstab");
575        }
576        mr_asprintf(&tmp,
577                "label-partitions-as-necessary %s < %s >> %s 2>> %s",
578                g_mountlist_fname, fstab_fname, MONDO_LOGFILE,
579                MONDO_LOGFILE);
580        mr_free(fstab_fname);
581
582        res = system(tmp);
583        mr_free(tmp);
584        if (res) {
585            log_to_screen
586                (_("label-partitions-as-necessary returned an error"));
587            mvaddstr_and_log_it(g_currentY++, 74, _("Failed."));
588        } else {
589            mvaddstr_and_log_it(g_currentY++, 74, "Done.");
590        }
591        retval += res;
592    }
593
594    iamhere("About to leave interactive_mode()");
595    if (retval) {
596        mvaddstr_and_log_it(g_currentY++,
597                            0,
598                            _
599                            ("Warning - errors occurred during the restore phase."));
600    }
601    return(retval);
602}
603
604/**************************************************************************
605 *END_INTERACTIVE_MODE                                                    *
606 **************************************************************************/
607
608
609/**
610 * Run an arbitrary restore mode (prompt the user), but from ISO images
611 * instead of real media.
612 * @param bkpinfo The backup information structure. Most fields are used.
613 * @param mountlist The mountlist containing information about the user's partitions.
614 * @param raidlist The raidlist that goes with @p mountlist.
615 * @param nuke_me_please If TRUE, we plan to run Nuke Mode.
616 * @return 0 for success, or the number of errors encountered.
617 */
618int
619iso_mode(struct s_bkpinfo *bkpinfo,
620         struct mountlist_itself *mountlist,
621         struct raidlist_itself *raidlist, bool nuke_me_please)
622{
623    char c;
624    int retval = 0;
625
626    assert(bkpinfo != NULL);
627    assert(mountlist != NULL);
628    assert(raidlist != NULL);
629    if (iso_fiddly_bits(bkpinfo, nuke_me_please)) {
630        log_msg(1, "iso_mode --- returning w/ error");
631        return (1);
632    } else {
633        c = which_restore_mode();
634        if (c == 'I' || c == 'N' || c == 'C') {
635            interactively_obtain_media_parameters_from_user(bkpinfo,
636                                                            FALSE);
637        }
638        if (c == 'I') {
639            retval += interactive_mode(bkpinfo, mountlist, raidlist);
640        } else if (c == 'N') {
641            retval += nuke_mode(bkpinfo, mountlist, raidlist);
642        } else if (c == 'C') {
643            retval += compare_mode(bkpinfo, mountlist, raidlist);
644        } else {
645            log_to_screen(_("OK, I shan't restore/compare any files."));
646        }
647    }
648    if (is_this_device_mounted(MNT_CDROM)) {
649        paranoid_system("umount " MNT_CDROM);
650    }
651//  if (! already_mounted)
652//    {
653    if (system("umount /tmp/isodir 2> /dev/null")) {
654        log_to_screen
655            (_
656             ("WARNING - unable to unmount device where the ISO files are stored."));
657    }
658//    }
659    return (retval);
660}
661
662/**************************************************************************
663 *END_ISO_MODE                                                            *
664 **************************************************************************/
665
666
667static void call_me_after_the_nuke(int retval) {
668
669    char *tmp = NULL;
670    char *tmp1 = NULL;
671
672    if (retval) {
673        log_to_screen(_("Errors occurred during the nuke phase."));
674        log_to_screen(_("Please visit our website at http://www.mondorescue.org for more information."));
675    } else {
676#ifdef __FreeBSD__
677        tmp1 = call_program_and_get_last_line_of_output("cat /tmp/cmdline");
678#else
679        tmp1 = call_program_and_get_last_line_of_output("cat /proc/cmdline");
680#endif
681        if ((strstr(tmp1,"restore") == NULL) ||
682            (strstr(tmp1,"RESTORE") == NULL)) {
683                /* -H option */
684                mr_asprintf(&tmp,
685                    _
686                    (" Mondo has restored your system. Please remove the backup media and reboot.\n\nPlease visit our website at http://www.mondorescue.org for more information."));
687                popup_and_OK(tmp);
688                mr_free(tmp);
689        }
690        mr_free(tmp1);
691
692        log_to_screen(_
693             ("Mondo has restored your system. Please remove the backup media and reboot."));
694        log_to_screen(_
695             ("Thank you for using Mondo Rescue."));
696        log_to_screen(_
697             ("Please visit our website at http://www.mondorescue.org for more information."));
698    }
699    g_I_have_just_nuked = TRUE;
700    return;
701}
702
703
704/**
705 * Restore the user's data automatically (no prompts), after a twenty-second
706 * warning period.
707 * @param bkpinfo The backup information structure. Most fields are used.
708 * @param mountlist The mountlist containing information about the user's partitions.
709 * @param raidlist The raidlist that goes with @p mountlist.
710 * @return 0 for success, or the number of errors encountered.
711 * @warning <b><i>THIS WILL ERASE ALL EXISTING DATA!</i></b>
712 */
713int
714nuke_mode(struct s_bkpinfo *bkpinfo,
715          struct mountlist_itself *mountlist,
716          struct raidlist_itself *raidlist)
717{
718    int retval = 0;
719    int res = 0;
720    bool boot_loader_installed = FALSE;
721    char *tmp = NULL;
722    char *tmpA = NULL;
723    char *tmpB = NULL;
724    char *tmpC = NULL;
725
726    assert(bkpinfo != NULL);
727    assert(mountlist != NULL);
728    assert(raidlist != NULL);
729
730    log_msg(2, "nuke_mode --- starting");
731
732    get_cfg_file_from_archive_or_bust(bkpinfo);
733    load_mountlist(mountlist, g_mountlist_fname);   // in case read_cfg_file_into_bkpinfo updated the mountlist
734#ifdef __FreeBSD__
735    tmp = call_program_and_get_last_line_of_output("cat /tmp/cmdline");
736#else
737    tmp = call_program_and_get_last_line_of_output("cat /proc/cmdline");
738#endif
739    if (strstr(tmp,"noresize")) {
740        log_msg(2, "Not resizing mountlist.");
741    } else {
742        resize_mountlist_proportionately_to_suit_new_drives(mountlist);
743    }
744    mr_free(tmp);
745
746    if (!evaluate_mountlist(mountlist, tmpA, tmpB, tmpC)) {
747        mr_asprintf(&tmp,
748                _
749                ("Mountlist analyzed. Result: \"%s %s %s\" Switch to Interactive Mode?"),
750                tmpA, tmpB, tmpC);
751        if (ask_me_yes_or_no(tmp)) {
752            mr_free(tmp);
753            retval = interactive_mode(bkpinfo, mountlist, raidlist);
754            goto after_the_nuke;
755        } else {
756            mr_free(tmp);
757            fatal_error("Nuke Mode aborted. ");
758        }
759    }
760    save_mountlist_to_disk(mountlist, g_mountlist_fname);
761    mvaddstr_and_log_it(1, 30, _("Restoring Automatically"));
762    if (bkpinfo->differential) {
763        log_to_screen(_("Because this is a differential backup, disk"));
764        log_to_screen(_
765                      ("partitioning and formatting will not take place."));
766        res = 0;
767    } else {
768        if (partition_table_contains_Compaq_diagnostic_partition
769            (mountlist)) {
770            offer_to_abort_because_Compaq_Proliants_suck();
771        } else {
772            twenty_seconds_til_yikes();
773            g_fprep = fopen("/tmp/prep.sh", "w");
774#ifdef __FreeBSD__
775            tmp = call_program_and_get_last_line_of_output("cat /tmp/cmdline");
776#else
777            tmp = call_program_and_get_last_line_of_output("cat /proc/cmdline");
778#endif
779            if (strstr(tmp,"nopart")) {
780                log_msg(2,
781                        "Not partitioning drives due to 'nopart' option.");
782                res = 0;
783            } else {
784                res = partition_everything(mountlist);
785                if (res) {
786                    log_to_screen
787                        (_
788                         ("Warning. Errors occurred during partitioning."));
789                    res = 0;
790                }
791            }
792            mr_free(tmp);
793
794            retval += res;
795            if (!res) {
796                log_to_screen(_("Preparing to format your disk(s)"));
797                sleep(1);
798                sync();
799                log_to_screen(_
800                              ("Please wait. This may take a few minutes."));
801                res += format_everything(mountlist, FALSE, raidlist);
802            }
803            paranoid_fclose(g_fprep);
804        }
805    }
806    retval += res;
807    if (res) {
808        mvaddstr_and_log_it(g_currentY++,
809                            0,
810                            _
811                            ("Failed to partition and/or format your hard drives."));
812
813        if (ask_me_yes_or_no(_("Try in interactive mode instead?"))) {
814            retval = interactive_mode(bkpinfo, mountlist, raidlist);
815            call_me_after_the_nuke(retval);
816        } else
817            if (!ask_me_yes_or_no
818                (_("Would you like to try to proceed anyway?"))) {
819        }
820        return(retval);
821    }
822    retval = mount_all_devices(mountlist, TRUE);
823    if (retval) {
824        unmount_all_devices(mountlist);
825        log_to_screen
826            (_
827             ("Unable to mount all partitions. Sorry, I cannot proceed."));
828        return (retval);
829    }
830    iamhere("Restoring everything");
831    retval += restore_everything(bkpinfo, NULL);
832    if (!run_boot_loader(FALSE)) {
833        log_msg(1,
834                "Great! Boot loader was installed. No need for msg at end.");
835        boot_loader_installed = TRUE;
836    }
837    protect_against_braindead_sysadmins();
838//  run_program_and_log_output("cp -af /etc/lvm " MNT_RESTORING "/etc/", 1);
839    retval += unmount_all_devices(mountlist);
840    mvaddstr_and_log_it(g_currentY,
841                        0,
842                        _
843                        ("Using e2label to label your ext2,3 partitions"));
844
845    mr_asprintf(&tmp, "label-partitions-as-necessary %s < /tmp/fstab",
846            g_mountlist_fname);
847    res = run_program_and_log_output(tmp, TRUE);
848    mr_free(tmp);
849
850    if (res) {
851        log_to_screen(_
852                      ("label-partitions-as-necessary returned an error"));
853        mvaddstr_and_log_it(g_currentY++, 74, _("Failed."));
854    } else {
855        mvaddstr_and_log_it(g_currentY++, 74, _("Done."));
856    }
857    retval += res;
858
859  after_the_nuke:
860    if (retval) {
861        log_to_screen("Errors occurred during the nuke phase.");
862    } else if (strstr(call_program_and_get_last_line_of_output("cat /proc/cmdline"), "RESTORE"))    // Bruno's thing
863    {
864        log_to_screen
865            ("PC was restored successfully. Thank you for using Mondo Rescue.");
866        log_to_screen
867            ("Please visit our website at http://www.mondorescue.org for more information.");
868    } else {
869        strcpy(tmp,"Mondo has restored your system.\n\nPlease wait for the command prompt. Then remove the backup media and reboot.\n\nPlease visit our website at http://www.mondorescue.org for more information.");
870        if (strstr(call_program_and_get_last_line_of_output("cat /proc/cmdline"), "restore") == NULL) {
871            popup_and_OK(tmp);
872        }
873        log_to_screen
874          ("Mondo has restored your system. Please wait for the command prompt.");
875        log_to_screen
876            ("Then remove the backup media and reboot.");
877        log_to_screen
878            ("Please visit our website at http://www.mondorescue.org for more information.");
879    }
880    g_I_have_just_nuked = TRUE;
881/*
882  if (!boot_loader_installed && !does_file_exist(DO_MBR_PLEASE))
883    {
884      log_to_screen("PLEASE RUN 'mondorestore --mbr' NOW TO INITIALIZE YOUR BOOT SECTOR");
885      write_one_liner_data_file(DO_MBR_PLEASE, "mondorestore --mbr");
886    }
887*/
888    return (retval);
889}
890/**************************************************************************
891 *END_NUKE_MODE                                                           *
892 **************************************************************************/
893
894
895/**
896 * Restore the user's data (or a subset of it) to the live filesystem.
897 * This should not be called if we're booted from CD!
898 * @param bkpinfo The backup information structure. Most fields are used.
899 * @return 0 for success, or the number of errors encountered.
900 */
901int restore_to_live_filesystem(struct s_bkpinfo *bkpinfo)
902{
903    int retval = 0;
904
905    char *old_restpath = NULL;
906
907    struct mountlist_itself *mountlist = NULL;
908    struct raidlist_itself *raidlist = NULL;
909    struct s_node *filelist = NULL;
910
911    log_msg(1, "restore_to_live_filesystem() - starting");
912    assert(bkpinfo != NULL);
913
914    mountlist = malloc(sizeof(struct mountlist_itself));
915    raidlist = malloc(sizeof(struct raidlist_itself));
916
917    if (!mountlist || !raidlist) {
918        fatal_error("Cannot malloc() mountlist and/or raidlist");
919    }
920
921    mr_allocstr(bkpinfo->restore_path, "/");
922    if (!g_restoring_live_from_cd) {
923        popup_and_OK
924            (_
925             ("Please insert tape/CD/boot floppy, then hit 'OK' to continue."));
926        sleep(1);
927    }
928    interactively_obtain_media_parameters_from_user(bkpinfo, FALSE);
929    if (bkpinfo->media_device == NULL) {
930        log_msg(2, "Warning - failed to find media dev");
931    } else {
932        log_msg(2, "bkpinfo->media_device = %s", bkpinfo->media_device);
933    }
934
935
936    log_msg(2, "bkpinfo->isodir = %s", bkpinfo->isodir);
937
938    open_evalcall_form(_("Thinking..."));
939
940    get_cfg_file_from_archive_or_bust(bkpinfo);
941    read_cfg_file_into_bkpinfo(g_mondo_cfg_file, bkpinfo);
942    load_mountlist(mountlist, g_mountlist_fname);   // in case read_cfg_file_into_bkpinfo
943
944    close_evalcall_form();
945    retval = load_mountlist(mountlist, g_mountlist_fname);
946    load_raidtab_into_raidlist(raidlist, RAIDTAB_FNAME);
947    filelist = process_filelist_and_biggielist(bkpinfo);
948    if (filelist) {
949        save_filelist(filelist, "/tmp/selected-files.txt");
950        mr_asprintf(&old_restpath,bkpinfo->restore_path);
951        if (popup_and_get_string(_("Restore path"),
952                                 _("Restore files to where? )"),
953                                 bkpinfo->restore_path)) {
954            iamhere("Restoring everything");
955            retval += restore_everything(bkpinfo, filelist);
956        }
957        free_filelist(filelist);
958        mr_allocstr(bkpinfo->restore_path,old_restpath);
959    }
960    if (IS_THIS_A_STREAMING_BACKUP(bkpinfo->backup_media_type)) {
961        log_msg(2,
962                "I probably don't need to unmount or eject the CD-ROM but I'm doing it anyway.");
963    }
964    run_program_and_log_output("umount " MNT_CDROM, FALSE);
965    if ((!bkpinfo->please_dont_eject) && (bkpinfo->media_device != NULL)) {
966        eject_device(bkpinfo->media_device);
967    }
968    free(mountlist);
969    free(raidlist);
970    return (retval);
971}
972
973/**************************************************************************
974 *END_RESTORE_TO_LIVE_FILESYSTEM                                          *
975 **************************************************************************/
976
977/* @} - end of restoreGroup */
978
979
980#include <utime.h>
981/**
982 * @addtogroup LLrestoreGroup
983 * @{
984 */
985/**
986 * Restore biggiefile @p bigfileno from the currently mounted CD.
987 * @param bkpinfo The backup information structure. Fields used:
988 * - @c bkpinfo->backup_media_type
989 * - @c bkpinfo->restore_path
990 * @param bigfileno The biggiefile number (starting from 0) to restore.
991 * @param filelist The node structure containing the list of files to restore.
992 * If the biggiefile is not in this list, it will be skipped (return value will
993 * still indicate success).
994 * @return 0 for success (or skip), nonzero for failure.
995 */
996char *
997restore_a_biggiefile_from_CD(struct s_bkpinfo *bkpinfo,
998                             long bigfileno,
999                             struct s_node *filelist)
1000{
1001    FILE *fin = NULL;
1002    FILE *fout = NULL;
1003    FILE *fbzip2 = NULL;
1004    char *checksum = NULL;
1005    char *outfile_fname = NULL;
1006    char *tmp = NULL;
1007    char *tmp1 = NULL;
1008    char *tmp2 = NULL;
1009    char *tmp3 = NULL;
1010    char *bzip2_command = NULL;
1011    char *bigblk = NULL;
1012    char *pathname_of_last_file_restored = NULL;
1013    int finished = FALSE;
1014    long sliceno;
1015    long siz;
1016    long siz1;
1017    char *ntfsprog_fifo = NULL;
1018    char *file_to_openout = NULL;
1019    struct s_filename_and_lstat_info biggiestruct;
1020    struct utimbuf the_utime_buf, *ubuf = NULL;
1021    bool use_ntfsprog_hack = FALSE;
1022    pid_t pid;
1023    int res = 0;
1024    int old_loglevel;
1025    char *sz_msg;
1026    struct s_node *node = NULL;
1027
1028    old_loglevel = g_loglevel;
1029    ubuf = &the_utime_buf;
1030    assert(bkpinfo != NULL);
1031
1032    if (!(bigblk = malloc(TAPE_BLOCK_SIZE))) {
1033        fatal_error("Cannot malloc bigblk");
1034    }
1035
1036    tmp = slice_fname(bigfileno, 0, ARCHIVES_PATH, "");
1037    if (!(fin = fopen(tmp,"r"))) {
1038        log_to_screen(_("Cannot even open bigfile's info file"));
1039        mr_free(tmp);
1040        return (pathname_of_last_file_restored);
1041    }
1042    mr_free(tmp);
1043
1044    memset((void *) &biggiestruct, 0, sizeof(biggiestruct));
1045    if (fread((void *) &biggiestruct, 1, sizeof(biggiestruct), fin) <
1046        sizeof(biggiestruct)) {
1047        log_msg(2, "Warning - unable to get biggiestruct of bigfile #%d",
1048                bigfileno + 1);
1049    }
1050    paranoid_fclose(fin);
1051
1052    mr_asprintf(&checksum, biggiestruct.checksum);
1053
1054    if (!checksum[0]) {
1055        mr_asprintf(&tmp, "Warning - bigfile %ld does not have a checksum",
1056                bigfileno + 1);
1057        log_msg(3, tmp);
1058        mr_free(tmp);
1059        /* BERLIOS : Useless ???
1060        p = checksum;
1061        */
1062    }
1063    mr_free(checksum);
1064
1065    if (!strncmp(biggiestruct.filename, "/dev/", 5))    // Whether NTFS or not :)
1066    {
1067        mr_asprintf(&outfile_fname, biggiestruct.filename);
1068    } else {
1069        mr_asprintf(&outfile_fname, "%s/%s", bkpinfo->restore_path,
1070                biggiestruct.filename);
1071    }
1072
1073    /* skip file if we have a selective restore subset & it doesn't match */
1074    if (filelist != NULL) {
1075        node = find_string_at_node(filelist, biggiestruct.filename);
1076        if (!node) {
1077            log_msg(0, "Skipping %s (name isn't in filelist)",
1078                    biggiestruct.filename);
1079            return (pathname_of_last_file_restored);
1080        } else if (!(node->selected)) {
1081            log_msg(1, "Skipping %s (name isn't in biggielist subset)",
1082                    biggiestruct.filename);
1083            return (pathname_of_last_file_restored);
1084        }
1085    }
1086    /* otherwise, continue */
1087
1088    log_msg(1, "DEFINITELY restoring %s", biggiestruct.filename);
1089    if (biggiestruct.use_ntfsprog) {
1090        if (strncmp(biggiestruct.filename, "/dev/", 5)) {
1091            log_msg(1,
1092                    "I was in error when I set biggiestruct.use_ntfsprog to TRUE.");
1093            log_msg(1, "%s isn't even in /dev", biggiestruct.filename);
1094            biggiestruct.use_ntfsprog = FALSE;
1095        }
1096    }
1097
1098    if (biggiestruct.use_ntfsprog)  // if it's an NTFS device
1099//  if (!strncmp ( biggiestruct.filename, "/dev/", 5))
1100    {
1101        g_loglevel = 4;
1102        use_ntfsprog_hack = TRUE;
1103        log_msg(2,
1104                "Calling ntfsclone in background because %s is an NTFS /dev entry",
1105                outfile_fname);
1106        mr_asprintf(&ntfsprog_fifo, "/tmp/%d.%d.000", (int) (random() % 32768),
1107                (int) (random() % 32768));
1108        mkfifo(ntfsprog_fifo, 0x770);
1109
1110        file_to_openout = ntfsprog_fifo;
1111        switch (pid = fork()) {
1112        case -1:
1113            fatal_error("Fork failure");
1114        case 0:
1115            log_msg(3,
1116                    "CHILD - fip - calling feed_outfrom_ntfsprog(%s, %s)",
1117                    biggiestruct.filename, ntfsprog_fifo);
1118            res =
1119                feed_outfrom_ntfsprog(biggiestruct.filename,
1120                                      ntfsprog_fifo);
1121//          log_msg(3, "CHILD - fip - exiting");
1122            exit(res);
1123            break;
1124        default:
1125            log_msg(3,
1126                    "feed_into_ntfsprog() called in background --- pid=%ld",
1127                    (long int) (pid));
1128        }
1129        // BERLIOS: Is it the right place ??
1130        mr_free(ntfsprog_fifo);
1131    } else {
1132        use_ntfsprog_hack = FALSE;
1133        file_to_openout = outfile_fname;
1134        if (!does_file_exist(outfile_fname))    // yes, it looks weird with the '!' but it's correct that way
1135        {
1136            make_hole_for_file(outfile_fname);
1137        }
1138    }
1139
1140    mr_asprintf(&tmp, "Reassembling big file %ld (%s)", bigfileno + 1,
1141            outfile_fname);
1142    log_msg(2, tmp);
1143    mr_free(tmp);
1144
1145    /*
1146       last slice is zero-length and uncompressed; when we find it, we stop.
1147       We DON'T wait until there are no more slices; if we did that,
1148       We might stop at end of CD, not at last slice (which is 0-len and uncompd)
1149     */
1150
1151    mr_asprintf(&pathname_of_last_file_restored, biggiestruct.filename);
1152
1153    log_msg(3, "file_to_openout = %s", file_to_openout);
1154    if (!(fout = fopen(file_to_openout, "w"))) {
1155        log_to_screen(_("Cannot openout outfile_fname - hard disk full?"));
1156        return (pathname_of_last_file_restored);
1157    }
1158    log_msg(3, "Opened out to %s", outfile_fname);  // CD/DVD --> mondorestore --> ntfsclone --> hard disk itself
1159
1160    for (sliceno = 1, finished = FALSE; !finished;) {
1161        tmp = slice_fname(bigfileno, sliceno, ARCHIVES_PATH, "");
1162        tmp1 = slice_fname(bigfileno, sliceno, ARCHIVES_PATH, "lzo");
1163        tmp2 = slice_fname(bigfileno, sliceno, ARCHIVES_PATH, "bz2");
1164        if (!does_file_exist(tmp) && !does_file_exist(tmp1) &&
1165            !does_file_exist(tmp2)) {
1166            log_msg(3,
1167                    "Cannot find a data slice or terminator slice on CD %d",
1168                    g_current_media_number);
1169            g_current_media_number++;
1170            mr_asprintf(&tmp3,
1171                    "Asking for %s #%d so that I may read slice #%ld\n",
1172                    bkpinfo->backup_media_string,
1173                    g_current_media_number, sliceno);
1174            log_msg(2, tmp3);
1175            mr_free(tmp3);
1176
1177            mr_asprintf(&tmp3, _("Restoring from %s #%d"),
1178                    bkpinfo->backup_media_string,
1179                    g_current_media_number);
1180            log_to_screen(tmp3);
1181            mr_free(tmp3);
1182
1183            insist_on_this_cd_number(bkpinfo, g_current_media_number);
1184            log_to_screen(_("Continuing to restore."));
1185        } else {
1186            if (does_file_exist(tmp) && length_of_file(tmp) == 0) {
1187                log_msg(2,
1188                        "End of bigfile # %ld (slice %ld is the terminator)",
1189                        bigfileno + 1, sliceno);
1190                finished = TRUE;
1191                continue;
1192            } else {
1193                if (does_file_exist(tmp1)) {
1194                    mr_asprintf(&bzip2_command, "lzop -dc %s 2>> %s",tmp1, MONDO_LOGFILE);
1195                } else if (does_file_exist(tmp2)) {
1196                        mr_asprintf(&bzip2_command, "bzip2 -dc %s 2>> %s",tmp2, MONDO_LOGFILE);
1197                } else if (does_file_exist(tmp)) {
1198                        mr_asprintf(&bzip2_command, "%s", "");
1199                } else {
1200                    log_to_screen(_("OK, that's pretty fsck0red..."));
1201                    return (pathname_of_last_file_restored);
1202                }
1203            }
1204
1205            if (bzip2_command == NULL) {
1206                mr_asprintf(&bzip2_command, "cat %s 2>> %s", tmp, MONDO_LOGFILE);
1207            }
1208            mr_asprintf(&tmp3, "Working on %s #%d, file #%ld, slice #%ld ",
1209                    bkpinfo->backup_media_string,
1210                    g_current_media_number, bigfileno + 1, sliceno);
1211            log_msg(2, tmp3);
1212            if (!g_text_mode) {
1213                newtDrawRootText(0, g_noof_rows - 2, tmp3);
1214                newtRefresh();
1215                update_progress_form(tmp3);
1216            }
1217            mr_free(tmp3);
1218
1219            if (!(fbzip2 = popen(bzip2_command, "r"))) {
1220                fatal_error("Can't run popen command");
1221            }
1222            mr_free(bzip2_command);
1223
1224            while (!feof(fbzip2)) {
1225                siz = fread(bigblk, 1, TAPE_BLOCK_SIZE, fbzip2);
1226                if (siz > 0) {
1227                    siz1 = fwrite(bigblk, 1, siz, fout);
1228                    mr_asprintf(&sz_msg, "Read %ld from fbzip2; written %ld to fout", siz, siz1);
1229                    log_it(sz_msg);
1230                    mr_free(sz_msg);
1231                }
1232            }
1233            paranoid_pclose(fbzip2);
1234
1235
1236            sliceno++;
1237            g_current_progress++;
1238        }
1239        mr_free(tmp);
1240        mr_free(tmp1);
1241        mr_free(tmp2);
1242    }
1243    paranoid_fclose(fout);
1244    g_loglevel = old_loglevel;
1245
1246    if (use_ntfsprog_hack) {
1247        log_msg(3, "Waiting for ntfsclone to finish");
1248        mr_asprintf(&tmp,
1249                " ps | grep \" ntfsclone \" | grep -v grep > /dev/null 2> /dev/null");
1250        while (system(tmp) == 0) {
1251            sleep(1);
1252        }
1253        mr_free(tmp);
1254        log_it("OK, ntfsclone has really finished");
1255    }
1256
1257    if (strcmp(outfile_fname, "/dev/null")) {
1258        chown(outfile_fname, biggiestruct.properties.st_uid,
1259              biggiestruct.properties.st_gid);
1260        chmod(outfile_fname, biggiestruct.properties.st_mode);
1261        ubuf->actime = biggiestruct.properties.st_atime;
1262        ubuf->modtime = biggiestruct.properties.st_mtime;
1263        utime(outfile_fname, ubuf);
1264    }
1265    mr_free(outfile_fname);
1266    mr_free(bigblk);
1267
1268    return (pathname_of_last_file_restored);
1269}
1270
1271
1272/**************************************************************************
1273 *END_ RESTORE_A_BIGGIEFILE_FROM_CD                                       *
1274 **************************************************************************/
1275
1276
1277/**
1278 * Restore a biggiefile from the currently opened stream.
1279 * @param bkpinfo The backup information structure. Fields used:
1280 * - @c bkpinfo->restore_path
1281 * - @c bkpinfo->zip_exe
1282 * @param orig_bf_fname The original filename of the biggiefile.
1283 * @param biggiefile_number The number of the biggiefile (starting from 0).
1284 * @param filelist The node structure containing the list of files to be restored.
1285 * If @p orig_bf_fname is not in the list, it will be ignored.
1286 * @return 0 for success (or skip), nonzero for failure.
1287 */
1288char *restore_a_biggiefile_from_stream(struct s_bkpinfo *bkpinfo, char *orig_bf_fname, long biggiefile_number,
1289                                     struct s_node *filelist,
1290                                     int use_ntfsprog)
1291{
1292    FILE *pout;
1293    FILE *fin;
1294
1295  /** mallocs ********/
1296    char *tmp = NULL;
1297    char *tmp1 = NULL;
1298    char *command = NULL;
1299    char *outfile_fname = NULL;
1300    char *ntfsprog_fifo = NULL;
1301    char *file_to_openout = NULL;
1302    char *pathname_of_last_file_restored = NULL;
1303
1304    struct s_node *node;
1305
1306    int old_loglevel;
1307    long current_slice_number = 0;
1308    int retval = 0;
1309    int res = 0;
1310    int ctrl_chr = '\0';
1311    long long slice_siz;
1312    bool dummy_restore = FALSE;
1313    bool use_ntfsprog_hack = FALSE;
1314    pid_t pid;
1315    struct s_filename_and_lstat_info biggiestruct;
1316    struct utimbuf the_utime_buf, *ubuf;
1317    ubuf = &the_utime_buf;
1318
1319    old_loglevel = g_loglevel;
1320    assert(bkpinfo != NULL);
1321    assert(orig_bf_fname != NULL);
1322
1323    if (use_ntfsprog == BLK_START_A_PIHBIGGIE) {
1324        use_ntfsprog = 1;
1325        log_msg(1, "%s --- pih=YES", orig_bf_fname);
1326    } else if (use_ntfsprog == BLK_START_A_NORMBIGGIE) {
1327        use_ntfsprog = 0;
1328        log_msg(1, "%s --- pih=NO", orig_bf_fname);
1329    } else {
1330        use_ntfsprog = 0;
1331        log_msg(1, "%s --- pih=NO (weird marker though)", orig_bf_fname);
1332    }
1333
1334    mr_asprintf(&pathname_of_last_file_restored, orig_bf_fname);
1335
1336    /* open out to biggiefile to be restored (or /dev/null if biggiefile is not to be restored) */
1337
1338    if (filelist != NULL) {
1339        node = find_string_at_node(filelist, orig_bf_fname);
1340        if (!node) {
1341            dummy_restore = TRUE;
1342            log_msg(1,
1343                    "Skipping big file %ld (%s) - not in biggielist subset",
1344                    biggiefile_number + 1, orig_bf_fname);
1345            pathname_of_last_file_restored = NULL;
1346        } else if (!(node->selected)) {
1347            dummy_restore = TRUE;
1348            log_msg(1, "Skipping %s (name isn't in biggielist subset)",
1349                    orig_bf_fname);
1350            pathname_of_last_file_restored = NULL;
1351        }
1352    }
1353
1354    if (use_ntfsprog) {
1355        if (strncmp(orig_bf_fname, "/dev/", 5)) {
1356            log_msg(1, "I was in error when I set use_ntfsprog to TRUE.");
1357            log_msg(1, "%s isn't even in /dev", orig_bf_fname);
1358            use_ntfsprog = FALSE;
1359        }
1360    }
1361
1362    if (use_ntfsprog) {
1363        g_loglevel = 4;
1364        mr_asprintf(&outfile_fname, orig_bf_fname);
1365        use_ntfsprog_hack = TRUE;
1366        log_msg(2,
1367                "Calling ntfsclone in background because %s is a /dev entry",
1368                outfile_fname);
1369        mr_asprintf(&ntfsprog_fifo, "%s/%d.%d.000", 
1370                bkpinfo->tmpdir,
1371                (int) (random() % 32768),
1372                (int) (random() % 32768));
1373        mkfifo(ntfsprog_fifo, 0x770);
1374
1375        file_to_openout = ntfsprog_fifo;
1376        switch (pid = fork()) {
1377        case -1:
1378            fatal_error("Fork failure");
1379        case 0:
1380            log_msg(3,
1381                    "CHILD - fip - calling feed_outfrom_ntfsprog(%s, %s)",
1382                    outfile_fname, ntfsprog_fifo);
1383            res = feed_outfrom_ntfsprog(outfile_fname, ntfsprog_fifo);
1384//          log_msg(3, "CHILD - fip - exiting");
1385            exit(res);
1386            break;
1387        default:
1388            log_msg(3,
1389                    "feed_into_ntfsprog() called in background --- pid=%ld",
1390                    (long int) (pid));
1391        }
1392        mr_free(ntfsprog_fifo);
1393    } else {
1394        if (!strncmp(orig_bf_fname, "/dev/", 5))    // non-NTFS partition
1395        {
1396            mr_asprintf(&outfile_fname, orig_bf_fname);
1397        } else                  // biggiefile
1398        {
1399            mr_asprintf(&outfile_fname, "%s/%s", bkpinfo->restore_path,
1400                    orig_bf_fname);
1401        }
1402        use_ntfsprog_hack = FALSE;
1403        file_to_openout = outfile_fname;
1404        if (!does_file_exist(outfile_fname))    // yes, it looks weird with the '!' but it's correct that way
1405        {
1406            make_hole_for_file(outfile_fname);
1407        }
1408        mr_asprintf(&tmp1, "Reassembling big file %ld (%s)",
1409                biggiefile_number + 1, orig_bf_fname);
1410        log_msg(2, tmp1);
1411        mr_free(tmp1);
1412    }
1413
1414    if (dummy_restore) {
1415        mr_free(outfile_fname);
1416        mr_asprintf(&outfile_fname, "/dev/null");
1417    }
1418
1419    if (bkpinfo->zip_exe == NULL) {
1420        mr_asprintf(&command, "cat > \"%s\"", file_to_openout);
1421    } else {
1422        mr_asprintf(&command, "%s -dc > \"%s\" 2>> %s", bkpinfo->zip_exe,
1423                file_to_openout, MONDO_LOGFILE);
1424    }
1425    mr_asprintf(&tmp1, "Pipe command = '%s'", command);
1426    log_msg(3, tmp1);
1427    mr_free(tmp1);
1428
1429    /* restore biggiefile, one slice at a time */
1430    if (!(pout = popen(command, "w"))) {
1431        fatal_error("Cannot pipe out");
1432    }
1433    mr_free(command);
1434
1435    for (res = read_header_block_from_stream(&slice_siz, tmp, &ctrl_chr);
1436         ctrl_chr != BLK_STOP_A_BIGGIE;
1437         res = read_header_block_from_stream(&slice_siz, tmp, &ctrl_chr)) {
1438        if (ctrl_chr != BLK_START_AN_AFIO_OR_SLICE) {
1439            wrong_marker(BLK_START_AN_AFIO_OR_SLICE, ctrl_chr);
1440        }
1441        mr_asprintf(&tmp1, "Working on file #%ld, slice #%ld    ",
1442                biggiefile_number + 1, current_slice_number);
1443        log_msg(2, tmp1);
1444
1445        if (!g_text_mode) {
1446            newtDrawRootText(0, g_noof_rows - 2, tmp1);
1447            newtRefresh();
1448        }
1449        strip_spaces(tmp1);
1450        update_progress_form(tmp1);
1451        mr_free(tmp1);
1452
1453        if (current_slice_number == 0) {
1454            res =
1455                read_file_from_stream_to_file(bkpinfo,
1456                                              "/tmp/biggie-blah.txt",
1457                                              slice_siz);
1458            if (!(fin = fopen("/tmp/biggie-blah.txt", "r"))) {
1459                log_OS_error("blah blah");
1460            } else {
1461                if (fread
1462                    ((void *) &biggiestruct, 1, sizeof(biggiestruct),
1463                     fin) < sizeof(biggiestruct)) {
1464                    log_msg(2,
1465                            "Warning - unable to get biggiestruct of bigfile #%d",
1466                            biggiefile_number + 1);
1467                }
1468                paranoid_fclose(fin);
1469            }
1470        } else {
1471            res =
1472                read_file_from_stream_to_stream(bkpinfo, pout, slice_siz);
1473        }
1474        retval += res;
1475        res = read_header_block_from_stream(&slice_siz, tmp, &ctrl_chr);
1476        if (ctrl_chr != BLK_STOP_AN_AFIO_OR_SLICE) {
1477            wrong_marker(BLK_STOP_AN_AFIO_OR_SLICE, ctrl_chr);
1478        }
1479        current_slice_number++;
1480        g_current_progress++;
1481    }
1482    mr_free(tmp);
1483    paranoid_pclose(pout);
1484
1485    log_msg(1, "pathname_of_last_file_restored is now %s",
1486            pathname_of_last_file_restored);
1487
1488    if (use_ntfsprog_hack) {
1489        log_msg(3, "Waiting for ntfsclone to finish");
1490        mr_asprintf(&tmp,
1491                " ps | grep \" ntfsclone \" | grep -v grep > /dev/null 2> /dev/null");
1492        while (system(tmp) == 0) {
1493            sleep(1);
1494        }   
1495        mr_free(tmp);
1496        log_msg(3, "OK, ntfsclone has really finished");
1497    }
1498
1499    log_msg(3, "biggiestruct.filename = %s", biggiestruct.filename);
1500    log_msg(3, "biggiestruct.checksum = %s", biggiestruct.checksum);
1501    if (strcmp(outfile_fname, "/dev/null")) {
1502        chmod(outfile_fname, biggiestruct.properties.st_mode);
1503        chown(outfile_fname, biggiestruct.properties.st_uid,
1504              biggiestruct.properties.st_gid);
1505        ubuf->actime = biggiestruct.properties.st_atime;
1506        ubuf->modtime = biggiestruct.properties.st_mtime;
1507        utime(outfile_fname, ubuf);
1508    }
1509
1510    mr_free(outfile_fname);
1511    g_loglevel = old_loglevel;
1512    return (pathname_of_last_file_restored);
1513}
1514
1515/**************************************************************************
1516 *END_RESTORE_A_BIGGIEFILE_FROM_STREAM                                    *
1517 **************************************************************************/
1518
1519
1520/**
1521 * Restore @p tarball_fname from CD.
1522 * @param tarball_fname The filename of the tarball to restore (in /mnt/cdrom).
1523 * This will be used unmodified.
1524 * @param current_tarball_number The number (starting from 0) of the fileset
1525 * we're restoring now.
1526 * @param filelist The node structure containing the list of files to be
1527 * restored. If no file in the afioball is in this list, afio will still be
1528 * called, but nothing will be written.
1529 * @return 0 for success, nonzero for failure.
1530 */
1531int
1532restore_a_tarball_from_CD(char *tarball_fname,
1533                          long current_tarball_number,
1534                          struct s_node *filelist)
1535{
1536    int retval = 0;
1537    int res;
1538    char *p;
1539
1540  /** malloc **/
1541    char *command;
1542    char *tmp = NULL;
1543    char *filelist_name;
1544    char *filelist_subset_fname = NULL;
1545    char *executable = NULL;
1546    char *temp_log = NULL;
1547    long matches = 0;
1548    bool use_star;
1549    char *xattr_fname = NULL;
1550    char *acl_fname = NULL;
1551
1552    assert_string_is_neither_NULL_nor_zerolength(tarball_fname);
1553
1554    log_msg(5, "Entering");
1555    use_star = (strstr(tarball_fname, ".star")) ? TRUE : FALSE;
1556    mr_asprintf(&command, "mkdir -p %s/tmp", MNT_RESTORING);
1557    run_program_and_log_output(command, 9);
1558    mr_free(command);
1559
1560    mr_asprintf(&filelist_name, MNT_CDROM "/archives/filelist.%ld",
1561            current_tarball_number);
1562    if (length_of_file(filelist_name) <= 2) {
1563        log_msg(2, "There are _zero_ files in filelist '%s'",
1564                filelist_name);
1565        log_msg(2,
1566                "This is a bit silly (ask dev-team to fix mondo_makefilelist, please)");
1567        log_msg(2,
1568                "but it's non-critical. It's cosmetic. Don't worry about it.");
1569        retval = 0;
1570        log_msg(5, "Leaving");
1571        return (retval);
1572    }
1573    if (count_lines_in_file(filelist_name) <= 0
1574        || length_of_file(tarball_fname) <= 0) {
1575        log_msg(3, "length_of_file(%s) = %llu", tarball_fname,
1576                length_of_file(tarball_fname));
1577        mr_asprintf(&tmp, "Unable to restore fileset #%ld (CD I/O error)",
1578                current_tarball_number);
1579        log_to_screen(tmp);
1580        mr_free(tmp);
1581        retval = 1;
1582        log_msg(5, "Leaving");
1583        return (retval);
1584    }
1585
1586    if (filelist) {
1587        mr_asprintf(&filelist_subset_fname, "/tmp/filelist-subset-%ld.tmp",
1588                current_tarball_number);
1589        if ((matches =
1590             save_filelist_entries_in_common(filelist_name, filelist,
1591                                             filelist_subset_fname,
1592                                             use_star))
1593            <= 0) {
1594            mr_asprintf(&tmp, "Skipping fileset %ld", current_tarball_number);
1595            log_msg(1, tmp);
1596            mr_free(tmp);
1597        } else {
1598            log_msg(3, "Saved fileset %ld's subset to %s",
1599                    current_tarball_number, filelist_subset_fname);
1600        }
1601        mr_asprintf(&tmp, "Tarball #%ld --- %ld matches",
1602                current_tarball_number, matches);
1603        log_to_screen(tmp);
1604        mr_free(tmp);
1605    } else {
1606        filelist_subset_fname = NULL;
1607    }
1608    mr_free(filelist_name);
1609
1610    if (filelist == NULL || matches > 0) {
1611        mr_asprintf(&xattr_fname, XATTR_LIST_FNAME_RAW_SZ,
1612                MNT_CDROM "/archives", current_tarball_number);
1613        mr_asprintf(&acl_fname, ACL_LIST_FNAME_RAW_SZ, MNT_CDROM "/archives",
1614                current_tarball_number);
1615        if (strstr(tarball_fname, ".bz2")) {
1616            mr_asprintf(&executable, "bzip2");
1617        } else if (strstr(tarball_fname, ".lzo")) {
1618            mr_asprintf(&executable, "lzop");
1619        } else {
1620            executable = NULL;
1621        }
1622
1623        if (executable == NULL) {
1624            mr_asprintf(&tmp, "which %s > /dev/null 2> /dev/null", executable);
1625            if (run_program_and_log_output(tmp, FALSE)) {
1626                log_to_screen
1627                    (_
1628                     ("(compare_a_tarball) Compression program not found - oh no!"));
1629                paranoid_MR_finish(1);
1630            }
1631            mr_free(tmp);
1632
1633            mr_asprintf(&tmp, executable);
1634            mr_asprintf(&executable, "-P %s -Z", tmp);
1635            mr_free(tmp);
1636        }
1637#ifdef __FreeBSD__
1638#define BUFSIZE 512
1639#else
1640#define BUFSIZE (1024L*1024L)/TAPE_BLOCK_SIZE
1641#endif
1642
1643        mr_asprintf(&temp_log, "/tmp/%d.%d", (int) (random() % 32768),
1644            (int) (random() % 32768));
1645
1646        if (use_star) {
1647            if (strstr(tarball_fname, ".bz2")) {
1648                mr_asprintf(&tmp, " -bz");
1649            } else {
1650                mr_asprintf(&tmp, "%s", "");
1651            }
1652            mr_asprintf(&command,
1653                    "star -x -force-remove -U " STAR_ACL_SZ
1654                    " errctl= file=%s %s 2>> %s >> %s", tarball_fname, tmp, temp_log, temp_log);
1655            mr_free(tmp);
1656        } else {
1657            if (filelist_subset_fname != NULL) {
1658                mr_asprintf(&command,
1659                        "afio -i -M 8m -b %ld -c %ld %s -w '%s' %s 2>> %s >> %s",
1660                        TAPE_BLOCK_SIZE,
1661                        BUFSIZE, executable, filelist_subset_fname,
1662//             files_to_restore_this_time_fname,
1663                        tarball_fname, temp_log, temp_log);
1664            } else {
1665                mr_asprintf(&command,
1666                        "afio -i -b %ld -c %ld -M 8m %s %s 2>> %s >> %s",
1667                        TAPE_BLOCK_SIZE,
1668                        BUFSIZE, executable, tarball_fname, temp_log, temp_log);
1669            }
1670        }
1671        mr_free(executable);
1672
1673#undef BUFSIZE
1674        log_msg(1, "command = '%s'", command);
1675        unlink(temp_log);
1676        res = system(command);
1677        if (res) {
1678            p = strstr(command, "-acl ");
1679            if (p) {
1680                p[0] = p[1] = p[2] = p[3] = ' ';
1681                log_msg(1, "new command = '%s'", command);
1682                res = system(command);
1683            }
1684        }
1685        mr_free(command);
1686
1687        if (res && length_of_file(temp_log) < 5) {
1688            res = 0;
1689        }
1690
1691        log_msg(1, "Setting fattr list %s", xattr_fname);
1692        if (length_of_file(xattr_fname) > 0) {
1693            res = set_fattr_list(filelist_subset_fname, xattr_fname);
1694            if (res) {
1695                log_to_screen
1696                    (_
1697                     ("Errors occurred while setting extended attributes"));
1698            } else {
1699                log_msg(1, "I set xattr OK");
1700            }
1701            retval += res;
1702        }
1703        if (length_of_file(acl_fname) > 0) {
1704            log_msg(1, "Setting acl list %s", acl_fname);
1705            res = set_acl_list(filelist_subset_fname, acl_fname);
1706            if (res) {
1707                log_to_screen
1708                    (_
1709                     ("Errors occurred while setting access control lists"));
1710            } else {
1711                log_msg(1, "I set ACL OK");
1712            }
1713            retval += res;
1714        }
1715        if (retval) {
1716            mr_asprintf(&command, "cat %s >> %s", temp_log, MONDO_LOGFILE);
1717            system(command);
1718            mr_free(command);
1719            log_msg(2, "Errors occurred while processing fileset #%d",
1720                    current_tarball_number);
1721        } else {
1722            log_msg(2, "Fileset #%d processed OK", current_tarball_number);
1723        }
1724        unlink(xattr_fname);
1725        mr_free(xattr_fname);
1726    }
1727    if (does_file_exist("/PAUSE")) {
1728        popup_and_OK
1729            (_
1730             ("Press ENTER to go on. Delete /PAUSE to stop these pauses."));
1731    }
1732    unlink(filelist_subset_fname);
1733    unlink(acl_fname);
1734    unlink(temp_log);
1735
1736    mr_free(filelist_subset_fname);
1737    mr_free(acl_fname);
1738    mr_free(temp_log);
1739
1740    log_msg(5, "Leaving");
1741    return (retval);
1742}
1743
1744/**************************************************************************
1745 *END_RESTORE_A_TARBALL_FROM_CD                                           *
1746 **************************************************************************/
1747
1748
1749/**
1750 * Restore a tarball from the currently opened stream.
1751 * @param bkpinfo The backup information structure. Fields used:
1752 * - @c bkpinfo->backup_media_type
1753 * - @c bkpinfo->media_device
1754 * - @c bkpinfo->zip_exe
1755 * @param tarball_fname The filename of the afioball to restore.
1756 * @param current_tarball_number The number (starting from 0) of the fileset
1757 * we're restoring now.
1758 * @param filelist The node structure containing the list of files to be
1759 * restored. If no file in the afioball is in this list, afio will still be
1760 * called, but nothing will be written.
1761 * @param size The size (in @b bytes) of the afioball.
1762 * @return 0 for success, nonzero for failure.
1763 */
1764int
1765restore_a_tarball_from_stream(struct s_bkpinfo *bkpinfo,
1766                              char *tarball_fname,
1767                              long current_tarball_number,
1768                              struct s_node *filelist,
1769                              long long size, char *xattr_fname,
1770                              char *acl_fname)
1771{
1772    int retval = 0;
1773    int res = 0;
1774
1775  /** malloc add ***/
1776    char *tmp = NULL;
1777    char *command = NULL;
1778    char *afio_fname = NULL;
1779    char *filelist_fname = NULL;
1780    char *filelist_subset_fname = NULL;
1781    char *executable = NULL;
1782    long matches = 0;
1783    bool restore_this_fileset = FALSE;
1784    bool use_star;
1785
1786    assert(bkpinfo != NULL);
1787    assert_string_is_neither_NULL_nor_zerolength(tarball_fname);
1788    /* to do it with a file... */
1789    use_star = (strstr(tarball_fname, ".star")) ? TRUE : FALSE;
1790    mr_asprintf(&tmp,
1791            "Restoring from fileset #%ld (%ld KB) on %s #%d",
1792            current_tarball_number, (long) size >> 10,
1793            bkpinfo->backup_media_string,
1794            g_current_media_number);
1795    log_msg(2, tmp);
1796    mr_free(tmp);
1797    run_program_and_log_output("mkdir -p " MNT_RESTORING "/tmp", FALSE);
1798
1799  /****************************************************************************
1800   * Use RAMDISK's /tmp; saves time; oh wait, it's too small                  *
1801   * Well, pipe from tape to afio, then; oh wait, can't do that either: bug   *
1802   * in afio or someting; oh darn.. OK, use tmpfs :-)                         *
1803   ****************************************************************************/
1804    mr_asprintf(&afio_fname, "/tmp/tmpfs/archive.tmp.%ld",
1805            current_tarball_number);
1806    mr_asprintf(&filelist_fname, "%s/filelist.%ld", bkpinfo->tmpdir,
1807            current_tarball_number);
1808    mr_asprintf(&filelist_subset_fname, "%s/filelist-subset-%ld.tmp",
1809            bkpinfo->tmpdir, current_tarball_number);
1810    res = read_file_from_stream_to_file(bkpinfo, afio_fname, size);
1811    if (strstr(tarball_fname, ".star")) {
1812        bkpinfo->use_star = TRUE;
1813    }
1814    if (res) {
1815        log_msg(1, "Warning - error reading afioball from tape");
1816    }
1817    if (bkpinfo->compression_level != 0) {
1818        if (bkpinfo->use_star) {
1819            mr_asprintf(&executable, " -bz");
1820        } else {
1821            mr_asprintf(&executable, "-P %s -Z", bkpinfo->zip_exe);
1822        }
1823    }
1824
1825    if (!filelist)              // if unconditional restore then restore entire fileset
1826    {
1827        restore_this_fileset = TRUE;
1828    } else                      // If restoring selectively then get TOC from tarball
1829    {
1830        if (strstr(tarball_fname, ".star.")) {
1831            use_star = TRUE;
1832            mr_asprintf(&command, "star -t file=%s %s > %s 2>> %s", afio_fname, executable, filelist_fname, MONDO_LOGFILE);
1833        } else {
1834            use_star = FALSE;
1835            mr_asprintf(&command, "afio -t -M 8m -b %ld %s %s > %s 2>> %s", TAPE_BLOCK_SIZE,
1836                    executable, afio_fname, filelist_fname, MONDO_LOGFILE);
1837        }
1838        log_msg(1, "command = %s", command);
1839        if (system(command)) {
1840            log_msg(4, "Warning - error occurred while retrieving TOC");
1841        }
1842        mr_free(command);
1843        if ((matches =
1844             save_filelist_entries_in_common(filelist_fname, filelist,
1845                                             filelist_subset_fname,
1846                                             use_star))
1847            <= 0 || length_of_file(filelist_subset_fname) < 2) {
1848            if (length_of_file(filelist_subset_fname) < 2) {
1849                log_msg(1, "No matches found in fileset %ld",
1850                        current_tarball_number);
1851            }
1852            mr_asprintf(&tmp, "Skipping fileset %ld", current_tarball_number);
1853            log_msg(2, tmp);
1854            mr_free(tmp);
1855            restore_this_fileset = FALSE;
1856        } else {
1857            log_msg(5, "%ld matches. Saved fileset %ld's subset to %s",
1858                    matches, current_tarball_number,
1859                    filelist_subset_fname);
1860            restore_this_fileset = TRUE;
1861        }
1862    }
1863    unlink(filelist_fname);
1864    mr_free(filelist_fname);
1865
1866// Concoct the call to star/afio to restore files
1867    if (strstr(tarball_fname, ".star.")) {
1868        // star
1869        if (filelist) {
1870            mr_asprintf(&command, "star -x file=%s %s list=%s 2>> %s", afio_fname, executable,
1871                    filelist_subset_fname,MONDO_LOGFILE);
1872        } else {
1873            mr_asprintf(&command,"star -x file=%s %s 2>> %s", afio_fname, executable,MONDO_LOGFILE);
1874        }
1875    } else {
1876        // afio
1877        if (filelist) {
1878            mr_asprintf(&command, "afio -i -M 8m -b %ld %s -w %s %s 2>> %s", TAPE_BLOCK_SIZE, executable, filelist_subset_fname,afio_fname,MONDO_LOGFILE);
1879        } else {
1880            mr_asprintf(&command, "afio -i -M 8m -b %ld %s %s 2>> %s", TAPE_BLOCK_SIZE, executable,afio_fname,MONDO_LOGFILE);
1881        }
1882    }
1883    mr_free(executable);
1884
1885    // Call if IF there are files to restore (selectively/unconditionally)
1886    if (restore_this_fileset) {
1887        log_msg(1, "Calling command='%s'", command);
1888        paranoid_system(command);
1889
1890        iamhere("Restoring xattr, acl stuff");
1891        res = set_fattr_list(filelist_subset_fname, xattr_fname);
1892        if (res) {
1893            log_msg(1, "Errors occurred while setting xattr");
1894        } else {
1895            log_msg(1, "I set xattr OK");
1896        }
1897        retval += res;
1898
1899        res = set_acl_list(filelist_subset_fname, acl_fname);
1900        if (res) {
1901            log_msg(1, "Errors occurred while setting ACL");
1902        } else {
1903            log_msg(1, "I set ACL OK");
1904        }
1905        retval += res;
1906
1907    } else {
1908        log_msg(1, "NOT CALLING '%s'", command);
1909    }
1910    mr_free(command);
1911
1912    if (does_file_exist("/PAUSE") && current_tarball_number >= 50) {
1913        log_to_screen(_("Paused after set %ld"), current_tarball_number);
1914        popup_and_OK(_("Pausing. Press ENTER to continue."));
1915    }
1916
1917    unlink(filelist_subset_fname);
1918    unlink(afio_fname);
1919
1920    mr_free(filelist_subset_fname);
1921    mr_free(afio_fname);
1922    return (retval);
1923}
1924
1925/**************************************************************************
1926 *END_RESTORE_A_TARBALL_FROM_STREAM                                       *
1927 **************************************************************************/
1928
1929
1930/**
1931 * Restore all biggiefiles from all media in this CD backup.
1932 * The CD with the last afioball should be currently mounted.
1933 * @param bkpinfo The backup information structure. @c backup_media_type is the
1934 * only field used in this function.
1935 * @param filelist The node structure containing the list of files to be
1936 * restored. If a prospective biggiefile is not in this list, it will be ignored.
1937 * @return 0 for success, nonzero for failure.
1938 */
1939int
1940restore_all_biggiefiles_from_CD(struct s_bkpinfo *bkpinfo,
1941                                struct s_node *filelist)
1942{
1943    int retval = 0;
1944    int res = 0;
1945    long noof_biggiefiles = 0L, bigfileno = 0L, total_slices = 0L;
1946    char *tmp = NULL;
1947    char *tmp1 = NULL;
1948    bool just_changed_cds = FALSE, finished = FALSE;
1949    char *xattr_fname = NULL;
1950    char *acl_fname = NULL;
1951    char *biggies_whose_EXATs_we_should_set = NULL; // EXtended ATtributes
1952    char *pathname_of_last_biggie_restored = NULL;
1953    FILE *fbw = NULL;
1954
1955    assert(bkpinfo != NULL);
1956
1957    mr_asprintf(&biggies_whose_EXATs_we_should_set,
1958            "%s/biggies-whose-EXATs-we-should-set", bkpinfo->tmpdir);
1959    if (!(fbw = fopen(biggies_whose_EXATs_we_should_set, "w"))) {
1960        log_msg(1, "Warning - cannot openout %s",
1961                biggies_whose_EXATs_we_should_set);
1962    }
1963
1964    read_cfg_var(g_mondo_cfg_file, "total-slices", tmp);
1965    total_slices = atol(tmp);
1966    mr_free(tmp);
1967
1968    mr_asprintf(&tmp, _("Reassembling large files      "));
1969    mvaddstr_and_log_it(g_currentY, 0, tmp);
1970    mr_free(tmp);
1971
1972    if (length_of_file(BIGGIELIST) < 6) {
1973        log_msg(1, "OK, no biggielist; not restoring biggiefiles");
1974        return (0);
1975    }
1976    noof_biggiefiles = count_lines_in_file(BIGGIELIST);
1977    if (noof_biggiefiles <= 0) {
1978        log_msg(2,
1979                "OK, no biggiefiles in biggielist; not restoring biggiefiles");
1980        return (0);
1981    }
1982    mr_asprintf(&tmp, "OK, there are %ld biggiefiles in the archives",
1983            noof_biggiefiles);
1984    log_msg(2, tmp);
1985    mr_free(tmp);
1986
1987    open_progress_form(_("Reassembling large files"),
1988                       _("I am now reassembling all the large files."),
1989                       _("Please wait. This may take some time."),
1990                       "", total_slices);
1991    for (bigfileno = 0, finished = FALSE; !finished;) {
1992        log_msg(2, "Thinking about restoring bigfile %ld", bigfileno + 1);
1993        tmp = slice_fname(bigfileno, 0, ARCHIVES_PATH, "");
1994        if (!does_file_exist(tmp)) {
1995            log_msg(3,
1996                    "...but its first slice isn't on this CD. Perhaps this was a selective restore?");
1997            log_msg(3, "Cannot find bigfile #%ld 's first slice on %s #%d",
1998                    bigfileno + 1,
1999                    bkpinfo->backup_media_string,
2000                    g_current_media_number);
2001            tmp1 = slice_fname(bigfileno + 1, 0, ARCHIVES_PATH, "");
2002            log_msg(3, "Slicename would have been %s", tmp1);
2003            mr_free(tmp1);
2004
2005            // I'm not positive 'just_changed_cds' is even necessary...
2006            if (just_changed_cds) {
2007                just_changed_cds = FALSE;
2008                log_msg(3,
2009                        "I'll continue to scan this CD for bigfiles to be restored.");
2010            } else if (does_file_exist(MNT_CDROM "/archives/NOT-THE-LAST")) {
2011                insist_on_this_cd_number(bkpinfo,
2012                                         ++g_current_media_number);
2013                mr_asprintf(&tmp, _("Restoring from %s #%d"),
2014                        bkpinfo->backup_media_string,
2015                        g_current_media_number);
2016                log_to_screen(tmp);
2017                mr_free(tmp);
2018
2019                just_changed_cds = TRUE;
2020            } else {
2021                log_msg(2, "There was no bigfile #%ld. That's OK.",
2022                        bigfileno + 1);
2023                log_msg(2, "I'm going to stop restoring bigfiles now.");
2024                finished = TRUE;
2025            }
2026        } else {
2027            just_changed_cds = FALSE;
2028            mr_asprintf(&tmp, _("Restoring big file %ld"), bigfileno + 1);
2029            update_progress_form(tmp);
2030            mr_free(tmp);
2031
2032            pathname_of_last_biggie_restored =
2033                restore_a_biggiefile_from_CD(bkpinfo, bigfileno, filelist);
2034            iamhere(pathname_of_last_biggie_restored);
2035            if (fbw && pathname_of_last_biggie_restored[0]) {
2036                fprintf(fbw, "%s\n", pathname_of_last_biggie_restored);
2037            }
2038            mr_free(pathname_of_last_biggie_restored);
2039            retval += res;
2040            bigfileno++;
2041
2042        }
2043        mr_free(tmp);
2044    }
2045
2046    if (fbw) {
2047        fclose(fbw);
2048        mr_asprintf(&acl_fname, ACL_BIGGLST_FNAME_RAW_SZ, ARCHIVES_PATH);
2049        mr_asprintf(&xattr_fname, XATTR_BIGGLST_FNAME_RAW_SZ, ARCHIVES_PATH);
2050        if (length_of_file(acl_fname) > 0) {
2051            set_acl_list(biggies_whose_EXATs_we_should_set, acl_fname);
2052        }
2053        if (length_of_file(xattr_fname) > 0) {
2054            set_fattr_list(biggies_whose_EXATs_we_should_set, xattr_fname);
2055        }
2056        mr_free(acl_fname);
2057        mr_free(xattr_fname);
2058    }
2059    mr_free(biggies_whose_EXATs_we_should_set);
2060
2061    if (does_file_exist("/PAUSE")) {
2062        popup_and_OK
2063            (_
2064             ("Press ENTER to go on. Delete /PAUSE to stop these pauses."));
2065    }
2066    close_progress_form();
2067    if (retval) {
2068        mvaddstr_and_log_it(g_currentY++, 74, _("Errors."));
2069    } else {
2070        mvaddstr_and_log_it(g_currentY++, 74, _("Done."));
2071    }
2072    return (retval);
2073}
2074/**************************************************************************
2075 *END_RESTORE_ALL_BIGGIFILES_FROM_CD                                      *
2076 **************************************************************************/
2077
2078
2079/**
2080 * Restore all afioballs from all CDs in the backup.
2081 * The first CD should be inserted (if not, it will be asked for).
2082 * @param bkpinfo The backup information structure. @c backup_media_type is the
2083 * only field used in @e this function.
2084 * @param filelist The node structure containing the list of files to be
2085 * restored. If no file in some particular afioball is in this list, afio will
2086 * still be called for that fileset, but nothing will be written.
2087 * @return 0 for success, or the number of filesets that failed.
2088 */
2089int
2090restore_all_tarballs_from_CD(struct s_bkpinfo *bkpinfo,
2091                             struct s_node *filelist)
2092{
2093    int retval = 0;
2094    int res;
2095    int attempts;
2096    long current_tarball_number = 0;
2097    long max_val;
2098  /**malloc ***/
2099    char *tmp;
2100    char *tmp1;
2101    char *tarball_fname;
2102    char *progress_str;
2103    char *comment;
2104
2105    assert(bkpinfo != NULL);
2106
2107    mvaddstr_and_log_it(g_currentY, 0, _("Restoring from archives"));
2108    log_msg(2,
2109            "Insisting on 1st CD, so that I can have a look at LAST-FILELIST-NUMBER");
2110    if (g_current_media_number != 1) {
2111        log_msg(3, "OK, that's jacked up.");
2112        g_current_media_number = 1;
2113    }
2114    insist_on_this_cd_number(bkpinfo, g_current_media_number);
2115    read_cfg_var(g_mondo_cfg_file, "last-filelist-number", tmp);
2116    max_val = atol(tmp) + 1;
2117    mr_free(tmp);
2118
2119    mr_asprintf(&progress_str, _("Restoring from %s #%d"),
2120            bkpinfo->backup_media_string,
2121            g_current_media_number);
2122    log_to_screen(progress_str);
2123    open_progress_form(_("Restoring from archives"),
2124                       _("Restoring data from the archives."),
2125                       _("Please wait. This may take some time."),
2126                       progress_str, max_val);
2127    for (;;) {
2128        insist_on_this_cd_number(bkpinfo, g_current_media_number);
2129        update_progress_form(progress_str);
2130
2131        mr_asprintf(&tarball_fname, MNT_CDROM "/archives/%ld.afio.bz2",
2132                current_tarball_number);
2133        if (!does_file_exist(tarball_fname)) {
2134            mr_free(tarball_fname);
2135            mr_asprintf(&tarball_fname, MNT_CDROM "/archives/%ld.afio.lzo",
2136                    current_tarball_number);
2137        }
2138        if (!does_file_exist(tarball_fname)) {
2139            mr_free(tarball_fname);
2140            mr_asprintf(&tarball_fname, MNT_CDROM "/archives/%ld.afio.",
2141                    current_tarball_number);
2142        }
2143        if (!does_file_exist(tarball_fname)) {
2144            mr_free(tarball_fname);
2145            mr_asprintf(&tarball_fname, MNT_CDROM "/archives/%ld.star.bz2",
2146                    current_tarball_number);
2147        }
2148        if (!does_file_exist(tarball_fname)) {
2149            mr_free(tarball_fname);
2150            mr_asprintf(&tarball_fname, MNT_CDROM "/archives/%ld.star.",
2151                    current_tarball_number);
2152        }
2153        if (!does_file_exist(tarball_fname)) {
2154            mr_free(tarball_fname);
2155            if (current_tarball_number == 0) {
2156                log_to_screen
2157                    (_
2158                     ("No tarballs. Strange. Maybe you only backed up freakin' big files?"));
2159                return (0);
2160            }
2161            if (!does_file_exist(MNT_CDROM "/archives/NOT-THE-LAST")
2162                || system("find " MNT_CDROM
2163                          "/archives/slice* > /dev/null 2> /dev/null") ==
2164                0) {
2165                break;
2166            }
2167            g_current_media_number++;
2168            mr_free(progress_str);
2169            mr_asprintf(&progress_str, _("Restoring from %s #%d"),
2170                    bkpinfo->backup_media_string,
2171                    g_current_media_number);
2172            log_to_screen(progress_str);
2173        } else {
2174            mr_free(progress_str);
2175            mr_asprintf(&progress_str,
2176                    _("Restoring from fileset #%ld on %s #%d"),
2177                    current_tarball_number,
2178                    bkpinfo->backup_media_string,
2179                    g_current_media_number);
2180//    log_msg(3, "progress_str = %s", progress_str);
2181            for (res = 999, attempts = 0; attempts < 3 && res != 0;
2182                 attempts++) {
2183                res =
2184                    restore_a_tarball_from_CD(tarball_fname,
2185                                              current_tarball_number,
2186                                              filelist);
2187            }
2188            if (res) {
2189                mr_asprintf(&tmp1, _("reported errors"));
2190            } else {
2191                mr_asprintf(&tmp1, _("succeeded"));
2192            }
2193            mr_asprintf(&tmp, _("%s #%d, fileset #%ld - restore %s"),
2194                    bkpinfo->backup_media_string,
2195                    g_current_media_number, current_tarball_number,tmp1);
2196            mr_free(tmp1);
2197           
2198            if (attempts > 1) {
2199                mr_asprintf(&tmp1, _(" (%d attempts) - review logs"), attempts);
2200            }
2201            mr_asprintf(&comment, "%s%s", tmp, tmp1);
2202            mr_free(tmp);
2203            mr_free(tmp1);
2204            if (attempts > 1) {
2205                log_to_screen(comment);
2206            }
2207            mr_free(comment);
2208
2209            retval += res;
2210            current_tarball_number++;
2211            g_current_progress++;
2212        }
2213        mr_free(tarball_fname);
2214    }
2215    mr_free(progress_str);
2216    close_progress_form();
2217
2218    if (retval) {
2219        mvaddstr_and_log_it(g_currentY++, 74, _("Errors."));
2220    } else {
2221        mvaddstr_and_log_it(g_currentY++, 74, _("Done."));
2222    }
2223
2224    return (retval);
2225}
2226
2227/**************************************************************************
2228 *END_RESTORE_ALL_TARBALLS_FROM_CD                                        *
2229 **************************************************************************/
2230
2231
2232/**
2233 * Restore all biggiefiles from the currently opened stream.
2234 * @param bkpinfo The backup information structure. Passed to other functions.
2235 * @param filelist The node structure containing the list of files to be
2236 * restored. If a prospective biggiefile is not in the list, it will be ignored.
2237 * @return 0 for success, or the number of biggiefiles that failed.
2238 */
2239int
2240restore_all_biggiefiles_from_stream(struct s_bkpinfo *bkpinfo,
2241                                    struct s_node *filelist)
2242{
2243    long noof_biggiefiles;
2244    long current_bigfile_number = 0;
2245    long total_slices;
2246
2247    int retval = 0;
2248    int res = 0;
2249    int ctrl_chr;
2250
2251  /** malloc add ****/
2252    char *tmp = NULL;
2253    char *biggie_fname = NULL;
2254    char *xattr_fname = NULL;
2255    char *acl_fname = NULL;
2256    char *pathname_of_last_biggie_restored = NULL;
2257    char *biggies_whose_EXATs_we_should_set = NULL; // EXtended ATtributes
2258    long long biggie_size = (long long)0;
2259    FILE *fbw;
2260
2261    assert(bkpinfo != NULL);
2262
2263    read_cfg_var(g_mondo_cfg_file, "total-slices", tmp);
2264    total_slices = atol(tmp);
2265    mr_free(tmp);
2266
2267    mr_asprintf(&tmp, "Reassembling large files      ");
2268    mr_asprintf(&xattr_fname, XATTR_BIGGLST_FNAME_RAW_SZ, bkpinfo->tmpdir);
2269    mr_asprintf(&acl_fname, ACL_BIGGLST_FNAME_RAW_SZ, bkpinfo->tmpdir);
2270    mvaddstr_and_log_it(g_currentY, 0, tmp);
2271    mr_free(tmp);
2272
2273    mr_asprintf(&biggies_whose_EXATs_we_should_set,
2274            "%s/biggies-whose-EXATs-we-should-set", bkpinfo->tmpdir);
2275    if (!(fbw = fopen(biggies_whose_EXATs_we_should_set, "w"))) {
2276        log_msg(1, "Warning - cannot openout %s",
2277                biggies_whose_EXATs_we_should_set);
2278    }
2279// get xattr and acl files if they're there
2280    res =
2281        read_header_block_from_stream(&biggie_size, biggie_fname,
2282                                      &ctrl_chr);
2283    if (ctrl_chr == BLK_START_EXTENDED_ATTRIBUTES) {
2284        res =
2285            read_EXAT_files_from_tape(bkpinfo, &biggie_size, biggie_fname,
2286                                      &ctrl_chr, xattr_fname, acl_fname);
2287    }
2288
2289    noof_biggiefiles = atol(biggie_fname);
2290    mr_asprintf(&tmp, "OK, there are %ld biggiefiles in the archives",
2291            noof_biggiefiles);
2292    log_msg(2, tmp);
2293    mr_free(tmp);
2294
2295    open_progress_form(_("Reassembling large files"),
2296                       _("I am now reassembling all the large files."),
2297                       _("Please wait. This may take some time."),
2298                       "", total_slices);
2299
2300    for (res =
2301         read_header_block_from_stream(&biggie_size, biggie_fname,
2302                                       &ctrl_chr);
2303         ctrl_chr != BLK_STOP_BIGGIEFILES;
2304         res =
2305         read_header_block_from_stream(&biggie_size, biggie_fname,
2306                                       &ctrl_chr)) {
2307        if (ctrl_chr != BLK_START_A_NORMBIGGIE
2308            && ctrl_chr != BLK_START_A_PIHBIGGIE) {
2309            wrong_marker(BLK_START_A_NORMBIGGIE, ctrl_chr);
2310        }
2311        /* BERLIOS: useless
2312        p = strrchr(biggie_fname, '/');
2313        if (!p) {
2314            p = biggie_fname;
2315        } else {
2316            p++;
2317        }
2318        */
2319        mr_asprintf(&tmp, _("Restoring big file %ld (%lld K)"),
2320                current_bigfile_number + 1, biggie_size / 1024);
2321        update_progress_form(tmp);
2322        mr_free(tmp);
2323
2324        pathname_of_last_biggie_restored = restore_a_biggiefile_from_stream(bkpinfo, biggie_fname,
2325                                               current_bigfile_number,
2326                                               filelist, ctrl_chr);
2327        log_msg(1, "I believe I have restored %s",
2328                pathname_of_last_biggie_restored);
2329        if (fbw && pathname_of_last_biggie_restored[0]) {
2330            fprintf(fbw, "%s\n", pathname_of_last_biggie_restored);
2331        }
2332        mr_free(pathname_of_last_biggie_restored);
2333
2334        retval += res;
2335        current_bigfile_number++;
2336
2337    }
2338    if (current_bigfile_number != noof_biggiefiles
2339        && noof_biggiefiles != 0) {
2340        mr_asprintf(&tmp, "Warning - bigfileno=%ld but noof_biggiefiles=%ld\n",
2341                current_bigfile_number, noof_biggiefiles);
2342    } else {
2343        mr_asprintf(&tmp,
2344                "%ld biggiefiles in biggielist.txt; %ld biggiefiles processed today.",
2345                noof_biggiefiles, current_bigfile_number);
2346    }
2347    log_msg(1, tmp);
2348    mr_free(tmp);
2349
2350    if (fbw) {
2351        fclose(fbw);
2352        if (length_of_file(biggies_whose_EXATs_we_should_set) > 2) {
2353            iamhere("Setting biggie-EXATs");
2354            if (length_of_file(acl_fname) > 0) {
2355                log_msg(1, "set_acl_list(%s,%s)",
2356                        biggies_whose_EXATs_we_should_set, acl_fname);
2357                set_acl_list(biggies_whose_EXATs_we_should_set, acl_fname);
2358            }
2359            if (length_of_file(xattr_fname) > 0) {
2360                log_msg(1, "set_fattr_List(%s,%s)",
2361                        biggies_whose_EXATs_we_should_set, xattr_fname);
2362                set_fattr_list(biggies_whose_EXATs_we_should_set,
2363                               xattr_fname);
2364            }
2365        } else {
2366            iamhere
2367                ("No biggiefiles selected. So, no biggie-EXATs to set.");
2368        }
2369    }
2370    mr_free(xattr_fname);
2371    mr_free(acl_fname);
2372    mr_free(biggies_whose_EXATs_we_should_set);
2373
2374    if (does_file_exist("/PAUSE")) {
2375        popup_and_OK
2376            (_
2377             ("Press ENTER to go on. Delete /PAUSE to stop these pauses."));
2378    }
2379
2380    close_progress_form();
2381    if (retval) {
2382        mvaddstr_and_log_it(g_currentY++, 74, _("Errors."));
2383    } else {
2384        mvaddstr_and_log_it(g_currentY++, 74, _("Done."));
2385    }
2386    mr_free(biggie_fname);
2387    return (retval);
2388}
2389
2390/**************************************************************************
2391 *END_RESTORE_ALL_BIGGIEFILES_FROM_STREAM                                 *
2392 **************************************************************************/
2393
2394
2395/**
2396 * Restore all afioballs from the currently opened tape stream.
2397 * @param bkpinfo The backup information structure. Fields used:
2398 * - @c bkpinfo->backup_media_type
2399 * - @c bkpinfo->restore_path
2400 * @param filelist The node structure containing the list of files to be
2401 * restored. If no file in an afioball is in this list, afio will still be
2402 * called for that fileset, but nothing will be written.
2403 * @return 0 for success, or the number of filesets that failed.
2404 */
2405int
2406restore_all_tarballs_from_stream(struct s_bkpinfo *bkpinfo,
2407                                 struct s_node *filelist)
2408{
2409    int retval = 0;
2410    int res;
2411    long current_afioball_number = 0;
2412    int ctrl_chr;
2413    long max_val /*, total_noof_files */ ;
2414
2415  /** malloc **/
2416    char *tmp = NULL;
2417    char *progress_str = NULL;
2418    char *tmp_fname = NULL;
2419    char *xattr_fname = NULL;
2420    char *acl_fname = NULL;
2421
2422    long long tmp_size;
2423
2424    assert(bkpinfo != NULL);
2425    mvaddstr_and_log_it(g_currentY, 0, _("Restoring from archives"));
2426    read_cfg_var(g_mondo_cfg_file, "last-filelist-number", tmp);
2427    max_val = atol(tmp) + 1;
2428    mr_free(tmp);
2429
2430    chdir(bkpinfo->restore_path);   /* I don't know why this is needed _here_ but it seems to be. -HR, 02/04/2002 */
2431
2432    run_program_and_log_output("pwd", 5);
2433
2434    mr_asprintf(&progress_str, _("Restoring from media #%d"),
2435            g_current_media_number);
2436    log_to_screen(progress_str);
2437    open_progress_form(_("Restoring from archives"),
2438                       _("Restoring data from the archives."),
2439                       _("Please wait. This may take some time."),
2440                       progress_str, max_val);
2441
2442    log_msg(3, "hey");
2443
2444    res = read_header_block_from_stream(&tmp_size, tmp_fname, &ctrl_chr);
2445    if (res) {
2446        log_msg(2, "Warning - error reading afioball from tape");
2447    }
2448    retval += res;
2449    if (ctrl_chr != BLK_START_AFIOBALLS) {
2450        wrong_marker(BLK_START_AFIOBALLS, ctrl_chr);
2451    }
2452    log_msg(2, "ho");
2453    res = read_header_block_from_stream(&tmp_size, tmp_fname, &ctrl_chr);
2454    while (ctrl_chr != BLK_STOP_AFIOBALLS) {
2455        update_progress_form(progress_str);
2456        mr_asprintf(&xattr_fname, "%s/xattr-subset-%ld.tmp", bkpinfo->tmpdir,
2457                current_afioball_number);
2458        mr_asprintf(&acl_fname, "%s/acl-subset-%ld.tmp", bkpinfo->tmpdir,
2459                current_afioball_number);
2460        unlink(xattr_fname);
2461        unlink(acl_fname);
2462        if (ctrl_chr == BLK_START_EXTENDED_ATTRIBUTES) {
2463            iamhere("Reading EXAT files from tape");
2464            res =
2465                read_EXAT_files_from_tape(bkpinfo, &tmp_size, tmp_fname,
2466                                          &ctrl_chr, xattr_fname,
2467                                          acl_fname);
2468        }
2469        if (ctrl_chr != BLK_START_AN_AFIO_OR_SLICE) {
2470            wrong_marker(BLK_START_AN_AFIO_OR_SLICE, ctrl_chr);
2471        }
2472        /* BERLIOS: useless ?
2473        mr_asprintf(&tmp,
2474                _("Restoring from fileset #%ld (name=%s, size=%ld K)"),
2475                current_afioball_number, tmp_fname, (long) tmp_size >> 10);
2476                */
2477        res =
2478            restore_a_tarball_from_stream(bkpinfo, tmp_fname,
2479                                          current_afioball_number,
2480                                          filelist, tmp_size, xattr_fname,
2481                                          acl_fname);
2482        retval += res;
2483        if (res) {
2484            mr_asprintf(&tmp, _("Fileset %ld - errors occurred"),
2485                    current_afioball_number);
2486            log_to_screen(tmp);
2487            mr_free(tmp);
2488        }
2489        res =
2490            read_header_block_from_stream(&tmp_size, tmp_fname, &ctrl_chr);
2491        if (ctrl_chr != BLK_STOP_AN_AFIO_OR_SLICE) {
2492            wrong_marker(BLK_STOP_AN_AFIO_OR_SLICE, ctrl_chr);
2493        }
2494
2495        current_afioball_number++;
2496        g_current_progress++;
2497
2498        mr_free(progress_str);
2499        mr_asprintf(&progress_str, _("Restoring from fileset #%ld on %s #%d"),
2500                current_afioball_number,
2501                bkpinfo->backup_media_string,
2502                g_current_media_number);
2503        res =
2504            read_header_block_from_stream(&tmp_size, tmp_fname, &ctrl_chr);
2505        unlink(xattr_fname);
2506        unlink(acl_fname);
2507        mr_free(xattr_fname);
2508        mr_free(acl_fname);
2509    }                           // next
2510    mr_free(progress_str);
2511    mr_free(tmp_fname);
2512
2513    log_msg(1, "All done with afioballs");
2514    close_progress_form();
2515    if (retval) {
2516        mvaddstr_and_log_it(g_currentY++, 74, _("Errors."));
2517    } else {
2518        mvaddstr_and_log_it(g_currentY++, 74, _("Done."));
2519    }
2520    return (retval);
2521}
2522
2523/**************************************************************************
2524 *END_ RESTORE_ALL_TARBALLS_FROM_STREAM                                   *
2525 **************************************************************************/
2526
2527/* @} - end of LLrestoreGroup */
2528
2529
2530/**
2531 * Restore all files in @p filelist.
2532 * @param bkpinfo The backup information structure. Most fields are used.
2533 * @param filelist The node structure containing the list of files to be
2534 * restored.
2535 * @return 0 for success, or the number of afioballs and biggiefiles that failed.
2536 * @ingroup restoreGroup
2537 */
2538int restore_everything(struct s_bkpinfo *bkpinfo, struct s_node *filelist)
2539{
2540    int resA;
2541    int resB;
2542
2543  /** mallco ***/
2544    char *cwd = NULL;
2545    char *newpath = NULL;
2546    char *tmp = NULL;
2547    assert(bkpinfo != NULL);
2548
2549    malloc_string(cwd);
2550    malloc_string(newpath);
2551    log_msg(2, "restore_everything() --- starting");
2552    g_current_media_number = 1;
2553    /* BERLIOS: should test return value, or better change the function */
2554    getcwd(cwd, MAX_STR_LEN - 1);
2555    mr_asprintf(&tmp, "mkdir -p %s", bkpinfo->restore_path);
2556    run_program_and_log_output(tmp, FALSE);
2557    mr_free(tmp);
2558
2559    log_msg(1, "Changing dir to %s", bkpinfo->restore_path);
2560    chdir(bkpinfo->restore_path);
2561    /* BERLIOS: should test return value, or better change the function */
2562    getcwd(newpath, MAX_STR_LEN - 1);
2563    log_msg(1, "path is now %s", newpath);
2564    log_msg(1, "restoring everything");
2565    tmp = find_home_of_exe("petris");
2566    if (!tmp && !g_text_mode) {
2567        newtDrawRootText(0, g_noof_rows - 2,
2568                         _
2569                         ("Press ALT-<left cursor> twice to play Petris :-) "));
2570        newtRefresh();
2571    }
2572    mr_free(tmp);
2573
2574    mvaddstr_and_log_it(g_currentY, 0,
2575                        _("Preparing to read your archives"));
2576    if (IS_THIS_A_STREAMING_BACKUP(bkpinfo->backup_media_type)) {
2577        mount_cdrom(bkpinfo);
2578        mvaddstr_and_log_it(g_currentY++, 0,
2579                            _
2580                            ("Restoring OS and data from streaming media"));
2581        if (bkpinfo->backup_media_type == cdstream) {
2582            openin_cdstream(bkpinfo);
2583        } else {
2584            assert_string_is_neither_NULL_nor_zerolength(bkpinfo->
2585                                                         media_device);
2586            openin_tape(bkpinfo);
2587        }
2588        resA = restore_all_tarballs_from_stream(bkpinfo, filelist);
2589        resB = restore_all_biggiefiles_from_stream(bkpinfo, filelist);
2590        if (bkpinfo->backup_media_type == cdstream) {
2591            closein_cdstream(bkpinfo);
2592        } else {
2593            closein_tape(bkpinfo);
2594        }
2595    } else {
2596        mvaddstr_and_log_it(g_currentY++, 0,
2597                            _("Restoring OS and data from CD       "));
2598        mount_cdrom(bkpinfo);
2599        resA = restore_all_tarballs_from_CD(bkpinfo, filelist);
2600        resB = restore_all_biggiefiles_from_CD(bkpinfo, filelist);
2601    }
2602    chdir(cwd);
2603    if (resA + resB) {
2604        log_to_screen(_("Errors occurred while data was being restored."));
2605    }
2606    if (length_of_file("/etc/raidtab") > 0) {
2607        log_msg(2, "Copying local raidtab to restored filesystem");
2608        run_program_and_log_output("cp -f /etc/raidtab " MNT_RESTORING
2609                                   "/etc/raidtab", FALSE);
2610    }
2611    kill_petris();
2612    log_msg(2, "restore_everything() --- leaving");
2613    mr_free(cwd);
2614    mr_free(newpath);
2615    return (resA + resB);
2616}
2617
2618/**************************************************************************
2619 *END_RESTORE_EVERYTHING                                                  *
2620 **************************************************************************/
2621
2622
2623/**
2624 * @brief Haha. You wish! (This function is not implemented :-)
2625 */
2626int
2627restore_live_from_monitas_server(struct s_bkpinfo *bkpinfo,
2628                                 char *monitas_device,
2629                                 char *restore_this_directory,
2630                                 char *restore_here)
2631     /* NB: bkpinfo hasn't been populated yet, except for ->tmp which is "/tmp" */
2632{
2633    FILE *fout;
2634    int retval = 0;
2635    int i;
2636    int j;
2637    struct mountlist_itself the_mountlist;
2638    static struct raidlist_itself the_raidlist;
2639  /** malloc **/
2640    char tmp[MAX_STR_LEN + 1];
2641    char command[MAX_STR_LEN + 1];
2642    char datablock[256 * 1024];
2643    char datadisks_fname[MAX_STR_LEN + 1];
2644    long k;
2645    long length;
2646    long long llt;
2647    struct s_node *filelist = NULL;
2648    assert(bkpinfo != NULL);
2649    assert_string_is_neither_NULL_nor_zerolength(monitas_device);
2650    assert(restore_this_directory != NULL);
2651    assert(restore_here != NULL);
2652
2653    sprintf(tmp, "restore_here = '%s'", restore_here);
2654
2655    log_msg(2, tmp);
2656
2657    log_msg(2, "restore_live_from_monitas_server() - starting");
2658    unlink("/tmp/mountlist.txt");
2659    unlink("/tmp/filelist.full");
2660    unlink("/tmp/biggielist.txt");
2661    if (restore_here[0] == '\0') {
2662        strcpy(bkpinfo->restore_path, MNT_RESTORING);
2663    } else {
2664        strcpy(bkpinfo->restore_path, restore_here);
2665    }
2666    log_msg(3, "FYI FYI FYI FYI FYI FYI FYI FYI FYI FYI FYI");
2667    sprintf(tmp, "FYI - data will be restored to %s",
2668            bkpinfo->restore_path);
2669    log_msg(3, tmp);
2670    log_msg(3, "FYI FYI FYI FYI FYI FYI FYI FYI FYI FYI FYI");
2671    sprintf(datadisks_fname, "/tmp/mondorestore.datadisks.%d",
2672            (int) (random() % 32768));
2673    chdir(bkpinfo->tmpdir);
2674
2675    sprintf(command, "cat %s", monitas_device);
2676    g_tape_stream = popen(command, "r");    // for compatibility with openin_tape()
2677    if (!(fout = fopen(datadisks_fname, "w"))) {
2678        log_OS_error(datadisks_fname);
2679        return (1);
2680    }
2681    for (i = 0; i < 32; i++) {
2682        for (j = 0; j < 4; j++) {
2683            for (length = k = 0; length < 256 * 1024; length += k) {
2684                k = fread(datablock + length, 1, 256 * 1024 - length,
2685                          g_tape_stream);
2686            }
2687            fwrite(datablock, 1, length, fout);
2688            g_tape_posK += length;
2689        }
2690    }
2691    paranoid_fclose(fout);
2692    sprintf(command,
2693            "tar -zxvf %s tmp/mondo-restore.cfg tmp/mountlist.txt tmp/filelist.full tmp/biggielist.txt",
2694            datadisks_fname);
2695    run_program_and_log_output(command, 4);
2696    read_header_block_from_stream(&llt, tmp, &i);
2697    read_header_block_from_stream(&llt, tmp, &i);
2698
2699    unlink(datadisks_fname);
2700    read_cfg_file_into_bkpinfo(g_mondo_cfg_file, bkpinfo);
2701    retval = load_mountlist(&the_mountlist, g_mountlist_fname); // in case read_cfg_file_into_bkpinfo   strcpy(bkpinfo->media_device, monitas_device);
2702
2703
2704    load_raidtab_into_raidlist(&the_raidlist, RAIDTAB_FNAME);
2705    iamhere("FIXME");
2706    fatal_error("This will fail");
2707    sprintf(command,
2708            "grep -E '^%s.*$' %s > %s",
2709            restore_this_directory, g_filelist_full, g_filelist_full);
2710    if (system(command)) {
2711        retval++;
2712        log_to_screen
2713            ("Error(s) occurred while processing filelist and wildcard");
2714    }
2715    iamhere("FIXME");
2716    fatal_error("This will fail");
2717    sprintf(command,
2718            "grep -E '^%s.*$' %s > %s",
2719            restore_this_directory, g_biggielist_txt, g_biggielist_txt);
2720    if (system(command)) {
2721        log_msg(1,
2722                "Error(s) occurred while processing biggielist and wildcard");
2723    }
2724    sprintf(command, "touch %s", g_biggielist_txt);
2725    run_program_and_log_output(command, FALSE);
2726//  filelist = load_filelist(g_filelist_restthese);  // FIXME --- this probably doesn't work because it doesn't include the biggiefiles
2727    retval += restore_everything(bkpinfo, filelist);
2728    free_filelist(filelist);
2729    log_msg(2, "--------End of restore_live_from_monitas_server--------");
2730    return (retval);
2731}
2732
2733/**************************************************************************
2734 *END_RESTORE_LIVE_FROM_MONITAS_SERVER                                    *
2735 **************************************************************************/
2736
2737
2738
2739
2740>>>>>>> .fusion-droit.r913
2741extern void wait_until_software_raids_are_prepped(char *, int);
2742
2743char which_restore_mode(void);
2744
2745
2746/**
2747 * Log a "don't panic" message to the logfile.
2748 */
2749void welcome_to_mondorestore()
2750{
2751    log_msg(0, "-------------- Mondo Restore v%s -------------",
2752            PACKAGE_VERSION);
2753    log_msg(0,
2754            "DON'T PANIC! Mondorestore logs almost everything, so please ");
2755    log_msg(0,
2756            "don't break out in a cold sweat just because you see a few  ");
2757    log_msg(0,
2758            "error messages in the log. Read them; analyze them; see if  ");
2759    log_msg(0,
2760            "they are significant; above all, verify your backups! Please");
2761    log_msg(0,
2762            "attach a compressed copy of this log to any e-mail you send ");
2763    log_msg(0,
2764            "to the Mondo mailing list when you are seeking technical    ");
2765    log_msg(0,
2766            "support. Without it, we can't help you.            - DevTeam");
2767    log_msg(0,
2768            "------------------------------------------------------------");
2769    log_msg(0,
2770            "BTW, despite (or perhaps because of) the wealth of messages,");
2771    log_msg(0,
2772            "some users are inclined to stop reading this log.  If Mondo ");
2773    log_msg(0,
2774            "stopped for some reason, chances are it's detailed here.    ");
2775    log_msg(0,
2776            "More than likely there's a message near the end of this     ");
2777    log_msg(0,
2778            "log that will tell you what is wrong.  Please read it!      ");
2779    log_msg(0,
2780            "------------------------------------------------------------");
2781}
2782
2783
2784/**
2785 * Restore the user's data.
2786 * What did you think it did, anyway? :-)
2787 */
2788int main(int argc, char *argv[])
2789{
2790    FILE *fin = NULL;
2791    FILE *fout = NULL;
2792    int retval = 0;
2793    int res = 0;
2794    char *tmp = NULL;
2795
2796    struct mountlist_itself *mountlist = NULL;
2797    struct raidlist_itself *raidlist = NULL;
2798    struct s_bkpinfo *bkpinfo = NULL;
2799    struct s_node *filelist = NULL;
2800    char *a = NULL, *b = NULL;
2801    bool run_postnuke = FALSE;
2802
2803  /**************************************************************************
2804   * hugo-                                                                  *
2805   * busy stuff here - it needs some comments -stan                           *
2806   *                                                                        *
2807   **************************************************************************/
2808
2809#ifdef ENABLE_NLS
2810    setlocale(LC_ALL, "");
2811    (void) textdomain("mondo");
2812#endif
2813
2814    if (getuid() != 0) {
2815        fprintf(stderr, _("Please run as root.\n"));
2816        exit(127);
2817    }
2818
2819    g_loglevel = DEFAULT_MR_LOGLEVEL;
2820
2821/* Configure global variables */
2822#ifdef __FreeBSD__
2823    tmp = call_program_and_get_last_line_of_output("cat /tmp/cmdline");
2824#else
2825    tmp = call_program_and_get_last_line_of_output("cat /proc/cmdline");
2826#endif
2827    if (strstr(tmp,"textonly")) {
2828        g_text_mode = TRUE;
2829        log_msg(1, "TEXTONLY MODE");
2830    } else {
2831        g_text_mode = FALSE;
2832    }                           // newt :-)
2833    mr_free(tmp);
2834
2835    if (!
2836        (bkpinfo = g_bkpinfo_DONTUSETHIS =
2837         malloc(sizeof(struct s_bkpinfo)))) {
2838        fatal_error("Cannot malloc bkpinfo");
2839    }
2840    if (!(mountlist = malloc(sizeof(struct mountlist_itself)))) {
2841        fatal_error("Cannot malloc mountlist");
2842    }
2843    if (!(raidlist = malloc(sizeof(struct raidlist_itself)))) {
2844        fatal_error("Cannot malloc raidlist");
2845    }
2846
2847    malloc_libmondo_global_strings();
2848
2849    g_mondo_home = call_program_and_get_last_line_of_output("which mondorestore");
2850    mr_allocstr(g_tmpfs_mountpt, "/tmp/tmpfs");
2851    make_hole_for_dir(g_tmpfs_mountpt);
2852    g_current_media_number = 1; // precaution
2853
2854    run_program_and_log_output("mkdir -p " MNT_CDROM, FALSE);
2855    run_program_and_log_output("mkdir -p /mnt/floppy", FALSE);
2856
2857    setup_MR_global_filenames(bkpinfo); // malloc() and set globals, using bkpinfo->tmpdir etc.
2858    reset_bkpinfo(bkpinfo);
2859    bkpinfo->backup_media_type = none;  // in case boot disk was made for one backup type but user wants to restore from another backup type
2860    bkpinfo->backup_media_string = NULL;
2861    bkpinfo->restore_data = TRUE;   // Well, yeah :-)
2862    if (am_I_in_disaster_recovery_mode()) {
2863        run_program_and_log_output("mount / -o remount,rw", 2);
2864    }                           // for b0rken distros
2865    g_main_pid = getpid();
2866    srandom((int) (time(NULL)));
2867    register_pid(getpid(), "mondo");
2868    set_signals(TRUE);
2869    g_kernel_version = get_kernel_version();
2870
2871    log_msg(1, "FYI - g_mountlist_fname = %s", g_mountlist_fname);
2872    mkdir(MNT_CDROM, 0x770);
2873
2874/* Backup original mountlist.txt */
2875    mr_asprintf(&tmp, "%s.orig", g_mountlist_fname);
2876    if (!does_file_exist(g_mountlist_fname)) {
2877        log_msg(2,
2878                "%ld: Warning - g_mountlist_fname (%s) does not exist yet",
2879                __LINE__, g_mountlist_fname);
2880    } else if (!does_file_exist(tmp)) {
2881        mr_free(tmp);
2882        mr_asprintf(&tmp, "cp -f %s %s.orig", g_mountlist_fname,
2883                g_mountlist_fname);
2884        run_program_and_log_output(tmp, FALSE);
2885    }
2886    mr_free(tmp);
2887
2888/* Init directories */
2889    make_hole_for_dir(bkpinfo->tmpdir);
2890    mr_asprintf(&tmp, "mkdir -p %s", bkpinfo->tmpdir);
2891    run_program_and_log_output(tmp, FALSE);
2892    mr_free(tmp);
2893
2894    make_hole_for_dir("/var/log");
2895    make_hole_for_dir("/tmp/tmpfs");    /* just in case... */
2896    run_program_and_log_output("umount " MNT_CDROM, FALSE);
2897    run_program_and_log_output
2898        ("ln -sf " MONDO_LOGFILE " /tmp/mondo-restore.log", FALSE);
2899
2900    run_program_and_log_output("rm -Rf /tmp/tmpfs/mondo.tmp.*", FALSE);
2901
2902/* Init GUI */
2903    malloc_libmondo_global_strings();
2904    setup_newt_stuff();         /* call newtInit and setup screen log */
2905    welcome_to_mondorestore();
2906    if (bkpinfo->disaster_recovery) {
2907        log_msg(1, "I am in disaster recovery mode");
2908    } else {
2909        log_msg(1, "I am in normal, live mode");
2910    }
2911
2912    iamhere("what time is it");
2913
2914/* Process command-line parameters */
2915    if (argc == 2 && strcmp(argv[1], "--edit-mountlist") == 0) {
2916#ifdef __FreeBSD__
2917        system("mv -f /tmp/raidconf.txt /etc/raidtab");
2918        if (!does_file_exist("/etc/raidtab"))
2919            system("vinum printconfig > /etc/raidtab");
2920#endif
2921        load_raidtab_into_raidlist(raidlist, RAIDTAB_FNAME);
2922        if (!does_file_exist(g_mountlist_fname)) {
2923            mr_allocstr(g_mountlist_fname, "/tmp/mountlist.txt");
2924        }
2925        res = let_user_edit_the_mountlist(bkpinfo, mountlist, raidlist);
2926#ifdef __FreeBSD__
2927        system("mv -f /etc/raidtab /tmp/raidconf.txt");
2928#endif
2929        paranoid_MR_finish(res);
2930    }
2931
2932    g_loglevel = DEFAULT_MR_LOGLEVEL;
2933    if (argc == 3 && strcmp(argv[1], "--echo-to-screen") == 0) {
2934        fout = fopen("/tmp/out.txt", "w");
2935        fput_string_one_char_at_a_time(stderr, argv[2]);
2936        finish(0);
2937    }
2938
2939    if (argc == 3 && strcmp(argv[1], "--gendf") == 0) {
2940        make_grub_install_scriptlet(argv[2]);
2941        finish(0);
2942    }
2943
2944    if (argc >= 2 && strcmp(argv[1], "--pih") == 0) {
2945        if (system("mount | grep cdrom 2> /dev/null > /dev/null")) {
2946            system("mount " MNT_CDROM);
2947        }
2948        bkpinfo->compression_level = 1;
2949        g_current_media_number = 2;
2950        mr_allocstr(bkpinfo->restore_path, "/tmp/TESTING");
2951        bkpinfo->backup_media_type = dvd;
2952        mr_free(bkpinfo->backup_media_string);
2953        bkpinfo->backup_media_string = bkptype_to_string(bkpinfo->backup_media_type);
2954        open_progress_form(_("Reassembling /dev/hda1"),
2955                           _("Shark is a bit of a silly person."),
2956                           _("Please wait. This may take some time."),
2957                           "", 1999);
2958        system("rm -Rf /tmp/*pih*");
2959
2960        (void)restore_a_biggiefile_from_CD(bkpinfo, 42, NULL);
2961    }
2962
2963    if (argc == 5 && strcmp(argv[1], "--common") == 0) {
2964        g_loglevel = 6;
2965        filelist = load_filelist(argv[2]);
2966        if (!filelist) {
2967            fatal_error("Failed to load filelist");
2968        }
2969        toggle_node_selection(filelist, FALSE);
2970        toggle_all_root_dirs_on(filelist);
2971        // BERLIOS: /usr/lib ???
2972        toggle_path_selection(filelist, "/usr/share", TRUE);
2973//      show_filelist(filelist);
2974        save_filelist(filelist, "/tmp/out.txt");
2975//      finish(0);
2976//      toggle_path_selection (filelist, "/root/stuff", TRUE);
2977        mr_asprintf(&a, argv[3]);
2978        mr_asprintf(&b, argv[4]);
2979
2980        res = save_filelist_entries_in_common(a, filelist, b, FALSE);
2981        free_filelist(filelist);
2982        mr_free(a);
2983        mr_free(b);
2984        printf("res = %d", res);
2985        finish(0);
2986    }
2987
2988    if (argc == 3 && strcmp(argv[1], "--popuplist") == 0) {
2989        popup_changelist_from_file(argv[2]);
2990        paranoid_MR_finish(0);
2991    }
2992
2993    if (argc == 5 && strcmp(argv[1], "--copy") == 0) {
2994        log_msg(1, "SCORE");
2995        g_loglevel = 10;
2996        if (strstr(argv[2], "save")) {
2997            log_msg(1, "Saving from %s to %s", argv[3], argv[4]);
2998            fin = fopen(argv[3], "r");
2999            fout = fopen(argv[4], "w");
3000            copy_from_src_to_dest(fin, fout, 'w');
3001            fclose(fin);
3002            fin = fopen(argv[3], "r");
3003            copy_from_src_to_dest(fin, fout, 'w');
3004            fclose(fout);
3005            fclose(fin);
3006        } else if (strstr(argv[2], "restore")) {
3007            fout = fopen(argv[3], "w");
3008            fin = fopen(argv[4], "r");
3009            copy_from_src_to_dest(fout, fin, 'r');
3010            fclose(fin);
3011            fin = fopen(argv[4], "r");
3012            copy_from_src_to_dest(fout, fin, 'r');
3013            fclose(fout);
3014            fclose(fin);
3015        } else {
3016            fatal_error("Unknown additional param");
3017        }
3018        finish(0);
3019    }
3020
3021    if (argc == 3 && strcmp(argv[1], "--mdstat") == 0) {
3022        wait_until_software_raids_are_prepped(argv[2], 100);
3023        finish(0);
3024    }
3025
3026    if (argc == 3 && strcmp(argv[1], "--mdconv") == 0) {
3027        finish(create_raidtab_from_mdstat(argv[2]));
3028    }
3029
3030
3031    if (argc == 2 && strcmp(argv[1], "--live-grub") == 0) {
3032        retval = run_grub(FALSE, "/dev/hda");
3033        if (retval) {
3034            log_to_screen(_("Failed to write Master Boot Record"));
3035        }
3036        paranoid_MR_finish(0);
3037    }
3038    if (argc == 3 && strcmp(argv[1], "--paa") == 0) {
3039        g_current_media_number = atoi(argv[2]);
3040        pause_and_ask_for_cdr(5, NULL);
3041        paranoid_MR_finish(0);
3042    } else if (!bkpinfo->disaster_recovery) {   // live!
3043        if (argc != 1) {
3044            popup_and_OK
3045                (_
3046                 ("Live mode doesn't support command-line parameters yet."));
3047            paranoid_MR_finish(1);
3048//    return(1);
3049        }
3050        log_msg(1, "I am in normal, live mode.");
3051        log_msg(2, "FYI, MOUNTLIST_FNAME = %s", g_mountlist_fname);
3052        mount_boot_if_necessary();  /* for Gentoo users */
3053        log_msg(2, "Still here.");
3054        if (argc > 1 && strcmp(argv[argc - 1], "--live-from-cd") == 0) {
3055            g_restoring_live_from_cd = TRUE;
3056        } else {
3057            log_msg(2, "Calling restore_to_live_filesystem()");
3058            retval = restore_to_live_filesystem(bkpinfo);
3059        }
3060        log_msg(2, "Still here. Yay.");
3061        if (strlen(bkpinfo->tmpdir) > 0) {
3062            mr_asprintf(&tmp, "rm -Rf %s/*", bkpinfo->tmpdir);
3063            run_program_and_log_output(tmp, FALSE);
3064            mr_free(tmp);
3065        }
3066        unmount_boot_if_necessary();    /* for Gentoo users */
3067        paranoid_MR_finish(retval);
3068    } else {
3069        /* Disaster recovery mode (must be) */
3070        log_msg(1, "I must be in disaster recovery mode.");
3071        log_msg(2, "FYI, MOUNTLIST_FNAME = %s ", g_mountlist_fname);
3072        if (argc == 3 && strcmp(argv[1], "--monitas-memorex") == 0) {
3073            log_to_screen(_("Uh, that hasn't been implemented yet."));
3074            paranoid_MR_finish(1);
3075        }
3076
3077        iamhere("About to call load_mountlist and load_raidtab");
3078        mr_allocstr(bkpinfo->restore_path, MNT_RESTORING);
3079        read_cfg_file_into_bkpinfo(g_mondo_cfg_file, bkpinfo);
3080        retval = load_mountlist(mountlist, g_mountlist_fname);
3081        retval += load_raidtab_into_raidlist(raidlist, RAIDTAB_FNAME);
3082        iamhere
3083            ("Returned from calling load_mountlist and load_raidtab successfully");
3084
3085        if (argc > 1
3086            && (strcmp(argv[1], "--compare") == 0
3087                || strcmp(argv[1], "--nuke") == 0)) {
3088            if (bkpinfo->backup_media_type == nfs
3089                && !is_this_device_mounted(bkpinfo->nfs_mount)) {
3090                log_msg(1, "Mounting nfs dir");
3091                mr_allocstr(bkpinfo->isodir, "/tmp/isodir");
3092                run_program_and_log_output("mkdir -p /tmp/isodir", 5);
3093                mr_asprintf(&tmp, "mount %s -t nfs -o nolock /tmp/isodir",
3094                        bkpinfo->nfs_mount);
3095                run_program_and_log_output(tmp, 1);
3096                mr_free(tmp);
3097            }
3098        }
3099
3100
3101        if (retval) {
3102            log_to_screen
3103                (_
3104                 ("Warning - load_raidtab_into_raidlist returned an error"));
3105        }
3106
3107
3108        log_msg(1, "Send in the clowns.");
3109
3110        if (argc == 2 && strcmp(argv[1], "--partition-only") == 0) {
3111            log_msg(0, "Partitioning only.");
3112            load_raidtab_into_raidlist(raidlist, RAIDTAB_FNAME);
3113            mr_allocstr(g_mountlist_fname, "/tmp/mountlist.txt");
3114            load_mountlist(mountlist, g_mountlist_fname);
3115            res = partition_everything(mountlist);
3116            finish(res);
3117        }
3118
3119        if (argc == 2 && strcmp(argv[1], "--format-only") == 0) {
3120            log_msg(0, "Formatting only.");
3121            load_raidtab_into_raidlist(raidlist, RAIDTAB_FNAME);
3122            mr_allocstr(g_mountlist_fname, "/tmp/mountlist.txt");
3123            load_mountlist(mountlist, g_mountlist_fname);
3124            res = format_everything(mountlist, FALSE, raidlist);
3125            finish(res);
3126        }
3127
3128        if (argc == 2 && strcmp(argv[1], "--stop-lvm-and-raid") == 0) {
3129            log_msg(0, "Stopping LVM and RAID");
3130            load_raidtab_into_raidlist(raidlist, RAIDTAB_FNAME);
3131            mr_allocstr(g_mountlist_fname, "/tmp/mountlist.txt");
3132            load_mountlist(mountlist, g_mountlist_fname);
3133            res = do_my_funky_lvm_stuff(TRUE, FALSE);
3134            res += stop_all_raid_devices(mountlist);
3135            finish(res);
3136        }
3137
3138        if (argc == 2 && strcmp(argv[1], "--nuke") == 0) {
3139            iamhere("nuking");
3140            retval += nuke_mode(bkpinfo, mountlist, raidlist);
3141        } else if (argc == 2 && strcmp(argv[1], "--interactive") == 0) {
3142            iamhere("catchall");
3143            retval += catchall_mode(bkpinfo, mountlist, raidlist);
3144        } else if (argc == 2 && strcmp(argv[1], "--compare") == 0) {
3145            iamhere("compare");
3146            retval += compare_mode(bkpinfo, mountlist, raidlist);
3147        } else if (argc == 2 && strcmp(argv[1], "--iso") == 0) {
3148            iamhere("iso");
3149            retval = iso_mode(bkpinfo, mountlist, raidlist, FALSE);
3150        } else if (argc == 2 && strcmp(argv[1], "--mbr") == 0) {
3151            iamhere("mbr");
3152            retval = mount_all_devices(mountlist, TRUE);
3153            if (!retval) {
3154                retval += run_boot_loader(FALSE);
3155                retval += unmount_all_devices(mountlist);
3156            }
3157            if (retval) {
3158                log_to_screen(_("Failed to write Master Boot Record"));
3159            }
3160        } else if (argc == 2 && strcmp(argv[1], "--isonuke") == 0) {
3161            iamhere("isonuke");
3162            retval = iso_mode(bkpinfo, mountlist, raidlist, TRUE);
3163        } else if (argc != 1) {
3164            log_to_screen(_("Invalid paremeters"));
3165            paranoid_MR_finish(1);
3166        } else {
3167            iamhere("catchall (no mode specified in command-line call");
3168            retval += catchall_mode(bkpinfo, mountlist, raidlist);
3169        }
3170    }
3171
3172    /* clean up at the end */
3173    if (retval) {
3174        if (does_file_exist("/tmp/changed.files")) {
3175            log_to_screen
3176                (_
3177                 ("See /tmp/changed.files for list of files that have changed."));
3178        }
3179        mvaddstr_and_log_it(g_currentY++,
3180                            0,
3181                            _
3182                            ("Run complete. Errors were reported. Please review the logfile."));
3183    } else {
3184        if (IS_THIS_A_STREAMING_BACKUP(bkpinfo->backup_media_type)) {
3185            mvaddstr_and_log_it(g_currentY++,
3186                                0,
3187                                _
3188                                ("Run complete. Please remove floppy/CD/media and reboot."));
3189        } else {
3190            run_program_and_log_output("sync", FALSE);
3191            if (is_this_device_mounted(MNT_CDROM)) {
3192                res =
3193                    run_program_and_log_output("umount " MNT_CDROM, FALSE);
3194            } else {
3195                res = 0;
3196            }
3197
3198            if (!bkpinfo->please_dont_eject) {
3199                res = eject_device("/dev/cdrom");
3200/*
3201              if (res)
3202        {
3203          log_to_screen( "WARNING - failed to eject CD-ROM disk" );
3204        }
3205*/
3206            }
3207            mvaddstr_and_log_it(g_currentY++,
3208                                0,
3209                                _
3210                                ("Run complete. Please remove media and reboot."));
3211        }
3212    }
3213
3214// g_I_have_just_nuked is set true by nuke_mode() just before it returns
3215    if (!system("which post-nuke > /dev/null 2> /dev/null")) {
3216      log_msg(1, "post-nuke found; find out whether we should run it...");
3217      if (g_I_have_just_nuked || does_file_exist("/POST-NUKE-ANYWAY")) {
3218        run_postnuke = TRUE;
3219        log_msg(1, "Yes, will run post-nuke because in nuke mode or file /POST-NUKE-ANYWAY exists.");
3220      } else if (ask_me_yes_or_no("post-nuke script found. Do you want to run it?")) {
3221        run_postnuke = TRUE;
3222        log_msg(1, "Yes, will run post-nuke because user interactively asked for it.");
3223      } else {
3224        run_postnuke = FALSE;
3225        log_msg(1, "No, will not run post-nuke.");
3226      }
3227    } else {
3228      log_msg(1, "No post-nuke found.");
3229    }
3230    if (run_postnuke) {
3231      log_to_screen("Running post-nuke...");
3232      if (mount_all_devices(mountlist, TRUE)) {
3233        log_to_screen
3234          ("Unable to re-mount partitions for post-nuke stuff");
3235      } else {
3236        log_msg(1, "Re-mounted partitions for post-nuke stuff");
3237        sprintf(tmp, "post-nuke %s %d", bkpinfo->restore_path,
3238            retval);
3239        log_msg(2, "Calling '%s'", tmp);
3240        if ((res = run_program_and_log_output(tmp, 0))) {
3241          log_OS_error(tmp);
3242        }
3243        log_msg(1, "post-nuke returned w/ res=%d", res);
3244      }
3245      unmount_all_devices(mountlist);
3246      log_to_screen("I've finished post-nuking.");
3247    }
3248
3249/* 
3250  log_to_screen("If you are REALLY in a hurry, hit Ctrl-Alt-Del now.");
3251  log_to_screen("Otherwise, please wait until the RAID disks are done.");
3252  wait_until_software_raids_are_prepped("/proc/mdstat", 100);
3253  log_to_screen("Thank you.");
3254*/
3255    unlink("/tmp/mondo-run-prog.tmp");
3256    set_signals(FALSE);
3257    mr_asprintf(&tmp, "rm -Rf %s", bkpinfo->tmpdir);
3258    run_program_and_log_output(tmp, FALSE);
3259    mr_free(tmp);
3260
3261    log_to_screen
3262        (_
3263         ("Restore log copied to /tmp/mondo-restore.log on your hard disk"));
3264    mr_asprintf(&tmp,
3265            _
3266            ("Mondo-restore is exiting (retval=%d)                                      "),
3267            retval);
3268    log_to_screen(tmp);
3269    mr_free(tmp);
3270
3271    mr_asprintf(&tmp, "umount %s", bkpinfo->isodir);
3272    run_program_and_log_output(tmp, 5);
3273    mr_free(tmp);
3274
3275    mr_free(mountlist);
3276    mr_free(raidlist);
3277    if (am_I_in_disaster_recovery_mode()) {
3278        run_program_and_log_output("mount / -o remount,rw", 2);
3279    }                           // for b0rken distros
3280    paranoid_MR_finish(retval); // frees global stuff plus bkpinfo
3281    free_libmondo_global_strings(); // it's fine to have this here :) really :)
3282
3283    unlink("/tmp/filelist.full");
3284    unlink("/tmp/filelist.full.gz");
3285
3286    exit(retval);
3287}
3288
3289/**************************************************************************
3290 *END_MAIN                                                                *
3291 **************************************************************************/
3292
3293
3294/**************************************************************************
3295 *END_MONDO-RESTORE.C                                                     *
3296 **************************************************************************/
Note: See TracBrowser for help on using the repository browser.