source: branches/2.2.6/mondo/src/mondorestore/mondo-rstr-tools.c @ 1971

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

Umount local /proc and /sys before trying to umount other FS at end of backup

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