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

Last change on this file since 497 was 497, checked in by bcornec, 14 years ago

Integration of a big patch from rene-marc dolhen <rmd_at_mecreant.org> to support internationalization with gettext.

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