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

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

r3332@localhost: bruno | 2009-08-07 23:59:34 +0200

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