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

Last change on this file since 2334 was 2334, checked in by Bruno Cornec, 11 years ago

r3369@localhost: bruno | 2009-08-18 16:57:27 +0200

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