source: trunk/mondo/src/mondorestore/mondo-rstr-tools.c @ 1081

Last change on this file since 1081 was 1081, checked in by bruno, 12 years ago

merge -r1078:1080 $SVN_M/branches/stable

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