source: branches/stable/mondo/src/mondorestore/mondo-rstr-tools.c @ 1067

Last change on this file since 1067 was 1067, checked in by bruno, 12 years ago

my-stuff.h is referred to in include now

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