source: MondoRescue/trunk/mondo/mondo/mondorestore/mondo-rstr-tools.c @ 561

Last change on this file since 561 was 561, checked in by bcornec, 14 years ago

merge -r 542:560 $SVN_M/branches/stable

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