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

Last change on this file since 1740 was 1740, checked in by Bruno Cornec, 12 years ago

typo again

  • Property svn:keywords set to Id
File size: 78.2 KB
Line 
1/***************************************************************************
2mondo-rstr-tools.c  -  description
3-----------------
4
5begin: Sun Sep 21 16:40:35 EDT 2003
6copyright : (C) 2002 Mondo  Hugo Rabson
7email     : Hugo Rabson <hugorabson@msn.com>
8edited by : by Stan Benoit ?/2003
9email     : troff@nakedsoul.org
10cvsid     : $Id: mondo-rstr-tools.c
11***************************************************************************/
12
13/***************************************************************************
14*                                                                         *
15*   This program is free software; you can redistribute it and/or modify  *
16*   it under the terms of the GNU General Public License as published by  *
17*   the Free Software Foundation; either version 2 of the License, or     *
18*   (at your option) any later version.                                   *
19*                                                                         *
20***************************************************************************/
21/* mondo-rstr-tools.c               Hugo Rabson
22
23
2407/27
25- if the user is foolish enough to use /dev/md0 as boot device,
26call lilo -M /dev/hda to make sure lilo does its job properly
27- better NFS+nuke support
28
2907/20
30- use backup's i-want-my-lvm file
31- be sure to use archives' raidtab when restoring
32
3307/18
34- use /tmp/isodir for NFS if DR mode
35- better support of users who boot from LVM CD and nuke-restore non-LVM backups
36
3707/12
38- bugfix to allow user to burn ISOs to CDs and restore from CDs (not original src)
39
4006/29
41- mount ext3 partitions as ext2, just in case :)
42
4306/26
44- delete make_relevant_partition_bootable()
45
4606/19
47- futzed with the call to mount floppy, to stop it from locking up on my AMD64 system
48
4906/14
50- shell out to /mnt/RESTORING chroot in order to let user install GRUB
51manually if automatic GRUB installation fails
52
5306/15
54- Added check for different 'isodir' chosen by user than stored in the archive
55Conor Daly <conor.daly@met.ie>
56
5704/17
58- replaced INTERNAL_TAPE_BLK_SIZE with bkpinfo->internal_tape_block_size
59
6004/09
61- don't try to mount CD if tape bkp
62
6304/03
64- trying to copy tmp/mondo-restore.cfg to itself - silly! - fixed
65
6604/02
67- when extracting cfg file and mountlist from all.tar.gz (tape copy),
68use block size of INTERNAL_TAPE_BLK_SIZE, not TAPE_BLOCK_SIZE
69
7002/21
71- don't use 'mv -v' cos Busybox won't support it
72
7302/09
74- make hole for cfg file before moving it (line 2094 or so)
75
7602/03
77- changed a couple of refs to filelist.full, to filelist.full.gz
78
7901/16/2004
80- instead of copying filelist, use 'ln -sf' to link to original;
81saves space
82
8311/20/2003
84- also retrieve /tmp/mountlist.txt if user wants
85
8611/16
87- fixed NFS path bug affecting the extractions of filelist/biggielist
88during selective restore
89
9011/02
91- fixed mount_cdrom() to run properly w/ nfs restores
92- mount_device() returns 0 if swap mount fails cos swap isn't crucial
93
9410/17
95- run_grub() uses MNT_RESTORING instead of "/mnt/RESTORING"
96
9710/26
98- cleaned up run_grub()
99
10010/25
101- fixed mount_cdrom() to run properly w/ nfs restores
102
10310/21
104- mount_device() returns 0 if swap mount fails cos swap isn't crucial
105
10610/15
107- run_grub() now uses its initiative instead
108of calling grub-install
109
11010/10
111- don't leave copies of filelist.full lying around, clogging up
112the ramdisk, there's a good fellow :-)
113
11410/02
115- added 'dvd' to the range of media types I'll understand
116- fixed iso->cdr problem (thanks, Stan Benoit & Fred Beondo)
117
11809/24
119- try lots of tape devs if /dev/st0 fails
120
12109/23/2003
122- first incarnation
123*/
124
125
126#include <pthread.h>
127#include "../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
157
158extern t_bkptype g_backup_media_type;
159
160extern int g_partition_table_locked_up;
161extern char *MONDO_LOGFILE;
162
163/* Reference to global bkpinfo */
164extern struct s_bkpinfo *bkpinfo;
165
166/* Should we use or not extended attributes and acl when restoring */
167char *g_getfattr = NULL;
168char *g_getfacl = NULL;
169
170/**
171* @addtogroup restoreUtilityGroup
172* @{
173*/
174/**
175* Free the malloc()s for the filename variables.
176*/
177void free_MR_global_filenames()
178{
179paranoid_free(g_biggielist_txt);
180paranoid_free(g_filelist_full);
181paranoid_free(g_filelist_imagedevs);
182//  paranoid_free (g_imagedevs_pot );
183paranoid_free(g_imagedevs_restthese);
184paranoid_free(g_mondo_cfg_file);
185paranoid_free(g_mountlist_fname);
186paranoid_free(g_mondo_home);
187paranoid_free(g_tmpfs_mountpt);
188paranoid_free(g_isodir_device);
189paranoid_free(g_isodir_format);
190
191}
192
193
194
195/**
196* Ask the user which imagedevs from the list contained in @p infname should
197* actually be restored.
198* @param infname The file containing a list of all imagedevs.
199* @param outfname The location of the output file containing the imagedevs the user wanted to restore.
200* @ingroup restoreUtilityGroup
201*/
202void ask_about_these_imagedevs(char *infname, char *outfname)
203{
204FILE *fin;
205FILE *fout;
206/************************************************************************
207* allocate memory regions. test and set  -sab 16 feb 2003              *
208************************************************************************/
209char *incoming_ptr;
210char *question_ptr;
211
212char incoming[MAX_STR_LEN] = "\0";
213char question[MAX_STR_LEN];
214
215assert_string_is_neither_NULL_nor_zerolength(infname);
216assert_string_is_neither_NULL_nor_zerolength(outfname);
217
218incoming_ptr = malloc(sizeof(incoming));
219if (incoming_ptr == NULL) {
220fprintf(stderr, "Out of Memory\n");
221exit(EXIT_FAILURE);
222}
223
224question_ptr = malloc(sizeof(question));
225if (question_ptr == NULL) {
226fprintf(stderr, "Out of Memory\n");
227exit(EXIT_FAILURE);
228}
229
230memset(incoming_ptr, '\0', sizeof(incoming));
231memset(question_ptr, '\0', sizeof(question));
232
233
234
235if (!(fin = fopen(infname, "r"))) {
236fatal_error("Cannot openin infname");
237}
238if (!(fout = fopen(outfname, "w"))) {
239fatal_error("Cannot openin outfname");
240}
241for (fgets(incoming_ptr, MAX_STR_LEN, fin);
242 !feof(fin); fgets(incoming_ptr, MAX_STR_LEN, fin)) {
243strip_spaces(incoming_ptr);
244
245if (incoming[0] == '\0') {
246    continue;
247}
248
249sprintf(question_ptr,
250        "Should I restore the image of %s ?", incoming_ptr);
251
252if (ask_me_yes_or_no(question_ptr)) {
253    fprintf(fout, "%s\n", incoming_ptr);
254}
255}
256
257/*** free memory ***********/
258paranoid_free(incoming_ptr);
259incoming_ptr = NULL;
260paranoid_free(question_ptr);
261question_ptr = NULL;
262
263
264paranoid_fclose(fout);
265paranoid_fclose(fin);
266}
267
268/**************************************************************************
269*ASK_ABOUT_THESE_IMAGEDEVS                                               *
270**************************************************************************/
271
272
273
274
275
276
277
278
279/**
280* Extract @c mondo-restore.cfg and @c mountlist.txt from @p ramdisk_fname.
281* @param bkpinfo The backup information structure. @c tmpdir is the only field used.
282* @param ramdisk_fname The filename of the @b compressed ramdisk to look in.
283* @param output_cfg_file Where to put the configuration file extracted.
284* @param output_mountlist_file Where to put the mountlist file extracted.
285* @return 0 for success, nonzero for failure.
286* @ingroup restoreUtilityGroup
287*/
288int
289extract_config_file_from_ramdisk(char *ramdisk_fname,
290                         char *output_cfg_file,
291                         char *output_mountlist_file)
292{
293char *mountpt;
294char *command;
295char *orig_fname;
296int retval = 0;
297
298assert(bkpinfo != NULL);
299malloc_string(mountpt);
300malloc_string(command);
301malloc_string(orig_fname);
302assert_string_is_neither_NULL_nor_zerolength(ramdisk_fname);
303assert_string_is_neither_NULL_nor_zerolength(output_cfg_file);
304assert_string_is_neither_NULL_nor_zerolength(output_mountlist_file);
305sprintf(mountpt, "%s/mount.bootdisk", bkpinfo->tmpdir);
306sprintf(command, "mkdir -p %s", mountpt);
307run_program_and_log_output(command, FALSE);
308sprintf(command, "gzip -dc %s > %s/mindi.rd 2> /dev/null",
309    ramdisk_fname, bkpinfo->tmpdir);
310
311run_program_and_log_output(command, FALSE);
312sprintf(command, "umount %s", mountpt);
313
314run_program_and_log_output(command, FALSE);
315
316sprintf(command, "mount -o loop %s/mindi.rd -t ext2 %s",
317    bkpinfo->tmpdir, mountpt);
318
319run_program_and_log_output(command, FALSE);
320
321sprintf(command, "mkdir -p %s/tmp", bkpinfo->tmpdir);
322
323run_program_and_log_output(command, FALSE);
324
325sprintf(command, "cp -f %s/%s %s",  // %s/%s becomes {mountpt}/tmp/m*ndo-restore.cfg
326    mountpt, g_mondo_cfg_file, output_cfg_file);
327run_program_and_log_output(command, FALSE);
328
329sprintf(orig_fname, "%s/%s", mountpt, g_mountlist_fname);
330if (does_file_exist(orig_fname)) {
331sprintf(command, "cp -f %s %s", orig_fname, output_mountlist_file);
332run_program_and_log_output(command, FALSE);
333}
334sprintf(command, "umount %s", mountpt);
335run_program_and_log_output(command, FALSE);
336if (!does_file_exist(output_cfg_file)
337|| (!does_file_exist(output_mountlist_file)
338    && does_file_exist(orig_fname))) {
339log_msg(2, "Failed to extract %s and/or %s from ramdisk",
340        output_cfg_file, output_mountlist_file);
341retval = 1;
342} else {
343retval = 0;
344}
345paranoid_free(mountpt);
346paranoid_free(command);
347paranoid_free(orig_fname);
348return (retval);
349
350}
351
352
353
354
355/**
356* Keep trying to get mondo-restore.cfg from the archive, until the user gives up.
357*/
358void get_cfg_file_from_archive_or_bust()
359{
360while (get_cfg_file_from_archive()) {
361if (!ask_me_yes_or_no
362    ("Failed to find config file/archives. Choose another source?"))
363{
364    fatal_error("Could not find config file/archives. Aborting.");
365}
366interactively_obtain_media_parameters_from_user(FALSE);
367}
368}
369
370
371/**
372* Determine whether @p list_fname contains a line containing @p f.
373* @param f The line to search for.
374* @param list_fname The file to search in.
375* @param preamble Ignore this beginning part of @p f ("" to disable).
376* @return TRUE if it's in the list, FALSE if it's not.
377*/
378bool is_file_in_list(char *f, char *list_fname, char *preamble)
379{
380
381/** needs malloc **/
382char *command;
383char *file;
384char *tmp;
385int res;
386
387malloc_string(command);
388malloc_string(file);
389malloc_string(tmp);
390assert_string_is_neither_NULL_nor_zerolength(f);
391assert_string_is_neither_NULL_nor_zerolength(list_fname);
392assert(preamble != NULL);
393
394if (strncmp(preamble, f, strlen(preamble)) == 0) {
395strcpy(file, f + strlen(preamble));
396} else {
397strcpy(file, f);
398}
399if (file[0] == '/' && file[1] == '/') {
400strcpy(tmp, file);
401strcpy(file, tmp + 1);
402}
403sprintf(tmp,
404    "Checking to see if f=%s, file=%s, is in the list of biggiefiles",
405    f, file);
406log_msg(2, tmp);
407sprintf(command, "grep -E '^%s$' %s", file, list_fname);
408res = run_program_and_log_output(command, FALSE);
409paranoid_free(command);
410paranoid_free(file);
411paranoid_free(tmp);
412if (res) {
413return (FALSE);
414} else {
415return (TRUE);
416}
417}
418
419/**************************************************************************
420*END_IS_FILE_IN_LIST                                                     *
421**************************************************************************/
422
423
424
425/**
426* Set up an ISO backup.
427* @param bkpinfo The backup information structure. Fields used:
428* - @c bkpinfo->backup_media_type
429* - @c bkpinfo->disaster_recovery
430* - @c bkpinfo->isodir
431* @param nuke_me_please If TRUE, we're in nuke mode; if FALSE we're in interactive mode.
432* @return 0 for success, nonzero for failure.
433*/
434int iso_fiddly_bits(bool nuke_me_please)
435{
436char *mount_isodir_command, *tmp, *command;
437int retval = 0, i;
438bool already_mounted = FALSE;
439
440assert(bkpinfo != NULL);
441malloc_string(mount_isodir_command);
442malloc_string(tmp);
443malloc_string(command);
444g_ISO_restore_mode = TRUE;
445read_cfg_var(g_mondo_cfg_file, "iso-dev", g_isodir_device);
446if (bkpinfo->disaster_recovery) {
447/* Patch Conor Daly 26-june-2004
448* Don't let this clobber an existing bkpinfo->isodir */
449if (!bkpinfo->isodir[0]) {
450    strcpy(bkpinfo->isodir, "/tmp/isodir");
451}
452/* End patch */
453sprintf(command, "mkdir -p %s", bkpinfo->isodir);
454run_program_and_log_output(command, 5);
455log_msg(2, "Setting isodir to %s", bkpinfo->isodir);
456}
457
458if (!get_isodir_info
459(g_isodir_device, g_isodir_format, bkpinfo->isodir,
460 nuke_me_please)) {
461return (1);
462}
463paranoid_system("umount " MNT_CDROM " 2> /dev/null");   /* just in case */
464
465if (is_this_device_mounted(g_isodir_device)) {
466log_to_screen("WARNING - isodir is already mounted");
467already_mounted = TRUE;
468} else {
469sprintf(mount_isodir_command, "mount %s", g_isodir_device);
470if (strlen(g_isodir_format) > 1) {
471    sprintf(mount_isodir_command + strlen(mount_isodir_command),
472            " -t %s", g_isodir_format);
473}
474strcat(mount_isodir_command, " -o ro ");
475strcat(mount_isodir_command, bkpinfo->isodir);
476run_program_and_log_output("df -m", FALSE);
477sprintf(tmp,
478        "The 'mount' command is '%s'. PLEASE report this command to be if you have problems, ok?",
479        mount_isodir_command);
480log_msg(1, tmp);
481if (run_program_and_log_output(mount_isodir_command, FALSE)) {
482    popup_and_OK
483        ("Cannot mount the device where the ISO files are stored.");
484    return (1);
485}
486log_to_screen
487    ("I have mounted the device where the ISO files are stored.");
488}
489if (!IS_THIS_A_STREAMING_BACKUP(bkpinfo->backup_media_type)) {
490    mount_media();
491}
492i = what_number_cd_is_this();   /* has the side-effect of calling mount_media() */
493sprintf(tmp, "%s #%d has been mounted via loopback mount",
494    media_descriptor_string(bkpinfo->backup_media_type), i);
495log_msg(1, tmp);
496if (i < 0) {
497popup_and_OK
498    ("Cannot find ISO images in the directory you specified.");
499retval = 1;
500}
501log_msg(2, "%ld: bkpinfo->isodir is now %s", __LINE__,
502    bkpinfo->isodir);
503paranoid_free(mount_isodir_command);
504paranoid_free(tmp);
505paranoid_free(command);
506return (retval);
507}
508
509
510
511
512/**
513* Kill all Petris processes.
514*/
515void kill_petris(void)
516{
517char *command;
518malloc_string(command);
519sprintf(command,
520    "kill `ps 2> /dev/null | grep petris 2> /dev/null | grep -v grep | cut -d' ' -f2` 2> /dev/null");
521paranoid_system(command);
522paranoid_free(command);
523}
524
525/**************************************************************************
526*END_KILL_PETRIS                                                         *
527**************************************************************************/
528
529
530/**
531* Mount all devices in @p p_external_copy_of_mountlist on @p MNT_RESTORING.
532* @param p_external_copy_of_mountlist The mountlist containing devices to be mounted.
533* @param writeable If TRUE, then mount read-write; if FALSE mount read-only.
534* @return The number of errors encountered (0 for success).
535*/
536int mount_all_devices(struct mountlist_itself
537              *p_external_copy_of_mountlist, bool writeable)
538{
539int retval = 0, lino, res;
540char *tmp, *these_failed, *format;
541struct mountlist_itself *mountlist;
542
543malloc_string(tmp);
544malloc_string(format);
545malloc_string(these_failed);
546assert(p_external_copy_of_mountlist != NULL);
547mountlist = malloc(sizeof(struct mountlist_itself));
548memcpy((void *) mountlist, (void *) p_external_copy_of_mountlist,
549   sizeof(struct mountlist_itself));
550sort_mountlist_by_mountpoint(mountlist, 0);
551
552/** menset **/
553these_failed[0] = '\0';
554
555mvaddstr_and_log_it(g_currentY, 0, "Mounting devices         ");
556open_progress_form("Mounting devices",
557               "I am now mounting all the drives.",
558               "This should not take long.",
559               "", mountlist->entries);
560
561for (lino = 0; lino < mountlist->entries; lino++) {
562if (!strcmp(mountlist->el[lino].device, "/proc")) {
563    log_msg(1,
564            "Again with the /proc - why is this in your mountlist?");
565} else if (is_this_device_mounted(mountlist->el[lino].device)) {
566    sprintf(tmp, "%s is already mounted",
567            mountlist->el[lino].device);
568    log_to_screen(tmp);
569} else if (strcmp(mountlist->el[lino].mountpoint, "none")
570           && strcmp(mountlist->el[lino].mountpoint, "lvm")
571           && strcmp(mountlist->el[lino].mountpoint, "raid")
572           && strcmp(mountlist->el[lino].mountpoint, "image")) {
573    sprintf(tmp, "Mounting %s", mountlist->el[lino].device);
574    update_progress_form(tmp);
575    strcpy(format, mountlist->el[lino].format);
576    if (!strcmp(format, "ext3")) {
577        strcpy(format, "ext2");
578    }
579    res = mount_device(mountlist->el[lino].device,
580                       mountlist->el[lino].mountpoint,
581                       format, writeable);
582    retval += res;
583    if (res) {
584        strcat(these_failed, mountlist->el[lino].device);
585        strcat(these_failed, " ");
586    }
587}
588g_current_progress++;
589}
590close_progress_form();
591run_program_and_log_output("df -m", TRUE);
592if (retval) {
593if (g_partition_table_locked_up > 0) {
594    log_to_screen
595        ("fdisk's ictol() call to refresh its copy of the partition table causes the kernel to");
596    log_to_screen
597        ("lock up the partition table. You might have to reboot and use Interactive Mode to");
598    log_to_screen
599        ("format and restore *without* partitioning first. Sorry for the inconvenience.");
600}
601sprintf(tmp, "Could not mount device(s) %s- shall I abort?",
602        these_failed);
603if (!ask_me_yes_or_no(tmp)) {
604    retval = 0;
605    log_to_screen
606        ("Continuing, although some device(s) failed to be mounted");
607    mvaddstr_and_log_it(g_currentY++, 74, "Done.");
608} else {
609    mvaddstr_and_log_it(g_currentY++, 74, "Failed.");
610    log_to_screen
611        ("Unable to mount some or all of your partitions.");
612}
613} else {
614log_to_screen("All partitions were mounted OK.");
615mvaddstr_and_log_it(g_currentY++, 74, "Done.");
616}
617run_program_and_log_output("df -m", 3);
618paranoid_free(mountlist);
619paranoid_free(tmp);
620paranoid_free(format);
621paranoid_free(these_failed);
622return (retval);
623}
624
625/**************************************************************************
626*END_MOUNT_ALL_DEVICES                                                   *
627**************************************************************************/
628
629
630/**
631* Mount the CD-ROM or USB device at /mnt/cdrom.
632* @param bkpinfo The backup information structure. Fields used:
633* - @c bkpinfo->backup_media_type
634* - @c bkpinfo->disaster_recovery
635* - @c bkpinfo->isodir
636* - @c bkpinfo->media_device
637* @return 0 for success, nonzero for failure.
638*/
639int mount_media()
640{
641char *mount_cmd;
642int i, res;
643#ifdef __FreeBSD__
644char mdd[32];
645char *mddev = mdd;
646#endif
647
648malloc_string(mount_cmd);
649assert(bkpinfo != NULL);
650
651if (bkpinfo->backup_media_type == tape
652    || bkpinfo->backup_media_type == udev) {
653    log_msg(8, "Tape/udev. Therefore, no need to mount a media.");
654    paranoid_free(mount_cmd);
655    return 0;
656}
657
658if (!run_program_and_log_output("mount | grep -F " MNT_CDROM, FALSE)) {
659    log_msg(2, "mount_media() - media already mounted. Fair enough.");
660    paranoid_free(mount_cmd);
661    return (0);
662}
663
664if (bkpinfo->backup_media_type == nfs) {
665    log_msg(2, "Mounting for NFS thingy");
666    log_msg(2, "isodir = %s", bkpinfo->isodir);
667    if ((!bkpinfo->isodir[0] || !strcmp(bkpinfo->isodir, "/"))
668        && am_I_in_disaster_recovery_mode()) {
669        strcpy(bkpinfo->isodir, "/tmp/isodir");
670        log_msg(1, "isodir is being set to %s", bkpinfo->isodir);
671    }
672#ifdef __FreeBSD__
673    sprintf(mount_cmd, "/mnt/isodir/%s/%s/%s-%d.iso", bkpinfo->isodir,
674        bkpinfo->nfs_remote_dir, bkpinfo->prefix, g_current_media_number);
675    mddev = make_vn(mount_cmd);
676    sprintf(mount_cmd, "mount_cd9660 -r %s " MNT_CDROM, mddev);
677#else
678    sprintf(mount_cmd, "mount %s/%s/%s-%d.iso -t iso9660 -o loop,ro %s",
679        bkpinfo->isodir, bkpinfo->nfs_remote_dir,
680        bkpinfo->prefix, g_current_media_number, MNT_CDROM);
681#endif
682
683} else if (bkpinfo->backup_media_type == iso) {
684#ifdef __FreeBSD__
685    sprintf(mount_cmd, "%s/%s-%d.iso", bkpinfo->isodir,
686        bkpinfo->prefix, g_current_media_number);
687    mddev = make_vn(mount_cmd);
688    sprintf(mount_cmd, "mount_cd9660 -r %s %s", mddev, MNT_CDROM);
689#else
690    sprintf(mount_cmd, "mount %s/%s-%d.iso -t iso9660 -o loop,ro %s",
691        bkpinfo->isodir, bkpinfo->prefix, g_current_media_number, MNT_CDROM);
692#endif
693} else if (bkpinfo->backup_media_type == usb) {
694        sprintf(mount_cmd, "mount -r %s %s", bkpinfo->media_device, MNT_CDROM);
695} else if (strstr(bkpinfo->media_device, "/dev/")) {
696#ifdef __FreeBSD__
697        sprintf(mount_cmd, "mount_cd9660 -r %s %s", bkpinfo->media_device,
698        MNT_CDROM);
699#else
700        sprintf(mount_cmd, "mount %s -t iso9660 -o ro %s",
701        bkpinfo->media_device, MNT_CDROM);
702#endif
703} else {
704    if (bkpinfo->disaster_recovery
705        && does_file_exist("/tmp/CDROM-LIVES-HERE")) {
706        strcpy(bkpinfo->media_device,
707            last_line_of_file("/tmp/CDROM-LIVES-HERE"));
708    } else {
709        find_cdrom_device(bkpinfo->media_device, TRUE);
710    }
711
712#ifdef __FreeBSD__
713    sprintf(mount_cmd, "mount_cd9660 -r %s %s", bkpinfo->media_device,
714        MNT_CDROM);
715#else
716    sprintf(mount_cmd, "mount %s -t iso9660 -o ro %s",
717        bkpinfo->media_device, MNT_CDROM);
718#endif
719}
720
721log_msg(2, "(mount_media) --- command = %s", mount_cmd);
722for (i = 0; i < 2; i++) {
723res = run_program_and_log_output(mount_cmd, FALSE);
724if (!res) {
725    break;
726} else {
727    log_msg(2, "Failed to mount device.");
728    sleep(5);
729    run_program_and_log_output("sync", FALSE);
730}
731}
732if (res) {
733    log_msg(2, "Failed, despite %d attempts", i);
734} else {
735    log_msg(2, "Mounted CD-ROM drive OK");
736}
737paranoid_free(mount_cmd);
738return (res);
739}
740
741
742
743
744
745/**************************************************************************
746*END_MOUNT_CDROM                                                         *
747**************************************************************************/
748
749
750/**
751* Mount @p device at @p mpt as @p format.
752* @param device The device (/dev entry) to mount.
753* @param mpt The directory to mount it on.
754* @param format The filesystem type of @p device.
755* @param writeable If TRUE, mount read-write; if FALSE, mount read-only.
756* @return 0 for success, nonzero for failure.
757*/
758int mount_device(char *device, char *mpt, char *format, bool writeable)
759{
760int res = 0;
761
762/** malloc **/
763char *tmp, *command, *mountdir, *mountpoint, *additional_parameters;
764
765assert_string_is_neither_NULL_nor_zerolength(device);
766assert_string_is_neither_NULL_nor_zerolength(mpt);
767assert(format != NULL);
768malloc_string(tmp);
769malloc_string(command);
770malloc_string(mountdir);
771malloc_string(mountpoint);
772malloc_string(additional_parameters);
773
774if (!strcmp(mpt, "/1")) {
775    strcpy(mountpoint, "/");
776    log_msg(3, "Mommm! SME is being a dildo!");
777} else {
778    strcpy(mountpoint, mpt);
779}
780
781if (!strcmp(mountpoint, "lvm")) {
782    return (0);
783}
784if (!strcmp(mountpoint, "image")) {
785    return (0);
786}
787sprintf(tmp, "Mounting device %s   ", device);
788log_msg(1, tmp);
789if (writeable) {
790    strcpy(additional_parameters, "-o rw");
791} else {
792    strcpy(additional_parameters, "-o ro");
793}
794if (find_home_of_exe("setfattr")) {
795    strcat(additional_parameters, ",user_xattr");
796}
797if (find_home_of_exe("setfacl")) {
798    strcat(additional_parameters, ",acl");
799}
800
801if (!strcmp(mountpoint, "swap")) {
802    sprintf(command, "swapon %s", device);
803} else {
804if (!strcmp(mountpoint, "/")) {
805    strcpy(mountdir, MNT_RESTORING);
806} else {
807    sprintf(mountdir, "%s%s", MNT_RESTORING, mountpoint);
808}
809sprintf(command, "mkdir -p %s", mountdir);
810run_program_and_log_output(command, FALSE);
811sprintf(command, "mount -t %s %s %s %s 2>> %s", format, device,
812        additional_parameters, mountdir, MONDO_LOGFILE);
813log_msg(2, "command='%s'", command);
814}
815res = run_program_and_log_output(command, TRUE);
816if (res && (strstr(command, "xattr") || strstr(command, "acl"))) {
817    log_msg(1, "Re-trying without the fancy extra parameters");
818    sprintf(command, "mount -t %s %s %s 2>> %s", format, device,
819        mountdir, MONDO_LOGFILE);
820    res = run_program_and_log_output(command, TRUE);
821}
822if (res) {
823    log_msg(1, "Unable to mount device %s (type %s) at %s", device,
824        format, mountdir);
825    log_msg(1, "command was '%s'", command);
826    if (!strcmp(mountpoint, "swap")) {
827        log_to_screen(tmp);
828    } else {
829        log_msg(2, "Retrying w/o the '-t' switch");
830        sprintf(command, "mount %s %s 2>> %s", device, mountdir,
831            MONDO_LOGFILE);
832        log_msg(2, "2nd command = '%s'", command);
833        res = run_program_and_log_output(command, TRUE);
834        if (res == 0) {
835            log_msg(1,
836                "That's OK. I called mount w/o a filesystem type and it worked fine in the end.");
837        } else {
838            log_to_screen(tmp);
839        }
840    }
841}
842if (res && !strcmp(mountpoint, "swap")) {
843    log_msg(2, "That's ok. It's just a swap partition.");
844    log_msg(2, "Non-fatal error. Returning 0.");
845    res = 0;
846}
847
848paranoid_free(tmp);
849paranoid_free(command);
850paranoid_free(mountdir);
851paranoid_free(mountpoint);
852paranoid_free(additional_parameters);
853
854return (res);
855}
856
857/**************************************************************************
858*END_MOUNT_DEVICE                                                        *
859**************************************************************************/
860
861
862
863/**
864* Fix some miscellaneous things in the filesystem so the system will come
865* up correctly on the first boot.
866*/
867void protect_against_braindead_sysadmins()
868{
869run_program_and_log_output("touch " MNT_RESTORING "/var/log/pacct",
870                       FALSE);
871run_program_and_log_output("touch " MNT_RESTORING "/var/account/pacct",
872                       FALSE);
873if (run_program_and_log_output("ls " MNT_RESTORING " /tmp", FALSE)) {
874run_program_and_log_output("chmod 1777 " MNT_RESTORING "/tmp",
875                           FALSE);
876}
877run_program_and_log_output("mkdir -p " MNT_RESTORING
878                       "/var/run/console", FALSE);
879run_program_and_log_output("chmod 777 " MNT_RESTORING "/dev/null",
880                       FALSE);
881run_program_and_log_output("cd " MNT_RESTORING
882                       "; for i in `ls home/`; do echo \"Moving $i's spurious files to $i/.disabled\"; mkdir \"$i\"/.disabled ; mv -f \"$i\"/.DCOP* \"$i\"/.MCOP* \"$i\"/.*authority \"$i\"/.kde/tmp* \"$i\"/.kde/socket* \"$i\"/.disabled/ ; done",
883                       TRUE);
884run_program_and_log_output("rm -f " MNT_RESTORING "/var/run/*.pid",
885                       TRUE);
886run_program_and_log_output("rm -f " MNT_RESTORING "/var/lock/subsys/*",
887                       TRUE);
888}
889
890/**************************************************************************
891*END_PROTECT_AGAINST_BRAINDEAD_SYSADMINS                                 *
892**************************************************************************/
893
894
895
896
897/**
898* Fill out @p bkpinfo based on @p cfg_file.
899* @param cfg_file The mondo-restore.cfg file to read into @p bkpinfo.
900* @param bkpinfo The backup information structure to fill out with information
901* from @p cfg_file.
902* @return 0 for success, nonzero for failure.
903*/
904int read_cfg_file_into_bkpinfo(char *cfgf)
905{
906/** add mallocs **/
907char *value = NULL;
908char *tmp = NULL;
909char *envtmp1 = NULL;
910char *envtmp2 = NULL;
911char *command = NULL;
912char *iso_mnt = NULL;
913char *iso_path = NULL;
914char *old_isodir = NULL;
915char cfg_file[100];
916t_bkptype media_specified_by_user;
917
918malloc_string(command);
919malloc_string(iso_mnt);
920malloc_string(iso_path);
921malloc_string(old_isodir);
922malloc_string(value);
923malloc_string(tmp);
924//  assert_string_is_neither_NULL_nor_zerolength(cfg_file);
925assert(bkpinfo != NULL);
926
927if (!cfgf) {
928strcpy(cfg_file, g_mondo_cfg_file);
929} else {
930strcpy(cfg_file, cfgf);
931}
932
933media_specified_by_user = bkpinfo->backup_media_type;   // or 'none', if not specified
934
935if (0 == read_cfg_var(cfg_file, "backup-media-type", value)) {
936if (!strcmp(value, "cdstream")) {
937    bkpinfo->backup_media_type = cdstream;
938} else if (!strcmp(value, "cdr")) {
939    bkpinfo->backup_media_type = cdr;
940} else if (!strcmp(value, "cdrw")) {
941    bkpinfo->backup_media_type = cdrw;
942} else if (!strcmp(value, "dvd")) {
943    bkpinfo->backup_media_type = dvd;
944} else if (!strcmp(value, "usb")) {
945    bkpinfo->backup_media_type = usb;
946} else if (!strcmp(value, "iso")) {
947/*
948if (am_I_in_disaster_recovery_mode()
949&& !run_program_and_log_output("mount /dev/cdrom "MNT_CDROM, 1)
950&& does_file_exist(MNT_CDROM"/archives/filelist.0"))
951*/
952
953// Patch by Conor Daly - 2004/07/12
954    bkpinfo->backup_media_type = iso;
955    if (am_I_in_disaster_recovery_mode()) {
956        /* Check to see if CD is already mounted before mounting it... */
957        if (!is_this_device_mounted("/dev/cdrom")) {
958            log_msg(2,
959                    "NB: CDROM device not mounted, mounting...");
960            run_program_and_log_output("mount /dev/cdrom "
961                                       MNT_CDROM, 1);
962        }
963        if (does_file_exist(MNT_CDROM "/archives/filelist.0")) {
964            bkpinfo->backup_media_type = cdr;
965            run_program_and_log_output("umount " MNT_CDROM, 1);
966            log_it
967                ("Re-jigging configuration AGAIN. CD-R, not ISO.");
968        }
969    }
970    if (read_cfg_var(cfg_file, "iso-prefix", value) == 0) {
971            strcpy(bkpinfo->prefix,value);
972    } else {
973            strcpy(bkpinfo->prefix,STD_PREFIX);
974    }
975} else if (!strcmp(value, "nfs")) {
976    bkpinfo->backup_media_type = nfs;
977    if (read_cfg_var(cfg_file, "iso-prefix", value) == 0) {
978            strcpy(bkpinfo->prefix,value);
979    } else {
980            strcpy(bkpinfo->prefix,STD_PREFIX);
981    }
982    if (strstr(call_program_and_get_last_line_of_output
983       ("cat /proc/cmdline"), "pxe")) {
984        /* We need to override prefix value in PXE mode as it's
985        * already done in start-nfs */
986        envtmp1 = getenv("imgname");
987        if (envtmp1 == NULL) {
988            fatal_error("no imgname variable in environment");
989        }
990        strcpy(bkpinfo->prefix,envtmp1);
991    }
992
993} else if (!strcmp(value, "tape")) {
994    bkpinfo->backup_media_type = tape;
995} else if (!strcmp(value, "udev")) {
996    bkpinfo->backup_media_type = udev;
997} else {
998    fatal_error("UNKNOWN bkp-media-type");
999}
1000} else {
1001fatal_error("backup-media-type not specified!");
1002}
1003if (bkpinfo->disaster_recovery) {
1004    if (bkpinfo->backup_media_type == cdstream) {
1005        sprintf(bkpinfo->media_device, "/dev/cdrom");
1006//          bkpinfo->media_size[0] = -1;
1007        bkpinfo->media_size[0] = 1999 * 1024;
1008        bkpinfo->media_size[1] = 650;   /* good guess */
1009    } else if (bkpinfo->backup_media_type == usb) {
1010        if (read_cfg_var(cfg_file, "usb-dev", value)) {
1011            fatal_error("Cannot get USB device name from cfg file");
1012        }
1013        strcpy(bkpinfo->media_device, value);
1014        sprintf(tmp, "Backup medium is USB --- dev=%s", bkpinfo->media_device);
1015        log_msg(2, tmp);
1016    } else if (bkpinfo->backup_media_type == tape
1017            || bkpinfo->backup_media_type == udev) {
1018        if (read_cfg_var(cfg_file, "media-dev", value)) {
1019            fatal_error("Cannot get tape device name from cfg file");
1020        }
1021        strcpy(bkpinfo->media_device, value);
1022        read_cfg_var(cfg_file, "media-size", value);
1023        bkpinfo->media_size[1] = atol(value);
1024        sprintf(tmp, "Backup medium is TAPE --- dev=%s",
1025                bkpinfo->media_device);
1026        log_msg(2, tmp);
1027    } else {
1028        strcpy(bkpinfo->media_device, "/dev/cdrom");    /* we don't really need this var */
1029        bkpinfo->media_size[0] = 1999 * 1024;   /* 650, probably, but we don't need this var anyway */
1030        bkpinfo->media_size[1] = 1999 * 1024;   /* 650, probably, but we don't need this var anyway */
1031        log_msg(2, "Backup medium is CD-R[W]");
1032    }
1033} else {
1034    log_msg(2,
1035        "Not in Disaster Recovery Mode. No need to derive device name from config file.");
1036}
1037
1038read_cfg_var(cfg_file, "use-star", value);
1039if (strstr(value, "yes")) {
1040bkpinfo->use_star = TRUE;
1041log_msg(1, "Goody! ... bkpinfo->use_star is now true.");
1042}
1043
1044read_cfg_var(cfg_file, "acl", value);
1045if (strstr(value, "TRUE")) {
1046asprintf(&g_getfacl,"setfacl");
1047log_msg(1, "We will restore ACLs");
1048if (! find_home_of_exe("setfacl")) {
1049    log_msg(1, "Unable to restore ACLs as no setfacl found");
1050}
1051}
1052read_cfg_var(cfg_file, "xattr", value);
1053if (strstr(value, "TRUE")) {
1054asprintf(&g_getfattr,"setfattr");
1055log_msg(1, "We will restore XATTRs");
1056if (! find_home_of_exe("setfattr")) {
1057    log_msg(1, "Unable to restore XATTRs as no setfattr found");
1058}
1059}
1060
1061if (0 == read_cfg_var(cfg_file, "internal-tape-block-size", value)) {
1062bkpinfo->internal_tape_block_size = atol(value);
1063log_msg(1, "Internal tape block size has been custom-set to %ld",
1064        bkpinfo->internal_tape_block_size);
1065} else {
1066bkpinfo->internal_tape_block_size =
1067    DEFAULT_INTERNAL_TAPE_BLOCK_SIZE;
1068log_msg(1, "Internal tape block size = default (%ld)",
1069        DEFAULT_INTERNAL_TAPE_BLOCK_SIZE);
1070}
1071
1072read_cfg_var(cfg_file, "use-lzo", value);
1073if (strstr(value, "yes")) {
1074bkpinfo->use_lzo = TRUE;
1075bkpinfo->use_gzip = FALSE;
1076strcpy(bkpinfo->zip_exe, "lzop");
1077strcpy(bkpinfo->zip_suffix, "lzo");
1078} else {
1079read_cfg_var(cfg_file, "use-gzip", value);
1080if (strstr(value, "yes")) {
1081    bkpinfo->use_lzo = FALSE;
1082    bkpinfo->use_gzip = TRUE;
1083    strcpy(bkpinfo->zip_exe, "gzip");
1084    strcpy(bkpinfo->zip_suffix, "gz");
1085} else {
1086    read_cfg_var(cfg_file, "use-comp", value);
1087    if (strstr(value, "yes")) {
1088        bkpinfo->use_lzo = FALSE;
1089        bkpinfo->use_gzip = FALSE;
1090        strcpy(bkpinfo->zip_exe, "bzip2");
1091        strcpy(bkpinfo->zip_suffix, "bz2");
1092    } else {
1093        bkpinfo->zip_exe[0] = bkpinfo->zip_suffix[0] = '\0';
1094    }
1095}
1096}
1097
1098value[0] = '\0';
1099read_cfg_var(cfg_file, "differential", value);
1100if (!strcmp(value, "yes") || !strcmp(value, "1")) {
1101bkpinfo->differential = TRUE;
1102}
1103log_msg(2, "differential var = '%s'", value);
1104if (bkpinfo->differential) {
1105log_msg(2, "THIS IS A DIFFERENTIAL BACKUP");
1106} else {
1107log_msg(2, "This is a regular (full) backup");
1108}
1109
1110read_cfg_var(g_mondo_cfg_file, "please-dont-eject", tmp);
1111if (tmp[0]
1112||
1113strstr(call_program_and_get_last_line_of_output
1114       ("cat /proc/cmdline"), "donteject")) {
1115bkpinfo->please_dont_eject = TRUE;
1116log_msg(2, "Ok, I shan't eject when restoring! Groovy.");
1117}
1118
1119if (bkpinfo->backup_media_type == nfs) {
1120    if (!cfgf) {
1121        log_msg(2, "nfs_mount remains %s", bkpinfo->nfs_mount);
1122        log_msg(2, "nfs_remote_dir remains %s",
1123                bkpinfo->nfs_remote_dir);
1124        log_msg(2,
1125                "...cos it wouldn't make sense to abandon the values that GOT ME to this config file in the first place");
1126    } else {
1127        read_cfg_var(g_mondo_cfg_file, "nfs-server-mount",
1128                    bkpinfo->nfs_mount);
1129        read_cfg_var(g_mondo_cfg_file, "nfs-server-path",
1130                    bkpinfo->nfs_remote_dir);
1131        log_msg(2, "nfs_mount is %s", bkpinfo->nfs_mount);
1132        log_msg(2, "nfs_remote_dir is %s", bkpinfo->nfs_remote_dir);
1133    }
1134    if (strstr(call_program_and_get_last_line_of_output
1135        ("cat /proc/cmdline"), "pxe")) {
1136        /* We need to override values in PXE mode as it's
1137        * already done in start-nfs */
1138        envtmp1 = getenv("nfsmount");
1139        if (envtmp1 == NULL) {
1140            fatal_error("no nfsmount variable in environment");
1141        }
1142        envtmp2 = getenv("dirimg");
1143        if (envtmp2 == NULL) {
1144            fatal_error("no dirimg variable in environment");
1145        }
1146        strcpy(bkpinfo->nfs_mount,envtmp1);
1147        strcpy(bkpinfo->nfs_remote_dir,envtmp2);
1148    }
1149} else if (bkpinfo->backup_media_type == iso) {
1150    /* Patch by Conor Daly 23-june-2004
1151    * to correctly mount iso-dev and set a sensible
1152    * isodir in disaster recovery mode
1153    */
1154    strcpy(old_isodir, bkpinfo->isodir);
1155    read_cfg_var(g_mondo_cfg_file, "iso-mnt", iso_mnt);
1156    read_cfg_var(g_mondo_cfg_file, "isodir", iso_path);
1157    sprintf(bkpinfo->isodir, "%s%s", iso_mnt, iso_path);
1158    if (!bkpinfo->isodir[0]) {
1159        strcpy(bkpinfo->isodir, old_isodir);
1160    }
1161    if (!bkpinfo->disaster_recovery) {
1162        if (strcmp(old_isodir, bkpinfo->isodir)) {
1163            log_it
1164                ("user nominated isodir differs from archive, keeping user's choice: %s %s\n",
1165                old_isodir, bkpinfo->isodir);
1166            strcpy(bkpinfo->isodir, old_isodir);
1167        }
1168    }
1169    read_cfg_var(g_mondo_cfg_file, "iso-dev", g_isodir_device);
1170    log_msg(2, "isodir=%s; iso-dev=%s", bkpinfo->isodir,
1171            g_isodir_device);
1172    if (bkpinfo->disaster_recovery) {
1173        if (is_this_device_mounted(g_isodir_device)) {
1174            log_msg(2, "NB: isodir is already mounted");
1175            /* Find out where it's mounted */
1176            sprintf(command,
1177                    "mount | grep -E '^%s' | tail -n1 | cut -d' ' -f3",
1178                    g_isodir_device);
1179            log_it("command = %s", command);
1180            log_it("res of it = %s",
1181                call_program_and_get_last_line_of_output(command));
1182            sprintf(iso_mnt, "%s",
1183                    call_program_and_get_last_line_of_output(command));
1184        } else {
1185            sprintf(iso_mnt, "/tmp/isodir");
1186            sprintf(tmp, "mkdir -p %s", iso_mnt);
1187            run_program_and_log_output(tmp, 5);
1188            sprintf(tmp, "mount %s %s", g_isodir_device, iso_mnt);
1189            if (run_program_and_log_output(tmp, 3)) {
1190                log_msg(1,
1191                        "Unable to mount isodir. Perhaps this is really a CD backup?");
1192                bkpinfo->backup_media_type = cdr;
1193                strcpy(bkpinfo->media_device, "/dev/cdrom");    /* superfluous */
1194                bkpinfo->isodir[0] = iso_mnt[0] = iso_path[0] = '\0';
1195                if (mount_media()) {
1196                    fatal_error
1197                        ("Unable to mount isodir. Failed to mount CD-ROM as well.");
1198                } else {
1199                    log_msg(1,
1200                            "You backed up to disk, then burned some CDs.");
1201                }
1202            }
1203        }
1204        /* bkpinfo->isodir should now be the true path to prefix-1.iso etc... */
1205        if (bkpinfo->backup_media_type == iso) {
1206            sprintf(bkpinfo->isodir, "%s%s", iso_mnt, iso_path);
1207        }
1208    }
1209}
1210
1211if (media_specified_by_user != none) {
1212    if (g_restoring_live_from_cd) {
1213        if (bkpinfo->backup_media_type != media_specified_by_user) {
1214            log_msg(2,
1215                    "bkpinfo->backup_media_type != media_specified_by_user, so I'd better ask :)");
1216            interactively_obtain_media_parameters_from_user(FALSE);
1217            media_specified_by_user = bkpinfo->backup_media_type;
1218            get_cfg_file_from_archive();
1219    /*
1220        if (media_specified_by_user != cdr && media_specified_by_user == cdrw)
1221            { g_restoring_live_from_cd = FALSE; }
1222    */
1223        }
1224    }
1225    bkpinfo->backup_media_type = media_specified_by_user;
1226}
1227g_backup_media_type = bkpinfo->backup_media_type;
1228paranoid_free(value);
1229paranoid_free(tmp);
1230paranoid_free(command);
1231paranoid_free(iso_mnt);
1232paranoid_free(iso_path);
1233paranoid_free(old_isodir);
1234return (0);
1235
1236}
1237
1238/**************************************************************************
1239*END_READ_CFG_FILE_INTO_BKPINFO                                          *
1240**************************************************************************/
1241
1242
1243
1244
1245/**
1246* Allow the user to edit the filelist and biggielist.
1247* The filelist is unlinked after it is read.
1248* @param bkpinfo The backup information structure. Fields used:
1249* - @c bkpinfo->backup_media_type
1250* - @c bkpinfo->isodir
1251* - @c bkpinfo->media_device
1252* - @c bkpinfo->tmpdir
1253* @return The filelist structure containing the information read from disk.
1254*/
1255struct
1256s_node *process_filelist_and_biggielist()
1257{
1258struct s_node *filelist;
1259
1260/** add mallocs**/
1261char *command;
1262char *tmp;
1263int res = 0;
1264pid_t pid;
1265
1266assert(bkpinfo != NULL);
1267malloc_string(command);
1268malloc_string(tmp);
1269
1270if (does_file_exist(g_filelist_full)
1271&& does_file_exist(g_biggielist_txt)) {
1272log_msg(1, "%s exists", g_filelist_full);
1273log_msg(1, "%s exists", g_biggielist_txt);
1274log_msg(2,
1275        "Filelist and biggielist already recovered from media. Yay!");
1276} else {
1277getcwd(tmp, MAX_STR_LEN);
1278chdir(bkpinfo->tmpdir);
1279log_msg(1, "chdir(%s)", bkpinfo->tmpdir);
1280log_to_screen("Extracting filelist and biggielist from media...");
1281unlink("/tmp/filelist.full");
1282unlink("/" FILELIST_FULL_STUB);
1283unlink("/tmp/i-want-my-lvm");
1284if (IS_THIS_A_STREAMING_BACKUP(bkpinfo->backup_media_type)) {
1285    sprintf(command,
1286            "tar -b %ld -zxf %s %s %s %s %s %s",
1287            bkpinfo->internal_tape_block_size,
1288            bkpinfo->media_device,
1289            MOUNTLIST_FNAME_STUB,
1290            BIGGIELIST_TXT_STUB,
1291            FILELIST_FULL_STUB,
1292            "tmp/i-want-my-lvm", MONDO_CFG_FILE_STUB);
1293    log_msg(1, "tarcommand = %s", command);
1294    run_program_and_log_output(command, 1);
1295} else {
1296    log_msg(2,
1297            "Calling insist_on_this_cd_number; bkpinfo->isodir=%s",
1298            bkpinfo->isodir);
1299    insist_on_this_cd_number(1);
1300    log_msg(2, "Back from iotcn");
1301    run_program_and_log_output("mount", 1);
1302    sprintf(command,
1303            "tar -zxf %s/images/all.tar.gz %s %s %s %s %s",
1304            MNT_CDROM,
1305            MOUNTLIST_FNAME_STUB,
1306            BIGGIELIST_TXT_STUB,
1307            FILELIST_FULL_STUB,
1308            "tmp/i-want-my-lvm", MONDO_CFG_FILE_STUB);
1309
1310    log_msg(1, "tarcommand = %s", command);
1311    run_program_and_log_output(command, 1);
1312//    popup_and_OK("Press ENTER to continue");
1313    if (!does_file_exist(BIGGIELIST_TXT_STUB)) {
1314        fatal_error
1315            ("all.tar.gz did not include tmp/biggielist.txt");
1316    }
1317    if (!does_file_exist(FILELIST_FULL_STUB)) {
1318        fatal_error
1319            ("all.tar.gz did not include tmp/filelist.full.gz");
1320    }
1321}
1322sprintf(command, "cp -f %s %s", MONDO_CFG_FILE_STUB,
1323        g_mondo_cfg_file);
1324run_program_and_log_output(command, FALSE);
1325
1326sprintf(command, "cp -f %s/%s %s", bkpinfo->tmpdir,
1327        BIGGIELIST_TXT_STUB, g_biggielist_txt);
1328log_msg(1, "command = %s", command);
1329paranoid_system(command);
1330sprintf(command, "ln -sf %s/%s %s", bkpinfo->tmpdir,
1331        FILELIST_FULL_STUB, g_filelist_full);
1332log_msg(1, "command = %s", command);
1333paranoid_system(command);
1334}
1335
1336if (am_I_in_disaster_recovery_mode()
1337&&
1338ask_me_yes_or_no("Do you want to retrieve the mountlist as well?"))
1339{
1340//      sprintf(command, "cp -f tmp/mountlist.txt /tmp");
1341sprintf(command, "ln -sf %s/%s /tmp", MOUNTLIST_FNAME_STUB,
1342        bkpinfo->tmpdir);
1343paranoid_system(command);
1344}
1345
1346chdir(tmp);
1347
1348if (!does_file_exist(g_biggielist_txt)) {
1349log_msg(1, "Warning - %s not found", g_biggielist_txt);
1350}
1351if (!does_file_exist(g_filelist_full)) {
1352log_msg(1, "Warning - %s does not exist", g_filelist_full);
1353}
1354//  popup_and_OK("Wonderful.");
1355
1356log_msg(2, "Forking");
1357pid = fork();
1358switch (pid) {
1359case -1:
1360fatal_error("Forking error");
1361break;
1362
1363case 0:
1364log_to_screen("Pre-processing filelist");
1365if (!does_file_exist(g_biggielist_txt)) {
1366            sprintf(command, "echo -n > %s", g_biggielist_txt);
1367            paranoid_system(command);
1368        }
1369        sprintf(command, "grep -E '^/dev/.*' %s > %s",
1370                g_biggielist_txt, g_filelist_imagedevs);
1371        paranoid_system(command);
1372        exit(0);
1373        break;
1374
1375    default:
1376        open_evalcall_form("Pre-processing filelist");
1377        while (!waitpid(pid, (int *) 0, WNOHANG)) {
1378            usleep(100000);
1379            update_evalcall_form(0);
1380        }
1381    }
1382    close_evalcall_form();
1383
1384    log_msg(3, "loading filelist");
1385    filelist = load_filelist(g_filelist_full);
1386    log_msg(3, "deleting original filelist");
1387    unlink(g_filelist_full);
1388    if (g_text_mode) {
1389        printf("Restore which directory? --> ");
1390        fgets(tmp, sizeof(tmp), stdin);
1391        toggle_path_selection(filelist, tmp, TRUE);
1392        if (strlen(tmp) == 0) {
1393            res = 1;
1394        } else {
1395            res = 0;
1396        }
1397    } else {
1398        res = edit_filelist(filelist);
1399    }
1400    if (res) {
1401        log_msg(2, "User hit 'cancel'. Freeing filelist and aborting.");
1402        free_filelist(filelist);
1403        return (NULL);
1404    }
1405    ask_about_these_imagedevs(g_filelist_imagedevs, g_imagedevs_restthese);
1406    close_evalcall_form();
1407
1408    // NB: It's not necessary to add g_biggielist_txt to the filelist.full
1409    // file. The filelist.full file already contains the filename of EVERY
1410    // file backed up - regular and biggie files.
1411
1412    // However, we do want to make sure the imagedevs selected by the user
1413    // are flagged for restoring.
1414    if (length_of_file(g_imagedevs_restthese) > 2) {
1415        add_list_of_files_to_filelist(filelist, g_imagedevs_restthese,
1416                                      TRUE);
1417    }
1418
1419    paranoid_free(command);
1420    paranoid_free(tmp);
1421    return (filelist);
1422}
1423
1424/**************************************************************************
1425 *END_ PROCESS_FILELIST_AND_BIGGIELIST                                    *
1426 **************************************************************************/
1427
1428
1429
1430
1431/**
1432 * Make a backup copy of <tt>path_root</tt>/<tt>filename</tt>.
1433 * The backup filename is the filename of the original with ".pristine" added.
1434 * @param path_root The place where the filesystem is mounted (e.g. MNT_RESTORING).
1435 * @param filename The filename (absolute path) within @p path_root.
1436 * @return 0 for success, nonzero for failure.
1437 */
1438int backup_crucial_file(char *path_root, char *filename)
1439{
1440    char *tmp;
1441    char *command;
1442    int res;
1443
1444    malloc_string(tmp);
1445    malloc_string(command);
1446    assert(path_root != NULL);
1447    assert_string_is_neither_NULL_nor_zerolength(filename);
1448
1449    sprintf(tmp, "%s/%s", path_root, filename);
1450    sprintf(command, "cp -f %s %s.pristine", tmp, tmp);
1451
1452    res = run_program_and_log_output(command, 5);
1453    paranoid_free(tmp);
1454    paranoid_free(command);
1455    return (res);
1456}
1457
1458
1459/**
1460 * Install the user's boot loader in the MBR.
1461 * Currently LILO, ELILO, GRUB, RAW (dd of MBR), and the FreeBSD bootloader are supported.
1462 * @param offer_to_hack_scripts If TRUE, then offer to hack the user's fstab for them.
1463 * @return 0 for success, nonzero for failure.
1464 */
1465int run_boot_loader(bool offer_to_hack_scripts)
1466{
1467    int res;
1468    int retval = 0;
1469
1470  /** malloc *******/
1471    char *device;
1472    char *tmp;
1473    char *name;
1474
1475    malloc_string(device);
1476    malloc_string(tmp);
1477    malloc_string(name);
1478    backup_crucial_file(MNT_RESTORING, "/etc/fstab");
1479    backup_crucial_file(MNT_RESTORING, "/etc/grub.conf");
1480    backup_crucial_file(MNT_RESTORING, "/etc/lilo.conf");
1481    backup_crucial_file(MNT_RESTORING, "/etc/elilo.conf");
1482    read_cfg_var(g_mondo_cfg_file, "bootloader.device", device);
1483    read_cfg_var(g_mondo_cfg_file, "bootloader.name", name);
1484    sprintf(tmp, "run_boot_loader: device='%s', name='%s'", device, name);
1485    log_msg(2, tmp);
1486    system("sync");
1487    if (!strcmp(name, "LILO")) {
1488        res = run_lilo(offer_to_hack_scripts);
1489    } else if (!strcmp(name, "ELILO")) {
1490        res = run_elilo(offer_to_hack_scripts);
1491    } else if (!strcmp(name, "GRUB")) {
1492//      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?")))
1493//        {
1494        res = run_grub(offer_to_hack_scripts, device);
1495//    unlink(DO_MBR_PLEASE);
1496//  }
1497//      else
1498//        {
1499//    log_msg(1, "Not running run_grub(). Was a bad idea anyway.");
1500//    res = 1;
1501//  }
1502    } else if (!strcmp(name, "RAW")) {
1503        res = run_raw_mbr(offer_to_hack_scripts, device);
1504    }
1505#ifdef __FreeBSD__
1506    else if (!strcmp(name, "BOOT0")) {
1507        sprintf(tmp, "boot0cfg -B %s", device);
1508        res = run_program_and_log_output(tmp, FALSE);
1509    } else {
1510        sprintf(tmp, "ls /dev | grep -Eq '^%ss[1-4].*'", device);
1511        if (!system(tmp)) {
1512            sprintf(tmp, MNT_RESTORING "/sbin/fdisk -B %s", device);
1513            res = run_program_and_log_output(tmp, 3);
1514        } else {
1515            log_msg(1,
1516                    "I'm not running any boot loader. You have a DD boot drive. It's already loaded up.");
1517        }
1518    }
1519#else
1520    else {
1521        log_to_screen
1522            ("Unable to determine type of boot loader. Defaulting to LILO.");
1523        res = run_lilo(offer_to_hack_scripts);
1524    }
1525#endif
1526    retval += res;
1527    if (res) {
1528        log_to_screen("Your boot loader returned an error");
1529    } else {
1530        log_to_screen("Your boot loader ran OK");
1531    }
1532    paranoid_free(device);
1533    paranoid_free(tmp);
1534    paranoid_free(name);
1535    return (retval);
1536}
1537
1538/**************************************************************************
1539 *END_ RUN_BOOT_LOADER                                                    *
1540 **************************************************************************/
1541
1542
1543
1544/**
1545 * Attempt to find the user's editor.
1546 * @return The editor found ("vi" if none could be found).
1547 * @note The returned string points to static storage that will be overwritten with each call.
1548 */
1549char *find_my_editor(void)
1550{
1551    static char output[MAX_STR_LEN];
1552    if (find_home_of_exe("pico")) {
1553        strcpy(output, "pico");
1554    } else if (find_home_of_exe("nano")) {
1555        strcpy(output, "nano");
1556    } else if (find_home_of_exe("e3em")) {
1557        strcpy(output, "e3em");
1558    } else if (find_home_of_exe("e3vi")) {
1559        strcpy(output, "e3vi");
1560    } else {
1561        strcpy(output, "vi");
1562    }
1563    if (!find_home_of_exe(output)) {
1564        log_msg(2, " (find_my_editor) --- warning - %s not found", output);
1565    }
1566    return (output);
1567}
1568
1569
1570/**
1571 * Install GRUB on @p bd.
1572 * @param offer_to_run_stabgrub If TRUE, then offer to hack the user's fstab for them.
1573 * @param bd The boot device where GRUB is installed.
1574 * @return 0 for success, nonzero for failure.
1575 */
1576int run_grub(bool offer_to_run_stabgrub, char *bd)
1577{
1578  /** malloc **/
1579    char *command;
1580    char *boot_device;
1581    char *rootdev;
1582    char *rootdrive;
1583    char *conffile;
1584    char *tmp;
1585    char *editor;
1586
1587    int res;
1588    int done;
1589
1590    malloc_string(command);
1591    malloc_string(boot_device);
1592    malloc_string(tmp);
1593    malloc_string(editor);
1594    malloc_string(rootdev);
1595    malloc_string(rootdrive);
1596    malloc_string(conffile);
1597    assert_string_is_neither_NULL_nor_zerolength(bd);
1598    strcpy(editor, find_my_editor());
1599    strcpy(boot_device, bd);
1600
1601    if (!run_program_and_log_output("which grub-MR", FALSE)) {
1602        log_msg(1, "Yay! grub-MR found...");
1603        sprintf(command, "grub-MR %s /tmp/mountlist.txt", boot_device);
1604        log_msg(1, "command = %s", command);
1605    } else {
1606        sprintf(command, "chroot " MNT_RESTORING " grub-install %s",
1607                boot_device);
1608        log_msg(1, "WARNING - grub-MR not found; using grub-install");
1609    }
1610    if (offer_to_run_stabgrub
1611        && ask_me_yes_or_no("Did you change the mountlist?"))
1612        /* interactive mode */
1613    {
1614        mvaddstr_and_log_it(g_currentY,
1615                            0,
1616                            "Modifying fstab, mtab, device.map and grub.conf, and running GRUB...                             ");
1617        for (done = FALSE; !done;) {
1618            popup_and_get_string("Boot device",
1619                                 "Please confirm/enter the boot device. If in doubt, try /dev/hda",
1620                                 boot_device, MAX_STR_LEN / 4);
1621            sprintf(command, "stabgrub-me %s", boot_device);
1622            res = run_program_and_log_output(command, 1);
1623            if (res) {
1624                popup_and_OK
1625                    ("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.");
1626                newtSuspend();
1627                system("chroot " MNT_RESTORING);
1628                newtResume();
1629                popup_and_OK("Thank you.");
1630            } else {
1631                done = TRUE;
1632            }
1633            popup_and_OK("You will now edit fstab, mtab, device.map and grub.conf");
1634            if (!g_text_mode) {
1635                newtSuspend();
1636            }
1637            sprintf(tmp, "chroot %s %s /etc/fstab", MNT_RESTORING, editor);
1638            paranoid_system(tmp);
1639            sprintf(tmp, "chroot %s %s /etc/mtab", MNT_RESTORING, editor);
1640            paranoid_system(tmp);
1641            sprintf(tmp, "chroot %s %s /etc/grub.conf", MNT_RESTORING, editor);
1642            paranoid_system(tmp);
1643            sprintf(tmp, "chroot %s %s /boot/grub/device.map", MNT_RESTORING, 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 %s for more info.", MONDO_LOGFILE);
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 %s for more info.", MONDO_LOGFILE);
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()
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 -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 | 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    sprintf(tmp, "cp -f %s " MNT_RESTORING "/var/log", MONDO_LOGFILE);
2190    if (run_program_and_log_output(tmp, FALSE)) {
2191        log_msg(1,
2192                "Error. Failed to copy log to PC's /var/log dir. (Mounted read-only?)");
2193    }
2194    if (does_file_exist("/tmp/DUMBASS-GENTOO")) {
2195        run_program_and_log_output("mkdir -p " MNT_RESTORING
2196                                   "/mnt/.boot.d", 5);
2197    }
2198    for (lino = mountlist->entries - 1; lino >= 0; lino--) {
2199        if (!strcmp(mountlist->el[lino].mountpoint, "lvm")) {
2200            continue;
2201        }
2202        sprintf(tmp, "Unmounting device %s  ", mountlist->el[lino].device);
2203
2204        update_progress_form(tmp);
2205        if (is_this_device_mounted(mountlist->el[lino].device)) {
2206            if (!strcmp(mountlist->el[lino].mountpoint, "swap")) {
2207                sprintf(command, "swapoff %s", mountlist->el[lino].device);
2208            } else {
2209                if (!strcmp(mountlist->el[lino].mountpoint, "/1")) {
2210                    sprintf(command, "umount %s/", MNT_RESTORING);
2211                    log_msg(3,
2212                            "Well, I know a certain kitty-kitty who'll be sleeping with Mommy tonight...");
2213                } else {
2214                    sprintf(command, "umount " MNT_RESTORING "%s",
2215                            mountlist->el[lino].mountpoint);
2216                }
2217            }
2218            log_msg(10, "The 'umount' command is '%s'", command);
2219            res = run_program_and_log_output(command, 3);
2220        } else {
2221            strcat(tmp, "...not mounted anyway :-) OK");
2222            res = 0;
2223        }
2224        g_current_progress++;
2225        if (res) {
2226            strcat(tmp, "...Failed");
2227            retval++;
2228            log_to_screen(tmp);
2229        } else {
2230            log_msg(2, tmp);
2231        }
2232    }
2233    close_progress_form();
2234    if (retval) {
2235        mvaddstr_and_log_it(g_currentY++, 74, "Failed.");
2236    } else {
2237        mvaddstr_and_log_it(g_currentY++, 74, "Done.");
2238    }
2239    if (retval) {
2240        log_to_screen("Unable to unmount some of your partitions.");
2241    } else {
2242        log_to_screen("All partitions were unmounted OK.");
2243    }
2244    free(mountlist);
2245    paranoid_free(command);
2246    paranoid_free(tmp);
2247    return (retval);
2248}
2249
2250/**************************************************************************
2251 *END_UNMOUNT_ALL_DEVICES                                                 *
2252 **************************************************************************/
2253
2254
2255
2256/**
2257 * Extract mondo-restore.cfg and the mountlist from the tape inserted
2258 * to the ./tmp/ directory.
2259 * @param dev The tape device to read from.
2260 * @return 0 for success, nonzero for failure.
2261 */
2262int extract_cfg_file_and_mountlist_from_tape_dev(char *dev)
2263{
2264    char *command;
2265    int res = 0;
2266    // BCO: below 32KB seems to block at least on RHAS 2.1 and MDK 10.0
2267    long tape_block_size = 32768;
2268
2269    malloc_string(command);
2270
2271    // tar -zxvf-
2272    sprintf(command,
2273            "dd if=%s bs=%ld count=%ld 2> /dev/null | tar -zx %s %s %s %s %s",
2274            dev,
2275            tape_block_size,
2276            1024L * 1024 * 32 / tape_block_size,
2277            MOUNTLIST_FNAME_STUB, MONDO_CFG_FILE_STUB,
2278            BIGGIELIST_TXT_STUB, FILELIST_FULL_STUB, "tmp/i-want-my-lvm");
2279    log_msg(2, "command = '%s'", command);
2280    res = run_program_and_log_output(command, -1);
2281    if (res != 0 && does_file_exist(MONDO_CFG_FILE_STUB)) {
2282        res = 0;
2283    }
2284    paranoid_free(command);
2285    return (res);
2286}
2287
2288
2289
2290/**
2291 * Get the configuration file from the floppy, tape, or CD.
2292 * @param bkpinfo The backup information structure. Fields used:
2293 * - @c bkpinfo->backup_media_type
2294 * - @c bkpinfo->media_device
2295 * - @c bkpinfo->tmpdir
2296 * @return 0 for success, nonzero for failure.
2297 */
2298int get_cfg_file_from_archive()
2299{
2300    int retval = 0;
2301
2302   /** malloc *****/
2303    char *device;
2304    char *command;
2305    char *cfg_file;
2306    char *mounted_cfgf_path;
2307    char *tmp;
2308    char *mountpt;
2309    char *ramdisk_fname;
2310    char *mountlist_file;
2311    int res;
2312
2313    bool try_plan_B;
2314
2315    assert(bkpinfo != NULL);
2316    malloc_string(cfg_file);
2317    malloc_string(mounted_cfgf_path);
2318    malloc_string(mountpt);
2319    malloc_string(ramdisk_fname);
2320    malloc_string(mountlist_file);
2321    malloc_string(device);
2322    malloc_string(command);
2323    malloc_string(tmp);
2324    log_msg(2, "gcffa --- starting");
2325    log_to_screen("I'm thinking...");
2326    sprintf(mountpt, "%s/mount.bootdisk", bkpinfo->tmpdir);
2327    device[0] = '\0';
2328    chdir(bkpinfo->tmpdir);
2329    strcpy(cfg_file, MONDO_CFG_FILE_STUB);
2330    unlink(cfg_file);           // cfg_file[] is missing the '/' at the start, FYI, by intent
2331    unlink(FILELIST_FULL_STUB);
2332    unlink(BIGGIELIST_TXT_STUB);
2333    unlink("tmp/i-want-my-lvm");
2334    sprintf(command, "mkdir -p %s", mountpt);
2335    run_program_and_log_output(command, FALSE);
2336
2337//   unlink( "tmp/mondo-restore.cfg" ); // superfluous, surely?
2338
2339    sprintf(cfg_file, "%s/%s", bkpinfo->tmpdir, MONDO_CFG_FILE_STUB);
2340    sprintf(mountlist_file, "%s/%s", bkpinfo->tmpdir,
2341            MOUNTLIST_FNAME_STUB);
2342    //   make_hole_for_file( cfg_file );
2343    //   make_hole_for_file( mountlist_file);
2344    log_msg(2, "mountpt = %s; cfg_file=%s", mountpt, cfg_file);
2345
2346    /* Floppy? */
2347    sprintf(tmp, "mkdir -p %s", mountpt);
2348    run_program_and_log_output(tmp, FALSE);
2349    sprintf(tmp, "mkdir -p %s/tmp", bkpinfo->tmpdir);
2350    run_program_and_log_output(tmp, FALSE);
2351
2352    /* Is there a floppy drive detected */
2353    sprintf(tmp, "%s", call_program_and_get_last_line_of_output("dmesg | grep -i floppy"));
2354    if (strcmp(tmp, "")) {
2355        sprintf(command, "mount /dev/fd0u1722 %s", mountpt);
2356        sprintf(tmp,
2357            "(sleep 15; kill `ps | grep \"%s\" | cut -d' ' -f1` 2> /dev/null) &",
2358            command);
2359        log_msg(1, "tmp = '%s'", tmp);
2360        system(tmp);
2361        res = run_program_and_log_output(command, FALSE);
2362        if (res) {
2363            sprintf(command, "mount /dev/fd0H1440 %s", mountpt);
2364            res = run_program_and_log_output(command, FALSE);
2365        }
2366    } else {
2367        res = 1;
2368    }
2369    if (res) {
2370        try_plan_B = TRUE;
2371    } else {
2372        try_plan_B = TRUE;
2373        log_msg(2,
2374                "Mounted floppy OK but I don't trust it because the archives might contain more up-to-date config file than the floppy does.");
2375        // NB: If busybox does not support 'mount -o loop' then Plan A WILL NOT WORK.
2376        log_msg(2, "Processing floppy (plan A?)");
2377        sprintf(ramdisk_fname, "%s/mindi.rdz", mountpt);
2378        if (!does_file_exist(ramdisk_fname)) {
2379            sprintf(ramdisk_fname, "%s/initrd.img", mountpt);
2380        }
2381        if (!does_file_exist(ramdisk_fname)) {
2382            log_msg(2,
2383                    "Cannot find ramdisk file on mountpoint. Are you sure that's a boot disk in the drive?");
2384        }
2385        if (extract_config_file_from_ramdisk(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_media now :)");
2399            if (!mount_media()) {
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() > 1) {
2407                insist_on_this_cd_number((g_current_media_number = 1));
2408            }
2409        }
2410        if (try_plan_B) {
2411            log_msg(2, "gcffa --- OK, switching to Plan B");
2412            chdir(bkpinfo->tmpdir);
2413            run_program_and_log_output("mkdir -p tmp", FALSE);
2414
2415            if (strlen(bkpinfo->media_device) == 0) {
2416                strcpy(bkpinfo->media_device, "/dev/st0");
2417                log_msg(2, "media_device is blank; assuming %s");
2418            }
2419            strcpy(tmp, bkpinfo->media_device);
2420            if (extract_cfg_file_and_mountlist_from_tape_dev
2421                (bkpinfo->media_device)) {
2422                strcpy(bkpinfo->media_device, "/dev/st0");
2423                if (extract_cfg_file_and_mountlist_from_tape_dev
2424                    (bkpinfo->media_device)) {
2425                    strcpy(bkpinfo->media_device, "/dev/osst0");
2426                    if (extract_cfg_file_and_mountlist_from_tape_dev
2427                        (bkpinfo->media_device)) {
2428                        strcpy(bkpinfo->media_device, "/dev/ht0");
2429                        if (extract_cfg_file_and_mountlist_from_tape_dev
2430                            (bkpinfo->media_device)) {
2431                            log_msg(3,
2432                                    "I tried lots of devices but none worked.");
2433                            strcpy(bkpinfo->media_device, tmp);
2434                        }
2435                    }
2436                }
2437            }
2438
2439            if (!does_file_exist("tmp/mondo-restore.cfg")) {
2440                log_to_screen("Cannot find config info on tape/CD/floppy");
2441                return (1);
2442            }
2443        } else {
2444            /* That boot imae doesn't always exist where the following method always works
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            */
2453                log_msg(2,
2454                        "gcffa --- Plan B, a.k.a. untarring some file from all.tar.gz");
2455                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
2456                run_program_and_log_output(command, TRUE);
2457                if (!does_file_exist(MONDO_CFG_FILE_STUB)) {
2458                    fatal_error
2459                        ("Please reinsert the disk/CD and try again.");
2460                }
2461                    /*
2462            }
2463                */
2464        }
2465    }
2466    if (does_file_exist(MONDO_CFG_FILE_STUB)) {
2467        log_msg(1, "gcffa --- great! We've got the config file");
2468        sprintf(tmp, "%s/%s",
2469                call_program_and_get_last_line_of_output("pwd"),
2470                MONDO_CFG_FILE_STUB);
2471        sprintf(command, "cp -f %s %s", tmp, cfg_file);
2472        iamhere(command);
2473        if (strcmp(tmp, cfg_file)
2474            && run_program_and_log_output(command, 1)) {
2475            log_msg(1,
2476                    "... but an error occurred when I tried to move it to %s",
2477                    cfg_file);
2478        } else {
2479            log_msg(1, "... and I moved it successfully to %s", cfg_file);
2480        }
2481        sprintf(command, "cp -f %s/%s %s",
2482                call_program_and_get_last_line_of_output("pwd"),
2483                MOUNTLIST_FNAME_STUB, mountlist_file);
2484        iamhere(command);
2485        if (strcmp(tmp, cfg_file)
2486            && run_program_and_log_output(command, 1)) {
2487            log_msg(1, "Failed to get mountlist");
2488        } else {
2489            log_msg(1, "Got mountlist too");
2490            sprintf(command, "cp -f %s %s", mountlist_file,
2491                    g_mountlist_fname);
2492            if (run_program_and_log_output(command, 1)) {
2493                log_msg(1, "Failed to copy mountlist to /tmp");
2494            } else {
2495                log_msg(1, "Copied mountlist to /tmp as well OK");
2496                sprintf(command, "cp -f tmp/i-want-my-lvm /tmp/");
2497                run_program_and_log_output(command, 1);
2498/*        sprintf(command, "grep \" lvm \" %s", g_mountlist_fname);
2499          if (!run_program_and_log_output(command, 5) && !does_file_exist("/tmp/i-want-my-lvm"))
2500            {
2501          log_msg(1, "Warning. You want LVM but I don't have i-want-my-lvm. FIXME.");
2502        }
2503              else if (run_program_and_log_output(command,5) && does_file_exist("/tmp/i-want-my-lvm"))
2504                {
2505          log_msg(1, "Warning. You don't want LVM but i-want-my-lvm exists. I'll delete it. Cool.");
2506              do_my_funky_lvm_stuff(TRUE, FALSE); // ...after I stop any LVMs :)
2507          stop_raid_device("/dev/md0");
2508          stop_raid_device("/dev/md1");
2509          stop_raid_device("/dev/md2");
2510          unlink("/tmp/i-want-my-lvm");
2511        }
2512          else if (!run_program_and_log_output(command,5) && does_file_exist("/tmp/i-want-my-lvm"))
2513            {
2514          log_msg(1, "You had better pray that i-want-my-lvm patches your mountlist. FIXME.");
2515        }
2516*/
2517            }
2518        }
2519    }
2520    run_program_and_log_output("umount " MNT_CDROM, FALSE);
2521    if (!does_file_exist(cfg_file)) {
2522        iamhere(cfg_file);
2523        log_msg(1, "%s not found", cfg_file);
2524        log_to_screen
2525            ("Oh dear. Unable to recover configuration file from boot disk");
2526        return (1);
2527    }
2528
2529    log_to_screen("Recovered mondo-restore.cfg");
2530    if (!does_file_exist(MOUNTLIST_FNAME_STUB)) {
2531        log_to_screen("...but not mountlist.txt - a pity, really...");
2532    }
2533/* start SAH */
2534    else {
2535        sprintf(command, "cp -f %s %s/%s", MOUNTLIST_FNAME_STUB,
2536                bkpinfo->tmpdir, MOUNTLIST_FNAME_STUB);
2537        run_program_and_log_output(command, FALSE);
2538    }
2539/*--commented out by SAH
2540  sprintf( command, "cp -f %s %s/%s", cfg_file, bkpinfo->tmpdir, MONDO_CFG_FILE_STUB );
2541  run_program_and_log_output( command, FALSE );
2542  sprintf( command, "cp -f %s %s/%s", mountlist_file, bkpinfo->tmpdir, MOUNTLIST_FNAME_STUB );
2543  run_program_and_log_output( command, FALSE );
2544*/
2545/* end SAH */
2546
2547    sprintf(command, "cp -f %s /%s", cfg_file, MONDO_CFG_FILE_STUB);
2548    run_program_and_log_output(command, FALSE);
2549    sprintf(command, "cp -f %s /%s", mountlist_file, MOUNTLIST_FNAME_STUB);
2550    run_program_and_log_output(command, FALSE);
2551    sprintf(command, "cp -f etc/raidtab /etc/");
2552    run_program_and_log_output(command, FALSE);
2553    sprintf(command, "cp -f tmp/i-want-my-lvm /tmp/");
2554    run_program_and_log_output(command, FALSE);
2555    g_backup_media_type = bkpinfo->backup_media_type;
2556    paranoid_free(device);
2557    paranoid_free(command);
2558    paranoid_free(tmp);
2559    paranoid_free(cfg_file);
2560    paranoid_free(mounted_cfgf_path);
2561    paranoid_free(mountpt);
2562    paranoid_free(ramdisk_fname);
2563    paranoid_free(mountlist_file);
2564    return (retval);
2565}
2566
2567/**************************************************************************
2568 *END_GET_CFG_FILE_FROM_ARCHIVE                                           *
2569 **************************************************************************/
2570
2571/* @} - end restoreUtilityGroup */
2572
2573
2574/***************************************************************************
2575 * F@                                                                      *
2576 * () -- Hugo Rabson                                  *
2577 *                                                                         *
2578 * Purpose:                                                                *
2579 *                                                                         *
2580 * Called by:                                                              *
2581 * Params:    -                      -                                     *
2582 * Returns:   0=success; nonzero=failure                                   *
2583 ***************************************************************************/
2584
2585
2586
2587void wait_until_software_raids_are_prepped(char *mdstat_file,
2588                                           int wait_for_percentage)
2589{
2590    struct raidlist_itself *raidlist;
2591    int unfinished_mdstat_devices = 9999, i;
2592    char *screen_message;
2593
2594    malloc_string(screen_message);
2595    raidlist = malloc(sizeof(struct raidlist_itself));
2596
2597    assert(wait_for_percentage <= 100);
2598    iamhere("wait_until_software_raids_are_prepped");
2599    while (unfinished_mdstat_devices > 0) {
2600            // FIXME: Prefix '/dev/' should really be dynamic!
2601        if (parse_mdstat(raidlist, "/dev/")) {
2602            log_to_screen("Sorry, cannot read %s", MDSTAT_FILE);
2603            log_msg(1,"Sorry, cannot read %s", MDSTAT_FILE);
2604            return;
2605        }
2606        for (unfinished_mdstat_devices = i = 0; i <= raidlist->entries; i++) {
2607            if (raidlist->el[i].progress < wait_for_percentage) {
2608                unfinished_mdstat_devices++;
2609                if (raidlist->el[i].progress == -1) // delayed while another partition inits
2610                {
2611                    continue;
2612                }
2613                log_msg(1,"Sync'ing %s (i=%d)", raidlist->el[i].raid_device, i);
2614                sprintf(screen_message, "Sync'ing %s",
2615                        raidlist->el[i].raid_device);
2616                open_evalcall_form(screen_message);
2617                while (raidlist->el[i].progress < wait_for_percentage) {
2618                    log_msg(1,"Percentage sync'ed: %d", raidlist->el[i].progress);
2619                    update_evalcall_form(raidlist->el[i].progress);
2620                    sleep(2);
2621                    // FIXME: Prefix '/dev/' should really be dynamic!
2622                    if (parse_mdstat(raidlist, "/dev/")) {
2623                        break;
2624                    }
2625                }
2626                close_evalcall_form();
2627            }
2628        }
2629    }
2630    paranoid_free(screen_message);
2631    paranoid_free(raidlist);
2632}
Note: See TracBrowser for help on using the repository browser.