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

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