source: branches/2.2.5/mondo/src/mondorestore/mondo-rstr-tools.c @ 1845

Last change on this file since 1845 was 1845, checked in by Bruno Cornec, 13 years ago

Attempt to fix #224

  • Property svn:keywords set to Id
File size: 78.7 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 <fd.h>
128#include "../common/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_sigpipe_caught;
137extern bool g_ISO_restore_mode; /* are we in Iso Mode? */
138extern bool g_I_have_just_nuked;
139extern char *g_tmpfs_mountpt;
140extern char *g_isodir_device;
141extern char *g_isodir_format;
142extern long g_current_progress, g_maximum_progress;
143extern char *g_biggielist_txt;  // where 'biggielist.txt' is stored, on ramdisk / tempdir;
144                  // biggielist.txt is the list of big files stored on the
145                  // backup media set in question
146extern char *g_filelist_full;   // filelist.full.gz is the list of all regular files
147                  // (excluding big files) stored on the backup media set
148extern char *g_biggielist_pot;  // list of big files which _could_ be restored, if the
149                  // user chooses them
150extern char *g_filelist_imagedevs;  // list of devices (e.g. /dev/hda1, /dev/sda5) which
151                     // were archived as images, not just /dev entries
152                     // ... e.g. NTFS, BeOS partitions
153extern char *g_imagedevs_restthese; // of the imagedevs listed in FILELIST_IMAGEDEVS,
154                      // restore only these
155extern char *g_mondo_cfg_file;  // where m*ndo-restore.cfg (the config file) is stored
156extern char *g_mountlist_fname; // where mountlist.txt (the mountlist file) is stored
157extern char *g_mondo_home;      // homedir of Mondo; usually /usr/local/share/mondo
158
159extern t_bkptype g_backup_media_type;
160
161extern int g_partition_table_locked_up;
162extern char *MONDO_LOGFILE;
163
164/* Reference to global bkpinfo */
165extern struct s_bkpinfo *bkpinfo;
166
167/* Should we use or not extended attributes and acl when restoring */
168char *g_getfattr = NULL;
169char *g_getfacl = NULL;
170
171/**
172* @addtogroup restoreUtilityGroup
173* @{
174*/
175/**
176* Free the malloc()s for the filename variables.
177*/
178void free_MR_global_filenames()
179{
180paranoid_free(g_biggielist_txt);
181paranoid_free(g_filelist_full);
182paranoid_free(g_filelist_imagedevs);
183//  paranoid_free (g_imagedevs_pot );
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{
518char *command;
519malloc_string(command);
520sprintf(command,
521    "kill `ps 2> /dev/null | grep petris 2> /dev/null | grep -v grep | cut -d' ' -f2` 2> /dev/null");
522paranoid_system(command);
523paranoid_free(command);
524}
525
526/**************************************************************************
527*END_KILL_PETRIS                                                         *
528**************************************************************************/
529
530
531/**
532 * Mount @p device at @p mpt as @p format.
533 * @param device The device (/dev entry) to mount.
534 * @param mpt The directory to mount it on.
535 * @param format The filesystem type of @p device.
536 * @param writeable If TRUE, mount read-write; if FALSE, mount read-only.
537 * @return 0 for success, nonzero for failure.
538 */
539int mount_device(char *device, char *mpt, char *format, bool writeable)
540{
541int res = 0;
542
543/** malloc **/
544char *tmp, *command, *mountdir, *mountpoint, *additional_parameters;
545
546assert_string_is_neither_NULL_nor_zerolength(device);
547assert_string_is_neither_NULL_nor_zerolength(mpt);
548assert(format != NULL);
549malloc_string(tmp);
550malloc_string(command);
551malloc_string(mountdir);
552malloc_string(mountpoint);
553malloc_string(additional_parameters);
554
555    if (!strcmp(mpt, "/1")) {
556        strcpy(mountpoint, "/");
557        log_msg(3, "Mommm! SME is being a dildo!");
558    } else {
559        strcpy(mountpoint, mpt);
560    }
561
562    if (!strcmp(mountpoint, "lvm")) {
563        return (0);
564    }
565    if (!strcmp(mountpoint, "image")) {
566        return (0);
567    }
568    sprintf(tmp, "Mounting device %s   ", device);
569    log_msg(1, tmp);
570    if (writeable) {
571        strcpy(additional_parameters, "-o rw");
572    } else {
573        strcpy(additional_parameters, "-o ro");
574    }
575    if (find_home_of_exe("setfattr")) {
576        strcat(additional_parameters, ",user_xattr");
577    }
578    if (find_home_of_exe("setfacl")) {
579        strcat(additional_parameters, ",acl");
580    }
581
582    if (!strcmp(mountpoint, "swap")) {
583        sprintf(command, "swapon %s", device);
584    } else {
585        if (!strcmp(mountpoint, "/")) {
586            strcpy(mountdir, MNT_RESTORING);
587        } else {
588            sprintf(mountdir, "%s%s", MNT_RESTORING, mountpoint);
589        }
590        sprintf(command, "mkdir -p %s", mountdir);
591        run_program_and_log_output(command, FALSE);
592        sprintf(command, "mount -t %s %s %s %s 2>> %s", format, device,
593                additional_parameters, mountdir, MONDO_LOGFILE);
594        log_msg(2, "command='%s'", command);
595    }
596
597    res = run_program_and_log_output(command, TRUE);
598    if (res && (strstr(command, "xattr") || strstr(command, "acl"))) {
599        log_msg(1, "Re-trying without the fancy extra parameters");
600        sprintf(command, "mount -t %s %s %s 2>> %s", format, device,
601            mountdir, MONDO_LOGFILE);
602        res = run_program_and_log_output(command, TRUE);
603    }
604    if (res) {
605        log_msg(1, "Unable to mount device %s (type %s) at %s", device,
606                format, mountdir);
607        log_msg(1, "command was '%s'", command);
608        if (!strcmp(mountpoint, "swap")) {
609            log_to_screen(tmp);
610        } else {
611            log_msg(2, "Retrying w/o the '-t' switch");
612            sprintf(command, "mount %s %s 2>> %s", device, mountdir,
613                MONDO_LOGFILE);
614            log_msg(2, "2nd command = '%s'", command);
615            res = run_program_and_log_output(command, TRUE);
616            if (res == 0) {
617                log_msg(1,
618                    "That's OK. I called mount w/o a filesystem type and it worked fine in the end.");
619            } else {
620                log_to_screen(tmp);
621            }
622        }
623    }
624
625    if (res && !strcmp(mountpoint, "swap")) {
626        log_msg(2, "That's ok. It's just a swap partition.");
627        log_msg(2, "Non-fatal error. Returning 0.");
628        res = 0;
629    }
630
631paranoid_free(tmp);
632paranoid_free(command);
633paranoid_free(mountdir);
634paranoid_free(mountpoint);
635paranoid_free(additional_parameters);
636
637    return (res);
638}
639/**************************************************************************
640 *END_MOUNT_DEVICE                                                        *
641**************************************************************************/
642
643
644/**
645 * Mount all devices in @p p_external_copy_of_mountlist on @p MNT_RESTORING.
646 * @param p_external_copy_of_mountlist The mountlist containing devices to be mounted.
647 * @param writeable If TRUE, then mount read-write; if FALSE mount read-only.
648 * @return The number of errors encountered (0 for success).
649 */
650int mount_all_devices(struct mountlist_itself
651                      *p_external_copy_of_mountlist, bool writeable)
652{
653int retval = 0, lino, res;
654char *tmp, *these_failed, *format;
655    struct mountlist_itself *mountlist = NULL;
656
657malloc_string(tmp);
658malloc_string(format);
659malloc_string(these_failed);
660/** menset **/
661these_failed[0] = '\0';
662
663assert(p_external_copy_of_mountlist != NULL);
664mountlist = malloc(sizeof(struct mountlist_itself));
665memcpy((void *) mountlist, (void *) p_external_copy_of_mountlist,
666   sizeof(struct mountlist_itself));
667    sort_mountlist_by_mountpoint(mountlist, 0);
668
669
670    mvaddstr_and_log_it(g_currentY, 0, "Mounting devices         ");
671    open_progress_form("Mounting devices",
672               "I am now mounting all the drives.",
673               "This should not take long.",
674               "", mountlist->entries);
675
676    for (lino = 0; lino < mountlist->entries; lino++) {
677        if (!strcmp(mountlist->el[lino].device, "/proc")) {
678            log_msg(1,
679                "Again with the /proc - why is this in your mountlist?");
680        } else if (is_this_device_mounted(mountlist->el[lino].device)) {
681            sprintf(tmp, "%s is already mounted",
682                mountlist->el[lino].device);
683            log_to_screen(tmp);
684        } else if (strcmp(mountlist->el[lino].mountpoint, "none")
685           && strcmp(mountlist->el[lino].mountpoint, "lvm")
686           && strcmp(mountlist->el[lino].mountpoint, "raid")
687           && strcmp(mountlist->el[lino].mountpoint, "image")) {
688            sprintf(tmp, "Mounting %s", mountlist->el[lino].device);
689            update_progress_form(tmp);
690            strcpy(format, mountlist->el[lino].format);
691            /* BERLIOS: removed as it doen't make sens to not mount ext3 partitions as ext3
692            if (!strcmp(format, "ext3")) {
693                strcpy(format, "ext2");
694            }
695            */
696            res = mount_device(mountlist->el[lino].device,
697                       mountlist->el[lino].mountpoint,
698                       format, writeable);
699            retval += res;
700            if (res) {
701                strcat(these_failed, mountlist->el[lino].device);
702                strcat(these_failed, " ");
703            }
704        }
705        g_current_progress++;
706    }
707    close_progress_form();
708    if (retval) {
709        if (g_partition_table_locked_up > 0) {
710            log_to_screen
711                ("fdisk's ictol() call to refresh its copy of the partition table causes the kernel to");
712            log_to_screen
713                ("lock up the partition table. You might have to reboot and use Interactive Mode to");
714            log_to_screen
715                ("format and restore *without* partitioning first. Sorry for the inconvenience.");
716        }
717        sprintf(tmp, "Could not mount device(s) %s- shall I abort?",
718                these_failed);
719
720        if (!ask_me_yes_or_no(tmp)) {
721            retval = 0;
722            log_to_screen
723                ("Continuing, although some device(s) failed to be mounted");
724            mvaddstr_and_log_it(g_currentY++, 74, "Done.");
725        } else {
726            mvaddstr_and_log_it(g_currentY++, 74, "Failed.");
727            log_to_screen
728        ("Unable to mount some or all of your partitions.");
729        }
730    } else {
731        log_to_screen("All partitions were mounted OK.");
732        mvaddstr_and_log_it(g_currentY++, 74, "Done.");
733    }
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    if (read_cfg_var(cfg_file, "iso-prefix", value) == 0) {
979            strcpy(bkpinfo->prefix,value);
980    } else {
981            strcpy(bkpinfo->prefix,STD_PREFIX);
982    }
983    if (strstr(call_program_and_get_last_line_of_output
984       ("cat /proc/cmdline"), "pxe")) {
985        /* We need to override prefix value in PXE mode as it's
986        * already done in start-nfs */
987        envtmp1 = getenv("imgname");
988        if (envtmp1 == NULL) {
989            fatal_error("no imgname variable in environment");
990        }
991        strcpy(bkpinfo->prefix,envtmp1);
992    }
993
994} else if (!strcmp(value, "tape")) {
995    bkpinfo->backup_media_type = tape;
996} else if (!strcmp(value, "udev")) {
997    bkpinfo->backup_media_type = udev;
998} else {
999    fatal_error("UNKNOWN bkp-media-type");
1000}
1001} else {
1002fatal_error("backup-media-type not specified!");
1003}
1004if (bkpinfo->disaster_recovery) {
1005    if (bkpinfo->backup_media_type == cdstream) {
1006        sprintf(bkpinfo->media_device, "/dev/cdrom");
1007//          bkpinfo->media_size[0] = -1;
1008        bkpinfo->media_size[0] = 1999 * 1024;
1009        bkpinfo->media_size[1] = 650;   /* good guess */
1010    } else if (bkpinfo->backup_media_type == usb) {
1011        if (read_cfg_var(cfg_file, "usb-dev", value)) {
1012            fatal_error("Cannot get USB device name from cfg file");
1013        }
1014        sprintf(bkpinfo->media_device, "%s1", value);
1015        sprintf(tmp, "Backup medium is USB --- dev=%s", bkpinfo->media_device);
1016        log_msg(2, tmp);
1017    } else if (bkpinfo->backup_media_type == tape
1018            || bkpinfo->backup_media_type == udev) {
1019        if (read_cfg_var(cfg_file, "media-dev", value)) {
1020            fatal_error("Cannot get tape device name from cfg file");
1021        }
1022        strcpy(bkpinfo->media_device, value);
1023        read_cfg_var(cfg_file, "media-size", value);
1024        bkpinfo->media_size[1] = atol(value);
1025        sprintf(tmp, "Backup medium is TAPE --- dev=%s",
1026                bkpinfo->media_device);
1027        log_msg(2, tmp);
1028    } else {
1029        strcpy(bkpinfo->media_device, "/dev/cdrom");    /* we don't really need this var */
1030        bkpinfo->media_size[0] = 1999 * 1024;   /* 650, probably, but we don't need this var anyway */
1031        bkpinfo->media_size[1] = 1999 * 1024;   /* 650, probably, but we don't need this var anyway */
1032        log_msg(2, "Backup medium is CD-R[W]");
1033    }
1034} else {
1035    log_msg(2,
1036        "Not in Disaster Recovery Mode. No need to derive device name from config file.");
1037}
1038
1039read_cfg_var(cfg_file, "use-star", value);
1040if (strstr(value, "yes")) {
1041bkpinfo->use_star = TRUE;
1042log_msg(1, "Goody! ... bkpinfo->use_star is now true.");
1043}
1044
1045read_cfg_var(cfg_file, "acl", value);
1046if (strstr(value, "TRUE")) {
1047asprintf(&g_getfacl,"setfacl");
1048log_msg(1, "We will restore ACLs");
1049if (! find_home_of_exe("setfacl")) {
1050    log_msg(1, "Unable to restore ACLs as no setfacl found");
1051}
1052}
1053read_cfg_var(cfg_file, "xattr", value);
1054if (strstr(value, "TRUE")) {
1055asprintf(&g_getfattr,"setfattr");
1056log_msg(1, "We will restore XATTRs");
1057if (! find_home_of_exe("setfattr")) {
1058    log_msg(1, "Unable to restore XATTRs as no setfattr found");
1059}
1060}
1061
1062if (0 == read_cfg_var(cfg_file, "internal-tape-block-size", value)) {
1063bkpinfo->internal_tape_block_size = atol(value);
1064log_msg(1, "Internal tape block size has been custom-set to %ld",
1065        bkpinfo->internal_tape_block_size);
1066} else {
1067bkpinfo->internal_tape_block_size =
1068    DEFAULT_INTERNAL_TAPE_BLOCK_SIZE;
1069log_msg(1, "Internal tape block size = default (%ld)",
1070        DEFAULT_INTERNAL_TAPE_BLOCK_SIZE);
1071}
1072
1073read_cfg_var(cfg_file, "use-lzo", value);
1074if (strstr(value, "yes")) {
1075bkpinfo->use_lzo = TRUE;
1076bkpinfo->use_gzip = FALSE;
1077strcpy(bkpinfo->zip_exe, "lzop");
1078strcpy(bkpinfo->zip_suffix, "lzo");
1079} else {
1080read_cfg_var(cfg_file, "use-gzip", value);
1081if (strstr(value, "yes")) {
1082    bkpinfo->use_lzo = FALSE;
1083    bkpinfo->use_gzip = TRUE;
1084    strcpy(bkpinfo->zip_exe, "gzip");
1085    strcpy(bkpinfo->zip_suffix, "gz");
1086} else {
1087    read_cfg_var(cfg_file, "use-comp", value);
1088    if (strstr(value, "yes")) {
1089        bkpinfo->use_lzo = FALSE;
1090        bkpinfo->use_gzip = FALSE;
1091        strcpy(bkpinfo->zip_exe, "bzip2");
1092        strcpy(bkpinfo->zip_suffix, "bz2");
1093    } else {
1094        bkpinfo->zip_exe[0] = bkpinfo->zip_suffix[0] = '\0';
1095    }
1096}
1097}
1098
1099value[0] = '\0';
1100read_cfg_var(cfg_file, "differential", value);
1101if (!strcmp(value, "yes") || !strcmp(value, "1")) {
1102bkpinfo->differential = TRUE;
1103}
1104log_msg(2, "differential var = '%s'", value);
1105if (bkpinfo->differential) {
1106log_msg(2, "THIS IS A DIFFERENTIAL BACKUP");
1107} else {
1108log_msg(2, "This is a regular (full) backup");
1109}
1110
1111read_cfg_var(g_mondo_cfg_file, "please-dont-eject", tmp);
1112if (tmp[0]
1113||
1114strstr(call_program_and_get_last_line_of_output
1115       ("cat /proc/cmdline"), "donteject")) {
1116bkpinfo->please_dont_eject = TRUE;
1117log_msg(2, "Ok, I shan't eject when restoring! Groovy.");
1118}
1119
1120if (bkpinfo->backup_media_type == nfs) {
1121    if (!cfgf) {
1122        log_msg(2, "nfs_mount remains %s", bkpinfo->nfs_mount);
1123        log_msg(2, "nfs_remote_dir remains %s",
1124                bkpinfo->nfs_remote_dir);
1125        log_msg(2,
1126                "...cos it wouldn't make sense to abandon the values that GOT ME to this config file in the first place");
1127    } else {
1128        read_cfg_var(g_mondo_cfg_file, "nfs-server-mount",
1129                    bkpinfo->nfs_mount);
1130        read_cfg_var(g_mondo_cfg_file, "nfs-server-path",
1131                    bkpinfo->nfs_remote_dir);
1132        log_msg(2, "nfs_mount is %s", bkpinfo->nfs_mount);
1133        log_msg(2, "nfs_remote_dir is %s", bkpinfo->nfs_remote_dir);
1134    }
1135    if (strstr(call_program_and_get_last_line_of_output
1136        ("cat /proc/cmdline"), "pxe")) {
1137        /* We need to override values in PXE mode as it's
1138        * already done in start-nfs */
1139        envtmp1 = getenv("nfsmount");
1140        if (envtmp1 == NULL) {
1141            fatal_error("no nfsmount variable in environment");
1142        }
1143        envtmp2 = getenv("dirimg");
1144        if (envtmp2 == NULL) {
1145            fatal_error("no dirimg variable in environment");
1146        }
1147        strcpy(bkpinfo->nfs_mount,envtmp1);
1148        strcpy(bkpinfo->nfs_remote_dir,envtmp2);
1149    }
1150} else if (bkpinfo->backup_media_type == iso) {
1151    /* Patch by Conor Daly 23-june-2004
1152    * to correctly mount iso-dev and set a sensible
1153    * isodir in disaster recovery mode
1154    */
1155    strcpy(old_isodir, bkpinfo->isodir);
1156    read_cfg_var(g_mondo_cfg_file, "iso-mnt", iso_mnt);
1157    read_cfg_var(g_mondo_cfg_file, "isodir", iso_path);
1158    sprintf(bkpinfo->isodir, "%s%s", iso_mnt, iso_path);
1159    if (!bkpinfo->isodir[0]) {
1160        strcpy(bkpinfo->isodir, old_isodir);
1161    }
1162    if (!bkpinfo->disaster_recovery) {
1163        if (strcmp(old_isodir, bkpinfo->isodir)) {
1164            log_it
1165                ("user nominated isodir differs from archive, keeping user's choice: %s %s\n",
1166                old_isodir, bkpinfo->isodir);
1167            strcpy(bkpinfo->isodir, old_isodir);
1168        }
1169    }
1170    read_cfg_var(g_mondo_cfg_file, "iso-dev", g_isodir_device);
1171    log_msg(2, "isodir=%s; iso-dev=%s", bkpinfo->isodir,
1172            g_isodir_device);
1173    if (bkpinfo->disaster_recovery) {
1174        if (is_this_device_mounted(g_isodir_device)) {
1175            log_msg(2, "NB: isodir is already mounted");
1176            /* Find out where it's mounted */
1177            sprintf(command,
1178                    "mount | grep -E '^%s' | tail -n1 | cut -d' ' -f3",
1179                    g_isodir_device);
1180            log_it("command = %s", command);
1181            log_it("res of it = %s",
1182                call_program_and_get_last_line_of_output(command));
1183            sprintf(iso_mnt, "%s",
1184                    call_program_and_get_last_line_of_output(command));
1185        } else {
1186            sprintf(iso_mnt, "/tmp/isodir");
1187            sprintf(tmp, "mkdir -p %s", iso_mnt);
1188            run_program_and_log_output(tmp, 5);
1189            sprintf(tmp, "mount %s %s", g_isodir_device, iso_mnt);
1190            if (run_program_and_log_output(tmp, 3)) {
1191                log_msg(1,
1192                        "Unable to mount isodir. Perhaps this is really a CD backup?");
1193                bkpinfo->backup_media_type = cdr;
1194                strcpy(bkpinfo->media_device, "/dev/cdrom");    /* superfluous */
1195                bkpinfo->isodir[0] = iso_mnt[0] = iso_path[0] = '\0';
1196                if (mount_media()) {
1197                    fatal_error
1198                        ("Unable to mount isodir. Failed to mount CD-ROM as well.");
1199                } else {
1200                    log_msg(1,
1201                            "You backed up to disk, then burned some CDs.");
1202                }
1203            }
1204        }
1205        /* bkpinfo->isodir should now be the true path to prefix-1.iso etc... */
1206        if (bkpinfo->backup_media_type == iso) {
1207            sprintf(bkpinfo->isodir, "%s%s", iso_mnt, iso_path);
1208        }
1209    }
1210}
1211
1212if (media_specified_by_user != none) {
1213    if (g_restoring_live_from_cd) {
1214        if (bkpinfo->backup_media_type != media_specified_by_user) {
1215            log_msg(2,
1216                    "bkpinfo->backup_media_type != media_specified_by_user, so I'd better ask :)");
1217            interactively_obtain_media_parameters_from_user(FALSE);
1218            media_specified_by_user = bkpinfo->backup_media_type;
1219            get_cfg_file_from_archive();
1220    /*
1221        if (media_specified_by_user != cdr && media_specified_by_user == cdrw)
1222            { g_restoring_live_from_cd = FALSE; }
1223    */
1224        }
1225    }
1226    bkpinfo->backup_media_type = media_specified_by_user;
1227}
1228g_backup_media_type = bkpinfo->backup_media_type;
1229paranoid_free(value);
1230paranoid_free(tmp);
1231paranoid_free(command);
1232paranoid_free(iso_mnt);
1233paranoid_free(iso_path);
1234paranoid_free(old_isodir);
1235return (0);
1236
1237}
1238
1239/**************************************************************************
1240*END_READ_CFG_FILE_INTO_BKPINFO                                          *
1241**************************************************************************/
1242
1243
1244
1245
1246/**
1247 * Allow the user to edit the filelist and biggielist.
1248 * The filelist is unlinked after it is read.
1249 * @param bkpinfo The backup information structure. Fields used:
1250 * - @c bkpinfo->backup_media_type
1251 * - @c bkpinfo->isodir
1252 * - @c bkpinfo->media_device
1253 * - @c bkpinfo->tmpdir
1254 * @return The filelist structure containing the information read from disk.
1255 */
1256struct
1257s_node *process_filelist_and_biggielist()
1258{
1259struct s_node *filelist;
1260
1261/** add mallocs**/
1262char *command;
1263char *tmp;
1264int res = 0;
1265pid_t pid;
1266
1267assert(bkpinfo != NULL);
1268malloc_string(command);
1269malloc_string(tmp);
1270
1271if (does_file_exist(g_filelist_full)
1272&& does_file_exist(g_biggielist_txt)) {
1273log_msg(1, "%s exists", g_filelist_full);
1274log_msg(1, "%s exists", g_biggielist_txt);
1275log_msg(2,
1276        "Filelist and biggielist already recovered from media. Yay!");
1277} else {
1278getcwd(tmp, MAX_STR_LEN);
1279chdir(bkpinfo->tmpdir);
1280log_msg(1, "chdir(%s)", bkpinfo->tmpdir);
1281log_to_screen("Extracting filelist and biggielist from media...");
1282unlink("/tmp/filelist.full");
1283unlink("/" FILELIST_FULL_STUB);
1284unlink("/tmp/i-want-my-lvm");
1285if (IS_THIS_A_STREAMING_BACKUP(bkpinfo->backup_media_type)) {
1286    sprintf(command,
1287            "tar -b %ld -zxf %s %s %s %s %s %s",
1288            bkpinfo->internal_tape_block_size,
1289            bkpinfo->media_device,
1290            MOUNTLIST_FNAME_STUB,
1291            BIGGIELIST_TXT_STUB,
1292            FILELIST_FULL_STUB,
1293            "tmp/i-want-my-lvm", MONDO_CFG_FILE_STUB);
1294    log_msg(1, "tarcommand = %s", command);
1295    run_program_and_log_output(command, 1);
1296} else {
1297    log_msg(2,
1298            "Calling insist_on_this_cd_number; bkpinfo->isodir=%s",
1299            bkpinfo->isodir);
1300    insist_on_this_cd_number(1);
1301    log_msg(2, "Back from iotcn");
1302    run_program_and_log_output("mount", 1);
1303    sprintf(command,
1304            "tar -zxf %s/images/all.tar.gz %s %s %s %s %s",
1305            MNT_CDROM,
1306            MOUNTLIST_FNAME_STUB,
1307            BIGGIELIST_TXT_STUB,
1308            FILELIST_FULL_STUB,
1309            "tmp/i-want-my-lvm", MONDO_CFG_FILE_STUB);
1310
1311    log_msg(1, "tarcommand = %s", command);
1312    run_program_and_log_output(command, 1);
1313//    popup_and_OK("Press ENTER to continue");
1314    if (!does_file_exist(BIGGIELIST_TXT_STUB)) {
1315        fatal_error
1316            ("all.tar.gz did not include tmp/biggielist.txt");
1317    }
1318    if (!does_file_exist(FILELIST_FULL_STUB)) {
1319        fatal_error
1320            ("all.tar.gz did not include tmp/filelist.full.gz");
1321    }
1322}
1323sprintf(command, "cp -f %s %s", MONDO_CFG_FILE_STUB,
1324        g_mondo_cfg_file);
1325run_program_and_log_output(command, FALSE);
1326
1327sprintf(command, "cp -f %s/%s %s", bkpinfo->tmpdir,
1328        BIGGIELIST_TXT_STUB, g_biggielist_txt);
1329log_msg(1, "command = %s", command);
1330paranoid_system(command);
1331sprintf(command, "ln -sf %s/%s %s", bkpinfo->tmpdir,
1332        FILELIST_FULL_STUB, g_filelist_full);
1333log_msg(1, "command = %s", command);
1334paranoid_system(command);
1335}
1336
1337if (am_I_in_disaster_recovery_mode()
1338&&
1339ask_me_yes_or_no("Do you want to retrieve the mountlist as well?"))
1340{
1341//      sprintf(command, "cp -f tmp/mountlist.txt /tmp");
1342sprintf(command, "ln -sf %s/%s /tmp", MOUNTLIST_FNAME_STUB,
1343        bkpinfo->tmpdir);
1344paranoid_system(command);
1345}
1346
1347chdir(tmp);
1348
1349if (!does_file_exist(g_biggielist_txt)) {
1350log_msg(1, "Warning - %s not found", g_biggielist_txt);
1351}
1352if (!does_file_exist(g_filelist_full)) {
1353log_msg(1, "Warning - %s does not exist", g_filelist_full);
1354}
1355//  popup_and_OK("Wonderful.");
1356
1357log_msg(2, "Forking");
1358pid = fork();
1359switch (pid) {
1360case -1:
1361fatal_error("Forking error");
1362break;
1363
1364case 0:
1365log_to_screen("Pre-processing filelist");
1366if (!does_file_exist(g_biggielist_txt)) {
1367            sprintf(command, "echo -n > %s", g_biggielist_txt);
1368            paranoid_system(command);
1369        }
1370        sprintf(command, "grep -E '^/dev/.*' %s > %s",
1371                g_biggielist_txt, g_filelist_imagedevs);
1372        paranoid_system(command);
1373        exit(0);
1374        break;
1375
1376    default:
1377        open_evalcall_form("Pre-processing filelist");
1378        while (!waitpid(pid, (int *) 0, WNOHANG)) {
1379            usleep(100000);
1380            update_evalcall_form(0);
1381        }
1382    }
1383    close_evalcall_form();
1384
1385    log_msg(3, "loading filelist");
1386    filelist = load_filelist(g_filelist_full);
1387    log_msg(3, "deleting original filelist");
1388    unlink(g_filelist_full);
1389    if (g_text_mode) {
1390        printf("Restore which directory? --> ");
1391        fgets(tmp, sizeof(tmp), stdin);
1392        toggle_path_selection(filelist, tmp, TRUE);
1393        if (strlen(tmp) == 0) {
1394            res = 1;
1395        } else {
1396            res = 0;
1397        }
1398    } else {
1399        res = edit_filelist(filelist);
1400    }
1401    if (res) {
1402        log_msg(2, "User hit 'cancel'. Freeing filelist and aborting.");
1403        free_filelist(filelist);
1404        return (NULL);
1405    }
1406    ask_about_these_imagedevs(g_filelist_imagedevs, g_imagedevs_restthese);
1407    close_evalcall_form();
1408
1409    // NB: It's not necessary to add g_biggielist_txt to the filelist.full
1410    // file. The filelist.full file already contains the filename of EVERY
1411    // file backed up - regular and biggie files.
1412
1413    // However, we do want to make sure the imagedevs selected by the user
1414    // are flagged for restoring.
1415    if (length_of_file(g_imagedevs_restthese) > 2) {
1416        add_list_of_files_to_filelist(filelist, g_imagedevs_restthese,
1417                                      TRUE);
1418    }
1419
1420    paranoid_free(command);
1421    paranoid_free(tmp);
1422    return (filelist);
1423}
1424
1425/**************************************************************************
1426 *END_ PROCESS_FILELIST_AND_BIGGIELIST                                    *
1427 **************************************************************************/
1428
1429
1430
1431
1432/**
1433 * Make a backup copy of <tt>path_root</tt>/<tt>filename</tt>.
1434 * The backup filename is the filename of the original with ".pristine" added.
1435 * @param path_root The place where the filesystem is mounted (e.g. MNT_RESTORING).
1436 * @param filename The filename (absolute path) within @p path_root.
1437 * @return 0 for success, nonzero for failure.
1438 */
1439int backup_crucial_file(char *path_root, char *filename)
1440{
1441    char *tmp;
1442    char *command;
1443    int res;
1444
1445    malloc_string(tmp);
1446    malloc_string(command);
1447    assert(path_root != NULL);
1448    assert_string_is_neither_NULL_nor_zerolength(filename);
1449
1450    sprintf(tmp, "%s/%s", path_root, filename);
1451    sprintf(command, "cp -f %s %s.pristine", tmp, tmp);
1452
1453    res = run_program_and_log_output(command, 5);
1454    paranoid_free(tmp);
1455    paranoid_free(command);
1456    return (res);
1457}
1458
1459
1460/**
1461 * Install the user's boot loader in the MBR.
1462 * Currently LILO, ELILO, GRUB, RAW (dd of MBR), and the FreeBSD bootloader are supported.
1463 * @param offer_to_hack_scripts If TRUE, then offer to hack the user's fstab for them.
1464 * @return 0 for success, nonzero for failure.
1465 */
1466int run_boot_loader(bool offer_to_hack_scripts)
1467{
1468    int res;
1469    int retval = 0;
1470
1471  /** malloc *******/
1472    char *device;
1473    char *tmp;
1474    char *name;
1475    char *cmd = NULL;
1476
1477    malloc_string(device);
1478    malloc_string(tmp);
1479    malloc_string(name);
1480
1481    /* In order to have a working bootloader, we need to have all devices
1482     * ready in the chroot. If they are not there (udev) then copy them from
1483     * the current /dev location
1484     */
1485    asprintf(&cmd,"tar cf - /dev | ( cd %s ; tar xf - )",MNT_RESTORING);
1486    run_program_and_log_output(cmd, 3);
1487
1488    backup_crucial_file(MNT_RESTORING, "/etc/fstab");
1489    backup_crucial_file(MNT_RESTORING, "/etc/grub.conf");
1490    backup_crucial_file(MNT_RESTORING, "/etc/lilo.conf");
1491    backup_crucial_file(MNT_RESTORING, "/etc/elilo.conf");
1492    backup_crucial_file(MNT_RESTORING, "/boot/grub/device.map");
1493    backup_crucial_file(MNT_RESTORING, "/etc/mtab");
1494    read_cfg_var(g_mondo_cfg_file, "bootloader.device", device);
1495    read_cfg_var(g_mondo_cfg_file, "bootloader.name", name);
1496    sprintf(tmp, "run_boot_loader: device='%s', name='%s'", device, name);
1497    log_msg(2, tmp);
1498    system("sync");
1499    if (!strcmp(name, "LILO")) {
1500        res = run_lilo(offer_to_hack_scripts);
1501    } else if (!strcmp(name, "ELILO")) {
1502        res = run_elilo(offer_to_hack_scripts);
1503    } else if (!strcmp(name, "GRUB")) {
1504        res = run_grub(offer_to_hack_scripts, device);
1505    } else if (!strcmp(name, "RAW")) {
1506        res = run_raw_mbr(offer_to_hack_scripts, device);
1507    }
1508#ifdef __FreeBSD__
1509    else if (!strcmp(name, "BOOT0")) {
1510        sprintf(tmp, "boot0cfg -B %s", device);
1511        res = run_program_and_log_output(tmp, FALSE);
1512    } else {
1513        sprintf(tmp, "ls /dev | grep -Eq '^%ss[1-4].*'", device);
1514        if (!system(tmp)) {
1515            sprintf(tmp, MNT_RESTORING "/sbin/fdisk -B %s", device);
1516            res = run_program_and_log_output(tmp, 3);
1517        } else {
1518            log_msg(1,
1519                    "I'm not running any boot loader. You have a DD boot drive. It's already loaded up.");
1520        }
1521    }
1522#else
1523    else {
1524        log_to_screen
1525            ("Unable to determine type of boot loader. Defaulting to LILO.");
1526        res = run_lilo(offer_to_hack_scripts);
1527    }
1528#endif
1529    retval += res;
1530    if (res) {
1531        log_to_screen("Your boot loader returned an error");
1532    } else {
1533        log_to_screen("Your boot loader ran OK");
1534    }
1535    paranoid_free(device);
1536    paranoid_free(tmp);
1537    paranoid_free(name);
1538    return (retval);
1539}
1540
1541/**************************************************************************
1542 *END_ RUN_BOOT_LOADER                                                    *
1543 **************************************************************************/
1544
1545
1546
1547/**
1548 * Attempt to find the user's editor.
1549 * @return The editor found ("vi" if none could be found).
1550 * @note The returned string points to static storage that will be overwritten with each call.
1551 */
1552char *find_my_editor(void)
1553{
1554    static char output[MAX_STR_LEN];
1555    if (find_home_of_exe("pico")) {
1556        strcpy(output, "pico");
1557    } else if (find_home_of_exe("nano")) {
1558        strcpy(output, "nano");
1559    } else if (find_home_of_exe("e3em")) {
1560        strcpy(output, "e3em");
1561    } else if (find_home_of_exe("e3vi")) {
1562        strcpy(output, "e3vi");
1563    } else {
1564        strcpy(output, "vi");
1565    }
1566    if (!find_home_of_exe(output)) {
1567        log_msg(2, " (find_my_editor) --- warning - %s not found", output);
1568    }
1569    return (output);
1570}
1571
1572
1573/**
1574 * Install GRUB on @p bd.
1575 * @param offer_to_run_stabgrub If TRUE, then offer to hack the user's fstab for them.
1576 * @param bd The boot device where GRUB is installed.
1577 * @return 0 for success, nonzero for failure.
1578 */
1579int run_grub(bool offer_to_run_stabgrub, char *bd)
1580{
1581  /** malloc **/
1582    char *command;
1583    char *boot_device;
1584    char *rootdev;
1585    char *rootdrive;
1586    char *conffile;
1587    char *tmp;
1588    char *editor;
1589
1590    int res;
1591    int done;
1592
1593    malloc_string(command);
1594    malloc_string(boot_device);
1595    malloc_string(tmp);
1596    malloc_string(editor);
1597    malloc_string(rootdev);
1598    malloc_string(rootdrive);
1599    malloc_string(conffile);
1600    assert_string_is_neither_NULL_nor_zerolength(bd);
1601    strcpy(editor, find_my_editor());
1602    strcpy(boot_device, bd);
1603
1604    if (!run_program_and_log_output("which grub-MR", FALSE)) {
1605        log_msg(1, "Yay! grub-MR found...");
1606        sprintf(command, "grub-MR %s /tmp/mountlist.txt", boot_device);
1607        log_msg(1, "command = %s", command);
1608    } else {
1609        sprintf(command, "chroot " MNT_RESTORING " grub-install %s",
1610                boot_device);
1611        log_msg(1, "WARNING - grub-MR not found; using grub-install");
1612    }
1613    if (offer_to_run_stabgrub
1614        && ask_me_yes_or_no("Did you change the mountlist?"))
1615        /* interactive mode */
1616    {
1617        mvaddstr_and_log_it(g_currentY,
1618                            0,
1619                            "Modifying fstab, mtab, device.map and grub.conf, and running GRUB...                             ");
1620        for (done = FALSE; !done;) {
1621            popup_and_get_string("Boot device",
1622                                 "Please confirm/enter the boot device. If in doubt, try /dev/hda",
1623                                 boot_device, MAX_STR_LEN / 4);
1624            sprintf(command, "stabgrub-me %s", boot_device);
1625            res = run_program_and_log_output(command, 1);
1626            if (res) {
1627                popup_and_OK
1628                    ("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.");
1629                newtSuspend();
1630                system("chroot " MNT_RESTORING);
1631                newtResume();
1632                popup_and_OK("Thank you.");
1633            } else {
1634                done = TRUE;
1635            }
1636            popup_and_OK("You will now edit fstab, mtab, device.map and grub.conf");
1637            if (!g_text_mode) {
1638                newtSuspend();
1639            }
1640            sprintf(tmp, "chroot %s %s /etc/fstab", MNT_RESTORING, editor);
1641            paranoid_system(tmp);
1642            sprintf(tmp, "chroot %s %s /etc/mtab", MNT_RESTORING, editor);
1643            paranoid_system(tmp);
1644            sprintf(tmp, "chroot %s %s /etc/grub.conf", MNT_RESTORING, editor);
1645            paranoid_system(tmp);
1646            sprintf(tmp, "chroot %s %s /boot/grub/device.map", MNT_RESTORING, editor);
1647            paranoid_system(tmp);
1648            if (!g_text_mode) {
1649                newtResume();
1650            }
1651        }
1652    } else
1653        /* nuke mode */
1654    {
1655        mvaddstr_and_log_it(g_currentY,
1656                            0,
1657                            "Running GRUB...                                                 ");
1658        iamhere(command);
1659        res = run_program_and_log_output(command, 1);
1660        if (res) {
1661            popup_and_OK
1662                ("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.");
1663            newtSuspend();
1664            system("chroot " MNT_RESTORING);
1665            newtResume();
1666            popup_and_OK("Thank you.");
1667        }
1668    }
1669    if (res) {
1670        mvaddstr_and_log_it(g_currentY++, 74, "Failed.");
1671        log_to_screen
1672            ("GRUB ran w/error(s). See %s for more info.", MONDO_LOGFILE);
1673        log_msg(1, "Type:-");
1674        log_msg(1, "    mount-me");
1675        log_msg(1, "    chroot " MNT_RESTORING);
1676        log_msg(1, "    mount /boot");
1677        log_msg(1, "    grub-install '(hd0)'");
1678        log_msg(1, "    exit");
1679        log_msg(1, "    unmount-me");
1680        log_msg(1,
1681                "If you're really stuck, please e-mail the mailing list.");
1682    } else {
1683        mvaddstr_and_log_it(g_currentY++, 74, "Done.");
1684    }
1685    paranoid_free(rootdev);
1686    paranoid_free(rootdrive);
1687    paranoid_free(conffile);
1688    paranoid_free(command);
1689    paranoid_free(boot_device);
1690    paranoid_free(tmp);
1691    paranoid_free(editor);
1692
1693    return (res);
1694}
1695
1696/**************************************************************************
1697 *END_RUN_GRUB                                                            *
1698 **************************************************************************/
1699
1700
1701/**
1702 * Install ELILO on the user's boot drive (determined by elilo.conf).
1703 * @param offer_to_run_stabelilo If TRUE, then offer to hack the user's fstab for them.
1704 * @return 0 for success, nonzero for failure.
1705 */
1706int run_elilo(bool offer_to_run_stabelilo)
1707{
1708  /** malloc **/
1709    char *command;
1710    char *tmp;
1711    char *editor;
1712
1713    int res;
1714    int done;
1715
1716    malloc_string(command);
1717    malloc_string(tmp);
1718    malloc_string(editor);
1719    strcpy(editor, find_my_editor());
1720    if (offer_to_run_stabelilo
1721        && ask_me_yes_or_no("Did you change the mountlist?"))
1722
1723        /* interactive mode */
1724    {
1725        mvaddstr_and_log_it(g_currentY,
1726                            0,
1727                            "Modifying fstab and elilo.conf...                             ");
1728        sprintf(command, "stabelilo-me");
1729        res = run_program_and_log_output(command, 3);
1730        if (res) {
1731            popup_and_OK
1732                ("You will now edit fstab and elilo.conf, to make sure they match your new mountlist.");
1733            for (done = FALSE; !done;) {
1734                if (!g_text_mode) {
1735                    newtSuspend();
1736                }
1737                sprintf(tmp, "chroot %s %s /etc/fstab", MNT_RESTORING, editor);
1738                paranoid_system(tmp);
1739                sprintf(tmp, "chroot %s %s /etc/elilo.conf", MNT_RESTORING, editor);
1740                paranoid_system(tmp);
1741                if (!g_text_mode) {
1742                    newtResume();
1743                }
1744//              newtCls();
1745                if (ask_me_yes_or_no("Edit them again?")) {
1746                    continue;
1747                }
1748                done = TRUE;
1749            }
1750        } else {
1751            log_to_screen("elilo.conf and fstab were modified OK");
1752        }
1753    } else
1754        /* nuke mode */
1755    {
1756        res = TRUE;
1757    }
1758    paranoid_free(command);
1759    paranoid_free(tmp);
1760    paranoid_free(editor);
1761    return (res);
1762}
1763
1764/**************************************************************************
1765 *END_RUN_ELILO                                                            *
1766 **************************************************************************/
1767
1768
1769/**
1770 * Install LILO on the user's boot drive (determined by /etc/lilo.conf).
1771 * @param offer_to_run_stablilo If TRUE, then offer to hack the user's fstab for them.
1772 * @return 0 for success, nonzero for failure.
1773 */
1774int run_lilo(bool offer_to_run_stablilo)
1775{
1776  /** malloc **/
1777    char *command;
1778    char *tmp;
1779    char *editor;
1780
1781    int res;
1782    int done;
1783    bool run_lilo_M = FALSE;
1784    malloc_string(command);
1785    malloc_string(tmp);
1786    malloc_string(editor);
1787
1788    if (!run_program_and_log_output
1789        ("grep \"boot.*=.*/dev/md\" " MNT_RESTORING "/etc/lilo.conf", 1)) {
1790        run_lilo_M = TRUE;
1791    }
1792
1793    strcpy(editor, find_my_editor());
1794    if (offer_to_run_stablilo
1795        && ask_me_yes_or_no("Did you change the mountlist?"))
1796
1797        /* interactive mode */
1798    {
1799        mvaddstr_and_log_it(g_currentY,
1800                            0,
1801                            "Modifying fstab and lilo.conf, and running LILO...                             ");
1802        sprintf(command, "stablilo-me");
1803        res = run_program_and_log_output(command, 3);
1804        if (res) {
1805            popup_and_OK
1806                ("You will now edit fstab and lilo.conf, to make sure they match your new mountlist.");
1807            for (done = FALSE; !done;) {
1808                if (!g_text_mode) {
1809                    newtSuspend();
1810                }
1811                sprintf(tmp, "%s " MNT_RESTORING "/etc/fstab", editor);
1812                paranoid_system(tmp);
1813                sprintf(tmp, "%s " MNT_RESTORING "/etc/lilo.conf", editor);
1814                paranoid_system(tmp);
1815                if (!g_text_mode) {
1816                    newtResume();
1817                }
1818//              newtCls();
1819                if (ask_me_yes_or_no("Edit them again?")) {
1820                    continue;
1821                }
1822                res =
1823                    run_program_and_log_output("chroot " MNT_RESTORING
1824                                               " lilo -L", 3);
1825                if (res) {
1826                    res =
1827                        run_program_and_log_output("chroot " MNT_RESTORING
1828                                                   " lilo", 3);
1829                }
1830                if (res) {
1831                    done =
1832                        ask_me_yes_or_no
1833                        ("LILO failed. Re-edit system files?");
1834                } else {
1835                    done = TRUE;
1836                }
1837            }
1838        } else {
1839            log_to_screen("lilo.conf and fstab were modified OK");
1840        }
1841    } else
1842        /* nuke mode */
1843    {
1844        mvaddstr_and_log_it(g_currentY,
1845                            0,
1846                            "Running LILO...                                                 ");
1847        res =
1848            run_program_and_log_output("chroot " MNT_RESTORING " lilo -L",
1849                                       3);
1850        if (res) {
1851            res =
1852                run_program_and_log_output("chroot " MNT_RESTORING " lilo",
1853                                           3);
1854        }
1855        if (res) {
1856            mvaddstr_and_log_it(g_currentY++, 74, "Failed.");
1857            log_to_screen
1858                ("Failed to re-jig fstab and/or lilo. Edit/run manually, please.");
1859        } else {
1860            mvaddstr_and_log_it(g_currentY++, 74, "Done.");
1861        }
1862    }
1863    if (run_lilo_M) {
1864        run_program_and_log_output("chroot " MNT_RESTORING
1865                                   " lilo -M /dev/hda", 3);
1866        run_program_and_log_output("chroot " MNT_RESTORING
1867                                   " lilo -M /dev/sda", 3);
1868    }
1869    paranoid_free(command);
1870    paranoid_free(tmp);
1871    paranoid_free(editor);
1872    return (res);
1873}
1874
1875/**************************************************************************
1876 *END_RUN_LILO                                                            *
1877 **************************************************************************/
1878
1879
1880/**
1881 * Install a raw MBR onto @p bd.
1882 * @param offer_to_hack_scripts If TRUE, then offer to hack the user's fstab for them.
1883 * @param bd The device to copy the stored MBR to.
1884 * @return 0 for success, nonzero for failure.
1885 */
1886int run_raw_mbr(bool offer_to_hack_scripts, char *bd)
1887{
1888  /** malloc **/
1889    char *command;
1890    char *boot_device;
1891    char *tmp;
1892    char *editor;
1893    int res;
1894    int done;
1895
1896    malloc_string(command);
1897    malloc_string(boot_device);
1898    malloc_string(tmp);
1899    malloc_string(editor);
1900    assert_string_is_neither_NULL_nor_zerolength(bd);
1901
1902    strcpy(editor, find_my_editor());
1903    strcpy(boot_device, bd);
1904    sprintf(command, "raw-MR %s /tmp/mountlist.txt", boot_device);
1905    log_msg(2, "run_raw_mbr() --- command='%s'", command);
1906
1907    if (offer_to_hack_scripts
1908        && ask_me_yes_or_no("Did you change the mountlist?"))
1909        /* interactive mode */
1910    {
1911        mvaddstr_and_log_it(g_currentY, 0,
1912                            "Modifying fstab and restoring MBR...                           ");
1913        for (done = FALSE; !done;) {
1914            if (!run_program_and_log_output("which vi", FALSE)) {
1915                popup_and_OK("You will now edit fstab");
1916                if (!g_text_mode) {
1917                    newtSuspend();
1918                }
1919                sprintf(tmp, "%s " MNT_RESTORING "/etc/fstab", editor);
1920                paranoid_system(tmp);
1921                if (!g_text_mode) {
1922                    newtResume();
1923                }
1924//              newtCls();
1925            }
1926            popup_and_get_string("Boot device",
1927                                 "Please confirm/enter the boot device. If in doubt, try /dev/hda",
1928                                 boot_device, MAX_STR_LEN / 4);
1929            sprintf(command, "stabraw-me %s", boot_device);
1930            res = run_program_and_log_output(command, 3);
1931            if (res) {
1932                done = ask_me_yes_or_no("Modifications failed. Re-try?");
1933            } else {
1934                done = TRUE;
1935            }
1936        }
1937    } else
1938        /* nuke mode */
1939    {
1940        mvaddstr_and_log_it(g_currentY, 0,
1941                            "Restoring MBR...                                               ");
1942        res = run_program_and_log_output(command, 3);
1943    }
1944    if (res) {
1945        mvaddstr_and_log_it(g_currentY++, 74, "Failed.");
1946        log_to_screen
1947            ("MBR+fstab processed w/error(s). See %s for more info.", MONDO_LOGFILE);
1948    } else {
1949        mvaddstr_and_log_it(g_currentY++, 74, "Done.");
1950    }
1951    paranoid_free(command);
1952    paranoid_free(boot_device);
1953    paranoid_free(tmp);
1954    paranoid_free(editor);
1955    return (res);
1956}
1957
1958/**************************************************************************
1959 *END_RUN_RAW_MBR                                                         *
1960 **************************************************************************/
1961
1962
1963
1964
1965
1966/**
1967 * Turn signal trapping on or off.
1968 * @param on If TRUE, then do full cleanup when we receive a signal; if FALSE, then
1969 * print a message and exit immediately.
1970 */
1971void set_signals(int on)
1972{
1973    int signals[] =
1974        { SIGKILL, SIGPIPE, SIGTERM, SIGHUP, SIGTRAP, SIGABRT, SIGINT,
1975SIGSTOP, 0 };
1976    int i;
1977    for (i = 0; signals[i]; i++) {
1978        if (on) {
1979            signal(signals[i], terminate_daemon);
1980        } else {
1981            signal(signals[i], termination_in_progress);
1982        }
1983    }
1984}
1985
1986/**************************************************************************
1987 *END_SET_SIGNALS                                                         *
1988 **************************************************************************/
1989
1990
1991/**
1992 * malloc() and set sensible defaults for the mondorestore filename variables.
1993 * @param bkpinfo The backup information structure. Fields used:
1994 * - @c bkpinfo->tmpdir
1995 * - @c bkpinfo->disaster_recovery
1996 */
1997void setup_MR_global_filenames()
1998{
1999    char *temppath;
2000
2001    assert(bkpinfo != NULL);
2002
2003    malloc_string(g_biggielist_txt);
2004    malloc_string(g_filelist_full);
2005    malloc_string(g_filelist_imagedevs);
2006    malloc_string(g_imagedevs_restthese);
2007    malloc_string(g_mondo_cfg_file);
2008    malloc_string(g_mountlist_fname);
2009    malloc_string(g_mondo_home);
2010    malloc_string(g_tmpfs_mountpt);
2011    malloc_string(g_isodir_device);
2012    malloc_string(g_isodir_format);
2013
2014    temppath = bkpinfo->tmpdir;
2015
2016    sprintf(g_biggielist_txt, "%s/%s", temppath, BIGGIELIST_TXT_STUB);
2017    sprintf(g_filelist_full, "%s/%s", temppath, FILELIST_FULL_STUB);
2018    sprintf(g_filelist_imagedevs, "%s/tmp/filelist.imagedevs", temppath);
2019//  sprintf(g_imagedevs_pot, "%s/tmp/imagedevs.pot", temppath);
2020    sprintf(g_imagedevs_restthese, "%s/tmp/imagedevs.restore-these",
2021            temppath);
2022    if (bkpinfo->disaster_recovery) {
2023        sprintf(g_mondo_cfg_file, "/%s", MONDO_CFG_FILE_STUB);
2024        sprintf(g_mountlist_fname, "/%s", MOUNTLIST_FNAME_STUB);
2025    } else {
2026        sprintf(g_mondo_cfg_file, "%s/%s", temppath, MONDO_CFG_FILE_STUB);
2027        sprintf(g_mountlist_fname, "%s/%s", temppath,
2028                MOUNTLIST_FNAME_STUB);
2029    }
2030}
2031
2032/**************************************************************************
2033 *END_SET_GLOBAL_FILENAME                                                 *
2034 **************************************************************************/
2035
2036
2037/**
2038 * Copy @p input_file (containing the result of a compare) to @p output_file,
2039 * deleting spurious "changes" along the way.
2040 * @param output_file The output file to write with spurious changes removed.
2041 * @param input_file The input file, a list of changed files created by a compare.
2042 */
2043void streamline_changes_file(char *output_file, char *input_file)
2044{
2045    FILE *fin;
2046    FILE *fout;
2047  /** malloc **/
2048    char *incoming;
2049
2050    assert_string_is_neither_NULL_nor_zerolength(output_file);
2051    assert_string_is_neither_NULL_nor_zerolength(input_file);
2052    malloc_string(incoming);
2053
2054    if (!(fin = fopen(input_file, "r"))) {
2055        log_OS_error(input_file);
2056        return;
2057    }
2058    if (!(fout = fopen(output_file, "w"))) {
2059        fatal_error("cannot open output_file");
2060    }
2061    for (fgets(incoming, MAX_STR_LEN - 1, fin); !feof(fin);
2062         fgets(incoming, MAX_STR_LEN - 1, fin)) {
2063        if (strncmp(incoming, "etc/adjtime", 11)
2064            && strncmp(incoming, "etc/mtab", 8)
2065            && strncmp(incoming, "tmp/", 4)
2066            && strncmp(incoming, "boot/map", 8)
2067            && !strstr(incoming, "incheckentry")
2068            && strncmp(incoming, "etc/mail/statistics", 19)
2069            && strncmp(incoming, "var/", 4))
2070            fprintf(fout, "%s", incoming);  /* don't need \n here, for some reason.. */
2071    }
2072    paranoid_fclose(fout);
2073    paranoid_fclose(fin);
2074    paranoid_free(incoming);
2075}
2076
2077/**************************************************************************
2078 *END_STREAMLINE_CHANGES_FILE                                             *
2079 **************************************************************************/
2080
2081
2082/**
2083 * Exit due to a signal (normal cleanup).
2084 * @param sig The signal we're exiting due to.
2085 */
2086void terminate_daemon(int sig)
2087{
2088    log_to_screen
2089        ("Mondorestore is terminating in response to a signal from the OS");
2090    paranoid_MR_finish(254);
2091}
2092
2093/**************************************************************************
2094 *END_TERMINATE_DAEMON                                                    *
2095 **************************************************************************/
2096
2097
2098/**
2099 * Give the user twenty seconds to press Ctrl-Alt-Del before we nuke their drives.
2100 */
2101void twenty_seconds_til_yikes()
2102{
2103    int i;
2104    /* MALLOC * */
2105    char *tmp;
2106
2107    malloc_string(tmp);
2108    if (does_file_exist("/tmp/NOPAUSE")) {
2109        return;
2110    }
2111    open_progress_form("CAUTION",
2112                       "Be advised: I am about to ERASE your hard disk(s)!",
2113                       "You may press Ctrl+Alt+Del to abort safely.",
2114                       "", 20);
2115    for (i = 0; i < 20; i++) {
2116        g_current_progress = i;
2117        sprintf(tmp, "You have %d seconds left to abort.", 20 - i);
2118        update_progress_form(tmp);
2119        sleep(1);
2120    }
2121    close_progress_form();
2122    paranoid_free(tmp);
2123}
2124
2125/**************************************************************************
2126 *END_TWENTY_SECONDS_TIL_YIKES                                            *
2127 **************************************************************************/
2128
2129
2130
2131
2132
2133/**
2134 * Exit due to a signal (no cleanup).
2135 * @param sig The signal we're exiting due to.
2136 */
2137void termination_in_progress(int sig)
2138{
2139    log_msg(1, "Termination in progress");
2140    usleep(1000);
2141    pthread_exit(0);
2142}
2143
2144/**************************************************************************
2145 *END_TERMINATION_IN_PROGRESS                                             *
2146 **************************************************************************/
2147
2148
2149
2150/**
2151 * Unmount all devices in @p p_external_copy_of_mountlist.
2152 * @param p_external_copy_of_mountlist The mountlist to guide the devices to unmount.
2153 * @return 0 for success, nonzero for failure.
2154 */
2155int unmount_all_devices(struct mountlist_itself
2156                        *p_external_copy_of_mountlist)
2157{
2158    struct mountlist_itself *mountlist;
2159    int retval = 0, lino, res = 0, i;
2160    char *command;
2161    char *tmp;
2162
2163    malloc_string(command);
2164    malloc_string(tmp);
2165    assert(p_external_copy_of_mountlist != NULL);
2166
2167    mountlist = malloc(sizeof(struct mountlist_itself));
2168    memcpy((void *) mountlist, (void *) p_external_copy_of_mountlist,
2169           sizeof(struct mountlist_itself));
2170    sort_mountlist_by_mountpoint(mountlist, 0);
2171
2172    run_program_and_log_output("df -m", 3);
2173    mvaddstr_and_log_it(g_currentY, 0, "Unmounting devices      ");
2174    open_progress_form("Unmounting devices",
2175                       "Unmounting all devices that were mounted,",
2176                       "in preparation for the post-restoration reboot.",
2177                       "", mountlist->entries);
2178    chdir("/");
2179    for (i = 0;
2180         i < 10
2181         &&
2182         run_program_and_log_output
2183         ("ps | grep buffer | grep -v \"grep buffer\"", TRUE) == 0;
2184         i++) {
2185        sleep(1);
2186        log_msg(2, "Waiting for buffer() to finish");
2187    }
2188
2189    paranoid_system("sync");
2190
2191    sprintf(tmp, "cp -f %s " MNT_RESTORING "/var/log", MONDO_LOGFILE);
2192    if (run_program_and_log_output(tmp, FALSE)) {
2193        log_msg(1,
2194                "Error. Failed to copy log to PC's /var/log dir. (Mounted read-only?)");
2195    }
2196    if (does_file_exist("/tmp/DUMBASS-GENTOO")) {
2197        run_program_and_log_output("mkdir -p " MNT_RESTORING
2198                                   "/mnt/.boot.d", 5);
2199    }
2200    for (lino = mountlist->entries - 1; lino >= 0; lino--) {
2201        if (!strcmp(mountlist->el[lino].mountpoint, "lvm")) {
2202            continue;
2203        }
2204        sprintf(tmp, "Unmounting device %s  ", mountlist->el[lino].device);
2205
2206        update_progress_form(tmp);
2207        if (is_this_device_mounted(mountlist->el[lino].device)) {
2208            if (!strcmp(mountlist->el[lino].mountpoint, "swap")) {
2209                sprintf(command, "swapoff %s", mountlist->el[lino].device);
2210            } else {
2211                if (!strcmp(mountlist->el[lino].mountpoint, "/1")) {
2212                    sprintf(command, "umount %s/", MNT_RESTORING);
2213                    log_msg(3,
2214                            "Well, I know a certain kitty-kitty who'll be sleeping with Mommy tonight...");
2215                } else {
2216                    sprintf(command, "umount " MNT_RESTORING "%s",
2217                            mountlist->el[lino].mountpoint);
2218                }
2219            }
2220            log_msg(10, "The 'umount' command is '%s'", command);
2221            res = run_program_and_log_output(command, 3);
2222        } else {
2223            strcat(tmp, "...not mounted anyway :-) OK");
2224            res = 0;
2225        }
2226        g_current_progress++;
2227        if (res) {
2228            strcat(tmp, "...Failed");
2229            retval++;
2230            log_to_screen(tmp);
2231        } else {
2232            log_msg(2, tmp);
2233        }
2234    }
2235    close_progress_form();
2236    if (retval) {
2237        mvaddstr_and_log_it(g_currentY++, 74, "Failed.");
2238    } else {
2239        mvaddstr_and_log_it(g_currentY++, 74, "Done.");
2240    }
2241    if (retval) {
2242        log_to_screen("Unable to unmount some of your partitions.");
2243    } else {
2244        log_to_screen("All partitions were unmounted OK.");
2245    }
2246    free(mountlist);
2247    paranoid_free(command);
2248    paranoid_free(tmp);
2249    return (retval);
2250}
2251
2252/**************************************************************************
2253 *END_UNMOUNT_ALL_DEVICES                                                 *
2254 **************************************************************************/
2255
2256
2257
2258/**
2259 * Extract mondo-restore.cfg and the mountlist from the tape inserted
2260 * to the ./tmp/ directory.
2261 * @param dev The tape device to read from.
2262 * @return 0 for success, nonzero for failure.
2263 */
2264int extract_cfg_file_and_mountlist_from_tape_dev(char *dev)
2265{
2266    char *command;
2267    int res = 0;
2268    // BCO: below 32KB seems to block at least on RHAS 2.1 and MDK 10.0
2269    long tape_block_size = 32768;
2270
2271    malloc_string(command);
2272
2273    // tar -zxvf-
2274    sprintf(command,
2275            "dd if=%s bs=%ld count=%ld 2> /dev/null | tar -zx %s %s %s %s %s",
2276            dev,
2277            tape_block_size,
2278            1024L * 1024 * 32 / tape_block_size,
2279            MOUNTLIST_FNAME_STUB, MONDO_CFG_FILE_STUB,
2280            BIGGIELIST_TXT_STUB, FILELIST_FULL_STUB, "tmp/i-want-my-lvm");
2281    log_msg(2, "command = '%s'", command);
2282    res = run_program_and_log_output(command, -1);
2283    if (res != 0 && does_file_exist(MONDO_CFG_FILE_STUB)) {
2284        res = 0;
2285    }
2286    paranoid_free(command);
2287    return (res);
2288}
2289
2290
2291
2292/**
2293 * Get the configuration file from the floppy, tape, or CD.
2294 * @param bkpinfo The backup information structure. Fields used:
2295 * - @c bkpinfo->backup_media_type
2296 * - @c bkpinfo->media_device
2297 * - @c bkpinfo->tmpdir
2298 * @return 0 for success, nonzero for failure.
2299 */
2300int get_cfg_file_from_archive()
2301{
2302    int retval = 0;
2303
2304   /** malloc *****/
2305    char *device;
2306    char *command;
2307    char *cfg_file;
2308    char *mounted_cfgf_path;
2309    char *tmp;
2310    char *mountpt;
2311    char *ramdisk_fname;
2312    char *mountlist_file;
2313    int res = 0;
2314    int fd = 0;
2315    struct floppy_struct fdprms;
2316
2317    bool try_plan_B;
2318
2319    assert(bkpinfo != NULL);
2320    malloc_string(cfg_file);
2321    malloc_string(mounted_cfgf_path);
2322    malloc_string(mountpt);
2323    malloc_string(ramdisk_fname);
2324    malloc_string(mountlist_file);
2325    malloc_string(device);
2326    malloc_string(command);
2327    malloc_string(tmp);
2328    log_msg(2, "gcffa --- starting");
2329    log_to_screen("I'm thinking...");
2330    sprintf(mountpt, "%s/mount.bootdisk", bkpinfo->tmpdir);
2331    device[0] = '\0';
2332    chdir(bkpinfo->tmpdir);
2333    strcpy(cfg_file, MONDO_CFG_FILE_STUB);
2334    unlink(cfg_file);           // cfg_file[] is missing the '/' at the start, FYI, by intent
2335    unlink(FILELIST_FULL_STUB);
2336    unlink(BIGGIELIST_TXT_STUB);
2337    unlink("tmp/i-want-my-lvm");
2338    sprintf(command, "mkdir -p %s", mountpt);
2339    run_program_and_log_output(command, FALSE);
2340
2341//   unlink( "tmp/mondo-restore.cfg" ); // superfluous, surely?
2342
2343    sprintf(cfg_file, "%s/%s", bkpinfo->tmpdir, MONDO_CFG_FILE_STUB);
2344    sprintf(mountlist_file, "%s/%s", bkpinfo->tmpdir,
2345            MOUNTLIST_FNAME_STUB);
2346    //   make_hole_for_file( cfg_file );
2347    //   make_hole_for_file( mountlist_file);
2348    log_msg(2, "mountpt = %s; cfg_file=%s", mountpt, cfg_file);
2349
2350    /* Floppy? */
2351    sprintf(tmp, "mkdir -p %s", mountpt);
2352    run_program_and_log_output(tmp, FALSE);
2353    sprintf(tmp, "mkdir -p %s/tmp", bkpinfo->tmpdir);
2354    run_program_and_log_output(tmp, FALSE);
2355
2356    /* Is there a floppy drive detected */
2357    fd = open("/dev/fd0u1722", O_RDONLY);
2358    if (fd > 0) {
2359        // open OK
2360        res = ioctl(fd, FDGETPRM, &fdprms);
2361        if (res >= 0) {
2362            // media OK to mount
2363            sprintf(command, "mount /dev/fd0u1722 %s", mountpt);
2364            res = run_program_and_log_output(command, FALSE);
2365        } else {
2366            //skip mount
2367            res = 1;
2368        } 
2369    } else { 
2370        fd = open("/dev/fd0H1440", O_RDONLY);
2371        if (fd > 0) {
2372            // open OK
2373            res = ioctl(fd, FDGETPRM, &fdprms);
2374            if (res >= 0) {
2375                // media OK to mount
2376                sprintf(command, "mount /dev/fd0H1440 %s", mountpt);
2377                res = run_program_and_log_output(command, FALSE);
2378            } else {
2379                //skip mount
2380                res = 1;
2381            } 
2382        }
2383    }
2384    if (res) {
2385        try_plan_B = TRUE;
2386    } else {
2387        try_plan_B = TRUE;
2388        log_msg(2,
2389                "Mounted floppy OK but I don't trust it because the archives might contain more up-to-date config file than the floppy does.");
2390        // NB: If busybox does not support 'mount -o loop' then Plan A WILL NOT WORK.
2391        log_msg(2, "Processing floppy (plan A?)");
2392        sprintf(ramdisk_fname, "%s/mindi.rdz", mountpt);
2393        if (!does_file_exist(ramdisk_fname)) {
2394            sprintf(ramdisk_fname, "%s/initrd.img", mountpt);
2395        }
2396        if (!does_file_exist(ramdisk_fname)) {
2397            log_msg(2,
2398                    "Cannot find ramdisk file on mountpoint. Are you sure that's a boot disk in the drive?");
2399        }
2400        if (extract_config_file_from_ramdisk(ramdisk_fname, cfg_file, mountlist_file)) {
2401            log_msg(2,
2402                    "Warning - failed to extract config file from ramdisk. I think this boot disk is mangled.");
2403        }
2404        sprintf(command, "umount %s", mountpt);
2405        run_program_and_log_output(command, 5);
2406        unlink(ramdisk_fname);
2407    }
2408    if (!does_file_exist(cfg_file)) {
2409        log_msg(2, "gcffa --- we don't have cfg file yet.");
2410        if (IS_THIS_A_STREAMING_BACKUP(bkpinfo->backup_media_type)) {
2411            try_plan_B = TRUE;
2412        } else {
2413            log_msg(2, "gcffa --- calling mount_media now :)");
2414            if (!mount_media()) {
2415                log_msg(2,
2416                        "gcffa --- managed to mount CD; so, no need for Plan B");
2417                try_plan_B = FALSE;
2418            } else {
2419                try_plan_B = TRUE;
2420            }
2421            if (what_number_cd_is_this() > 1) {
2422                insist_on_this_cd_number((g_current_media_number = 1));
2423            }
2424        }
2425        if (try_plan_B) {
2426            log_msg(2, "gcffa --- OK, switching to Plan B");
2427            chdir(bkpinfo->tmpdir);
2428            run_program_and_log_output("mkdir -p tmp", FALSE);
2429
2430            if (strlen(bkpinfo->media_device) == 0) {
2431                strcpy(bkpinfo->media_device, "/dev/st0");
2432                log_msg(2, "media_device is blank; assuming %s");
2433            }
2434            strcpy(tmp, bkpinfo->media_device);
2435            if (extract_cfg_file_and_mountlist_from_tape_dev
2436                (bkpinfo->media_device)) {
2437                strcpy(bkpinfo->media_device, "/dev/st0");
2438                if (extract_cfg_file_and_mountlist_from_tape_dev
2439                    (bkpinfo->media_device)) {
2440                    strcpy(bkpinfo->media_device, "/dev/osst0");
2441                    if (extract_cfg_file_and_mountlist_from_tape_dev
2442                        (bkpinfo->media_device)) {
2443                        strcpy(bkpinfo->media_device, "/dev/ht0");
2444                        if (extract_cfg_file_and_mountlist_from_tape_dev
2445                            (bkpinfo->media_device)) {
2446                            log_msg(3,
2447                                    "I tried lots of devices but none worked.");
2448                            strcpy(bkpinfo->media_device, tmp);
2449                        }
2450                    }
2451                }
2452            }
2453
2454            if (!does_file_exist("tmp/mondo-restore.cfg")) {
2455                log_to_screen("Cannot find config info on tape/CD/floppy");
2456                return (1);
2457            }
2458        } else {
2459            /* That boot imae doesn't always exist where the following method always works
2460            log_msg(2,
2461                    "gcffa --- looking at mounted CD for mindi-boot.2880.img");
2462            sprintf(command,
2463                    "mount " MNT_CDROM
2464                    "/images/mindi-boot.2880.img -o loop %s", mountpt);
2465            sprintf(mounted_cfgf_path, "%s/%s", mountpt, cfg_file);
2466            if (!does_file_exist(mounted_cfgf_path)) {
2467            */
2468                log_msg(2,
2469                        "gcffa --- Plan B, a.k.a. untarring some file from all.tar.gz");
2470                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
2471                run_program_and_log_output(command, TRUE);
2472                if (!does_file_exist(MONDO_CFG_FILE_STUB)) {
2473                    fatal_error
2474                        ("Please reinsert the disk/CD and try again.");
2475                }
2476                    /*
2477            }
2478                */
2479        }
2480    }
2481    if (does_file_exist(MONDO_CFG_FILE_STUB)) {
2482        log_msg(1, "gcffa --- great! We've got the config file");
2483        sprintf(tmp, "%s/%s",
2484                call_program_and_get_last_line_of_output("pwd"),
2485                MONDO_CFG_FILE_STUB);
2486        sprintf(command, "cp -f %s %s", tmp, cfg_file);
2487        iamhere(command);
2488        if (strcmp(tmp, cfg_file)
2489            && run_program_and_log_output(command, 1)) {
2490            log_msg(1,
2491                    "... but an error occurred when I tried to move it to %s",
2492                    cfg_file);
2493        } else {
2494            log_msg(1, "... and I moved it successfully to %s", cfg_file);
2495        }
2496        sprintf(command, "cp -f %s/%s %s",
2497                call_program_and_get_last_line_of_output("pwd"),
2498                MOUNTLIST_FNAME_STUB, mountlist_file);
2499        iamhere(command);
2500        if (strcmp(tmp, cfg_file)
2501            && run_program_and_log_output(command, 1)) {
2502            log_msg(1, "Failed to get mountlist");
2503        } else {
2504            log_msg(1, "Got mountlist too");
2505            sprintf(command, "cp -f %s %s", mountlist_file,
2506                    g_mountlist_fname);
2507            if (run_program_and_log_output(command, 1)) {
2508                log_msg(1, "Failed to copy mountlist to /tmp");
2509            } else {
2510                log_msg(1, "Copied mountlist to /tmp as well OK");
2511                sprintf(command, "cp -f tmp/i-want-my-lvm /tmp/");
2512                run_program_and_log_output(command, 1);
2513/*        sprintf(command, "grep \" lvm \" %s", g_mountlist_fname);
2514          if (!run_program_and_log_output(command, 5) && !does_file_exist("/tmp/i-want-my-lvm"))
2515            {
2516          log_msg(1, "Warning. You want LVM but I don't have i-want-my-lvm. FIXME.");
2517        }
2518              else if (run_program_and_log_output(command,5) && does_file_exist("/tmp/i-want-my-lvm"))
2519                {
2520          log_msg(1, "Warning. You don't want LVM but i-want-my-lvm exists. I'll delete it. Cool.");
2521              do_my_funky_lvm_stuff(TRUE, FALSE); // ...after I stop any LVMs :)
2522          stop_raid_device("/dev/md0");
2523          stop_raid_device("/dev/md1");
2524          stop_raid_device("/dev/md2");
2525          unlink("/tmp/i-want-my-lvm");
2526        }
2527          else if (!run_program_and_log_output(command,5) && does_file_exist("/tmp/i-want-my-lvm"))
2528            {
2529          log_msg(1, "You had better pray that i-want-my-lvm patches your mountlist. FIXME.");
2530        }
2531*/
2532            }
2533        }
2534    }
2535    run_program_and_log_output("umount " MNT_CDROM, FALSE);
2536    if (!does_file_exist(cfg_file)) {
2537        iamhere(cfg_file);
2538        log_msg(1, "%s not found", cfg_file);
2539        log_to_screen
2540            ("Oh dear. Unable to recover configuration file from boot disk");
2541        return (1);
2542    }
2543
2544    log_to_screen("Recovered mondo-restore.cfg");
2545    if (!does_file_exist(MOUNTLIST_FNAME_STUB)) {
2546        log_to_screen("...but not mountlist.txt - a pity, really...");
2547    }
2548/* start SAH */
2549    else {
2550        sprintf(command, "cp -f %s %s/%s", MOUNTLIST_FNAME_STUB,
2551                bkpinfo->tmpdir, MOUNTLIST_FNAME_STUB);
2552        run_program_and_log_output(command, FALSE);
2553    }
2554/*--commented out by SAH
2555  sprintf( command, "cp -f %s %s/%s", cfg_file, bkpinfo->tmpdir, MONDO_CFG_FILE_STUB );
2556  run_program_and_log_output( command, FALSE );
2557  sprintf( command, "cp -f %s %s/%s", mountlist_file, bkpinfo->tmpdir, MOUNTLIST_FNAME_STUB );
2558  run_program_and_log_output( command, FALSE );
2559*/
2560/* end SAH */
2561
2562    sprintf(command, "cp -f %s /%s", cfg_file, MONDO_CFG_FILE_STUB);
2563    run_program_and_log_output(command, FALSE);
2564    sprintf(command, "cp -f %s /%s", mountlist_file, MOUNTLIST_FNAME_STUB);
2565    run_program_and_log_output(command, FALSE);
2566    sprintf(command, "cp -f etc/raidtab /etc/");
2567    run_program_and_log_output(command, FALSE);
2568    sprintf(command, "cp -f tmp/i-want-my-lvm /tmp/");
2569    run_program_and_log_output(command, FALSE);
2570    g_backup_media_type = bkpinfo->backup_media_type;
2571    paranoid_free(device);
2572    paranoid_free(command);
2573    paranoid_free(tmp);
2574    paranoid_free(cfg_file);
2575    paranoid_free(mounted_cfgf_path);
2576    paranoid_free(mountpt);
2577    paranoid_free(ramdisk_fname);
2578    paranoid_free(mountlist_file);
2579    return (retval);
2580}
2581
2582/**************************************************************************
2583 *END_GET_CFG_FILE_FROM_ARCHIVE                                           *
2584 **************************************************************************/
2585
2586/* @} - end restoreUtilityGroup */
2587
2588
2589/***************************************************************************
2590 * F@                                                                      *
2591 * () -- Hugo Rabson                                  *
2592 *                                                                         *
2593 * Purpose:                                                                *
2594 *                                                                         *
2595 * Called by:                                                              *
2596 * Params:    -                      -                                     *
2597 * Returns:   0=success; nonzero=failure                                   *
2598 ***************************************************************************/
2599
2600
2601
2602void wait_until_software_raids_are_prepped(char *mdstat_file,
2603                                           int wait_for_percentage)
2604{
2605    struct raidlist_itself *raidlist;
2606    int unfinished_mdstat_devices = 9999, i;
2607    char *screen_message;
2608
2609    malloc_string(screen_message);
2610    raidlist = malloc(sizeof(struct raidlist_itself));
2611
2612    assert(wait_for_percentage <= 100);
2613    iamhere("wait_until_software_raids_are_prepped");
2614    while (unfinished_mdstat_devices > 0) {
2615            // FIXME: Prefix '/dev/' should really be dynamic!
2616        if (parse_mdstat(raidlist, "/dev/")) {
2617            log_to_screen("Sorry, cannot read %s", MDSTAT_FILE);
2618            log_msg(1,"Sorry, cannot read %s", MDSTAT_FILE);
2619            return;
2620        }
2621        for (unfinished_mdstat_devices = i = 0; i <= raidlist->entries; i++) {
2622            if (raidlist->el[i].progress < wait_for_percentage) {
2623                unfinished_mdstat_devices++;
2624                if (raidlist->el[i].progress == -1) // delayed while another partition inits
2625                {
2626                    continue;
2627                }
2628                log_msg(1,"Sync'ing %s (i=%d)", raidlist->el[i].raid_device, i);
2629                sprintf(screen_message, "Sync'ing %s",
2630                        raidlist->el[i].raid_device);
2631                open_evalcall_form(screen_message);
2632                while (raidlist->el[i].progress < wait_for_percentage) {
2633                    log_msg(1,"Percentage sync'ed: %d", raidlist->el[i].progress);
2634                    update_evalcall_form(raidlist->el[i].progress);
2635                    sleep(2);
2636                    // FIXME: Prefix '/dev/' should really be dynamic!
2637                    if (parse_mdstat(raidlist, "/dev/")) {
2638                        break;
2639                    }
2640                }
2641                close_evalcall_form();
2642            }
2643        }
2644    }
2645    paranoid_free(screen_message);
2646    paranoid_free(raidlist);
2647}
Note: See TracBrowser for help on using the repository browser.