source: trunk/mondo/mondo/mondorestore/mondo-rstr-tools.c @ 507

Last change on this file since 507 was 507, checked in by bcornec, 13 years ago

merge -r489:506 $SVN_M/branches/stable

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