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

Last change on this file since 1579 was 1579, checked in by Bruno Cornec, 13 years ago

Remove the useless modify_rclocal_one_time

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