source: MondoRescue/branches/stable/mondo/src/mondorestore/mondo-rstr-tools.c @ 1166

Last change on this file since 1166 was 1166, checked in by Bruno Cornec, 13 years ago

Suppress g_bkpinfo_DONTUSETHIS (Idea from M. Loiseleur)

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