source: MondoRescue/branches/2.2.5/mondo/src/mondorestore/mondo-restore.c@ 1869

Last change on this file since 1869 was 1869, checked in by Bruno Cornec, 16 years ago

Solve an issue on Bigfiles:
When one bigfile (such as mondo's ISO image) is deleted during the archiving,
it creates a hole in the suite of Bigfiles (in my case bigfile 0 was missing)
So at restore time, it was aborting the rest of the restoration of big files as this one was failing, which is worng
Now mondorestore loops until it reaches the number of bigfiles, so will restore the others.

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