source: MondoRescue/trunk/mondo/src/mondorestore/mondo-restore.c@ 900

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

Huge patch to introduce low level functions that will bw used everywhere (mr_free, mr_asprintf, ...)
Nearly linking now due to that.

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