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

Last change on this file since 2389 was 2389, checked in by bruno, 10 years ago

Fix a problem in netfs analysis in mondoarchive
(Backport from 2.2.9)

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