source: MondoRescue/branches/2.2.2/mondo/src/mondorestore/mondo-rstr-tools.c @ 1322

Last change on this file since 1322 was 1322, checked in by Bruno Cornec, 14 years ago

Idem

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