source: MondoRescue/trunk/mondo/mondo/mondorestore/mondo-rstr-tools.c@ 149

Last change on this file since 149 was 149, checked in by bcornec, 18 years ago

merge -r144:148 $SVN_M/branches/2.05

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