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

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

r3342@localhost: bruno | 2009-08-14 00:46:51 +0200

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