source: MondoRescue/branches/2.2.7/mondo/src/mondorestore/mondo-rstr-tools.c@ 1996

Last change on this file since 1996 was 1996, checked in by Bruno Cornec, 16 years ago

small cleanup

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