source: branches/2.2.2/mondo/src/mondorestore/mondo-rstr-tools.c @ 1315

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

Log files are now consistent: mondoarchive.log for mondoarchive (containing also mindi.log) and mondorestore.log for mondorestore (copied from /tmp (ram) to /var/log (disk) at the end of the restore)
One include has been created for each bianry containing only that declaration ofr the moment, but which will be extended to include all local definitions (ps_* e.g.)
Doc updated accordingly
LOGFILE in restore process is now passed in the environment and not duplicated anymore
LogIt? is not redifined either
LOGFILE should be put in environment by mondoarchive for mindi's usage but that's a step left for later.

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