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

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

call_program_and_get_last_line_of_output is now allocating memory and returning that string

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