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

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

merge -r 542:560 $SVN_M/branches/stable

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