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

Last change on this file since 951 was 951, checked in by Bruno Cornec, 14 years ago

typo

  • Property svn:keywords set to Id
File size: 80.6 KB
Line 
1/***************************************************************************
2mondo-rstr-tools.c  -  description
3-----------------
4
5begin: Sun Sep 21 16:40:35 EDT 2003
6copyright : (C) 2002 Mondo  Hugo Rabson
7email     : Hugo Rabson <hugorabson@msn.com>
8edited by : by Stan Benoit ?/2003
9email     : troff@nakedsoul.org
10cvsid     : $Id: mondo-rstr-tools.c
11***************************************************************************/
12
13/***************************************************************************
14 *                                                                         *
15 *   This program is free software; you can redistribute it and/or modify  *
16 *   it under the terms of the GNU General Public License as published by  *
17 *   the Free Software Foundation; either version 2 of the License, or     *
18 *   (at your option) any later version.                                   *
19 *                                                                         *
20 ***************************************************************************/
21/* mondo-rstr-tools.c               Hugo Rabson
22
23
2407/27
25- if the user is foolish enough to use /dev/md0 as boot device,
26  call lilo -M /dev/hda to make sure lilo does its job properly
27- better NFS+nuke support
28
2907/20
30- use backup's i-want-my-lvm file
31- be sure to use archives' raidtab when restoring
32
3307/18
34- use /tmp/isodir for NFS if DR mode
35- better support of users who boot from LVM CD and nuke-restore non-LVM backups
36
3707/12
38- bugfix to allow user to burn ISOs to CDs and restore from CDs (not original src)
39
4006/29
41- mount ext3 partitions as ext2, just in case :)
42
4306/26
44- delete make_relevant_partition_bootable()
45
4606/19
47- futzed with the call to mount floppy, to stop it from locking up on my AMD64 system
48
4906/14
50- shell out to /mnt/RESTORING chroot in order to let user install GRUB
51  manually if automatic GRUB installation fails
52
5306/15
54- Added check for different 'isodir' chosen by user than stored in the archive
55  Conor Daly <conor.daly@met.ie>
56
5704/17
58- replaced INTERNAL_TAPE_BLK_SIZE with bkpinfo->internal_tape_block_size
59
6004/09
61- don't try to mount CD if tape bkp
62
6304/03
64- trying to copy tmp/mondo-restore.cfg to itself - silly! - fixed
65
6604/02
67- when extracting cfg file and mountlist from all.tar.gz (tape copy),
68  use block size of INTERNAL_TAPE_BLK_SIZE, not TAPE_BLOCK_SIZE
69
7002/21
71- don't use 'mv -v' cos Busybox won't support it
72
7302/09
74- make hole for cfg file before moving it (line 2094 or so)
75
7602/03
77- changed a couple of refs to filelist.full, to filelist.full.gz
78
7901/16/2004
80- instead of copying filelist, use 'ln -sf' to link to original;
81  saves space
82
8311/20/2003
84- also retrieve /tmp/mountlist.txt if user wants
85
8611/16
87- fixed NFS path bug affecting the extractions of filelist/biggielist
88  during selective restore
89
9011/02
91- fixed mount_cdrom() to run properly w/ nfs restores
92- mount_device() returns 0 if swap mount fails cos swap isn't crucial
93
9410/17
95- run_grub() uses MNT_RESTORING instead of "/mnt/RESTORING"
96
9710/26
98- cleaned up run_grub()
99
10010/25
101- fixed mount_cdrom() to run properly w/ nfs restores
102
10310/21
104- mount_device() returns 0 if swap mount fails cos swap isn't crucial
105
10610/15
107- run_grub() now uses its initiative instead
108  of calling grub-install
109
11010/10
111- don't leave copies of filelist.full lying around, clogging up
112  the ramdisk, there's a good fellow :-)
113
11410/02
115- added 'dvd' to the range of media types I'll understand
116- fixed iso->cdr problem (thanks, Stan Benoit & Fred Beondo)
117
11809/24
119- try lots of tape devs if /dev/st0 fails
120
12109/23/2003
122- first incarnation
123*/
124
125
126#include <pthread.h>
127#include "../common/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        strcpy(bkpinfo->zip_exe, "lzop");
1139        strcpy(bkpinfo->zip_suffix, "lzo");
1140    } else {
1141        read_cfg_var(cfg_file, "use-comp", value);
1142        if (strstr(value, "yes")) {
1143            bkpinfo->use_lzo = FALSE;
1144            strcpy(bkpinfo->zip_exe, "bzip2");
1145            strcpy(bkpinfo->zip_suffix, "bz2");
1146        } else {
1147            bkpinfo->zip_exe[0] = bkpinfo->zip_suffix[0] = '\0';
1148        }
1149    }
1150
1151    value[0] = '\0';
1152    read_cfg_var(cfg_file, "differential", value);
1153    if (!strcmp(value, "yes") || !strcmp(value, "1")) {
1154        bkpinfo->differential = TRUE;
1155    }
1156    log_msg(2, "differential var = '%s'", value);
1157    if (bkpinfo->differential) {
1158        log_msg(2, "THIS IS A DIFFERENTIAL BACKUP");
1159    } else {
1160        log_msg(2, "This is a regular (full) backup");
1161    }
1162
1163    read_cfg_var(g_mondo_cfg_file, "please-dont-eject", tmp);
1164    if (tmp[0]
1165        ||
1166        strstr(call_program_and_get_last_line_of_output
1167               ("cat /proc/cmdline"), "donteject")) {
1168        bkpinfo->please_dont_eject = TRUE;
1169        log_msg(2, "Ok, I shan't eject when restoring! Groovy.");
1170    }
1171
1172    if (bkpinfo->backup_media_type == nfs) {
1173        if (!cfgf) {
1174            log_msg(2, "nfs_mount remains %s", bkpinfo->nfs_mount);
1175            log_msg(2, "nfs_remote_dir remains %s",
1176                    bkpinfo->nfs_remote_dir);
1177            log_msg(2,
1178                    "...cos it wouldn't make sense to abandon the values that GOT ME to this config file in the first place");
1179        } else {
1180            read_cfg_var(g_mondo_cfg_file, "nfs-server-mount",
1181                         bkpinfo->nfs_mount);
1182            read_cfg_var(g_mondo_cfg_file, "nfs-server-path",
1183                         bkpinfo->nfs_remote_dir);
1184            log_msg(2, "nfs_mount is %s", bkpinfo->nfs_mount);
1185            log_msg(2, "nfs_remote_dir is %s", bkpinfo->nfs_remote_dir);
1186        }
1187        if (strstr(call_program_and_get_last_line_of_output
1188           ("cat /proc/cmdline"), "pxe")) {
1189            /* We need to override values in PXE mode as it's
1190            * already done in start-nfs */
1191            envtmp1 = getenv("nfsmount");
1192            if (envtmp1 == NULL) {
1193                fatal_error("no nfsmount variable in environment");
1194            }
1195            envtmp2 = getenv("dirimg");
1196            if (envtmp2 == NULL) {
1197                fatal_error("no dirimg variable in environment");
1198            }
1199            strcpy(bkpinfo->nfs_mount,envtmp1);
1200            strcpy(bkpinfo->nfs_remote_dir,envtmp2);
1201        }
1202    } else if (bkpinfo->backup_media_type == iso) {
1203        /* Patch by Conor Daly 23-june-2004
1204         * to correctly mount iso-dev and set a sensible
1205         * isodir in disaster recovery mode
1206         */
1207        strcpy(old_isodir, bkpinfo->isodir);
1208        read_cfg_var(g_mondo_cfg_file, "iso-mnt", iso_mnt);
1209        read_cfg_var(g_mondo_cfg_file, "isodir", iso_path);
1210        sprintf(bkpinfo->isodir, "%s%s", iso_mnt, iso_path);
1211        if (!bkpinfo->isodir[0]) {
1212            strcpy(bkpinfo->isodir, old_isodir);
1213        }
1214        if (!bkpinfo->disaster_recovery) {
1215            if (strcmp(old_isodir, bkpinfo->isodir)) {
1216                log_it
1217                    ("user nominated isodir differs from archive, keeping user's choice: %s %s\n",
1218                     old_isodir, bkpinfo->isodir);
1219                strcpy(bkpinfo->isodir, old_isodir);
1220            }
1221        }
1222        read_cfg_var(g_mondo_cfg_file, "iso-dev", g_isodir_device);
1223        log_msg(2, "isodir=%s; iso-dev=%s", bkpinfo->isodir,
1224                g_isodir_device);
1225        if (bkpinfo->disaster_recovery) {
1226            if (is_this_device_mounted(g_isodir_device)) {
1227                log_msg(2, "NB: isodir is already mounted");
1228                /* Find out where it's mounted */
1229                sprintf(command,
1230                        "mount | grep -E '^%s' | tail -n1 | cut -d' ' -f3",
1231                        g_isodir_device);
1232                log_it("command = %s", command);
1233                log_it("res of it = %s",
1234                       call_program_and_get_last_line_of_output(command));
1235                sprintf(iso_mnt, "%s",
1236                        call_program_and_get_last_line_of_output(command));
1237            } else {
1238                sprintf(iso_mnt, "/tmp/isodir");
1239                sprintf(tmp, "mkdir -p %s", iso_mnt);
1240                run_program_and_log_output(tmp, 5);
1241                sprintf(tmp, "mount %s %s", g_isodir_device, iso_mnt);
1242                if (run_program_and_log_output(tmp, 3)) {
1243                    log_msg(1,
1244                            "Unable to mount isodir. Perhaps this is really a CD backup?");
1245                    bkpinfo->backup_media_type = cdr;
1246                    strcpy(bkpinfo->media_device, "/dev/cdrom");    /* superfluous */
1247                    bkpinfo->isodir[0] = iso_mnt[0] = iso_path[0] = '\0';
1248                    if (mount_cdrom(bkpinfo)) {
1249                        fatal_error
1250                            ("Unable to mount isodir. Failed to mount CD-ROM as well.");
1251                    } else {
1252                        log_msg(1,
1253                                "You backed up to disk, then burned some CDs.");
1254                    }
1255                }
1256            }
1257            /* bkpinfo->isodir should now be the true path to prefix-1.iso etc... */
1258            if (bkpinfo->backup_media_type == iso) {
1259                sprintf(bkpinfo->isodir, "%s%s", iso_mnt, iso_path);
1260            }
1261        }
1262    }
1263
1264    if (media_specified_by_user != none) {
1265        if (g_restoring_live_from_cd) {
1266            if (bkpinfo->backup_media_type != media_specified_by_user) {
1267                log_msg(2,
1268                        "bkpinfo->backup_media_type != media_specified_by_user, so I'd better ask :)");
1269                interactively_obtain_media_parameters_from_user(bkpinfo,
1270                                                                FALSE);
1271                media_specified_by_user = bkpinfo->backup_media_type;
1272                get_cfg_file_from_archive(bkpinfo);
1273/*
1274              if (media_specified_by_user != cdr && media_specified_by_user == cdrw)
1275                { g_restoring_live_from_cd = FALSE; }
1276*/
1277            }
1278        }
1279        bkpinfo->backup_media_type = media_specified_by_user;
1280    }
1281    g_backup_media_type = bkpinfo->backup_media_type;
1282    paranoid_free(value);
1283    paranoid_free(tmp);
1284    paranoid_free(command);
1285    paranoid_free(iso_mnt);
1286    paranoid_free(iso_path);
1287    paranoid_free(old_isodir);
1288    return (0);
1289
1290}
1291
1292/**************************************************************************
1293 *END_READ_CFG_FILE_INTO_BKPINFO                                          *
1294 **************************************************************************/
1295
1296
1297
1298
1299/**
1300 * Allow the user to edit the filelist and biggielist.
1301 * The filelist is unlinked after it is read.
1302 * @param bkpinfo The backup information structure. Fields used:
1303 * - @c bkpinfo->backup_media_type
1304 * - @c bkpinfo->isodir
1305 * - @c bkpinfo->media_device
1306 * - @c bkpinfo->tmpdir
1307 * @return The filelist structure containing the information read from disk.
1308 */
1309struct
1310s_node *process_filelist_and_biggielist(struct s_bkpinfo *bkpinfo)
1311{
1312    struct s_node *filelist;
1313
1314  /** add mallocs**/
1315    char *command;
1316    char *tmp;
1317    int res = 0;
1318    pid_t pid;
1319
1320    assert(bkpinfo != NULL);
1321    malloc_string(command);
1322    malloc_string(tmp);
1323
1324    if (does_file_exist(g_filelist_full)
1325        && does_file_exist(g_biggielist_txt)) {
1326        log_msg(1, "%s exists", g_filelist_full);
1327        log_msg(1, "%s exists", g_biggielist_txt);
1328        log_msg(2,
1329                "Filelist and biggielist already recovered from media. Yay!");
1330    } else {
1331        getcwd(tmp, MAX_STR_LEN);
1332        chdir(bkpinfo->tmpdir);
1333        log_msg(1, "chdir(%s)", bkpinfo->tmpdir);
1334        log_to_screen("Extracting filelist and biggielist from media...");
1335        unlink("/tmp/filelist.full");
1336        unlink("/" FILELIST_FULL_STUB);
1337        unlink("/tmp/i-want-my-lvm");
1338        if (IS_THIS_A_STREAMING_BACKUP(bkpinfo->backup_media_type)) {
1339            sprintf(command,
1340                    "tar -zxf %s %s %s %s %s %s",
1341                    bkpinfo->media_device,
1342                    MOUNTLIST_FNAME_STUB,
1343                    BIGGIELIST_TXT_STUB,
1344                    FILELIST_FULL_STUB,
1345                    "tmp/i-want-my-lvm", MONDO_CFG_FILE_STUB);
1346            log_msg(1, "tarcommand = %s", command);
1347            run_program_and_log_output(command, 1);
1348        } else {
1349            log_msg(2,
1350                    "Calling insist_on_this_cd_number; bkpinfo->isodir=%s",
1351                    bkpinfo->isodir);
1352            insist_on_this_cd_number(bkpinfo, 1);
1353            log_msg(2, "Back from iotcn");
1354            run_program_and_log_output("mount", 1);
1355            sprintf(command,
1356                    "tar -zxf %s/images/all.tar.gz %s %s %s %s %s",
1357                    MNT_CDROM,
1358                    MOUNTLIST_FNAME_STUB,
1359                    BIGGIELIST_TXT_STUB,
1360                    FILELIST_FULL_STUB,
1361                    "tmp/i-want-my-lvm", MONDO_CFG_FILE_STUB);
1362
1363            log_msg(1, "tarcommand = %s", command);
1364            run_program_and_log_output(command, 1);
1365//    popup_and_OK("Press ENTER to continue");
1366            if (!does_file_exist(BIGGIELIST_TXT_STUB)) {
1367                fatal_error
1368                    ("all.tar.gz did not include tmp/biggielist.txt");
1369            }
1370            if (!does_file_exist(FILELIST_FULL_STUB)) {
1371                fatal_error
1372                    ("all.tar.gz did not include tmp/filelist.full.gz");
1373            }
1374        }
1375        sprintf(command, "cp -f %s %s", MONDO_CFG_FILE_STUB,
1376                g_mondo_cfg_file);
1377        run_program_and_log_output(command, FALSE);
1378
1379        sprintf(command, "cp -f %s/%s %s", bkpinfo->tmpdir,
1380                BIGGIELIST_TXT_STUB, g_biggielist_txt);
1381        log_msg(1, "command = %s", command);
1382        paranoid_system(command);
1383        sprintf(command, "ln -sf %s/%s %s", bkpinfo->tmpdir,
1384                FILELIST_FULL_STUB, g_filelist_full);
1385        log_msg(1, "command = %s", command);
1386        paranoid_system(command);
1387    }
1388
1389    if (am_I_in_disaster_recovery_mode()
1390        &&
1391        ask_me_yes_or_no("Do you want to retrieve the mountlist as well?"))
1392    {
1393//      sprintf(command, "cp -f tmp/mountlist.txt /tmp");
1394        sprintf(command, "ln -sf %s/%s /tmp", MOUNTLIST_FNAME_STUB,
1395                bkpinfo->tmpdir);
1396        paranoid_system(command);
1397    }
1398
1399    chdir(tmp);
1400
1401    if (!does_file_exist(g_biggielist_txt)) {
1402        log_msg(1, "Warning - %s not found", g_biggielist_txt);
1403    }
1404    if (!does_file_exist(g_filelist_full)) {
1405        log_msg(1, "Warning - %s does not exist", g_filelist_full);
1406    }
1407//  popup_and_OK("Wonderful.");
1408
1409    log_msg(2, "Forking");
1410    pid = fork();
1411    switch (pid) {
1412    case -1:
1413        fatal_error("Forking error");
1414        break;
1415
1416    case 0:
1417        log_to_screen("Pre-processing filelist");
1418        if (!does_file_exist(g_biggielist_txt)) {
1419            sprintf(command, "> %s", g_biggielist_txt);
1420            paranoid_system(command);
1421        }
1422        sprintf(command, "grep -E '^/dev/.*' %s > %s",
1423                g_biggielist_txt, g_filelist_imagedevs);
1424        paranoid_system(command);
1425        exit(0);
1426        break;
1427
1428    default:
1429        open_evalcall_form("Pre-processing filelist");
1430        while (!waitpid(pid, (int *) 0, WNOHANG)) {
1431            usleep(100000);
1432            update_evalcall_form(0);
1433        }
1434    }
1435    close_evalcall_form();
1436
1437    log_msg(3, "loading filelist");
1438    filelist = load_filelist(g_filelist_full);
1439    log_msg(3, "deleting original filelist");
1440    unlink(g_filelist_full);
1441    if (g_text_mode) {
1442        printf("Restore which directory? --> ");
1443        fgets(tmp, sizeof(tmp), stdin);
1444        toggle_path_selection(filelist, tmp, TRUE);
1445        if (strlen(tmp) == 0) {
1446            res = 1;
1447        } else {
1448            res = 0;
1449        }
1450    } else {
1451        res = edit_filelist(filelist);
1452    }
1453    if (res) {
1454        log_msg(2, "User hit 'cancel'. Freeing filelist and aborting.");
1455        free_filelist(filelist);
1456        return (NULL);
1457    }
1458    ask_about_these_imagedevs(g_filelist_imagedevs, g_imagedevs_restthese);
1459    close_evalcall_form();
1460
1461    // NB: It's not necessary to add g_biggielist_txt to the filelist.full
1462    // file. The filelist.full file already contains the filename of EVERY
1463    // file backed up - regular and biggie files.
1464
1465    // However, we do want to make sure the imagedevs selected by the user
1466    // are flagged for restoring.
1467    if (length_of_file(g_imagedevs_restthese) > 2) {
1468        add_list_of_files_to_filelist(filelist, g_imagedevs_restthese,
1469                                      TRUE);
1470    }
1471
1472    paranoid_free(command);
1473    paranoid_free(tmp);
1474    return (filelist);
1475}
1476
1477/**************************************************************************
1478 *END_ PROCESS_FILELIST_AND_BIGGIELIST                                    *
1479 **************************************************************************/
1480
1481
1482
1483
1484/**
1485 * Make a backup copy of <tt>path_root</tt>/<tt>filename</tt>.
1486 * The backup filename is the filename of the original with ".pristine" added.
1487 * @param path_root The place where the filesystem is mounted (e.g. MNT_RESTORING).
1488 * @param filename The filename (absolute path) within @p path_root.
1489 * @return 0 for success, nonzero for failure.
1490 */
1491int backup_crucial_file(char *path_root, char *filename)
1492{
1493    char *tmp;
1494    char *command;
1495    int res;
1496
1497    malloc_string(tmp);
1498    malloc_string(command);
1499    assert(path_root != NULL);
1500    assert_string_is_neither_NULL_nor_zerolength(filename);
1501
1502    sprintf(tmp, "%s/%s", path_root, filename);
1503    sprintf(command, "cp -f %s %s.pristine", tmp, tmp);
1504
1505    res = run_program_and_log_output(command, 5);
1506    paranoid_free(tmp);
1507    paranoid_free(command);
1508    return (res);
1509}
1510
1511
1512/**
1513 * Install the user's boot loader in the MBR.
1514 * Currently LILO, ELILO, GRUB, RAW (dd of MBR), and the FreeBSD bootloader are supported.
1515 * @param offer_to_hack_scripts If TRUE, then offer to hack the user's fstab for them.
1516 * @return 0 for success, nonzero for failure.
1517 */
1518int run_boot_loader(bool offer_to_hack_scripts)
1519{
1520    int res;
1521    int retval = 0;
1522
1523  /** malloc *******/
1524    char *device;
1525    char *tmp;
1526    char *name;
1527
1528    malloc_string(device);
1529    malloc_string(tmp);
1530    malloc_string(name);
1531    backup_crucial_file(MNT_RESTORING, "/etc/fstab");
1532    backup_crucial_file(MNT_RESTORING, "/etc/grub.conf");
1533    backup_crucial_file(MNT_RESTORING, "/etc/lilo.conf");
1534    backup_crucial_file(MNT_RESTORING, "/etc/elilo.conf");
1535    read_cfg_var(g_mondo_cfg_file, "bootloader.device", device);
1536    read_cfg_var(g_mondo_cfg_file, "bootloader.name", name);
1537    sprintf(tmp, "run_boot_loader: device='%s', name='%s'", device, name);
1538    log_msg(2, tmp);
1539    system("sync");
1540    if (!strcmp(name, "LILO")) {
1541        res = run_lilo(offer_to_hack_scripts);
1542    } else if (!strcmp(name, "ELILO")) {
1543        res = run_elilo(offer_to_hack_scripts);
1544    } else if (!strcmp(name, "GRUB")) {
1545//      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?")))
1546//        {
1547        res = run_grub(offer_to_hack_scripts, device);
1548//    unlink(DO_MBR_PLEASE);
1549//  }
1550//      else
1551//        {
1552//    log_msg(1, "Not running run_grub(). Was a bad idea anyway.");
1553//    res = 1;
1554//  }
1555    } else if (!strcmp(name, "RAW")) {
1556        res = run_raw_mbr(offer_to_hack_scripts, device);
1557    }
1558#ifdef __FreeBSD__
1559    else if (!strcmp(name, "BOOT0")) {
1560        sprintf(tmp, "boot0cfg -B %s", device);
1561        res = run_program_and_log_output(tmp, FALSE);
1562    } else {
1563        sprintf(tmp, "ls /dev | grep -Eq '^%ss[1-4].*'", device);
1564        if (!system(tmp)) {
1565            sprintf(tmp, MNT_RESTORING "/sbin/fdisk -B %s", device);
1566            res = run_program_and_log_output(tmp, 3);
1567        } else {
1568            log_msg(1,
1569                    "I'm not running any boot loader. You have a DD boot drive. It's already loaded up.");
1570        }
1571    }
1572#else
1573    else {
1574        log_to_screen
1575            ("Unable to determine type of boot loader. Defaulting to LILO.");
1576        res = run_lilo(offer_to_hack_scripts);
1577    }
1578#endif
1579    retval += res;
1580    if (res) {
1581        log_to_screen("Your boot loader returned an error");
1582    } else {
1583        log_to_screen("Your boot loader ran OK");
1584    }
1585    paranoid_free(device);
1586    paranoid_free(tmp);
1587    paranoid_free(name);
1588    return (retval);
1589}
1590
1591/**************************************************************************
1592 *END_ RUN_BOOT_LOADER                                                    *
1593 **************************************************************************/
1594
1595
1596
1597/**
1598 * Attempt to find the user's editor.
1599 * @return The editor found ("vi" if none could be found).
1600 * @note The returned string points to static storage that will be overwritten with each call.
1601 */
1602char *find_my_editor(void)
1603{
1604    static char output[MAX_STR_LEN];
1605    if (find_home_of_exe("pico")) {
1606        strcpy(output, "pico");
1607    } else if (find_home_of_exe("nano")) {
1608        strcpy(output, "nano");
1609    } else if (find_home_of_exe("e3em")) {
1610        strcpy(output, "e3em");
1611    } else if (find_home_of_exe("e3vi")) {
1612        strcpy(output, "e3vi");
1613    } else {
1614        strcpy(output, "vi");
1615    }
1616    if (!find_home_of_exe(output)) {
1617        log_msg(2, " (find_my_editor) --- warning - %s not found", output);
1618    }
1619    return (output);
1620}
1621
1622
1623/**
1624 * Install GRUB on @p bd.
1625 * @param offer_to_run_stabgrub If TRUE, then offer to hack the user's fstab for them.
1626 * @param bd The boot device where GRUB is installed.
1627 * @return 0 for success, nonzero for failure.
1628 */
1629int run_grub(bool offer_to_run_stabgrub, char *bd)
1630{
1631  /** malloc **/
1632    char *command;
1633    char *boot_device;
1634    char *rootdev;
1635    char *rootdrive;
1636    char *conffile;
1637    char *tmp;
1638    char *editor;
1639
1640    int res;
1641    int done;
1642
1643    malloc_string(command);
1644    malloc_string(boot_device);
1645    malloc_string(tmp);
1646    malloc_string(editor);
1647    malloc_string(rootdev);
1648    malloc_string(rootdrive);
1649    malloc_string(conffile);
1650    assert_string_is_neither_NULL_nor_zerolength(bd);
1651    strcpy(editor, "vi");       // find_my_editor() );
1652    strcpy(boot_device, bd);
1653
1654    if (!run_program_and_log_output("which grub-MR", FALSE)) {
1655        log_msg(1, "Yay! grub-MR found...");
1656        sprintf(command, "grub-MR %s /tmp/mountlist.txt", boot_device);
1657        log_msg(1, "command = %s", command);
1658    } else {
1659        sprintf(command, "chroot " MNT_RESTORING " grub-install %s",
1660                boot_device);
1661        log_msg(1, "WARNING - grub-MR not found; using grub-install");
1662    }
1663    if (offer_to_run_stabgrub
1664        && ask_me_yes_or_no("Did you change the mountlist?"))
1665        /* interactive mode */
1666    {
1667        mvaddstr_and_log_it(g_currentY,
1668                            0,
1669                            "Modifying fstab and grub.conf, and running GRUB...                             ");
1670        for (done = FALSE; !done;) {
1671            popup_and_get_string("Boot device",
1672                                 "Please confirm/enter the boot device. If in doubt, try /dev/hda",
1673                                 boot_device, MAX_STR_LEN / 4);
1674            sprintf(command, "stabgrub-me %s", boot_device);
1675            res = run_program_and_log_output(command, 1);
1676            if (res) {
1677                popup_and_OK
1678                    ("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.");
1679                newtSuspend();
1680                system("chroot " MNT_RESTORING);
1681                newtResume();
1682                popup_and_OK("Thank you.");
1683            } else {
1684                done = TRUE;
1685            }
1686            popup_and_OK("You will now edit fstab and grub.conf");
1687            if (!g_text_mode) {
1688                newtSuspend();
1689            }
1690            sprintf(tmp, "%s " MNT_RESTORING "/etc/fstab", editor);
1691            paranoid_system(tmp);
1692            sprintf(tmp, "%s " MNT_RESTORING "/etc/grub.conf", editor);
1693            paranoid_system(tmp);
1694            if (!g_text_mode) {
1695                newtResume();
1696            }
1697        }
1698    } else
1699        /* nuke mode */
1700    {
1701        mvaddstr_and_log_it(g_currentY,
1702                            0,
1703                            "Running GRUB...                                                 ");
1704        iamhere(command);
1705        res = run_program_and_log_output(command, 1);
1706        if (res) {
1707            popup_and_OK
1708                ("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.");
1709            newtSuspend();
1710            system("chroot " MNT_RESTORING);
1711            newtResume();
1712            popup_and_OK("Thank you.");
1713        }
1714    }
1715    if (res) {
1716        mvaddstr_and_log_it(g_currentY++, 74, "Failed.");
1717        log_to_screen
1718            ("GRUB ran w/error(s). See /tmp/mondo-restore.log for more info.");
1719        log_msg(1, "Type:-");
1720        log_msg(1, "    mount-me");
1721        log_msg(1, "    chroot " MNT_RESTORING);
1722        log_msg(1, "    mount /boot");
1723        log_msg(1, "    grub-install '(hd0)'");
1724        log_msg(1, "    exit");
1725        log_msg(1, "    unmount-me");
1726        log_msg(1,
1727                "If you're really stuck, please e-mail the mailing list.");
1728    } else {
1729        mvaddstr_and_log_it(g_currentY++, 74, "Done.");
1730    }
1731    paranoid_free(rootdev);
1732    paranoid_free(rootdrive);
1733    paranoid_free(conffile);
1734    paranoid_free(command);
1735    paranoid_free(boot_device);
1736    paranoid_free(tmp);
1737    paranoid_free(editor);
1738
1739    return (res);
1740}
1741
1742/**************************************************************************
1743 *END_RUN_GRUB                                                            *
1744 **************************************************************************/
1745
1746
1747/**
1748 * Install ELILO on the user's boot drive (determined by elilo.conf).
1749 * @param offer_to_run_stabelilo If TRUE, then offer to hack the user's fstab for them.
1750 * @return 0 for success, nonzero for failure.
1751 */
1752int run_elilo(bool offer_to_run_stabelilo)
1753{
1754  /** malloc **/
1755    char *command;
1756    char *tmp;
1757    char *editor;
1758
1759    int res;
1760    int done;
1761
1762    malloc_string(command);
1763    malloc_string(tmp);
1764    malloc_string(editor);
1765    strcpy(editor, find_my_editor());
1766    if (offer_to_run_stabelilo
1767        && ask_me_yes_or_no("Did you change the mountlist?"))
1768
1769        /* interactive mode */
1770    {
1771        mvaddstr_and_log_it(g_currentY,
1772                            0,
1773                            "Modifying fstab and elilo.conf...                             ");
1774        sprintf(command, "stabelilo-me");
1775        res = run_program_and_log_output(command, 3);
1776        if (res) {
1777            popup_and_OK
1778                ("You will now edit fstab and elilo.conf, to make sure they match your new mountlist.");
1779            for (done = FALSE; !done;) {
1780                if (!g_text_mode) {
1781                    newtSuspend();
1782                }
1783                sprintf(tmp, "%s " MNT_RESTORING "/etc/fstab", editor);
1784                paranoid_system(tmp);
1785                sprintf(tmp, "%s " MNT_RESTORING "/etc/elilo.conf",
1786                        editor);
1787                paranoid_system(tmp);
1788                if (!g_text_mode) {
1789                    newtResume();
1790                }
1791//              newtCls();
1792                if (ask_me_yes_or_no("Edit them again?")) {
1793                    continue;
1794                }
1795                done = TRUE;
1796            }
1797        } else {
1798            log_to_screen("elilo.conf and fstab were modified OK");
1799        }
1800    } else
1801        /* nuke mode */
1802    {
1803        res = TRUE;
1804    }
1805    paranoid_free(command);
1806    paranoid_free(tmp);
1807    paranoid_free(editor);
1808    return (res);
1809}
1810
1811/**************************************************************************
1812 *END_RUN_ELILO                                                            *
1813 **************************************************************************/
1814
1815
1816/**
1817 * Install LILO on the user's boot drive (determined by /etc/lilo.conf).
1818 * @param offer_to_run_stablilo If TRUE, then offer to hack the user's fstab for them.
1819 * @return 0 for success, nonzero for failure.
1820 */
1821int run_lilo(bool offer_to_run_stablilo)
1822{
1823  /** malloc **/
1824    char *command;
1825    char *tmp;
1826    char *editor;
1827
1828    int res;
1829    int done;
1830    bool run_lilo_M = FALSE;
1831    malloc_string(command);
1832    malloc_string(tmp);
1833    malloc_string(editor);
1834
1835    if (!run_program_and_log_output
1836        ("grep \"boot.*=.*/dev/md\" " MNT_RESTORING "/etc/lilo.conf", 1)) {
1837        run_lilo_M = TRUE;
1838    }
1839
1840    strcpy(editor, find_my_editor());
1841    if (offer_to_run_stablilo
1842        && ask_me_yes_or_no("Did you change the mountlist?"))
1843
1844        /* interactive mode */
1845    {
1846        mvaddstr_and_log_it(g_currentY,
1847                            0,
1848                            "Modifying fstab and lilo.conf, and running LILO...                             ");
1849        sprintf(command, "stablilo-me");
1850        res = run_program_and_log_output(command, 3);
1851        if (res) {
1852            popup_and_OK
1853                ("You will now edit fstab and lilo.conf, to make sure they match your new mountlist.");
1854            for (done = FALSE; !done;) {
1855                if (!g_text_mode) {
1856                    newtSuspend();
1857                }
1858                sprintf(tmp, "%s " MNT_RESTORING "/etc/fstab", editor);
1859                paranoid_system(tmp);
1860                sprintf(tmp, "%s " MNT_RESTORING "/etc/lilo.conf", editor);
1861                paranoid_system(tmp);
1862                if (!g_text_mode) {
1863                    newtResume();
1864                }
1865//              newtCls();
1866                if (ask_me_yes_or_no("Edit them again?")) {
1867                    continue;
1868                }
1869                res =
1870                    run_program_and_log_output("chroot " MNT_RESTORING
1871                                               " lilo -L", 3);
1872                if (res) {
1873                    res =
1874                        run_program_and_log_output("chroot " MNT_RESTORING
1875                                                   " lilo", 3);
1876                }
1877                if (res) {
1878                    done =
1879                        ask_me_yes_or_no
1880                        ("LILO failed. Re-edit system files?");
1881                } else {
1882                    done = TRUE;
1883                }
1884            }
1885        } else {
1886            log_to_screen("lilo.conf and fstab were modified OK");
1887        }
1888    } else
1889        /* nuke mode */
1890    {
1891        mvaddstr_and_log_it(g_currentY,
1892                            0,
1893                            "Running LILO...                                                 ");
1894        res =
1895            run_program_and_log_output("chroot " MNT_RESTORING " lilo -L",
1896                                       3);
1897        if (res) {
1898            res =
1899                run_program_and_log_output("chroot " MNT_RESTORING " lilo",
1900                                           3);
1901        }
1902        if (res) {
1903            mvaddstr_and_log_it(g_currentY++, 74, "Failed.");
1904            log_to_screen
1905                ("Failed to re-jig fstab and/or lilo. Edit/run manually, please.");
1906        } else {
1907            mvaddstr_and_log_it(g_currentY++, 74, "Done.");
1908        }
1909    }
1910    if (run_lilo_M) {
1911        run_program_and_log_output("chroot " MNT_RESTORING
1912                                   " lilo -M /dev/hda", 3);
1913        run_program_and_log_output("chroot " MNT_RESTORING
1914                                   " lilo -M /dev/sda", 3);
1915    }
1916    paranoid_free(command);
1917    paranoid_free(tmp);
1918    paranoid_free(editor);
1919    return (res);
1920}
1921
1922/**************************************************************************
1923 *END_RUN_LILO                                                            *
1924 **************************************************************************/
1925
1926
1927/**
1928 * Install a raw MBR onto @p bd.
1929 * @param offer_to_hack_scripts If TRUE, then offer to hack the user's fstab for them.
1930 * @param bd The device to copy the stored MBR to.
1931 * @return 0 for success, nonzero for failure.
1932 */
1933int run_raw_mbr(bool offer_to_hack_scripts, char *bd)
1934{
1935  /** malloc **/
1936    char *command;
1937    char *boot_device;
1938    char *tmp;
1939    char *editor;
1940    int res;
1941    int done;
1942
1943    malloc_string(command);
1944    malloc_string(boot_device);
1945    malloc_string(tmp);
1946    malloc_string(editor);
1947    assert_string_is_neither_NULL_nor_zerolength(bd);
1948
1949    strcpy(editor, find_my_editor());
1950    strcpy(boot_device, bd);
1951    sprintf(command, "raw-MR %s /tmp/mountlist.txt", boot_device);
1952    log_msg(2, "run_raw_mbr() --- command='%s'", command);
1953
1954    if (offer_to_hack_scripts
1955        && ask_me_yes_or_no("Did you change the mountlist?"))
1956        /* interactive mode */
1957    {
1958        mvaddstr_and_log_it(g_currentY, 0,
1959                            "Modifying fstab and restoring MBR...                           ");
1960        for (done = FALSE; !done;) {
1961            if (!run_program_and_log_output("which vi", FALSE)) {
1962                popup_and_OK("You will now edit fstab");
1963                if (!g_text_mode) {
1964                    newtSuspend();
1965                }
1966                sprintf(tmp, "%s " MNT_RESTORING "/etc/fstab", editor);
1967                paranoid_system(tmp);
1968                if (!g_text_mode) {
1969                    newtResume();
1970                }
1971//              newtCls();
1972            }
1973            popup_and_get_string("Boot device",
1974                                 "Please confirm/enter the boot device. If in doubt, try /dev/hda",
1975                                 boot_device, MAX_STR_LEN / 4);
1976            sprintf(command, "stabraw-me %s", boot_device);
1977            res = run_program_and_log_output(command, 3);
1978            if (res) {
1979                done = ask_me_yes_or_no("Modifications failed. Re-try?");
1980            } else {
1981                done = TRUE;
1982            }
1983        }
1984    } else
1985        /* nuke mode */
1986    {
1987        mvaddstr_and_log_it(g_currentY, 0,
1988                            "Restoring MBR...                                               ");
1989        res = run_program_and_log_output(command, 3);
1990    }
1991    if (res) {
1992        mvaddstr_and_log_it(g_currentY++, 74, "Failed.");
1993        log_to_screen
1994            ("MBR+fstab processed w/error(s). See /tmp/mondo-restore.log for more info.");
1995    } else {
1996        mvaddstr_and_log_it(g_currentY++, 74, "Done.");
1997    }
1998    paranoid_free(command);
1999    paranoid_free(boot_device);
2000    paranoid_free(tmp);
2001    paranoid_free(editor);
2002    return (res);
2003}
2004
2005/**************************************************************************
2006 *END_RUN_RAW_MBR                                                         *
2007 **************************************************************************/
2008
2009
2010
2011
2012
2013/**
2014 * Turn signal trapping on or off.
2015 * @param on If TRUE, then do full cleanup when we receive a signal; if FALSE, then
2016 * print a message and exit immediately.
2017 */
2018void set_signals(int on)
2019{
2020    int signals[] =
2021        { SIGKILL, SIGPIPE, SIGTERM, SIGHUP, SIGTRAP, SIGABRT, SIGINT,
2022SIGSTOP, 0 };
2023    int i;
2024    for (i = 0; signals[i]; i++) {
2025        if (on) {
2026            signal(signals[i], terminate_daemon);
2027        } else {
2028            signal(signals[i], termination_in_progress);
2029        }
2030    }
2031}
2032
2033/**************************************************************************
2034 *END_SET_SIGNALS                                                         *
2035 **************************************************************************/
2036
2037
2038/**
2039 * malloc() and set sensible defaults for the mondorestore filename variables.
2040 * @param bkpinfo The backup information structure. Fields used:
2041 * - @c bkpinfo->tmpdir
2042 * - @c bkpinfo->disaster_recovery
2043 */
2044void setup_MR_global_filenames(struct s_bkpinfo *bkpinfo)
2045{
2046    char *temppath;
2047
2048    assert(bkpinfo != NULL);
2049
2050    malloc_string(g_biggielist_txt);
2051    malloc_string(g_filelist_full);
2052    malloc_string(g_filelist_imagedevs);
2053    malloc_string(g_imagedevs_restthese);
2054    malloc_string(g_mondo_cfg_file);
2055    malloc_string(g_mountlist_fname);
2056    malloc_string(g_mondo_home);
2057    malloc_string(g_tmpfs_mountpt);
2058    malloc_string(g_isodir_device);
2059    malloc_string(g_isodir_format);
2060
2061    temppath = bkpinfo->tmpdir;
2062
2063    sprintf(g_biggielist_txt, "%s/%s", temppath, BIGGIELIST_TXT_STUB);
2064    sprintf(g_filelist_full, "%s/%s", temppath, FILELIST_FULL_STUB);
2065    sprintf(g_filelist_imagedevs, "%s/tmp/filelist.imagedevs", temppath);
2066//  sprintf(g_imagedevs_pot, "%s/tmp/imagedevs.pot", temppath);
2067    sprintf(g_imagedevs_restthese, "%s/tmp/imagedevs.restore-these",
2068            temppath);
2069    if (bkpinfo->disaster_recovery) {
2070        sprintf(g_mondo_cfg_file, "/%s", MONDO_CFG_FILE_STUB);
2071        sprintf(g_mountlist_fname, "/%s", MOUNTLIST_FNAME_STUB);
2072    } else {
2073        sprintf(g_mondo_cfg_file, "%s/%s", temppath, MONDO_CFG_FILE_STUB);
2074        sprintf(g_mountlist_fname, "%s/%s", temppath,
2075                MOUNTLIST_FNAME_STUB);
2076    }
2077}
2078
2079/**************************************************************************
2080 *END_SET_GLOBAL_FILENAME                                                 *
2081 **************************************************************************/
2082
2083
2084/**
2085 * Copy @p input_file (containing the result of a compare) to @p output_file,
2086 * deleting spurious "changes" along the way.
2087 * @param output_file The output file to write with spurious changes removed.
2088 * @param input_file The input file, a list of changed files created by a compare.
2089 */
2090void streamline_changes_file(char *output_file, char *input_file)
2091{
2092    FILE *fin;
2093    FILE *fout;
2094  /** malloc **/
2095    char *incoming;
2096
2097    assert_string_is_neither_NULL_nor_zerolength(output_file);
2098    assert_string_is_neither_NULL_nor_zerolength(input_file);
2099    malloc_string(incoming);
2100
2101    if (!(fin = fopen(input_file, "r"))) {
2102        log_OS_error(input_file);
2103        return;
2104    }
2105    if (!(fout = fopen(output_file, "w"))) {
2106        fatal_error("cannot open output_file");
2107    }
2108    for (fgets(incoming, MAX_STR_LEN - 1, fin); !feof(fin);
2109         fgets(incoming, MAX_STR_LEN - 1, fin)) {
2110        if (strncmp(incoming, "etc/adjtime", 11)
2111            && strncmp(incoming, "etc/mtab", 8)
2112            && strncmp(incoming, "tmp/", 4)
2113            && strncmp(incoming, "boot/map", 8)
2114            && !strstr(incoming, "incheckentry")
2115            && strncmp(incoming, "etc/mail/statistics", 19)
2116            && strncmp(incoming, "var/", 4))
2117            fprintf(fout, "%s", incoming);  /* don't need \n here, for some reason.. */
2118    }
2119    paranoid_fclose(fout);
2120    paranoid_fclose(fin);
2121    paranoid_free(incoming);
2122}
2123
2124/**************************************************************************
2125 *END_STREAMLINE_CHANGES_FILE                                             *
2126 **************************************************************************/
2127
2128
2129/**
2130 * Exit due to a signal (normal cleanup).
2131 * @param sig The signal we're exiting due to.
2132 */
2133void terminate_daemon(int sig)
2134{
2135    log_to_screen
2136        ("Mondorestore is terminating in response to a signal from the OS");
2137    paranoid_MR_finish(254);
2138}
2139
2140/**************************************************************************
2141 *END_TERMINATE_DAEMON                                                    *
2142 **************************************************************************/
2143
2144
2145/**
2146 * Give the user twenty seconds to press Ctrl-Alt-Del before we nuke their drives.
2147 */
2148void twenty_seconds_til_yikes()
2149{
2150    int i;
2151    /* MALLOC * */
2152    char *tmp;
2153
2154    malloc_string(tmp);
2155    if (does_file_exist("/tmp/NOPAUSE")) {
2156        return;
2157    }
2158    open_progress_form("CAUTION",
2159                       "Be advised: I am about to ERASE your hard disk(s)!",
2160                       "You may press Ctrl+Alt+Del to abort safely.",
2161                       "", 20);
2162    for (i = 0; i < 20; i++) {
2163        g_current_progress = i;
2164        sprintf(tmp, "You have %d seconds left to abort.", 20 - i);
2165        update_progress_form(tmp);
2166        sleep(1);
2167    }
2168    close_progress_form();
2169    paranoid_free(tmp);
2170}
2171
2172/**************************************************************************
2173 *END_TWENTY_SECONDS_TIL_YIKES                                            *
2174 **************************************************************************/
2175
2176
2177
2178
2179
2180/**
2181 * Exit due to a signal (no cleanup).
2182 * @param sig The signal we're exiting due to.
2183 */
2184void termination_in_progress(int sig)
2185{
2186    log_msg(1, "Termination in progress");
2187    usleep(1000);
2188    pthread_exit(0);
2189}
2190
2191/**************************************************************************
2192 *END_TERMINATION_IN_PROGRESS                                             *
2193 **************************************************************************/
2194
2195
2196
2197/**
2198 * Unmount all devices in @p p_external_copy_of_mountlist.
2199 * @param p_external_copy_of_mountlist The mountlist to guide the devices to unmount.
2200 * @return 0 for success, nonzero for failure.
2201 */
2202int unmount_all_devices(struct mountlist_itself
2203                        *p_external_copy_of_mountlist)
2204{
2205    struct mountlist_itself *mountlist;
2206    int retval = 0, lino, res = 0, i;
2207    char *command;
2208    char *tmp;
2209
2210    malloc_string(command);
2211    malloc_string(tmp);
2212    assert(p_external_copy_of_mountlist != NULL);
2213
2214    mountlist = malloc(sizeof(struct mountlist_itself));
2215    memcpy((void *) mountlist, (void *) p_external_copy_of_mountlist,
2216           sizeof(struct mountlist_itself));
2217    sort_mountlist_by_mountpoint(mountlist, 0);
2218
2219    run_program_and_log_output("df -m", 3);
2220    mvaddstr_and_log_it(g_currentY, 0, "Unmounting devices      ");
2221    open_progress_form("Unmounting devices",
2222                       "Unmounting all devices that were mounted,",
2223                       "in preparation for the post-restoration reboot.",
2224                       "", mountlist->entries);
2225    chdir("/");
2226    for (i = 0;
2227         i < 10
2228         &&
2229         run_program_and_log_output
2230         ("ps | grep buffer | grep -v \"grep buffer\"", TRUE) == 0;
2231         i++) {
2232        sleep(1);
2233        log_msg(2, "Waiting for buffer() to finish");
2234    }
2235
2236    paranoid_system("sync");
2237
2238    if (run_program_and_log_output
2239        ("cp -f /tmp/mondo-restore.log " MNT_RESTORING "/tmp/", FALSE)) {
2240        log_msg(1,
2241                "Error. Failed to copy log to PC's /tmp dir. (Mounted read-only?)");
2242    }
2243    if (run_program_and_log_output
2244        ("cp -f /tmp/mondo-restore.log " MNT_RESTORING "/root/", FALSE)) {
2245        log_msg(1,
2246                "Error. Failed to copy log to PC's /root dir. (Mounted read-only?)");
2247    }
2248    if (does_file_exist("/tmp/DUMBASS-GENTOO")) {
2249        run_program_and_log_output("mkdir -p " MNT_RESTORING
2250                                   "/mnt/.boot.d", 5);
2251    }
2252    for (lino = mountlist->entries - 1; lino >= 0; lino--) {
2253        if (!strcmp(mountlist->el[lino].mountpoint, "lvm")) {
2254            continue;
2255        }
2256        sprintf(tmp, "Unmounting device %s  ", mountlist->el[lino].device);
2257
2258        update_progress_form(tmp);
2259        if (is_this_device_mounted(mountlist->el[lino].device)) {
2260            if (!strcmp(mountlist->el[lino].mountpoint, "swap")) {
2261                sprintf(command, "swapoff %s", mountlist->el[lino].device);
2262            } else {
2263                if (!strcmp(mountlist->el[lino].mountpoint, "/1")) {
2264                    sprintf(command, "umount %s/", MNT_RESTORING);
2265                    log_msg(3,
2266                            "Well, I know a certain kitty-kitty who'll be sleeping with Mommy tonight...");
2267                } else {
2268                    sprintf(command, "umount " MNT_RESTORING "%s",
2269                            mountlist->el[lino].mountpoint);
2270                }
2271            }
2272            log_msg(10, "The 'umount' command is '%s'", command);
2273            res = run_program_and_log_output(command, 3);
2274        } else {
2275            strcat(tmp, "...not mounted anyway :-) OK");
2276            res = 0;
2277        }
2278        g_current_progress++;
2279        if (res) {
2280            strcat(tmp, "...Failed");
2281            retval++;
2282            log_to_screen(tmp);
2283        } else {
2284            log_msg(2, tmp);
2285        }
2286    }
2287    close_progress_form();
2288    if (retval) {
2289        mvaddstr_and_log_it(g_currentY++, 74, "Failed.");
2290    } else {
2291        mvaddstr_and_log_it(g_currentY++, 74, "Done.");
2292    }
2293    if (retval) {
2294        log_to_screen("Unable to unmount some of your partitions.");
2295    } else {
2296        log_to_screen("All partitions were unmounted OK.");
2297    }
2298    free(mountlist);
2299    paranoid_free(command);
2300    paranoid_free(tmp);
2301    return (retval);
2302}
2303
2304/**************************************************************************
2305 *END_UNMOUNT_ALL_DEVICES                                                 *
2306 **************************************************************************/
2307
2308
2309
2310/**
2311 * Extract mondo-restore.cfg and the mountlist from the tape inserted
2312 * to the ./tmp/ directory.
2313 * @param dev The tape device to read from.
2314 * @return 0 for success, nonzero for failure.
2315 */
2316int extract_cfg_file_and_mountlist_from_tape_dev(char *dev)
2317{
2318    char *command;
2319    int res = 0;
2320    // BCO: below 32KB seems to block at least on RHAS 2.1 and MDK 10.0
2321    long tape_block_size = 32768;
2322
2323    malloc_string(command);
2324
2325    // tar -zxvf-
2326    sprintf(command,
2327            "dd if=%s bs=%ld count=%ld 2> /dev/null | tar -zx %s %s %s %s %s",
2328            dev,
2329            tape_block_size,
2330            1024L * 1024 * 32 / tape_block_size,
2331            MOUNTLIST_FNAME_STUB, MONDO_CFG_FILE_STUB,
2332            BIGGIELIST_TXT_STUB, FILELIST_FULL_STUB, "tmp/i-want-my-lvm");
2333    log_msg(2, "command = '%s'", command);
2334    res = run_program_and_log_output(command, -1);
2335    if (res != 0 && does_file_exist(MONDO_CFG_FILE_STUB)) {
2336        res = 0;
2337    }
2338    paranoid_free(command);
2339    return (res);
2340}
2341
2342
2343
2344/**
2345 * Get the configuration file from the floppy, tape, or CD.
2346 * @param bkpinfo The backup information structure. Fields used:
2347 * - @c bkpinfo->backup_media_type
2348 * - @c bkpinfo->media_device
2349 * - @c bkpinfo->tmpdir
2350 * @return 0 for success, nonzero for failure.
2351 */
2352int get_cfg_file_from_archive(struct s_bkpinfo *bkpinfo)
2353{
2354    int retval = 0;
2355
2356   /** malloc *****/
2357    char *device;
2358    char *command;
2359    char *cfg_file;
2360    char *mounted_cfgf_path;
2361    char *tmp;
2362    char *mountpt;
2363    char *ramdisk_fname;
2364    char *mountlist_file;
2365    int res;
2366
2367    bool try_plan_B;
2368
2369    assert(bkpinfo != NULL);
2370    malloc_string(cfg_file);
2371    malloc_string(mounted_cfgf_path);
2372    malloc_string(mountpt);
2373    malloc_string(ramdisk_fname);
2374    malloc_string(mountlist_file);
2375    malloc_string(device);
2376    malloc_string(command);
2377    malloc_string(tmp);
2378    log_msg(2, "gcffa --- starting");
2379    log_to_screen("I'm thinking...");
2380    sprintf(mountpt, "%s/mount.bootdisk", bkpinfo->tmpdir);
2381    device[0] = '\0';
2382    chdir(bkpinfo->tmpdir);
2383    strcpy(cfg_file, MONDO_CFG_FILE_STUB);
2384    unlink(cfg_file);           // cfg_file[] is missing the '/' at the start, FYI, by intent
2385    unlink(FILELIST_FULL_STUB);
2386    unlink(BIGGIELIST_TXT_STUB);
2387    unlink("tmp/i-want-my-lvm");
2388    sprintf(command, "mkdir -p %s", mountpt);
2389    run_program_and_log_output(command, FALSE);
2390
2391//   unlink( "tmp/mondo-restore.cfg" ); // superfluous, surely?
2392
2393    sprintf(cfg_file, "%s/%s", bkpinfo->tmpdir, MONDO_CFG_FILE_STUB);
2394    sprintf(mountlist_file, "%s/%s", bkpinfo->tmpdir,
2395            MOUNTLIST_FNAME_STUB);
2396    //   make_hole_for_file( cfg_file );
2397    //   make_hole_for_file( mountlist_file);
2398    log_msg(2, "mountpt = %s; cfg_file=%s", mountpt, cfg_file);
2399
2400    /* Floppy? */
2401    sprintf(tmp, "mkdir -p %s", mountpt);
2402    run_program_and_log_output(tmp, FALSE);
2403    sprintf(tmp, "mkdir -p %s/tmp", bkpinfo->tmpdir);
2404    run_program_and_log_output(tmp, FALSE);
2405
2406    sprintf(command, "mount /dev/fd0u1722 %s", mountpt);
2407    sprintf(tmp,
2408            "(sleep 15; kill `ps | grep \"%s\" | cut -d' ' -f1` 2> /dev/null) &",
2409            command);
2410    log_msg(1, "tmp = '%s'", tmp);
2411    system(tmp);
2412    res = run_program_and_log_output(command, FALSE);
2413    if (res) {
2414        sprintf(command, "mount /dev/fd0H1440 %s", mountpt);
2415        res = run_program_and_log_output(command, FALSE);
2416    }
2417    if (res) {
2418        try_plan_B = TRUE;
2419    } else {
2420        try_plan_B = TRUE;
2421        log_msg(2,
2422                "Mounted floppy OK but I don't trust it because the archives might contain more up-to-date config file than the floppy does.");
2423// NB: If busybox does not support 'mount -o loop' then Plan A WILL NOT WORK.
2424        log_msg(2, "Processing floppy (plan A?)");
2425        sprintf(ramdisk_fname, "%s/mindi.rdz", mountpt);
2426        if (!does_file_exist(ramdisk_fname)) {
2427            sprintf(ramdisk_fname, "%s/initrd.img", mountpt);
2428        }
2429        if (!does_file_exist(ramdisk_fname)) {
2430            log_msg(2,
2431                    "Cannot find ramdisk file on mountpoint. Are you sure that's a boot disk in the drive?");
2432        }
2433        if (extract_config_file_from_ramdisk
2434            (bkpinfo, ramdisk_fname, cfg_file, mountlist_file)) {
2435            log_msg(2,
2436                    "Warning - failed to extract config file from ramdisk. I think this boot disk is mangled.");
2437        }
2438        sprintf(command, "umount %s", mountpt);
2439        run_program_and_log_output(command, 5);
2440        unlink(ramdisk_fname);
2441    }
2442    if (!does_file_exist(cfg_file)) {
2443        log_msg(2, "gcffa --- we don't have cfg file yet.");
2444        if (IS_THIS_A_STREAMING_BACKUP(bkpinfo->backup_media_type)) {
2445            try_plan_B = TRUE;
2446        } else {
2447            log_msg(2, "gcffa --- calling mount_cdrom now :)");
2448            if (!mount_cdrom(bkpinfo)) {
2449                log_msg(2,
2450                        "gcffa --- managed to mount CD; so, no need for Plan B");
2451                try_plan_B = FALSE;
2452            } else {
2453                try_plan_B = TRUE;
2454            }
2455            if (what_number_cd_is_this(bkpinfo) > 1) {
2456                insist_on_this_cd_number(bkpinfo,
2457                                         (g_current_media_number = 1));
2458            }
2459        }
2460        if (try_plan_B) {
2461            log_msg(2, "gcffa --- OK, switching to Plan B");
2462            chdir(bkpinfo->tmpdir);
2463            run_program_and_log_output("mkdir -p tmp", FALSE);
2464
2465            if (strlen(bkpinfo->media_device) == 0) {
2466                strcpy(bkpinfo->media_device, "/dev/st0");
2467                log_msg(2, "media_device is blank; assuming %s");
2468            }
2469            strcpy(tmp, bkpinfo->media_device);
2470            if (extract_cfg_file_and_mountlist_from_tape_dev
2471                (bkpinfo->media_device)) {
2472                strcpy(bkpinfo->media_device, "/dev/st0");
2473                if (extract_cfg_file_and_mountlist_from_tape_dev
2474                    (bkpinfo->media_device)) {
2475                    strcpy(bkpinfo->media_device, "/dev/osst0");
2476                    if (extract_cfg_file_and_mountlist_from_tape_dev
2477                        (bkpinfo->media_device)) {
2478                        strcpy(bkpinfo->media_device, "/dev/ht0");
2479                        if (extract_cfg_file_and_mountlist_from_tape_dev
2480                            (bkpinfo->media_device)) {
2481                            log_msg(3,
2482                                    "I tried lots of devices but none worked.");
2483                            strcpy(bkpinfo->media_device, tmp);
2484                        }
2485                    }
2486                }
2487            }
2488
2489            if (!does_file_exist("tmp/mondo-restore.cfg")) {
2490                log_to_screen("Cannot find config info on tape/CD/floppy");
2491                return (1);
2492            }
2493        } else {
2494            log_msg(2,
2495                    "gcffa --- looking at mounted CD for mindi-boot.2880.img");
2496            sprintf(command,
2497                    "mount " MNT_CDROM
2498                    "/images/mindi-boot.2880.img -o loop %s", mountpt);
2499            sprintf(mounted_cfgf_path, "%s/%s", mountpt, cfg_file);
2500            if (!does_file_exist(mounted_cfgf_path)) {
2501                log_msg(2,
2502                        "gcffa --- Plan C, a.k.a. untarring some file from all.tar.gz");
2503                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
2504                run_program_and_log_output(command, TRUE);
2505                if (!does_file_exist(MONDO_CFG_FILE_STUB)) {
2506                    fatal_error
2507                        ("Please reinsert the disk/CD and try again.");
2508                }
2509            }
2510        }
2511    }
2512    if (does_file_exist(MONDO_CFG_FILE_STUB)) {
2513        log_msg(1, "gcffa --- great! We've got the config file");
2514        sprintf(tmp, "%s/%s",
2515                call_program_and_get_last_line_of_output("pwd"),
2516                MONDO_CFG_FILE_STUB);
2517        sprintf(command, "cp -f %s %s", tmp, cfg_file);
2518        iamhere(command);
2519        if (strcmp(tmp, cfg_file)
2520            && run_program_and_log_output(command, 1)) {
2521            log_msg(1,
2522                    "... but an error occurred when I tried to move it to %s",
2523                    cfg_file);
2524        } else {
2525            log_msg(1, "... and I moved it successfully to %s", cfg_file);
2526        }
2527        sprintf(command, "cp -f %s/%s %s",
2528                call_program_and_get_last_line_of_output("pwd"),
2529                MOUNTLIST_FNAME_STUB, mountlist_file);
2530        iamhere(command);
2531        if (strcmp(tmp, cfg_file)
2532            && run_program_and_log_output(command, 1)) {
2533            log_msg(1, "Failed to get mountlist");
2534        } else {
2535            log_msg(1, "Got mountlist too");
2536            sprintf(command, "cp -f %s %s", mountlist_file,
2537                    g_mountlist_fname);
2538            if (run_program_and_log_output(command, 1)) {
2539                log_msg(1, "Failed to copy mountlist to /tmp");
2540            } else {
2541                log_msg(1, "Copied mountlist to /tmp as well OK");
2542                sprintf(command, "cp -f tmp/i-want-my-lvm /tmp/");
2543                run_program_and_log_output(command, 1);
2544/*        sprintf(command, "grep \" lvm \" %s", g_mountlist_fname);
2545          if (!run_program_and_log_output(command, 5) && !does_file_exist("/tmp/i-want-my-lvm"))
2546            {
2547          log_msg(1, "Warning. You want LVM but I don't have i-want-my-lvm. FIXME.");
2548        }
2549              else if (run_program_and_log_output(command,5) && does_file_exist("/tmp/i-want-my-lvm"))
2550                {
2551          log_msg(1, "Warning. You don't want LVM but i-want-my-lvm exists. I'll delete it. Cool.");
2552              do_my_funky_lvm_stuff(TRUE, FALSE); // ...after I stop any LVMs :)
2553          stop_raid_device("/dev/md0");
2554          stop_raid_device("/dev/md1");
2555          stop_raid_device("/dev/md2");
2556          unlink("/tmp/i-want-my-lvm");
2557        }
2558          else if (!run_program_and_log_output(command,5) && does_file_exist("/tmp/i-want-my-lvm"))
2559            {
2560          log_msg(1, "You had better pray that i-want-my-lvm patches your mountlist. FIXME.");
2561        }
2562*/
2563            }
2564        }
2565    }
2566    run_program_and_log_output("umount " MNT_CDROM, FALSE);
2567    if (!does_file_exist(cfg_file)) {
2568        iamhere(cfg_file);
2569        log_msg(1, "%s not found", cfg_file);
2570        log_to_screen
2571            ("Oh dear. Unable to recover configuration file from boot disk");
2572        return (1);
2573    }
2574
2575    log_to_screen("Recovered mondo-restore.cfg");
2576    if (!does_file_exist(MOUNTLIST_FNAME_STUB)) {
2577        log_to_screen("...but not mountlist.txt - a pity, really...");
2578    }
2579/* start SAH */
2580    else {
2581        sprintf(command, "cp -f %s %s/%s", MOUNTLIST_FNAME_STUB,
2582                bkpinfo->tmpdir, MOUNTLIST_FNAME_STUB);
2583        run_program_and_log_output(command, FALSE);
2584    }
2585/*--commented out by SAH
2586  sprintf( command, "cp -f %s %s/%s", cfg_file, bkpinfo->tmpdir, MONDO_CFG_FILE_STUB );
2587  run_program_and_log_output( command, FALSE );
2588  sprintf( command, "cp -f %s %s/%s", mountlist_file, bkpinfo->tmpdir, MOUNTLIST_FNAME_STUB );
2589  run_program_and_log_output( command, FALSE );
2590*/
2591/* end SAH */
2592
2593    sprintf(command, "cp -f %s /%s", cfg_file, MONDO_CFG_FILE_STUB);
2594    run_program_and_log_output(command, FALSE);
2595    sprintf(command, "cp -f %s /%s", mountlist_file, MOUNTLIST_FNAME_STUB);
2596    run_program_and_log_output(command, FALSE);
2597    sprintf(command, "cp -f etc/raidtab /etc/");
2598    run_program_and_log_output(command, FALSE);
2599    sprintf(command, "cp -f tmp/i-want-my-lvm /tmp/");
2600    run_program_and_log_output(command, FALSE);
2601    g_backup_media_type = bkpinfo->backup_media_type;
2602    paranoid_free(device);
2603    paranoid_free(command);
2604    paranoid_free(tmp);
2605    paranoid_free(cfg_file);
2606    paranoid_free(mounted_cfgf_path);
2607    paranoid_free(mountpt);
2608    paranoid_free(ramdisk_fname);
2609    paranoid_free(mountlist_file);
2610    return (retval);
2611}
2612
2613/**************************************************************************
2614 *END_GET_CFG_FILE_FROM_ARCHIVE                                           *
2615 **************************************************************************/
2616
2617/* @} - end restoreUtilityGroup */
2618
2619
2620/***************************************************************************
2621 * F@                                                                      *
2622 * () -- Hugo Rabson                                  *
2623 *                                                                         *
2624 * Purpose:                                                                *
2625 *                                                                         *
2626 * Called by:                                                              *
2627 * Params:    -                      -                                     *
2628 * Returns:   0=success; nonzero=failure                                   *
2629 ***************************************************************************/
2630
2631
2632
2633void wait_until_software_raids_are_prepped(char *mdstat_file,
2634                                           int wait_for_percentage)
2635{
2636    struct raidlist_itself *raidlist;
2637    int unfinished_mdstat_devices = 9999, i;
2638    char *screen_message;
2639
2640    malloc_string(screen_message);
2641    raidlist = malloc(sizeof(struct raidlist_itself));
2642
2643    assert(wait_for_percentage <= 100);
2644    iamhere("wait_until_software_raids_are_prepped");
2645    while (unfinished_mdstat_devices > 0) {
2646            // FIXME: Prefix '/dev/' should really be dynamic!
2647        if (parse_mdstat(raidlist, "/dev/")) {
2648            log_to_screen("Sorry, cannot read %s", MDSTAT_FILE);
2649            log_msg(1,"Sorry, cannot read %s", MDSTAT_FILE);
2650            return;
2651        }
2652        for (unfinished_mdstat_devices = i = 0; i <= raidlist->entries; i++) {
2653            if (raidlist->el[i].progress < wait_for_percentage) {
2654                unfinished_mdstat_devices++;
2655                if (raidlist->el[i].progress == -1) // delayed while another partition inits
2656                {
2657                    continue;
2658                }
2659                log_msg(1,"Sync'ing %s (i=%d)", raidlist->el[i].raid_device, i);
2660                sprintf(screen_message, "Sync'ing %s",
2661                        raidlist->el[i].raid_device);
2662                open_evalcall_form(screen_message);
2663                while (raidlist->el[i].progress < wait_for_percentage) {
2664                    log_msg(1,"Percentage sync'ed: %d", raidlist->el[i].progress);
2665                    update_evalcall_form(raidlist->el[i].progress);
2666                    sleep(2);
2667                    // FIXME: Prefix '/dev/' should really be dynamic!
2668                    if (parse_mdstat(raidlist, "/dev/")) {
2669                        break;
2670                    }
2671                }
2672                close_evalcall_form();
2673            }
2674        }
2675    }
2676    paranoid_free(screen_message);
2677    paranoid_free(raidlist);
2678}
Note: See TracBrowser for help on using the repository browser.