source: branches/2.2.10/mondo/src/mondorestore/mondo-rstr-tools.c @ 2508

Last change on this file since 2508 was 2508, checked in by bruno, 9 years ago

r3287@localhost (orig r2285): bruno | 2009-07-20 11:36:47 +0200

r3285@localhost: bruno | 2009-07-20 11:17:35 +0200
Apply fix in 2.2.10 around multi USB device handling to 2.2.9 as well


r3291@localhost (orig r2288): bruno | 2009-07-21 16:48:31 +0200
Copy 2.2.10 test script in to 2.2.9 for memory problm analysis


r3293@localhost (orig r2290): bruno | 2009-07-22 14:03:44 +0200

  • Fix a printing error in mindi for the tar command
  • Fix all mr_asprintf which had no second param as a string


r3295@localhost (orig r2292): bruno | 2009-07-22 16:55:00 +0200

  • Fix #160 and #346 by rewriting the message.txt file with more valid information gathered in mindi


r3300@localhost (orig r2294): bruno | 2009-07-23 01:58:08 +0200

Man pages patch from Joe Ross (joe.ross_at_gmail.com)


r3303@localhost (orig r2297): bruno | 2009-07-23 17:43:49 +0200
Fix a remaining display error for 2.2.9. That version has been tested OK in a lab.


r3304@localhost (orig r2298): bruno | 2009-07-23 18:18:27 +0200

  • Remove memory leak for the last modification


r3308@localhost (orig r2302): bruno | 2009-07-24 21:18:50 +0200
Improve logging of mountlist.txt


r3310@localhost (orig r2304): bruno | 2009-07-27 19:45:10 +0200

  • popup_and_get_string needs an allocated buffer for the moment so fixing the calls with dyn. ones
  • Fix a bug in mem.c for mr_strcat, which wasn't modifying the right pointer level


r3311@localhost (orig r2305): bruno | 2009-07-27 19:49:35 +0200
Avoid a memory leak in the previous patch


r3314@localhost (orig r2308): bruno | 2009-07-27 20:59:06 +0200
Fix a bug in mr_strcat backported from 2.2.10. Should solve our seg faults.


r3315@localhost (orig r2309): bruno | 2009-07-28 02:14:23 +0200
Cosmetic changes to allow for quality to not giv false positive


r3343@localhost (orig r2311): bruno | 2009-08-18 02:13:43 +0200
Fix for initramfs detection with 2.6.30 (Hugo Vanwoerkom hvw59601_at_care2.com)


r3367@localhost (orig r2333): bruno | 2009-08-18 16:26:26 +0200
Adds a precision for -U option in man page on raw device usage and not partition name


r3373@localhost (orig r2336): bruno | 2009-08-20 17:37:41 +0200

  • Precise the combined usage of -E and -I in mondoarchive (Case 4601017223)


r3379@localhost (orig r2342): bruno | 2009-08-21 16:27:10 +0200


r3383@localhost (orig r2344): bruno | 2009-08-24 13:37:09 +0200

r3382@localhost: bruno | 2009-08-24 13:30:25 +0200
In NFS mode also propose access to expert, interactive, ... entry at boot prompt


r3388@localhost (orig r2346): bruno | 2009-08-27 11:41:16 +0200
Adds fdisk -l result in Log File at restore time


r3389@localhost (orig r2347): bruno | 2009-08-27 13:51:00 +0200

  • Solve tmp dir creation which sometimes was trying to create /%xx dirs. Should fix #293 for good


r3390@localhost (orig r2348): bruno | 2009-08-27 13:54:25 +0200
Improve logging (minor)


r3394@localhost (orig r2350): bruno | 2009-08-28 02:24:19 +0200
Change inerface of evaluate_mountlist and spread_flaws_across_three_lines in order to solve bugs linked to strings management in these functions. May fix a restoration crash seen by some customers


r3397@localhost (orig r2353): bruno | 2009-08-28 19:03:45 +0200

  • Addition of a nomd option to avoid starting mdadm
  • mpath is now already started if there was a mpath entry in mountlist


r3399@localhost (orig r2355): bruno | 2009-08-29 00:56:50 +0200
Remove function spread_flaws_across_three_lines and expand it at the single place where it was useful, and fix memory allocation issues in it.


r3402@localhost (orig r2358): bruno | 2009-09-01 19:02:35 +0200
P2V doc updated (Lester Wade lester.wade_at_hp.com)


r3404@localhost (orig r2360): bruno | 2009-09-01 19:26:53 +0200
Website update to refer to new P2V document


r3405@localhost (orig r2361): bruno | 2009-09-03 13:54:25 +0200

  • Fix a case where the NFS dir in restore mode was mounted rw (linked to bug #291 could create a huge problem)


r3407@localhost (orig r2363): bruno | 2009-09-03 14:46:46 +0200
More verbose at installation of additional tools


r3409@localhost (orig r2365): bruno | 2009-09-03 18:08:32 +0200

  • New update from Lester Wade (lester.wade_at_hp.com) for P2V doc


r3410@localhost (orig r2366): bruno | 2009-09-05 01:28:18 +0200
place the code of mondo_makefilelist before its call



r3411@localhost (orig r2367): bruno | 2009-09-06 01:51:26 +0200

  • Advertising for project-builder on the website added


r3412@localhost (orig r2368): bruno | 2009-09-07 15:36:23 +0200
Fix compilation issue


r3413@localhost (orig r2369): bruno | 2009-09-07 18:03:40 +0200
Another compilation issue fixed.


r3415@localhost (orig r2371): bruno | 2009-09-08 13:40:25 +0200

  • Fix a problem a error detection in evaluate_mountlist which casued nuke mode to abort. Error string should also be better now.


r3417@localhost (orig r2373): bruno | 2009-09-08 13:55:31 +0200
Avoid asking the Prefix name in NFS mode twice


r3418@localhost (orig r2374): bruno | 2009-09-08 20:04:07 +0200

  • Try to fix garbled screen progression in text mode based on 2.2.10 modifications which are working


r3424@localhost (orig r2380): bruno | 2009-09-09 20:30:47 +0200

  • Change NFS support into a NetFS support to allow for multiple protocol in addition to NFS (NEEDS TESTING)
  • Better logging to detect a potential nuke issue


r3425@localhost (orig r2381): bruno | 2009-09-10 02:05:55 +0200
Fix a missing param for sshfs call


r3428@localhost (orig r2384): bruno | 2009-09-10 13:02:56 +0200

  • Remove separate function look_for_duplicate_mountpoints used only once and whose interface created problems with caller


r3430@localhost (orig r2386): bruno | 2009-09-10 16:06:52 +0200
Be compatible on backup type by making old nfs recognized as netfs and proto forced


r3431@localhost (orig r2387): bruno | 2009-09-10 18:40:47 +0200
Fix a problem in netfs analysis in mondoarchive


r3432@localhost (orig r2388): bruno | 2009-09-10 20:25:13 +0200
Fix mondoarchive CLI analysis for NETFS type of requests


r3434@localhost (orig r2390): bruno | 2009-09-11 03:05:20 +0200

  • Adds ext3 initrd support for 2.6.30


r3437@localhost (orig r2393): bruno | 2009-09-11 11:56:52 +0200

  • Tries to add support for bzip2 and lzma initramfs (preliminary, not tested) for 2.6.30


r3438@localhost (orig r2394): bruno | 2009-09-12 02:53:02 +0200
Fix interface of evaluate_mountlist (remove 2nd param useless) and fix nuke mode which wasn't working.


r3441@localhost (orig r2397): bruno | 2009-09-14 18:54:34 +0200
Fix a format issue in text mode on percentage


r3452@localhost (orig r2398): bruno | 2009-09-15 16:00:13 +0200

  • Fix a bug where flaws_str could be NULL and wasn't tested correctly.


r3453@localhost (orig r2399): bruno | 2009-09-15 19:28:39 +0200

  • Use protocol name when displaying restore progress instead of netfs
  • Ask for network protocol name at restore time


r3455@localhost (orig r2401): bruno | 2009-09-15 19:34:19 +0200
Wrong structure member name was used


r3456@localhost (orig r2402): bruno | 2009-09-16 13:04:17 +0200
Use dir for shell related commands and dir1 for C related actions in open_and_list_dir to avoid missing some files with { in names e.g.


r3457@localhost (orig r2403): bruno | 2009-09-16 16:32:03 +0200

  • At restore time read the netfs protocol in the conf file


r3462@localhost (orig r2408): bruno | 2009-09-18 15:17:08 +0200
Remove useless script


r3463@localhost (orig r2409): bruno | 2009-09-18 15:25:35 +0200

  • Split deplist.txt into multiple conf files under deplist.d in the conf dir. This will allow to have a minimal.conf file for initrd content to analyze to improve support of new embedded feature in the future (sshfs, live install). The other conf files contain the additional commands to put in the all.tar.gz. For the moment, mindi is still working the same. THis infra will allow that support in a near future. deplist.txt is now reserved for the admin additional commands.


r3465@localhost (orig r2410): bruno | 2009-09-18 19:10:54 +0200

  • Better list of mandatory tools
  • Adds fuse and sshfs support in initrd


r3466@localhost (orig r2411): bruno | 2009-09-18 20:32:47 +0200
sshfs also needs ssh at restore time in initrd


r3478@localhost (orig r2418): bruno | 2009-09-23 23:22:39 +0200
Modify getfattr call to have all extended attributes, including non user ones. (patch from Kevin Ritzenthaler Kevin.Ritzenthaler_at_hp.com) and fix #357


r3479@localhost (orig r2419): bruno | 2009-09-23 23:50:34 +0200
star only supports ACL when used with exustar mode. Fix #356.


r3482@localhost (orig r2422): bruno | 2009-09-24 16:53:24 +0200

  • Adds support for bnx2x (BL 460 G6) and auth_rpcgss (Debian 2.6.31)


r3485@localhost (orig r2423): bruno | 2009-09-25 16:38:40 +0200
Fix an issue in is_this_device_mounted (string freed before last usage)


r3486@localhost (orig r2424): bruno | 2009-09-25 18:44:01 +0200

  • analyze-my-lvm now removes excluded devices from list coming from mondoarchive
  • new mr_make_devlist_from_pathlist which handle the new bkpinfo->exclude_devs field containing the excluded devices and remove corresponding code from libmondo-cli.c
  • Move DSF code into libmondo-devices.c for coherency, and only the previous function is made externally available
  • Remove dev_to_exclude in libmondo-archive.c which wasn't working correctly and replace it with bkpinfo->exclude_devs


r3487@localhost (orig r2425): bruno | 2009-09-25 18:58:23 +0200

  • Improving ssh support at restore time by providing a shadow file


r3489@localhost (orig r2426): bruno | 2009-09-25 19:42:09 +0200

  • Attempt to stay backward compatible without protocol for -n option


r3490@localhost (orig r2427): bruno | 2009-09-28 02:08:06 +0200
Avoids null param for excludes_devs for mindi call


r3492@localhost (orig r2429): bruno | 2009-09-28 11:46:16 +0200

  • Simplify GetInitrdFilesystemToUse? which doesn't need to detect everything, but just know if it's initramfs (new mode) or a compressed FS ext2/3 (older mode) as initrd is anyway re-made by mindi. Should fix #353


r3494@localhost (orig r2431): bruno | 2009-09-28 13:16:18 +0200

  • Use only the AWK veriable everywhere and not the awk command


r3495@localhost (orig r2432): bruno | 2009-09-28 14:16:31 +0200
Warning emited in case of duplicate mountpoints or devices in fstab found


r3496@localhost (orig r2433): bruno | 2009-09-28 15:55:17 +0200
ssh in the restore env needs some dlopened libs (libnss_compat|files)


r3497@localhost (orig r2434): bruno | 2009-09-28 16:33:14 +0200
Compiler warning fixed


r3498@localhost (orig r2435): bruno | 2009-09-28 17:55:26 +0200
Improve user management for NetFS cases


r3499@localhost (orig r2436): bruno | 2009-09-29 01:48:32 +0200

  • Improve deplist.d/* files
  • adds libnss for ssh support in boot disk
  • Solve a memory management issue in DSF module (strtok => mr_strtok)
  • DSF now also supports partitions in addition to full disks
  • Adds debug in open_and_list_dir


r3500@localhost (orig r2437): bruno | 2009-09-29 10:41:56 +0200

  • Fix udev support in init for Mandriva 2009.1 (udevadm settle is blocking)


r3501@localhost (orig r2438): bruno | 2009-09-29 14:41:36 +0200

  • Improvements on sshfs/ssh management in restore mode
  • Include now all minimal requirements for sshfs


r3502@localhost (orig r2439): bruno | 2009-09-29 18:46:08 +0200

  • Avoids error message if some ssh conf files do not exist


r3503@localhost (orig r2440): bruno | 2009-09-29 18:57:13 +0200

  • Avoids comment analysis in the new code handling deplist.d


r3504@localhost (orig r2441): bruno | 2009-09-29 19:34:34 +0200

  • fuse device is needed at restore time for sshfs


r3505@localhost (orig r2442): bruno | 2009-09-29 20:02:36 +0200

  • Improves udev timeout handling


r3506@localhost (orig r2443): bruno | 2009-09-29 20:43:38 +0200

  • priority given to env var for tmpdir
  • fuse FS excluded from tmpdir computation


r3518@localhost (orig r2447): bruno | 2009-10-04 01:58:08 +0200

  • Iprove USB log in case of error by adding the conf file


r3519@localhost (orig r2448): bruno | 2009-10-05 11:06:13 +0200


r3520@localhost (orig r2449): bruno | 2009-10-06 01:10:35 +0200

  • Adds support for grub2 conf file grub.cfg in addition to menu.lst


r3521@localhost (orig r2450): bruno | 2009-10-06 01:24:02 +0200

  • Fix a mr_asprintf usage without & causing a seg fault.


r3523@localhost (orig r2452): bruno | 2009-10-06 12:47:56 +0200
CIFS mounts shouldn't be part of the mountlist analysis (should help solving #288)


r3524@localhost (orig r2453): bruno | 2009-10-07 10:17:03 +0200

  • Fix a bug in handling of -E option with real devices (bad report in function mr_make_devlist_from_pathlist of the test between -E and -I)


r3525@localhost (orig r2454): bruno | 2009-10-07 10:19:02 +0200

  • Fix an error in the test for grub conf files (or used instead of and)


r3526@localhost (orig r2455): bruno | 2009-10-07 16:14:59 +0200
afio is under /bin on Debian


r3527@localhost (orig r2456): bruno | 2009-10-07 17:31:26 +0200

  • Adds support for libcrc32c (needed by bnx2x)


r3532@localhost (orig r2457): bruno | 2009-10-09 13:33:44 +0200

  • Apply path from Matthew Cline (matt_at_nightrealms.com) in order to fix #359


r3533@localhost (orig r2458): bruno | 2009-10-09 13:41:02 +0200
Adds a conf file example for mindi and fix #360


r3535@localhost (orig r2459): bruno | 2009-10-09 15:13:01 +0200
MOde of conf file


r3546@localhost (orig r2461): bruno | 2009-10-14 01:12:24 +0200

  • umount freshly created VFAT partition on USB key as Ubunu has an automounter mounting it as soon as created (Steffen Neumann sneumann_at_ipb-halle.de)


r3566@localhost (orig r2463): bruno | 2009-10-26 01:34:16 +0100

  • Reset an error counter before blanking a DVD to avoid always returning an error (Vincent Raman vincent.raman_at_macqel.eu)


r3567@localhost (orig r2464): bruno | 2009-10-26 13:57:14 +0100
bzip2 is under /bin on Debian


r3568@localhost (orig r2465): bruno | 2009-10-28 01:46:30 +0100
some distro hold lvm commands under /usr/sbin


r3595@localhost (orig r2469): bruno | 2009-11-10 12:22:10 +0100
/dev/shm is now part of the default exclude list


r3596@localhost (orig r2470): bruno | 2009-11-10 12:32:40 +0100
Remove useless pb_log and MONDO_TRACEFILE


r3597@localhost (orig r2471): bruno | 2009-11-10 12:57:58 +0100
Improve analysis of kernel modules by printing whether it's a live or extra module which has not been found (Matthew Cline) as reported in #362


r3598@localhost (orig r2472): bruno | 2009-11-10 13:21:46 +0100

  • Default to DVD size when in iso or netfs mode


r3599@localhost (orig r2473): bruno | 2009-11-10 14:13:10 +0100

  • Fix #363 where exclude_paths was extended up to memory limit dumping core


r3600@localhost (orig r2474): bruno | 2009-11-10 14:31:14 +0100

  • Update deplist for Debian support


r3602@localhost (orig r2476): bruno | 2009-11-11 02:44:42 +0100

  • small improvement for loging in USB case


r3603@localhost (orig r2477): bruno | 2009-11-11 13:29:27 +0100

  • Adds a nolvm boot option at restore time


r3604@localhost (orig r2478): bruno | 2009-11-11 19:54:51 +0100

  • Fix #367 - the for loop doesn't make any test now, as it was computed before entering the loop, leading to an error, and was also made inside the loop anyway.


r3605@localhost (orig r2479): bruno | 2009-11-12 00:32:45 +0100

  • Add support for diskdumplib driver useful for RHEL 3 and IBM xseries 336


r3606@localhost (orig r2480): bruno | 2009-11-12 01:09:40 +0100

  • If using nolvm, mondorestore should also not nalyze and handle i-want-my-lvm


r3608@localhost (orig r2482): bruno | 2009-11-14 12:54:11 +0100
Fix bunzip2 on debian as well


r3610@localhost (orig r2484): bruno | 2009-11-15 00:44:19 +0100

  • Adds support for variable serial port console, with defalut to /dev/ttyS0, and a boot param to change it with serial=/dev/ttySx


r3615@localhost (orig r2485): bruno | 2009-11-15 01:34:33 +0100

r3614@localhost: bruno | 2009-11-15 01:34:12 +0100
Adds a space in exclude paths


r3623@localhost (orig r2487): bruno | 2009-11-18 20:41:40 +0100

r3620@localhost: bruno | 2009-11-18 10:31:36 +0100

  • Only link /dev/tty to serial port when there is indeed a serial port. If not breaks mondorestore on normal console


r3631@localhost (orig r2490): bruno | 2009-11-24 01:48:29 +0100
Put news below in the main page to make it more readable


r3648@localhost (orig r2492): bruno | 2009-11-25 23:50:13 +0100

r3647@localhost: bruno | 2009-11-25 23:49:11 +0100

  • Add warning for -f and SW Raid as in 2.2.10


r3650@localhost (orig r2493): bruno | 2009-11-26 00:19:52 +0100

r3649@localhost: bruno | 2009-11-26 00:18:27 +0100

  • Addition of the german translation made by Magnus Rasche (Magnus.rasche_at_gmx.de) and Website inclusion


r3652@localhost (orig r2495): bruno | 2009-11-27 15:55:55 +0100
cosmetic display fix
r3659@localhost (orig r2498): bruno | 2009-12-05 17:53:03 +0100
nfsopt restore boot time option added to support custom mount options for network restore


r3684@localhost (orig r2501): bruno | 2009-12-17 00:35:08 +0100
Fix #375 mondo will segfault if the partition in sensibly_set_tmpdir_and_scratchdir() is read-only (cylau)


r3685@localhost (orig r2502): bruno | 2009-12-17 01:02:47 +0100

  • Fix an issue in the function listing kernel modules when not found


r3686@localhost (orig r2503): bruno | 2009-12-17 01:15:01 +0100
Adds scsi_dump_register to mindi SCSI_MODS for RHEL3 + IBM servers


r3701@localhost (orig r2504): bruno | 2009-12-23 02:24:33 +0100

  • Addition of the Lab for Mondorescue


r3702@localhost (orig r2505): bruno | 2009-12-23 02:41:17 +0100
Web site update for Lab MondoRescue? delivery


r3706@localhost (orig r2506): bruno | 2010-01-04 11:31:53 +0100

  • Fix a bug when isodir is / only when splitting it in iso_path and iso_mnt


r3707@localhost (orig r2507): bruno | 2010-01-04 13:22:49 +0100

  • Fix #377: Segfault in pause_and_ask_for_cdr() (ggeens)


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