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

Last change on this file since 1156 was 1125, checked in by Bruno Cornec, 14 years ago

Still linker fixes (grrr)

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