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

Last change on this file since 1080 was 1080, checked in by bruno, 12 years ago
  • Fix mindi install messages (reported by Andree Leidenfrost)
  • remove paranoid_free/free for mr_free
  • mr_asprintf used everywhere
  • mr_malloc used everywhere
  • Property svn:keywords set to Id
File size: 76.9 KB
Line 
1/***************************************************************************
2 * $Id: mondo-rstr-tools.c 1080 2007-01-28 18:04:41Z 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
16extern bool g_sigpipe_caught;
17extern bool g_ISO_restore_mode; /* are we in Iso Mode? */
18extern bool g_I_have_just_nuked;
19extern char *g_tmpfs_mountpt;
20extern char *g_isodir_device;
21extern char *g_isodir_format;
22extern long g_current_progress, g_maximum_progress;
23extern char *g_biggielist_txt;  // where 'biggielist.txt' is stored, on ramdisk / tempdir;
24                          // biggielist.txt is the list of big files stored on the
25                          // backup media set in question
26extern char *g_filelist_full;   // filelist.full.gz is the list of all regular files
27                          // (excluding big files) stored on the backup media set
28extern char *g_biggielist_pot;  // list of big files which _could_ be restored, if the
29                          // user chooses them
30extern char *g_filelist_imagedevs;  // list of devices (e.g. /dev/hda1, /dev/sda5) which
31                             // were archived as images, not just /dev entries
32                             // ... e.g. NTFS, BeOS partitions
33extern char *g_imagedevs_restthese; // of the imagedevs listed in FILELIST_IMAGEDEVS,
34                              // restore only these
35extern char *g_mondo_cfg_file;  // where m*ndo-restore.cfg (the config file) is stored
36extern char *g_mountlist_fname; // where mountlist.txt (the mountlist file) is stored
37extern char *g_mondo_home;      // homedir of Mondo; usually /usr/local/share/mondo
38extern struct s_bkpinfo *g_bkpinfo_DONTUSETHIS;
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()
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        log_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    log_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        log_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        log_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    log_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    log_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 = 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            log_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        log_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        log_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        log_msg(2, "Mounting for NFS thingy");
606        log_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            log_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    log_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            log_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        log_msg(2, "Failed, despite %d attempts", i);
678    } else {
679        log_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        log_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    log_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        log_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        log_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        log_msg(1, "Unable to mount device %s (type %s) at %s", device,
768                format, mountdir);
769        log_msg(1, "command was '%s'", command);
770        if (!strcmp(mountpoint, "swap")) {
771            log_to_screen(tmp);
772        } else {
773            log_msg(2, "Retrying w/o the '-t' switch");
774            sprintf(command, "mount %s %s 2>> %s", device, mountdir,
775                    MONDO_LOGFILE);
776            log_msg(2, "2nd command = '%s'", command);
777            res = run_program_and_log_output(command, TRUE);
778            if (res == 0) {
779                log_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        log_msg(2, "That's ok. It's just a swap partition.");
788        log_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                    log_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            log_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            log_msg(2, "Backup medium is CD-R[W]");
967        }
968    } else {
969        log_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        log_msg(1, "Goody! ... bkpinfo->use_star is now true.");
977    }
978
979    read_cfg_var(cfg_file, "acl", value);
980    if (strstr(value, "TRUE")) {
981        mr_asprintf(&g_getfacl,"setfacl");
982        log_msg(1, "We will restore ACLs");
983        if (! find_home_of_exe("setfacl")) {
984            log_msg(1, "Unable to restore ACLs as no setfacl found");
985        }
986    }
987    read_cfg_var(cfg_file, "xattr", value);
988    if (strstr(value, "TRUE")) {
989        mr_asprintf(&g_getfattr,"setfattr");
990        log_msg(1, "We will restore XATTRs");
991        if (! find_home_of_exe("setfattr")) {
992            log_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        log_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        log_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    log_msg(2, "differential var = '%s'", value);
1039    if (bkpinfo->differential) {
1040        log_msg(2, "THIS IS A DIFFERENTIAL BACKUP");
1041    } else {
1042        log_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        log_msg(2, "Ok, I shan't eject when restoring! Groovy.");
1052    }
1053
1054    if (bkpinfo->backup_media_type == nfs) {
1055        if (!cfgf) {
1056            log_msg(2, "nfs_mount remains %s", bkpinfo->nfs_mount);
1057            log_msg(2, "nfs_remote_dir remains %s",
1058                    bkpinfo->nfs_remote_dir);
1059            log_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            log_msg(2, "nfs_mount is %s", bkpinfo->nfs_mount);
1067            log_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        log_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                log_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                    log_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                        log_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                log_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        log_msg(1, "%s exists", g_filelist_full);
1209        log_msg(1, "%s exists", g_biggielist_txt);
1210        log_msg(2,
1211                "Filelist and biggielist already recovered from media. Yay!");
1212    } else {
1213        getcwd(tmp, MAX_STR_LEN);
1214        chdir(bkpinfo->tmpdir);
1215        log_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            log_msg(1, "tarcommand = %s", command);
1229            run_program_and_log_output(command, 1);
1230        } else {
1231            log_msg(2,
1232                    "Calling insist_on_this_cd_number; bkpinfo->isodir=%s",
1233                    bkpinfo->isodir);
1234            insist_on_this_cd_number(bkpinfo, 1);
1235            log_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            log_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        log_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        log_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        log_msg(1, "Warning - %s not found", g_biggielist_txt);
1285    }
1286    if (!does_file_exist(g_filelist_full)) {
1287        log_msg(1, "Warning - %s does not exist", g_filelist_full);
1288    }
1289//  popup_and_OK("Wonderful.");
1290
1291    log_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    log_msg(3, "loading filelist");
1320    filelist = load_filelist(g_filelist_full);
1321    log_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        log_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    log_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//    log_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            log_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        log_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        log_msg(1, "Yay! grub-MR found...");
1538        sprintf(command, "grub-MR %s /tmp/mountlist.txt", boot_device);
1539        log_msg(1, "command = %s", command);
1540    } else {
1541        sprintf(command, "chroot " MNT_RESTORING " grub-install %s",
1542                boot_device);
1543        log_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        log_msg(1, "Type:-");
1602        log_msg(1, "    mount-me");
1603        log_msg(1, "    chroot " MNT_RESTORING);
1604        log_msg(1, "    mount /boot");
1605        log_msg(1, "    grub-install '(hd0)'");
1606        log_msg(1, "    exit");
1607        log_msg(1, "    unmount-me");
1608        log_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    log_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    paranoid_MR_finish(254);
2020}
2021
2022/**************************************************************************
2023 *END_TERMINATE_DAEMON                                                    *
2024 **************************************************************************/
2025
2026
2027/**
2028 * Give the user twenty seconds to press Ctrl-Alt-Del before we nuke their drives.
2029 */
2030void twenty_seconds_til_yikes()
2031{
2032    int i;
2033    /* MALLOC * */
2034    char *tmp;
2035
2036    malloc_string(tmp);
2037    if (does_file_exist("/tmp/NOPAUSE")) {
2038        return;
2039    }
2040    open_progress_form("CAUTION",
2041                       "Be advised: I am about to ERASE your hard disk(s)!",
2042                       "You may press Ctrl+Alt+Del to abort safely.",
2043                       "", 20);
2044    for (i = 0; i < 20; i++) {
2045        g_current_progress = i;
2046        sprintf(tmp, "You have %d seconds left to abort.", 20 - i);
2047        update_progress_form(tmp);
2048        sleep(1);
2049    }
2050    close_progress_form();
2051    mr_free(tmp);
2052}
2053
2054/**************************************************************************
2055 *END_TWENTY_SECONDS_TIL_YIKES                                            *
2056 **************************************************************************/
2057
2058
2059
2060
2061
2062/**
2063 * Exit due to a signal (no cleanup).
2064 * @param sig The signal we're exiting due to.
2065 */
2066void termination_in_progress(int sig)
2067{
2068    log_msg(1, "Termination in progress");
2069    usleep(1000);
2070    pthread_exit(0);
2071}
2072
2073/**************************************************************************
2074 *END_TERMINATION_IN_PROGRESS                                             *
2075 **************************************************************************/
2076
2077
2078
2079/**
2080 * Unmount all devices in @p p_external_copy_of_mountlist.
2081 * @param p_external_copy_of_mountlist The mountlist to guide the devices to unmount.
2082 * @return 0 for success, nonzero for failure.
2083 */
2084int unmount_all_devices(struct mountlist_itself
2085                        *p_external_copy_of_mountlist)
2086{
2087    struct mountlist_itself *mountlist;
2088    int retval = 0, lino, res = 0, i;
2089    char *command;
2090    char *tmp;
2091
2092    malloc_string(command);
2093    malloc_string(tmp);
2094    assert(p_external_copy_of_mountlist != NULL);
2095
2096    mountlist = mr_malloc(sizeof(struct mountlist_itself));
2097    memcpy((void *) mountlist, (void *) p_external_copy_of_mountlist,
2098           sizeof(struct mountlist_itself));
2099    sort_mountlist_by_mountpoint(mountlist, 0);
2100
2101    run_program_and_log_output("df -m", 3);
2102    mvaddstr_and_log_it(g_currentY, 0, "Unmounting devices      ");
2103    open_progress_form("Unmounting devices",
2104                       "Unmounting all devices that were mounted,",
2105                       "in preparation for the post-restoration reboot.",
2106                       "", mountlist->entries);
2107    chdir("/");
2108    for (i = 0;
2109         i < 10
2110         &&
2111         run_program_and_log_output
2112         ("ps | grep buffer | grep -v \"grep buffer\"", TRUE) == 0;
2113         i++) {
2114        sleep(1);
2115        log_msg(2, "Waiting for buffer() to finish");
2116    }
2117
2118    paranoid_system("sync");
2119
2120    if (run_program_and_log_output
2121        ("cp -f /tmp/mondo-restore.log " MNT_RESTORING "/tmp/", FALSE)) {
2122        log_msg(1,
2123                "Error. Failed to copy log to PC's /tmp dir. (Mounted read-only?)");
2124    }
2125    if (run_program_and_log_output
2126        ("cp -f /tmp/mondo-restore.log " MNT_RESTORING "/root/", FALSE)) {
2127        log_msg(1,
2128                "Error. Failed to copy log to PC's /root dir. (Mounted read-only?)");
2129    }
2130    if (does_file_exist("/tmp/DUMBASS-GENTOO")) {
2131        run_program_and_log_output("mkdir -p " MNT_RESTORING
2132                                   "/mnt/.boot.d", 5);
2133    }
2134    for (lino = mountlist->entries - 1; lino >= 0; lino--) {
2135        if (!strcmp(mountlist->el[lino].mountpoint, "lvm")) {
2136            continue;
2137        }
2138        sprintf(tmp, "Unmounting device %s  ", mountlist->el[lino].device);
2139
2140        update_progress_form(tmp);
2141        if (is_this_device_mounted(mountlist->el[lino].device)) {
2142            if (!strcmp(mountlist->el[lino].mountpoint, "swap")) {
2143                sprintf(command, "swapoff %s", mountlist->el[lino].device);
2144            } else {
2145                if (!strcmp(mountlist->el[lino].mountpoint, "/1")) {
2146                    sprintf(command, "umount %s/", MNT_RESTORING);
2147                    log_msg(3,
2148                            "Well, I know a certain kitty-kitty who'll be sleeping with Mommy tonight...");
2149                } else {
2150                    sprintf(command, "umount " MNT_RESTORING "%s",
2151                            mountlist->el[lino].mountpoint);
2152                }
2153            }
2154            log_msg(10, "The 'umount' command is '%s'", command);
2155            res = run_program_and_log_output(command, 3);
2156        } else {
2157            strcat(tmp, "...not mounted anyway :-) OK");
2158            res = 0;
2159        }
2160        g_current_progress++;
2161        if (res) {
2162            strcat(tmp, "...Failed");
2163            retval++;
2164            log_to_screen(tmp);
2165        } else {
2166            log_msg(2, tmp);
2167        }
2168    }
2169    close_progress_form();
2170    if (retval) {
2171        mvaddstr_and_log_it(g_currentY++, 74, "Failed.");
2172    } else {
2173        mvaddstr_and_log_it(g_currentY++, 74, "Done.");
2174    }
2175    if (retval) {
2176        log_to_screen("Unable to unmount some of your partitions.");
2177    } else {
2178        log_to_screen("All partitions were unmounted OK.");
2179    }
2180    mr_free(mountlist);
2181    mr_free(command);
2182    mr_free(tmp);
2183    return (retval);
2184}
2185
2186/**************************************************************************
2187 *END_UNMOUNT_ALL_DEVICES                                                 *
2188 **************************************************************************/
2189
2190
2191
2192/**
2193 * Extract mondo-restore.cfg and the mountlist from the tape inserted
2194 * to the ./tmp/ directory.
2195 * @param dev The tape device to read from.
2196 * @return 0 for success, nonzero for failure.
2197 */
2198int extract_cfg_file_and_mountlist_from_tape_dev(char *dev)
2199{
2200    char *command;
2201    int res = 0;
2202    // BCO: below 32KB seems to block at least on RHAS 2.1 and MDK 10.0
2203    long tape_block_size = 32768;
2204
2205    malloc_string(command);
2206
2207    // tar -zxvf-
2208    sprintf(command,
2209            "dd if=%s bs=%ld count=%ld 2> /dev/null | tar -zx %s %s %s %s %s",
2210            dev,
2211            tape_block_size,
2212            1024L * 1024 * 32 / tape_block_size,
2213            MOUNTLIST_FNAME_STUB, MONDO_CFG_FILE_STUB,
2214            BIGGIELIST_TXT_STUB, FILELIST_FULL_STUB, "tmp/i-want-my-lvm");
2215    log_msg(2, "command = '%s'", command);
2216    res = run_program_and_log_output(command, -1);
2217    if (res != 0 && does_file_exist(MONDO_CFG_FILE_STUB)) {
2218        res = 0;
2219    }
2220    mr_free(command);
2221    return (res);
2222}
2223
2224
2225
2226/**
2227 * Get the configuration file from the floppy, tape, or CD.
2228 * @param bkpinfo The backup information structure. Fields used:
2229 * - @c bkpinfo->backup_media_type
2230 * - @c bkpinfo->media_device
2231 * - @c bkpinfo->tmpdir
2232 * @return 0 for success, nonzero for failure.
2233 */
2234int get_cfg_file_from_archive(struct s_bkpinfo *bkpinfo)
2235{
2236    int retval = 0;
2237
2238   /** malloc *****/
2239    char *device;
2240    char *command;
2241    char *cfg_file;
2242    char *mounted_cfgf_path;
2243    char *tmp;
2244    char *mountpt;
2245    char *ramdisk_fname;
2246    char *mountlist_file;
2247    int res;
2248
2249    bool try_plan_B;
2250
2251    assert(bkpinfo != NULL);
2252    malloc_string(cfg_file);
2253    malloc_string(mounted_cfgf_path);
2254    malloc_string(mountpt);
2255    malloc_string(ramdisk_fname);
2256    malloc_string(mountlist_file);
2257    malloc_string(device);
2258    malloc_string(command);
2259    malloc_string(tmp);
2260    log_msg(2, "gcffa --- starting");
2261    log_to_screen("I'm thinking...");
2262    sprintf(mountpt, "%s/mount.bootdisk", bkpinfo->tmpdir);
2263    device[0] = '\0';
2264    chdir(bkpinfo->tmpdir);
2265    strcpy(cfg_file, MONDO_CFG_FILE_STUB);
2266    unlink(cfg_file);           // cfg_file[] is missing the '/' at the start, FYI, by intent
2267    unlink(FILELIST_FULL_STUB);
2268    unlink(BIGGIELIST_TXT_STUB);
2269    unlink("tmp/i-want-my-lvm");
2270    sprintf(command, "mkdir -p %s", mountpt);
2271    run_program_and_log_output(command, FALSE);
2272
2273//   unlink( "tmp/mondo-restore.cfg" ); // superfluous, surely?
2274
2275    sprintf(cfg_file, "%s/%s", bkpinfo->tmpdir, MONDO_CFG_FILE_STUB);
2276    sprintf(mountlist_file, "%s/%s", bkpinfo->tmpdir,
2277            MOUNTLIST_FNAME_STUB);
2278    //   make_hole_for_file( cfg_file );
2279    //   make_hole_for_file( mountlist_file);
2280    log_msg(2, "mountpt = %s; cfg_file=%s", mountpt, cfg_file);
2281
2282    /* Floppy? */
2283    sprintf(tmp, "mkdir -p %s", mountpt);
2284    run_program_and_log_output(tmp, FALSE);
2285    sprintf(tmp, "mkdir -p %s/tmp", bkpinfo->tmpdir);
2286    run_program_and_log_output(tmp, FALSE);
2287
2288    sprintf(command, "mount /dev/fd0u1722 %s", mountpt);
2289    sprintf(tmp,
2290            "(sleep 15; kill `ps | grep \"%s\" | cut -d' ' -f1` 2> /dev/null) &",
2291            command);
2292    log_msg(1, "tmp = '%s'", tmp);
2293    system(tmp);
2294    res = run_program_and_log_output(command, FALSE);
2295    if (res) {
2296        sprintf(command, "mount /dev/fd0H1440 %s", mountpt);
2297        res = run_program_and_log_output(command, FALSE);
2298    }
2299    if (res) {
2300        try_plan_B = TRUE;
2301    } else {
2302        try_plan_B = TRUE;
2303        log_msg(2,
2304                "Mounted floppy OK but I don't trust it because the archives might contain more up-to-date config file than the floppy does.");
2305// NB: If busybox does not support 'mount -o loop' then Plan A WILL NOT WORK.
2306        log_msg(2, "Processing floppy (plan A?)");
2307        sprintf(ramdisk_fname, "%s/mindi.rdz", mountpt);
2308        if (!does_file_exist(ramdisk_fname)) {
2309            sprintf(ramdisk_fname, "%s/initrd.img", mountpt);
2310        }
2311        if (!does_file_exist(ramdisk_fname)) {
2312            log_msg(2,
2313                    "Cannot find ramdisk file on mountpoint. Are you sure that's a boot disk in the drive?");
2314        }
2315        if (extract_config_file_from_ramdisk
2316            (bkpinfo, ramdisk_fname, cfg_file, mountlist_file)) {
2317            log_msg(2,
2318                    "Warning - failed to extract config file from ramdisk. I think this boot disk is mangled.");
2319        }
2320        sprintf(command, "umount %s", mountpt);
2321        run_program_and_log_output(command, 5);
2322        unlink(ramdisk_fname);
2323    }
2324    if (!does_file_exist(cfg_file)) {
2325        log_msg(2, "gcffa --- we don't have cfg file yet.");
2326        if (IS_THIS_A_STREAMING_BACKUP(bkpinfo->backup_media_type)) {
2327            try_plan_B = TRUE;
2328        } else {
2329            log_msg(2, "gcffa --- calling mount_cdrom now :)");
2330            if (!mount_cdrom(bkpinfo)) {
2331                log_msg(2,
2332                        "gcffa --- managed to mount CD; so, no need for Plan B");
2333                try_plan_B = FALSE;
2334            } else {
2335                try_plan_B = TRUE;
2336            }
2337            if (what_number_cd_is_this(bkpinfo) > 1) {
2338                insist_on_this_cd_number(bkpinfo,
2339                                         (g_current_media_number = 1));
2340            }
2341        }
2342        if (try_plan_B) {
2343            log_msg(2, "gcffa --- OK, switching to Plan B");
2344            chdir(bkpinfo->tmpdir);
2345            run_program_and_log_output("mkdir -p tmp", FALSE);
2346
2347            if (strlen(bkpinfo->media_device) == 0) {
2348                strcpy(bkpinfo->media_device, "/dev/st0");
2349                log_msg(2, "media_device is blank; assuming %s");
2350            }
2351            strcpy(tmp, bkpinfo->media_device);
2352            if (extract_cfg_file_and_mountlist_from_tape_dev
2353                (bkpinfo->media_device)) {
2354                strcpy(bkpinfo->media_device, "/dev/st0");
2355                if (extract_cfg_file_and_mountlist_from_tape_dev
2356                    (bkpinfo->media_device)) {
2357                    strcpy(bkpinfo->media_device, "/dev/osst0");
2358                    if (extract_cfg_file_and_mountlist_from_tape_dev
2359                        (bkpinfo->media_device)) {
2360                        strcpy(bkpinfo->media_device, "/dev/ht0");
2361                        if (extract_cfg_file_and_mountlist_from_tape_dev
2362                            (bkpinfo->media_device)) {
2363                            log_msg(3,
2364                                    "I tried lots of devices but none worked.");
2365                            strcpy(bkpinfo->media_device, tmp);
2366                        }
2367                    }
2368                }
2369            }
2370
2371            if (!does_file_exist("tmp/mondo-restore.cfg")) {
2372                log_to_screen("Cannot find config info on tape/CD/floppy");
2373                return (1);
2374            }
2375        } else {
2376            log_msg(2,
2377                    "gcffa --- looking at mounted CD for mindi-boot.2880.img");
2378            sprintf(command,
2379                    "mount " MNT_CDROM
2380                    "/images/mindi-boot.2880.img -o loop %s", mountpt);
2381            sprintf(mounted_cfgf_path, "%s/%s", mountpt, cfg_file);
2382            if (!does_file_exist(mounted_cfgf_path)) {
2383                log_msg(2,
2384                        "gcffa --- Plan C, a.k.a. untarring some file from all.tar.gz");
2385                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
2386                run_program_and_log_output(command, TRUE);
2387                if (!does_file_exist(MONDO_CFG_FILE_STUB)) {
2388                    fatal_error
2389                        ("Please reinsert the disk/CD and try again.");
2390                }
2391            }
2392        }
2393    }
2394    if (does_file_exist(MONDO_CFG_FILE_STUB)) {
2395        log_msg(1, "gcffa --- great! We've got the config file");
2396        sprintf(tmp, "%s/%s",
2397                call_program_and_get_last_line_of_output("pwd"),
2398                MONDO_CFG_FILE_STUB);
2399        sprintf(command, "cp -f %s %s", tmp, cfg_file);
2400        iamhere(command);
2401        if (strcmp(tmp, cfg_file)
2402            && run_program_and_log_output(command, 1)) {
2403            log_msg(1,
2404                    "... but an error occurred when I tried to move it to %s",
2405                    cfg_file);
2406        } else {
2407            log_msg(1, "... and I moved it successfully to %s", cfg_file);
2408        }
2409        sprintf(command, "cp -f %s/%s %s",
2410                call_program_and_get_last_line_of_output("pwd"),
2411                MOUNTLIST_FNAME_STUB, mountlist_file);
2412        iamhere(command);
2413        if (strcmp(tmp, cfg_file)
2414            && run_program_and_log_output(command, 1)) {
2415            log_msg(1, "Failed to get mountlist");
2416        } else {
2417            log_msg(1, "Got mountlist too");
2418            sprintf(command, "cp -f %s %s", mountlist_file,
2419                    g_mountlist_fname);
2420            if (run_program_and_log_output(command, 1)) {
2421                log_msg(1, "Failed to copy mountlist to /tmp");
2422            } else {
2423                log_msg(1, "Copied mountlist to /tmp as well OK");
2424                sprintf(command, "cp -f tmp/i-want-my-lvm /tmp/");
2425                run_program_and_log_output(command, 1);
2426/*        sprintf(command, "grep \" lvm \" %s", g_mountlist_fname);
2427          if (!run_program_and_log_output(command, 5) && !does_file_exist("/tmp/i-want-my-lvm"))
2428            {
2429          log_msg(1, "Warning. You want LVM but I don't have i-want-my-lvm. FIXME.");
2430        }
2431              else if (run_program_and_log_output(command,5) && does_file_exist("/tmp/i-want-my-lvm"))
2432                {
2433          log_msg(1, "Warning. You don't want LVM but i-want-my-lvm exists. I'll delete it. Cool.");
2434              do_my_funky_lvm_stuff(TRUE, FALSE); // ...after I stop any LVMs :)
2435          stop_raid_device("/dev/md0");
2436          stop_raid_device("/dev/md1");
2437          stop_raid_device("/dev/md2");
2438          unlink("/tmp/i-want-my-lvm");
2439        }
2440          else if (!run_program_and_log_output(command,5) && does_file_exist("/tmp/i-want-my-lvm"))
2441            {
2442          log_msg(1, "You had better pray that i-want-my-lvm patches your mountlist. FIXME.");
2443        }
2444*/
2445            }
2446        }
2447    }
2448    run_program_and_log_output("umount " MNT_CDROM, FALSE);
2449    if (!does_file_exist(cfg_file)) {
2450        iamhere(cfg_file);
2451        log_msg(1, "%s not found", cfg_file);
2452        log_to_screen
2453            ("Oh dear. Unable to recover configuration file from boot disk");
2454        return (1);
2455    }
2456
2457    log_to_screen("Recovered mondo-restore.cfg");
2458    if (!does_file_exist(MOUNTLIST_FNAME_STUB)) {
2459        log_to_screen("...but not mountlist.txt - a pity, really...");
2460    }
2461/* start SAH */
2462    else {
2463        sprintf(command, "cp -f %s %s/%s", MOUNTLIST_FNAME_STUB,
2464                bkpinfo->tmpdir, MOUNTLIST_FNAME_STUB);
2465        run_program_and_log_output(command, FALSE);
2466    }
2467/*--commented out by SAH
2468  sprintf( command, "cp -f %s %s/%s", cfg_file, bkpinfo->tmpdir, MONDO_CFG_FILE_STUB );
2469  run_program_and_log_output( command, FALSE );
2470  sprintf( command, "cp -f %s %s/%s", mountlist_file, bkpinfo->tmpdir, MOUNTLIST_FNAME_STUB );
2471  run_program_and_log_output( command, FALSE );
2472*/
2473/* end SAH */
2474
2475    sprintf(command, "cp -f %s /%s", cfg_file, MONDO_CFG_FILE_STUB);
2476    run_program_and_log_output(command, FALSE);
2477    sprintf(command, "cp -f %s /%s", mountlist_file, MOUNTLIST_FNAME_STUB);
2478    run_program_and_log_output(command, FALSE);
2479    sprintf(command, "cp -f etc/raidtab /etc/");
2480    run_program_and_log_output(command, FALSE);
2481    sprintf(command, "cp -f tmp/i-want-my-lvm /tmp/");
2482    run_program_and_log_output(command, FALSE);
2483    g_backup_media_type = bkpinfo->backup_media_type;
2484    mr_free(device);
2485    mr_free(command);
2486    mr_free(tmp);
2487    mr_free(cfg_file);
2488    mr_free(mounted_cfgf_path);
2489    mr_free(mountpt);
2490    mr_free(ramdisk_fname);
2491    mr_free(mountlist_file);
2492    return (retval);
2493}
2494
2495/**************************************************************************
2496 *END_GET_CFG_FILE_FROM_ARCHIVE                                           *
2497 **************************************************************************/
2498
2499/* @} - end restoreUtilityGroup */
2500
2501
2502/***************************************************************************
2503 * F@                                                                      *
2504 * () -- Hugo Rabson                                  *
2505 *                                                                         *
2506 * Purpose:                                                                *
2507 *                                                                         *
2508 * Called by:                                                              *
2509 * Params:    -                      -                                     *
2510 * Returns:   0=success; nonzero=failure                                   *
2511 ***************************************************************************/
2512
2513
2514
2515void wait_until_software_raids_are_prepped(char *mdstat_file,
2516                                           int wait_for_percentage)
2517{
2518    struct raidlist_itself *raidlist;
2519    int unfinished_mdstat_devices = 9999, i;
2520    char *screen_message;
2521
2522    malloc_string(screen_message);
2523    raidlist = mr_malloc(sizeof(struct raidlist_itself));
2524
2525    assert(wait_for_percentage <= 100);
2526    iamhere("wait_until_software_raids_are_prepped");
2527    while (unfinished_mdstat_devices > 0) {
2528            // FIXME: Prefix '/dev/' should really be dynamic!
2529        if (parse_mdstat(raidlist, "/dev/")) {
2530            log_to_screen("Sorry, cannot read %s", MDSTAT_FILE);
2531            log_msg(1,"Sorry, cannot read %s", MDSTAT_FILE);
2532            return;
2533        }
2534        for (unfinished_mdstat_devices = i = 0; i <= raidlist->entries; i++) {
2535            if (raidlist->el[i].progress < wait_for_percentage) {
2536                unfinished_mdstat_devices++;
2537                if (raidlist->el[i].progress == -1) // delayed while another partition inits
2538                {
2539                    continue;
2540                }
2541                log_msg(1,"Sync'ing %s (i=%d)", raidlist->el[i].raid_device, i);
2542                sprintf(screen_message, "Sync'ing %s",
2543                        raidlist->el[i].raid_device);
2544                open_evalcall_form(screen_message);
2545                while (raidlist->el[i].progress < wait_for_percentage) {
2546                    log_msg(1,"Percentage sync'ed: %d", raidlist->el[i].progress);
2547                    update_evalcall_form(raidlist->el[i].progress);
2548                    sleep(2);
2549                    // FIXME: Prefix '/dev/' should really be dynamic!
2550                    if (parse_mdstat(raidlist, "/dev/")) {
2551                        break;
2552                    }
2553                }
2554                close_evalcall_form();
2555            }
2556        }
2557    }
2558    mr_free(screen_message);
2559    mr_free(raidlist);
2560}
Note: See TracBrowser for help on using the repository browser.