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

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

Correct [ Bug #4991 ] -H option of mondoarchive is not completely automatic
https://developer.berlios.de/bugs/?func=detailbug&bug_id=4991&group_id=2524

Not tested yet.

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