source: MondoRescue/branches/2.2.10/mondo/src/mondorestore/mondo-rstr-tools.c @ 2338

Last change on this file since 2338 was 2338, checked in by Bruno Cornec, 11 years ago
  • Adds LZMA support (Fix #309)
  • Change
  • Property svn:keywords set to Id
File size: 75.2 KB
Line 
1/***************************************************************************
2$Id: mondo-rstr-tools.c 2338 2009-08-20 23:47:12Z bruno $
3***************************************************************************/
4
5#include <pthread.h>
6#include <linux/fd.h>
7#include "my-stuff.h"
8#include "mr_mem.h"
9#include "../common/mondostructures.h"
10#include "../common/libmondo.h"
11#include "mr-externs.h"
12#include "mondo-rstr-tools.h"
13
14/**
15 * The biggielist stub (appended to the directory where all.tar.gz was unpacked).
16 */
17#define BIGGIELIST_TXT_STUB "tmp/biggielist.txt"
18
19/**
20 * The filelist stub (appended to the directory where all.tar.gz was unpacked).
21 */
22#define FILELIST_FULL_STUB "tmp/filelist.full.gz"
23
24/**
25 * The mountlist stub (appended to the directory where all.tar.gz was unpacked).
26 */
27#define MOUNTLIST_FNAME_STUB "tmp/mountlist.txt"
28
29/**
30 * The mondo-restore.cfg stub (appended to the directory where all.tar.gz was unpacked).
31 */
32#define MONDO_CFG_FILE_STUB "tmp/mondo-restore.cfg"
33/**
34 * The i-want-my-lvm stub
35 */
36#define IWANTMYLVM_STUB "tmp/i-want-my-lvm"
37
38extern bool g_ISO_restore_mode; /* are we in Iso Mode? */
39extern bool g_I_have_just_nuked;
40/*
41extern char *g_tmpfs_mountpt;
42*/
43extern char *g_isodir_device;
44extern long g_current_progress, g_maximum_progress;
45extern char *g_biggielist_txt;  // where 'biggielist.txt' is stored, on ramdisk / tempdir;
46                  // biggielist.txt is the list of big files stored on the
47                  // backup media set in question
48extern char *g_filelist_full;   // filelist.full.gz is the list of all regular files
49                  // (excluding big files) stored on the backup media set
50extern char *g_biggielist_pot;  // list of big files which _could_ be restored, if the
51                  // user chooses them
52extern char *g_filelist_imagedevs;  // list of devices (e.g. /dev/hda1, /dev/sda5) which
53                     // were archived as images, not just /dev entries
54                     // ... e.g. NTFS, BeOS partitions
55extern char *g_imagedevs_restthese; // of the imagedevs listed in FILELIST_IMAGEDEVS,
56                      // restore only these
57extern char *g_mondo_cfg_file;  // where m*ndo-restore.cfg (the config file) is stored
58extern char *g_mountlist_fname; // where mountlist.txt (the mountlist file) is stored
59extern char *g_mondo_home;      // homedir of Mondo; usually /usr/local/share/mondo
60
61extern t_bkptype g_backup_media_type;
62
63extern int g_partition_table_locked_up;
64extern char *MONDO_LOGFILE;
65
66/* Reference to global bkpinfo */
67extern struct s_bkpinfo *bkpinfo;
68
69/* Should we use or not extended attributes and acl when restoring */
70char *g_getfattr = NULL;
71char *g_getfacl = NULL;
72
73extern void kill_anything_like_this(char *str);
74extern int skip_obdr(void);
75extern int set_tape_block_size_with_mt(long internal_tape_block_size);
76
77/**
78* @addtogroup restoreUtilityGroup
79* @{
80*/
81/**
82* Free the malloc()s for the filename variables.
83*/
84void free_MR_global_filenames(void)
85{
86paranoid_free(g_biggielist_txt);
87paranoid_free(g_filelist_full);
88paranoid_free(g_filelist_imagedevs);
89paranoid_free(g_imagedevs_restthese);
90paranoid_free(g_mondo_cfg_file);
91paranoid_free(g_mountlist_fname);
92paranoid_free(g_mondo_home);
93/*
94paranoid_free(g_tmpfs_mountpt);
95*/
96mr_free(g_isodir_device);
97
98}
99
100
101
102/**
103* Ask the user which imagedevs from the list contained in @p infname should
104* actually be restored.
105* @param infname The file containing a list of all imagedevs.
106* @param outfname The location of the output file containing the imagedevs the user wanted to restore.
107* @ingroup restoreUtilityGroup
108*/
109void ask_about_these_imagedevs(char *infname, char *outfname)
110{
111FILE *fin;
112FILE *fout;
113/************************************************************************
114* allocate memory regions. test and set  -sab 16 feb 2003              *
115************************************************************************/
116char *incoming_ptr;
117char *question_ptr = NULL;
118
119char incoming[MAX_STR_LEN] = "\0";
120
121assert_string_is_neither_NULL_nor_zerolength(infname);
122assert_string_is_neither_NULL_nor_zerolength(outfname);
123
124incoming_ptr = malloc(sizeof(incoming));
125if (incoming_ptr == NULL) {
126fprintf(stderr, "Out of Memory\n");
127exit(EXIT_FAILURE);
128}
129
130memset(incoming_ptr, '\0', sizeof(incoming));
131
132if (!(fin = fopen(infname, "r"))) {
133fatal_error("Cannot openin infname");
134}
135if (!(fout = fopen(outfname, "w"))) {
136fatal_error("Cannot openin outfname");
137}
138for (fgets(incoming_ptr, MAX_STR_LEN, fin);
139 !feof(fin); fgets(incoming_ptr, MAX_STR_LEN, fin)) {
140strip_spaces(incoming_ptr);
141
142if (incoming[0] == '\0') {
143    continue;
144}
145
146mr_asprintf(question_ptr, "Should I restore the image of %s ?", incoming_ptr);
147
148if (ask_me_yes_or_no(question_ptr)) {
149    fprintf(fout, "%s\n", incoming_ptr);
150}
151}
152
153/*** free memory ***********/
154paranoid_free(incoming_ptr);
155incoming_ptr = NULL;
156mr_free(question_ptr);
157paranoid_fclose(fout);
158paranoid_fclose(fin);
159}
160
161/**************************************************************************
162*ASK_ABOUT_THESE_IMAGEDEVS                                               *
163**************************************************************************/
164
165
166
167
168
169
170
171
172/**
173* Extract @c mondo-restore.cfg and @c mountlist.txt from @p ramdisk_fname.
174* @param bkpinfo The backup information structure. @c tmpdir is the only field used.
175* @param ramdisk_fname The filename of the @b compressed ramdisk to look in.
176* @param output_cfg_file Where to put the configuration file extracted.
177* @param output_mountlist_file Where to put the mountlist file extracted.
178* @return 0 for success, nonzero for failure.
179* @ingroup restoreUtilityGroup
180*/
181
182/**
183* Keep trying to get mondo-restore.cfg from the archive, until the user gives up.
184*/
185void get_cfg_file_from_archive_or_bust()
186{
187while (get_cfg_file_from_archive()) {
188if (!ask_me_yes_or_no
189    ("Failed to find config file/archives. Choose another source?"))
190{
191    fatal_error("Could not find config file/archives. Aborting.");
192}
193interactively_obtain_media_parameters_from_user(FALSE);
194}
195}
196
197
198/**
199* Determine whether @p list_fname contains a line containing @p f.
200* @param f The line to search for.
201* @param list_fname The file to search in.
202* @param preamble Ignore this beginning part of @p f ("" to disable).
203* @return TRUE if it's in the list, FALSE if it's not.
204*/
205bool is_file_in_list(char *f, char *list_fname, char *preamble)
206{
207
208char *command = NULL;
209char *file = NULL;
210char *tmp = NULL;
211int res;
212
213assert_string_is_neither_NULL_nor_zerolength(f);
214assert_string_is_neither_NULL_nor_zerolength(list_fname);
215assert(preamble != NULL);
216
217if (strncmp(preamble, f, strlen(preamble)) == 0) {
218    mr_asprintf(file, "%s", f + strlen(preamble));
219} else {
220    mr_asprintf(file, "%s", f);
221}
222if (file[0] == '/' && file[1] == '/') {
223    mr_asprintf(tmp, "%s", file);
224    mr_free(file);
225
226    mr_asprintf(file, "%s", tmp + 1);
227    mr_free(tmp);
228}
229log_msg(2, "Checking to see if f=%s, file=%s, is in the list of biggiefiles", f, file);
230mr_asprintf(command, "grep -E '^%s$' %s", file, list_fname);
231mr_free(file);
232
233res = run_program_and_log_output(command, FALSE);
234mr_free(command);
235if (res) {
236    return (FALSE);
237} else {
238    return (TRUE);
239}
240}
241
242/**************************************************************************
243*END_IS_FILE_IN_LIST                                                     *
244**************************************************************************/
245
246
247
248/**
249* Set up an ISO backup.
250* @param bkpinfo The backup information structure. Fields used:
251* - @c bkpinfo->backup_media_type
252* - @c bkpinfo->disaster_recovery
253* - @c bkpinfo->isodir
254* @param nuke_me_please If TRUE, we're in nuke mode; if FALSE we're in interactive mode.
255* @return 0 for success, nonzero for failure.
256*/
257int iso_fiddly_bits(bool nuke_me_please)
258{
259    char *mount_isodir_command = NULL;
260    char *command = NULL;
261    char *mds = NULL;
262    int retval = 0, i;
263    bool already_mounted = FALSE;
264    char *isodir_format = NULL;
265
266g_ISO_restore_mode = TRUE;
267mr_free(g_isodir_device);
268g_isodir_device = read_cfg_var(g_mondo_cfg_file, "iso-dev");
269if (bkpinfo->disaster_recovery) {
270    /* Patch Conor Daly 26-june-2004
271    * Don't let this clobber an existing bkpinfo->isodir */
272    if (!bkpinfo->isodir[0]) {
273        mr_free(bkpinfo->isodir);
274        mr_asprintf(bkpinfo->isodir, "/tmp/isodir");
275    }
276    /* End patch */
277    mr_asprintf(command, "mkdir -p %s", bkpinfo->isodir);
278    run_program_and_log_output(command, 5);
279    mr_free(command);
280    log_msg(2, "Setting isodir to %s", bkpinfo->isodir);
281}
282
283/* g_isodir_device is passed and modified in this function - memory is managed correctly in it */
284if (!get_isodir_info(g_isodir_device, isodir_format, bkpinfo->isodir, nuke_me_please)) {
285    mr_free(isodir_format);
286    return (1);
287}
288paranoid_system("umount " MNT_CDROM " 2> /dev/null");   /* just in case */
289
290if (is_this_device_mounted(g_isodir_device)) {
291    log_to_screen("WARNING - isodir is already mounted");
292    already_mounted = TRUE;
293} else {
294    mr_asprintf(mount_isodir_command, "mount %s", g_isodir_device);
295    if (isodir_format) {
296        mr_strcat(mount_isodir_command, " -t %s", isodir_format);
297    }
298
299    mr_strcat(mount_isodir_command, " -o ro %s", bkpinfo->isodir);
300    run_program_and_log_output("df -m", FALSE);
301    log_msg(1, 
302        "The 'mount' command is '%s'. PLEASE report this command to be if you have problems, ok?",
303        mount_isodir_command);
304    if (run_program_and_log_output(mount_isodir_command, FALSE)) {
305        popup_and_OK
306            ("Cannot mount the device where the ISO files are stored.");
307        return (1);
308    }
309    paranoid_free(mount_isodir_command);
310    log_to_screen
311    ("I have mounted the device where the ISO files are stored.");
312}
313mr_free(isodir_format);
314
315if (!IS_THIS_A_STREAMING_BACKUP(bkpinfo->backup_media_type)) {
316    mount_media();
317}
318i = what_number_cd_is_this();   /* has the side-effect of calling mount_media() */
319mds = media_descriptor_string(bkpinfo->backup_media_type);
320mr_free(mds);
321
322log_msg(1, "%s #%d has been mounted via loopback mount", mds, i);
323if (i < 0) {
324    popup_and_OK("Cannot find ISO images in the directory you specified.");
325    retval = 1;
326}
327log_msg(2, "bkpinfo->isodir is now %s", bkpinfo->isodir);
328return (retval);
329}
330
331
332
333
334/**
335* Kill all Petris processes.
336*/
337void kill_petris(void) {
338    kill_anything_like_this("petris");
339}
340
341/**************************************************************************
342*END_KILL_PETRIS                                                         *
343**************************************************************************/
344
345
346/**
347 * Mount @p device at @p mpt as @p format.
348 * @param device The device (/dev entry) to mount.
349 * @param mpt The directory to mount it on.
350 * @param format The filesystem type of @p device.
351 * @param writeable If TRUE, mount read-write; if FALSE, mount read-only.
352 * @return 0 for success, nonzero for failure.
353 */
354int mount_device(char *device, char *mpt, char *format, bool writeable)
355{
356int res = 0;
357
358/** malloc **/
359char *tmp = NULL;
360char *command = NULL;
361char *mountdir = NULL;
362char *mountpoint = NULL;
363char *additional_parameters = NULL;
364
365assert_string_is_neither_NULL_nor_zerolength(device);
366assert_string_is_neither_NULL_nor_zerolength(mpt);
367assert(format != NULL);
368
369    if (!strcmp(mpt, "/1")) {
370        mr_asprintf(mountpoint, "/");
371        log_msg(3, "Mommm! SME is being a dildo!");
372    } else {
373        mr_asprintf(mountpoint, "%s", mpt);
374    }
375
376    if (!strcmp(mountpoint, "lvm")) {
377        return (0);
378    }
379    if (!strcmp(mountpoint, "image")) {
380        return (0);
381    }
382    mr_asprintf(tmp, "Mounting device %s   ", device);
383    log_msg(1, tmp);
384    /* Deal with additional params only if not /proc or /sys */
385    mr_asprintf(additional_parameters, "");
386    if (strcmp(format, "proc") && strcmp(format, "sys")) {
387        if (writeable) {
388            mr_strcat(additional_parameters, "-o rw");
389        } else {
390            mr_strcat(additional_parameters, "-o ro");
391        }
392        tmp = find_home_of_exe("setfattr");
393        if (tmp) {
394            mr_strcat(additional_parameters, ",user_xattr");
395        }
396        mr_free(tmp);
397
398        tmp = find_home_of_exe("setfacl");
399        if (tmp) {
400            mr_strcat(additional_parameters, ",acl");
401        }
402        mr_free(tmp);
403    }
404
405    if (!strcmp(mountpoint, "swap")) {
406        mr_asprintf(command, "swapon %s", device);
407        mr_asprintf(mountdir, "swap");
408    } else {
409        if (!strcmp(mountpoint, "/")) {
410            mr_asprintf(mountdir, "%s", MNT_RESTORING);
411        } else {
412            mr_asprintf(mountdir, "%s%s", MNT_RESTORING, mountpoint);
413        }
414        mr_asprintf(command, "mkdir -p %s", mountdir);
415        run_program_and_log_output(command, FALSE);
416        mr_free(command);
417
418        mr_asprintf(command, "mount -t %s %s %s %s 2>> %s", format, device, additional_parameters, mountdir, MONDO_LOGFILE);
419        log_msg(2, "command='%s'", command);
420    }
421    mr_free(additional_parameters);
422
423    res = run_program_and_log_output(command, TRUE);
424    if (res && (strstr(command, "xattr") || strstr(command, "acl"))) {
425        log_msg(1, "Re-trying without the fancy extra parameters");
426        mr_free(command);
427        mr_asprintf(command, "mount -t %s %s %s 2>> %s", format, device, mountdir, MONDO_LOGFILE);
428        res = run_program_and_log_output(command, TRUE);
429    }
430    if (res) {
431        log_msg(1, "Unable to mount device %s (type %s) at %s", device, format, mountdir);
432        log_msg(1, "command was '%s'", command);
433        if (!strcmp(mountpoint, "swap")) {
434            log_to_screen(tmp);
435        } else {
436            log_msg(2, "Retrying w/o the '-t' switch");
437            mr_free(command);
438            mr_asprintf(command, "mount %s %s 2>> %s", device, mountdir, MONDO_LOGFILE);
439            log_msg(2, "2nd command = '%s'", command);
440            res = run_program_and_log_output(command, TRUE);
441            if (res == 0) {
442                log_msg(1,
443                    "That's OK. I called mount w/o a filesystem type and it worked fine in the end.");
444            } else {
445                log_to_screen(tmp);
446            }
447        }
448    }
449
450    if (res && !strcmp(mountpoint, "swap")) {
451        log_msg(2, "That's ok. It's just a swap partition.");
452        log_msg(2, "Non-fatal error. Returning 0.");
453        res = 0;
454    }
455
456mr_free(tmp);
457mr_free(command);
458mr_free(mountdir);
459mr_free(mountpoint);
460
461    return (res);
462}
463/**************************************************************************
464 *END_MOUNT_DEVICE                                                        *
465**************************************************************************/
466
467
468/**
469 * Mount all devices in @p p_external_copy_of_mountlist on @p MNT_RESTORING.
470 * @param p_external_copy_of_mountlist The mountlist containing devices to be mounted.
471 * @param writeable If TRUE, then mount read-write; if FALSE mount read-only.
472 * @return The number of errors encountered (0 for success).
473 */
474int mount_all_devices(struct mountlist_itself
475                      *p_external_copy_of_mountlist, bool writeable)
476{
477int retval = 0, lino, res;
478char *tmp = NULL;
479char *these_failed = NULL;
480struct mountlist_itself *mountlist = NULL;
481
482assert(p_external_copy_of_mountlist != NULL);
483mountlist = malloc(sizeof(struct mountlist_itself));
484memcpy((void *) mountlist, (void *) p_external_copy_of_mountlist,
485   sizeof(struct mountlist_itself));
486    sort_mountlist_by_mountpoint(mountlist, 0);
487
488
489    mvaddstr_and_log_it(g_currentY, 0, "Mounting devices         ");
490    open_progress_form("Mounting devices",
491               "I am now mounting all the drives.",
492               "This should not take long.",
493               "", mountlist->entries);
494
495    mr_asprintf(these_failed, "");
496    for (lino = 0; lino < mountlist->entries; lino++) {
497        if (!strcmp(mountlist->el[lino].device, "/proc")) {
498            log_msg(1,
499                "Again with the /proc - why is this in your mountlist?");
500        } else if (is_this_device_mounted(mountlist->el[lino].device)) {
501            log_to_screen("%s is already mounted", mountlist->el[lino].device);
502        } else if (strcmp(mountlist->el[lino].mountpoint, "none")
503           && strcmp(mountlist->el[lino].mountpoint, "lvm")
504           && strcmp(mountlist->el[lino].mountpoint, "raid")
505           && strcmp(mountlist->el[lino].mountpoint, "image")) {
506            mr_asprintf(tmp, "Mounting %s", mountlist->el[lino].device);
507            update_progress_form(tmp);
508            mr_free(tmp);
509            res = mount_device(mountlist->el[lino].device, mountlist->el[lino].mountpoint, mountlist->el[lino].format, writeable);
510
511            retval += res;
512            if (res) {
513                mr_strcat(these_failed, "%s ",mountlist->el[lino].device);
514            }
515        }
516        g_current_progress++;
517    }
518    close_progress_form();
519    if (retval) {
520        if (g_partition_table_locked_up > 0) {
521            log_to_screen
522                ("fdisk's ictol() call to refresh its copy of the partition table causes the kernel to");
523            log_to_screen
524                ("lock up the partition table. You might have to reboot and use Interactive Mode to");
525            log_to_screen
526                ("format and restore *without* partitioning first. Sorry for the inconvenience.");
527        }
528        mr_asprintf(tmp, "Could not mount device(s) %s- shall I abort?", these_failed);
529
530        if (!ask_me_yes_or_no(tmp)) {
531            retval = 0;
532            log_to_screen
533                ("Continuing, although some device(s) failed to be mounted");
534            mvaddstr_and_log_it(g_currentY++, 74, "Done.");
535        } else {
536            mvaddstr_and_log_it(g_currentY++, 74, "Failed.");
537            log_to_screen
538        ("Unable to mount some or all of your partitions.");
539        }
540        mr_free(tmp);
541    } else {
542        log_to_screen("All partitions were mounted OK.");
543        mvaddstr_and_log_it(g_currentY++, 74, "Done.");
544    }
545    paranoid_free(these_failed);
546
547    /* Also mounting under MNT_RESTORING  special FS */
548    (void)mount_device("/proc","/proc","proc",TRUE);
549    (void)mount_device("/sys","/sys","sysfs",TRUE);
550    run_program_and_log_output("df -m", 3);
551    paranoid_free(mountlist);
552    return (retval);
553}
554/**************************************************************************
555*END_MOUNT_ALL_DEVICES                                                   *
556**************************************************************************/
557
558
559/**
560* Mount the CD-ROM or USB device at /mnt/cdrom.
561* @param bkpinfo The backup information structure. Fields used:
562* - @c bkpinfo->backup_media_type
563* - @c bkpinfo->disaster_recovery
564* - @c bkpinfo->isodir
565* - @c bkpinfo->media_device
566* @return 0 for success, nonzero for failure.
567*/
568int mount_media() {
569
570    char *mount_cmd = NULL;
571    int i, res;
572#ifdef __FreeBSD__
573    char mdd[32];
574    char *mddev = mdd;
575#endif
576
577    if (bkpinfo->backup_media_type == tape || bkpinfo->backup_media_type == udev) {
578        log_msg(8, "Tape/udev. Therefore, no need to mount a media.");
579        return 0;
580    }
581
582    if (!run_program_and_log_output("mount | grep -F " MNT_CDROM, FALSE)) {
583        log_msg(2, "mount_media() - media already mounted. Fair enough.");
584        return (0);
585    }
586
587    if (bkpinfo->media_device == NULL) {
588        fatal_error("No media device at that point");
589    }
590
591    if (bkpinfo->backup_media_type == nfs) {
592        log_msg(2, "Mounting for NFS thingy");
593        log_msg(2, "isodir = %s", bkpinfo->isodir);
594        if (!strcmp(bkpinfo->isodir, "/") && am_I_in_disaster_recovery_mode()) {
595            mr_free(bkpinfo->isodir);
596            mr_asprintf(bkpinfo->isodir, "/tmp/isodir");
597            log_msg(1, "isodir is being set to %s", bkpinfo->isodir);
598        }
599        if ((bkpinfo->isodir == NULL) || (bkpinfo->nfs_remote_dir == NULL) || (bkpinfo->prefix == NULL)) {
600            fatal_error("Unable to prepare the iso filename");
601        }
602#ifdef __FreeBSD__
603        mr_asprintf(mount_cmd, "/mnt/isodir/%s/%s/%s-%d.iso", bkpinfo->isodir, bkpinfo->nfs_remote_dir, bkpinfo->prefix, g_current_media_number);
604        mddev = make_vn(mount_cmd);
605        mr_free(mount_cmd);
606
607        mr_asprintf(mount_cmd, "mount_cd9660 -r %s " MNT_CDROM, mddev);
608#else
609        mr_asprintf(mount_cmd, "mount %s/%s/%s-%d.iso -t iso9660 -o loop,ro %s", bkpinfo->isodir, bkpinfo->nfs_remote_dir, bkpinfo->prefix, g_current_media_number, MNT_CDROM);
610#endif
611
612    } else if (bkpinfo->backup_media_type == iso) {
613#ifdef __FreeBSD__
614        mr_asprintf(mount_cmd, "%s/%s-%d.iso", bkpinfo->isodir, bkpinfo->prefix, g_current_media_number);
615        mddev = make_vn(mount_cmd);
616        mr_free(mount_cmd);
617
618        mr_asprintf(mount_cmd, "mount_cd9660 -r %s %s", mddev, MNT_CDROM);
619#else
620        mr_asprintf(mount_cmd, "mount %s/%s-%d.iso -t iso9660 -o loop,ro %s", bkpinfo->isodir, bkpinfo->prefix, g_current_media_number, MNT_CDROM);
621#endif
622    } else if (bkpinfo->backup_media_type == usb) {
623        mr_asprintf(mount_cmd, "mount -t vfat %s %s", bkpinfo->media_device, MNT_CDROM);
624    } else if (strstr(bkpinfo->media_device, "/dev/")) {
625#ifdef __FreeBSD__
626        mr_asprintf(mount_cmd, "mount_cd9660 -r %s %s", bkpinfo->media_device, MNT_CDROM);
627#else
628        mr_asprintf(mount_cmd, "mount %s -t iso9660 -o ro %s", bkpinfo->media_device, MNT_CDROM);
629#endif
630    } else {
631        mr_free(bkpinfo->media_device);
632        if (bkpinfo->disaster_recovery && does_file_exist("/tmp/CDROM-LIVES-HERE")) {
633            mr_asprintf(bkpinfo->media_device, "%s", last_line_of_file("/tmp/CDROM-LIVES-HERE"));
634        } else {
635            bkpinfo->media_device = find_cdrom_device(TRUE);
636        }
637
638#ifdef __FreeBSD__
639        mr_asprintf(mount_cmd, "mount_cd9660 -r %s %s", bkpinfo->media_device, MNT_CDROM);
640#else
641        mr_asprintf(mount_cmd, "mount %s -t iso9660 -o ro %s", bkpinfo->media_device, MNT_CDROM);
642#endif
643    }
644
645    log_msg(2, "(mount_media) --- command = %s", mount_cmd);
646    for (i = 0; i < 2; i++) {
647        res = run_program_and_log_output(mount_cmd, FALSE);
648        if (!res) {
649            break;
650        } else {
651            log_msg(2, "Failed to mount device.");
652            sleep(5);
653            run_program_and_log_output("sync", FALSE);
654        }
655    }
656    mr_free(mount_cmd);
657
658    if (res) {
659        log_msg(2, "Failed, despite %d attempts", i);
660    } else {
661        log_msg(2, "Mounted media drive OK");
662    }
663    return (res);
664}
665/**************************************************************************
666*END_MOUNT_CDROM                                                         *
667**************************************************************************/
668
669
670/**
671* Fix some miscellaneous things in the filesystem so the system will come
672* up correctly on the first boot.
673*/
674void protect_against_braindead_sysadmins()
675{
676run_program_and_log_output("touch " MNT_RESTORING "/var/log/pacct",
677                       FALSE);
678run_program_and_log_output("touch " MNT_RESTORING "/var/account/pacct",
679                       FALSE);
680if (run_program_and_log_output("ls " MNT_RESTORING " /tmp", FALSE)) {
681run_program_and_log_output("chmod 1777 " MNT_RESTORING "/tmp",
682                           FALSE);
683}
684run_program_and_log_output("mkdir -p " MNT_RESTORING
685                       "/var/run/console", FALSE);
686run_program_and_log_output("chmod 777 " MNT_RESTORING "/dev/null",
687                       FALSE);
688run_program_and_log_output("cd " MNT_RESTORING
689                       "; for i in `ls home/`; do echo \"Moving $i's spurious files to $i/.disabled\"; mkdir \"$i\"/.disabled ; mv -f \"$i\"/.DCOP* \"$i\"/.MCOP* \"$i\"/.*authority \"$i\"/.kde/tmp* \"$i\"/.kde/socket* \"$i\"/.disabled/ ; done",
690                       TRUE);
691run_program_and_log_output("rm -f " MNT_RESTORING "/var/run/*.pid",
692                       TRUE);
693run_program_and_log_output("rm -f " MNT_RESTORING "/var/lock/subsys/*",
694                       TRUE);
695}
696
697/**************************************************************************
698*END_PROTECT_AGAINST_BRAINDEAD_SYSADMINS                                 *
699**************************************************************************/
700
701
702
703
704/**
705* Fill out @p bkpinfo based on @p cfg_file.
706* @param cfg_file The mondo-restore.cfg file to read into @p bkpinfo.
707* @param bkpinfo The backup information structure to fill out with information
708* from @p cfg_file.
709* @return 0 for success, nonzero for failure.
710*/
711int read_cfg_file_into_bkpinfo(char *cfgf)
712{
713/** add mallocs **/
714char *value = NULL;
715char *tmp = NULL;
716char *tmp1 = NULL;
717char *envtmp1 = NULL;
718char *envtmp2 = NULL;
719char *command = NULL;
720char *iso_mnt = NULL;
721char *iso_path = NULL;
722char *old_isodir = NULL;
723char *cfg_file = NULL;
724t_bkptype media_specified_by_user;
725
726malloc_string(tmp);
727//  assert_string_is_neither_NULL_nor_zerolength(cfg_file);
728assert(bkpinfo != NULL);
729
730if (!cfgf) {
731    cfg_file = g_mondo_cfg_file;
732} else {
733    cfg_file = cfgf;
734}
735
736media_specified_by_user = bkpinfo->backup_media_type;   // or 'none', if not specified
737
738if ((value = read_cfg_var(cfg_file, "backup-media-type")) == 0) {
739    if (!strcmp(value, "cdstream")) {
740        bkpinfo->backup_media_type = cdstream;
741    } else if (!strcmp(value, "cdr")) {
742        bkpinfo->backup_media_type = cdr;
743    } else if (!strcmp(value, "cdrw")) {
744        bkpinfo->backup_media_type = cdrw;
745    } else if (!strcmp(value, "dvd")) {
746        bkpinfo->backup_media_type = dvd;
747    } else if (!strcmp(value, "usb")) {
748        bkpinfo->backup_media_type = usb;
749        bkpinfo->please_dont_eject = TRUE;
750    } else if (!strcmp(value, "iso")) {
751        // Patch by Conor Daly - 2004/07/12
752        bkpinfo->backup_media_type = iso;
753        if (am_I_in_disaster_recovery_mode()) {
754            /* Check to see if CD is already mounted before mounting it... */
755            if (!is_this_device_mounted("/dev/cdrom")) {
756                log_msg(2, "NB: CDROM device not mounted, mounting...");
757                run_program_and_log_output("mount /dev/cdrom " MNT_CDROM, 1);
758            }
759            if (does_file_exist(MNT_CDROM "/archives/filelist.0")) {
760                bkpinfo->backup_media_type = cdr;
761                run_program_and_log_output("umount " MNT_CDROM, 1);
762                log_it
763                    ("Re-jigging configuration AGAIN. CD-R, not ISO.");
764            }
765        }
766        mr_free(bkpinfo->prefix);
767        mr_free(value);
768        if ((value = read_cfg_var(cfg_file, "iso-prefix")) == 0) {
769            mr_asprintf(bkpinfo->prefix, "%s", value);
770        } else {
771            mr_asprintf(bkpinfo->prefix, "%s", STD_PREFIX);
772        }
773    } else if (!strcmp(value, "nfs")) {
774        bkpinfo->backup_media_type = nfs;
775        bkpinfo->please_dont_eject = TRUE;
776        mr_free(bkpinfo->prefix);
777        mr_free(value);
778        if ((value = read_cfg_var(cfg_file, "iso-prefix")) == 0) {
779            mr_asprintf(bkpinfo->prefix, "%s", value);
780        } else {
781            mr_asprintf(bkpinfo->prefix, "%s", STD_PREFIX);
782        }
783   
784        if (strstr(call_program_and_get_last_line_of_output("cat " CMDLINE), "pxe")) {
785            /* We need to override prefix value in PXE mode as it's
786            * already done in start-nfs */
787            envtmp1 = getenv("imgname");
788            if (envtmp1 == NULL) {
789                fatal_error("no imgname variable in environment");
790            }
791            mr_free(bkpinfo->prefix);
792            mr_asprintf(bkpinfo->prefix, "%s", envtmp1);
793        }
794
795    } else if (!strcmp(value, "tape")) {
796        bkpinfo->backup_media_type = tape;
797    } else if (!strcmp(value, "udev")) {
798        bkpinfo->backup_media_type = udev;
799    } else {
800        fatal_error("UNKNOWN bkp-media-type");
801    }
802} else {
803    fatal_error("backup-media-type not specified!");
804}
805mr_free(value);
806
807if (bkpinfo->disaster_recovery) {
808    if (bkpinfo->backup_media_type == cdstream) {
809        mr_free(bkpinfo->media_device);
810        mr_asprintf(bkpinfo->media_device, "/dev/cdrom");
811        bkpinfo->media_size[0] = 1999 * 1024;
812        bkpinfo->media_size[1] = 650;   /* good guess */
813    } else if (bkpinfo->backup_media_type == usb) {
814        envtmp1 = getenv("MRUSBDEV");
815        if (envtmp1 == NULL) {
816            if ((value = read_cfg_var(cfg_file, "usb-dev")) == NULL) {
817                fatal_error("Cannot get USB device name from cfg file");
818            }
819        } else {
820            mr_asprintf(value,"%s", envtmp1);
821        }
822        mr_free(bkpinfo->media_device);
823        mr_asprintf(bkpinfo->media_device, "%s1", value);
824        mr_free(value);
825        log_msg(2, "Backup medium is USB --- dev=%s", bkpinfo->media_device);
826    } else if (bkpinfo->backup_media_type == tape || bkpinfo->backup_media_type == udev) {
827        if ((value = read_cfg_var(cfg_file, "media-dev")) == NULL) {
828            fatal_error("Cannot get tape device name from cfg file");
829        }
830        mr_free(bkpinfo->media_device);
831        bkpinfo->media_device = value;
832
833        value = read_cfg_var(cfg_file, "media-size");
834        if (value != NULL) {
835            bkpinfo->media_size[1] = atol(value);
836            mr_free(value);
837        } else {
838            bkpinfo->media_size[1] = 0L;
839        }
840        log_msg(2, "Backup medium is TAPE --- dev=%s", bkpinfo->media_device);
841    } else {
842        mr_free(bkpinfo->media_device);
843        mr_asprintf(bkpinfo->media_device, "/dev/cdrom");   /* we don't really need this var */
844        bkpinfo->media_size[0] = 1999 * 1024;   /* 650, probably, but we don't need this var anyway */
845        bkpinfo->media_size[1] = 1999 * 1024;   /* 650, probably, but we don't need this var anyway */
846        log_msg(2, "Backup medium is CD-R[W]");
847    }
848} else {
849    log_msg(2, "Not in Disaster Recovery Mode. No need to derive device name from config file.");
850}
851
852value = read_cfg_var(cfg_file, "use-star");
853if (value && strstr(value, "yes")) {
854    bkpinfo->use_star = TRUE;
855    log_msg(1, "Goody! ... bkpinfo->use_star is now true.");
856}
857mr_free(value);
858
859value = read_cfg_var(cfg_file, "obdr");
860if (value && strstr(value, "TRUE")) {
861    bkpinfo->use_obdr = TRUE;
862    log_msg(1, "OBDR mode activated");
863}
864mr_free(value);
865
866value = read_cfg_var(cfg_file, "acl");
867if (value && strstr(value, "TRUE")) {
868    mr_asprintf(g_getfacl,"setfacl");
869    log_msg(1, "We will restore ACLs");
870    tmp = find_home_of_exe("setfacl");
871    if (!tmp) {
872        log_msg(1, "Unable to restore ACLs as no setfacl found");
873    }
874    mr_free(tmp);
875}
876mr_free(value);
877
878value = read_cfg_var(cfg_file, "xattr");
879if (value && strstr(value, "TRUE")) {
880    mr_asprintf(g_getfattr,"setfattr");
881    log_msg(1, "We will restore XATTRs");
882    tmp = find_home_of_exe("setfattr");
883    if (!tmp) {
884        log_msg(1, "Unable to restore XATTRs as no setfattr found");
885    }
886    mr_free(tmp);
887}
888mr_free(value);
889
890value = read_cfg_var(cfg_file, "internal-tape-block-size");
891if (value != NULL) {
892    bkpinfo->internal_tape_block_size = atol(value);
893} else {
894    bkpinfo->internal_tape_block_size = DEFAULT_INTERNAL_TAPE_BLOCK_SIZE;
895}
896log_msg(1, "Internal tape block size set to %ld", bkpinfo->internal_tape_block_size);
897mr_free(value);
898
899value = read_cfg_var(cfg_file, "use-lzma");
900if (value && strstr(value, "yes")) {
901    bkpinfo->use_lzma = TRUE;
902    bkpinfo->use_lzo = FALSE;
903    bkpinfo->use_gzip = FALSE;
904    mr_free(bkpinfo->zip_exe);
905    mr_asprintf(bkpinfo->zip_exe, "lzma");
906    mr_free(bkpinfo->zip_suffix);
907    mr_asprintf(bkpinfo->zip_suffix, "lzma");
908}
909mr_free(value);
910
911value = read_cfg_var(cfg_file, "use-lzo");
912if (value && strstr(value, "yes")) {
913    bkpinfo->use_lzma = FALSE;
914    bkpinfo->use_lzo = TRUE;
915    bkpinfo->use_gzip = FALSE;
916    mr_free(bkpinfo->zip_exe);
917    mr_asprintf(bkpinfo->zip_exe, "lzop");
918    mr_free(bkpinfo->zip_suffix);
919    mr_asprintf(bkpinfo->zip_suffix, "lzo");
920}
921mr_free(value);
922
923value = read_cfg_var(cfg_file, "use-gzip");
924if (value && strstr(value, "yes")) {
925    bkpinfo->use_lzma = FALSE;
926    bkpinfo->use_lzo = FALSE;
927    bkpinfo->use_gzip = TRUE;
928    mr_free(bkpinfo->zip_exe);
929    mr_asprintf(bkpinfo->zip_exe, "gzip");
930    mr_free(bkpinfo->zip_suffix);
931    mr_asprintf(bkpinfo->zip_suffix, "gz");
932}
933mr_free(value);
934
935value = read_cfg_var(cfg_file, "use-comp");
936if (value && strstr(value, "yes")) {
937    bkpinfo->use_lzma = FALSE;
938    bkpinfo->use_lzo = FALSE;
939    bkpinfo->use_gzip = FALSE;
940    mr_free(bkpinfo->zip_exe);
941    mr_asprintf(bkpinfo->zip_exe, "bzip2");
942    mr_free(bkpinfo->zip_suffix);
943    mr_asprintf(bkpinfo->zip_suffix, "bz2");
944}
945mr_free(value);
946
947if (bkpinfo->zip_exe == NULL) {
948    mr_asprintf(bkpinfo->zip_exe, "none");
949}
950if (bkpinfo->zip_suffix == NULL) {
951    mr_asprintf(bkpinfo->zip_suffix, "");
952}
953
954value = read_cfg_var(cfg_file, "differential");
955if (value && (!strcmp(value, "yes") || !strcmp(value, "1"))) {
956    bkpinfo->differential = TRUE;
957}
958log_msg(2, "differential var = '%s'", value);
959mr_free(value);
960if (bkpinfo->differential) {
961    log_msg(2, "THIS IS A DIFFERENTIAL BACKUP");
962} else {
963    log_msg(2, "This is a regular (full) backup");
964}
965
966tmp = read_cfg_var(g_mondo_cfg_file, "please-dont-eject");
967if (tmp || strstr(call_program_and_get_last_line_of_output("cat " CMDLINE), "donteject")) {
968    bkpinfo->please_dont_eject = TRUE;
969    log_msg(2, "Ok, I shan't eject when restoring! Groovy.");
970}
971mr_free(tmp);
972
973if (bkpinfo->backup_media_type == nfs) {
974    if (!cfgf) {
975        if (bkpinfo->nfs_mount) {
976            log_msg(2, "nfs_mount remains %s", bkpinfo->nfs_mount);
977        }
978        if (bkpinfo->nfs_remote_dir) {
979            log_msg(2, "nfs_remote_dir remains %s", bkpinfo->nfs_remote_dir);
980        }
981        log_msg(2, "...cos it wouldn't make sense to abandon the values that GOT ME to this config file in the first place");
982    } else {
983        mr_free(bkpinfo->nfs_mount);
984        bkpinfo->nfs_mount = read_cfg_var(g_mondo_cfg_file, "nfs-server-mount");
985
986        mr_free(bkpinfo->nfs_remote_dir);
987        bkpinfo->nfs_remote_dir = read_cfg_var(g_mondo_cfg_file, "nfs-server-path");
988
989        if (bkpinfo->nfs_mount != NULL) {
990            log_msg(2, "nfs_mount is %s", bkpinfo->nfs_mount);
991        }
992        if (bkpinfo->nfs_remote_dir != NULL) {
993            log_msg(2, "nfs_remote_dir is %s", bkpinfo->nfs_remote_dir);
994        }
995    }
996    if (strstr(call_program_and_get_last_line_of_output("cat " CMDLINE), "pxe")) {
997        /* We need to override values in PXE mode as it's
998        * already done in start-nfs */
999        envtmp1 = getenv("nfsmount");
1000        if (envtmp1 == NULL) {
1001            fatal_error("no nfsmount variable in environment");
1002        }
1003        envtmp2 = getenv("dirimg");
1004        if (envtmp2 == NULL) {
1005            fatal_error("no dirimg variable in environment");
1006        }
1007        mr_free(bkpinfo->nfs_mount);
1008        mr_asprintf(bkpinfo->nfs_mount, "%s", envtmp1);
1009
1010        mr_free(bkpinfo->nfs_remote_dir);
1011        mr_asprintf(bkpinfo->nfs_remote_dir, "%s", envtmp2);
1012    }
1013} else if (bkpinfo->backup_media_type == iso) {
1014    /* Patch by Conor Daly 23-june-2004
1015    * to correctly mount iso-dev and set a sensible
1016    * isodir in disaster recovery mode
1017    */
1018    mr_asprintf(old_isodir, "%s", bkpinfo->isodir);
1019    iso_mnt = read_cfg_var(g_mondo_cfg_file, "iso-mnt");
1020    iso_path = read_cfg_var(g_mondo_cfg_file, "isodir");
1021    mr_free(bkpinfo->isodir);
1022    mr_asprintf(bkpinfo->isodir, "%s%s", iso_mnt, iso_path);
1023    mr_free(iso_mnt);
1024
1025    if (!bkpinfo->isodir[0]) {
1026        mr_free(bkpinfo->isodir);
1027        bkpinfo->isodir = old_isodir;
1028    } else {
1029        mr_free(old_isodir);
1030    }
1031    if (!bkpinfo->disaster_recovery) {
1032        if (strcmp(old_isodir, bkpinfo->isodir)) {
1033            log_it("user nominated isodir %s differs from archive, keeping user's choice: %s\n", bkpinfo->isodir, old_isodir );
1034            mr_free(bkpinfo->isodir);
1035            bkpinfo->isodir = old_isodir;
1036        } else {
1037            mr_free(old_isodir);
1038        }
1039    }
1040    mr_free(g_isodir_device);
1041    g_isodir_device = read_cfg_var(g_mondo_cfg_file, "iso-dev");
1042    log_msg(2, "isodir=%s; iso-dev=%s", bkpinfo->isodir, g_isodir_device);
1043
1044    if (bkpinfo->disaster_recovery) {
1045        if (is_this_device_mounted(g_isodir_device)) {
1046            log_msg(2, "NB: isodir is already mounted");
1047            /* Find out where it's mounted */
1048            mr_asprintf(command, "mount | grep -E '^%s' | tail -n1 | cut -d' ' -f3", g_isodir_device);
1049            log_it("command = %s", command);
1050            log_it("res of it = %s", call_program_and_get_last_line_of_output(command));
1051            mr_asprintf(iso_mnt, "%s", call_program_and_get_last_line_of_output(command));
1052            mr_free(command);
1053        } else {
1054            mr_asprintf(iso_mnt, "/tmp/isodir");
1055            mr_asprintf(tmp1, "mkdir -p %s", iso_mnt);
1056            run_program_and_log_output(tmp1, 5);
1057            mr_free(tmp1);
1058
1059            mr_asprintf(tmp1, "mount %s %s", g_isodir_device, iso_mnt);
1060            if (run_program_and_log_output(tmp1, 3)) {
1061                log_msg(1, "Unable to mount isodir. Perhaps this is really a CD backup?");
1062                bkpinfo->backup_media_type = cdr;
1063                mr_free(bkpinfo->media_device);
1064                mr_asprintf(bkpinfo->media_device, "/dev/cdrom");   /* superfluous */
1065                if (mount_media()) {
1066                    mr_free(tmp1);
1067                    fatal_error("Unable to mount isodir. Failed to mount CD-ROM as well.");
1068                } else {
1069                    log_msg(1, "You backed up to disk, then burned some CDs.");
1070                }
1071            }
1072            mr_free(tmp1);
1073        }
1074        /* bkpinfo->isodir should now be the true path to prefix-1.iso etc... */
1075        if (bkpinfo->backup_media_type == iso) {
1076            mr_free(bkpinfo->isodir);
1077            mr_asprintf(tmp1, "%s%s", iso_mnt, iso_path);
1078            bkpinfo->isodir = tmp1;
1079        }
1080        mr_free(iso_mnt);
1081    }
1082    mr_free(iso_path);
1083}
1084
1085if (media_specified_by_user != none) {
1086    if (g_restoring_live_from_cd) {
1087        if (bkpinfo->backup_media_type != media_specified_by_user) {
1088            log_msg(2,
1089                    "bkpinfo->backup_media_type != media_specified_by_user, so I'd better ask :)");
1090            interactively_obtain_media_parameters_from_user(FALSE);
1091            media_specified_by_user = bkpinfo->backup_media_type;
1092            get_cfg_file_from_archive();
1093    /*
1094        if (media_specified_by_user != cdr && media_specified_by_user == cdrw)
1095            { g_restoring_live_from_cd = FALSE; }
1096    */
1097        }
1098    }
1099    bkpinfo->backup_media_type = media_specified_by_user;
1100}
1101g_backup_media_type = bkpinfo->backup_media_type;
1102paranoid_free(value);
1103paranoid_free(tmp);
1104return (0);
1105
1106}
1107
1108/**************************************************************************
1109*END_READ_CFG_FILE_INTO_BKPINFO                                          *
1110**************************************************************************/
1111
1112
1113
1114
1115/**
1116 * Allow the user to edit the filelist and biggielist.
1117 * The filelist is unlinked after it is read.
1118 * @param bkpinfo The backup information structure. Fields used:
1119 * - @c bkpinfo->backup_media_type
1120 * - @c bkpinfo->isodir
1121 * - @c bkpinfo->media_device
1122 * - @c bkpinfo->tmpdir
1123 * @return The filelist structure containing the information read from disk.
1124 */
1125struct
1126s_node *process_filelist_and_biggielist()
1127{
1128struct s_node *filelist;
1129
1130/** add mallocs**/
1131char *command = NULL;
1132char *tmp;
1133int res = 0;
1134pid_t pid;
1135bool extract_mountlist_stub = FALSE;
1136
1137assert(bkpinfo != NULL);
1138malloc_string(tmp);
1139
1140/* If those files already exist, do not overwrite them later on */
1141if (does_file_exist("/"MOUNTLIST_FNAME_STUB)) {
1142    extract_mountlist_stub = FALSE;
1143} else {
1144    extract_mountlist_stub = TRUE;
1145}
1146
1147if (does_file_exist(g_filelist_full)
1148&& does_file_exist(g_biggielist_txt)) {
1149    log_msg(1, "%s exists", g_filelist_full);
1150    log_msg(1, "%s exists", g_biggielist_txt);
1151    log_msg(2,
1152        "Filelist and biggielist already recovered from media. Yay!");
1153} else {
1154    getcwd(tmp, MAX_STR_LEN);
1155    chdir(bkpinfo->tmpdir);
1156    log_msg(1, "chdir(%s)", bkpinfo->tmpdir);
1157    log_to_screen("Extracting filelist and biggielist from media...");
1158    unlink("/tmp/filelist.full");
1159    unlink(FILELIST_FULL_STUB);
1160    if (IS_THIS_A_STREAMING_BACKUP(bkpinfo->backup_media_type)) {
1161        mr_asprintf(command, "tar -b %ld -zxf %s ./%s ./%s ./%s ./%s ./%s", bkpinfo->internal_tape_block_size, bkpinfo->media_device, MOUNTLIST_FNAME_STUB, BIGGIELIST_TXT_STUB, FILELIST_FULL_STUB, IWANTMYLVM_STUB, MONDO_CFG_FILE_STUB);
1162        log_msg(1, "tarcommand = %s", command);
1163        run_program_and_log_output(command, 1);
1164        mr_free(command);
1165
1166        if (!does_file_exist(FILELIST_FULL_STUB)) {
1167            /* Doing that allow us to remain compatible with pre-2.2.5 versions */
1168            log_msg(2, "pre-2.2.4 compatible mode on");
1169            mr_asprintf(command, "tar -b %ld -zxf %s %s %s %s %s %s", bkpinfo->internal_tape_block_size, bkpinfo->media_device, MOUNTLIST_FNAME_STUB, BIGGIELIST_TXT_STUB, FILELIST_FULL_STUB, IWANTMYLVM_STUB, MONDO_CFG_FILE_STUB);
1170            log_msg(1, "tarcommand = %s", command);
1171            run_program_and_log_output(command, 1);
1172            mr_free(command);
1173        }
1174    } else {
1175        log_msg(2, "Calling insist_on_this_cd_number; bkpinfo->isodir=%s", bkpinfo->isodir);
1176        insist_on_this_cd_number(1);
1177        log_msg(2, "Back from iotcn");
1178        run_program_and_log_output("mount", 1);
1179        mr_asprintf(command, "tar -zxf %s/images/all.tar.gz ./%s ./%s ./%s ./%s ./%s", MNT_CDROM, MOUNTLIST_FNAME_STUB, BIGGIELIST_TXT_STUB, FILELIST_FULL_STUB, IWANTMYLVM_STUB, MONDO_CFG_FILE_STUB);
1180
1181        log_msg(1, "tarcommand = %s", command);
1182        run_program_and_log_output(command, 1);
1183        mr_free(command);
1184
1185        if (!does_file_exist(FILELIST_FULL_STUB)) {
1186            /* Doing that allow us to remain compatible with pre-2.2.5 versions */
1187            log_msg(2, "pre-2.2.4 compatible mode on");
1188            mr_asprintf(command, "tar -zxf %s/images/all.tar.gz %s %s %s %s %s", MNT_CDROM, MOUNTLIST_FNAME_STUB, BIGGIELIST_TXT_STUB, FILELIST_FULL_STUB, IWANTMYLVM_STUB, MONDO_CFG_FILE_STUB);
1189
1190            log_msg(1, "tarcommand = %s", command);
1191            run_program_and_log_output(command, 1);
1192            mr_free(command);
1193        }
1194        if (!does_file_exist(BIGGIELIST_TXT_STUB)) {
1195            fatal_error
1196                ("all.tar.gz did not include " BIGGIELIST_TXT_STUB);
1197        }
1198        if (!does_file_exist(FILELIST_FULL_STUB)) {
1199            fatal_error
1200                ("all.tar.gz did not include " FILELIST_FULL_STUB);
1201        }
1202    }
1203    mr_asprintf(command, "cp -f %s %s", MONDO_CFG_FILE_STUB, g_mondo_cfg_file);
1204    run_program_and_log_output(command, FALSE);
1205    mr_free(command);
1206
1207    mr_asprintf(command, "cp -f %s/%s %s", bkpinfo->tmpdir, BIGGIELIST_TXT_STUB, g_biggielist_txt);
1208    log_msg(1, "command = %s", command);
1209    paranoid_system(command);
1210    mr_free(command);
1211
1212    mr_asprintf(command, "ln -sf %s/%s %s", bkpinfo->tmpdir, FILELIST_FULL_STUB, g_filelist_full);
1213    log_msg(1, "command = %s", command);
1214    paranoid_system(command);
1215    mr_free(command);
1216}
1217
1218if (am_I_in_disaster_recovery_mode()
1219    &&
1220    /* If it was there, do not overwrite it */
1221    (extract_mountlist_stub) 
1222    &&
1223    ask_me_yes_or_no("Do you want to retrieve the mountlist as well?")) {
1224        mr_asprintf(command, "ln -sf %s/%s /tmp", MOUNTLIST_FNAME_STUB, bkpinfo->tmpdir);
1225        paranoid_system(command);
1226        mr_free(command);
1227    }
1228
1229    chdir(tmp);
1230
1231    if (!does_file_exist(g_biggielist_txt)) {
1232        log_msg(1, "Warning - %s not found", g_biggielist_txt);
1233    }
1234    if (!does_file_exist(g_filelist_full)) {
1235        log_msg(1, "Warning - %s does not exist", g_filelist_full);
1236    }
1237//  popup_and_OK("Wonderful.");
1238
1239    log_msg(2, "Forking");
1240    pid = fork();
1241    switch (pid) {
1242    case -1:
1243        fatal_error("Forking error");
1244        break;
1245
1246    case 0:
1247        log_to_screen("Pre-processing filelist");
1248        if (!does_file_exist(g_biggielist_txt)) {
1249            mr_asprintf(command, "echo -n > %s", g_biggielist_txt);
1250            paranoid_system(command);
1251            mr_free(command);
1252        }
1253        mr_asprintf(command, "grep -E '^/dev/.*' %s > %s", g_biggielist_txt, g_filelist_imagedevs);
1254        paranoid_system(command);
1255        mr_free(command);
1256        exit(0);
1257        break;
1258
1259    default:
1260        open_evalcall_form("Pre-processing filelist");
1261        while (!waitpid(pid, (int *) 0, WNOHANG)) {
1262            usleep(100000);
1263            update_evalcall_form(0);
1264        }
1265    }
1266    close_evalcall_form();
1267
1268    log_msg(3, "loading filelist");
1269    filelist = load_filelist(g_filelist_full);
1270    log_msg(3, "deleting original filelist");
1271    unlink(g_filelist_full);
1272    if (g_text_mode) {
1273        printf("Restore which directory? --> ");
1274        fgets(tmp, sizeof(tmp), stdin);
1275        toggle_path_selection(filelist, tmp, TRUE);
1276        if (strlen(tmp) == 0) {
1277            res = 1;
1278        } else {
1279            res = 0;
1280        }
1281    } else {
1282        res = edit_filelist(filelist);
1283    }
1284    if (res) {
1285        log_msg(2, "User hit 'cancel'. Freeing filelist and aborting.");
1286        free_filelist(filelist);
1287        return (NULL);
1288    }
1289    ask_about_these_imagedevs(g_filelist_imagedevs, g_imagedevs_restthese);
1290    close_evalcall_form();
1291
1292    // NB: It's not necessary to add g_biggielist_txt to the filelist.full
1293    // file. The filelist.full file already contains the filename of EVERY
1294    // file backed up - regular and biggie files.
1295
1296    // However, we do want to make sure the imagedevs selected by the user
1297    // are flagged for restoring.
1298    if (length_of_file(g_imagedevs_restthese) > 2) {
1299        add_list_of_files_to_filelist(filelist, g_imagedevs_restthese,
1300                                      TRUE);
1301    }
1302
1303    paranoid_free(tmp);
1304    return (filelist);
1305}
1306
1307/**************************************************************************
1308 *END_ PROCESS_FILELIST_AND_BIGGIELIST                                    *
1309 **************************************************************************/
1310
1311
1312
1313
1314/**
1315 * Make a backup copy of <tt>path_root</tt>/<tt>filename</tt>.
1316 * The backup filename is the filename of the original with ".pristine" added.
1317 * @param path_root The place where the filesystem is mounted (e.g. MNT_RESTORING).
1318 * @param filename The filename (absolute path) within @p path_root.
1319 * @return 0 for success, nonzero for failure.
1320 */
1321int backup_crucial_file(char *path_root, char *filename)
1322{
1323    char *tmp = NULL;
1324    char *command = NULL;
1325    int res;
1326
1327    assert(path_root != NULL);
1328    assert_string_is_neither_NULL_nor_zerolength(filename);
1329
1330    mr_asprintf(tmp, "%s/%s", path_root, filename);
1331    mr_asprintf(command, "cp -f %s %s.pristine", tmp, tmp);
1332    mr_free(tmp);
1333
1334    res = run_program_and_log_output(command, 5);
1335    mr_free(command);
1336    return (res);
1337}
1338
1339void offer_to_make_initrd() {
1340
1341if (bkpinfo->restore_mode != nuke) {
1342    if (ask_me_yes_or_no
1343        ("You will now be able to re-generate your initrd.\nThis is especially useful if you changed of hardware configuration, cloned, made P2V, used multipath...\nDo you need to do it ?")) {
1344        log_msg(1,"Launching shell for manual initrd recreation");
1345        popup_and_OK("You'll now be chrooted under your future / partition.\nGo under /boot and rebuild your initrd with\nmkinitrd -f -v initrd-2.x.y.img 2.x.y e.g.\nThen type exit to finish.");
1346        mvaddstr_and_log_it(g_currentY, 0, "Modifying initrd...");
1347        if (!g_text_mode) {
1348            newtSuspend();
1349        }
1350        (void)system("chroot " MNT_RESTORING);
1351        if (!g_text_mode) {
1352            newtResume();
1353        }
1354        mvaddstr_and_log_it(g_currentY++, 74, "Done.");
1355    } else {
1356        return;
1357    }
1358} else {
1359    log_to_screen("Non-interactive mode: no way to give you the keyboard so that you re-generate your initrd. Hope it's OK");
1360    log_msg(1,"Non-interactive mode: no way to give you the keyboard so that you re-generate your initrd. Hope it's OK");
1361}
1362}
1363
1364
1365/**
1366 * Install the user's boot loader in the MBR.
1367 * Currently LILO, ELILO, GRUB, RAW (dd of MBR), and the FreeBSD bootloader are supported.
1368 * @param offer_to_hack_scripts If TRUE, then offer to hack the user's fstab for them.
1369 * @return 0 for success, nonzero for failure.
1370 */
1371int run_boot_loader(bool offer_to_hack_scripts)
1372{
1373    int res;
1374    int retval = 0;
1375
1376  /** malloc *******/
1377    char *device = NULL;
1378    char *name = NULL;
1379    char *cmd = NULL;
1380
1381    /* In order to have a working bootloader, we need to have all devices
1382     * ready in the chroot. If they are not there (udev) then copy them from
1383     * the current /dev location
1384     */
1385    mr_asprintf(cmd,"tar cf - /dev | ( cd %s ; tar xf - )",MNT_RESTORING);
1386    run_program_and_log_output(cmd, 3);
1387    paranoid_free(cmd);
1388
1389    backup_crucial_file(MNT_RESTORING, "/etc/fstab");
1390    backup_crucial_file(MNT_RESTORING, "/boot/grub/menu.lst");
1391    backup_crucial_file(MNT_RESTORING, "/etc/lilo.conf");
1392    backup_crucial_file(MNT_RESTORING, "/etc/elilo.conf");
1393    backup_crucial_file(MNT_RESTORING, "/boot/grub/device.map");
1394    backup_crucial_file(MNT_RESTORING, "/etc/mtab");
1395    device = read_cfg_var(g_mondo_cfg_file, "bootloader.device");
1396    name = read_cfg_var(g_mondo_cfg_file, "bootloader.name");
1397    log_msg(2, "run_boot_loader: device='%s', name='%s'", device, name);
1398    system("sync");
1399
1400    offer_to_make_initrd();
1401    if (!strcmp(name, "LILO")) {
1402        res = run_lilo(offer_to_hack_scripts);
1403    } else if (!strcmp(name, "ELILO")) {
1404        res = run_elilo(offer_to_hack_scripts);
1405    } else if (!strcmp(name, "GRUB")) {
1406        res = run_grub(offer_to_hack_scripts, device);
1407    } else if (!strcmp(name, "RAW")) {
1408        res = run_raw_mbr(offer_to_hack_scripts, device);
1409    }
1410#ifdef __FreeBSD__
1411    else if (!strcmp(name, "BOOT0")) {
1412        mr_asprintf(tmp, "boot0cfg -B %s", device);
1413        res = run_program_and_log_output(tmp, FALSE);
1414        paranoid_free(tmp);
1415    } else {
1416        mr_asprintf(tmp, "ls /dev | grep -Eq '^%ss[1-4].*'", device);
1417        if (!system(tmp)) {
1418            mr_free(tmp);
1419            mr_asprintf(tmp, MNT_RESTORING "/sbin/fdisk -B %s", device);
1420            res = run_program_and_log_output(tmp, 3);
1421        } else {
1422            log_msg(1, "I'm not running any boot loader. You have a DD boot drive. It's already loaded up.");
1423        }
1424        mr_free(tmp);
1425    }
1426#else
1427    else {
1428        log_to_screen
1429            ("Unable to determine type of boot loader. Defaulting to LILO.");
1430        res = run_lilo(offer_to_hack_scripts);
1431    }
1432#endif
1433    mr_free(device);
1434    mr_free(name);
1435
1436    retval += res;
1437    if (res) {
1438        log_to_screen("Your boot loader returned an error");
1439    } else {
1440        log_to_screen("Your boot loader ran OK");
1441    }
1442    return (retval);
1443}
1444
1445/**************************************************************************
1446 *END_ RUN_BOOT_LOADER                                                    *
1447 **************************************************************************/
1448
1449
1450
1451/**
1452 * Attempt to find the user's editor.
1453 * @return The editor found ("vi" if none could be found).
1454 * @note The returned string points to static storage that will be overwritten with each call.
1455 */
1456char *find_my_editor(void) {
1457   
1458    char *tmp = NULL;
1459    static char output[MAX_STR_LEN];
1460
1461    tmp = find_home_of_exe("pico");
1462    if (tmp) {
1463        strcpy(output, "pico");
1464    } else { 
1465        mr_free(tmp);
1466        tmp = find_home_of_exe("nano");
1467        if (tmp) {
1468            strcpy(output, "nano");
1469        } else {
1470            mr_free(tmp);
1471            tmp = find_home_of_exe("joe");
1472            if (tmp) {
1473                strcpy(output, "joe");
1474            } else {
1475                strcpy(output, "vi");
1476            }
1477        }
1478    }
1479    mr_free(tmp);
1480
1481    tmp = find_home_of_exe(output);
1482    if (!tmp) {
1483        log_msg(2, " (find_my_editor) --- warning - %s not found", output);
1484    }
1485    mr_free(tmp);
1486    return (output);
1487}
1488
1489
1490/**
1491 * Install GRUB on @p bd.
1492 * @param offer_to_run_stabgrub If TRUE, then offer to hack the user's fstab for them.
1493 * @param bd The boot device where GRUB is installed.
1494 * @return 0 for success, nonzero for failure.
1495 */
1496int run_grub(bool offer_to_run_stabgrub, char *bd)
1497{
1498  /** malloc **/
1499    char *command = NULL;
1500    char *boot_device = NULL;
1501    char *rootdev;
1502    char *rootdrive;
1503    char *conffile;
1504    char *tmp = NULL;
1505    char *editor = NULL;
1506    char *p = NULL;
1507
1508    int res = 0;
1509    bool done;
1510
1511    malloc_string(rootdev);
1512    malloc_string(rootdrive);
1513    malloc_string(conffile);
1514    assert_string_is_neither_NULL_nor_zerolength(bd);
1515    mr_asprintf(boot_device, "%s", bd);
1516
1517    if (offer_to_run_stabgrub
1518        && ask_me_yes_or_no("Did you change the mountlist or cloned the system ?")) {
1519        /* interactive mode */
1520        mvaddstr_and_log_it(g_currentY,
1521                            0,
1522                            "Modifying fstab, mtab, device.map and menu.lst, and running GRUB...                             ");
1523        for (done = FALSE; !done;) {
1524            p = popup_and_get_string("Boot device", "Please confirm/enter the boot device. If in doubt, try /dev/hda", boot_device);
1525            if (p == NULL) {
1526                done = TRUE;
1527                mr_free(p);
1528                /* we want some warnings later on */
1529                res = 1;
1530                continue;
1531            }
1532            mr_asprintf(command, "stabgrub-me %s", p);
1533            mr_free(p);
1534
1535            res = run_program_and_log_output(command, 1);
1536            mr_free(command);
1537
1538            if (res) {
1539                popup_and_OK
1540                    ("GRUB installation failed. Please install manually using 'grub-install' or similar command. You are now chroot()'ed to your restored system. Please type 'exit' when you are done.");
1541                newtSuspend();
1542                system("chroot " MNT_RESTORING);
1543                newtResume();
1544                popup_and_OK("Thank you.");
1545            } else {
1546                done = TRUE;
1547            }
1548            popup_and_OK("You will now edit fstab, mtab, device.map and menu.lst");
1549            if (!g_text_mode) {
1550                newtSuspend();
1551            }
1552            mr_asprintf(editor, "%s", find_my_editor());
1553
1554            mr_asprintf(tmp, "chroot %s %s /etc/fstab", MNT_RESTORING, editor);
1555            paranoid_system(tmp);
1556            mr_free(tmp);
1557
1558            mr_asprintf(tmp, "chroot %s %s /etc/mtab", MNT_RESTORING, editor);
1559            paranoid_system(tmp);
1560            mr_free(tmp);
1561
1562            mr_asprintf(tmp, "chroot %s %s /boot/grub/menu.lst", MNT_RESTORING, editor);
1563            paranoid_system(tmp);
1564            mr_free(tmp);
1565
1566            mr_asprintf(tmp, "chroot %s %s /boot/grub/device.map", MNT_RESTORING, editor);
1567            paranoid_system(tmp);
1568            mr_free(tmp);
1569            mr_free(editor);
1570
1571            if (!g_text_mode) {
1572                newtResume();
1573            }
1574        }
1575    } else {
1576        /* nuke mode */
1577        if (!run_program_and_log_output("which grub-MR", FALSE)) {
1578            log_msg(1, "Yay! grub-MR found...");
1579            mr_asprintf(command, "grub-MR %s /tmp/mountlist.txt", boot_device);
1580            log_msg(1, "command = %s", command);
1581        } else {
1582            mr_asprintf(command, "chroot " MNT_RESTORING " grub-install %s", boot_device);
1583            log_msg(1, "WARNING - grub-MR not found; using grub-install");
1584        }
1585        mvaddstr_and_log_it(g_currentY,
1586                            0,
1587                            "Running GRUB...                                                 ");
1588        log_it("%s",command);
1589        res = run_program_and_log_output(command, 1);
1590        mr_free(command);
1591
1592        if (res) {
1593            popup_and_OK
1594                ("Because of bugs in GRUB's own installer, GRUB was not installed properly. Please install the boot loader manually now, using this chroot()'ed shell prompt. Type 'exit' when you have finished.");
1595            newtSuspend();
1596            system("chroot " MNT_RESTORING);
1597            newtResume();
1598            popup_and_OK("Thank you.");
1599        }
1600    }
1601    mr_free(boot_device);
1602
1603    if (res) {
1604        mvaddstr_and_log_it(g_currentY++, 74, "Failed.");
1605        log_to_screen
1606            ("GRUB ran w/error(s). See %s for more info.", MONDO_LOGFILE);
1607        log_msg(1, "Type:-");
1608        log_msg(1, "    mount-me");
1609        log_msg(1, "    chroot " MNT_RESTORING);
1610        log_msg(1, "    mount /boot");
1611        log_msg(1, "    grub-install '(hd0)'");
1612        log_msg(1, "    exit");
1613        log_msg(1, "    unmount-me");
1614        log_msg(1,
1615                "If you're really stuck, please e-mail the mailing list.");
1616    } else {
1617        mvaddstr_and_log_it(g_currentY++, 74, "Done.");
1618    }
1619    paranoid_free(rootdev);
1620    paranoid_free(rootdrive);
1621    paranoid_free(conffile);
1622
1623    return (res);
1624}
1625
1626/**************************************************************************
1627 *END_RUN_GRUB                                                            *
1628 **************************************************************************/
1629
1630
1631/**
1632 * Install ELILO on the user's boot drive (determined by elilo.conf).
1633 * @param offer_to_run_stabelilo If TRUE, then offer to hack the user's fstab for them.
1634 * @return 0 for success, nonzero for failure.
1635 */
1636int run_elilo(bool offer_to_run_stabelilo)
1637{
1638  /** malloc **/
1639    char *command = NULL;
1640    char *tmp = NULL;
1641    char *editor = NULL;
1642
1643    int res;
1644    int done;
1645
1646    if (offer_to_run_stabelilo
1647        && ask_me_yes_or_no("Did you change the mountlist or cloned the system ?"))
1648
1649        /* interactive mode */
1650    {
1651        mvaddstr_and_log_it(g_currentY,
1652                            0,
1653                            "Modifying fstab and elilo.conf...                             ");
1654        mr_asprintf(command, "stabelilo-me");
1655        res = run_program_and_log_output(command, 3);
1656        mr_free(command);
1657
1658        if (res) {
1659            popup_and_OK
1660                ("You will now edit fstab and elilo.conf, to make sure they match your new mountlist.");
1661            for (done = FALSE; !done;) {
1662                if (!g_text_mode) {
1663                    newtSuspend();
1664                }
1665                mr_asprintf(editor, "%s", find_my_editor());
1666
1667                mr_asprintf(tmp, "chroot %s %s /etc/fstab", MNT_RESTORING, editor);
1668                paranoid_system(tmp);
1669                mr_free(tmp);
1670
1671                mr_asprintf(tmp, "chroot %s %s /etc/elilo.conf", MNT_RESTORING, editor);
1672                paranoid_system(tmp);
1673                mr_free(tmp);
1674
1675                mr_free(editor);
1676
1677                if (!g_text_mode) {
1678                    newtResume();
1679                }
1680//              newtCls();
1681                if (ask_me_yes_or_no("Edit them again?")) {
1682                    continue;
1683                }
1684                done = TRUE;
1685            }
1686        } else {
1687            log_to_screen("elilo.conf and fstab were modified OK");
1688        }
1689    } else
1690        /* nuke mode */
1691    {
1692        res = TRUE;
1693    }
1694    return (res);
1695}
1696
1697/**************************************************************************
1698 *END_RUN_ELILO                                                            *
1699 **************************************************************************/
1700
1701
1702/**
1703 * Install LILO on the user's boot drive (determined by /etc/lilo.conf).
1704 * @param offer_to_run_stablilo If TRUE, then offer to hack the user's fstab for them.
1705 * @return 0 for success, nonzero for failure.
1706 */
1707int run_lilo(bool offer_to_run_stablilo)
1708{
1709  /** malloc **/
1710    char *command = NULL;
1711    char *tmp = NULL;
1712    char *editor = NULL;
1713
1714    int res;
1715    int done;
1716    bool run_lilo_M = FALSE;
1717
1718    if (!run_program_and_log_output
1719        ("grep \"boot.*=.*/dev/md\" " MNT_RESTORING "/etc/lilo.conf", 1)) {
1720        run_lilo_M = TRUE;
1721    }
1722
1723    if (offer_to_run_stablilo
1724        && ask_me_yes_or_no("Did you change the mountlist or cloned the system ?"))
1725
1726        /* interactive mode */
1727    {
1728        mvaddstr_and_log_it(g_currentY,
1729                            0,
1730                            "Modifying fstab and lilo.conf, and running LILO...                             ");
1731        mr_asprintf(command, "stablilo-me");
1732        res = run_program_and_log_output(command, 3);
1733        mr_free(command);
1734
1735        if (res) {
1736            popup_and_OK
1737                ("You will now edit fstab and lilo.conf, to make sure they match your new mountlist.");
1738            for (done = FALSE; !done;) {
1739                if (!g_text_mode) {
1740                    newtSuspend();
1741                }
1742                mr_asprintf(editor, "%s", find_my_editor());
1743
1744                mr_asprintf(tmp, "%s " MNT_RESTORING "/etc/fstab", editor);
1745                paranoid_system(tmp);
1746                mr_free(tmp);
1747
1748                mr_asprintf(tmp, "%s " MNT_RESTORING "/etc/lilo.conf", editor);
1749                paranoid_system(tmp);
1750                mr_free(tmp);
1751
1752                mr_free(editor);
1753
1754                if (!g_text_mode) {
1755                    newtResume();
1756                }
1757//              newtCls();
1758                if (ask_me_yes_or_no("Edit them again?")) {
1759                    continue;
1760                }
1761                res =
1762                    run_program_and_log_output("chroot " MNT_RESTORING
1763                                               " lilo -L", 3);
1764                if (res) {
1765                    res =
1766                        run_program_and_log_output("chroot " MNT_RESTORING
1767                                                   " lilo", 3);
1768                }
1769                if (res) {
1770                    done =
1771                        ask_me_yes_or_no
1772                        ("LILO failed. Re-edit system files?");
1773                } else {
1774                    done = TRUE;
1775                }
1776            }
1777        } else {
1778            log_to_screen("lilo.conf and fstab were modified OK");
1779        }
1780    } else
1781        /* nuke mode */
1782    {
1783        mvaddstr_and_log_it(g_currentY,
1784                            0,
1785                            "Running LILO...                                                 ");
1786        res =
1787            run_program_and_log_output("chroot " MNT_RESTORING " lilo -L",
1788                                       3);
1789        if (res) {
1790            res =
1791                run_program_and_log_output("chroot " MNT_RESTORING " lilo",
1792                                           3);
1793        }
1794        if (res) {
1795            mvaddstr_and_log_it(g_currentY++, 74, "Failed.");
1796            log_to_screen
1797                ("Failed to re-jig fstab and/or lilo. Edit/run manually, please.");
1798        } else {
1799            mvaddstr_and_log_it(g_currentY++, 74, "Done.");
1800        }
1801    }
1802    if (run_lilo_M) {
1803        run_program_and_log_output("chroot " MNT_RESTORING
1804                                   " lilo -M /dev/hda", 3);
1805        run_program_and_log_output("chroot " MNT_RESTORING
1806                                   " lilo -M /dev/sda", 3);
1807    }
1808    return (res);
1809}
1810
1811/**************************************************************************
1812 *END_RUN_LILO                                                            *
1813 **************************************************************************/
1814
1815
1816/**
1817 * Install a raw MBR onto @p bd.
1818 * @param offer_to_hack_scripts If TRUE, then offer to hack the user's fstab for them.
1819 * @param bd The device to copy the stored MBR to.
1820 * @return 0 for success, nonzero for failure.
1821 */
1822int run_raw_mbr(bool offer_to_hack_scripts, char *bd)
1823{
1824  /** malloc **/
1825    char *command = NULL;
1826    char *boot_device = NULL;
1827    char *tmp = NULL;
1828    char *editor;
1829    char *p = NULL;
1830    int res;
1831    int done;
1832
1833    assert_string_is_neither_NULL_nor_zerolength(bd);
1834
1835    mr_asprintf(boot_device, "%s", bd);
1836
1837    if (offer_to_hack_scripts
1838        && ask_me_yes_or_no("Did you change the mountlist or cloned the system ?")) {
1839        /* interactive mode */
1840        mvaddstr_and_log_it(g_currentY, 0,
1841                            "Modifying fstab and restoring MBR...                           ");
1842        for (done = FALSE; !done;) {
1843            if (!run_program_and_log_output("which vi", FALSE)) {
1844                popup_and_OK("You will now edit fstab");
1845                if (!g_text_mode) {
1846                    newtSuspend();
1847                }
1848                mr_asprintf(editor, "%s", find_my_editor());
1849                mr_asprintf(tmp, "%s " MNT_RESTORING "/etc/fstab", editor);
1850                mr_free(editor);
1851
1852                paranoid_system(tmp);
1853                mr_free(tmp);
1854                if (!g_text_mode) {
1855                    newtResume();
1856                }
1857            }
1858            p = popup_and_get_string("Boot device", "Please confirm/enter the boot device. If in doubt, try /dev/hda", boot_device);
1859            if (p == NULL) {
1860                done = TRUE;
1861                mr_free(p);
1862                /* we want some warnings later on */
1863                res = 1;
1864                continue;
1865            }
1866            mr_asprintf(command, "stabraw-me %s", p);
1867            mr_free(p);
1868
1869            res = run_program_and_log_output(command, 3);
1870            mr_free(command);
1871
1872            if (res) {
1873                done = ask_me_yes_or_no("Modifications failed. Re-try?");
1874            } else {
1875                done = TRUE;
1876            }
1877        }
1878    } else {
1879        /* nuke mode */
1880        mr_asprintf(command, "raw-MR %s /tmp/mountlist.txt", boot_device);
1881        log_msg(2, "run_raw_mbr() --- command='%s'", command);
1882
1883        mvaddstr_and_log_it(g_currentY, 0,
1884                            "Restoring MBR...                                               ");
1885        res = run_program_and_log_output(command, 3);
1886        mr_free(command);
1887    }
1888    mr_free(boot_device);
1889
1890    if (res) {
1891        mvaddstr_and_log_it(g_currentY++, 74, "Failed.");
1892        log_to_screen
1893            ("MBR+fstab processed w/error(s). See %s for more info.", MONDO_LOGFILE);
1894    } else {
1895        mvaddstr_and_log_it(g_currentY++, 74, "Done.");
1896    }
1897    return (res);
1898}
1899
1900/**************************************************************************
1901 *END_RUN_RAW_MBR                                                         *
1902 **************************************************************************/
1903
1904
1905
1906/**
1907 * malloc() and set sensible defaults for the mondorestore filename variables.
1908 * @param bkpinfo The backup information structure. Fields used:
1909 * - @c bkpinfo->tmpdir
1910 * - @c bkpinfo->disaster_recovery
1911 */
1912void setup_MR_global_filenames()
1913{
1914    assert(bkpinfo != NULL);
1915
1916    malloc_string(g_biggielist_txt);
1917    malloc_string(g_filelist_full);
1918    malloc_string(g_filelist_imagedevs);
1919    malloc_string(g_imagedevs_restthese);
1920    malloc_string(g_mondo_cfg_file);
1921    malloc_string(g_mountlist_fname);
1922    malloc_string(g_mondo_home);
1923
1924    sprintf(g_biggielist_txt, "%s/%s", bkpinfo->tmpdir, BIGGIELIST_TXT_STUB);
1925    sprintf(g_filelist_full, "%s/%s", bkpinfo->tmpdir, FILELIST_FULL_STUB);
1926    sprintf(g_filelist_imagedevs, "%s/tmp/filelist.imagedevs", bkpinfo->tmpdir);
1927    sprintf(g_imagedevs_restthese, "%s/tmp/imagedevs.restore-these", bkpinfo->tmpdir);
1928    if (bkpinfo->disaster_recovery) {
1929        sprintf(g_mondo_cfg_file, "/%s", MONDO_CFG_FILE_STUB);
1930        sprintf(g_mountlist_fname, "/%s", MOUNTLIST_FNAME_STUB);
1931    } else {
1932        sprintf(g_mondo_cfg_file, "%s/%s", bkpinfo->tmpdir, MONDO_CFG_FILE_STUB);
1933        sprintf(g_mountlist_fname, "%s/%s", bkpinfo->tmpdir, MOUNTLIST_FNAME_STUB);
1934    }
1935}
1936
1937/**************************************************************************
1938 *END_SET_GLOBAL_FILENAME                                                 *
1939 **************************************************************************/
1940
1941
1942/**
1943 * Copy @p input_file (containing the result of a compare) to @p output_file,
1944 * deleting spurious "changes" along the way.
1945 * @param output_file The output file to write with spurious changes removed.
1946 * @param input_file The input file, a list of changed files created by a compare.
1947 */
1948void streamline_changes_file(char *output_file, char *input_file)
1949{
1950    FILE *fin;
1951    FILE *fout;
1952  /** malloc **/
1953    char *incoming;
1954
1955    assert_string_is_neither_NULL_nor_zerolength(output_file);
1956    assert_string_is_neither_NULL_nor_zerolength(input_file);
1957    malloc_string(incoming);
1958
1959    if (!(fin = fopen(input_file, "r"))) {
1960        log_OS_error(input_file);
1961        return;
1962    }
1963    if (!(fout = fopen(output_file, "w"))) {
1964        fatal_error("cannot open output_file");
1965    }
1966    for (fgets(incoming, MAX_STR_LEN - 1, fin); !feof(fin);
1967         fgets(incoming, MAX_STR_LEN - 1, fin)) {
1968        if (strncmp(incoming, "etc/adjtime", 11)
1969            && strncmp(incoming, "etc/mtab", 8)
1970            && strncmp(incoming, "tmp/", 4)
1971            && strncmp(incoming, "boot/map", 8)
1972            && !strstr(incoming, "incheckentry")
1973            && strncmp(incoming, "etc/mail/statistics", 19)
1974            && strncmp(incoming, "var/", 4))
1975            fprintf(fout, "%s", incoming);  /* don't need \n here, for some reason.. */
1976    }
1977    paranoid_fclose(fout);
1978    paranoid_fclose(fin);
1979    paranoid_free(incoming);
1980}
1981
1982/**************************************************************************
1983 *END_STREAMLINE_CHANGES_FILE                                             *
1984 **************************************************************************/
1985
1986
1987/**
1988 * Give the user twenty seconds to press Ctrl-Alt-Del before we nuke their drives.
1989 */
1990void twenty_seconds_til_yikes()
1991{
1992    int i;
1993    /* MALLOC * */
1994    char *tmp = NULL;
1995
1996    if (does_file_exist("/tmp/NOPAUSE")) {
1997        return;
1998    }
1999    open_progress_form("CAUTION",
2000                       "Be advised: I am about to ERASE your hard disk(s)!",
2001                       "You may press Ctrl+Alt+Del to abort safely.",
2002                       "", 20);
2003    for (i = 0; i < 20; i++) {
2004        g_current_progress = i;
2005        mr_asprintf(tmp, "You have %d seconds left to abort.", 20 - i);
2006        update_progress_form(tmp);
2007        mr_free(tmp);
2008        sleep(1);
2009    }
2010    close_progress_form();
2011}
2012
2013/**************************************************************************
2014 *END_TWENTY_SECONDS_TIL_YIKES                                            *
2015 **************************************************************************/
2016
2017
2018/**
2019 * Unmount all devices in @p p_external_copy_of_mountlist.
2020 * @param p_external_copy_of_mountlist The mountlist to guide the devices to unmount.
2021 * @return 0 for success, nonzero for failure.
2022 */
2023int unmount_all_devices(struct mountlist_itself
2024                        *p_external_copy_of_mountlist)
2025{
2026    struct mountlist_itself *mountlist;
2027    int retval = 0, lino, res = 0, i;
2028    char *command = NULL;
2029    char *tmp = NULL;
2030
2031    assert(p_external_copy_of_mountlist != NULL);
2032
2033    mountlist = malloc(sizeof(struct mountlist_itself));
2034    memcpy((void *) mountlist, (void *) p_external_copy_of_mountlist,
2035           sizeof(struct mountlist_itself));
2036    sort_mountlist_by_mountpoint(mountlist, 0);
2037
2038    run_program_and_log_output("df -m", 3);
2039    mvaddstr_and_log_it(g_currentY, 0, "Unmounting devices      ");
2040    open_progress_form("Unmounting devices",
2041                       "Unmounting all devices that were mounted,",
2042                       "in preparation for the post-restoration reboot.",
2043                       "", mountlist->entries);
2044    chdir("/");
2045    for (i = 0;
2046         i < 10
2047         &&
2048         run_program_and_log_output
2049         ("ps | grep buffer | grep -v \"grep buffer\"", TRUE) == 0;
2050         i++) {
2051        sleep(1);
2052        log_msg(2, "Waiting for buffer() to finish");
2053    }
2054
2055    paranoid_system("sync");
2056
2057    mr_asprintf(tmp, "cp -f %s " MNT_RESTORING "/var/log", MONDO_LOGFILE);
2058    if (run_program_and_log_output(tmp, FALSE)) {
2059        log_msg(1,
2060                "Error. Failed to copy log to PC's /var/log dir. (Mounted read-only?)");
2061    }
2062    paranoid_free(tmp);
2063    if (does_file_exist("/tmp/DUMBASS-GENTOO")) {
2064        run_program_and_log_output("mkdir -p " MNT_RESTORING
2065                                   "/mnt/.boot.d", 5);
2066    }
2067
2068    /* Unmounting the local /proc and /sys first */
2069    run_program_and_log_output("umount " MNT_RESTORING "/proc",3);
2070    run_program_and_log_output("umount " MNT_RESTORING "/sys",3);
2071
2072    for (lino = mountlist->entries - 1; lino >= 0; lino--) {
2073        if (!strcmp(mountlist->el[lino].mountpoint, "lvm")) {
2074            continue;
2075        }
2076        mr_asprintf(tmp, "Unmounting device %s  ", mountlist->el[lino].device);
2077        update_progress_form(tmp);
2078
2079        if (is_this_device_mounted(mountlist->el[lino].device)) {
2080            if (!strcmp(mountlist->el[lino].mountpoint, "swap")) {
2081                mr_asprintf(command, "swapoff %s", mountlist->el[lino].device);
2082            } else {
2083                if (!strcmp(mountlist->el[lino].mountpoint, "/1")) {
2084                    mr_asprintf(command, "umount %s/", MNT_RESTORING);
2085                    log_msg(3,
2086                            "Well, I know a certain kitty-kitty who'll be sleeping with Mommy tonight...");
2087                } else {
2088                    mr_asprintf(command, "umount " MNT_RESTORING "%s", mountlist->el[lino].mountpoint);
2089
2090                    /* To support latest Ubuntu where /var is a separate FS
2091                     * Cf: http://linux.derkeiler.com/Mailing-Lists/Ubuntu/2007-04/msg01319.html
2092                     * we need to create some dirs under the real / before unmounting it */
2093                    if (!strcmp(mountlist->el[lino].mountpoint, "/")) {
2094                        run_program_and_log_output("mkdir -p " MNT_RESTORING "/var/lock", FALSE);
2095                        run_program_and_log_output("mkdir -p " MNT_RESTORING "/var/run", FALSE);
2096                    }
2097                }
2098            }
2099            log_msg(10, "The 'umount' command is '%s'", command);
2100            res = run_program_and_log_output(command, 3);
2101            mr_free(command);
2102        } else {
2103            mr_strcat(tmp, "...not mounted anyway :-) OK");
2104            res = 0;
2105        }
2106        g_current_progress++;
2107        if (res) {
2108            mr_strcat(tmp, "...Failed");
2109            retval++;
2110            log_to_screen(tmp);
2111        } else {
2112            log_msg(2, tmp);
2113        }
2114        paranoid_free(tmp);
2115    }
2116    close_progress_form();
2117    if (retval) {
2118        mvaddstr_and_log_it(g_currentY++, 74, "Failed.");
2119    } else {
2120        mvaddstr_and_log_it(g_currentY++, 74, "Done.");
2121    }
2122    if (retval) {
2123        log_to_screen("Unable to unmount some of your partitions.");
2124    } else {
2125        log_to_screen("All partitions were unmounted OK.");
2126    }
2127    free(mountlist);
2128    return (retval);
2129}
2130
2131/**************************************************************************
2132 *END_UNMOUNT_ALL_DEVICES                                                 *
2133 **************************************************************************/
2134
2135
2136
2137/**
2138 * Extract mondo-restore.cfg and the mountlist from the tape inserted
2139 * to the ./tmp/ directory.
2140 * @param dev The tape device to read from.
2141 * @return 0 for success, nonzero for failure.
2142 */
2143int extract_cfg_file_and_mountlist_from_tape_dev(char *dev)
2144{
2145    char *command = NULL;
2146    int res = 0;
2147
2148    if (bkpinfo->use_obdr) {
2149        skip_obdr();
2150    } else {
2151        // BCO: below 32KB seems to block at least on RHAS 2.1 and MDK 10.0
2152        set_tape_block_size_with_mt(bkpinfo->internal_tape_block_size);
2153    }
2154
2155    mr_asprintf(command, "dd if=%s bs=%ld count=%ld 2> /dev/null | tar -zx ./%s ./%s ./%s ./%s ./%s", dev, bkpinfo->internal_tape_block_size, 1024L * 1024 * 32 / bkpinfo->internal_tape_block_size, MOUNTLIST_FNAME_STUB, MONDO_CFG_FILE_STUB, BIGGIELIST_TXT_STUB, FILELIST_FULL_STUB, IWANTMYLVM_STUB);
2156    log_msg(2, "command = '%s'", command);
2157    res = run_program_and_log_output(command, -1);
2158    mr_free(command);
2159
2160    if (res != 0) {
2161        if (does_file_exist(MONDO_CFG_FILE_STUB)) {
2162            res = 0;
2163        } else {
2164            /* Doing that allow us to remain compatible with pre-2.2.5 versions */
2165            log_msg(2, "pre-2.2.4 compatible mode on");
2166            mr_asprintf(command, "dd if=%s bs=%ld count=%ld 2> /dev/null | tar -zx %s %s %s %s %s", dev, bkpinfo->internal_tape_block_size, 1024L * 1024 * 32 / bkpinfo->internal_tape_block_size, MOUNTLIST_FNAME_STUB, MONDO_CFG_FILE_STUB, BIGGIELIST_TXT_STUB, FILELIST_FULL_STUB, IWANTMYLVM_STUB);
2167            log_msg(2, "command = '%s'", command);
2168            res = run_program_and_log_output(command, -1);
2169            mr_free(command);
2170
2171            if ((res != 0) && (does_file_exist(MONDO_CFG_FILE_STUB))) {
2172                res = 0;
2173            }
2174        }
2175    }
2176    return (res);
2177}
2178
2179
2180
2181/**
2182 * Get the configuration file from the floppy, tape, or CD.
2183 * @param bkpinfo The backup information structure. Fields used:
2184 * - @c bkpinfo->backup_media_type
2185 * - @c bkpinfo->media_device
2186 * - @c bkpinfo->tmpdir
2187 * @return 0 for success, nonzero for failure.
2188 */
2189int get_cfg_file_from_archive()
2190{
2191    int retval = 0;
2192
2193   /** malloc *****/
2194    char *device;
2195    char *command = NULL;
2196    char *cfg_file = NULL;
2197    char *mounted_cfgf_path;
2198    char *tmp = NULL;
2199    char *mountpt = NULL;
2200    char *ramdisk_fname;
2201    char *mountlist_file = NULL;
2202    bool extract_mountlist_stub = FALSE;
2203    bool extract_i_want_my_lvm = FALSE;
2204
2205    bool try_plan_B;
2206
2207    assert(bkpinfo != NULL);
2208    malloc_string(mounted_cfgf_path);
2209    malloc_string(ramdisk_fname);
2210    malloc_string(device);
2211    log_msg(2, "gcffa --- starting");
2212    log_to_screen("I'm thinking...");
2213    mr_asprintf(mountpt, "%s/mount.bootdisk", bkpinfo->tmpdir);
2214    device[0] = '\0';
2215    chdir(bkpinfo->tmpdir);
2216    mr_asprintf(cfg_file, "%s", MONDO_CFG_FILE_STUB);
2217    unlink(cfg_file);           // cfg_file[] is missing the '/' at the start, FYI, by intent
2218    mr_free(cfg_file);
2219
2220    unlink(FILELIST_FULL_STUB);
2221    unlink(BIGGIELIST_TXT_STUB);
2222    mr_asprintf(command, "mkdir -p %s", mountpt);
2223    run_program_and_log_output(command, FALSE);
2224    mr_free(command);
2225
2226    mr_asprintf(cfg_file, "%s/%s", bkpinfo->tmpdir, MONDO_CFG_FILE_STUB);
2227    mr_asprintf(mountlist_file, "%s/%s", bkpinfo->tmpdir, MOUNTLIST_FNAME_STUB);
2228    log_msg(2, "mountpt = %s; cfg_file=%s", mountpt, cfg_file);
2229    mr_free(mountpt);
2230
2231    if (!does_file_exist(cfg_file)) {
2232        log_msg(2, "gcffa --- we don't have cfg file yet.");
2233        if (IS_THIS_A_STREAMING_BACKUP(bkpinfo->backup_media_type)) {
2234            try_plan_B = TRUE;
2235        } else {
2236            log_msg(2, "gcffa --- calling mount_media now :)");
2237            if (!mount_media()) {
2238                log_msg(2,
2239                        "gcffa --- managed to mount CD; so, no need for Plan B");
2240                try_plan_B = FALSE;
2241            } else {
2242                try_plan_B = TRUE;
2243            }
2244            if (what_number_cd_is_this() > 1) {
2245                insist_on_this_cd_number((g_current_media_number = 1));
2246            }
2247        }
2248        if (try_plan_B) {
2249            log_msg(2, "gcffa --- OK, switching to Plan B");
2250            chdir(bkpinfo->tmpdir);
2251            run_program_and_log_output("mkdir -p tmp", FALSE);
2252
2253            if (! bkpinfo->media_device) {
2254                mr_asprintf(bkpinfo->media_device, "/dev/st0");
2255                log_msg(2, "media_device is blank; assuming %s", bkpinfo->media_device);
2256            }
2257            mr_asprintf(tmp, "%s", bkpinfo->media_device);
2258            if (extract_cfg_file_and_mountlist_from_tape_dev (bkpinfo->media_device)) {
2259                mr_free(bkpinfo->media_device);
2260                mr_asprintf(bkpinfo->media_device, "/dev/st0");
2261                if (extract_cfg_file_and_mountlist_from_tape_dev (bkpinfo->media_device)) {
2262                    mr_free(bkpinfo->media_device);
2263                    mr_asprintf(bkpinfo->media_device, "/dev/osst0");
2264                    if (extract_cfg_file_and_mountlist_from_tape_dev (bkpinfo->media_device)) {
2265                        mr_free(bkpinfo->media_device);
2266                        mr_asprintf(bkpinfo->media_device, "/dev/ht0");
2267                        if (extract_cfg_file_and_mountlist_from_tape_dev (bkpinfo->media_device)) {
2268                            log_msg(3, "I tried lots of devices but none worked.");
2269                            mr_free(bkpinfo->media_device);
2270                            mr_asprintf(bkpinfo->media_device, "%s", tmp);
2271                        }
2272                    }
2273                }
2274            }
2275            mr_free(tmp);
2276
2277            if (!does_file_exist("tmp/mondo-restore.cfg")) {
2278                log_to_screen("Cannot find config info on media");
2279                return (1);
2280            }
2281        } else {
2282                if (does_file_exist("/"MOUNTLIST_FNAME_STUB)) {
2283                    extract_mountlist_stub = FALSE;
2284                } else {
2285                    extract_mountlist_stub = TRUE;
2286                }
2287                if (does_file_exist("/"IWANTMYLVM_STUB)) {
2288                    extract_i_want_my_lvm = FALSE;
2289                } else {
2290                    extract_i_want_my_lvm = TRUE;
2291                }
2292
2293                log_msg(2,
2294                        "gcffa --- Plan B, a.k.a. untarring some file from all.tar.gz");
2295                mr_asprintf(command, "tar -zxvf " MNT_CDROM "/images/all.tar.gz ./%s ./%s ./%s ./%s ./%s", MOUNTLIST_FNAME_STUB, MONDO_CFG_FILE_STUB, BIGGIELIST_TXT_STUB, FILELIST_FULL_STUB, IWANTMYLVM_STUB);    // add -b TAPE_BLOCK_SIZE if you _really_ think it's necessary
2296                run_program_and_log_output(command, TRUE);
2297                mr_free(command);
2298
2299                if (!does_file_exist(MONDO_CFG_FILE_STUB)) {
2300                    /* Doing that allow us to remain compatible with pre-2.2.5 versions */
2301                    log_msg(2, "pre-2.2.4 compatible mode on");
2302                    mr_asprintf(command, "tar -zxvf " MNT_CDROM "/images/all.tar.gz %s %s %s %s %s", MOUNTLIST_FNAME_STUB, MONDO_CFG_FILE_STUB, BIGGIELIST_TXT_STUB, FILELIST_FULL_STUB, IWANTMYLVM_STUB);  // add -b TAPE_BLOCK_SIZE if you _really_ think it's necessary
2303                    run_program_and_log_output(command, TRUE);
2304                    mr_free(command);
2305
2306                    if (!does_file_exist(MONDO_CFG_FILE_STUB)) {
2307                        fatal_error
2308                            ("Please reinsert the disk/CD and try again.");
2309                    }
2310                }
2311        }
2312    }
2313    if (does_file_exist(MONDO_CFG_FILE_STUB)) {
2314        log_msg(1, "gcffa --- great! We've got the config file");
2315        mr_asprintf(tmp, "%s/%s", call_program_and_get_last_line_of_output("pwd"), MONDO_CFG_FILE_STUB);
2316        mr_asprintf(command, "cp -f %s %s", tmp, cfg_file);
2317        log_it("%s",command);
2318        if (strcmp(tmp, cfg_file) && run_program_and_log_output(command, 1)) {
2319            log_msg(1, "... but an error occurred when I tried to move it to %s", cfg_file);
2320        } else {
2321            log_msg(1, "... and I moved it successfully to %s", cfg_file);
2322        }
2323        mr_free(command);
2324
2325        mr_asprintf(command, "cp -f %s/%s %s", call_program_and_get_last_line_of_output("pwd"),
2326            MOUNTLIST_FNAME_STUB, mountlist_file);
2327        log_it("%s",command);
2328        if (extract_mountlist_stub) {
2329            if (strcmp(tmp, cfg_file) && run_program_and_log_output(command, 1)) {
2330                log_msg(1, "Failed to get mountlist");
2331            } else {
2332                log_msg(1, "Got mountlist too");
2333
2334                mr_free(command);
2335                mr_asprintf(command, "cp -f %s %s", mountlist_file, g_mountlist_fname);
2336                if (run_program_and_log_output(command, 1)) {
2337                    log_msg(1, "Failed to copy mountlist to /tmp");
2338                } else {
2339                    log_msg(1, "Copied mountlist to /tmp as well OK");
2340                    mr_free(command);
2341                    mr_asprintf(command, "cp -f %s /tmp/",IWANTMYLVM_STUB);
2342                    run_program_and_log_output(command, 1);
2343                }
2344            }
2345        }
2346        mr_free(tmp);
2347        mr_free(command);
2348    }
2349    run_program_and_log_output("umount " MNT_CDROM, FALSE);
2350    if (!does_file_exist(cfg_file)) {
2351        log_it("%s",cfg_file);
2352        log_msg(1, "%s not found", cfg_file);
2353        log_to_screen
2354            ("Oh dear. Unable to recover configuration file from boot disk");
2355        return (1);
2356    }
2357
2358    log_to_screen("Recovered mondo-restore.cfg");
2359    if (!does_file_exist(MOUNTLIST_FNAME_STUB)) {
2360        log_to_screen("...but not mountlist.txt - a pity, really...");
2361    }
2362    else {
2363            /* Is this code really useful ??? */
2364        if (extract_mountlist_stub) {
2365            mr_asprintf(command, "cp -f %s %s/%s", MOUNTLIST_FNAME_STUB, bkpinfo->tmpdir, MOUNTLIST_FNAME_STUB);
2366            run_program_and_log_output(command, FALSE);
2367            mr_free(command);
2368        }
2369    }
2370
2371    mr_asprintf(command, "cp -f %s /%s", cfg_file, MONDO_CFG_FILE_STUB);
2372    mr_free(cfg_file);
2373
2374    run_program_and_log_output(command, FALSE);
2375    mr_free(command);
2376
2377    if (extract_mountlist_stub) {
2378        mr_asprintf(command, "cp -f %s /%s", mountlist_file, MOUNTLIST_FNAME_STUB);
2379        run_program_and_log_output(command, FALSE);
2380        mr_free(command);
2381    }
2382    mr_free(mountlist_file);
2383
2384    mr_asprintf(command, "cp -f etc/raidtab /etc/");
2385    run_program_and_log_output(command, FALSE);
2386    mr_free(command);
2387
2388    if (extract_i_want_my_lvm) {
2389        mr_asprintf(command, "cp -f %s /tmp/",IWANTMYLVM_STUB);
2390        run_program_and_log_output(command, FALSE);
2391        mr_free(command);
2392    }
2393    g_backup_media_type = bkpinfo->backup_media_type;
2394    paranoid_free(device);
2395    paranoid_free(mounted_cfgf_path);
2396    paranoid_free(ramdisk_fname);
2397    return (retval);
2398}
2399
2400/**************************************************************************
2401 *END_GET_CFG_FILE_FROM_ARCHIVE                                           *
2402 **************************************************************************/
2403
2404/* @} - end restoreUtilityGroup */
2405
2406void wait_until_software_raids_are_prepped(char *mdstat_file,
2407                                           int wait_for_percentage)
2408{
2409    struct raidlist_itself *raidlist;
2410    int unfinished_mdstat_devices = 9999, i;
2411    char *screen_message = NULL;
2412
2413    raidlist = malloc(sizeof(struct raidlist_itself));
2414
2415    assert(wait_for_percentage <= 100);
2416    log_it("wait_until_software_raids_are_prepped");
2417    while (unfinished_mdstat_devices > 0) {
2418            // FIXME: Prefix '/dev/' should really be dynamic!
2419        if (parse_mdstat(raidlist, "/dev/")) {
2420            log_to_screen("Sorry, cannot read %s", MDSTAT_FILE);
2421            log_msg(1,"Sorry, cannot read %s", MDSTAT_FILE);
2422            return;
2423        }
2424        for (unfinished_mdstat_devices = i = 0; i <= raidlist->entries; i++) {
2425            if (raidlist->el[i].progress < wait_for_percentage) {
2426                unfinished_mdstat_devices++;
2427                if (raidlist->el[i].progress == -1) // delayed while another partition inits
2428                {
2429                    continue;
2430                }
2431                log_msg(1,"Sync'ing %s (i=%d)", raidlist->el[i].raid_device, i);
2432                mr_asprintf(screen_message, "Sync'ing %s", raidlist->el[i].raid_device);
2433                open_evalcall_form(screen_message);
2434                mr_free(screen_message);
2435
2436                while (raidlist->el[i].progress < wait_for_percentage) {
2437                    log_msg(1,"Percentage sync'ed: %d", raidlist->el[i].progress);
2438                    update_evalcall_form(raidlist->el[i].progress);
2439                    sleep(2);
2440                    // FIXME: Prefix '/dev/' should really be dynamic!
2441                    if (parse_mdstat(raidlist, "/dev/")) {
2442                        break;
2443                    }
2444                }
2445                close_evalcall_form();
2446            }
2447        }
2448    }
2449    paranoid_free(raidlist);
2450}
2451
2452
Note: See TracBrowser for help on using the repository browser.