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

Last change on this file since 2329 was 2329, checked in by Bruno Cornec, 12 years ago

r3340@localhost: bruno | 2009-08-12 00:17:29 +0200
Improve portability by defining all cmdline usage in 1 include (/tmp for FreeBSD and /proc fior LInux). Also doing tht for scripts.

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