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

Last change on this file since 2850 was 2850, checked in by Bruno Cornec, 9 years ago

svn merge -r 2773:2849 2.2.9 in 2.2.10

  • Adds 3 binaries called potentially by udev o support USB key mount at restore time (Victor Gattegno)
  • Really support both mkisofs and genisoimage everywhere
  • Try to handle netfs_user better in all cases (NFS and SSHFS)
    • Improve logging in init script
    • Format improvement
    • Removes a warning when trying to launch udevadm and it doesn't exist (RHEL 5 e.g.)
    • Fix syntax description in mondoarchive man page for -E & -I with |
  • Adds download entries for new distro supported (Mageia, Fedora 15, Ubuntu 11.04)

-Fix mindi-get-perl-modules when perl dirs in @INC are symlinks (case on Ubuntu 11.04)

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