source: MondoRescue/branches/2.2.5/mondo/src/mondorestore/mondo-rstr-tools.c @ 1547

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