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

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

merge -r489:506 $SVN_M/branches/stable

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