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

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

Render bkpinfo global (potential issue on thread, but should not be a problem as that structure is indeed static during archive)
Should solve the tmpdir issue from previous rev.
May still not compile

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