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

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

Remove g_bkpinfo_DONTUSETHIS

  • Property svn:keywords set to Id
File size: 77.5 KB
Line 
1/***************************************************************************
2mondo-rstr-tools.c  -  description
3-----------------
4
5begin: Sun Sep 21 16:40:35 EDT 2003
6copyright : (C) 2002 Mondo  Hugo Rabson
7email     : Hugo Rabson <hugorabson@msn.com>
8edited by : by Stan Benoit ?/2003
9email     : troff@nakedsoul.org
10cvsid     : $Id: mondo-rstr-tools.c
11***************************************************************************/
12
13/***************************************************************************
14*                                                                         *
15*   This program is free software; you can redistribute it and/or modify  *
16*   it under the terms of the GNU General Public License as published by  *
17*   the Free Software Foundation; either version 2 of the License, or     *
18*   (at your option) any later version.                                   *
19*                                                                         *
20***************************************************************************/
21/* mondo-rstr-tools.c               Hugo Rabson
22
23
2407/27
25- if the user is foolish enough to use /dev/md0 as boot device,
26call lilo -M /dev/hda to make sure lilo does its job properly
27- better NFS+nuke support
28
2907/20
30- use backup's i-want-my-lvm file
31- be sure to use archives' raidtab when restoring
32
3307/18
34- use /tmp/isodir for NFS if DR mode
35- better support of users who boot from LVM CD and nuke-restore non-LVM backups
36
3707/12
38- bugfix to allow user to burn ISOs to CDs and restore from CDs (not original src)
39
4006/29
41- mount ext3 partitions as ext2, just in case :)
42
4306/26
44- delete make_relevant_partition_bootable()
45
4606/19
47- futzed with the call to mount floppy, to stop it from locking up on my AMD64 system
48
4906/14
50- shell out to /mnt/RESTORING chroot in order to let user install GRUB
51manually if automatic GRUB installation fails
52
5306/15
54- Added check for different 'isodir' chosen by user than stored in the archive
55Conor Daly <conor.daly@met.ie>
56
5704/17
58- replaced INTERNAL_TAPE_BLK_SIZE with bkpinfo->internal_tape_block_size
59
6004/09
61- don't try to mount CD if tape bkp
62
6304/03
64- trying to copy tmp/mondo-restore.cfg to itself - silly! - fixed
65
6604/02
67- when extracting cfg file and mountlist from all.tar.gz (tape copy),
68use block size of INTERNAL_TAPE_BLK_SIZE, not TAPE_BLOCK_SIZE
69
7002/21
71- don't use 'mv -v' cos Busybox won't support it
72
7302/09
74- make hole for cfg file before moving it (line 2094 or so)
75
7602/03
77- changed a couple of refs to filelist.full, to filelist.full.gz
78
7901/16/2004
80- instead of copying filelist, use 'ln -sf' to link to original;
81saves space
82
8311/20/2003
84- also retrieve /tmp/mountlist.txt if user wants
85
8611/16
87- fixed NFS path bug affecting the extractions of filelist/biggielist
88during selective restore
89
9011/02
91- fixed mount_cdrom() to run properly w/ nfs restores
92- mount_device() returns 0 if swap mount fails cos swap isn't crucial
93
9410/17
95- run_grub() uses MNT_RESTORING instead of "/mnt/RESTORING"
96
9710/26
98- cleaned up run_grub()
99
10010/25
101- fixed mount_cdrom() to run properly w/ nfs restores
102
10310/21
104- mount_device() returns 0 if swap mount fails cos swap isn't crucial
105
10610/15
107- run_grub() now uses its initiative instead
108of calling grub-install
109
11010/10
111- don't leave copies of filelist.full lying around, clogging up
112the ramdisk, there's a good fellow :-)
113
11410/02
115- added 'dvd' to the range of media types I'll understand
116- fixed iso->cdr problem (thanks, Stan Benoit & Fred Beondo)
117
11809/24
119- try lots of tape devs if /dev/st0 fails
120
12109/23/2003
122- first incarnation
123*/
124
125
126#include <pthread.h>
127#include "../common/my-stuff.h"
128#include "../common/mondostructures.h"
129#include "../common/libmondo.h"
130#include "mr-externs.h"
131//#include "mondo-restore.h"
132//#include "mondo-rstr-compare-EXT.h"
133#include "mondo-rstr-tools.h"
134
135extern bool g_sigpipe_caught;
136extern bool g_ISO_restore_mode; /* are we in Iso Mode? */
137extern bool g_I_have_just_nuked;
138extern char *g_tmpfs_mountpt;
139extern char *g_isodir_device;
140extern char *g_isodir_format;
141extern long g_current_progress, g_maximum_progress;
142extern char *g_biggielist_txt;  // where 'biggielist.txt' is stored, on ramdisk / tempdir;
143                  // biggielist.txt is the list of big files stored on the
144                  // backup media set in question
145extern char *g_filelist_full;   // filelist.full.gz is the list of all regular files
146                  // (excluding big files) stored on the backup media set
147extern char *g_biggielist_pot;  // list of big files which _could_ be restored, if the
148                  // user chooses them
149extern char *g_filelist_imagedevs;  // list of devices (e.g. /dev/hda1, /dev/sda5) which
150                     // were archived as images, not just /dev entries
151                     // ... e.g. NTFS, BeOS partitions
152extern char *g_imagedevs_restthese; // of the imagedevs listed in FILELIST_IMAGEDEVS,
153                      // restore only these
154extern char *g_mondo_cfg_file;  // where m*ndo-restore.cfg (the config file) is stored
155extern char *g_mountlist_fname; // where mountlist.txt (the mountlist file) is stored
156extern char *g_mondo_home;      // homedir of Mondo; usually /usr/local/share/mondo
157
158extern t_bkptype g_backup_media_type;
159
160extern int g_partition_table_locked_up;
161extern char *MONDO_LOGFILE;
162
163/* Reference to global bkpinfo */
164extern struct s_bkpinfo *bkpinfo;
165
166/* Should we use or not extended attributes and acl when restoring */
167char *g_getfattr = NULL;
168char *g_getfacl = NULL;
169
170/**
171* @addtogroup restoreUtilityGroup
172* @{
173*/
174/**
175* Free the malloc()s for the filename variables.
176*/
177void free_MR_global_filenames()
178{
179paranoid_free(g_biggielist_txt);
180paranoid_free(g_filelist_full);
181paranoid_free(g_filelist_imagedevs);
182//  paranoid_free (g_imagedevs_pot );
183paranoid_free(g_imagedevs_restthese);
184paranoid_free(g_mondo_cfg_file);
185paranoid_free(g_mountlist_fname);
186paranoid_free(g_mondo_home);
187paranoid_free(g_tmpfs_mountpt);
188paranoid_free(g_isodir_device);
189paranoid_free(g_isodir_format);
190
191}
192
193
194
195/**
196* Ask the user which imagedevs from the list contained in @p infname should
197* actually be restored.
198* @param infname The file containing a list of all imagedevs.
199* @param outfname The location of the output file containing the imagedevs the user wanted to restore.
200* @ingroup restoreUtilityGroup
201*/
202void ask_about_these_imagedevs(char *infname, char *outfname)
203{
204FILE *fin;
205FILE *fout;
206/************************************************************************
207* allocate memory regions. test and set  -sab 16 feb 2003              *
208************************************************************************/
209char *incoming_ptr;
210char *question_ptr;
211
212char incoming[MAX_STR_LEN] = "\0";
213char question[MAX_STR_LEN];
214
215assert_string_is_neither_NULL_nor_zerolength(infname);
216assert_string_is_neither_NULL_nor_zerolength(outfname);
217
218incoming_ptr = malloc(sizeof(incoming));
219if (incoming_ptr == NULL) {
220fprintf(stderr, "Out of Memory\n");
221exit(EXIT_FAILURE);
222}
223
224question_ptr = malloc(sizeof(question));
225if (question_ptr == NULL) {
226fprintf(stderr, "Out of Memory\n");
227exit(EXIT_FAILURE);
228}
229
230memset(incoming_ptr, '\0', sizeof(incoming));
231memset(question_ptr, '\0', sizeof(question));
232
233
234
235if (!(fin = fopen(infname, "r"))) {
236fatal_error("Cannot openin infname");
237}
238if (!(fout = fopen(outfname, "w"))) {
239fatal_error("Cannot openin outfname");
240}
241for (fgets(incoming_ptr, MAX_STR_LEN, fin);
242 !feof(fin); fgets(incoming_ptr, MAX_STR_LEN, fin)) {
243strip_spaces(incoming_ptr);
244
245if (incoming[0] == '\0') {
246    continue;
247}
248
249sprintf(question_ptr,
250        "Should I restore the image of %s ?", incoming_ptr);
251
252if (ask_me_yes_or_no(question_ptr)) {
253    fprintf(fout, "%s\n", incoming_ptr);
254}
255}
256
257/*** free memory ***********/
258paranoid_free(incoming_ptr);
259incoming_ptr = NULL;
260paranoid_free(question_ptr);
261question_ptr = NULL;
262
263
264paranoid_fclose(fout);
265paranoid_fclose(fin);
266}
267
268/**************************************************************************
269*ASK_ABOUT_THESE_IMAGEDEVS                                               *
270**************************************************************************/
271
272
273
274
275
276
277
278
279/**
280* Extract @c mondo-restore.cfg and @c mountlist.txt from @p ramdisk_fname.
281* @param bkpinfo The backup information structure. @c tmpdir is the only field used.
282* @param ramdisk_fname The filename of the @b compressed ramdisk to look in.
283* @param output_cfg_file Where to put the configuration file extracted.
284* @param output_mountlist_file Where to put the mountlist file extracted.
285* @return 0 for success, nonzero for failure.
286* @ingroup restoreUtilityGroup
287*/
288int
289extract_config_file_from_ramdisk(char *ramdisk_fname,
290                         char *output_cfg_file,
291                         char *output_mountlist_file)
292{
293char *mountpt;
294char *command;
295char *orig_fname;
296int retval = 0;
297
298assert(bkpinfo != NULL);
299malloc_string(mountpt);
300malloc_string(command);
301malloc_string(orig_fname);
302assert_string_is_neither_NULL_nor_zerolength(ramdisk_fname);
303assert_string_is_neither_NULL_nor_zerolength(output_cfg_file);
304assert_string_is_neither_NULL_nor_zerolength(output_mountlist_file);
305sprintf(mountpt, "%s/mount.bootdisk", bkpinfo->tmpdir);
306sprintf(command, "mkdir -p %s", mountpt);
307run_program_and_log_output(command, FALSE);
308sprintf(command, "gzip -dc %s > %s/mindi.rd 2> /dev/null",
309    ramdisk_fname, bkpinfo->tmpdir);
310
311run_program_and_log_output(command, FALSE);
312sprintf(command, "umount %s", mountpt);
313
314run_program_and_log_output(command, FALSE);
315
316sprintf(command, "mount -o loop %s/mindi.rd -t ext2 %s",
317    bkpinfo->tmpdir, mountpt);
318
319run_program_and_log_output(command, FALSE);
320
321sprintf(command, "mkdir -p %s/tmp", bkpinfo->tmpdir);
322
323run_program_and_log_output(command, FALSE);
324
325sprintf(command, "cp -f %s/%s %s",  // %s/%s becomes {mountpt}/tmp/m*ndo-restore.cfg
326    mountpt, g_mondo_cfg_file, output_cfg_file);
327run_program_and_log_output(command, FALSE);
328
329sprintf(orig_fname, "%s/%s", mountpt, g_mountlist_fname);
330if (does_file_exist(orig_fname)) {
331sprintf(command, "cp -f %s %s", orig_fname, output_mountlist_file);
332run_program_and_log_output(command, FALSE);
333}
334sprintf(command, "umount %s", mountpt);
335run_program_and_log_output(command, FALSE);
336if (!does_file_exist(output_cfg_file)
337|| (!does_file_exist(output_mountlist_file)
338    && does_file_exist(orig_fname))) {
339log_msg(2, "Failed to extract %s and/or %s from ramdisk",
340        output_cfg_file, output_mountlist_file);
341retval = 1;
342} else {
343retval = 0;
344}
345paranoid_free(mountpt);
346paranoid_free(command);
347paranoid_free(orig_fname);
348return (retval);
349
350}
351
352
353
354
355/**
356* Keep trying to get mondo-restore.cfg from the archive, until the user gives up.
357*/
358void get_cfg_file_from_archive_or_bust()
359{
360while (get_cfg_file_from_archive()) {
361if (!ask_me_yes_or_no
362    ("Failed to find config file/archives. Choose another source?"))
363{
364    fatal_error("Could not find config file/archives. Aborting.");
365}
366interactively_obtain_media_parameters_from_user(FALSE);
367}
368}
369
370
371/**
372* Determine whether @p list_fname contains a line containing @p f.
373* @param f The line to search for.
374* @param list_fname The file to search in.
375* @param preamble Ignore this beginning part of @p f ("" to disable).
376* @return TRUE if it's in the list, FALSE if it's not.
377*/
378bool is_file_in_list(char *f, char *list_fname, char *preamble)
379{
380
381/** needs malloc **/
382char *command;
383char *file;
384char *tmp;
385int res;
386
387malloc_string(command);
388malloc_string(file);
389malloc_string(tmp);
390assert_string_is_neither_NULL_nor_zerolength(f);
391assert_string_is_neither_NULL_nor_zerolength(list_fname);
392assert(preamble != NULL);
393
394if (strncmp(preamble, f, strlen(preamble)) == 0) {
395strcpy(file, f + strlen(preamble));
396} else {
397strcpy(file, f);
398}
399if (file[0] == '/' && file[1] == '/') {
400strcpy(tmp, file);
401strcpy(file, tmp + 1);
402}
403sprintf(tmp,
404    "Checking to see if f=%s, file=%s, is in the list of biggiefiles",
405    f, file);
406log_msg(2, tmp);
407sprintf(command, "grep -E '^%s$' %s", file, list_fname);
408res = run_program_and_log_output(command, FALSE);
409paranoid_free(command);
410paranoid_free(file);
411paranoid_free(tmp);
412if (res) {
413return (FALSE);
414} else {
415return (TRUE);
416}
417}
418
419/**************************************************************************
420*END_IS_FILE_IN_LIST                                                     *
421**************************************************************************/
422
423
424
425/**
426* Set up an ISO backup.
427* @param bkpinfo The backup information structure. Fields used:
428* - @c bkpinfo->backup_media_type
429* - @c bkpinfo->disaster_recovery
430* - @c bkpinfo->isodir
431* @param nuke_me_please If TRUE, we're in nuke mode; if FALSE we're in interactive mode.
432* @return 0 for success, nonzero for failure.
433*/
434int iso_fiddly_bits(bool nuke_me_please)
435{
436char *mount_isodir_command, *tmp, *command;
437int retval = 0, i;
438bool already_mounted = FALSE;
439
440assert(bkpinfo != NULL);
441malloc_string(mount_isodir_command);
442malloc_string(tmp);
443malloc_string(command);
444g_ISO_restore_mode = TRUE;
445read_cfg_var(g_mondo_cfg_file, "iso-dev", g_isodir_device);
446if (bkpinfo->disaster_recovery) {
447/* Patch Conor Daly 26-june-2004
448* Don't let this clobber an existing bkpinfo->isodir */
449if (!bkpinfo->isodir[0]) {
450    strcpy(bkpinfo->isodir, "/tmp/isodir");
451}
452/* End patch */
453sprintf(command, "mkdir -p %s", bkpinfo->isodir);
454run_program_and_log_output(command, 5);
455log_msg(2, "Setting isodir to %s", bkpinfo->isodir);
456}
457
458if (!get_isodir_info
459(g_isodir_device, g_isodir_format, bkpinfo->isodir,
460 nuke_me_please)) {
461return (1);
462}
463paranoid_system("umount " MNT_CDROM " 2> /dev/null");   /* just in case */
464
465if (is_this_device_mounted(g_isodir_device)) {
466log_to_screen("WARNING - isodir is already mounted");
467already_mounted = TRUE;
468} else {
469sprintf(mount_isodir_command, "mount %s", g_isodir_device);
470if (strlen(g_isodir_format) > 1) {
471    sprintf(mount_isodir_command + strlen(mount_isodir_command),
472            " -t %s", g_isodir_format);
473}
474strcat(mount_isodir_command, " -o ro ");
475strcat(mount_isodir_command, bkpinfo->isodir);
476run_program_and_log_output("df -m", FALSE);
477sprintf(tmp,
478        "The 'mount' command is '%s'. PLEASE report this command to be if you have problems, ok?",
479        mount_isodir_command);
480log_msg(1, tmp);
481if (run_program_and_log_output(mount_isodir_command, FALSE)) {
482    popup_and_OK
483        ("Cannot mount the device where the ISO files are stored.");
484    return (1);
485}
486log_to_screen
487    ("I have mounted the device where the ISO files are stored.");
488}
489if (!IS_THIS_A_STREAMING_BACKUP(bkpinfo->backup_media_type)) {
490mount_cdrom();
491}
492i = what_number_cd_is_this();   /* 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()
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)
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()) {
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(FALSE);
1212        media_specified_by_user = bkpinfo->backup_media_type;
1213        get_cfg_file_from_archive();
1214/*
1215      if (media_specified_by_user != cdr && media_specified_by_user == cdrw)
1216        { g_restoring_live_from_cd = FALSE; }
1217*/
1218    }
1219}
1220bkpinfo->backup_media_type = media_specified_by_user;
1221}
1222g_backup_media_type = bkpinfo->backup_media_type;
1223paranoid_free(value);
1224paranoid_free(tmp);
1225paranoid_free(command);
1226paranoid_free(iso_mnt);
1227paranoid_free(iso_path);
1228paranoid_free(old_isodir);
1229return (0);
1230
1231}
1232
1233/**************************************************************************
1234*END_READ_CFG_FILE_INTO_BKPINFO                                          *
1235**************************************************************************/
1236
1237
1238
1239
1240/**
1241* Allow the user to edit the filelist and biggielist.
1242* The filelist is unlinked after it is read.
1243* @param bkpinfo The backup information structure. Fields used:
1244* - @c bkpinfo->backup_media_type
1245* - @c bkpinfo->isodir
1246* - @c bkpinfo->media_device
1247* - @c bkpinfo->tmpdir
1248* @return The filelist structure containing the information read from disk.
1249*/
1250struct
1251s_node *process_filelist_and_biggielist()
1252{
1253struct s_node *filelist;
1254
1255/** add mallocs**/
1256char *command;
1257char *tmp;
1258int res = 0;
1259pid_t pid;
1260
1261assert(bkpinfo != NULL);
1262malloc_string(command);
1263malloc_string(tmp);
1264
1265if (does_file_exist(g_filelist_full)
1266&& does_file_exist(g_biggielist_txt)) {
1267log_msg(1, "%s exists", g_filelist_full);
1268log_msg(1, "%s exists", g_biggielist_txt);
1269log_msg(2,
1270        "Filelist and biggielist already recovered from media. Yay!");
1271} else {
1272getcwd(tmp, MAX_STR_LEN);
1273chdir(bkpinfo->tmpdir);
1274log_msg(1, "chdir(%s)", bkpinfo->tmpdir);
1275log_to_screen("Extracting filelist and biggielist from media...");
1276unlink("/tmp/filelist.full");
1277unlink("/" FILELIST_FULL_STUB);
1278unlink("/tmp/i-want-my-lvm");
1279if (IS_THIS_A_STREAMING_BACKUP(bkpinfo->backup_media_type)) {
1280    sprintf(command,
1281            "tar -b %ld -zxf %s %s %s %s %s %s",
1282            bkpinfo->internal_tape_block_size,
1283            bkpinfo->media_device,
1284            MOUNTLIST_FNAME_STUB,
1285            BIGGIELIST_TXT_STUB,
1286            FILELIST_FULL_STUB,
1287            "tmp/i-want-my-lvm", MONDO_CFG_FILE_STUB);
1288    log_msg(1, "tarcommand = %s", command);
1289    run_program_and_log_output(command, 1);
1290} else {
1291    log_msg(2,
1292            "Calling insist_on_this_cd_number; bkpinfo->isodir=%s",
1293            bkpinfo->isodir);
1294    insist_on_this_cd_number(1);
1295    log_msg(2, "Back from iotcn");
1296    run_program_and_log_output("mount", 1);
1297    sprintf(command,
1298            "tar -zxf %s/images/all.tar.gz %s %s %s %s %s",
1299            MNT_CDROM,
1300            MOUNTLIST_FNAME_STUB,
1301            BIGGIELIST_TXT_STUB,
1302            FILELIST_FULL_STUB,
1303            "tmp/i-want-my-lvm", MONDO_CFG_FILE_STUB);
1304
1305    log_msg(1, "tarcommand = %s", command);
1306    run_program_and_log_output(command, 1);
1307//    popup_and_OK("Press ENTER to continue");
1308    if (!does_file_exist(BIGGIELIST_TXT_STUB)) {
1309        fatal_error
1310            ("all.tar.gz did not include tmp/biggielist.txt");
1311    }
1312    if (!does_file_exist(FILELIST_FULL_STUB)) {
1313        fatal_error
1314            ("all.tar.gz did not include tmp/filelist.full.gz");
1315    }
1316}
1317sprintf(command, "cp -f %s %s", MONDO_CFG_FILE_STUB,
1318        g_mondo_cfg_file);
1319run_program_and_log_output(command, FALSE);
1320
1321sprintf(command, "cp -f %s/%s %s", bkpinfo->tmpdir,
1322        BIGGIELIST_TXT_STUB, g_biggielist_txt);
1323log_msg(1, "command = %s", command);
1324paranoid_system(command);
1325sprintf(command, "ln -sf %s/%s %s", bkpinfo->tmpdir,
1326        FILELIST_FULL_STUB, g_filelist_full);
1327log_msg(1, "command = %s", command);
1328paranoid_system(command);
1329}
1330
1331if (am_I_in_disaster_recovery_mode()
1332&&
1333ask_me_yes_or_no("Do you want to retrieve the mountlist as well?"))
1334{
1335//      sprintf(command, "cp -f tmp/mountlist.txt /tmp");
1336sprintf(command, "ln -sf %s/%s /tmp", MOUNTLIST_FNAME_STUB,
1337        bkpinfo->tmpdir);
1338paranoid_system(command);
1339}
1340
1341chdir(tmp);
1342
1343if (!does_file_exist(g_biggielist_txt)) {
1344log_msg(1, "Warning - %s not found", g_biggielist_txt);
1345}
1346if (!does_file_exist(g_filelist_full)) {
1347log_msg(1, "Warning - %s does not exist", g_filelist_full);
1348}
1349//  popup_and_OK("Wonderful.");
1350
1351log_msg(2, "Forking");
1352pid = fork();
1353switch (pid) {
1354case -1:
1355fatal_error("Forking error");
1356break;
1357
1358case 0:
1359log_to_screen("Pre-processing filelist");
1360if (!does_file_exist(g_biggielist_txt)) {
1361            sprintf(command, "echo -n > %s", g_biggielist_txt);
1362            paranoid_system(command);
1363        }
1364        sprintf(command, "grep -E '^/dev/.*' %s > %s",
1365                g_biggielist_txt, g_filelist_imagedevs);
1366        paranoid_system(command);
1367        exit(0);
1368        break;
1369
1370    default:
1371        open_evalcall_form("Pre-processing filelist");
1372        while (!waitpid(pid, (int *) 0, WNOHANG)) {
1373            usleep(100000);
1374            update_evalcall_form(0);
1375        }
1376    }
1377    close_evalcall_form();
1378
1379    log_msg(3, "loading filelist");
1380    filelist = load_filelist(g_filelist_full);
1381    log_msg(3, "deleting original filelist");
1382    unlink(g_filelist_full);
1383    if (g_text_mode) {
1384        printf("Restore which directory? --> ");
1385        fgets(tmp, sizeof(tmp), stdin);
1386        toggle_path_selection(filelist, tmp, TRUE);
1387        if (strlen(tmp) == 0) {
1388            res = 1;
1389        } else {
1390            res = 0;
1391        }
1392    } else {
1393        res = edit_filelist(filelist);
1394    }
1395    if (res) {
1396        log_msg(2, "User hit 'cancel'. Freeing filelist and aborting.");
1397        free_filelist(filelist);
1398        return (NULL);
1399    }
1400    ask_about_these_imagedevs(g_filelist_imagedevs, g_imagedevs_restthese);
1401    close_evalcall_form();
1402
1403    // NB: It's not necessary to add g_biggielist_txt to the filelist.full
1404    // file. The filelist.full file already contains the filename of EVERY
1405    // file backed up - regular and biggie files.
1406
1407    // However, we do want to make sure the imagedevs selected by the user
1408    // are flagged for restoring.
1409    if (length_of_file(g_imagedevs_restthese) > 2) {
1410        add_list_of_files_to_filelist(filelist, g_imagedevs_restthese,
1411                                      TRUE);
1412    }
1413
1414    paranoid_free(command);
1415    paranoid_free(tmp);
1416    return (filelist);
1417}
1418
1419/**************************************************************************
1420 *END_ PROCESS_FILELIST_AND_BIGGIELIST                                    *
1421 **************************************************************************/
1422
1423
1424
1425
1426/**
1427 * Make a backup copy of <tt>path_root</tt>/<tt>filename</tt>.
1428 * The backup filename is the filename of the original with ".pristine" added.
1429 * @param path_root The place where the filesystem is mounted (e.g. MNT_RESTORING).
1430 * @param filename The filename (absolute path) within @p path_root.
1431 * @return 0 for success, nonzero for failure.
1432 */
1433int backup_crucial_file(char *path_root, char *filename)
1434{
1435    char *tmp;
1436    char *command;
1437    int res;
1438
1439    malloc_string(tmp);
1440    malloc_string(command);
1441    assert(path_root != NULL);
1442    assert_string_is_neither_NULL_nor_zerolength(filename);
1443
1444    sprintf(tmp, "%s/%s", path_root, filename);
1445    sprintf(command, "cp -f %s %s.pristine", tmp, tmp);
1446
1447    res = run_program_and_log_output(command, 5);
1448    paranoid_free(tmp);
1449    paranoid_free(command);
1450    return (res);
1451}
1452
1453
1454/**
1455 * Install the user's boot loader in the MBR.
1456 * Currently LILO, ELILO, GRUB, RAW (dd of MBR), and the FreeBSD bootloader are supported.
1457 * @param offer_to_hack_scripts If TRUE, then offer to hack the user's fstab for them.
1458 * @return 0 for success, nonzero for failure.
1459 */
1460int run_boot_loader(bool offer_to_hack_scripts)
1461{
1462    int res;
1463    int retval = 0;
1464
1465  /** malloc *******/
1466    char *device;
1467    char *tmp;
1468    char *name;
1469
1470    malloc_string(device);
1471    malloc_string(tmp);
1472    malloc_string(name);
1473    backup_crucial_file(MNT_RESTORING, "/etc/fstab");
1474    backup_crucial_file(MNT_RESTORING, "/etc/grub.conf");
1475    backup_crucial_file(MNT_RESTORING, "/etc/lilo.conf");
1476    backup_crucial_file(MNT_RESTORING, "/etc/elilo.conf");
1477    read_cfg_var(g_mondo_cfg_file, "bootloader.device", device);
1478    read_cfg_var(g_mondo_cfg_file, "bootloader.name", name);
1479    sprintf(tmp, "run_boot_loader: device='%s', name='%s'", device, name);
1480    log_msg(2, tmp);
1481    system("sync");
1482    if (!strcmp(name, "LILO")) {
1483        res = run_lilo(offer_to_hack_scripts);
1484    } else if (!strcmp(name, "ELILO")) {
1485        res = run_elilo(offer_to_hack_scripts);
1486    } else if (!strcmp(name, "GRUB")) {
1487//      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?")))
1488//        {
1489        res = run_grub(offer_to_hack_scripts, device);
1490//    unlink(DO_MBR_PLEASE);
1491//  }
1492//      else
1493//        {
1494//    log_msg(1, "Not running run_grub(). Was a bad idea anyway.");
1495//    res = 1;
1496//  }
1497    } else if (!strcmp(name, "RAW")) {
1498        res = run_raw_mbr(offer_to_hack_scripts, device);
1499    }
1500#ifdef __FreeBSD__
1501    else if (!strcmp(name, "BOOT0")) {
1502        sprintf(tmp, "boot0cfg -B %s", device);
1503        res = run_program_and_log_output(tmp, FALSE);
1504    } else {
1505        sprintf(tmp, "ls /dev | grep -Eq '^%ss[1-4].*'", device);
1506        if (!system(tmp)) {
1507            sprintf(tmp, MNT_RESTORING "/sbin/fdisk -B %s", device);
1508            res = run_program_and_log_output(tmp, 3);
1509        } else {
1510            log_msg(1,
1511                    "I'm not running any boot loader. You have a DD boot drive. It's already loaded up.");
1512        }
1513    }
1514#else
1515    else {
1516        log_to_screen
1517            ("Unable to determine type of boot loader. Defaulting to LILO.");
1518        res = run_lilo(offer_to_hack_scripts);
1519    }
1520#endif
1521    retval += res;
1522    if (res) {
1523        log_to_screen("Your boot loader returned an error");
1524    } else {
1525        log_to_screen("Your boot loader ran OK");
1526    }
1527    paranoid_free(device);
1528    paranoid_free(tmp);
1529    paranoid_free(name);
1530    return (retval);
1531}
1532
1533/**************************************************************************
1534 *END_ RUN_BOOT_LOADER                                                    *
1535 **************************************************************************/
1536
1537
1538
1539/**
1540 * Attempt to find the user's editor.
1541 * @return The editor found ("vi" if none could be found).
1542 * @note The returned string points to static storage that will be overwritten with each call.
1543 */
1544char *find_my_editor(void)
1545{
1546    static char output[MAX_STR_LEN];
1547    if (find_home_of_exe("pico")) {
1548        strcpy(output, "pico");
1549    } else if (find_home_of_exe("nano")) {
1550        strcpy(output, "nano");
1551    } else if (find_home_of_exe("e3em")) {
1552        strcpy(output, "e3em");
1553    } else if (find_home_of_exe("e3vi")) {
1554        strcpy(output, "e3vi");
1555    } else {
1556        strcpy(output, "vi");
1557    }
1558    if (!find_home_of_exe(output)) {
1559        log_msg(2, " (find_my_editor) --- warning - %s not found", output);
1560    }
1561    return (output);
1562}
1563
1564
1565/**
1566 * Install GRUB on @p bd.
1567 * @param offer_to_run_stabgrub If TRUE, then offer to hack the user's fstab for them.
1568 * @param bd The boot device where GRUB is installed.
1569 * @return 0 for success, nonzero for failure.
1570 */
1571int run_grub(bool offer_to_run_stabgrub, char *bd)
1572{
1573  /** malloc **/
1574    char *command;
1575    char *boot_device;
1576    char *rootdev;
1577    char *rootdrive;
1578    char *conffile;
1579    char *tmp;
1580    char *editor;
1581
1582    int res;
1583    int done;
1584
1585    malloc_string(command);
1586    malloc_string(boot_device);
1587    malloc_string(tmp);
1588    malloc_string(editor);
1589    malloc_string(rootdev);
1590    malloc_string(rootdrive);
1591    malloc_string(conffile);
1592    assert_string_is_neither_NULL_nor_zerolength(bd);
1593    strcpy(editor, find_my_editor());
1594    strcpy(boot_device, bd);
1595
1596    if (!run_program_and_log_output("which grub-MR", FALSE)) {
1597        log_msg(1, "Yay! grub-MR found...");
1598        sprintf(command, "grub-MR %s /tmp/mountlist.txt", boot_device);
1599        log_msg(1, "command = %s", command);
1600    } else {
1601        sprintf(command, "chroot " MNT_RESTORING " grub-install %s",
1602                boot_device);
1603        log_msg(1, "WARNING - grub-MR not found; using grub-install");
1604    }
1605    if (offer_to_run_stabgrub
1606        && ask_me_yes_or_no("Did you change the mountlist?"))
1607        /* interactive mode */
1608    {
1609        mvaddstr_and_log_it(g_currentY,
1610                            0,
1611                            "Modifying fstab, mtab, device.map and grub.conf, and running GRUB...                             ");
1612        for (done = FALSE; !done;) {
1613            popup_and_get_string("Boot device",
1614                                 "Please confirm/enter the boot device. If in doubt, try /dev/hda",
1615                                 boot_device, MAX_STR_LEN / 4);
1616            sprintf(command, "stabgrub-me %s", boot_device);
1617            res = run_program_and_log_output(command, 1);
1618            if (res) {
1619                popup_and_OK
1620                    ("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.");
1621                newtSuspend();
1622                system("chroot " MNT_RESTORING);
1623                newtResume();
1624                popup_and_OK("Thank you.");
1625            } else {
1626                done = TRUE;
1627            }
1628            popup_and_OK("You will now edit fstab, mtab, device.map and grub.conf");
1629            if (!g_text_mode) {
1630                newtSuspend();
1631            }
1632            sprintf(tmp, "chroot %s %s /etc/fstab", MNT_RESTORING, editor);
1633            paranoid_system(tmp);
1634            sprintf(tmp, "chroot %s %s /etc/mtab", MNT_RESTORING, editor);
1635            paranoid_system(tmp);
1636            sprintf(tmp, "chroot %s %s /etc/grub.conf", MNT_RESTORING, editor);
1637            paranoid_system(tmp);
1638            sprintf(tmp, "chroot %s %s /boot/grub/device.map", MNT_RESTORING, editor);
1639            paranoid_system(tmp);
1640            if (!g_text_mode) {
1641                newtResume();
1642            }
1643        }
1644    } else
1645        /* nuke mode */
1646    {
1647        mvaddstr_and_log_it(g_currentY,
1648                            0,
1649                            "Running GRUB...                                                 ");
1650        iamhere(command);
1651        res = run_program_and_log_output(command, 1);
1652        if (res) {
1653            popup_and_OK
1654                ("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.");
1655            newtSuspend();
1656            system("chroot " MNT_RESTORING);
1657            newtResume();
1658            popup_and_OK("Thank you.");
1659        }
1660    }
1661    if (res) {
1662        mvaddstr_and_log_it(g_currentY++, 74, "Failed.");
1663        log_to_screen
1664            ("GRUB ran w/error(s). See %s for more info.", MONDO_LOGFILE);
1665        log_msg(1, "Type:-");
1666        log_msg(1, "    mount-me");
1667        log_msg(1, "    chroot " MNT_RESTORING);
1668        log_msg(1, "    mount /boot");
1669        log_msg(1, "    grub-install '(hd0)'");
1670        log_msg(1, "    exit");
1671        log_msg(1, "    unmount-me");
1672        log_msg(1,
1673                "If you're really stuck, please e-mail the mailing list.");
1674    } else {
1675        mvaddstr_and_log_it(g_currentY++, 74, "Done.");
1676    }
1677    paranoid_free(rootdev);
1678    paranoid_free(rootdrive);
1679    paranoid_free(conffile);
1680    paranoid_free(command);
1681    paranoid_free(boot_device);
1682    paranoid_free(tmp);
1683    paranoid_free(editor);
1684
1685    return (res);
1686}
1687
1688/**************************************************************************
1689 *END_RUN_GRUB                                                            *
1690 **************************************************************************/
1691
1692
1693/**
1694 * Install ELILO on the user's boot drive (determined by elilo.conf).
1695 * @param offer_to_run_stabelilo If TRUE, then offer to hack the user's fstab for them.
1696 * @return 0 for success, nonzero for failure.
1697 */
1698int run_elilo(bool offer_to_run_stabelilo)
1699{
1700  /** malloc **/
1701    char *command;
1702    char *tmp;
1703    char *editor;
1704
1705    int res;
1706    int done;
1707
1708    malloc_string(command);
1709    malloc_string(tmp);
1710    malloc_string(editor);
1711    strcpy(editor, find_my_editor());
1712    if (offer_to_run_stabelilo
1713        && ask_me_yes_or_no("Did you change the mountlist?"))
1714
1715        /* interactive mode */
1716    {
1717        mvaddstr_and_log_it(g_currentY,
1718                            0,
1719                            "Modifying fstab and elilo.conf...                             ");
1720        sprintf(command, "stabelilo-me");
1721        res = run_program_and_log_output(command, 3);
1722        if (res) {
1723            popup_and_OK
1724                ("You will now edit fstab and elilo.conf, to make sure they match your new mountlist.");
1725            for (done = FALSE; !done;) {
1726                if (!g_text_mode) {
1727                    newtSuspend();
1728                }
1729                sprintf(tmp, "%s " MNT_RESTORING "/etc/fstab", editor);
1730                paranoid_system(tmp);
1731                sprintf(tmp, "%s " MNT_RESTORING "/etc/elilo.conf",
1732                        editor);
1733                paranoid_system(tmp);
1734                if (!g_text_mode) {
1735                    newtResume();
1736                }
1737//              newtCls();
1738                if (ask_me_yes_or_no("Edit them again?")) {
1739                    continue;
1740                }
1741                done = TRUE;
1742            }
1743        } else {
1744            log_to_screen("elilo.conf and fstab were modified OK");
1745        }
1746    } else
1747        /* nuke mode */
1748    {
1749        res = TRUE;
1750    }
1751    paranoid_free(command);
1752    paranoid_free(tmp);
1753    paranoid_free(editor);
1754    return (res);
1755}
1756
1757/**************************************************************************
1758 *END_RUN_ELILO                                                            *
1759 **************************************************************************/
1760
1761
1762/**
1763 * Install LILO on the user's boot drive (determined by /etc/lilo.conf).
1764 * @param offer_to_run_stablilo If TRUE, then offer to hack the user's fstab for them.
1765 * @return 0 for success, nonzero for failure.
1766 */
1767int run_lilo(bool offer_to_run_stablilo)
1768{
1769  /** malloc **/
1770    char *command;
1771    char *tmp;
1772    char *editor;
1773
1774    int res;
1775    int done;
1776    bool run_lilo_M = FALSE;
1777    malloc_string(command);
1778    malloc_string(tmp);
1779    malloc_string(editor);
1780
1781    if (!run_program_and_log_output
1782        ("grep \"boot.*=.*/dev/md\" " MNT_RESTORING "/etc/lilo.conf", 1)) {
1783        run_lilo_M = TRUE;
1784    }
1785
1786    strcpy(editor, find_my_editor());
1787    if (offer_to_run_stablilo
1788        && ask_me_yes_or_no("Did you change the mountlist?"))
1789
1790        /* interactive mode */
1791    {
1792        mvaddstr_and_log_it(g_currentY,
1793                            0,
1794                            "Modifying fstab and lilo.conf, and running LILO...                             ");
1795        sprintf(command, "stablilo-me");
1796        res = run_program_and_log_output(command, 3);
1797        if (res) {
1798            popup_and_OK
1799                ("You will now edit fstab and lilo.conf, to make sure they match your new mountlist.");
1800            for (done = FALSE; !done;) {
1801                if (!g_text_mode) {
1802                    newtSuspend();
1803                }
1804                sprintf(tmp, "%s " MNT_RESTORING "/etc/fstab", editor);
1805                paranoid_system(tmp);
1806                sprintf(tmp, "%s " MNT_RESTORING "/etc/lilo.conf", editor);
1807                paranoid_system(tmp);
1808                if (!g_text_mode) {
1809                    newtResume();
1810                }
1811//              newtCls();
1812                if (ask_me_yes_or_no("Edit them again?")) {
1813                    continue;
1814                }
1815                res =
1816                    run_program_and_log_output("chroot " MNT_RESTORING
1817                                               " lilo -L", 3);
1818                if (res) {
1819                    res =
1820                        run_program_and_log_output("chroot " MNT_RESTORING
1821                                                   " lilo", 3);
1822                }
1823                if (res) {
1824                    done =
1825                        ask_me_yes_or_no
1826                        ("LILO failed. Re-edit system files?");
1827                } else {
1828                    done = TRUE;
1829                }
1830            }
1831        } else {
1832            log_to_screen("lilo.conf and fstab were modified OK");
1833        }
1834    } else
1835        /* nuke mode */
1836    {
1837        mvaddstr_and_log_it(g_currentY,
1838                            0,
1839                            "Running LILO...                                                 ");
1840        res =
1841            run_program_and_log_output("chroot " MNT_RESTORING " lilo -L",
1842                                       3);
1843        if (res) {
1844            res =
1845                run_program_and_log_output("chroot " MNT_RESTORING " lilo",
1846                                           3);
1847        }
1848        if (res) {
1849            mvaddstr_and_log_it(g_currentY++, 74, "Failed.");
1850            log_to_screen
1851                ("Failed to re-jig fstab and/or lilo. Edit/run manually, please.");
1852        } else {
1853            mvaddstr_and_log_it(g_currentY++, 74, "Done.");
1854        }
1855    }
1856    if (run_lilo_M) {
1857        run_program_and_log_output("chroot " MNT_RESTORING
1858                                   " lilo -M /dev/hda", 3);
1859        run_program_and_log_output("chroot " MNT_RESTORING
1860                                   " lilo -M /dev/sda", 3);
1861    }
1862    paranoid_free(command);
1863    paranoid_free(tmp);
1864    paranoid_free(editor);
1865    return (res);
1866}
1867
1868/**************************************************************************
1869 *END_RUN_LILO                                                            *
1870 **************************************************************************/
1871
1872
1873/**
1874 * Install a raw MBR onto @p bd.
1875 * @param offer_to_hack_scripts If TRUE, then offer to hack the user's fstab for them.
1876 * @param bd The device to copy the stored MBR to.
1877 * @return 0 for success, nonzero for failure.
1878 */
1879int run_raw_mbr(bool offer_to_hack_scripts, char *bd)
1880{
1881  /** malloc **/
1882    char *command;
1883    char *boot_device;
1884    char *tmp;
1885    char *editor;
1886    int res;
1887    int done;
1888
1889    malloc_string(command);
1890    malloc_string(boot_device);
1891    malloc_string(tmp);
1892    malloc_string(editor);
1893    assert_string_is_neither_NULL_nor_zerolength(bd);
1894
1895    strcpy(editor, find_my_editor());
1896    strcpy(boot_device, bd);
1897    sprintf(command, "raw-MR %s /tmp/mountlist.txt", boot_device);
1898    log_msg(2, "run_raw_mbr() --- command='%s'", command);
1899
1900    if (offer_to_hack_scripts
1901        && ask_me_yes_or_no("Did you change the mountlist?"))
1902        /* interactive mode */
1903    {
1904        mvaddstr_and_log_it(g_currentY, 0,
1905                            "Modifying fstab and restoring MBR...                           ");
1906        for (done = FALSE; !done;) {
1907            if (!run_program_and_log_output("which vi", FALSE)) {
1908                popup_and_OK("You will now edit fstab");
1909                if (!g_text_mode) {
1910                    newtSuspend();
1911                }
1912                sprintf(tmp, "%s " MNT_RESTORING "/etc/fstab", editor);
1913                paranoid_system(tmp);
1914                if (!g_text_mode) {
1915                    newtResume();
1916                }
1917//              newtCls();
1918            }
1919            popup_and_get_string("Boot device",
1920                                 "Please confirm/enter the boot device. If in doubt, try /dev/hda",
1921                                 boot_device, MAX_STR_LEN / 4);
1922            sprintf(command, "stabraw-me %s", boot_device);
1923            res = run_program_and_log_output(command, 3);
1924            if (res) {
1925                done = ask_me_yes_or_no("Modifications failed. Re-try?");
1926            } else {
1927                done = TRUE;
1928            }
1929        }
1930    } else
1931        /* nuke mode */
1932    {
1933        mvaddstr_and_log_it(g_currentY, 0,
1934                            "Restoring MBR...                                               ");
1935        res = run_program_and_log_output(command, 3);
1936    }
1937    if (res) {
1938        mvaddstr_and_log_it(g_currentY++, 74, "Failed.");
1939        log_to_screen
1940            ("MBR+fstab processed w/error(s). See %s for more info.", MONDO_LOGFILE);
1941    } else {
1942        mvaddstr_and_log_it(g_currentY++, 74, "Done.");
1943    }
1944    paranoid_free(command);
1945    paranoid_free(boot_device);
1946    paranoid_free(tmp);
1947    paranoid_free(editor);
1948    return (res);
1949}
1950
1951/**************************************************************************
1952 *END_RUN_RAW_MBR                                                         *
1953 **************************************************************************/
1954
1955
1956
1957
1958
1959/**
1960 * Turn signal trapping on or off.
1961 * @param on If TRUE, then do full cleanup when we receive a signal; if FALSE, then
1962 * print a message and exit immediately.
1963 */
1964void set_signals(int on)
1965{
1966    int signals[] =
1967        { SIGKILL, SIGPIPE, SIGTERM, SIGHUP, SIGTRAP, SIGABRT, SIGINT,
1968SIGSTOP, 0 };
1969    int i;
1970    for (i = 0; signals[i]; i++) {
1971        if (on) {
1972            signal(signals[i], terminate_daemon);
1973        } else {
1974            signal(signals[i], termination_in_progress);
1975        }
1976    }
1977}
1978
1979/**************************************************************************
1980 *END_SET_SIGNALS                                                         *
1981 **************************************************************************/
1982
1983
1984/**
1985 * malloc() and set sensible defaults for the mondorestore filename variables.
1986 * @param bkpinfo The backup information structure. Fields used:
1987 * - @c bkpinfo->tmpdir
1988 * - @c bkpinfo->disaster_recovery
1989 */
1990void setup_MR_global_filenames()
1991{
1992    char *temppath;
1993
1994    assert(bkpinfo != NULL);
1995
1996    malloc_string(g_biggielist_txt);
1997    malloc_string(g_filelist_full);
1998    malloc_string(g_filelist_imagedevs);
1999    malloc_string(g_imagedevs_restthese);
2000    malloc_string(g_mondo_cfg_file);
2001    malloc_string(g_mountlist_fname);
2002    malloc_string(g_mondo_home);
2003    malloc_string(g_tmpfs_mountpt);
2004    malloc_string(g_isodir_device);
2005    malloc_string(g_isodir_format);
2006
2007    temppath = bkpinfo->tmpdir;
2008
2009    sprintf(g_biggielist_txt, "%s/%s", temppath, BIGGIELIST_TXT_STUB);
2010    sprintf(g_filelist_full, "%s/%s", temppath, FILELIST_FULL_STUB);
2011    sprintf(g_filelist_imagedevs, "%s/tmp/filelist.imagedevs", temppath);
2012//  sprintf(g_imagedevs_pot, "%s/tmp/imagedevs.pot", temppath);
2013    sprintf(g_imagedevs_restthese, "%s/tmp/imagedevs.restore-these",
2014            temppath);
2015    if (bkpinfo->disaster_recovery) {
2016        sprintf(g_mondo_cfg_file, "/%s", MONDO_CFG_FILE_STUB);
2017        sprintf(g_mountlist_fname, "/%s", MOUNTLIST_FNAME_STUB);
2018    } else {
2019        sprintf(g_mondo_cfg_file, "%s/%s", temppath, MONDO_CFG_FILE_STUB);
2020        sprintf(g_mountlist_fname, "%s/%s", temppath,
2021                MOUNTLIST_FNAME_STUB);
2022    }
2023}
2024
2025/**************************************************************************
2026 *END_SET_GLOBAL_FILENAME                                                 *
2027 **************************************************************************/
2028
2029
2030/**
2031 * Copy @p input_file (containing the result of a compare) to @p output_file,
2032 * deleting spurious "changes" along the way.
2033 * @param output_file The output file to write with spurious changes removed.
2034 * @param input_file The input file, a list of changed files created by a compare.
2035 */
2036void streamline_changes_file(char *output_file, char *input_file)
2037{
2038    FILE *fin;
2039    FILE *fout;
2040  /** malloc **/
2041    char *incoming;
2042
2043    assert_string_is_neither_NULL_nor_zerolength(output_file);
2044    assert_string_is_neither_NULL_nor_zerolength(input_file);
2045    malloc_string(incoming);
2046
2047    if (!(fin = fopen(input_file, "r"))) {
2048        log_OS_error(input_file);
2049        return;
2050    }
2051    if (!(fout = fopen(output_file, "w"))) {
2052        fatal_error("cannot open output_file");
2053    }
2054    for (fgets(incoming, MAX_STR_LEN - 1, fin); !feof(fin);
2055         fgets(incoming, MAX_STR_LEN - 1, fin)) {
2056        if (strncmp(incoming, "etc/adjtime", 11)
2057            && strncmp(incoming, "etc/mtab", 8)
2058            && strncmp(incoming, "tmp/", 4)
2059            && strncmp(incoming, "boot/map", 8)
2060            && !strstr(incoming, "incheckentry")
2061            && strncmp(incoming, "etc/mail/statistics", 19)
2062            && strncmp(incoming, "var/", 4))
2063            fprintf(fout, "%s", incoming);  /* don't need \n here, for some reason.. */
2064    }
2065    paranoid_fclose(fout);
2066    paranoid_fclose(fin);
2067    paranoid_free(incoming);
2068}
2069
2070/**************************************************************************
2071 *END_STREAMLINE_CHANGES_FILE                                             *
2072 **************************************************************************/
2073
2074
2075/**
2076 * Exit due to a signal (normal cleanup).
2077 * @param sig The signal we're exiting due to.
2078 */
2079void terminate_daemon(int sig)
2080{
2081    log_to_screen
2082        ("Mondorestore is terminating in response to a signal from the OS");
2083    paranoid_MR_finish(254);
2084}
2085
2086/**************************************************************************
2087 *END_TERMINATE_DAEMON                                                    *
2088 **************************************************************************/
2089
2090
2091/**
2092 * Give the user twenty seconds to press Ctrl-Alt-Del before we nuke their drives.
2093 */
2094void twenty_seconds_til_yikes()
2095{
2096    int i;
2097    /* MALLOC * */
2098    char *tmp;
2099
2100    malloc_string(tmp);
2101    if (does_file_exist("/tmp/NOPAUSE")) {
2102        return;
2103    }
2104    open_progress_form("CAUTION",
2105                       "Be advised: I am about to ERASE your hard disk(s)!",
2106                       "You may press Ctrl+Alt+Del to abort safely.",
2107                       "", 20);
2108    for (i = 0; i < 20; i++) {
2109        g_current_progress = i;
2110        sprintf(tmp, "You have %d seconds left to abort.", 20 - i);
2111        update_progress_form(tmp);
2112        sleep(1);
2113    }
2114    close_progress_form();
2115    paranoid_free(tmp);
2116}
2117
2118/**************************************************************************
2119 *END_TWENTY_SECONDS_TIL_YIKES                                            *
2120 **************************************************************************/
2121
2122
2123
2124
2125
2126/**
2127 * Exit due to a signal (no cleanup).
2128 * @param sig The signal we're exiting due to.
2129 */
2130void termination_in_progress(int sig)
2131{
2132    log_msg(1, "Termination in progress");
2133    usleep(1000);
2134    pthread_exit(0);
2135}
2136
2137/**************************************************************************
2138 *END_TERMINATION_IN_PROGRESS                                             *
2139 **************************************************************************/
2140
2141
2142
2143/**
2144 * Unmount all devices in @p p_external_copy_of_mountlist.
2145 * @param p_external_copy_of_mountlist The mountlist to guide the devices to unmount.
2146 * @return 0 for success, nonzero for failure.
2147 */
2148int unmount_all_devices(struct mountlist_itself
2149                        *p_external_copy_of_mountlist)
2150{
2151    struct mountlist_itself *mountlist;
2152    int retval = 0, lino, res = 0, i;
2153    char *command;
2154    char *tmp;
2155
2156    malloc_string(command);
2157    malloc_string(tmp);
2158    assert(p_external_copy_of_mountlist != NULL);
2159
2160    mountlist = malloc(sizeof(struct mountlist_itself));
2161    memcpy((void *) mountlist, (void *) p_external_copy_of_mountlist,
2162           sizeof(struct mountlist_itself));
2163    sort_mountlist_by_mountpoint(mountlist, 0);
2164
2165    run_program_and_log_output("df -m", 3);
2166    mvaddstr_and_log_it(g_currentY, 0, "Unmounting devices      ");
2167    open_progress_form("Unmounting devices",
2168                       "Unmounting all devices that were mounted,",
2169                       "in preparation for the post-restoration reboot.",
2170                       "", mountlist->entries);
2171    chdir("/");
2172    for (i = 0;
2173         i < 10
2174         &&
2175         run_program_and_log_output
2176         ("ps | grep buffer | grep -v \"grep buffer\"", TRUE) == 0;
2177         i++) {
2178        sleep(1);
2179        log_msg(2, "Waiting for buffer() to finish");
2180    }
2181
2182    paranoid_system("sync");
2183
2184    sprintf(tmp, "cp -f %s " MNT_RESTORING "/var/log", MONDO_LOGFILE);
2185    if (run_program_and_log_output(tmp, FALSE)) {
2186        log_msg(1,
2187                "Error. Failed to copy log to PC's /var/log dir. (Mounted read-only?)");
2188    }
2189    if (does_file_exist("/tmp/DUMBASS-GENTOO")) {
2190        run_program_and_log_output("mkdir -p " MNT_RESTORING
2191                                   "/mnt/.boot.d", 5);
2192    }
2193    for (lino = mountlist->entries - 1; lino >= 0; lino--) {
2194        if (!strcmp(mountlist->el[lino].mountpoint, "lvm")) {
2195            continue;
2196        }
2197        sprintf(tmp, "Unmounting device %s  ", mountlist->el[lino].device);
2198
2199        update_progress_form(tmp);
2200        if (is_this_device_mounted(mountlist->el[lino].device)) {
2201            if (!strcmp(mountlist->el[lino].mountpoint, "swap")) {
2202                sprintf(command, "swapoff %s", mountlist->el[lino].device);
2203            } else {
2204                if (!strcmp(mountlist->el[lino].mountpoint, "/1")) {
2205                    sprintf(command, "umount %s/", MNT_RESTORING);
2206                    log_msg(3,
2207                            "Well, I know a certain kitty-kitty who'll be sleeping with Mommy tonight...");
2208                } else {
2209                    sprintf(command, "umount " MNT_RESTORING "%s",
2210                            mountlist->el[lino].mountpoint);
2211                }
2212            }
2213            log_msg(10, "The 'umount' command is '%s'", command);
2214            res = run_program_and_log_output(command, 3);
2215        } else {
2216            strcat(tmp, "...not mounted anyway :-) OK");
2217            res = 0;
2218        }
2219        g_current_progress++;
2220        if (res) {
2221            strcat(tmp, "...Failed");
2222            retval++;
2223            log_to_screen(tmp);
2224        } else {
2225            log_msg(2, tmp);
2226        }
2227    }
2228    close_progress_form();
2229    if (retval) {
2230        mvaddstr_and_log_it(g_currentY++, 74, "Failed.");
2231    } else {
2232        mvaddstr_and_log_it(g_currentY++, 74, "Done.");
2233    }
2234    if (retval) {
2235        log_to_screen("Unable to unmount some of your partitions.");
2236    } else {
2237        log_to_screen("All partitions were unmounted OK.");
2238    }
2239    free(mountlist);
2240    paranoid_free(command);
2241    paranoid_free(tmp);
2242    return (retval);
2243}
2244
2245/**************************************************************************
2246 *END_UNMOUNT_ALL_DEVICES                                                 *
2247 **************************************************************************/
2248
2249
2250
2251/**
2252 * Extract mondo-restore.cfg and the mountlist from the tape inserted
2253 * to the ./tmp/ directory.
2254 * @param dev The tape device to read from.
2255 * @return 0 for success, nonzero for failure.
2256 */
2257int extract_cfg_file_and_mountlist_from_tape_dev(char *dev)
2258{
2259    char *command;
2260    int res = 0;
2261    // BCO: below 32KB seems to block at least on RHAS 2.1 and MDK 10.0
2262    long tape_block_size = 32768;
2263
2264    malloc_string(command);
2265
2266    // tar -zxvf-
2267    sprintf(command,
2268            "dd if=%s bs=%ld count=%ld 2> /dev/null | tar -zx %s %s %s %s %s",
2269            dev,
2270            tape_block_size,
2271            1024L * 1024 * 32 / tape_block_size,
2272            MOUNTLIST_FNAME_STUB, MONDO_CFG_FILE_STUB,
2273            BIGGIELIST_TXT_STUB, FILELIST_FULL_STUB, "tmp/i-want-my-lvm");
2274    log_msg(2, "command = '%s'", command);
2275    res = run_program_and_log_output(command, -1);
2276    if (res != 0 && does_file_exist(MONDO_CFG_FILE_STUB)) {
2277        res = 0;
2278    }
2279    paranoid_free(command);
2280    return (res);
2281}
2282
2283
2284
2285/**
2286 * Get the configuration file from the floppy, tape, or CD.
2287 * @param bkpinfo The backup information structure. Fields used:
2288 * - @c bkpinfo->backup_media_type
2289 * - @c bkpinfo->media_device
2290 * - @c bkpinfo->tmpdir
2291 * @return 0 for success, nonzero for failure.
2292 */
2293int get_cfg_file_from_archive()
2294{
2295    int retval = 0;
2296
2297   /** malloc *****/
2298    char *device;
2299    char *command;
2300    char *cfg_file;
2301    char *mounted_cfgf_path;
2302    char *tmp;
2303    char *mountpt;
2304    char *ramdisk_fname;
2305    char *mountlist_file;
2306    int res;
2307
2308    bool try_plan_B;
2309
2310    assert(bkpinfo != NULL);
2311    malloc_string(cfg_file);
2312    malloc_string(mounted_cfgf_path);
2313    malloc_string(mountpt);
2314    malloc_string(ramdisk_fname);
2315    malloc_string(mountlist_file);
2316    malloc_string(device);
2317    malloc_string(command);
2318    malloc_string(tmp);
2319    log_msg(2, "gcffa --- starting");
2320    log_to_screen("I'm thinking...");
2321    sprintf(mountpt, "%s/mount.bootdisk", bkpinfo->tmpdir);
2322    device[0] = '\0';
2323    chdir(bkpinfo->tmpdir);
2324    strcpy(cfg_file, MONDO_CFG_FILE_STUB);
2325    unlink(cfg_file);           // cfg_file[] is missing the '/' at the start, FYI, by intent
2326    unlink(FILELIST_FULL_STUB);
2327    unlink(BIGGIELIST_TXT_STUB);
2328    unlink("tmp/i-want-my-lvm");
2329    sprintf(command, "mkdir -p %s", mountpt);
2330    run_program_and_log_output(command, FALSE);
2331
2332//   unlink( "tmp/mondo-restore.cfg" ); // superfluous, surely?
2333
2334    sprintf(cfg_file, "%s/%s", bkpinfo->tmpdir, MONDO_CFG_FILE_STUB);
2335    sprintf(mountlist_file, "%s/%s", bkpinfo->tmpdir,
2336            MOUNTLIST_FNAME_STUB);
2337    //   make_hole_for_file( cfg_file );
2338    //   make_hole_for_file( mountlist_file);
2339    log_msg(2, "mountpt = %s; cfg_file=%s", mountpt, cfg_file);
2340
2341    /* Floppy? */
2342    sprintf(tmp, "mkdir -p %s", mountpt);
2343    run_program_and_log_output(tmp, FALSE);
2344    sprintf(tmp, "mkdir -p %s/tmp", bkpinfo->tmpdir);
2345    run_program_and_log_output(tmp, FALSE);
2346
2347    /* Is there a floppy drive detected */
2348    sprintf(tmp, "%s", call_program_and_get_last_line_of_output("dmesg | grep -i floppy"));
2349    if (strcmp(tmp, "")) {
2350        sprintf(command, "mount /dev/fd0u1722 %s", mountpt);
2351        sprintf(tmp,
2352            "(sleep 15; kill `ps | grep \"%s\" | cut -d' ' -f1` 2> /dev/null) &",
2353            command);
2354        log_msg(1, "tmp = '%s'", tmp);
2355        system(tmp);
2356        res = run_program_and_log_output(command, FALSE);
2357        if (res) {
2358            sprintf(command, "mount /dev/fd0H1440 %s", mountpt);
2359            res = run_program_and_log_output(command, FALSE);
2360        }
2361    } else {
2362        res = 1;
2363    }
2364    if (res) {
2365        try_plan_B = TRUE;
2366    } else {
2367        try_plan_B = TRUE;
2368        log_msg(2,
2369                "Mounted floppy OK but I don't trust it because the archives might contain more up-to-date config file than the floppy does.");
2370        // NB: If busybox does not support 'mount -o loop' then Plan A WILL NOT WORK.
2371        log_msg(2, "Processing floppy (plan A?)");
2372        sprintf(ramdisk_fname, "%s/mindi.rdz", mountpt);
2373        if (!does_file_exist(ramdisk_fname)) {
2374            sprintf(ramdisk_fname, "%s/initrd.img", mountpt);
2375        }
2376        if (!does_file_exist(ramdisk_fname)) {
2377            log_msg(2,
2378                    "Cannot find ramdisk file on mountpoint. Are you sure that's a boot disk in the drive?");
2379        }
2380        if (extract_config_file_from_ramdisk(ramdisk_fname, cfg_file, mountlist_file)) {
2381            log_msg(2,
2382                    "Warning - failed to extract config file from ramdisk. I think this boot disk is mangled.");
2383        }
2384        sprintf(command, "umount %s", mountpt);
2385        run_program_and_log_output(command, 5);
2386        unlink(ramdisk_fname);
2387    }
2388    if (!does_file_exist(cfg_file)) {
2389        log_msg(2, "gcffa --- we don't have cfg file yet.");
2390        if (IS_THIS_A_STREAMING_BACKUP(bkpinfo->backup_media_type)) {
2391            try_plan_B = TRUE;
2392        } else {
2393            log_msg(2, "gcffa --- calling mount_cdrom now :)");
2394            if (!mount_cdrom()) {
2395                log_msg(2,
2396                        "gcffa --- managed to mount CD; so, no need for Plan B");
2397                try_plan_B = FALSE;
2398            } else {
2399                try_plan_B = TRUE;
2400            }
2401            if (what_number_cd_is_this() > 1) {
2402                insist_on_this_cd_number((g_current_media_number = 1));
2403            }
2404        }
2405        if (try_plan_B) {
2406            log_msg(2, "gcffa --- OK, switching to Plan B");
2407            chdir(bkpinfo->tmpdir);
2408            run_program_and_log_output("mkdir -p tmp", FALSE);
2409
2410            if (strlen(bkpinfo->media_device) == 0) {
2411                strcpy(bkpinfo->media_device, "/dev/st0");
2412                log_msg(2, "media_device is blank; assuming %s");
2413            }
2414            strcpy(tmp, bkpinfo->media_device);
2415            if (extract_cfg_file_and_mountlist_from_tape_dev
2416                (bkpinfo->media_device)) {
2417                strcpy(bkpinfo->media_device, "/dev/st0");
2418                if (extract_cfg_file_and_mountlist_from_tape_dev
2419                    (bkpinfo->media_device)) {
2420                    strcpy(bkpinfo->media_device, "/dev/osst0");
2421                    if (extract_cfg_file_and_mountlist_from_tape_dev
2422                        (bkpinfo->media_device)) {
2423                        strcpy(bkpinfo->media_device, "/dev/ht0");
2424                        if (extract_cfg_file_and_mountlist_from_tape_dev
2425                            (bkpinfo->media_device)) {
2426                            log_msg(3,
2427                                    "I tried lots of devices but none worked.");
2428                            strcpy(bkpinfo->media_device, tmp);
2429                        }
2430                    }
2431                }
2432            }
2433
2434            if (!does_file_exist("tmp/mondo-restore.cfg")) {
2435                log_to_screen("Cannot find config info on tape/CD/floppy");
2436                return (1);
2437            }
2438        } else {
2439            /* That boot imae doesn't always exist where the following method always works
2440            log_msg(2,
2441                    "gcffa --- looking at mounted CD for mindi-boot.2880.img");
2442            sprintf(command,
2443                    "mount " MNT_CDROM
2444                    "/images/mindi-boot.2880.img -o loop %s", mountpt);
2445            sprintf(mounted_cfgf_path, "%s/%s", mountpt, cfg_file);
2446            if (!does_file_exist(mounted_cfgf_path)) {
2447            */
2448                log_msg(2,
2449                        "gcffa --- Plan B, a.k.a. untarring some file from all.tar.gz");
2450                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
2451                run_program_and_log_output(command, TRUE);
2452                if (!does_file_exist(MONDO_CFG_FILE_STUB)) {
2453                    fatal_error
2454                        ("Please reinsert the disk/CD and try again.");
2455                }
2456                    /*
2457            }
2458                */
2459        }
2460    }
2461    if (does_file_exist(MONDO_CFG_FILE_STUB)) {
2462        log_msg(1, "gcffa --- great! We've got the config file");
2463        sprintf(tmp, "%s/%s",
2464                call_program_and_get_last_line_of_output("pwd"),
2465                MONDO_CFG_FILE_STUB);
2466        sprintf(command, "cp -f %s %s", tmp, cfg_file);
2467        iamhere(command);
2468        if (strcmp(tmp, cfg_file)
2469            && run_program_and_log_output(command, 1)) {
2470            log_msg(1,
2471                    "... but an error occurred when I tried to move it to %s",
2472                    cfg_file);
2473        } else {
2474            log_msg(1, "... and I moved it successfully to %s", cfg_file);
2475        }
2476        sprintf(command, "cp -f %s/%s %s",
2477                call_program_and_get_last_line_of_output("pwd"),
2478                MOUNTLIST_FNAME_STUB, mountlist_file);
2479        iamhere(command);
2480        if (strcmp(tmp, cfg_file)
2481            && run_program_and_log_output(command, 1)) {
2482            log_msg(1, "Failed to get mountlist");
2483        } else {
2484            log_msg(1, "Got mountlist too");
2485            sprintf(command, "cp -f %s %s", mountlist_file,
2486                    g_mountlist_fname);
2487            if (run_program_and_log_output(command, 1)) {
2488                log_msg(1, "Failed to copy mountlist to /tmp");
2489            } else {
2490                log_msg(1, "Copied mountlist to /tmp as well OK");
2491                sprintf(command, "cp -f tmp/i-want-my-lvm /tmp/");
2492                run_program_and_log_output(command, 1);
2493/*        sprintf(command, "grep \" lvm \" %s", g_mountlist_fname);
2494          if (!run_program_and_log_output(command, 5) && !does_file_exist("/tmp/i-want-my-lvm"))
2495            {
2496          log_msg(1, "Warning. You want LVM but I don't have i-want-my-lvm. FIXME.");
2497        }
2498              else if (run_program_and_log_output(command,5) && does_file_exist("/tmp/i-want-my-lvm"))
2499                {
2500          log_msg(1, "Warning. You don't want LVM but i-want-my-lvm exists. I'll delete it. Cool.");
2501              do_my_funky_lvm_stuff(TRUE, FALSE); // ...after I stop any LVMs :)
2502          stop_raid_device("/dev/md0");
2503          stop_raid_device("/dev/md1");
2504          stop_raid_device("/dev/md2");
2505          unlink("/tmp/i-want-my-lvm");
2506        }
2507          else if (!run_program_and_log_output(command,5) && does_file_exist("/tmp/i-want-my-lvm"))
2508            {
2509          log_msg(1, "You had better pray that i-want-my-lvm patches your mountlist. FIXME.");
2510        }
2511*/
2512            }
2513        }
2514    }
2515    run_program_and_log_output("umount " MNT_CDROM, FALSE);
2516    if (!does_file_exist(cfg_file)) {
2517        iamhere(cfg_file);
2518        log_msg(1, "%s not found", cfg_file);
2519        log_to_screen
2520            ("Oh dear. Unable to recover configuration file from boot disk");
2521        return (1);
2522    }
2523
2524    log_to_screen("Recovered mondo-restore.cfg");
2525    if (!does_file_exist(MOUNTLIST_FNAME_STUB)) {
2526        log_to_screen("...but not mountlist.txt - a pity, really...");
2527    }
2528/* start SAH */
2529    else {
2530        sprintf(command, "cp -f %s %s/%s", MOUNTLIST_FNAME_STUB,
2531                bkpinfo->tmpdir, MOUNTLIST_FNAME_STUB);
2532        run_program_and_log_output(command, FALSE);
2533    }
2534/*--commented out by SAH
2535  sprintf( command, "cp -f %s %s/%s", cfg_file, bkpinfo->tmpdir, MONDO_CFG_FILE_STUB );
2536  run_program_and_log_output( command, FALSE );
2537  sprintf( command, "cp -f %s %s/%s", mountlist_file, bkpinfo->tmpdir, MOUNTLIST_FNAME_STUB );
2538  run_program_and_log_output( command, FALSE );
2539*/
2540/* end SAH */
2541
2542    sprintf(command, "cp -f %s /%s", cfg_file, MONDO_CFG_FILE_STUB);
2543    run_program_and_log_output(command, FALSE);
2544    sprintf(command, "cp -f %s /%s", mountlist_file, MOUNTLIST_FNAME_STUB);
2545    run_program_and_log_output(command, FALSE);
2546    sprintf(command, "cp -f etc/raidtab /etc/");
2547    run_program_and_log_output(command, FALSE);
2548    sprintf(command, "cp -f tmp/i-want-my-lvm /tmp/");
2549    run_program_and_log_output(command, FALSE);
2550    g_backup_media_type = bkpinfo->backup_media_type;
2551    paranoid_free(device);
2552    paranoid_free(command);
2553    paranoid_free(tmp);
2554    paranoid_free(cfg_file);
2555    paranoid_free(mounted_cfgf_path);
2556    paranoid_free(mountpt);
2557    paranoid_free(ramdisk_fname);
2558    paranoid_free(mountlist_file);
2559    return (retval);
2560}
2561
2562/**************************************************************************
2563 *END_GET_CFG_FILE_FROM_ARCHIVE                                           *
2564 **************************************************************************/
2565
2566/* @} - end restoreUtilityGroup */
2567
2568
2569/***************************************************************************
2570 * F@                                                                      *
2571 * () -- Hugo Rabson                                  *
2572 *                                                                         *
2573 * Purpose:                                                                *
2574 *                                                                         *
2575 * Called by:                                                              *
2576 * Params:    -                      -                                     *
2577 * Returns:   0=success; nonzero=failure                                   *
2578 ***************************************************************************/
2579
2580
2581
2582void wait_until_software_raids_are_prepped(char *mdstat_file,
2583                                           int wait_for_percentage)
2584{
2585    struct raidlist_itself *raidlist;
2586    int unfinished_mdstat_devices = 9999, i;
2587    char *screen_message;
2588
2589    malloc_string(screen_message);
2590    raidlist = malloc(sizeof(struct raidlist_itself));
2591
2592    assert(wait_for_percentage <= 100);
2593    iamhere("wait_until_software_raids_are_prepped");
2594    while (unfinished_mdstat_devices > 0) {
2595            // FIXME: Prefix '/dev/' should really be dynamic!
2596        if (parse_mdstat(raidlist, "/dev/")) {
2597            log_to_screen("Sorry, cannot read %s", MDSTAT_FILE);
2598            log_msg(1,"Sorry, cannot read %s", MDSTAT_FILE);
2599            return;
2600        }
2601        for (unfinished_mdstat_devices = i = 0; i <= raidlist->entries; i++) {
2602            if (raidlist->el[i].progress < wait_for_percentage) {
2603                unfinished_mdstat_devices++;
2604                if (raidlist->el[i].progress == -1) // delayed while another partition inits
2605                {
2606                    continue;
2607                }
2608                log_msg(1,"Sync'ing %s (i=%d)", raidlist->el[i].raid_device, i);
2609                sprintf(screen_message, "Sync'ing %s",
2610                        raidlist->el[i].raid_device);
2611                open_evalcall_form(screen_message);
2612                while (raidlist->el[i].progress < wait_for_percentage) {
2613                    log_msg(1,"Percentage sync'ed: %d", raidlist->el[i].progress);
2614                    update_evalcall_form(raidlist->el[i].progress);
2615                    sleep(2);
2616                    // FIXME: Prefix '/dev/' should really be dynamic!
2617                    if (parse_mdstat(raidlist, "/dev/")) {
2618                        break;
2619                    }
2620                }
2621                close_evalcall_form();
2622            }
2623        }
2624    }
2625    paranoid_free(screen_message);
2626    paranoid_free(raidlist);
2627}
Note: See TracBrowser for help on using the repository browser.