source: MondoRescue/branches/stable/mondo/mondo/mondorestore/mondo-rstr-tools.c@ 497

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

Integration of a big patch from rene-marc dolhen <rmd_at_mecreant.org> to support internationalization with gettext.

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