source: MondoRescue/branches/stable/mondo/src/mondorestore/mondo-restore.c@ 1108

Last change on this file since 1108 was 1108, checked in by Bruno Cornec, 17 years ago

log_msg => mr_msg for main files

  • Property svn:keywords set to Id
File size: 100.4 KB
Line 
1/***************************************************************************
2* restores mondoarchive data
3* $Id: mondo-restore.c 1108 2007-02-07 23:10:16Z bruno $
4***************************************************************************/
5
6/**
7 * @file
8 * The main file for mondorestore.
9 */
10
11/**************************************************************************
12 * #include statements *
13 **************************************************************************/
14#include <pthread.h>
15#include "my-stuff.h"
16#include "../common/mondostructures.h"
17#include "../common/libmondo.h"
18#include "mr-externs.h"
19#include "mondo-restore.h"
20#include "mondo-rstr-compare-EXT.h"
21#include "mondo-rstr-tools-EXT.h"
22#include "mr_mem.h"
23
24extern void twenty_seconds_til_yikes(void);
25
26
27/* For use in other programs (ex. XMondo) */
28#ifdef MONDORESTORE_MODULE
29#define main __mondorestore_main
30#define g_ISO_restore_mode __mondorestore_g_ISO_restore_mode
31#endif
32
33//static char cvsid[] = "$Id: mondo-restore.c 1108 2007-02-07 23:10:16Z bruno $";
34
35/**************************************************************************
36 * Globals *
37 **************************************************************************/
38extern char *g_tmpfs_mountpt; // declared in libmondo-tools.c
39extern struct s_bkpinfo *g_bkpinfo_DONTUSETHIS; // used by finish() to free
40 // up global bkpinfo struct
41extern bool g_text_mode;
42extern FILE *g_fprep;
43extern double g_kernel_version;
44extern int g_partition_table_locked_up;
45extern int g_noof_rows;
46
47extern int partition_everything(struct mountlist_itself *mountlist);
48
49
50/**
51 * @name Restore-Time Globals
52 * @ingroup globalGroup
53 * @{
54 */
55/**
56 * If TRUE, then SIGPIPE was just caught.
57 * Set by the signal handler; cleared after it's handled.
58 */
59bool g_sigpipe_caught = FALSE;
60
61/**
62 * If TRUE, then we're restoring from ISOs or an NFS server.
63 * If FALSE, then we're restoring from some kind of real media (tape, CD, etc.)
64 */
65bool g_ISO_restore_mode = FALSE; /* are we in Iso Mode? */
66
67/**
68 * If TRUE, then we have had a successful "nuke" restore.
69 */
70bool g_I_have_just_nuked = FALSE;
71
72/**
73 * The device to mount to get at the ISO images. Ignored unless @p g_ISO_restore_mode.
74 */
75char *g_isodir_device;
76
77/**
78 * The format of @p g_isodir_device. Ignored unless @p g_ISO_restore_mode.
79 */
80char *g_isodir_format;
81
82/**
83 * The location of 'biggielist.txt', containing the biggiefiles on the current archive set.
84 */
85char *g_biggielist_txt;
86
87/**
88 * The location of 'filelist.full', containing all files (<em>including biggiefiles</em>) on
89 * the current archive set.
90 */
91char *g_filelist_full;
92
93/**
94 * The location of a file containing a list of the devices that were archived
95 * as images, not as individual files.
96 */
97char *g_filelist_imagedevs;
98
99/**
100 * The location of a file containing a list of imagedevs to actually restore.
101 * @see g_filelist_imagedevs
102 */
103char *g_imagedevs_restthese;
104
105/**
106 * The location of 'mondo-restore.cfg', containing the metadata
107 * information for this backup.
108 */
109char *g_mondo_cfg_file;
110
111/**
112 * The location of 'mountlist.txt', containing the information on the
113 * user's partitions and hard drives.
114 */
115char *g_mountlist_fname;
116
117/**
118 * Mondo's home directory during backup. Unused in mondo-restore; included
119 * to avoid link errors.
120 */
121char *g_mondo_home;
122
123/* Busybox ps has no option and PID in first pos */
124char *ps_options = "";
125char *ps_proc_id = "$1";
126
127extern char *g_getfacl;
128extern char *g_getfattr;
129
130/* @} - end of "Restore-Time Globals" in globalGroup */
131
132
133
134extern int copy_from_src_to_dest(FILE * f_orig, FILE * f_archived,
135 char direction);
136
137
138
139/**************************************************************************
140 * COMPAQ PROLIANT Stuff: needs some special help *
141**************************************************************************/
142
143/**
144 * The message to display if we detect that the user is using a Compaq Proliant.
145 */
146#define COMPAQ_PROLIANTS_SUCK "Partition and format your disk using Compaq's disaster recovery CD. After you've done that, please reboot with your Mondo CD/floppy in Interactive Mode."
147
148
149
150
151/**
152 * Allow the user to modify the mountlist before we partition & format their drives.
153 * @param bkpinfo The backup information structure. @c disaster_recovery is the only field used.
154 * @param mountlist The mountlist to let the user modify.
155 * @param raidlist The raidlist that goes with @p mountlist.
156 * @return 0 for success, nonzero for failure.
157 * @ingroup restoreGuiGroup
158 */
159int let_user_edit_the_mountlist(struct s_bkpinfo *bkpinfo,
160 struct mountlist_itself *mountlist,
161 struct raidlist_itself *raidlist)
162{
163 int retval = 0, res = 0;
164
165 mr_msg(2, "let_user_edit_the_mountlist() --- starting");
166
167 assert(bkpinfo != NULL);
168 assert(mountlist != NULL);
169 assert(raidlist != NULL);
170 if (!bkpinfo->disaster_recovery) {
171 strcpy(g_mountlist_fname, "/tmp/mountlist.txt");
172 mr_msg(2, "I guess you're testing edit_mountlist()");
173 }
174 if (!does_file_exist(g_mountlist_fname)) {
175 log_to_screen(g_mountlist_fname);
176 log_to_screen("does not exist");
177 return (1);
178 }
179
180 retval = load_mountlist(mountlist, g_mountlist_fname);
181 load_raidtab_into_raidlist(raidlist, RAIDTAB_FNAME);
182 if (retval) {
183 log_to_screen
184 ("Warning - load_raidtab_into_raidlist returned an error");
185 }
186 res = edit_mountlist(g_mountlist_fname, mountlist, raidlist);
187 if (res) {
188 return (1);
189 }
190
191 save_mountlist_to_disk(mountlist, g_mountlist_fname);
192 save_raidlist_to_raidtab(raidlist, RAIDTAB_FNAME);
193
194 log_to_screen("I have finished editing the mountlist for you.");
195
196 return (retval);
197}
198
199
200
201
202
203/**
204 * Determine whether @p mountlist contains a Compaq diagnostic partition.
205 * @param mountlist The mountlist to examine.
206 * @return TRUE if there's a Compaq diagnostic partition; FALSE if not.
207 * @ingroup restoreUtilityGroup
208 */
209bool
210partition_table_contains_Compaq_diagnostic_partition(struct
211 mountlist_itself *
212 mountlist)
213{
214 int i;
215
216 assert(mountlist != NULL);
217
218 for (i = 0; i < mountlist->entries; i++) {
219 if (strstr(mountlist->el[i].format, "ompaq")) {
220 mr_msg(2, "mountlist[%d] (%s) is %s (Compaq alert!)",
221 i, mountlist->el[i].device, mountlist->el[i].format);
222
223 return (TRUE);
224 }
225 }
226 return (FALSE);
227}
228
229/**************************************************************************
230 *END_PARTITION_TABLE_CONTAINS_COMPAQ_DIAGNOSTIC_PARTITION *
231 **************************************************************************/
232
233
234/**
235 * Allow the user to abort the backup if we find that there is a Compaq diagnostic partition.
236 * @note This function does not actually check for the presence of a Compaq partition.
237 * @ingroup restoreUtilityGroup
238 */
239void offer_to_abort_because_Compaq_Proliants_suck(void)
240{
241 popup_and_OK(COMPAQ_PROLIANTS_SUCK);
242 if (ask_me_yes_or_no
243 ("Would you like to reboot and use your Compaq CD to prep your hard drive?"))
244 {
245 fatal_error
246 ("Aborting. Please reboot and prep your hard drive with your Compaq CD.");
247 }
248}
249
250/**************************************************************************
251 *END_OFFER_TO_ABORT_BECAUSE_COMPAQ_PROLIANTS_SUCK *
252 **************************************************************************/
253
254
255
256/**
257 * Call interactive_mode(), nuke_mode(), or compare_mode() depending on the user's choice.
258 * @param bkpinfo The backup information structure. Most fields are used.
259 * @param mountlist The mountlist containing information about the user's partitions.
260 * @param raidlist The raidlist to go with @p mountlist.
261 * @return The return code from the mode function called.
262 * @ingroup restoreGroup
263 */
264int
265catchall_mode(struct s_bkpinfo *bkpinfo,
266 struct mountlist_itself *mountlist,
267 struct raidlist_itself *raidlist)
268{
269 char c, *tmp;
270 int retval = 0;
271
272 iamhere("inside catchall");
273 assert(bkpinfo != NULL);
274 assert(mountlist != NULL);
275 assert(raidlist != NULL);
276 malloc_string(tmp);
277 iamhere("pre wrm");
278 c = which_restore_mode();
279 iamhere("post wrm");
280 if (c == 'I' || c == 'N' || c == 'C') {
281 interactively_obtain_media_parameters_from_user(bkpinfo, FALSE);
282 } else {
283 popup_and_OK("No restoring or comparing will take place today.");
284 if (is_this_device_mounted("/mnt/cdrom")) {
285 run_program_and_log_output("umount /mnt/cdrom", FALSE);
286 }
287 if (g_ISO_restore_mode) {
288 sprintf(tmp, "umount %s", bkpinfo->isodir);
289 run_program_and_log_output(tmp, FALSE);
290 }
291 paranoid_MR_finish(0);
292 }
293
294 iamhere("post int");
295
296 if (bkpinfo->backup_media_type == iso) {
297 if (iso_fiddly_bits(bkpinfo, (c == 'N') ? TRUE : FALSE)) {
298 mr_msg(2,
299 "catchall_mode --- iso_fiddly_bits returned w/ error");
300 return (1);
301 } else {
302 mr_msg(2, "catchall_mode --- iso_fiddly_bits ok");
303 }
304 }
305
306 if (c == 'I') {
307 mr_msg(2, "IM selected");
308 retval += interactive_mode(bkpinfo, mountlist, raidlist);
309 } else if (c == 'N') {
310 mr_msg(2, "NM selected");
311 retval += nuke_mode(bkpinfo, mountlist, raidlist);
312 } else if (c == 'C') {
313 mr_msg(2, "CM selected");
314 retval += compare_mode(bkpinfo, mountlist, raidlist);
315 }
316 mr_free(tmp);
317 return (retval);
318}
319
320/**************************************************************************
321 *END_CATCHALL_MODE *
322 **************************************************************************/
323
324/**************************************************************************
325 *END_ EXTRACT_CONFIG_FILE_FROM_RAMDISK *
326 **************************************************************************/
327
328
329/**
330 * Locate an executable in the directory structure rooted at @p restg.
331 * @param out_path Where to put the executable.
332 * @param fname The basename of the executable.
333 * @param restg The directory structure to look in.
334 * @note If it could not be found in @p restg then @p fname is put in @p out_path.
335 * @ingroup restoreUtilityGroup
336 */
337void
338find_pathname_of_executable_preferably_in_RESTORING(char *out_path,
339 char *fname,
340 char *restg)
341{
342 assert(out_path != NULL);
343 assert_string_is_neither_NULL_nor_zerolength(fname);
344
345 sprintf(out_path, "%s/sbin/%s", restg, fname);
346 if (does_file_exist(out_path)) {
347 sprintf(out_path, "%s/usr/sbin/%s", restg, fname);
348 if (does_file_exist(out_path)) {
349 sprintf(out_path, "%s/bin/%s", restg, fname);
350 if (does_file_exist(out_path)) {
351 sprintf(out_path, "%s/usr/bin/%s", restg, fname);
352 if (does_file_exist(out_path)) {
353 strcpy(out_path, fname);
354 }
355 }
356 }
357 }
358}
359
360/**************************************************************************
361 *END_FIND_PATHNAME_OF_EXECUTABLE_PREFERABLY_IN_RESTORING *
362 **************************************************************************/
363
364
365
366
367/**
368 * @addtogroup restoreGroup
369 * @{
370 */
371/**
372 * Restore the user's data, in a disaster recovery situation, prompting the
373 * user about whether or not to do every step.
374 * The user can edit the mountlist, choose files to restore, etc.
375 * @param bkpinfo The backup information structure. Most fields are used.
376 * @param mountlist The mountlist containing information about the user's partitions.
377 * @param raidlist The raidlist to go with @p mountlist.
378 * @return 0 for success, or the number of errors encountered.
379 */
380int
381interactive_mode(struct s_bkpinfo *bkpinfo,
382 struct mountlist_itself *mountlist,
383 struct raidlist_itself *raidlist)
384{
385 int retval = 0;
386 int res;
387 int ptn_errs = 0;
388 int fmt_errs = 0;
389
390 bool done;
391 bool restore_all;
392
393 /** needs malloc **********/
394 char *tmp;
395 char *fstab_fname;
396 char *old_restpath;
397
398 struct s_node *filelist;
399
400 /* try to partition and format */
401
402 mr_msg(2, "interactive_mode --- starting (great, assertions OK)");
403
404 malloc_string(tmp);
405 malloc_string(fstab_fname);
406 malloc_string(old_restpath);
407 assert(bkpinfo != NULL);
408 assert(mountlist != NULL);
409 assert(raidlist != NULL);
410
411 mr_msg(2, "interactive_mode --- assertions OK");
412
413 if (g_text_mode) {
414 if (!ask_me_yes_or_no
415 ("Interactive Mode + textonly = experimental! Proceed anyway?"))
416 {
417 fatal_error("Wise move.");
418 }
419 }
420
421 iamhere("About to load config file");
422 get_cfg_file_from_archive_or_bust(bkpinfo);
423 read_cfg_file_into_bkpinfo(g_mondo_cfg_file, bkpinfo);
424 iamhere("Done loading config file; resizing ML");
425#ifdef __FreeBSD__
426 if (strstr
427 (call_program_and_get_last_line_of_output("cat /tmp/cmdline"),
428 "noresize"))
429#else
430 if (strstr
431 (call_program_and_get_last_line_of_output("cat /proc/cmdline"),
432 "noresize"))
433#endif
434 {
435 mr_msg(1, "Not resizing mountlist.");
436 } else {
437 resize_mountlist_proportionately_to_suit_new_drives(mountlist);
438 }
439 for (done = FALSE; !done;) {
440 iamhere("About to edit mountlist");
441 if (g_text_mode) {
442 save_mountlist_to_disk(mountlist, g_mountlist_fname);
443 sprintf(tmp, "%s %s", find_my_editor(), g_mountlist_fname);
444 res = system(tmp);
445 load_mountlist(mountlist, g_mountlist_fname);
446 } else {
447 res = edit_mountlist(g_mountlist_fname, mountlist, raidlist);
448 }
449 iamhere("Finished editing mountlist");
450 if (res) {
451 paranoid_MR_finish(1);
452 }
453 mr_msg(2, "Proceeding...");
454 save_mountlist_to_disk(mountlist, g_mountlist_fname);
455 save_raidlist_to_raidtab(raidlist, RAIDTAB_FNAME);
456 mvaddstr_and_log_it(1, 30, "Restoring Interactively");
457 if (bkpinfo->differential) {
458 log_to_screen("Because this is a differential backup, disk");
459 log_to_screen
460 (" partitioning and formatting will not take place.");
461 done = TRUE;
462 } else {
463 if (ask_me_yes_or_no
464 ("Do you want to erase and partition your hard drives?")) {
465 if (partition_table_contains_Compaq_diagnostic_partition
466 (mountlist)) {
467 offer_to_abort_because_Compaq_Proliants_suck();
468 done = TRUE;
469 } else {
470 twenty_seconds_til_yikes();
471 g_fprep = fopen("/tmp/prep.sh", "w");
472 ptn_errs = partition_everything(mountlist);
473 if (ptn_errs) {
474 log_to_screen
475 ("Warning. Errors occurred during disk partitioning.");
476 }
477
478 fmt_errs = format_everything(mountlist, FALSE, raidlist);
479 if (!fmt_errs) {
480 log_to_screen
481 ("Errors during disk partitioning were handled OK.");
482 log_to_screen
483 ("Partitions were formatted OK despite those errors.");
484 ptn_errs = 0;
485 }
486 if (!ptn_errs && !fmt_errs) {
487 done = TRUE;
488 }
489 }
490 paranoid_fclose(g_fprep);
491 } else {
492 mvaddstr_and_log_it(g_currentY++, 0,
493 "User opted not to partition the devices");
494 if (ask_me_yes_or_no
495 ("Do you want to format your hard drives?")) {
496 fmt_errs = format_everything(mountlist, TRUE, raidlist);
497 if (!fmt_errs) {
498 done = TRUE;
499 }
500 } else {
501 ptn_errs = fmt_errs = 0;
502 done = TRUE;
503 }
504 }
505 if (fmt_errs) {
506 mvaddstr_and_log_it(g_currentY++,
507 0,
508 "Errors occurred. Please repartition and format drives manually.");
509 done = FALSE;
510 }
511 if (ptn_errs & !fmt_errs) {
512 mvaddstr_and_log_it(g_currentY++,
513 0,
514 "Errors occurred during partitioning. Formatting, however, went OK.");
515 done = TRUE;
516 }
517 if (!done) {
518 if (!ask_me_yes_or_no("Re-edit the mountlist?")) {
519 retval++;
520 goto end_of_func;
521 }
522 }
523 }
524 }
525
526 /* mount */
527 if (mount_all_devices(mountlist, TRUE)) {
528 unmount_all_devices(mountlist);
529 retval++;
530 goto end_of_func;
531 }
532 /* restore */
533 if ((restore_all =
534 ask_me_yes_or_no("Do you want me to restore all of your data?")))
535 {
536 mr_msg(1, "Restoring all data");
537 retval += restore_everything(bkpinfo, NULL);
538 } else
539 if ((restore_all =
540 ask_me_yes_or_no
541 ("Do you want me to restore _some_ of your data?"))) {
542 strcpy(old_restpath, bkpinfo->restore_path);
543 for (done = FALSE; !done;) {
544 unlink("/tmp/filelist.full");
545 filelist = process_filelist_and_biggielist(bkpinfo);
546 /* Now you have /tmp/tmpfs/filelist.restore-these and /tmp/tmpfs/biggielist.restore-these;
547 the former is a list of regular files; the latter, biggiefiles and imagedevs.
548 */
549 if (filelist) {
550 gotos_suck:
551 strcpy(tmp, old_restpath);
552// (NB: %s is where your filesystem is mounted now, by default)", MNT_RESTORING);
553 if (popup_and_get_string
554 ("Restore path", "Restore files to where?", tmp,
555 MAX_STR_LEN / 4)) {
556 if (!strcmp(tmp, "/")) {
557 if (!ask_me_yes_or_no("Are you sure?")) {
558 goto gotos_suck;
559 }
560 tmp[0] = '\0'; // so we restore to [blank]/file/name :)
561 }
562 strcpy(bkpinfo->restore_path, tmp);
563 mr_msg(1, "Restoring subset");
564 retval += restore_everything(bkpinfo, filelist);
565 free_filelist(filelist);
566 } else {
567 strcpy(bkpinfo->restore_path, old_restpath);
568 free_filelist(filelist);
569 }
570 if (!ask_me_yes_or_no
571 ("Restore another subset of your backup?")) {
572 done = TRUE;
573 }
574 } else {
575 done = TRUE;
576 }
577 }
578 strcpy(old_restpath, bkpinfo->restore_path);
579 } else {
580 mvaddstr_and_log_it(g_currentY++,
581 0,
582 "User opted not to restore any data. ");
583 }
584 if (retval) {
585 mvaddstr_and_log_it(g_currentY++,
586 0,
587 "Errors occurred during the restore phase. ");
588 }
589
590 if (ask_me_yes_or_no("Initialize the boot loader?")) {
591 run_boot_loader(TRUE);
592 } else {
593 mvaddstr_and_log_it(g_currentY++,
594 0,
595 "User opted not to initialize the boot loader.");
596 }
597
598// run_program_and_log_output("cp -af /etc/lvm " MNT_RESTORING "/etc/", 1);
599 protect_against_braindead_sysadmins();
600 // modify_rclocal_one_time( MNT_RESTORING "/etc" );
601 retval += unmount_all_devices(mountlist);
602 /* if (restore_some || restore_all || */
603 if (ask_me_yes_or_no
604 ("Label your ext2 and ext3 partitions if necessary?")) {
605 mvaddstr_and_log_it(g_currentY, 0,
606 "Using e2label to label your ext2,3 partitions");
607 if (does_file_exist("/tmp/fstab.new")) {
608 strcpy(fstab_fname, "/tmp/fstab.new");
609 } else {
610 strcpy(fstab_fname, "/tmp/fstab");
611 }
612 sprintf(tmp,
613 "label-partitions-as-necessary %s < %s >> %s 2>> %s",
614 g_mountlist_fname, fstab_fname, MONDO_LOGFILE,
615 MONDO_LOGFILE);
616 res = system(tmp);
617 if (res) {
618 log_to_screen
619 ("label-partitions-as-necessary returned an error");
620 mvaddstr_and_log_it(g_currentY++, 74, "Failed.");
621 } else {
622 mvaddstr_and_log_it(g_currentY++, 74, "Done.");
623 }
624 retval += res;
625 }
626
627 iamhere("About to leave interactive_mode()");
628 if (retval) {
629 mvaddstr_and_log_it(g_currentY++,
630 0,
631 "Warning - errors occurred during the restore phase.");
632 }
633 end_of_func:
634 mr_free(tmp);
635 mr_free(fstab_fname);
636 mr_free(old_restpath);
637 iamhere("Leaving interactive_mode()");
638 return (retval);
639}
640
641/**************************************************************************
642 *END_INTERACTIVE_MODE *
643 **************************************************************************/
644
645
646
647/**
648 * Run an arbitrary restore mode (prompt the user), but from ISO images
649 * instead of real media.
650 * @param bkpinfo The backup information structure. Most fields are used.
651 * @param mountlist The mountlist containing information about the user's partitions.
652 * @param raidlist The raidlist that goes with @p mountlist.
653 * @param nuke_me_please If TRUE, we plan to run Nuke Mode.
654 * @return 0 for success, or the number of errors encountered.
655 */
656int
657iso_mode(struct s_bkpinfo *bkpinfo,
658 struct mountlist_itself *mountlist,
659 struct raidlist_itself *raidlist, bool nuke_me_please)
660{
661 char c;
662 int retval = 0;
663
664 assert(bkpinfo != NULL);
665 assert(mountlist != NULL);
666 assert(raidlist != NULL);
667 if (iso_fiddly_bits(bkpinfo, nuke_me_please)) {
668 mr_msg(1, "iso_mode --- returning w/ error");
669 return (1);
670 } else {
671 c = which_restore_mode();
672 if (c == 'I' || c == 'N' || c == 'C') {
673 interactively_obtain_media_parameters_from_user(bkpinfo,
674 FALSE);
675 }
676 if (c == 'I') {
677 retval += interactive_mode(bkpinfo, mountlist, raidlist);
678 } else if (c == 'N') {
679 retval += nuke_mode(bkpinfo, mountlist, raidlist);
680 } else if (c == 'C') {
681 retval += compare_mode(bkpinfo, mountlist, raidlist);
682 } else {
683 log_to_screen("OK, I shan't restore/compare any files.");
684 }
685 }
686 if (is_this_device_mounted(MNT_CDROM)) {
687 paranoid_system("umount " MNT_CDROM);
688 }
689// if (! already_mounted)
690// {
691 if (system("umount /tmp/isodir 2> /dev/null")) {
692 log_to_screen
693 ("WARNING - unable to unmount device where the ISO files are stored.");
694 }
695// }
696 return (retval);
697}
698
699/**************************************************************************
700 *END_ISO_MODE *
701 **************************************************************************/
702
703
704/* MONDO - saving your a$$ since Feb 18th, 2000 */
705
706
707
708
709/**
710 * Restore the user's data automatically (no prompts), after a twenty-second
711 * warning period.
712 * @param bkpinfo The backup information structure. Most fields are used.
713 * @param mountlist The mountlist containing information about the user's partitions.
714 * @param raidlist The raidlist that goes with @p mountlist.
715 * @return 0 for success, or the number of errors encountered.
716 * @warning <b><i>THIS WILL ERASE ALL EXISTING DATA!</i></b>
717 */
718int
719nuke_mode(struct s_bkpinfo *bkpinfo,
720 struct mountlist_itself *mountlist,
721 struct raidlist_itself *raidlist)
722{
723 int retval = 0;
724 int res = 0;
725 bool boot_loader_installed = FALSE;
726 /** malloc **/
727 char tmp[MAX_STR_LEN], tmpA[MAX_STR_LEN], tmpB[MAX_STR_LEN],
728 tmpC[MAX_STR_LEN];
729
730 assert(bkpinfo != NULL);
731 assert(mountlist != NULL);
732 assert(raidlist != NULL);
733
734 mr_msg(2, "nuke_mode --- starting");
735
736 get_cfg_file_from_archive_or_bust(bkpinfo);
737 load_mountlist(mountlist, g_mountlist_fname); // in case read_cfg_file_into_bkpinfo updated the mountlist
738#ifdef __FreeBSD__
739 if (strstr
740 (call_program_and_get_last_line_of_output("cat /tmp/cmdline"),
741 "noresize"))
742#else
743 if (strstr
744 (call_program_and_get_last_line_of_output("cat /proc/cmdline"),
745 "noresize"))
746#endif
747 {
748 mr_msg(2, "Not resizing mountlist.");
749 } else {
750 resize_mountlist_proportionately_to_suit_new_drives(mountlist);
751 }
752 if (!evaluate_mountlist(mountlist, tmpA, tmpB, tmpC)) {
753 sprintf(tmp,
754 "Mountlist analyzed. Result: \"%s %s %s\" Switch to Interactive Mode?",
755 tmpA, tmpB, tmpC);
756 if (ask_me_yes_or_no(tmp)) {
757 retval = interactive_mode(bkpinfo, mountlist, raidlist);
758 goto after_the_nuke;
759 } else {
760 fatal_error("Nuke Mode aborted. ");
761 }
762 }
763 save_mountlist_to_disk(mountlist, g_mountlist_fname);
764 mvaddstr_and_log_it(1, 30, "Restoring Automatically");
765 if (bkpinfo->differential) {
766 log_to_screen("Because this is a differential backup, disk");
767 log_to_screen("partitioning and formatting will not take place.");
768 res = 0;
769 } else {
770 if (partition_table_contains_Compaq_diagnostic_partition
771 (mountlist)) {
772 offer_to_abort_because_Compaq_Proliants_suck();
773 } else {
774 twenty_seconds_til_yikes();
775 g_fprep = fopen("/tmp/prep.sh", "w");
776#ifdef __FreeBSD__
777 if (strstr
778 (call_program_and_get_last_line_of_output
779 ("cat /tmp/cmdline"), "nopart"))
780#else
781 if (strstr
782 (call_program_and_get_last_line_of_output
783 ("cat /proc/cmdline"), "nopart"))
784#endif
785 {
786 mr_msg(2,
787 "Not partitioning drives due to 'nopart' option.");
788 res = 0;
789 } else {
790 res = partition_everything(mountlist);
791 if (res) {
792 log_to_screen
793 ("Warning. Errors occurred during partitioning.");
794 res = 0;
795 }
796 }
797 retval += res;
798 if (!res) {
799 log_to_screen("Preparing to format your disk(s)");
800 sleep(1);
801 system("sync");
802 log_to_screen("Please wait. This may take a few minutes.");
803 res += format_everything(mountlist, FALSE, raidlist);
804 }
805 paranoid_fclose(g_fprep);
806 }
807 }
808 retval += res;
809 if (res) {
810 mvaddstr_and_log_it(g_currentY++,
811 0,
812 "Failed to partition and/or format your hard drives.");
813
814 if (ask_me_yes_or_no("Try in interactive mode instead?")) {
815 retval = interactive_mode(bkpinfo, mountlist, raidlist);
816 goto after_the_nuke;
817 } else
818 if (!ask_me_yes_or_no
819 ("Would you like to try to proceed anyway?")) {
820 return (retval);
821 }
822 }
823 retval = mount_all_devices(mountlist, TRUE);
824 if (retval) {
825 unmount_all_devices(mountlist);
826 log_to_screen
827 ("Unable to mount all partitions. Sorry, I cannot proceed.");
828 return (retval);
829 }
830 iamhere("Restoring everything");
831 retval += restore_everything(bkpinfo, NULL);
832 if (!run_boot_loader(FALSE)) {
833 mr_msg(1,
834 "Great! Boot loader was installed. No need for msg at end.");
835 boot_loader_installed = TRUE;
836 }
837 protect_against_braindead_sysadmins();
838// run_program_and_log_output("cp -af /etc/lvm " MNT_RESTORING "/etc/", 1);
839 // modify_rclocal_one_time( MNT_RESTORING "/etc" );
840 retval += unmount_all_devices(mountlist);
841 mvaddstr_and_log_it(g_currentY,
842 0,
843 "Using e2label to label your ext2,3 partitions");
844
845 sprintf(tmp, "label-partitions-as-necessary %s < /tmp/fstab",
846 g_mountlist_fname);
847 res = run_program_and_log_output(tmp, TRUE);
848 if (res) {
849 log_to_screen("label-partitions-as-necessary returned an error");
850 mvaddstr_and_log_it(g_currentY++, 74, "Failed.");
851 } else {
852 mvaddstr_and_log_it(g_currentY++, 74, "Done.");
853 }
854 retval += res;
855
856 after_the_nuke:
857 if (retval) {
858 log_to_screen("Errors occurred during the nuke phase.");
859 } else if (strstr(call_program_and_get_last_line_of_output("cat /proc/cmdline"), "RESTORE")) // Bruno's thing
860 {
861 log_to_screen
862 ("PC was restored successfully. Thank you for using Mondo Rescue.");
863 log_to_screen
864 ("Please visit our website at http://www.mondorescue.org for more information.");
865 } else {
866 strcpy(tmp,"Mondo has restored your system.\n\nPlease wait for the command prompt. Then remove the backup media and reboot.\n\nPlease visit our website at http://www.mondorescue.org for more information.");
867 if (strstr(call_program_and_get_last_line_of_output("cat /proc/cmdline"), "restore") == NULL) {
868 popup_and_OK(tmp);
869 }
870 log_to_screen
871 ("Mondo has restored your system. Please wait for the command prompt.");
872 log_to_screen
873 ("Then remove the backup media and reboot.");
874 log_to_screen
875 ("Please visit our website at http://www.mondorescue.org for more information.");
876 }
877 g_I_have_just_nuked = TRUE;
878/*
879 if (!boot_loader_installed && !does_file_exist(DO_MBR_PLEASE))
880 {
881 log_to_screen("PLEASE RUN 'mondorestore --mbr' NOW TO INITIALIZE YOUR BOOT SECTOR");
882 write_one_liner_data_file(DO_MBR_PLEASE, "mondorestore --mbr");
883 }
884*/
885 return (retval);
886}
887
888/**************************************************************************
889 *END_NUKE_MODE *
890 **************************************************************************/
891
892
893
894/**
895 * Restore the user's data (or a subset of it) to the live filesystem.
896 * This should not be called if we're booted from CD!
897 * @param bkpinfo The backup information structure. Most fields are used.
898 * @return 0 for success, or the number of errors encountered.
899 */
900int restore_to_live_filesystem(struct s_bkpinfo *bkpinfo)
901{
902 int retval = 0;
903
904 /** malloc **/
905 char *old_restpath;
906
907 struct mountlist_itself *mountlist;
908// static
909 struct raidlist_itself *raidlist;
910 struct s_node *filelist;
911
912 mr_msg(1, "restore_to_live_filesystem() - starting");
913 assert(bkpinfo != NULL);
914 malloc_string(old_restpath);
915 mountlist = mr_malloc(sizeof(struct mountlist_itself));
916 raidlist = mr_malloc(sizeof(struct raidlist_itself));
917
918 strcpy(bkpinfo->restore_path, "/");
919 if (!g_restoring_live_from_cd) {
920 popup_and_OK
921 ("Please insert tape/CD/boot floppy, then hit 'OK' to continue.");
922 sleep(1);
923 }
924 interactively_obtain_media_parameters_from_user(bkpinfo, FALSE);
925 mr_msg(2, "bkpinfo->media_device = %s", bkpinfo->media_device);
926 if (!bkpinfo->media_device[0]) {
927 mr_msg(2, "Warning - failed to find media dev");
928 }
929
930
931 mr_msg(2, "bkpinfo->isodir = %s", bkpinfo->isodir);
932
933 open_evalcall_form("Thinking...");
934
935 get_cfg_file_from_archive_or_bust(bkpinfo);
936 read_cfg_file_into_bkpinfo(g_mondo_cfg_file, bkpinfo);
937 load_mountlist(mountlist, g_mountlist_fname); // in case read_cfg_file_into_bkpinfo
938
939 close_evalcall_form();
940 retval = load_mountlist(mountlist, g_mountlist_fname);
941 load_raidtab_into_raidlist(raidlist, RAIDTAB_FNAME);
942 filelist = process_filelist_and_biggielist(bkpinfo);
943 if (filelist) {
944 save_filelist(filelist, "/tmp/selected-files.txt");
945 strcpy(old_restpath, bkpinfo->restore_path);
946 if (popup_and_get_string("Restore path",
947 "Restore files to where? )",
948 bkpinfo->restore_path, MAX_STR_LEN / 4)) {
949 iamhere("Restoring everything");
950 retval += restore_everything(bkpinfo, filelist);
951 free_filelist(filelist);
952 strcpy(bkpinfo->restore_path, old_restpath);
953 } else {
954 free_filelist(filelist);
955 }
956 strcpy(bkpinfo->restore_path, old_restpath);
957 }
958 if (IS_THIS_A_STREAMING_BACKUP(bkpinfo->backup_media_type)) {
959 mr_msg(2,
960 "I probably don't need to unmount or eject the CD-ROM but I'm doing it anyway.");
961 }
962 run_program_and_log_output("umount " MNT_CDROM, FALSE);
963 if (!bkpinfo->please_dont_eject) {
964 eject_device(bkpinfo->media_device);
965 }
966 mr_free(old_restpath);
967 mr_free(mountlist);
968 mr_free(raidlist);
969 return (retval);
970}
971
972/**************************************************************************
973 *END_RESTORE_TO_LIVE_FILESYSTEM *
974 **************************************************************************/
975
976/* @} - end of restoreGroup */
977
978
979#include <utime.h>
980/**
981 * @addtogroup LLrestoreGroup
982 * @{
983 */
984/**
985 * Restore biggiefile @p bigfileno from the currently mounted CD.
986 * @param bkpinfo The backup information structure. Fields used:
987 * - @c bkpinfo->backup_media_type
988 * - @c bkpinfo->restore_path
989 * @param bigfileno The biggiefile number (starting from 0) to restore.
990 * @param filelist The node structure containing the list of files to restore.
991 * If the biggiefile is not in this list, it will be skipped (return value will
992 * still indicate success).
993 * @return 0 for success (or skip), nonzero for failure.
994 */
995int
996restore_a_biggiefile_from_CD(struct s_bkpinfo *bkpinfo,
997 long bigfileno,
998 struct s_node *filelist,
999 char *pathname_of_last_file_restored)
1000{
1001 FILE *fin;
1002 FILE *fout;
1003 FILE *fbzip2;
1004
1005 /** malloc ***/
1006 char *checksum, *outfile_fname, *tmp, *bzip2_command,
1007 *ntfsprog_command, *suffix, *sz_devfile;
1008 char *bigblk;
1009 char *p;
1010 int retval = 0;
1011 int finished = FALSE;
1012 long sliceno;
1013 long siz;
1014 char ntfsprog_fifo[MAX_STR_LEN];
1015 char *file_to_openout = NULL;
1016 struct s_filename_and_lstat_info biggiestruct;
1017 struct utimbuf the_utime_buf, *ubuf;
1018 bool use_ntfsprog_hack = FALSE;
1019 pid_t pid;
1020 int res = 0;
1021 int old_loglevel;
1022 char sz_msg[MAX_STR_LEN];
1023 struct s_node *node;
1024
1025 old_loglevel = g_loglevel;
1026 ubuf = &the_utime_buf;
1027 assert(bkpinfo != NULL);
1028
1029 malloc_string(checksum);
1030 malloc_string(outfile_fname);
1031 malloc_string(tmp);
1032 malloc_string(bzip2_command);
1033 malloc_string(ntfsprog_command);
1034 malloc_string(suffix);
1035 malloc_string(sz_devfile);
1036
1037 pathname_of_last_file_restored[0] = '\0';
1038 bigblk = mr_malloc(TAPE_BLOCK_SIZE);
1039
1040 if (!(fin = fopen(slice_fname(bigfileno, 0, ARCHIVES_PATH, ""), "r"))) {
1041 log_to_screen("Cannot even open bigfile's info file");
1042 return (1);
1043 }
1044
1045 memset((void *) &biggiestruct, 0, sizeof(biggiestruct));
1046 if (fread((void *) &biggiestruct, 1, sizeof(biggiestruct), fin) <
1047 sizeof(biggiestruct)) {
1048 mr_msg(2, "Warning - unable to get biggiestruct of bigfile #%d",
1049 bigfileno + 1);
1050 }
1051 paranoid_fclose(fin);
1052
1053 strcpy(checksum, biggiestruct.checksum);
1054
1055 if (!checksum[0]) {
1056 sprintf(tmp, "Warning - bigfile %ld does not have a checksum",
1057 bigfileno + 1);
1058 mr_msg(3, tmp);
1059 p = checksum;
1060 }
1061
1062 if (!strncmp(biggiestruct.filename, "/dev/", 5)) // Whether NTFS or not :)
1063 {
1064 strcpy(outfile_fname, biggiestruct.filename);
1065 } else {
1066 sprintf(outfile_fname, "%s/%s", bkpinfo->restore_path,
1067 biggiestruct.filename);
1068 }
1069
1070 /* skip file if we have a selective restore subset & it doesn't match */
1071 if (filelist != NULL) {
1072 node = find_string_at_node(filelist, biggiestruct.filename);
1073 if (!node) {
1074 mr_msg(0, "Skipping %s (name isn't in filelist)",
1075 biggiestruct.filename);
1076 pathname_of_last_file_restored[0] = '\0';
1077 return (0);
1078 } else if (!(node->selected)) {
1079 mr_msg(1, "Skipping %s (name isn't in biggielist subset)",
1080 biggiestruct.filename);
1081 pathname_of_last_file_restored[0] = '\0';
1082 return (0);
1083 }
1084 }
1085 /* otherwise, continue */
1086
1087 mr_msg(1, "DEFINITELY restoring %s", biggiestruct.filename);
1088 if (biggiestruct.use_ntfsprog) {
1089 if (strncmp(biggiestruct.filename, "/dev/", 5)) {
1090 mr_msg(1,
1091 "I was in error when I set biggiestruct.use_ntfsprog to TRUE.");
1092 mr_msg(1, "%s isn't even in /dev", biggiestruct.filename);
1093 biggiestruct.use_ntfsprog = FALSE;
1094 }
1095 }
1096
1097 if (biggiestruct.use_ntfsprog) // if it's an NTFS device
1098// if (!strncmp ( biggiestruct.filename, "/dev/", 5))
1099 {
1100 g_loglevel = 4;
1101 use_ntfsprog_hack = TRUE;
1102 mr_msg(2,
1103 "Calling ntfsclone in background because %s is an NTFS /dev entry",
1104 outfile_fname);
1105 sprintf(sz_devfile, "/tmp/%d.%d.000", (int) (random() % 32768),
1106 (int) (random() % 32768));
1107 mkfifo(sz_devfile, 0x770);
1108 strcpy(ntfsprog_fifo, sz_devfile);
1109 file_to_openout = ntfsprog_fifo;
1110 switch (pid = fork()) {
1111 case -1:
1112 fatal_error("Fork failure");
1113 case 0:
1114 mr_msg(3,
1115 "CHILD - fip - calling feed_outfrom_ntfsprog(%s, %s)",
1116 biggiestruct.filename, ntfsprog_fifo);
1117 res =
1118 feed_outfrom_ntfsprog(biggiestruct.filename,
1119 ntfsprog_fifo);
1120// mr_msg(3, "CHILD - fip - exiting");
1121 exit(res);
1122 break;
1123 default:
1124 mr_msg(3,
1125 "feed_into_ntfsprog() called in background --- pid=%ld",
1126 (long int) (pid));
1127 }
1128 } else {
1129 use_ntfsprog_hack = FALSE;
1130 ntfsprog_fifo[0] = '\0';
1131 file_to_openout = outfile_fname;
1132 if (!does_file_exist(outfile_fname)) // yes, it looks weird with the '!' but it's correct that way
1133 {
1134 make_hole_for_file(outfile_fname);
1135 }
1136 }
1137
1138 sprintf(tmp, "Reassembling big file %ld (%s)", bigfileno + 1,
1139 outfile_fname);
1140 mr_msg(2, tmp);
1141
1142 /*
1143 last slice is zero-length and uncompressed; when we find it, we stop.
1144 We DON'T wait until there are no more slices; if we did that,
1145 We might stop at end of CD, not at last slice (which is 0-len and uncompd)
1146 */
1147
1148 strncpy(pathname_of_last_file_restored, biggiestruct.filename,
1149 MAX_STR_LEN - 1);
1150 pathname_of_last_file_restored[MAX_STR_LEN - 1] = '\0';
1151
1152 mr_msg(3, "file_to_openout = %s", file_to_openout);
1153 if (!(fout = fopen(file_to_openout, "w"))) {
1154 log_to_screen("Cannot openout outfile_fname - hard disk full?");
1155 return (1);
1156 }
1157 mr_msg(3, "Opened out to %s", outfile_fname); // CD/DVD --> mondorestore --> ntfsclone --> hard disk itself
1158
1159 for (sliceno = 1, finished = FALSE; !finished;) {
1160 if (!does_file_exist
1161 (slice_fname(bigfileno, sliceno, ARCHIVES_PATH, ""))
1162 &&
1163 !does_file_exist(slice_fname
1164 (bigfileno, sliceno, ARCHIVES_PATH, "lzo"))
1165 &&
1166 !does_file_exist(slice_fname
1167 (bigfileno, sliceno, ARCHIVES_PATH, "gz"))
1168 &&
1169 !does_file_exist(slice_fname
1170 (bigfileno, sliceno, ARCHIVES_PATH, "bz2"))) {
1171 mr_msg(3,
1172 "Cannot find a data slice or terminator slice on CD %d",
1173 g_current_media_number);
1174 g_current_media_number++;
1175 sprintf(tmp,
1176 "Asking for %s #%d so that I may read slice #%ld\n",
1177 media_descriptor_string(bkpinfo->backup_media_type),
1178 g_current_media_number, sliceno);
1179 mr_msg(2, tmp);
1180 sprintf(tmp, "Restoring from %s #%d",
1181 media_descriptor_string(bkpinfo->backup_media_type),
1182 g_current_media_number);
1183 log_to_screen(tmp);
1184 insist_on_this_cd_number(bkpinfo, g_current_media_number);
1185 log_to_screen("Continuing to restore.");
1186 } else {
1187 strcpy(tmp,
1188 slice_fname(bigfileno, sliceno, ARCHIVES_PATH, ""));
1189 if (does_file_exist(tmp) && length_of_file(tmp) == 0) {
1190 mr_msg(2,
1191 "End of bigfile # %ld (slice %ld is the terminator)",
1192 bigfileno + 1, sliceno);
1193 finished = TRUE;
1194 continue;
1195 } else {
1196 if (does_file_exist
1197 (slice_fname
1198 (bigfileno, sliceno, ARCHIVES_PATH, "lzo"))) {
1199 strcpy(bzip2_command, "lzop");
1200 strcpy(suffix, "lzo");
1201 } else
1202 if (does_file_exist
1203 (slice_fname
1204 (bigfileno, sliceno, ARCHIVES_PATH, "gz"))) {
1205 strcpy(bzip2_command, "gzip");
1206 strcpy(suffix, "gz");
1207 } else
1208 if (does_file_exist
1209 (slice_fname
1210 (bigfileno, sliceno, ARCHIVES_PATH, "bz2"))) {
1211 strcpy(bzip2_command, "bzip2");
1212 strcpy(suffix, "bz2");
1213 } else
1214 if (does_file_exist
1215 (slice_fname
1216 (bigfileno, sliceno, ARCHIVES_PATH, ""))) {
1217 strcpy(bzip2_command, "");
1218 strcpy(suffix, "");
1219 } else {
1220 log_to_screen("OK, that's pretty fsck0red...");
1221 return (1);
1222 }
1223 }
1224 if (bzip2_command[0] != '\0') {
1225 sprintf(bzip2_command + strlen(bzip2_command),
1226 " -dc %s 2>> %s",
1227 slice_fname(bigfileno, sliceno, ARCHIVES_PATH,
1228 suffix), MONDO_LOGFILE);
1229 } else {
1230 sprintf(bzip2_command, "cat %s 2>> %s",
1231 slice_fname(bigfileno, sliceno, ARCHIVES_PATH,
1232 suffix), MONDO_LOGFILE);
1233 }
1234 sprintf(tmp, "Working on %s #%d, file #%ld, slice #%ld ",
1235 media_descriptor_string(bkpinfo->backup_media_type),
1236 g_current_media_number, bigfileno + 1, sliceno);
1237 mr_msg(2, tmp);
1238
1239 if (!g_text_mode) {
1240 newtDrawRootText(0, g_noof_rows - 2, tmp);
1241 newtRefresh();
1242 strip_spaces(tmp);
1243 update_progress_form(tmp);
1244 }
1245 if (!(fbzip2 = popen(bzip2_command, "r"))) {
1246 fatal_error("Can't run popen command");
1247 }
1248 while (!feof(fbzip2)) {
1249 siz = fread(bigblk, 1, TAPE_BLOCK_SIZE, fbzip2);
1250 if (siz > 0) {
1251 sprintf(sz_msg, "Read %ld from fbzip2", siz);
1252 siz = fwrite(bigblk, 1, siz, fout);
1253 sprintf(sz_msg + strlen(sz_msg),
1254 "; written %ld to fout", siz);
1255// mr_msg(2. sz_msg);
1256 }
1257 }
1258 paranoid_pclose(fbzip2);
1259
1260
1261 sliceno++;
1262 g_current_progress++;
1263 }
1264 }
1265/*
1266 memset(bigblk, TAPE_BLOCK_SIZE, 1); // This all looks very fishy...
1267 fwrite( bigblk, 1, TAPE_BLOCK_SIZE, fout);
1268 fwrite( bigblk, 1, TAPE_BLOCK_SIZE, fout);
1269 fwrite( bigblk, 1, TAPE_BLOCK_SIZE, fout);
1270 fwrite( bigblk, 1, TAPE_BLOCK_SIZE, fout);
1271*/
1272 paranoid_fclose(fout);
1273 g_loglevel = old_loglevel;
1274
1275 if (use_ntfsprog_hack) {
1276 mr_msg(3, "Waiting for ntfsclone to finish");
1277 sprintf(tmp,
1278 " ps | grep \" ntfsclone \" | grep -v grep > /dev/null 2> /dev/null");
1279 while (system(tmp) == 0) {
1280 sleep(1);
1281 }
1282 log_it("OK, ntfsclone has really finished");
1283 }
1284
1285 if (strcmp(outfile_fname, "/dev/null")) {
1286 chown(outfile_fname, biggiestruct.properties.st_uid,
1287 biggiestruct.properties.st_gid);
1288 chmod(outfile_fname, biggiestruct.properties.st_mode);
1289 ubuf->actime = biggiestruct.properties.st_atime;
1290 ubuf->modtime = biggiestruct.properties.st_mtime;
1291 utime(outfile_fname, ubuf);
1292 }
1293 mr_free(bigblk);
1294 mr_free(checksum);
1295 mr_free(outfile_fname);
1296 mr_free(tmp);
1297 mr_free(bzip2_command);
1298 mr_free(ntfsprog_command);
1299 mr_free(suffix);
1300 mr_free(sz_devfile);
1301
1302 return (retval);
1303}
1304
1305/**************************************************************************
1306 *END_ RESTORE_A_BIGGIEFILE_FROM_CD *
1307 **************************************************************************/
1308
1309
1310
1311/**
1312 * Restore a biggiefile from the currently opened stream.
1313 * @param bkpinfo The backup information structure. Fields used:
1314 * - @c bkpinfo->restore_path
1315 * - @c bkpinfo->zip_exe
1316 * @param orig_bf_fname The original filename of the biggiefile.
1317 * @param biggiefile_number The number of the biggiefile (starting from 0).
1318 * @param orig_checksum Unused.
1319 * @param biggiefile_size Unused.
1320 * @param filelist The node structure containing the list of files to be restored.
1321 * If @p orig_bf_fname is not in the list, it will be ignored.
1322 * @return 0 for success (or skip), nonzero for failure.
1323 * @bug orig_checksum and biggiefile_size are unused (except to check that they are non-NULL).
1324 */
1325int restore_a_biggiefile_from_stream(struct s_bkpinfo *bkpinfo, char *orig_bf_fname, long biggiefile_number, char *orig_checksum, //UNUSED
1326 long long biggiefile_size, //UNUSED
1327 struct s_node *filelist,
1328 int use_ntfsprog,
1329 char *pathname_of_last_file_restored)
1330{
1331 FILE *pout;
1332 FILE *fin;
1333
1334 /** mallocs ********/
1335 char *tmp;
1336 char *command;
1337 char *outfile_fname;
1338 char *ntfsprog_command;
1339 char *sz_devfile;
1340 char *ntfsprog_fifo;
1341 char *file_to_openout = NULL;
1342
1343 struct s_node *node;
1344
1345 int old_loglevel;
1346 long current_slice_number = 0;
1347 int retval = 0;
1348 int res = 0;
1349 int ctrl_chr = '\0';
1350 long long slice_siz;
1351 bool dummy_restore = FALSE;
1352 bool use_ntfsprog_hack = FALSE;
1353 pid_t pid;
1354 struct s_filename_and_lstat_info biggiestruct;
1355 struct utimbuf the_utime_buf, *ubuf;
1356 ubuf = &the_utime_buf;
1357
1358 malloc_string(tmp);
1359 malloc_string(ntfsprog_fifo);
1360 malloc_string(outfile_fname);
1361 malloc_string(command);
1362 malloc_string(sz_devfile);
1363 malloc_string(ntfsprog_command);
1364 old_loglevel = g_loglevel;
1365 assert(bkpinfo != NULL);
1366 assert(orig_bf_fname != NULL);
1367 assert(orig_checksum != NULL);
1368
1369 pathname_of_last_file_restored[0] = '\0';
1370 if (use_ntfsprog == BLK_START_A_PIHBIGGIE) {
1371 use_ntfsprog = 1;
1372 mr_msg(1, "%s --- pih=YES", orig_bf_fname);
1373 } else if (use_ntfsprog == BLK_START_A_NORMBIGGIE) {
1374 use_ntfsprog = 0;
1375 mr_msg(1, "%s --- pih=NO", orig_bf_fname);
1376 } else {
1377 use_ntfsprog = 0;
1378 mr_msg(1, "%s --- pih=NO (weird marker though)", orig_bf_fname);
1379 }
1380
1381 strncpy(pathname_of_last_file_restored, orig_bf_fname,
1382 MAX_STR_LEN - 1);
1383 pathname_of_last_file_restored[MAX_STR_LEN - 1] = '\0';
1384
1385 /* open out to biggiefile to be restored (or /dev/null if biggiefile is not to be restored) */
1386
1387 if (filelist != NULL) {
1388 node = find_string_at_node(filelist, orig_bf_fname);
1389 if (!node) {
1390 dummy_restore = TRUE;
1391 mr_msg(1,
1392 "Skipping big file %ld (%s) - not in biggielist subset",
1393 biggiefile_number + 1, orig_bf_fname);
1394 pathname_of_last_file_restored[0] = '\0';
1395 } else if (!(node->selected)) {
1396 dummy_restore = TRUE;
1397 mr_msg(1, "Skipping %s (name isn't in biggielist subset)",
1398 orig_bf_fname);
1399 pathname_of_last_file_restored[0] = '\0';
1400 }
1401 }
1402
1403 if (use_ntfsprog) {
1404 if (strncmp(orig_bf_fname, "/dev/", 5)) {
1405 mr_msg(1,
1406 "I was in error when I set use_ntfsprog to TRUE.");
1407 mr_msg(1, "%s isn't even in /dev", orig_bf_fname);
1408 use_ntfsprog = FALSE;
1409 }
1410 }
1411
1412 if (use_ntfsprog) {
1413 g_loglevel = 4;
1414 strcpy(outfile_fname, orig_bf_fname);
1415 use_ntfsprog_hack = TRUE;
1416 mr_msg(2,
1417 "Calling ntfsclone in background because %s is a /dev entry",
1418 outfile_fname);
1419 sprintf(sz_devfile, "%s/%d.%d.000",
1420 bkpinfo->tmpdir,
1421 (int) (random() % 32768),
1422 (int) (random() % 32768));
1423 mkfifo(sz_devfile, 0x770);
1424 strcpy(ntfsprog_fifo, sz_devfile);
1425 file_to_openout = ntfsprog_fifo;
1426 switch (pid = fork()) {
1427 case -1:
1428 fatal_error("Fork failure");
1429 case 0:
1430 mr_msg(3,
1431 "CHILD - fip - calling feed_outfrom_ntfsprog(%s, %s)",
1432 outfile_fname, ntfsprog_fifo);
1433 res =
1434 feed_outfrom_ntfsprog(outfile_fname, ntfsprog_fifo);
1435// mr_msg(3, "CHILD - fip - exiting");
1436 exit(res);
1437 break;
1438 default:
1439 mr_msg(3,
1440 "feed_into_ntfsprog() called in background --- pid=%ld",
1441 (long int) (pid));
1442 }
1443 } else {
1444 if (!strncmp(orig_bf_fname, "/dev/", 5)) // non-NTFS partition
1445 {
1446 strcpy(outfile_fname, orig_bf_fname);
1447 } else // biggiefile
1448 {
1449 sprintf(outfile_fname, "%s/%s", bkpinfo->restore_path,
1450 orig_bf_fname);
1451 }
1452 use_ntfsprog_hack = FALSE;
1453 ntfsprog_fifo[0] = '\0';
1454 file_to_openout = outfile_fname;
1455 if (!does_file_exist(outfile_fname)) // yes, it looks weird with the '!' but it's correct that way
1456 {
1457 make_hole_for_file(outfile_fname);
1458 }
1459 sprintf(tmp, "Reassembling big file %ld (%s)",
1460 biggiefile_number + 1, orig_bf_fname);
1461 mr_msg(2, tmp);
1462 }
1463
1464 if (dummy_restore) {
1465 sprintf(outfile_fname, "/dev/null");
1466 }
1467
1468 if (!bkpinfo->zip_exe[0]) {
1469 sprintf(command, "cat > \"%s\"", file_to_openout);
1470 } else {
1471 sprintf(command, "%s -dc > \"%s\" 2>> %s", bkpinfo->zip_exe,
1472 file_to_openout, MONDO_LOGFILE);
1473 }
1474 sprintf(tmp, "Pipe command = '%s'", command);
1475 mr_msg(3, tmp);
1476
1477 /* restore biggiefile, one slice at a time */
1478 if (!(pout = popen(command, "w"))) {
1479 fatal_error("Cannot pipe out");
1480 }
1481 for (res = read_header_block_from_stream(&slice_siz, tmp, &ctrl_chr);
1482 ctrl_chr != BLK_STOP_A_BIGGIE;
1483 res = read_header_block_from_stream(&slice_siz, tmp, &ctrl_chr)) {
1484 if (ctrl_chr != BLK_START_AN_AFIO_OR_SLICE) {
1485 wrong_marker(BLK_START_AN_AFIO_OR_SLICE, ctrl_chr);
1486 }
1487 sprintf(tmp, "Working on file #%ld, slice #%ld ",
1488 biggiefile_number + 1, current_slice_number);
1489 mr_msg(2, tmp);
1490 if (!g_text_mode) {
1491 newtDrawRootText(0, g_noof_rows - 2, tmp);
1492 newtRefresh();
1493 }
1494 strip_spaces(tmp);
1495 update_progress_form(tmp);
1496 if (current_slice_number == 0) {
1497 res =
1498 read_file_from_stream_to_file(bkpinfo,
1499 "/tmp/biggie-blah.txt",
1500 slice_siz);
1501 if (!(fin = fopen("/tmp/biggie-blah.txt", "r"))) {
1502 log_OS_error("blah blah");
1503 } else {
1504 if (fread
1505 ((void *) &biggiestruct, 1, sizeof(biggiestruct),
1506 fin) < sizeof(biggiestruct)) {
1507 mr_msg(2,
1508 "Warning - unable to get biggiestruct of bigfile #%d",
1509 biggiefile_number + 1);
1510 }
1511 paranoid_fclose(fin);
1512 }
1513 } else {
1514 res =
1515 read_file_from_stream_to_stream(bkpinfo, pout, slice_siz);
1516 }
1517 retval += res;
1518 res = read_header_block_from_stream(&slice_siz, tmp, &ctrl_chr);
1519 if (ctrl_chr != BLK_STOP_AN_AFIO_OR_SLICE) {
1520 wrong_marker(BLK_STOP_AN_AFIO_OR_SLICE, ctrl_chr);
1521 }
1522 current_slice_number++;
1523 g_current_progress++;
1524 }
1525 paranoid_pclose(pout);
1526
1527 mr_msg(1, "pathname_of_last_file_restored is now %s",
1528 pathname_of_last_file_restored);
1529
1530 if (use_ntfsprog_hack) {
1531 mr_msg(3, "Waiting for ntfsclone to finish");
1532 sprintf(tmp,
1533 " ps | grep \" ntfsclone \" | grep -v grep > /dev/null 2> /dev/null");
1534 while (system(tmp) == 0) {
1535 sleep(1);
1536 }
1537 mr_msg(3, "OK, ntfsclone has really finished");
1538 }
1539
1540 mr_msg(3, "biggiestruct.filename = %s", biggiestruct.filename);
1541 mr_msg(3, "biggiestruct.checksum = %s", biggiestruct.checksum);
1542 if (strcmp(outfile_fname, "/dev/null")) {
1543 chmod(outfile_fname, biggiestruct.properties.st_mode);
1544 chown(outfile_fname, biggiestruct.properties.st_uid,
1545 biggiestruct.properties.st_gid);
1546 ubuf->actime = biggiestruct.properties.st_atime;
1547 ubuf->modtime = biggiestruct.properties.st_mtime;
1548 utime(outfile_fname, ubuf);
1549 }
1550
1551 mr_free(tmp);
1552 mr_free(outfile_fname);
1553 mr_free(command);
1554 mr_free(ntfsprog_command);
1555 mr_free(sz_devfile);
1556 mr_free(ntfsprog_fifo);
1557 g_loglevel = old_loglevel;
1558 return (retval);
1559}
1560
1561/**************************************************************************
1562 *END_RESTORE_A_BIGGIEFILE_FROM_STREAM *
1563 **************************************************************************/
1564
1565
1566
1567/**
1568 * Restore @p tarball_fname from CD.
1569 * @param tarball_fname The filename of the tarball to restore (in /mnt/cdrom).
1570 * This will be used unmodified.
1571 * @param current_tarball_number The number (starting from 0) of the fileset
1572 * we're restoring now.
1573 * @param filelist The node structure containing the list of files to be
1574 * restored. If no file in the afioball is in this list, afio will still be
1575 * called, but nothing will be written.
1576 * @return 0 for success, nonzero for failure.
1577 */
1578int
1579restore_a_tarball_from_CD(char *tarball_fname,
1580 long current_tarball_number,
1581 struct s_node *filelist)
1582{
1583 int retval = 0;
1584 int res;
1585 char *p;
1586
1587 /** malloc **/
1588 char *command;
1589 char *tmp;
1590 char *filelist_name;
1591 char *filelist_subset_fname;
1592 char *executable;
1593 char *temp_log;
1594 char screen_message[100];
1595 long matches = 0;
1596 bool use_star;
1597 char *xattr_fname;
1598 char *acl_fname;
1599// char files_to_restore_this_time_fname[MAX_STR_LEN];
1600
1601 assert_string_is_neither_NULL_nor_zerolength(tarball_fname);
1602 malloc_string(command);
1603 malloc_string(tmp);
1604 malloc_string(filelist_name);
1605 malloc_string(filelist_subset_fname);
1606 malloc_string(executable);
1607 malloc_string(temp_log);
1608 malloc_string(xattr_fname);
1609 malloc_string(acl_fname);
1610
1611 mr_msg(5, "Entering");
1612 filelist_subset_fname[0] = '\0';
1613 use_star = (strstr(tarball_fname, ".star")) ? TRUE : FALSE;
1614// sprintf(files_to_restore_this_time_fname, "/tmp/ftrttf.%d.%d", (int)getpid(), (int)random());
1615 sprintf(command, "mkdir -p %s/tmp", MNT_RESTORING);
1616 run_program_and_log_output(command, 9);
1617 sprintf(temp_log, "/tmp/%d.%d", (int) (random() % 32768),
1618 (int) (random() % 32768));
1619
1620 sprintf(filelist_name, MNT_CDROM "/archives/filelist.%ld",
1621 current_tarball_number);
1622 if (length_of_file(filelist_name) <= 2) {
1623 mr_msg(2, "There are _zero_ files in filelist '%s'",
1624 filelist_name);
1625 mr_msg(2,
1626 "This is a bit silly (ask dev-team to fix mondo_makefilelist, please)");
1627 mr_msg(2,
1628 "but it's non-critical. It's cosmetic. Don't worry about it.");
1629 retval = 0;
1630 goto leave_sub;
1631 }
1632 if (count_lines_in_file(filelist_name) <= 0
1633 || length_of_file(tarball_fname) <= 0) {
1634 mr_msg(3, "length_of_file(%s) = %llu", tarball_fname,
1635 length_of_file(tarball_fname));
1636 sprintf(tmp, "Unable to restore fileset #%ld (CD I/O error)",
1637 current_tarball_number);
1638 log_to_screen(tmp);
1639 retval = 1;
1640 goto leave_sub;
1641 }
1642
1643 if (filelist) {
1644 sprintf(filelist_subset_fname, "/tmp/filelist-subset-%ld.tmp",
1645 current_tarball_number);
1646 if ((matches =
1647 save_filelist_entries_in_common(filelist_name, filelist,
1648 filelist_subset_fname,
1649 use_star))
1650 <= 0) {
1651 sprintf(tmp, "Skipping fileset %ld", current_tarball_number);
1652 mr_msg(1, tmp);
1653 } else {
1654 mr_msg(3, "Saved fileset %ld's subset to %s",
1655 current_tarball_number, filelist_subset_fname);
1656 }
1657 sprintf(screen_message, "Tarball #%ld --- %ld matches",
1658 current_tarball_number, matches);
1659 log_to_screen(screen_message);
1660 } else {
1661 filelist_subset_fname[0] = '\0';
1662 }
1663
1664 if (filelist == NULL || matches > 0) {
1665 if (g_getfattr) {
1666 sprintf(xattr_fname, XATTR_LIST_FNAME_RAW_SZ,
1667 MNT_CDROM "/archives", current_tarball_number);
1668 }
1669 if (g_getfacl) {
1670 sprintf(acl_fname, ACL_LIST_FNAME_RAW_SZ, MNT_CDROM "/archives",
1671 current_tarball_number);
1672 }
1673 if (strstr(tarball_fname, ".bz2")) {
1674 strcpy(executable, "bzip2");
1675 } else if (strstr(tarball_fname, ".gz")) {
1676 strcpy(executable, "gzip");
1677 } else if (strstr(tarball_fname, ".lzo")) {
1678 strcpy(executable, "lzop");
1679 } else {
1680 executable[0] = '\0';
1681 }
1682 if (executable[0]) {
1683 sprintf(tmp, "which %s > /dev/null 2> /dev/null", executable);
1684 if (run_program_and_log_output(tmp, FALSE)) {
1685 log_to_screen
1686 ("(compare_a_tarball) Compression program not found - oh no!");
1687 paranoid_MR_finish(1);
1688 }
1689 strcpy(tmp, executable);
1690 sprintf(executable, "-P %s -Z", tmp);
1691 }
1692#ifdef __FreeBSD__
1693#define BUFSIZE 512
1694#else
1695#define BUFSIZE (1024L*1024L)/TAPE_BLOCK_SIZE
1696#endif
1697
1698// if (strstr(tarball_fname, ".star."))
1699 if (use_star) {
1700 sprintf(command,
1701 "star -x -force-remove -U " STAR_ACL_SZ
1702 " errctl= file=%s", tarball_fname);
1703 if (strstr(tarball_fname, ".bz2")) {
1704 strcat(command, " -bz");
1705 }
1706 } else {
1707 if (filelist_subset_fname[0] != '\0') {
1708 sprintf(command,
1709 "afio -i -M 8m -b %ld -c %ld %s -w '%s' %s",
1710 TAPE_BLOCK_SIZE,
1711 BUFSIZE, executable, filelist_subset_fname,
1712// files_to_restore_this_time_fname,
1713 tarball_fname);
1714 } else {
1715 sprintf(command,
1716 "afio -i -b %ld -c %ld -M 8m %s %s",
1717 TAPE_BLOCK_SIZE,
1718 BUFSIZE, executable, tarball_fname);
1719 }
1720 }
1721#undef BUFSIZE
1722 sprintf(command + strlen(command), " 2>> %s >> %s", temp_log,
1723 temp_log);
1724 mr_msg(1, "command = '%s'", command);
1725 unlink(temp_log);
1726 res = system(command);
1727 if (res) {
1728 p = strstr(command, "-acl ");
1729 if (p) {
1730 p[0] = p[1] = p[2] = p[3] = ' ';
1731 mr_msg(1, "new command = '%s'", command);
1732 res = system(command);
1733 }
1734 }
1735 if (res && length_of_file(temp_log) < 5) {
1736 res = 0;
1737 }
1738
1739 if (g_getfattr) {
1740 mr_msg(1, "Setting fattr list %s", xattr_fname);
1741 if (length_of_file(xattr_fname) > 0) {
1742 res = set_fattr_list(filelist_subset_fname, xattr_fname);
1743 if (res) {
1744 log_to_screen
1745 ("Errors occurred while setting extended attributes");
1746 } else {
1747 mr_msg(1, "I set xattr OK");
1748 }
1749 retval += res;
1750 }
1751 }
1752 if (g_getfacl) {
1753 mr_msg(1, "Setting acl list %s", acl_fname);
1754 if (length_of_file(acl_fname) > 0) {
1755 res = set_acl_list(filelist_subset_fname, acl_fname);
1756 if (res) {
1757 log_to_screen
1758 ("Errors occurred while setting access control lists");
1759 } else {
1760 mr_msg(1, "I set ACL OK");
1761 }
1762 retval += res;
1763 }
1764 }
1765 if (retval) {
1766 sprintf(command, "cat %s >> %s", temp_log, MONDO_LOGFILE);
1767 system(command);
1768 mr_msg(2, "Errors occurred while processing fileset #%d",
1769 current_tarball_number);
1770 } else {
1771 mr_msg(2, "Fileset #%d processed OK", current_tarball_number);
1772 }
1773 }
1774 if (does_file_exist("/PAUSE")) {
1775 popup_and_OK
1776 ("Press ENTER to go on. Delete /PAUSE to stop these pauses.");
1777 }
1778 unlink(filelist_subset_fname);
1779 unlink(xattr_fname);
1780 unlink(acl_fname);
1781 unlink(temp_log);
1782
1783 leave_sub:
1784 mr_free(command);
1785 mr_free(tmp);
1786 mr_free(filelist_name);
1787 mr_free(filelist_subset_fname);
1788 mr_free(executable);
1789 mr_free(temp_log);
1790 mr_free(xattr_fname);
1791 mr_free(acl_fname);
1792 mr_msg(5, "Leaving");
1793 return (retval);
1794}
1795
1796/**************************************************************************
1797 *END_RESTORE_A_TARBALL_FROM_CD *
1798 **************************************************************************/
1799
1800
1801/**
1802 * Restore a tarball from the currently opened stream.
1803 * @param bkpinfo The backup information structure. Fields used:
1804 * - @c bkpinfo->backup_media_type
1805 * - @c bkpinfo->media_device
1806 * - @c bkpinfo->zip_exe
1807 * @param tarball_fname The filename of the afioball to restore.
1808 * @param current_tarball_number The number (starting from 0) of the fileset
1809 * we're restoring now.
1810 * @param filelist The node structure containing the list of files to be
1811 * restored. If no file in the afioball is in this list, afio will still be
1812 * called, but nothing will be written.
1813 * @param size The size (in @b bytes) of the afioball.
1814 * @return 0 for success, nonzero for failure.
1815 */
1816int
1817restore_a_tarball_from_stream(struct s_bkpinfo *bkpinfo,
1818 char *tarball_fname,
1819 long current_tarball_number,
1820 struct s_node *filelist,
1821 long long size, char *xattr_fname,
1822 char *acl_fname)
1823{
1824 int retval = 0;
1825 int res = 0;
1826
1827 /** malloc add ***/
1828 char *tmp;
1829 char *command;
1830 char *afio_fname;
1831 char *filelist_fname;
1832 char *filelist_subset_fname;
1833 char *executable;
1834 long matches = 0;
1835 bool restore_this_fileset = FALSE;
1836 bool use_star;
1837
1838 assert(bkpinfo != NULL);
1839 assert_string_is_neither_NULL_nor_zerolength(tarball_fname);
1840 malloc_string(filelist_subset_fname);
1841 malloc_string(filelist_fname);
1842 malloc_string(afio_fname);
1843 malloc_string(executable);
1844 malloc_string(command);
1845 malloc_string(tmp);
1846 filelist_subset_fname[0] = '\0';
1847 /* to do it with a file... */
1848 use_star = (strstr(tarball_fname, ".star")) ? TRUE : FALSE;
1849 sprintf(tmp,
1850 "Restoring from fileset #%ld (%ld KB) on %s #%d",
1851 current_tarball_number, (long) size >> 10,
1852 media_descriptor_string(bkpinfo->backup_media_type),
1853 g_current_media_number);
1854 mr_msg(2, tmp);
1855 run_program_and_log_output("mkdir -p " MNT_RESTORING "/tmp", FALSE);
1856
1857 /****************************************************************************
1858 * Use RAMDISK's /tmp; saves time; oh wait, it's too small *
1859 * Well, pipe from tape to afio, then; oh wait, can't do that either: bug *
1860 * in afio or someting; oh darn.. OK, use tmpfs :-) *
1861 ****************************************************************************/
1862 filelist_fname[0] = filelist_subset_fname[0] = '\0';
1863 sprintf(afio_fname, "/tmp/tmpfs/archive.tmp.%ld",
1864 current_tarball_number);
1865 sprintf(filelist_fname, "%s/filelist.%ld", bkpinfo->tmpdir,
1866 current_tarball_number);
1867 sprintf(filelist_subset_fname, "%s/filelist-subset-%ld.tmp",
1868 bkpinfo->tmpdir, current_tarball_number);
1869// sprintf(filelist_fname, "/tmp/tmpfs/temp-filelist.%ld", current_tarball_number);
1870 res = read_file_from_stream_to_file(bkpinfo, afio_fname, size);
1871 if (strstr(tarball_fname, ".star")) {
1872 bkpinfo->use_star = TRUE;
1873 }
1874 if (res) {
1875 mr_msg(1, "Warning - error reading afioball from tape");
1876 }
1877 if (bkpinfo->compression_level == 0) {
1878 executable[0] = '\0';
1879 } else {
1880 if (bkpinfo->use_star) {
1881 strcpy(executable, " -bz");
1882 } else {
1883 sprintf(executable, "-P %s -Z", bkpinfo->zip_exe);
1884 }
1885 }
1886
1887 if (!filelist) // if unconditional restore then restore entire fileset
1888 {
1889 restore_this_fileset = TRUE;
1890 } else // If restoring selectively then get TOC from tarball
1891 {
1892 if (strstr(tarball_fname, ".star.")) {
1893 use_star = TRUE;
1894 sprintf(command, "star -t file=%s %s", afio_fname, executable);
1895 } else {
1896 use_star = FALSE;
1897 sprintf(command, "afio -t -M 8m -b %ld %s %s", TAPE_BLOCK_SIZE,
1898 executable, afio_fname);
1899 }
1900 sprintf(command + strlen(command), " > %s 2>> %s", filelist_fname,
1901 MONDO_LOGFILE);
1902 mr_msg(1, "command = %s", command);
1903 if (system(command)) {
1904 mr_msg(4, "Warning - error occurred while retrieving TOC");
1905 }
1906 if ((matches =
1907 save_filelist_entries_in_common(filelist_fname, filelist,
1908 filelist_subset_fname,
1909 use_star))
1910 <= 0 || length_of_file(filelist_subset_fname) < 2) {
1911 if (length_of_file(filelist_subset_fname) < 2) {
1912 mr_msg(1, "No matches found in fileset %ld",
1913 current_tarball_number);
1914 }
1915 sprintf(tmp, "Skipping fileset %ld", current_tarball_number);
1916 mr_msg(2, tmp);
1917 restore_this_fileset = FALSE;
1918 } else {
1919 mr_msg(5, "%ld matches. Saved fileset %ld's subset to %s",
1920 matches, current_tarball_number,
1921 filelist_subset_fname);
1922 restore_this_fileset = TRUE;
1923 }
1924 }
1925
1926// Concoct the call to star/afio to restore files
1927 if (strstr(tarball_fname, ".star.")) // star
1928 {
1929 sprintf(command, "star -x file=%s %s", afio_fname, executable);
1930 if (filelist) {
1931 sprintf(command + strlen(command), " list=%s",
1932 filelist_subset_fname);
1933 }
1934 } else // afio
1935 {
1936 sprintf(command, "afio -i -M 8m -b %ld %s", TAPE_BLOCK_SIZE,
1937 executable);
1938 if (filelist) {
1939 sprintf(command + strlen(command), " -w %s",
1940 filelist_subset_fname);
1941 }
1942 sprintf(command + strlen(command), " %s", afio_fname);
1943 }
1944 sprintf(command + strlen(command), " 2>> %s", MONDO_LOGFILE);
1945
1946// Call if IF there are files to restore (selectively/unconditionally)
1947 if (restore_this_fileset) {
1948 mr_msg(1, "Calling command='%s'", command);
1949 paranoid_system(command);
1950
1951 if (g_getfattr) {
1952 iamhere("Restoring xattr stuff");
1953 res = set_fattr_list(filelist_subset_fname, xattr_fname);
1954 if (res) {
1955 mr_msg(1, "Errors occurred while setting xattr");
1956 } else {
1957 mr_msg(1, "I set xattr OK");
1958 }
1959 retval += res;
1960 }
1961
1962 if (g_getfacl) {
1963 iamhere("Restoring acl stuff");
1964 res = set_acl_list(filelist_subset_fname, acl_fname);
1965 if (res) {
1966 mr_msg(1, "Errors occurred while setting ACL");
1967 } else {
1968 mr_msg(1, "I set ACL OK");
1969 }
1970 retval += res;
1971 }
1972
1973 } else {
1974 mr_msg(1, "NOT CALLING '%s'", command);
1975 }
1976
1977 if (does_file_exist("/PAUSE") && current_tarball_number >= 50) {
1978 log_to_screen("Paused after set %ld", current_tarball_number);
1979 popup_and_OK("Pausing. Press ENTER to continue.");
1980 }
1981
1982 unlink(filelist_subset_fname);
1983 unlink(filelist_fname);
1984 unlink(afio_fname);
1985
1986 mr_free(filelist_subset_fname);
1987 mr_free(filelist_fname);
1988 mr_free(afio_fname);
1989 mr_free(command);
1990 mr_free(tmp);
1991 return (retval);
1992}
1993
1994/**************************************************************************
1995 *END_RESTORE_A_TARBALL_FROM_STREAM *
1996 **************************************************************************/
1997
1998
1999
2000
2001/**
2002 * Restore all biggiefiles from all media in this CD backup.
2003 * The CD with the last afioball should be currently mounted.
2004 * @param bkpinfo The backup information structure. @c backup_media_type is the
2005 * only field used in this function.
2006 * @param filelist The node structure containing the list of files to be
2007 * restored. If a prospective biggiefile is not in this list, it will be ignored.
2008 * @return 0 for success, nonzero for failure.
2009 */
2010int
2011restore_all_biggiefiles_from_CD(struct s_bkpinfo *bkpinfo,
2012 struct s_node *filelist)
2013{
2014 int retval = 0;
2015 int res;
2016 long noof_biggiefiles, bigfileno = 0, total_slices;
2017 /** malloc **/
2018 char *tmp;
2019 bool just_changed_cds = FALSE, finished;
2020 char *xattr_fname;
2021 char *acl_fname;
2022 char *biggies_whose_EXATs_we_should_set; // EXtended ATtributes
2023 char *pathname_of_last_biggie_restored;
2024 FILE *fbw = NULL;
2025
2026 malloc_string(xattr_fname);
2027 malloc_string(acl_fname);
2028 malloc_string(tmp);
2029 malloc_string(biggies_whose_EXATs_we_should_set);
2030 malloc_string(pathname_of_last_biggie_restored);
2031 assert(bkpinfo != NULL);
2032
2033 sprintf(biggies_whose_EXATs_we_should_set,
2034 "%s/biggies-whose-EXATs-we-should-set", bkpinfo->tmpdir);
2035 if (!(fbw = fopen(biggies_whose_EXATs_we_should_set, "w"))) {
2036 mr_msg(1, "Warning - cannot openout %s",
2037 biggies_whose_EXATs_we_should_set);
2038 }
2039
2040 read_cfg_var(g_mondo_cfg_file, "total-slices", tmp);
2041 total_slices = atol(tmp);
2042 sprintf(tmp, "Reassembling large files ");
2043 mvaddstr_and_log_it(g_currentY, 0, tmp);
2044 if (length_of_file(BIGGIELIST) < 6) {
2045 mr_msg(1, "OK, no biggielist; not restoring biggiefiles");
2046 return (0);
2047 }
2048 noof_biggiefiles = count_lines_in_file(BIGGIELIST);
2049 if (noof_biggiefiles <= 0) {
2050 mr_msg(2,
2051 "OK, no biggiefiles in biggielist; not restoring biggiefiles");
2052 return (0);
2053 }
2054 sprintf(tmp, "OK, there are %ld biggiefiles in the archives",
2055 noof_biggiefiles);
2056 mr_msg(2, tmp);
2057
2058 open_progress_form("Reassembling large files",
2059 "I am now reassembling all the large files.",
2060 "Please wait. This may take some time.",
2061 "", total_slices);
2062 for (bigfileno = 0, finished = FALSE; !finished;) {
2063 mr_msg(2, "Thinking about restoring bigfile %ld", bigfileno + 1);
2064 if (!does_file_exist(slice_fname(bigfileno, 0, ARCHIVES_PATH, ""))) {
2065 mr_msg(3,
2066 "...but its first slice isn't on this CD. Perhaps this was a selective restore?");
2067 mr_msg(3, "Cannot find bigfile #%ld 's first slice on %s #%d",
2068 bigfileno + 1,
2069 media_descriptor_string(bkpinfo->backup_media_type),
2070 g_current_media_number);
2071 mr_msg(3, "Slicename would have been %s",
2072 slice_fname(bigfileno + 1, 0, ARCHIVES_PATH, ""));
2073 // I'm not positive 'just_changed_cds' is even necessary...
2074 if (just_changed_cds) {
2075 just_changed_cds = FALSE;
2076 mr_msg(3,
2077 "I'll continue to scan this CD for bigfiles to be restored.");
2078 } else if (does_file_exist(MNT_CDROM "/archives/NOT-THE-LAST")) {
2079 insist_on_this_cd_number(bkpinfo,
2080 ++g_current_media_number);
2081 sprintf(tmp, "Restoring from %s #%d",
2082 media_descriptor_string(bkpinfo->
2083 backup_media_type),
2084 g_current_media_number);
2085 log_to_screen(tmp);
2086 just_changed_cds = TRUE;
2087 } else {
2088 mr_msg(2, "There was no bigfile #%ld. That's OK.",
2089 bigfileno + 1);
2090 mr_msg(2, "I'm going to stop restoring bigfiles now.");
2091 finished = TRUE;
2092 }
2093 } else {
2094 just_changed_cds = FALSE;
2095 sprintf(tmp, "Restoring big file %ld", bigfileno + 1);
2096 update_progress_form(tmp);
2097 res =
2098 restore_a_biggiefile_from_CD(bkpinfo, bigfileno, filelist,
2099 pathname_of_last_biggie_restored);
2100 iamhere(pathname_of_last_biggie_restored);
2101 if (fbw && pathname_of_last_biggie_restored[0]) {
2102 fprintf(fbw, "%s\n", pathname_of_last_biggie_restored);
2103 }
2104 retval += res;
2105 bigfileno++;
2106
2107 }
2108 }
2109
2110 if (fbw) {
2111 fclose(fbw);
2112 if (g_getfattr) {
2113 sprintf(xattr_fname, XATTR_BIGGLST_FNAME_RAW_SZ, ARCHIVES_PATH);
2114 if (length_of_file(xattr_fname) > 0) {
2115 set_fattr_list(biggies_whose_EXATs_we_should_set, xattr_fname);
2116 }
2117 }
2118 if (g_getfacl) {
2119 sprintf(acl_fname, ACL_BIGGLST_FNAME_RAW_SZ, ARCHIVES_PATH);
2120 if (length_of_file(acl_fname) > 0) {
2121 set_acl_list(biggies_whose_EXATs_we_should_set, acl_fname);
2122 }
2123 }
2124 }
2125 if (does_file_exist("/PAUSE")) {
2126 popup_and_OK
2127 ("Press ENTER to go on. Delete /PAUSE to stop these pauses.");
2128 }
2129 close_progress_form();
2130 if (retval) {
2131 mvaddstr_and_log_it(g_currentY++, 74, "Errors.");
2132 } else {
2133 mvaddstr_and_log_it(g_currentY++, 74, "Done.");
2134 }
2135 mr_free(xattr_fname);
2136 mr_free(acl_fname);
2137 mr_free(tmp);
2138 mr_free(biggies_whose_EXATs_we_should_set);
2139 mr_free(pathname_of_last_biggie_restored);
2140 return (retval);
2141}
2142
2143/**************************************************************************
2144 *END_RESTORE_ALL_BIGGIFILES_FROM_CD *
2145 **************************************************************************/
2146
2147
2148
2149/**
2150 * Restore all afioballs from all CDs in the backup.
2151 * The first CD should be inserted (if not, it will be asked for).
2152 * @param bkpinfo The backup information structure. @c backup_media_type is the
2153 * only field used in @e this function.
2154 * @param filelist The node structure containing the list of files to be
2155 * restored. If no file in some particular afioball is in this list, afio will
2156 * still be called for that fileset, but nothing will be written.
2157 * @return 0 for success, or the number of filesets that failed.
2158 */
2159int
2160restore_all_tarballs_from_CD(struct s_bkpinfo *bkpinfo,
2161 struct s_node *filelist)
2162{
2163 int retval = 0;
2164 int res;
2165 int attempts;
2166 long current_tarball_number = 0;
2167 long max_val;
2168 /**malloc ***/
2169 char *tmp;
2170 char *tarball_fname;
2171 char *progress_str;
2172 char *comment;
2173
2174 malloc_string(tmp);
2175 malloc_string(tarball_fname);
2176 malloc_string(progress_str);
2177 malloc_string(comment);
2178
2179 assert(bkpinfo != NULL);
2180
2181 mvaddstr_and_log_it(g_currentY, 0, "Restoring from archives");
2182 mr_msg(2,
2183 "Insisting on 1st CD, so that I can have a look at LAST-FILELIST-NUMBER");
2184 if (g_current_media_number != 1) {
2185 mr_msg(3, "OK, that's jacked up.");
2186 g_current_media_number = 1;
2187 }
2188 insist_on_this_cd_number(bkpinfo, g_current_media_number);
2189 read_cfg_var(g_mondo_cfg_file, "last-filelist-number", tmp);
2190 max_val = atol(tmp) + 1;
2191 sprintf(progress_str, "Restoring from %s #%d",
2192 media_descriptor_string(bkpinfo->backup_media_type),
2193 g_current_media_number);
2194 log_to_screen(progress_str);
2195 open_progress_form("Restoring from archives",
2196 "Restoring data from the archives.",
2197 "Please wait. This may take some time.",
2198 progress_str, max_val);
2199 for (;;) {
2200 insist_on_this_cd_number(bkpinfo, g_current_media_number);
2201 update_progress_form(progress_str);
2202 sprintf(tarball_fname, MNT_CDROM "/archives/%ld.afio.bz2",
2203 current_tarball_number);
2204 if (!does_file_exist(tarball_fname)) {
2205 sprintf(tarball_fname, MNT_CDROM "/archives/%ld.afio.gz",
2206 current_tarball_number);
2207 }
2208 if (!does_file_exist(tarball_fname)) {
2209 sprintf(tarball_fname, MNT_CDROM "/archives/%ld.afio.lzo",
2210 current_tarball_number);
2211 }
2212 if (!does_file_exist(tarball_fname)) {
2213 sprintf(tarball_fname, MNT_CDROM "/archives/%ld.afio.",
2214 current_tarball_number);
2215 }
2216 if (!does_file_exist(tarball_fname)) {
2217 sprintf(tarball_fname, MNT_CDROM "/archives/%ld.star.bz2",
2218 current_tarball_number);
2219 }
2220 if (!does_file_exist(tarball_fname)) {
2221 sprintf(tarball_fname, MNT_CDROM "/archives/%ld.star.",
2222 current_tarball_number);
2223 }
2224 if (!does_file_exist(tarball_fname)) {
2225 if (current_tarball_number == 0) {
2226 log_to_screen
2227 ("No tarballs. Strange. Maybe you only backed up freakin' big files?");
2228 return (0);
2229 }
2230 if (!does_file_exist(MNT_CDROM "/archives/NOT-THE-LAST")
2231 || system("find " MNT_CDROM
2232 "/archives/slice* > /dev/null 2> /dev/null") ==
2233 0) {
2234 break;
2235 }
2236 g_current_media_number++;
2237 sprintf(progress_str, "Restoring from %s #%d",
2238 media_descriptor_string(bkpinfo->backup_media_type),
2239 g_current_media_number);
2240 log_to_screen(progress_str);
2241 } else {
2242 sprintf(progress_str, "Restoring from fileset #%ld on %s #%d",
2243 current_tarball_number,
2244 media_descriptor_string(bkpinfo->backup_media_type),
2245 g_current_media_number);
2246// mr_msg(3, "progress_str = %s", progress_str);
2247 for (res = 999, attempts = 0; attempts < 3 && res != 0;
2248 attempts++) {
2249 res =
2250 restore_a_tarball_from_CD(tarball_fname,
2251 current_tarball_number,
2252 filelist);
2253 }
2254 sprintf(tmp, "%s #%d, fileset #%ld - restore ",
2255 media_descriptor_string(bkpinfo->backup_media_type),
2256 g_current_media_number, current_tarball_number);
2257 if (res) {
2258 strcat(tmp, "reported errors");
2259 } else if (attempts > 1) {
2260 strcat(tmp, "succeeded");
2261 } else {
2262 strcat(tmp, "succeeded");
2263 }
2264 if (attempts > 1) {
2265 sprintf(tmp + strlen(tmp), " (%d attempts) - review logs",
2266 attempts);
2267 }
2268 strcpy(comment, tmp);
2269 if (attempts > 1) {
2270 log_to_screen(comment);
2271 }
2272
2273 retval += res;
2274 current_tarball_number++;
2275 g_current_progress++;
2276 }
2277 }
2278 close_progress_form();
2279 if (retval) {
2280 mvaddstr_and_log_it(g_currentY++, 74, "Errors.");
2281 } else {
2282 mvaddstr_and_log_it(g_currentY++, 74, "Done.");
2283 }
2284 mr_free(tmp);
2285 mr_free(tarball_fname);
2286 mr_free(progress_str);
2287 mr_free(comment);
2288
2289 return (retval);
2290}
2291
2292/**************************************************************************
2293 *END_RESTORE_ALL_TARBALLS_FROM_CD *
2294 **************************************************************************/
2295
2296
2297
2298/**
2299 * Restore all biggiefiles from the currently opened stream.
2300 * @param bkpinfo The backup information structure. Passed to other functions.
2301 * @param filelist The node structure containing the list of files to be
2302 * restored. If a prospective biggiefile is not in the list, it will be ignored.
2303 * @return 0 for success, or the number of biggiefiles that failed.
2304 */
2305int
2306restore_all_biggiefiles_from_stream(struct s_bkpinfo *bkpinfo,
2307 struct s_node *filelist)
2308{
2309 long noof_biggiefiles;
2310 long current_bigfile_number = 0;
2311 long total_slices;
2312
2313 int retval = 0;
2314 int res = 0;
2315 int ctrl_chr;
2316
2317 /** malloc add ****/
2318 char *tmp;
2319 char *biggie_fname;
2320 char *biggie_cksum;
2321 char *xattr_fname;
2322 char *acl_fname;
2323 char *p;
2324 char *pathname_of_last_biggie_restored;
2325 char *biggies_whose_EXATs_we_should_set; // EXtended ATtributes
2326 long long biggie_size;
2327 FILE *fbw = NULL;
2328
2329 malloc_string(tmp);
2330 malloc_string(biggie_fname);
2331 malloc_string(biggie_cksum);
2332 malloc_string(xattr_fname);
2333 malloc_string(acl_fname);
2334 malloc_string(biggies_whose_EXATs_we_should_set);
2335 malloc_string(pathname_of_last_biggie_restored);
2336 assert(bkpinfo != NULL);
2337
2338 read_cfg_var(g_mondo_cfg_file, "total-slices", tmp);
2339
2340 total_slices = atol(tmp);
2341 sprintf(tmp, "Reassembling large files ");
2342 if (g_getfattr) {
2343 sprintf(xattr_fname, XATTR_BIGGLST_FNAME_RAW_SZ, bkpinfo->tmpdir);
2344 }
2345 if (g_getfacl) {
2346 sprintf(acl_fname, ACL_BIGGLST_FNAME_RAW_SZ, bkpinfo->tmpdir);
2347 }
2348 mvaddstr_and_log_it(g_currentY, 0, tmp);
2349 sprintf(biggies_whose_EXATs_we_should_set,
2350 "%s/biggies-whose-EXATs-we-should-set", bkpinfo->tmpdir);
2351 if (!(fbw = fopen(biggies_whose_EXATs_we_should_set, "w"))) {
2352 mr_msg(1, "Warning - cannot openout %s",
2353 biggies_whose_EXATs_we_should_set);
2354 }
2355// get xattr and acl files if they're there
2356 res =
2357 read_header_block_from_stream(&biggie_size, biggie_fname,
2358 &ctrl_chr);
2359 if (ctrl_chr == BLK_START_EXTENDED_ATTRIBUTES) {
2360 res =
2361 read_EXAT_files_from_tape(bkpinfo, &biggie_size, biggie_fname,
2362 &ctrl_chr, xattr_fname, acl_fname);
2363 }
2364
2365 noof_biggiefiles = atol(biggie_fname);
2366 sprintf(tmp, "OK, there are %ld biggiefiles in the archives",
2367 noof_biggiefiles);
2368 mr_msg(2, tmp);
2369 open_progress_form("Reassembling large files",
2370 "I am now reassembling all the large files.",
2371 "Please wait. This may take some time.",
2372 "", total_slices);
2373
2374 for (res =
2375 read_header_block_from_stream(&biggie_size, biggie_fname,
2376 &ctrl_chr);
2377 ctrl_chr != BLK_STOP_BIGGIEFILES;
2378 res =
2379 read_header_block_from_stream(&biggie_size, biggie_fname,
2380 &ctrl_chr)) {
2381 if (ctrl_chr != BLK_START_A_NORMBIGGIE
2382 && ctrl_chr != BLK_START_A_PIHBIGGIE) {
2383 wrong_marker(BLK_START_A_NORMBIGGIE, ctrl_chr);
2384 }
2385 p = strrchr(biggie_fname, '/');
2386 if (!p) {
2387 p = biggie_fname;
2388 } else {
2389 p++;
2390 }
2391 sprintf(tmp, "Restoring big file %ld (%lld K)",
2392 current_bigfile_number + 1, biggie_size / 1024);
2393 update_progress_form(tmp);
2394 res = restore_a_biggiefile_from_stream(bkpinfo, biggie_fname,
2395 current_bigfile_number,
2396 biggie_cksum,
2397 biggie_size,
2398 filelist, ctrl_chr,
2399 pathname_of_last_biggie_restored);
2400 mr_msg(1, "I believe I have restored %s",
2401 pathname_of_last_biggie_restored);
2402 if (fbw && pathname_of_last_biggie_restored[0]) {
2403 fprintf(fbw, "%s\n", pathname_of_last_biggie_restored);
2404 }
2405 retval += res;
2406 current_bigfile_number++;
2407
2408 }
2409 if (current_bigfile_number != noof_biggiefiles
2410 && noof_biggiefiles != 0) {
2411 sprintf(tmp, "Warning - bigfileno=%ld but noof_biggiefiles=%ld\n",
2412 current_bigfile_number, noof_biggiefiles);
2413 } else {
2414 sprintf(tmp,
2415 "%ld biggiefiles in biggielist.txt; %ld biggiefiles processed today.",
2416 noof_biggiefiles, current_bigfile_number);
2417 }
2418 mr_msg(1, tmp);
2419
2420 if (fbw) {
2421 fclose(fbw);
2422 if (length_of_file(biggies_whose_EXATs_we_should_set) > 2) {
2423 iamhere("Setting biggie-EXATs");
2424 if (g_getfattr) {
2425 if (length_of_file(xattr_fname) > 0) {
2426 mr_msg(1, "set_fattr_List(%s,%s)",
2427 biggies_whose_EXATs_we_should_set, xattr_fname);
2428 set_fattr_list(biggies_whose_EXATs_we_should_set,
2429 xattr_fname);
2430 }
2431 }
2432 if (g_getfacl) {
2433 if (length_of_file(acl_fname) > 0) {
2434 mr_msg(1, "set_acl_list(%s,%s)",
2435 biggies_whose_EXATs_we_should_set, acl_fname);
2436 set_acl_list(biggies_whose_EXATs_we_should_set, acl_fname);
2437 }
2438 }
2439 } else {
2440 iamhere
2441 ("No biggiefiles selected. So, no biggie-EXATs to set.");
2442 }
2443 }
2444 if (does_file_exist("/PAUSE")) {
2445 popup_and_OK
2446 ("Press ENTER to go on. Delete /PAUSE to stop these pauses.");
2447 }
2448
2449 close_progress_form();
2450 if (retval) {
2451 mvaddstr_and_log_it(g_currentY++, 74, "Errors.");
2452 } else {
2453 mvaddstr_and_log_it(g_currentY++, 74, "Done.");
2454 }
2455 mr_free(biggies_whose_EXATs_we_should_set);
2456 mr_free(pathname_of_last_biggie_restored);
2457 mr_free(biggie_fname);
2458 mr_free(biggie_cksum);
2459 mr_free(xattr_fname);
2460 mr_free(acl_fname);
2461 mr_free(tmp);
2462 return (retval);
2463}
2464
2465/**************************************************************************
2466 *END_RESTORE_ALL_BIGGIEFILES_FROM_STREAM *
2467 **************************************************************************/
2468
2469
2470
2471
2472
2473
2474/**
2475 * Restore all afioballs from the currently opened tape stream.
2476 * @param bkpinfo The backup information structure. Fields used:
2477 * - @c bkpinfo->backup_media_type
2478 * - @c bkpinfo->restore_path
2479 * @param filelist The node structure containing the list of files to be
2480 * restored. If no file in an afioball is in this list, afio will still be
2481 * called for that fileset, but nothing will be written.
2482 * @return 0 for success, or the number of filesets that failed.
2483 */
2484int
2485restore_all_tarballs_from_stream(struct s_bkpinfo *bkpinfo,
2486 struct s_node *filelist)
2487{
2488 int retval = 0;
2489 int res;
2490 long current_afioball_number = 0;
2491 int ctrl_chr;
2492 long max_val /*, total_noof_files */ ;
2493
2494 /** malloc **/
2495 char *tmp;
2496 char *progress_str;
2497 char *tmp_fname;
2498 char *xattr_fname;
2499 char *acl_fname;
2500
2501 long long tmp_size;
2502
2503 malloc_string(tmp);
2504 malloc_string(progress_str);
2505 malloc_string(tmp_fname);
2506 assert(bkpinfo != NULL);
2507 malloc_string(xattr_fname);
2508 malloc_string(acl_fname);
2509 mvaddstr_and_log_it(g_currentY, 0, "Restoring from archives");
2510 read_cfg_var(g_mondo_cfg_file, "last-filelist-number", tmp);
2511 max_val = atol(tmp) + 1;
2512
2513 chdir(bkpinfo->restore_path); /* I don't know why this is needed _here_ but it seems to be. -HR, 02/04/2002 */
2514
2515 run_program_and_log_output("pwd", 5);
2516
2517 sprintf(progress_str, "Restoring from media #%d",
2518 g_current_media_number);
2519 log_to_screen(progress_str);
2520 open_progress_form("Restoring from archives",
2521 "Restoring data from the archives.",
2522 "Please wait. This may take some time.",
2523 progress_str, max_val);
2524
2525 mr_msg(3, "hey");
2526
2527 res = read_header_block_from_stream(&tmp_size, tmp_fname, &ctrl_chr);
2528 if (res) {
2529 mr_msg(2, "Warning - error reading afioball from tape");
2530 }
2531 retval += res;
2532 if (ctrl_chr != BLK_START_AFIOBALLS) {
2533 wrong_marker(BLK_START_AFIOBALLS, ctrl_chr);
2534 }
2535 mr_msg(2, "ho");
2536 res = read_header_block_from_stream(&tmp_size, tmp_fname, &ctrl_chr);
2537 while (ctrl_chr != BLK_STOP_AFIOBALLS) {
2538 update_progress_form(progress_str);
2539 if (g_getfattr) {
2540 sprintf(xattr_fname, "%s/xattr-subset-%ld.tmp", bkpinfo->tmpdir,
2541 current_afioball_number);
2542 unlink(xattr_fname);
2543 }
2544 if (g_getfacl) {
2545 sprintf(acl_fname, "%s/acl-subset-%ld.tmp", bkpinfo->tmpdir,
2546 current_afioball_number);
2547 unlink(acl_fname);
2548 }
2549 if (ctrl_chr == BLK_START_EXTENDED_ATTRIBUTES) {
2550 iamhere("Reading EXAT files from tape");
2551 res =
2552 read_EXAT_files_from_tape(bkpinfo, &tmp_size, tmp_fname,
2553 &ctrl_chr, xattr_fname,
2554 acl_fname);
2555 }
2556 if (ctrl_chr != BLK_START_AN_AFIO_OR_SLICE) {
2557 wrong_marker(BLK_START_AN_AFIO_OR_SLICE, ctrl_chr);
2558 }
2559 sprintf(tmp,
2560 "Restoring from fileset #%ld (name=%s, size=%ld K)",
2561 current_afioball_number, tmp_fname, (long) tmp_size >> 10);
2562 res =
2563 restore_a_tarball_from_stream(bkpinfo, tmp_fname,
2564 current_afioball_number,
2565 filelist, tmp_size, xattr_fname,
2566 acl_fname);
2567 retval += res;
2568 if (res) {
2569 sprintf(tmp, "Fileset %ld - errors occurred",
2570 current_afioball_number);
2571 log_to_screen(tmp);
2572 }
2573 res =
2574 read_header_block_from_stream(&tmp_size, tmp_fname, &ctrl_chr);
2575 if (ctrl_chr != BLK_STOP_AN_AFIO_OR_SLICE) {
2576 wrong_marker(BLK_STOP_AN_AFIO_OR_SLICE, ctrl_chr);
2577 }
2578
2579 current_afioball_number++;
2580 g_current_progress++;
2581 sprintf(progress_str, "Restoring from fileset #%ld on %s #%d",
2582 current_afioball_number,
2583 media_descriptor_string(bkpinfo->backup_media_type),
2584 g_current_media_number);
2585 res =
2586 read_header_block_from_stream(&tmp_size, tmp_fname, &ctrl_chr);
2587 if (g_getfattr) {
2588 unlink(xattr_fname);
2589 }
2590 if (g_getfacl) {
2591 unlink(acl_fname);
2592 }
2593 } // next
2594 mr_msg(1, "All done with afioballs");
2595 close_progress_form();
2596 if (retval) {
2597 mvaddstr_and_log_it(g_currentY++, 74, "Errors.");
2598 } else {
2599 mvaddstr_and_log_it(g_currentY++, 74, "Done.");
2600 }
2601 mr_free(tmp);
2602 mr_free(progress_str);
2603 mr_free(tmp_fname);
2604 mr_free(xattr_fname);
2605 mr_free(acl_fname);
2606 return (retval);
2607}
2608
2609/**************************************************************************
2610 *END_ RESTORE_ALL_TARBALLS_FROM_STREAM *
2611 **************************************************************************/
2612
2613/* @} - end of LLrestoreGroup */
2614
2615
2616/**
2617 * Restore all files in @p filelist.
2618 * @param bkpinfo The backup information structure. Most fields are used.
2619 * @param filelist The node structure containing the list of files to be
2620 * restored.
2621 * @return 0 for success, or the number of afioballs and biggiefiles that failed.
2622 * @ingroup restoreGroup
2623 */
2624int restore_everything(struct s_bkpinfo *bkpinfo, struct s_node *filelist)
2625{
2626 int resA;
2627 int resB;
2628
2629 /** mallco ***/
2630 char *cwd;
2631 char *newpath;
2632 char *tmp;
2633 assert(bkpinfo != NULL);
2634
2635 malloc_string(cwd);
2636 malloc_string(newpath);
2637 malloc_string(tmp);
2638 mr_msg(2, "restore_everything() --- starting");
2639 g_current_media_number = 1;
2640 getcwd(cwd, MAX_STR_LEN - 1);
2641 sprintf(tmp, "mkdir -p %s", bkpinfo->restore_path);
2642 run_program_and_log_output(tmp, FALSE);
2643 mr_msg(1, "Changing dir to %s", bkpinfo->restore_path);
2644 chdir(bkpinfo->restore_path);
2645 getcwd(newpath, MAX_STR_LEN - 1);
2646 mr_msg(1, "path is now %s", newpath);
2647 mr_msg(1, "restoring everything");
2648 if (!find_home_of_exe("petris") && !g_text_mode) {
2649 newtDrawRootText(0, g_noof_rows - 2,
2650 "Press ALT-<left cursor> twice to play Petris :-) ");
2651 newtRefresh();
2652 }
2653 mvaddstr_and_log_it(g_currentY, 0, "Preparing to read your archives");
2654 if (IS_THIS_A_STREAMING_BACKUP(bkpinfo->backup_media_type)) {
2655 mount_cdrom(bkpinfo);
2656 mvaddstr_and_log_it(g_currentY++, 0,
2657 "Restoring OS and data from streaming media");
2658 if (bkpinfo->backup_media_type == cdstream) {
2659 openin_cdstream(bkpinfo);
2660 } else {
2661 assert_string_is_neither_NULL_nor_zerolength(bkpinfo->
2662 media_device);
2663 openin_tape(bkpinfo);
2664 }
2665 resA = restore_all_tarballs_from_stream(bkpinfo, filelist);
2666 resB = restore_all_biggiefiles_from_stream(bkpinfo, filelist);
2667 if (bkpinfo->backup_media_type == cdstream) {
2668 closein_cdstream(bkpinfo);
2669 } else {
2670 closein_tape(bkpinfo);
2671 }
2672 } else {
2673 mvaddstr_and_log_it(g_currentY++, 0,
2674 "Restoring OS and data from CD ");
2675 mount_cdrom(bkpinfo);
2676 resA = restore_all_tarballs_from_CD(bkpinfo, filelist);
2677 resB = restore_all_biggiefiles_from_CD(bkpinfo, filelist);
2678 }
2679 chdir(cwd);
2680 if (resA + resB) {
2681 log_to_screen("Errors occurred while data was being restored.");
2682 }
2683 if (length_of_file("/etc/raidtab") > 0) {
2684 mr_msg(2, "Copying local raidtab to restored filesystem");
2685 run_program_and_log_output("cp -f /etc/raidtab " MNT_RESTORING
2686 "/etc/raidtab", FALSE);
2687 }
2688 kill_petris();
2689 mr_msg(2, "restore_everything() --- leaving");
2690 mr_free(cwd);
2691 mr_free(newpath);
2692 mr_free(tmp);
2693 return (resA + resB);
2694}
2695
2696/**************************************************************************
2697 *END_RESTORE_EVERYTHING *
2698 **************************************************************************/
2699
2700
2701
2702/**
2703 * @brief Haha. You wish! (This function is not implemented :-)
2704 */
2705int
2706restore_live_from_monitas_server(struct s_bkpinfo *bkpinfo,
2707 char *monitas_device,
2708 char *restore_this_directory,
2709 char *restore_here)
2710 /* NB: bkpinfo hasn't been populated yet, except for ->tmp which is "/tmp" */
2711{
2712 FILE *fout;
2713 int retval = 0;
2714 int i;
2715 int j;
2716 struct mountlist_itself the_mountlist;
2717 static struct raidlist_itself the_raidlist;
2718 /** malloc **/
2719 char tmp[MAX_STR_LEN + 1];
2720 char command[MAX_STR_LEN + 1];
2721 char datablock[256 * 1024];
2722 char datadisks_fname[MAX_STR_LEN + 1];
2723 long k;
2724 long length;
2725 long long llt;
2726 struct s_node *filelist = NULL;
2727 assert(bkpinfo != NULL);
2728 assert_string_is_neither_NULL_nor_zerolength(monitas_device);
2729 assert(restore_this_directory != NULL);
2730 assert(restore_here != NULL);
2731
2732 sprintf(tmp, "restore_here = '%s'", restore_here);
2733
2734 mr_msg(2, tmp);
2735
2736 mr_msg(2, "restore_live_from_monitas_server() - starting");
2737 unlink("/tmp/mountlist.txt");
2738 unlink("/tmp/filelist.full");
2739 unlink("/tmp/biggielist.txt");
2740 if (restore_here[0] == '\0') {
2741 strcpy(bkpinfo->restore_path, MNT_RESTORING);
2742 } else {
2743 strcpy(bkpinfo->restore_path, restore_here);
2744 }
2745 mr_msg(3, "FYI FYI FYI FYI FYI FYI FYI FYI FYI FYI FYI");
2746 sprintf(tmp, "FYI - data will be restored to %s",
2747 bkpinfo->restore_path);
2748 mr_msg(3, tmp);
2749 mr_msg(3, "FYI FYI FYI FYI FYI FYI FYI FYI FYI FYI FYI");
2750 sprintf(datadisks_fname, "/tmp/mondorestore.datadisks.%d",
2751 (int) (random() % 32768));
2752 chdir(bkpinfo->tmpdir);
2753
2754 sprintf(command, "cat %s", monitas_device);
2755 g_tape_stream = popen(command, "r"); // for compatibility with openin_tape()
2756 if (!(fout = fopen(datadisks_fname, "w"))) {
2757 log_OS_error(datadisks_fname);
2758 return (1);
2759 }
2760 for (i = 0; i < 32; i++) {
2761 for (j = 0; j < 4; j++) {
2762 for (length = k = 0; length < 256 * 1024; length += k) {
2763 k = fread(datablock + length, 1, 256 * 1024 - length,
2764 g_tape_stream);
2765 }
2766 fwrite(datablock, 1, length, fout);
2767 g_tape_posK += length;
2768 }
2769 }
2770 paranoid_fclose(fout);
2771 sprintf(command,
2772 "tar -zxvf %s tmp/mondo-restore.cfg tmp/mountlist.txt tmp/filelist.full tmp/biggielist.txt",
2773 datadisks_fname);
2774 run_program_and_log_output(command, 4);
2775 read_header_block_from_stream(&llt, tmp, &i);
2776 read_header_block_from_stream(&llt, tmp, &i);
2777
2778 unlink(datadisks_fname);
2779 read_cfg_file_into_bkpinfo(g_mondo_cfg_file, bkpinfo);
2780 retval = load_mountlist(&the_mountlist, g_mountlist_fname); // in case read_cfg_file_into_bkpinfo strcpy(bkpinfo->media_device, monitas_device);
2781
2782
2783 load_raidtab_into_raidlist(&the_raidlist, RAIDTAB_FNAME);
2784 iamhere("FIXME");
2785 fatal_error("This will fail");
2786 sprintf(command,
2787 "grep -E '^%s.*$' %s > %s",
2788 restore_this_directory, g_filelist_full, g_filelist_full);
2789 if (system(command)) {
2790 retval++;
2791 log_to_screen
2792 ("Error(s) occurred while processing filelist and wildcard");
2793 }
2794 iamhere("FIXME");
2795 fatal_error("This will fail");
2796 sprintf(command,
2797 "grep -E '^%s.*$' %s > %s",
2798 restore_this_directory, g_biggielist_txt, g_biggielist_txt);
2799 if (system(command)) {
2800 mr_msg(1,
2801 "Error(s) occurred while processing biggielist and wildcard");
2802 }
2803 sprintf(command, "touch %s", g_biggielist_txt);
2804 run_program_and_log_output(command, FALSE);
2805// filelist = load_filelist(g_filelist_restthese); // FIXME --- this probably doesn't work because it doesn't include the biggiefiles
2806 retval += restore_everything(bkpinfo, filelist);
2807 free_filelist(filelist);
2808 mr_msg(2, "--------End of restore_live_from_monitas_server--------");
2809 return (retval);
2810}
2811
2812/**************************************************************************
2813 *END_RESTORE_LIVE_FROM_MONITAS_SERVER *
2814 **************************************************************************/
2815
2816
2817
2818
2819extern void wait_until_software_raids_are_prepped(char *, int);
2820
2821
2822char which_restore_mode(void);
2823
2824
2825/**
2826 * Log a "don't panic" message to the logfile.
2827 */
2828void welcome_to_mondorestore()
2829{
2830 mr_msg(0, "-------------- Mondo Restore v%s -------------", PACKAGE_VERSION);
2831 mr_msg(0,
2832 "DON'T PANIC! Mondorestore logs almost everything, so please ");
2833 mr_msg(0,
2834 "don't break out in a cold sweat just because you see a few ");
2835 mr_msg(0,
2836 "error messages in the log. Read them; analyze them; see if ");
2837 mr_msg(0,
2838 "they are significant; above all, verify your backups! Please");
2839 mr_msg(0,
2840 "attach a compressed copy of this log to any e-mail you send ");
2841 mr_msg(0,
2842 "to the Mondo mailing list when you are seeking technical ");
2843 mr_msg(0,
2844 "support. Without it, we can't help you. - DevTeam");
2845 mr_msg(0,
2846 "------------------------------------------------------------");
2847 mr_msg(0,
2848 "BTW, despite (or perhaps because of) the wealth of messages,");
2849 mr_msg(0,
2850 "some users are inclined to stop reading this log. If Mondo ");
2851 mr_msg(0,
2852 "stopped for some reason, chances are it's detailed here. ");
2853 mr_msg(0,
2854 "More than likely there's a message at the very end of this ");
2855 mr_msg(0,
2856 "log that will tell you what is wrong. Please read it! ");
2857 mr_msg(0,
2858 "------------------------------------------------------------");
2859}
2860
2861
2862
2863/**
2864 * Restore the user's data.
2865 * What did you think it did, anyway? :-)
2866 */
2867int main(int argc, char *argv[])
2868{
2869 FILE *fin;
2870 FILE *fout;
2871 int retval = 0;
2872 int res;
2873// int c;
2874 char *tmp;
2875
2876 struct mountlist_itself *mountlist;
2877 struct raidlist_itself *raidlist;
2878 struct s_bkpinfo *bkpinfo;
2879 struct s_node *filelist;
2880 char *a, *b;
2881 bool run_postnuke = FALSE;
2882
2883 /**************************************************************************
2884 * hugo- *
2885 * busy stuff here - it needs some comments -stan *
2886 * *
2887 **************************************************************************/
2888 if (getuid() != 0) {
2889 fprintf(stderr, "Please run as root.\r\n");
2890 exit(127);
2891 }
2892
2893 g_loglevel = DEFAULT_MR_LOGLEVEL;
2894 malloc_string(tmp);
2895
2896/* Configure global variables */
2897#ifdef __FreeBSD__
2898 if (strstr
2899 (call_program_and_get_last_line_of_output("cat /tmp/cmdline"),
2900 "textonly"))
2901#else
2902 if (strstr
2903 (call_program_and_get_last_line_of_output("cat /proc/cmdline"),
2904 "textonly"))
2905#endif
2906 {
2907 g_text_mode = TRUE;
2908 mr_msg(1, "TEXTONLY MODE");
2909 } else {
2910 g_text_mode = FALSE;
2911 } // newt :-)
2912 bkpinfo = g_bkpinfo_DONTUSETHIS = mr_malloc(sizeof(struct s_bkpinfo));
2913 mountlist = mr_malloc(sizeof(struct mountlist_itself));
2914 raidlist = mr_malloc(sizeof(struct raidlist_itself));
2915
2916 malloc_libmondo_global_strings();
2917
2918 strcpy(g_mondo_home,
2919 call_program_and_get_last_line_of_output("which mondorestore"));
2920 sprintf(g_tmpfs_mountpt, "/tmp/tmpfs");
2921 make_hole_for_dir(g_tmpfs_mountpt);
2922 g_current_media_number = 1; // precaution
2923
2924 run_program_and_log_output("mkdir -p " MNT_CDROM, FALSE);
2925 run_program_and_log_output("mkdir -p /mnt/floppy", FALSE);
2926
2927 malloc_string(tmp);
2928 malloc_string(a);
2929 malloc_string(b);
2930 setup_MR_global_filenames(bkpinfo); // malloc() and set globals, using bkpinfo->tmpdir etc.
2931 reset_bkpinfo(bkpinfo);
2932 bkpinfo->backup_media_type = none; // in case boot disk was made for one backup type but user wants to restore from another backup type
2933 bkpinfo->restore_data = TRUE; // Well, yeah :-)
2934 if (am_I_in_disaster_recovery_mode()) {
2935 run_program_and_log_output("mount / -o remount,rw", 2);
2936 } // for b0rken distros
2937 g_main_pid = getpid();
2938 srandom((int) (time(NULL)));
2939 register_pid(getpid(), "mondo");
2940 set_signals(TRUE);
2941 g_kernel_version = get_kernel_version();
2942
2943 mr_msg(1, "FYI - g_mountlist_fname = %s", g_mountlist_fname);
2944 if (strlen(g_mountlist_fname) < 3) {
2945 fatal_error
2946 ("Serious error in malloc()'ing. Could be a bug in your glibc.");
2947 }
2948 mkdir(MNT_CDROM, 0x770);
2949
2950/* Backup original mountlist.txt */
2951 sprintf(tmp, "%s.orig", g_mountlist_fname);
2952 if (!does_file_exist(g_mountlist_fname)) {
2953 mr_msg(2,
2954 "%ld: Warning - g_mountlist_fname (%s) does not exist yet",
2955 __LINE__, g_mountlist_fname);
2956 } else if (!does_file_exist(tmp)) {
2957 sprintf(tmp, "cp -f %s %s.orig", g_mountlist_fname,
2958 g_mountlist_fname);
2959 run_program_and_log_output(tmp, FALSE);
2960 }
2961
2962/* Init directories */
2963 make_hole_for_dir(bkpinfo->tmpdir);
2964 sprintf(tmp, "mkdir -p %s", bkpinfo->tmpdir);
2965 run_program_and_log_output(tmp, FALSE);
2966 make_hole_for_dir("/var/log");
2967 make_hole_for_dir("/tmp/tmpfs"); /* just in case... */
2968 run_program_and_log_output("umount " MNT_CDROM, FALSE);
2969 run_program_and_log_output
2970 ("ln -sf /var/log/mondo-archive.log /tmp/mondo-restore.log",
2971 FALSE);
2972
2973 run_program_and_log_output("rm -Rf /tmp/tmpfs/mondo.tmp.*", FALSE);
2974
2975/* Init GUI */
2976 malloc_libmondo_global_strings();
2977 setup_newt_stuff(); /* call newtInit and setup screen log */
2978 welcome_to_mondorestore();
2979 if (bkpinfo->disaster_recovery) {
2980 mr_msg(1, "I am in disaster recovery mode");
2981 } else {
2982 mr_msg(1, "I am in normal, live mode");
2983 }
2984
2985 iamhere("what time is it");
2986
2987/* Process command-line parameters */
2988 if (argc == 2 && strcmp(argv[1], "--edit-mountlist") == 0) {
2989#ifdef __FreeBSD__
2990 system("mv -f /tmp/raidconf.txt /etc/raidtab");
2991 if (!does_file_exist("/etc/raidtab"))
2992 system("vinum printconfig > /etc/raidtab");
2993#endif
2994 load_raidtab_into_raidlist(raidlist, RAIDTAB_FNAME);
2995 if (!does_file_exist(g_mountlist_fname)) {
2996 strcpy(g_mountlist_fname, "/tmp/mountlist.txt");
2997 }
2998 res = let_user_edit_the_mountlist(bkpinfo, mountlist, raidlist);
2999#ifdef __FreeBSD__
3000 system("mv -f /etc/raidtab /tmp/raidconf.txt");
3001#endif
3002 paranoid_MR_finish(res);
3003 }
3004
3005 g_loglevel = DEFAULT_MR_LOGLEVEL;
3006 if (argc == 3 && strcmp(argv[1], "--echo-to-screen") == 0) {
3007 fout = fopen("/tmp/out.txt", "w");
3008 fput_string_one_char_at_a_time(stderr, argv[2]);
3009 finish(0);
3010 }
3011
3012 if (argc == 3 && strcmp(argv[1], "--gendf") == 0) {
3013 make_grub_install_scriptlet(argv[2]);
3014 finish(0);
3015 }
3016
3017 if (argc >= 2 && strcmp(argv[1], "--pih") == 0) {
3018 if (system("mount | grep cdrom 2> /dev/null > /dev/null")) {
3019 system("mount " MNT_CDROM);
3020 }
3021 bkpinfo->compression_level = 1;
3022 g_current_media_number = 2;
3023 strcpy(bkpinfo->restore_path, "/tmp/TESTING");
3024 bkpinfo->backup_media_type = dvd;
3025 open_progress_form("Reassembling /dev/hda1",
3026 "Shark is a bit of a silly person.",
3027 "Please wait. This may take some time.",
3028 "", 1999);
3029 system("rm -Rf /tmp/*pih*");
3030
3031 restore_a_biggiefile_from_CD(bkpinfo, 42, NULL, tmp);
3032 }
3033
3034 if (argc == 5 && strcmp(argv[1], "--common") == 0) {
3035 g_loglevel = 6;
3036 filelist = load_filelist(argv[2]);
3037 if (!filelist) {
3038 fatal_error("Failed to load filelist");
3039 }
3040 toggle_node_selection(filelist, FALSE);
3041 toggle_all_root_dirs_on(filelist);
3042 // BERLIOS: /usr/lib ???
3043 toggle_path_selection(filelist, "/usr/share", TRUE);
3044// show_filelist(filelist);
3045 save_filelist(filelist, "/tmp/out.txt");
3046// finish(0);
3047// toggle_path_selection (filelist, "/root/stuff", TRUE);
3048 strcpy(a, argv[3]);
3049 strcpy(b, argv[4]);
3050
3051 res = save_filelist_entries_in_common(a, filelist, b, FALSE);
3052 free_filelist(filelist);
3053 printf("res = %d", res);
3054 finish(0);
3055 }
3056
3057 if (argc == 3 && strcmp(argv[1], "--popuplist") == 0) {
3058 popup_changelist_from_file(argv[2]);
3059 paranoid_MR_finish(0);
3060 }
3061
3062 if (argc == 5 && strcmp(argv[1], "--copy") == 0) {
3063 mr_msg(1, "SCORE");
3064 g_loglevel = 10;
3065 if (strstr(argv[2], "save")) {
3066 mr_msg(1, "Saving from %s to %s", argv[3], argv[4]);
3067 fin = fopen(argv[3], "r");
3068 fout = fopen(argv[4], "w");
3069 copy_from_src_to_dest(fin, fout, 'w');
3070 fclose(fin);
3071 fin = fopen(argv[3], "r");
3072 copy_from_src_to_dest(fin, fout, 'w');
3073 fclose(fout);
3074 fclose(fin);
3075 } else if (strstr(argv[2], "restore")) {
3076 fout = fopen(argv[3], "w");
3077 fin = fopen(argv[4], "r");
3078 copy_from_src_to_dest(fout, fin, 'r');
3079 fclose(fin);
3080 fin = fopen(argv[4], "r");
3081 copy_from_src_to_dest(fout, fin, 'r');
3082 fclose(fout);
3083 fclose(fin);
3084 } else {
3085 fatal_error("Unknown additional param");
3086 }
3087 finish(0);
3088 }
3089
3090 if (argc == 3 && strcmp(argv[1], "--mdstat") == 0) {
3091 wait_until_software_raids_are_prepped(argv[2], 100);
3092 finish(0);
3093 }
3094
3095 if (argc == 3 && strcmp(argv[1], "--mdconv") == 0) {
3096 finish(create_raidtab_from_mdstat(argv[2]));
3097 }
3098
3099
3100 if (argc == 2 && strcmp(argv[1], "--live-grub") == 0) {
3101 retval = run_grub(FALSE, "/dev/hda");
3102 if (retval) {
3103 log_to_screen("Failed to write Master Boot Record");
3104 }
3105 paranoid_MR_finish(0);
3106 }
3107 if (argc == 3 && strcmp(argv[1], "--paa") == 0) {
3108 g_current_media_number = atoi(argv[2]);
3109 pause_and_ask_for_cdr(5, NULL);
3110 paranoid_MR_finish(0);
3111 } else if (!bkpinfo->disaster_recovery) { // live!
3112 if (argc != 1) {
3113 popup_and_OK
3114 ("Live mode doesn't support command-line parameters yet.");
3115 paranoid_MR_finish(1);
3116// return(1);
3117 }
3118 mr_msg(1, "I am in normal, live mode.");
3119 mr_msg(2, "FYI, MOUNTLIST_FNAME = %s", g_mountlist_fname);
3120 mount_boot_if_necessary(); /* for Gentoo users */
3121 mr_msg(2, "Still here.");
3122 if (argc > 1 && strcmp(argv[argc - 1], "--live-from-cd") == 0) {
3123 g_restoring_live_from_cd = TRUE;
3124 }
3125 if (argc == 5 && strcmp(argv[1], "--monitas-live") == 0) {
3126 retval =
3127 restore_live_from_monitas_server(bkpinfo,
3128 argv[2],
3129 argv[3], argv[4]);
3130 } else {
3131 mr_msg(2, "Calling restore_to_live_filesystem()");
3132 retval = restore_to_live_filesystem(bkpinfo);
3133 }
3134 mr_msg(2, "Still here. Yay.");
3135 if (strlen(bkpinfo->tmpdir) > 0) {
3136 sprintf(tmp, "rm -Rf %s/*", bkpinfo->tmpdir);
3137 run_program_and_log_output(tmp, FALSE);
3138 }
3139 unmount_boot_if_necessary(); /* for Gentoo users */
3140 paranoid_MR_finish(retval);
3141 } else {
3142 /* Disaster recovery mode (must be) */
3143 mr_msg(1, "I must be in disaster recovery mode.");
3144 mr_msg(2, "FYI, MOUNTLIST_FNAME = %s ", g_mountlist_fname);
3145 if (argc == 3 && strcmp(argv[1], "--monitas-memorex") == 0) {
3146 log_to_screen("Uh, that hasn't been implemented yet.");
3147 paranoid_MR_finish(1);
3148 }
3149
3150 iamhere("About to call load_mountlist and load_raidtab");
3151 strcpy(bkpinfo->restore_path, MNT_RESTORING);
3152 read_cfg_file_into_bkpinfo(g_mondo_cfg_file, bkpinfo);
3153 retval = load_mountlist(mountlist, g_mountlist_fname);
3154 retval += load_raidtab_into_raidlist(raidlist, RAIDTAB_FNAME);
3155 iamhere
3156 ("Returned from calling load_mountlist and load_raidtab successfully");
3157
3158 if (argc > 1
3159 && (strcmp(argv[1], "--compare") == 0
3160 || strcmp(argv[1], "--nuke") == 0)) {
3161 if (bkpinfo->backup_media_type == nfs
3162 && !is_this_device_mounted(bkpinfo->nfs_mount)) {
3163 mr_msg(1, "Mounting nfs dir");
3164 sprintf(bkpinfo->isodir, "/tmp/isodir");
3165 run_program_and_log_output("mkdir -p /tmp/isodir", 5);
3166 sprintf(tmp, "mount %s -t nfs -o nolock /tmp/isodir",
3167 bkpinfo->nfs_mount);
3168 run_program_and_log_output(tmp, 1);
3169 }
3170 }
3171
3172
3173 if (retval) {
3174 log_to_screen
3175 ("Warning - load_raidtab_into_raidlist returned an error");
3176 }
3177
3178
3179 mr_msg(1, "Send in the clowns.");
3180
3181 if (argc == 2 && strcmp(argv[1], "--partition-only") == 0) {
3182 mr_msg(0, "Partitioning only.");
3183 load_raidtab_into_raidlist(raidlist, RAIDTAB_FNAME);
3184 strcpy(g_mountlist_fname, "/tmp/mountlist.txt");
3185 load_mountlist(mountlist, g_mountlist_fname);
3186 res = partition_everything(mountlist);
3187 finish(res);
3188 }
3189
3190 if (argc == 2 && strcmp(argv[1], "--format-only") == 0) {
3191 mr_msg(0, "Formatting only.");
3192 load_raidtab_into_raidlist(raidlist, RAIDTAB_FNAME);
3193 strcpy(g_mountlist_fname, "/tmp/mountlist.txt");
3194 load_mountlist(mountlist, g_mountlist_fname);
3195 res = format_everything(mountlist, FALSE, raidlist);
3196 finish(res);
3197 }
3198
3199 if (argc == 2 && strcmp(argv[1], "--stop-lvm-and-raid") == 0) {
3200 mr_msg(0, "Stopping LVM and RAID");
3201 load_raidtab_into_raidlist(raidlist, RAIDTAB_FNAME);
3202 strcpy(g_mountlist_fname, "/tmp/mountlist.txt");
3203 load_mountlist(mountlist, g_mountlist_fname);
3204 res = do_my_funky_lvm_stuff(TRUE, FALSE);
3205 res += stop_all_raid_devices(mountlist);
3206 finish(res);
3207 }
3208
3209 if (argc == 2 && strcmp(argv[1], "--nuke") == 0) {
3210 iamhere("nuking");
3211 retval += nuke_mode(bkpinfo, mountlist, raidlist);
3212 } else if (argc == 2 && strcmp(argv[1], "--interactive") == 0) {
3213 iamhere("catchall");
3214 retval += catchall_mode(bkpinfo, mountlist, raidlist);
3215 } else if (argc == 2 && strcmp(argv[1], "--compare") == 0) {
3216 iamhere("compare");
3217 retval += compare_mode(bkpinfo, mountlist, raidlist);
3218 } else if (argc == 2 && strcmp(argv[1], "--iso") == 0) {
3219 iamhere("iso");
3220 retval = iso_mode(bkpinfo, mountlist, raidlist, FALSE);
3221 } else if (argc == 2 && strcmp(argv[1], "--mbr") == 0) {
3222 iamhere("mbr");
3223 retval = mount_all_devices(mountlist, TRUE);
3224 if (!retval) {
3225 retval += run_boot_loader(FALSE);
3226 retval += unmount_all_devices(mountlist);
3227 }
3228 if (retval) {
3229 log_to_screen("Failed to write Master Boot Record");
3230 }
3231 } else if (argc == 2 && strcmp(argv[1], "--isonuke") == 0) {
3232 iamhere("isonuke");
3233 retval = iso_mode(bkpinfo, mountlist, raidlist, TRUE);
3234 } else if (argc != 1) {
3235 log_to_screen("Invalid paremeters");
3236 paranoid_MR_finish(1);
3237 } else {
3238 iamhere("catchall (no mode specified in command-line call");
3239 retval += catchall_mode(bkpinfo, mountlist, raidlist);
3240 }
3241 }
3242
3243 /* clean up at the end */
3244 if (retval) {
3245 if (does_file_exist("/tmp/changed.files")) {
3246 log_to_screen
3247 ("See /tmp/changed.files for list of files that have changed.");
3248 }
3249 mvaddstr_and_log_it(g_currentY++,
3250 0,
3251 "Run complete. Errors were reported. Please review the logfile.");
3252 } else {
3253 if (IS_THIS_A_STREAMING_BACKUP(bkpinfo->backup_media_type)) {
3254 mvaddstr_and_log_it(g_currentY++,
3255 0,
3256 "Run complete. Please remove floppy/CD/media and reboot.");
3257 } else {
3258 run_program_and_log_output("sync", FALSE);
3259 if (is_this_device_mounted(MNT_CDROM)) {
3260 res =
3261 run_program_and_log_output("umount " MNT_CDROM, FALSE);
3262 } else {
3263 res = 0;
3264 }
3265
3266 if (!bkpinfo->please_dont_eject) {
3267 res = eject_device("/dev/cdrom");
3268/*
3269 if (res)
3270 {
3271 log_to_screen( "WARNING - failed to eject CD-ROM disk" );
3272 }
3273*/
3274 }
3275 mvaddstr_and_log_it(g_currentY++,
3276 0,
3277 "Run complete. Please remove media and reboot.");
3278 }
3279 }
3280
3281// g_I_have_just_nuked is set true by nuke_mode() just before it returns
3282 if (!system("which post-nuke > /dev/null 2> /dev/null")) {
3283 mr_msg(1, "post-nuke found; find out whether we should run it...");
3284 if (g_I_have_just_nuked || does_file_exist("/POST-NUKE-ANYWAY")) {
3285 run_postnuke = TRUE;
3286 mr_msg(1, "Yes, will run post-nuke because in nuke mode or file /POST-NUKE-ANYWAY exists.");
3287 } else if (ask_me_yes_or_no("post-nuke script found. Do you want to run it?")) {
3288 run_postnuke = TRUE;
3289 mr_msg(1, "Yes, will run post-nuke because user interactively asked for it.");
3290 } else {
3291 run_postnuke = FALSE;
3292 mr_msg(1, "No, will not run post-nuke.");
3293 }
3294 } else {
3295 mr_msg(1, "No post-nuke found.");
3296 }
3297 if (run_postnuke) {
3298 log_to_screen("Running post-nuke...");
3299 if (mount_all_devices(mountlist, TRUE)) {
3300 log_to_screen
3301 ("Unable to re-mount partitions for post-nuke stuff");
3302 } else {
3303 mr_msg(1, "Re-mounted partitions for post-nuke stuff");
3304 sprintf(tmp, "post-nuke %s %d", bkpinfo->restore_path,
3305 retval);
3306 mr_msg(2, "Calling '%s'", tmp);
3307 if ((res = run_program_and_log_output(tmp, 0))) {
3308 log_OS_error(tmp);
3309 }
3310 mr_msg(1, "post-nuke returned w/ res=%d", res);
3311 }
3312 unmount_all_devices(mountlist);
3313 log_to_screen("I've finished post-nuking.");
3314 }
3315
3316/*
3317 log_to_screen("If you are REALLY in a hurry, hit Ctrl-Alt-Del now.");
3318 log_to_screen("Otherwise, please wait until the RAID disks are done.");
3319 wait_until_software_raids_are_prepped("/proc/mdstat", 100);
3320 log_to_screen("Thank you.");
3321*/
3322 unlink("/tmp/mondo-run-prog.tmp");
3323 set_signals(FALSE);
3324 sprintf(tmp, "rm -Rf %s", bkpinfo->tmpdir);
3325 run_program_and_log_output(tmp, FALSE);
3326 log_to_screen
3327 ("Restore log copied to /tmp/mondo-restore.log on your hard disk");
3328 sprintf(tmp,
3329 "Mondo-restore is exiting (retval=%d) ",
3330 retval);
3331 log_to_screen(tmp);
3332 sprintf(tmp, "umount %s", bkpinfo->isodir);
3333 run_program_and_log_output(tmp, 5);
3334 mr_free(mountlist);
3335 mr_free(raidlist);
3336 if (am_I_in_disaster_recovery_mode()) {
3337 run_program_and_log_output("mount / -o remount,rw", 2);
3338 } // for b0rken distros
3339 paranoid_MR_finish(retval); // frees global stuff plus bkpinfo
3340 free_libmondo_global_strings(); // it's fine to have this here :) really :)
3341 mr_free(a);
3342 mr_free(b);
3343 mr_free(tmp);
3344
3345 unlink("/tmp/filelist.full");
3346 unlink("/tmp/filelist.full.gz");
3347
3348 exit(retval);
3349}
3350
3351/**************************************************************************
3352 *END_MAIN *
3353 **************************************************************************/
3354
3355
3356
3357
3358
3359/**************************************************************************
3360 *END_MONDO-RESTORE.C *
3361 **************************************************************************/
Note: See TracBrowser for help on using the repository browser.