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

Last change on this file since 2404 was 2404, checked in by bruno, 10 years ago
  • At restore time read the netfs protocol in the conf file
  • Use dir for shell related commands and dir1 for C related actions in open_and_list_dir to avoid missing some files with { in names e.g.

(Backports from 2.2.9)

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