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

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