Changeset 1939 in MondoRescue for branches/stable/mondo


Ignore:
Timestamp:
May 17, 2008, 1:29:54 AM (16 years ago)
Author:
Bruno Cornec
Message:

svn merge -r 1923:1938 $SVN_M/branches/2.2.6

Location:
branches/stable/mondo/src
Files:
12 edited

Legend:

Unmodified
Added
Removed
  • branches/stable/mondo/src/common/Makefile.am

    r1924 r1939  
    44## Process this file with Automake to generate `Makefile.in'
    55##
    6 AM_CPPFLAGS = -DMONDO_SHARE=\"$(pkgdatadir)\" -DMONDO_CONF_DIR=\"$(sysconfdir)\" -I${top_builddir}/src/include
     6AM_CPPFLAGS = -DMONDO_SHARE=\"$(pkgdatadir)\" -DMONDO_CONF_DIR=\"$(sysconfdir)/mondo\" -I${top_builddir}/src/include -I${top_builddir}/src/common
    77
    88## libmondo
  • branches/stable/mondo/src/common/libmondo-archive.c

    r1904 r1939  
    951951            mr_free(command);
    952952        } else {
    953             mr_asprintf(&command, "cp -f %s/mindi-*oot*.img %s/images",
    954                 bkpinfo->tmpdir, bkpinfo->scratchdir);
    955             if (system(command)) {
    956                 mr_msg(2, "Unable to copy mindi images");
    957             }
    958             mr_free(command);
    959 
    960953            mr_asprintf(&tmp, "cp -f %s/images/all.tar.gz %s",
    961954                 bkpinfo->scratchdir, bkpinfo->tmpdir);
     
    13681361    int i;
    13691362    char *curr_xattr_list_fname = NULL;
    1370     char *curr_acl_list_fname;
     1363    char *curr_acl_list_fname = NULL;
    13711364    int misc_counter_that_is_not_important = 0;
    13721365
     
    14761469                res += write_EXAT_files_to_tape(curr_xattr_list_fname,
    14771470                                                curr_acl_list_fname);
     1471                // archives themselves
     1472                res +=
     1473                    write_EXAT_files_to_tape(curr_xattr_list_fname,
     1474                                             curr_acl_list_fname);
    14781475                // archives themselves
    14791476                res +=
     
    21522149                                                   curr_afioball_fname);
    21532150            iamhere("Writing EXAT files");
    2154             res += write_EXAT_files_to_tape(curr_xattr_list_fname,
    2155                                             curr_acl_list_fname);
     2151            res +=
     2152                write_EXAT_files_to_tape(curr_xattr_list_fname,
     2153                                         curr_acl_list_fname);
    21562154            // archives themselves
    21572155            res = move_files_to_stream(curr_afioball_fname, NULL);
  • branches/stable/mondo/src/common/libmondo-cli.c

    r1924 r1939  
    170170extern bool g_text_mode;
    171171extern char g_startdir[MAX_STR_LEN];    ///< ????? @bug ?????
    172 extern bool g_sigpipe;
    173172extern char *MONDO_OPTIONS;
    174173
  • branches/stable/mondo/src/common/libmondo-devices.c

    r1924 r1939  
    15671567    bkpinfo->nonbootable_backup = FALSE;
    15681568
    1569 // Tape, CD, NFS, ...?
     1569    // Tape, CD, NFS, ...?
    15701570    srandom(getpid());
    15711571    bkpinfo->backup_media_type =
     
    15761576        finish(1);
    15771577    }
     1578    /* Why asking to remove the media with tape ?
    15781579    if (bkpinfo->backup_media_type == tape && bkpinfo->restore_data) {
    15791580        popup_and_OK(_("Please remove media from drive"));
    15801581    }
     1582    */
    15811583    mr_msg(3, "media type = %s",
    15821584            bkptype_to_string(bkpinfo->backup_media_type));
     
    15881590    mvaddstr_and_log_it(2, 0, " ");
    15891591
    1590 // Find device's /dev (or SCSI) entry
     1592    // Find device's /dev (or SCSI) entry
    15911593    switch (bkpinfo->backup_media_type) {
    15921594    case cdr:
  • branches/stable/mondo/src/common/libmondo-stream.c

    r1924 r1939  
    3030
    3131#define EXTRA_TAPE_CHECKSUMS
     32#define STR_HEADER  "Mondolicious, baby"
    3233
    3334/*@unused@*/
     
    362363{
    363364    int res = 0;
    364     int retval = 0;
    365365    char *fname = (char *)&res;                 /* Should NOT be NULL */
    366366
    367 // xattr
     367    // xattr
    368368    if (g_getfattr) {
    369369        res = read_header_block_from_stream(ptmp_size, fname, pctrl_chr);
     
    372372        }
    373373        if (!strstr(fname, "xattr")) {
    374             fatal_error("Wrong order, sunshine.");
     374            fatal_error("Wrong order for xattr, sunshine.");
    375375        }
    376376        read_file_from_stream_to_file(xattr_fname, *ptmp_size);
     
    380380        }
    381381        mr_msg(1, "Got xattr");
     382        res = read_header_block_from_stream(ptmp_size, tmp_fname, pctrl_chr);
     383        if (*pctrl_chr != BLK_STOP_EXTENDED_ATTRIBUTES) {
     384            wrong_marker(BLK_STOP_EXTENDED_ATTRIBUTES, *pctrl_chr);
     385        }
     386        res = read_header_block_from_stream(ptmp_size, tmp_fname, pctrl_chr);
     387        if (pctrl_chr == BLK_START_AN_AFIO_OR_SLICE) {
     388            log_msg(1, "No acl attributes found, skipping to afio files");
     389            return(0);
     390        } else {
     391            if (pctrl_chr != BLK_START_EXTENDED_ATTRIBUTES) {
     392                wrong_marker(BLK_START_EXTENDED_ATTRIBUTES, *pctrl_chr);
     393            }
     394        }
    382395    }
    383396    // acl
     
    385398        res = read_header_block_from_stream(ptmp_size, fname, pctrl_chr);
    386399        if (!strstr(fname, "acl")) {
    387             fatal_error("Wrong order, sunshine.");
     400            fatal_error("Wrong order for acl, sunshine.");
    388401        }
    389402        if (*pctrl_chr != BLK_START_EXAT_FILE) {
     
    403416    // tarball itself
    404417    res = read_header_block_from_stream(ptmp_size, tmp_fname, pctrl_chr);
    405     mr_msg(1, "now looking for afioball");
    406     return (retval);
     418    mr_msg(1, "End of extended attributes, now looking for afioball");
     419    return (0);
    407420}
    408421
     
    420433        write_file_to_stream_from_file(xattr_fname);
    421434        write_header_block_to_stream((off_t)-1, xattr_fname, BLK_STOP_EXAT_FILE);
     435        write_header_block_to_stream(length_of_file(xattr_fname), xattr_fname,
     436                             BLK_STOP_EXTENDED_ATTRIBUTES);
    422437    }
    423438    if (g_getfacl) {
    424439    // acl
     440        write_header_block_to_stream(length_of_file(acl_fname), acl_fname,
     441                             BLK_START_EXTENDED_ATTRIBUTES);
    425442        write_header_block_to_stream(length_of_file(acl_fname), acl_fname,
    426443                             BLK_START_EXAT_FILE);
    427444        write_file_to_stream_from_file(acl_fname);
    428445        write_header_block_to_stream((off_t)-1, acl_fname, BLK_STOP_EXAT_FILE);
    429         write_header_block_to_stream(length_of_file(xattr_fname), xattr_fname,
     446        write_header_block_to_stream(length_of_file(acl_fname), acl_fname,
    430447                             BLK_STOP_EXTENDED_ATTRIBUTES);
    431448    }
     
    10081025    }
    10091026    memcpy((char *) plen, tempblock + 7001, sizeof(long long));
    1010     if (strcmp(tempblock + 6000 + *pcontrol_char, "Mondolicious, baby")) {
     1027    if (strcmp(tempblock + 6000 + *pcontrol_char, STR_HEADER)) {
    10111028        log_it("Bad header block at %ld K", (long) g_tape_posK);
    10121029    }
     
    15941611        tempblock[i] = 0;
    15951612    }
    1596     sprintf(tempblock + 6000 + control_char, "Mondolicious, baby");
     1613    sprintf(tempblock + 6000 + control_char, STR_HEADER);
    15971614    tempblock[7000] = control_char;
    15981615    memcpy(tempblock + 7001, (char *) &olen, sizeof(off_t));
  • branches/stable/mondo/src/include/my-stuff.h

    • Property svn:keywords set to Id
    r1924 r1939  
    22 * Common defines across the project
    33 *
    4  *  $Id: my-stuff.h 973 2006-11-23 18:05:21Z bruno $
     4 *  $Id$
    55 */
    66
     
    286286
    287287#endif                          /* _MY_STUFF_H_ */
     288=======
     289/* my-stuff.h
     290   $Id$
     291*/
     292
     293#define HAVE_MALLOC 1
     294
     295
     296// Extra info for ACLs and SELINUX users
     297#define STAR_ACL_SZ "-xfflags -acl"
     298//#define STAR_ACL_SZ "-xfflags"
     299//#define STAR_ACL_SZ ""
     300// Enable the first line and disable the second if you are a Fedora Core 2 user
     301
     302/**
     303 * @file
     304 * The main header file for Mondo.
     305 */
     306
     307#if !defined(bool) && !defined(__cplusplus)
     308/**
     309 * Create the illusion of a Boolean type.
     310 */
     311#define bool int
     312#define TRUE 1
     313#define FALSE 0
     314#endif
     315
     316#ifndef _MY_STUFF_H_
     317#define _MY_STUFF_H_
     318
     319#ifdef HAVE_CONFIG_H
     320#include <config.h>
     321#endif
     322
     323#ifndef __FreeBSD__
     324#include <getopt.h>
     325#endif
     326#include <sys/types.h>
     327#include <sys/shm.h>
     328#include <sys/ipc.h>
     329#include <sys/ioctl.h>
     330#include <sys/sem.h>
     331#include <sys/param.h>
     332#include <stdio.h>
     333#include <stdlib.h>
     334#ifndef  __USE_FILE_OFFSET64
     335#define  __USE_FILE_OFFSET64
     336#endif
     337#ifndef  __USE_LARGEFILE64
     338#define  __USE_LARGEFILE64
     339#endif
     340#include <sys/stat.h>
     341#include <fcntl.h>
     342#include <errno.h>
     343#include <stddef.h>
     344#include <sys/stat.h>
     345#include <sys/wait.h>
     346#include <time.h>
     347#include <unistd.h>
     348#include <signal.h>
     349//#include <curses.h>
     350#include <newt.h>
     351#include <ctype.h>
     352#include <string.h>
     353#include <pthread.h>
     354#include <assert.h>
     355
     356#if defined(DEBUG) && !__cplusplus
     357int count;
     358char trace_log[255];            /*buffer for logging */
     359char *trace_log_ptr;
     360#endif                          /* DEBUG */
     361
     362#define IA64_BOOT_SIZE "16384"  /* Should be coherent with mindi */
     363#define STD_PREFIX "mondorescue"    /* Should be coherent with mindi */
     364
     365/**
     366 * The biggielist stub (appended to the directory where all.tar.gz was unpacked).
     367 */
     368#define BIGGIELIST_TXT_STUB "./tmp/biggielist.txt"
     369
     370/**
     371 * The filelist stub (appended to the directory where all.tar.gz was unpacked).
     372 */
     373#define FILELIST_FULL_STUB "./tmp/filelist.full.gz"
     374
     375/**
     376 * The mountlist stub (appended to the directory where all.tar.gz was unpacked).
     377 */
     378#define MOUNTLIST_FNAME_STUB "./tmp/mountlist.txt"
     379
     380/**
     381 * The mondo-restore.cfg stub (appended to the directory where all.tar.gz was unpacked).
     382 */
     383#define MONDO_CFG_FILE_STUB "./tmp/mondo-restore.cfg"
     384/**
     385 * The location where mindi media images are stored.
     386 */
     387#define MINDI_CACHE "/var/cache/mindi"
     388
     389/**
     390 * The location where mondo changed info are stored.
     391 */
     392#define MONDO_CACHE "/var/cache/mondo"
     393
     394/**
     395 * The RAID kernel proc file
     396 */
     397#define MDSTAT_FILE "/proc/mdstat"
     398
     399/**
     400 * @bug Apparently unused.
     401 */
     402#define MONDO_TRACEFILE "/var/log/mondo-tracefile.log"
     403
     404#undef assert
     405
     406extern void _mondo_assert_fail(const char *file, const char *function,
     407                               int line, const char *exp);
     408
     409/**
     410 * An assert macro that calls _mondo_assert_fail() when it fails.
     411 */
     412#ifdef NDEBUG
     413#define assert(exp) ((void)0)
     414#else
     415#define assert(exp) ((exp)?((void)0):_mondo_assert_fail(__FILE__, __FUNCTION__, __LINE__, #exp))
     416#endif
     417
     418#define CRC_M16 0xA001          ///< Mask for crc16.
     419#define CRC_MTT 0x1021          ///< Mask for crc-ccitt.
     420
     421#define FALSE 0                 ///< The ubiquitous FALSE macro.
     422#define TRUE 1                  ///< The even more ubiquitous TRUE macro.
     423
     424#define SCREEN_LENGTH 25        ///< The default size of the screen.
     425#define NOOF_ERR_LINES 6        ///< The number of lines of log output to keep at the bottom of the screen.
     426#define ARBITRARY_MAXIMUM 2000  ///< The maximum number of items showing at once in the mountlist or filelist editor.
     427#define MAX_TAPECATALOG_ENTRIES 8192    ///< The maximum number of entries in the tape catalog.
     428#define MAX_STR_LEN 384         ///< The maximum length of almost all @p char buffers in Mondo.
     429                                        ///  Note: Make this divisible by eight to avoid aligment issues
     430                                        ///        on 64bit platforms like ia64.
     431#define MAXIMUM_RAID_DEVS 32    ///< The maximum number of RAID devices in the raidlist.
     432#define MAXIMUM_ADDITIONAL_RAID_VARS 32 ///< The maximum number of additional RAID variables per RAID device in the raidlist.
     433#define MAXIMUM_DISKS_PER_RAID_DEV 32   ///< The maximum number of disks per RAID device in the raidtab.
     434
     435#define RAIDTAB_FNAME "/etc/raidtab"    ///< The filename of the raidtab file, at least on Linux.
     436
     437#define BLK_START_OF_BACKUP     1   ///< Marker block: start a backup.
     438#define BLK_START_OF_TAPE       2   ///< Marker block: start a tape.
     439#define BLK_START_AFIOBALLS 10  ///< Marker block: start the afioball section.
     440#define BLK_STOP_AFIOBALLS  19  ///< Marker block: stop the afioball section.
     441#define BLK_START_AN_AFIO_OR_SLICE      20  ///< Marker block: start an afioball or a slice.
     442#define BLK_STOP_AN_AFIO_OR_SLICE   29  ///< Marker block: stop an afioball or a slice.
     443#define BLK_START_BIGGIEFILES   30  ///< Marker block: start the biggiefile section.
     444#define BLK_STOP_BIGGIEFILES    39  ///< Marker block: stop the biggiefile section.
     445#define BLK_START_A_NORMBIGGIE  40  ///< Marker block: start a normal biggiefile.
     446#define BLK_START_A_PIHBIGGIE   41  ///< Marker block: start a ntfsprog'd biggiefile
     447#define BLK_START_EXTENDED_ATTRIBUTES 45    ///< Marker block: start xattr/acl info
     448#define BLK_STOP_EXTENDED_ATTRIBUTES 46 ///< Marker block: stop xattr/acl info
     449#define BLK_START_EXAT_FILE     47
     450#define BLK_STOP_EXAT_FILE      48
     451#define BLK_STOP_A_BIGGIE   59  ///< Marker block: stop a biggiefile.
     452#define BLK_START_FILE          80  ///< Marker block: start a file (non-afio or slice).
     453#define BLK_STOP_FILE           89  ///< Marker block: stop a file (non-afio or slice).
     454#define BLK_END_OF_TAPE         100 ///< Marker block: end of tape.
     455#define BLK_END_OF_BACKUP       101 ///< Marker block: end of backup.
     456#define BLK_ABORTED_BACKUP      102 ///< Marker block: backup was aborted.
     457
     458/// The external tape blocksize.
     459#ifdef EXTTAPE
     460#define TAPE_BLOCK_SIZE (long)EXTTAPE
     461#else
     462#define TAPE_BLOCK_SIZE 131072L /* was 8192; 06/2002-->65536; 11/2002-->131072 */
     463#endif
     464
     465#define DEFAULT_INTERNAL_TAPE_BLOCK_SIZE 32768  // Nov 2003?
     466
     467
     468
     469
     470#define SLICE_SIZE 4096         ///< The size of a slice of a biggiefile.
     471
     472
     473
     474
     475
     476
     477/**
     478 * Determine whether @p x (t_bkptype) is a streaming backup.
     479 */
     480#define IS_THIS_A_STREAMING_BACKUP(x) (x == tape || x == udev || x == cdstream)
     481
     482
     483/**
     484 * @c mkisofs command to generate a nonbootable CD, except for -o option and the directory to image.
     485 */
     486#define MONDO_MKISOFS_NONBOOT   "mkisofs -r -p MondoRescue -publisher www.mondorescue.org -A Mondo_Rescue_GPL_Version -V _CD#_"
     487
     488/**
     489 * @c mkisofs command to generate a bootable CD using isolinux, except for -o option and the directory to image.
     490 */
     491#define MONDO_MKISOFS_REGULAR_SYSLINUX  "mkisofs -J -boot-info-table -no-emul-boot -b isolinux.bin -c boot.cat -boot-load-size 4 -r -p MondoRescue -publisher www.mondorescue.org -A Mondo_Rescue_GPL_Version -V _CD#_"
     492
     493/**
     494 * @c mkisofs command to generate a bootable CD using LILO, except for -o option and the directory to image.
     495 */
     496#define MONDO_MKISOFS_REGULAR_LILO      "mkisofs -boot-info-table -no-emul-boot -b isolinux.bin -c boot.cat -boot-load-size 4 -J -r -p MondoRescue -publisher www.mondorescue.org -A Mondo_Rescue_GPL -V _CD#_"
     497
     498/**
     499 * @c mkisofs command to generate a bootable CD using ELILO, except for -o option and the directory to image.
     500 */
     501// Should replace 8192 by IA64_BOOT_SIZE
     502#define MONDO_MKISOFS_REGULAR_ELILO      "mkisofs -no-emul-boot -b images/mindi-bootroot.8192.img -c boot.cat -J -r -p MondoRescue -publisher www.mondorescue.org -A Mondo_Rescue_GPL -V _CD#_"
     503
     504/**
     505 * The stub name of the temporary ISO image to create, burn, and remove.
     506 */
     507#define MONDO_TMPISOS "temporary.iso"
     508
     509/**
     510 * @c growisofs command to generate a bootable DVD using isolinux, except for the directory to image.
     511 */
     512#define MONDO_GROWISOFS_REGULAR_SYSLINUX "growisofs -use-the-force-luke -J -no-emul-boot -boot-load-size 4 -b isolinux.bin --boot-info-table -c boot.cat -boot-load-size 4 -r -p MondoRescue -publisher www.mondorescue.org -A Mondo_Rescue_GPL_Version -V _CD#_ -v"
     513
     514/**
     515 * @c growisofs command to generate a bootable DVD using LILO, except for the directory to image.
     516     */
     517#define MONDO_GROWISOFS_REGULAR_ELILO     "growisofs -use-the-force-luke -no-emul-boot -b images/mindi-boot.2880.img -c boot.cat -J -r -p MondoRescue -publisher www.mondorescue.org -A Mondo_Rescue_GPL -V _CD#_ -v"
     518
     519/**
     520 * @c growisofs command to generate a bootable DVD using LILO, except for the directory to image.
     521     */
     522#define MONDO_GROWISOFS_REGULAR_LILO     "growisofs -no-emul-boot -b isolinux.bin -c boot.cat -J -r -p MondoRescue -publisher www.mondorescue.org -A Mondo_Rescue_GPL -V _CD#_ -v"
     523
     524/**
     525 * @c growisofs command to generate a nonbootable DVD, except for the directory to image.
     526 */
     527#define MONDO_GROWISOFS_NONBOOT          "growisofs -use-the-force-luke -J -r -p MondoRescue -publisher www.mondorescue.org -A Mondo_Rescue_GPL -V _CD#_ -v"
     528
     529/**
     530 * Welcome string displayed at the top of the newt interface.
     531 */
     532#define WELCOME_STRING "W E L C O M E   T O   M O N D O   R E S C U E"
     533
     534/**
     535 * The maximum length of a filename in the tape catalog.
     536 */
     537#define MAX_TAPECAT_FNAME_LEN 32
     538
     539//#define strcpy(y,x) strncpy(y, x, sizeof(y)-1)
     540
     541
     542/**
     543 * Assert that (@p x != NULL) and (@p x[0] != '\\0').
     544 */
     545#define assert_string_is_neither_NULL_nor_zerolength(x) {assert(x!=NULL);assert(x[0]!='\0');}
     546
     547/**
     548 * Log the file, line, Mondo error message, and OS error message (errno).
     549 */
     550#define log_OS_error(x) {log_msg(0, "%s (%s)", x, strerror(errno));}
     551
     552/**
     553 * Assert that (@p x != NULL).
     554 */
     555#define assert_pointer_is_not_NULL(x) {assert(x!=NULL);}
     556
     557/**
     558 * close() @p x and log a message if it fails.
     559 */
     560#define paranoid_close(x) {if(close(x)) {log_msg(5, "close err");} x=-999; }
     561
     562/**
     563 * fclose() @p x and log a message if it fails.
     564 */
     565#define paranoid_fclose(x) {if(fclose(x)) {log_msg(5, "fclose err");} x=NULL; }
     566
     567/**
     568 * pclose() @p x and log a message if it fails.
     569 */
     570#define paranoid_pclose(x) {if(pclose(x)) {log_msg(5, "pclose err");} x=NULL; }
     571
     572/**
     573 * Run the command @p x and log it if it fails.
     574 */
     575#define paranoid_system(x) {if(system(x)) log_msg(4, x); }
     576
     577/**
     578 * Free @p x and set it to NULL.
     579 */
     580#define paranoid_free(x) {if (x != NULL) free(x); x=NULL;}
     581
     582/**
     583 * Free variables and call finish(@p x).
     584 */
     585#define paranoid_MR_finish(x) {free_MR_global_filenames (); finish(x); }
     586
     587/**
     588 * Log file, function, line, and @p x.
     589 */
     590#define iamhere(x) {log_it("%s, %s, %ld: %s", __FILE__, __FUNCTION__, __LINE__, x);}
     591
     592/**
     593 * Yes, we want malloc() to help us fix bugs.
     594 */
     595#define MALLOC_CHECK_ 1
     596
     597/**
     598 * Malloc @p x to be MAX_STR_LEN bytes and call fatal_error() if we're out of memory.
     599 */
     600#define malloc_string(x) { x = (char *)malloc(MAX_STR_LEN); if (!x) { fatal_error("Unable to malloc"); } x[0] = x[1] = '\0'; }
     601
     602/**
     603 * Path to the location the hard drive is mounted on during a restore.
     604 */
     605#define MNT_RESTORING "/mnt/RESTORING"
     606
     607/** @def VANILLA_SCSI_CDROM The first SCSI CD-ROM in the system (most likely to be the one to write to). */
     608/** @def VANILLA_SCSI_TAPE  The first SCSI tape in the system (most likely to be the one towrite to. */
     609/** @def DONT_KNOW_HOW_TO_EVALUATE_THIS_DEVICE_TYPE A string whose presence in a device name indicates the
     610 * inability to check this device for errors in the mountlist. */
     611/** @def RAID_DEVICE_STUB The stub of a RAID device (set up RAID if we find it). */
     612/** @def SANE_FORMATS Sane formats for this OS, separated by spaces. */
     613/** @def ALT_TAPE The first IDE tape in the system. */
     614/** @def MKE2FS_OR_NEWFS @c mke2fs or @c newfs, depending on the OS. */
     615/** @def CP_BIN The GNU @c cp binary to use. */
     616#ifdef __FreeBSD__
     617#define VANILLA_SCSI_CDROM  "/dev/cd0"
     618#define VANILLA_SCSI_TAPE   "/dev/sa0"
     619#define VANILLA_USB_DEVICE  "tobegivenbybsdguru"
     620#define DONT_KNOW_HOW_TO_EVALUATE_THIS_DEVICE_TYPE  "/dev/vinum/"
     621#define RAID_DEVICE_STUB    DONT_KNOW_HOW_TO_EVALUATE_THIS_DEVICE_TYPE
     622#define SANE_FORMATS        "swap image msdosfs nfs ntfs raid lvm ffs ufs ext2fs"
     623#define ALT_TAPE        "/dev/ast0"
     624#define MKE2FS_OR_NEWFS "newfs"
     625#define CP_BIN      "gcp"
     626#else
     627#define VANILLA_SCSI_CDROM  "/dev/scd0"
     628#define VANILLA_SCSI_TAPE   "/dev/st0"
     629#define VANILLA_USB_DEVICE  "/dev/hda"
     630#define DONT_KNOW_HOW_TO_EVALUATE_THIS_DEVICE_TYPE  "/dev/md"
     631#define RAID_DEVICE_STUB    DONT_KNOW_HOW_TO_EVALUATE_THIS_DEVICE_TYPE
     632#define SANE_FORMATS        "swap image vfat ext2 ext3 xfs vfs jfs reiserfs vmfs dos minix coda nfs ntfs hpfs raid lvm cifs"
     633#define ALT_TAPE        "/dev/ht0"
     634#define MKE2FS_OR_NEWFS "mke2fs"
     635#define CP_BIN      "cp"
     636#endif
     637
     638
     639/**
     640 * The template for a filelist filename.
     641 * The first argument (%s) is the tempdir and the second (%d) is the filelist number.
     642 */
     643#define FILELIST_FNAME_RAW_SZ "%s/filelist.%ld"
     644
     645#define XATTR_LIST_FNAME_RAW_SZ      "%s/xattr_list.%ld.gz"
     646#define XATTR_BIGGLST_FNAME_RAW_SZ   "%s/xattr_list.big.gz"
     647#define ACL_LIST_FNAME_RAW_SZ        "%s/acl_list.%ld.gz"
     648#define ACL_BIGGLST_FNAME_RAW_SZ     "%s/acl_list.big.gz"
     649
     650/**
     651 * The template for an afioball filename.
     652 * The first argument (%s) is the tempdir and the second (%d) is the filelist number.
     653 */
     654#define AFIOBALL_FNAME_RAW_SZ (bkpinfo->use_star)?"%s/tmpfs/%ld.star.%s":"%s/tmpfs/%ld.afio.%s"
     655#define ARCH_THREADS 2          ///< The number of simultaneous threads running afio in the background.
     656#define ARCH_BUFFER_NUM (ARCH_THREADS*4)    // Number of permissible queued afio files
     657#define FORTY_SPACES "                                         "    ///< 40 spaces.
     658#define PPCFG_RAMDISK_SIZE 350  ///< Size of the tmpfs, in megabytes, to attempt to mount (to speed up Mondo).
     659
     660#define DO_MBR_PLEASE "/tmp/DO-MBR-PLEASE"
     661
     662
     663/**
     664 * Compatibility define to change log_it() calls to log_debug_msg() calls.
     665 */
     666#define log_it(format, args...) log_debug_msg(2, __FILE__, __FUNCTION__, __LINE__, format, ## args)
     667
     668/**
     669 * Macro to log a message along with file, line, and function information.
     670 */
     671#define log_msg(level, format, args...) log_debug_msg(level, __FILE__, __FUNCTION__, __LINE__, format, ## args)
     672
     673#define DEFAULT_DVD_DISK_SIZE 4480  ///< The default size (in MB) of a DVD disk, unless the user says otherwise.
     674
     675#define DEFAULT_DEBUG_LEVEL 4   ///< By default, don't log messages with a loglevel higher than this.
     676
     677#define SZ_NTFSPROG_VOLSIZE "1048576"   // was 4096
     678#define NTFSPROG_PARAMS "-z0 -V" SZ_NTFSPROG_VOLSIZE " -o -b -d -g1"
     679
     680#define MNT_CDROM "/mnt/cdrom"
     681#define MNT_FLOPPY "/mnt/floppy"
     682
     683#define DEFAULT_MR_LOGLEVEL 4
     684
     685#endif                          /* _MY_STUFF_H_ */
  • branches/stable/mondo/src/mondoarchive/Makefile.am

    r1924 r1939  
    55##
    66AM_CPPFLAGS = -DMONDO_CONF_DIR=\"$(sysconfdir)/mondo\" -I${top_builddir}/src/include -I${top_builddir}/src/common -I${top_builddir}/src/mondoarchive
     7
     8AM_CPPFLAGS = -DMONDO_CONF_DIR=\"$(sysconfdir)/mondo\" -I${top_builddir}/src/include -I${top_builddir}/src/common
    79
    810## Headers
  • branches/stable/mondo/src/mondoarchive/mondoarchive.c

    r1924 r1939  
    743743    return EXIT_SUCCESS;
    744744}
     745=======
     746/***************************************************************************
     747                          main.c  -  description
     748                             -------------------
     749    begin                : Fri Apr 19 16:40:35 EDT 2002
     750    copyright            : (C) 2002 by Stan Benoit
     751    email                : troff@nakedsoul.org
     752    cvsid                : $Id$
     753 ***************************************************************************/
     754
     755/***************************************************************************
     756 *                                                                         *
     757 *   This program is free software; you can redistribute it and/or modify  *
     758 *   it under the terms of the GNU General Public License as published by  *
     759 *   the Free Software Foundation; either version 2 of the License, or     *
     760 *   (at your option) any later version.                                   *
     761 *                                                                         *
     762 ***************************************************************************/
     763
     764/**
     765 * @file
     766 * The main file for mondoarchive.
     767 */
     768
     769/************************* #include statements *************************/
     770#include <pthread.h>
     771#include <stdio.h>
     772#include <stdlib.h>
     773#include "my-stuff.h"
     774#include "../common/mondostructures.h"
     775#include "../common/libmondo.h"
     776#include "../common/libmondo-cli-EXT.h"
     777#include "../common/libmondo-tools-EXT.h"
     778#include "mondoarchive.h"
     779
     780// for CVS
     781//static char cvsid[] = "$Id$";
     782
     783/************************* external variables *************************/
     784extern void set_signals(int);
     785extern int g_current_media_number;
     786extern void register_pid(pid_t, char *);
     787extern int g_currentY;
     788extern bool g_text_mode;
     789extern char *g_boot_mountpt;
     790extern bool g_remount_floppy_at_end;
     791extern char *g_cdrw_drive_is_here;
     792static char *g_cdrom_drive_is_here = NULL;
     793static char *g_dvd_drive_is_here = NULL;
     794extern double g_kernel_version;
     795
     796/***************** global vars, used only by main.c ******************/
     797long diffs;
     798
     799extern t_bkptype g_backup_media_type;
     800extern int g_loglevel;
     801
     802/**
     803 * Whether we're restoring from ISOs. Obviously not, since this is the
     804 * backup program.
     805 * @note You @b MUST declare this variable somewhere in your program if
     806 * you use libmondo. Otherwise the link will fail.
     807 * @ingroup globalGroup
     808 */
     809bool g_ISO_restore_mode = FALSE;
     810
     811/* Do we use extended attributes and acl ?
     812 *  * By default no, use --acl & --attr options to force their usage */
     813char *g_getfacl = NULL;
     814char *g_getfattr = NULL;
     815
     816/* Reference to global bkpinfo */
     817struct s_bkpinfo *bkpinfo;
     818
     819/****************** subroutines used only by main.c ******************/
     820
     821
     822/**
     823 * Print a "don't panic" message to the log and a message about the logfile to the screen.
     824 */
     825void welcome_to_mondoarchive(void)
     826{
     827    char *tmp = NULL;
     828
     829    log_msg(0, "Mondo Archive v%s --- http://www.mondorescue.org",
     830            PACKAGE_VERSION);
     831    log_msg(0, "running %s binaries", get_architecture());
     832    tmp = get_uname_m();
     833    log_msg(0, "running on %s architecture", tmp);
     834    free(tmp);
     835    log_msg(0,
     836            "-----------------------------------------------------------");
     837    log_msg(0,
     838            "NB: Mondo logs almost everything, so don't panic if you see");
     839    log_msg(0,
     840            "some error messages.  Please read them carefully before you");
     841    log_msg(0,
     842            "decide to break out in a cold sweat.    Despite (or perhaps");
     843    log_msg(0,
     844            "because of) the wealth of messages. some users are inclined");
     845    log_msg(0,
     846            "to stop reading this log. If Mondo stopped for some reason,");
     847    log_msg(0,
     848            "chances are it's detailed here.  More than likely there's a");
     849    log_msg(0,
     850            "message at the very end of this log that will tell you what");
     851    log_msg(0,
     852            "is wrong. Please read it!                          -Devteam");
     853    log_msg(0,
     854            "-----------------------------------------------------------");
     855
     856    log_msg(0, "Zero...");
     857    log_msg(1, "One...");
     858    log_msg(2, "Two...");
     859    log_msg(3, "Three...");
     860    log_msg(4, "Four...");
     861    log_msg(5, "Five...");
     862    log_msg(6, "Six...");
     863    log_msg(7, "Seven...");
     864    log_msg(8, "Eight...");
     865    printf("See %s for details of backup run.\n", MONDO_LOGFILE);
     866}
     867
     868
     869extern char *g_magicdev_command;
     870
     871/**
     872 * Do whatever is necessary to insure a successful backup on the Linux distribution
     873 * of the day.
     874 */
     875void distro_specific_kludges_at_start_of_mondoarchive(void)
     876{
     877    log_msg(2, "Unmounting old ramdisks if necessary");
     878    stop_magicdev_if_necessary();   // for RH+Gnome users
     879    run_program_and_log_output
     880        ("umount `mount | grep shm | grep mondo | cut -d' ' -f3`", 2);
     881    unmount_supermounts_if_necessary(); // for Mandrake users whose CD-ROMs are supermounted
     882    //  stop_autofs_if_necessary(); // for Xandros users
     883    mount_boot_if_necessary();  // for Gentoo users with non-mounted /boot partitions
     884    clean_up_KDE_desktop_if_necessary();    // delete various misc ~/.* files that get in the way
     885}
     886
     887
     888
     889/**
     890 * Undo whatever was done by distro_specific_kludges_at_start_of_mondoarchive().
     891 */
     892void distro_specific_kludges_at_end_of_mondoarchive(void)
     893{
     894//  char tmp[500];
     895    log_msg(2, "Restarting magicdev if necessary");
     896    sync();
     897    restart_magicdev_if_necessary();    // for RH+Gnome users
     898
     899    log_msg(2, "Restarting autofs if necessary");
     900    sync();
     901    //  restart_autofs_if_necessary(); // for Xandros users
     902
     903    log_msg(2, "Restarting supermounts if necessary");
     904    sync();
     905    remount_supermounts_if_necessary(); // for Mandrake users
     906
     907    log_msg(2, "Unmounting /boot if necessary");
     908    sync();
     909    unmount_boot_if_necessary();    // for Gentoo users
     910
     911//  log_msg( 2, "Cleaning up KDE desktop");
     912//  clean_up_KDE_desktop_if_necessary();
     913}
     914
     915
     916/**
     917 * Backup/verify the user's data.
     918 * What did you think it did, anyway? :-)
     919 */
     920int main(int argc, char *argv[])
     921{
     922    char *tmp;
     923    int res, retval;
     924    char *say_at_end;
     925
     926/* Make sure I'm root; abort if not */
     927    if (getuid() != 0) {
     928        fprintf(stderr, "Please run as root.\r\n");
     929        exit(127);
     930    }
     931
     932/* If -V, -v or --version then echo version no. and quit */
     933    if (argc == 2
     934        && (!strcmp(argv[argc - 1], "-v") || !strcmp(argv[argc - 1], "-V")
     935            || !strcmp(argv[argc - 1], "--version"))) {
     936        printf("mondoarchive v%s\nSee man page for help\n", PACKAGE_VERSION);
     937        exit(0);
     938    }
     939
     940/* Initialize variables */
     941
     942    printf("Initializing...\n");
     943    if (!(bkpinfo = malloc(sizeof(struct s_bkpinfo)))) {
     944        fatal_error("Cannot malloc bkpinfo");
     945    }
     946    reset_bkpinfo();
     947
     948    res = 0;
     949    retval = 0;
     950    diffs = 0;
     951    malloc_string(tmp);
     952    malloc_string(say_at_end);
     953    say_at_end[0] = '\0';
     954    malloc_libmondo_global_strings();
     955
     956    /* initialize log file with time stamp */
     957    unlink(MONDO_LOGFILE);
     958    log_msg(0, "Time started: %s", mr_date());
     959
     960    /* make sure PATH environmental variable allows access to mkfs, fdisk, etc. */
     961    strncpy(tmp, getenv("PATH"), MAX_STR_LEN - 1);
     962    tmp[MAX_STR_LEN - 1] = '\0';
     963    if (strlen(tmp) >= MAX_STR_LEN - 33) {
     964        fatal_error
     965            ("Your PATH environmental variable is too long. Please shorten it.");
     966    }
     967    strcat(tmp, ":/sbin:/usr/sbin:/usr/local/sbin");
     968    setenv("PATH", tmp, 1);
     969
     970    /* Add the ARCH environment variable for ia64 purposes */
     971    strncpy(tmp, get_architecture(), MAX_STR_LEN - 1);
     972    tmp[MAX_STR_LEN - 1] = '\0';
     973    setenv("ARCH", tmp, 1);
     974
     975    /* Add MONDO_SHARE environment variable for mindi */
     976    setenv_mondo_share();
     977
     978    /* Configure the bkpinfo structure, global file paths, etc. */
     979    g_main_pid = getpid();
     980    log_msg(9, "This");
     981
     982    register_pid(g_main_pid, "mondo");
     983    set_signals(TRUE);          // catch SIGTERM, etc.
     984    run_program_and_log_output("dmesg -n1", TRUE);
     985
     986    log_msg(9, "Next");
     987    make_hole_for_dir(MONDO_CACHE);
     988
     989    welcome_to_mondoarchive();
     990    distro_specific_kludges_at_start_of_mondoarchive();
     991    g_kernel_version = get_kernel_version();
     992
     993    if (argc == 4 && !strcmp(argv[1], "getfattr")) {
     994        g_loglevel = 10;
     995        g_text_mode = TRUE;
     996        setup_newt_stuff();
     997        if (!strstr(argv[2], "filelist")) {
     998            printf("Sorry - filelist goes first\n");
     999            finish(1);
     1000        } else {
     1001            finish(get_fattr_list(argv[2], argv[3]));
     1002        }
     1003        finish(0);
     1004    }
     1005    if (argc == 4 && !strcmp(argv[1], "setfattr")) {
     1006        g_loglevel = 10;
     1007//      chdir("/tmp");
     1008        g_text_mode = TRUE;
     1009        setup_newt_stuff();
     1010        finish(set_fattr_list(argv[2], argv[3]));
     1011    }
     1012
     1013    if (argc == 3 && !strcmp(argv[1], "wildcards")) {
     1014        g_loglevel = 10;
     1015        g_text_mode = TRUE;
     1016        setup_newt_stuff();
     1017        turn_wildcard_chars_into_literal_chars(tmp, argv[2]);
     1018        printf("in=%s; out=%s\n", argv[2], tmp);
     1019        finish(1);
     1020    }
     1021
     1022    if (argc == 4 && !strcmp(argv[1], "getfacl")) {
     1023        g_loglevel = 10;
     1024        g_text_mode = TRUE;
     1025        setup_newt_stuff();
     1026        if (!strstr(argv[2], "filelist")) {
     1027            printf("Sorry - filelist goes first\n");
     1028            finish(1);
     1029        } else {
     1030            finish(get_acl_list(argv[2], argv[3]));
     1031        }
     1032        finish(0);
     1033    }
     1034    if (argc == 4 && !strcmp(argv[1], "setfacl")) {
     1035        g_loglevel = 10;
     1036//      chdir("/tmp");
     1037        g_text_mode = TRUE;
     1038        setup_newt_stuff();
     1039        finish(set_acl_list(argv[2], argv[3]));
     1040    }
     1041
     1042    if (argc > 2 && !strcmp(argv[1], "find-cd")) {
     1043        g_loglevel = 10;
     1044        g_text_mode = TRUE;
     1045        setup_newt_stuff();
     1046        if (find_cdrw_device(tmp)) {
     1047            printf("Failed to find CDR-RW drive\n");
     1048        } else {
     1049            printf("CD-RW is at %s\n", tmp);
     1050        }
     1051        tmp[0] = '\0';
     1052        if (find_cdrom_device(tmp, atoi(argv[2]))) {
     1053            printf("Failed to find CD-ROM drive\n");
     1054        } else {
     1055            printf("CD-ROM is at %s\n", tmp);
     1056        }
     1057        finish(0);
     1058    }
     1059
     1060    if (argc > 2 && !strcmp(argv[1], "find-dvd")) {
     1061        g_loglevel = 10;
     1062        g_text_mode = TRUE;
     1063        setup_newt_stuff();
     1064        if (find_dvd_device(tmp, atoi(argv[2]))) {
     1065            printf("Failed to find DVD drive\n");
     1066        } else {
     1067            printf("DVD is at %s\n", tmp);
     1068        }
     1069        finish(0);
     1070    }
     1071
     1072    if (argc > 2 && !strcmp(argv[1], "disksize")) {
     1073        printf("%s --> %ld\n", argv[2], get_phys_size_of_drive(argv[2]));
     1074        finish(0);
     1075    }
     1076    if (argc > 2 && !strcmp(argv[1], "test-dev")) {
     1077        if (is_dev_an_NTFS_dev(argv[2])) {
     1078            printf("%s is indeed an NTFS dev\n", argv[2]);
     1079        } else {
     1080            printf("%s is _not_ an NTFS dev\n", argv[2]);
     1081        }
     1082        finish(0);
     1083    }
     1084
     1085    if (pre_param_configuration()) {
     1086        fatal_error
     1087            ("Pre-param initialization phase failed. Please review the error messages above, make the specified changes, then try again. Exiting...");
     1088    }
     1089
     1090/* Process command line, if there is one. If not, ask user for info. */
     1091    if (argc == 1) {
     1092        g_text_mode = FALSE;
     1093        setup_newt_stuff();
     1094        res = interactively_obtain_media_parameters_from_user(TRUE);    /* yes, archiving */
     1095        if (res) {
     1096            fatal_error
     1097                ("Syntax error. Please review the parameters you have supplied and try again.");
     1098        }
     1099    } else {
     1100        res = handle_incoming_parameters(argc, argv);
     1101        if (res) {
     1102            printf
     1103                ("Errors were detected in the command line you supplied.\n");
     1104            printf("Please review the log file - %s\n", MONDO_LOGFILE );
     1105            log_msg(1, "Mondoarchive will now exit.");
     1106            finish(1);
     1107        }
     1108        setup_newt_stuff();
     1109    }
     1110
     1111/* Finish configuring global structures */
     1112    if (post_param_configuration()) {
     1113        fatal_error
     1114            ("Post-param initialization phase failed. Perhaps bad parameters were supplied to mondoarchive? Please review the documentation, error messages and logs. Exiting...");
     1115    }
     1116
     1117    log_to_screen
     1118        ("BusyBox's sources are available from http://www.busybox.net");
     1119
     1120    /* If we're meant to backup then backup */
     1121    if (bkpinfo->backup_data) {
     1122        res = backup_data();
     1123        retval += res;
     1124        if (res) {
     1125            strcat(say_at_end,
     1126                   "Data archived. Please check the logs, just as a precaution. ");
     1127        } else {
     1128            strcat(say_at_end, "Data archived OK. ");
     1129        }
     1130    }
     1131
     1132/* If we're meant to verify then verify */
     1133    if (bkpinfo->verify_data) {
     1134        res = verify_data();
     1135        if (res < 0) {
     1136            sprintf(tmp, "%d difference%c found.", -res,
     1137                    (-res != 1) ? 's' : ' ');
     1138            strcat(say_at_end, tmp);
     1139            log_to_screen(tmp);
     1140            res = 0;
     1141        }
     1142        retval += res;
     1143    }
     1144
     1145/* Report result of entire operation (success? errors?) */
     1146    if (!retval) {
     1147        mvaddstr_and_log_it(g_currentY++, 0,
     1148                            "Backup and/or verify ran to completion. Everything appears to be fine.");
     1149    } else {
     1150        mvaddstr_and_log_it(g_currentY++, 0,
     1151                            "Backup and/or verify ran to completion. However, errors did occur.");
     1152    }
     1153
     1154    if (does_file_exist(MINDI_CACHE"/mondorescue.iso")) {
     1155        log_to_screen
     1156            (MINDI_CACHE"/mondorescue.iso, a boot/utility CD, is available if you want it.");
     1157    }
     1158
     1159    if (length_of_file(MONDO_CACHE"/changed.files") > 2) {
     1160        if (g_text_mode) {
     1161            log_to_screen("Type 'less "MONDO_CACHE"/changed.files' to see which files don't match the archives");
     1162        } else {
     1163            log_msg(1, "Type 'less "MONDO_CACHE"/changed.files' to see which files don't match the archives");
     1164            log_msg(2, "Calling popup_changelist_from_file()");
     1165            popup_changelist_from_file(MONDO_CACHE"/changed.files");
     1166            log_msg(2, "Returned from popup_changelist_from_file()");
     1167        }
     1168    } else {
     1169        unlink(MONDO_CACHE"/changed.files");
     1170    }
     1171    log_to_screen(say_at_end);
     1172    sprintf(tmp, "umount %s/tmpfs", bkpinfo->tmpdir);
     1173    run_program_and_log_output(tmp, TRUE);
     1174    if (bkpinfo->backup_media_type == usb) {
     1175        log_msg(1, "Unmounting USB device.");
     1176        sprintf(tmp, "umount %s1", bkpinfo->media_device);
     1177        run_program_and_log_output(tmp, TRUE);
     1178    }
     1179
     1180    run_program_and_log_output("mount", 2);
     1181
     1182    system("rm -f "MONDO_CACHE"/last-backup.aborted");
     1183    if (!retval) {
     1184        printf("Mondoarchive ran OK.\n");
     1185    } else {
     1186        printf("Errors occurred during backup. Please check logfile.\n");
     1187    }
     1188    distro_specific_kludges_at_end_of_mondoarchive();
     1189    register_pid(0, "mondo");
     1190    set_signals(FALSE);
     1191
     1192    free_libmondo_global_strings();
     1193    paranoid_free(say_at_end);
     1194   
     1195
     1196    if (!g_cdrom_drive_is_here) {
     1197        log_msg(10, "FYI, g_cdrom_drive_is_here was never used");
     1198    }
     1199    if (!g_dvd_drive_is_here) {
     1200        log_msg(10, "FYI, g_dvd_drive_is_here was never used");
     1201    }
     1202
     1203    /* finalize log file with time stamp */
     1204    log_msg(0, "Time finished: %s", mr_date());
     1205
     1206    chdir("/tmp");
     1207
     1208    if (!g_text_mode) {
     1209        popup_and_OK
     1210            ("Mondo Archive has finished its run. Please press ENTER to return to the shell prompt.");
     1211        log_to_screen("See %s for details of backup run.", MONDO_LOGFILE);
     1212    } else {
     1213        printf("See %s for details of backup run.\n", MONDO_LOGFILE);
     1214    }
     1215    finish(retval);
     1216
     1217    return EXIT_SUCCESS;
     1218}
  • branches/stable/mondo/src/mondorestore/Makefile.am

    r1560 r1939  
    44## Process with Automake to generate Makefile.in
    55##
     6AM_CPPFLAGS = -DMONDO_CONF_DIR=\"$(sysconfdir)/mondo\" -I${top_builddir}/src/include -I${top_builddir}/src/common
     7
    68AM_CPPFLAGS = -DMONDO_CONF_DIR=\"$(sysconfdir)/mondo\" -I${top_builddir}/src/include -I${top_builddir}/src/common
    79
  • branches/stable/mondo/src/mondorestore/mondo-restore-EXT.h

    r1842 r1939  
    55#endif
    66
    7 extern bool g_sigpipe_caught;
    87extern bool g_ISO_restore_mode; /* are we in Iso Mode? */
    98extern bool g_I_have_just_nuked;
  • branches/stable/mondo/src/mondorestore/mondo-rstr-tools.c

    r1924 r1939  
    2121extern char *bkptype_to_string(t_bkptype bt);
    2222
    23 extern bool g_sigpipe_caught;
    2423extern bool g_ISO_restore_mode; /* are we in Iso Mode? */
    2524extern bool g_I_have_just_nuked;
     
    414413    }
    415414    mr_msg(1, "Mounting device %s   ", device);
    416     if (writeable) {
    417         mr_asprintf(&additional_parameters, "-o rw");
    418     } else {
    419         mr_asprintf(&additional_parameters, "-o ro");
    420     }
    421     if (find_home_of_exe("setfattr")) {
    422         mr_strcat(additional_parameters, ",user_xattr");
    423     }
    424     if (find_home_of_exe("setfacl")) {
    425         mr_strcat(additional_parameters, ",acl");
     415    /* Deal with additional params only if not /proc or /sys */
     416    if (strcmp(format, "proc") && strcmp(format, "sys")) {
     417        if (writeable) {
     418            mr_asprintf(&additional_parameters, "-o rw");
     419        } else {
     420            mr_asprintf(&additional_parameters, "-o ro");
     421        }
     422        if (find_home_of_exe("setfattr")) {
     423            mr_strcat(additional_parameters, ",user_xattr");
     424        }
     425        if (find_home_of_exe("setfacl")) {
     426            mr_strcat(additional_parameters, ",acl");
     427        }
    426428    }
    427429
     
    586588        mvaddstr_and_log_it(g_currentY++, 74, _("Done."));
    587589    }
     590    /* Also mounting under MNT_RESTORING  special FS */
     591    (void)mount_device("/proc","/proc","proc",TRUE);
     592    (void)mount_device("/sys","/sys","sysfs",TRUE);
    588593    run_program_and_log_output("df -m", 3);
    589594    mr_free(mountlist);
  • branches/stable/mondo/src/mondorestore/mondorestore.c

    r1924 r1939  
    32753275 *END_MONDO-RESTORE.C                                                     *
    32763276 **************************************************************************/
     3277=======
     3278/***************************************************************************
     3279$Id$
     3280restores mondoarchive data
     3281***************************************************************************/
     3282
     3283/**
     3284 * @file
     3285 * The main file for mondorestore.
     3286 */
     3287
     3288/**************************************************************************
     3289 * #include statements                                                    *
     3290 **************************************************************************/
     3291#include <pthread.h>
     3292#include "my-stuff.h"
     3293#include "../common/mondostructures.h"
     3294#include "../common/libmondo.h"
     3295#include "mr-externs.h"
     3296#include "mondo-restore.h"
     3297#include "mondorestore.h"
     3298#include "mondo-rstr-compare-EXT.h"
     3299#include "mondo-rstr-tools-EXT.h"
     3300
     3301extern void twenty_seconds_til_yikes(void);
     3302
     3303/* Reference to global bkpinfo */
     3304struct s_bkpinfo *bkpinfo;
     3305
     3306
     3307/* For use in other programs (ex. XMondo) */
     3308#ifdef MONDORESTORE_MODULE
     3309#define main __mondorestore_main
     3310#define g_ISO_restore_mode __mondorestore_g_ISO_restore_mode
     3311#endif
     3312
     3313//static char cvsid[] = "$Id$";
     3314
     3315/**************************************************************************
     3316 * Globals                                                                *
     3317 **************************************************************************/
     3318extern char *g_tmpfs_mountpt;   // declared in libmondo-tools.c
     3319extern bool g_text_mode;
     3320extern FILE *g_fprep;
     3321extern double g_kernel_version;
     3322extern int g_partition_table_locked_up;
     3323extern int g_noof_rows;
     3324
     3325extern int partition_everything(struct mountlist_itself *mountlist);
     3326
     3327
     3328/**
     3329 * @name Restore-Time Globals
     3330 * @ingroup globalGroup
     3331 * @{
     3332 */
     3333
     3334/**
     3335 * If TRUE, then we're restoring from ISOs or an NFS server.
     3336 * If FALSE, then we're restoring from some kind of real media (tape, CD, etc.)
     3337 */
     3338bool g_ISO_restore_mode = FALSE;    /* are we in Iso Mode? */
     3339
     3340/**
     3341 * If TRUE, then we have had a successful "nuke" restore.
     3342 */
     3343bool g_I_have_just_nuked = FALSE;
     3344
     3345/**
     3346 * The device to mount to get at the ISO images. Ignored unless @p g_ISO_restore_mode.
     3347 */
     3348char *g_isodir_device;
     3349
     3350/**
     3351 * The format of @p g_isodir_device. Ignored unless @p g_ISO_restore_mode.
     3352 */
     3353char *g_isodir_format;
     3354
     3355/**
     3356 * The location of 'biggielist.txt', containing the biggiefiles on the current archive set.
     3357 */
     3358char *g_biggielist_txt;
     3359
     3360/**
     3361 * The location of 'filelist.full', containing all files (<em>including biggiefiles</em>) on
     3362 * the current archive set.
     3363 */
     3364char *g_filelist_full;
     3365
     3366/**
     3367 * The location of a file containing a list of the devices that were archived
     3368 * as images, not as individual files.
     3369 */
     3370char *g_filelist_imagedevs;
     3371
     3372/**
     3373 * The location of a file containing a list of imagedevs to actually restore.
     3374 * @see g_filelist_imagedevs
     3375 */
     3376char *g_imagedevs_restthese;
     3377
     3378/**
     3379 * The location of 'mondo-restore.cfg', containing the metadata
     3380 * information for this backup.
     3381 */
     3382char *g_mondo_cfg_file;
     3383
     3384/**
     3385 * The location of 'mountlist.txt', containing the information on the
     3386 * user's partitions and hard drives.
     3387 */
     3388char *g_mountlist_fname;
     3389
     3390/**
     3391 * Mondo's home directory during backup. Unused in mondorestore; included
     3392 * to avoid link errors.
     3393 */
     3394char *g_mondo_home;
     3395
     3396extern char *g_getfacl;
     3397extern char *g_getfattr;
     3398
     3399/* @} - end of "Restore-Time Globals" in globalGroup */
     3400
     3401
     3402
     3403extern int copy_from_src_to_dest(FILE * f_orig, FILE * f_archived,
     3404                                 char direction);
     3405
     3406
     3407
     3408/**************************************************************************
     3409 * COMPAQ PROLIANT Stuff:  needs some special help                        *
     3410**************************************************************************/
     3411
     3412/**
     3413 * The message to display if we detect that the user is using a Compaq Proliant.
     3414 */
     3415#define COMPAQ_PROLIANTS_SUCK "Partition and format your disk using Compaq's disaster recovery CD. After you've done that, please reboot with your Mondo media in Interactive Mode."
     3416
     3417
     3418
     3419
     3420/**
     3421 * Allow the user to modify the mountlist before we partition & format their drives.
     3422 * @param bkpinfo The backup information structure. @c disaster_recovery is the only field used.
     3423 * @param mountlist The mountlist to let the user modify.
     3424 * @param raidlist The raidlist that goes with @p mountlist.
     3425 * @return 0 for success, nonzero for failure.
     3426 * @ingroup restoreGuiGroup
     3427 */
     3428int let_user_edit_the_mountlist(struct mountlist_itself *mountlist,
     3429                                struct raidlist_itself *raidlist)
     3430{
     3431    int retval = 0, res = 0;
     3432
     3433    log_msg(2, "let_user_edit_the_mountlist() --- starting");
     3434
     3435    assert(bkpinfo != NULL);
     3436    assert(mountlist != NULL);
     3437    assert(raidlist != NULL);
     3438    if (!bkpinfo->disaster_recovery) {
     3439        strcpy(g_mountlist_fname, "/tmp/mountlist.txt");
     3440        log_msg(2, "I guess you're testing edit_mountlist()");
     3441    }
     3442    if (!does_file_exist(g_mountlist_fname)) {
     3443        log_to_screen(g_mountlist_fname);
     3444        log_to_screen("does not exist");
     3445        return (1);
     3446    }
     3447
     3448    retval = load_mountlist(mountlist, g_mountlist_fname);
     3449    load_raidtab_into_raidlist(raidlist, RAIDTAB_FNAME);
     3450    if (retval) {
     3451        log_to_screen
     3452            ("Warning - load_raidtab_into_raidlist returned an error");
     3453    }
     3454    res = edit_mountlist(g_mountlist_fname, mountlist, raidlist);
     3455    if (res) {
     3456        return (1);
     3457    }
     3458
     3459    save_mountlist_to_disk(mountlist, g_mountlist_fname);
     3460    save_raidlist_to_raidtab(raidlist, RAIDTAB_FNAME);
     3461
     3462    log_to_screen("I have finished editing the mountlist for you.");
     3463
     3464    return (retval);
     3465}
     3466
     3467
     3468
     3469
     3470
     3471/**
     3472 * Determine whether @p mountlist contains a Compaq diagnostic partition.
     3473 * @param mountlist The mountlist to examine.
     3474 * @return TRUE if there's a Compaq diagnostic partition; FALSE if not.
     3475 * @ingroup restoreUtilityGroup
     3476 */
     3477bool
     3478partition_table_contains_Compaq_diagnostic_partition(struct
     3479                                                     mountlist_itself *
     3480                                                     mountlist)
     3481{
     3482    int i;
     3483
     3484    assert(mountlist != NULL);
     3485
     3486    for (i = 0; i < mountlist->entries; i++) {
     3487        if (strstr(mountlist->el[i].format, "ompaq")) {
     3488            log_msg(2, "mountlist[%d] (%s) is %s (Compaq alert!)",
     3489                    i, mountlist->el[i].device, mountlist->el[i].format);
     3490
     3491            return (TRUE);
     3492        }
     3493    }
     3494    return (FALSE);
     3495}
     3496
     3497/**************************************************************************
     3498 *END_PARTITION_TABLE_CONTAINS_COMPAQ_DIAGNOSTIC_PARTITION                *
     3499 **************************************************************************/
     3500
     3501
     3502/**
     3503 * Allow the user to abort the backup if we find that there is a Compaq diagnostic partition.
     3504 * @note This function does not actually check for the presence of a Compaq partition.
     3505 * @ingroup restoreUtilityGroup
     3506 */
     3507void offer_to_abort_because_Compaq_Proliants_suck(void)
     3508{
     3509    popup_and_OK(COMPAQ_PROLIANTS_SUCK);
     3510    if (ask_me_yes_or_no
     3511        ("Would you like to reboot and use your Compaq CD to prep your hard drive?"))
     3512    {
     3513        fatal_error
     3514            ("Aborting. Please reboot and prep your hard drive with your Compaq CD.");
     3515    }
     3516}
     3517
     3518/**************************************************************************
     3519 *END_OFFER_TO_ABORT_BECAUSE_COMPAQ_PROLIANTS_SUCK                        *
     3520 **************************************************************************/
     3521
     3522
     3523
     3524/**
     3525 * Call interactive_mode(), nuke_mode(), or compare_mode() depending on the user's choice.
     3526 * @param bkpinfo The backup information structure. Most fields are used.
     3527 * @param mountlist The mountlist containing information about the user's partitions.
     3528 * @param raidlist The raidlist to go with @p mountlist.
     3529 * @return The return code from the mode function called.
     3530 * @ingroup restoreGroup
     3531 */
     3532int
     3533catchall_mode(struct mountlist_itself *mountlist,
     3534              struct raidlist_itself *raidlist)
     3535{
     3536    char c, *tmp;
     3537    int retval = 0;
     3538
     3539    iamhere("inside catchall");
     3540    assert(bkpinfo != NULL);
     3541    assert(mountlist != NULL);
     3542    assert(raidlist != NULL);
     3543    malloc_string(tmp);
     3544    iamhere("pre wrm");
     3545    c = which_restore_mode();
     3546    iamhere("post wrm");
     3547    if (c == 'I' || c == 'N' || c == 'C') {
     3548        interactively_obtain_media_parameters_from_user(FALSE);
     3549    } else {
     3550        popup_and_OK("No restoring or comparing will take place today.");
     3551        if (is_this_device_mounted("/mnt/cdrom")) {
     3552            run_program_and_log_output("umount /mnt/cdrom", FALSE);
     3553        }
     3554        if (g_ISO_restore_mode) {
     3555            sprintf(tmp, "umount %s", bkpinfo->isodir);
     3556            run_program_and_log_output(tmp, FALSE);
     3557        }
     3558        paranoid_MR_finish(0);
     3559    }
     3560
     3561    iamhere("post int");
     3562
     3563    if (bkpinfo->backup_media_type == iso) {
     3564        if (iso_fiddly_bits((c == 'N') ? TRUE : FALSE)) {
     3565            log_msg(2,
     3566                    "catchall_mode --- iso_fiddly_bits returned w/ error");
     3567            return (1);
     3568        } else {
     3569            log_msg(2, "catchall_mode --- iso_fiddly_bits ok");
     3570        }
     3571    }
     3572
     3573    if (c == 'I') {
     3574        log_msg(2, "IM selected");
     3575        retval += interactive_mode(mountlist, raidlist);
     3576    } else if (c == 'N') {
     3577        log_msg(2, "NM selected");
     3578        retval += nuke_mode(mountlist, raidlist);
     3579    } else if (c == 'C') {
     3580        log_msg(2, "CM selected");
     3581        retval += compare_mode(mountlist, raidlist);
     3582    }
     3583    paranoid_free(tmp);
     3584    return (retval);
     3585}
     3586
     3587/**************************************************************************
     3588 *END_CATCHALL_MODE                                                      *
     3589 **************************************************************************/
     3590
     3591/**************************************************************************
     3592 *END_  EXTRACT_CONFIG_FILE_FROM_RAMDISK                                  *
     3593 **************************************************************************/
     3594
     3595
     3596/**
     3597 * Locate an executable in the directory structure rooted at @p restg.
     3598 * @param out_path Where to put the executable.
     3599 * @param fname The basename of the executable.
     3600 * @param restg The directory structure to look in.
     3601 * @note If it could not be found in @p restg then @p fname is put in @p out_path.
     3602 * @ingroup restoreUtilityGroup
     3603 */
     3604void
     3605find_pathname_of_executable_preferably_in_RESTORING(char *out_path,
     3606                                                    char *fname,
     3607                                                    char *restg)
     3608{
     3609    assert(out_path != NULL);
     3610    assert_string_is_neither_NULL_nor_zerolength(fname);
     3611
     3612    sprintf(out_path, "%s/sbin/%s", restg, fname);
     3613    if (does_file_exist(out_path)) {
     3614        sprintf(out_path, "%s/usr/sbin/%s", restg, fname);
     3615        if (does_file_exist(out_path)) {
     3616            sprintf(out_path, "%s/bin/%s", restg, fname);
     3617            if (does_file_exist(out_path)) {
     3618                sprintf(out_path, "%s/usr/bin/%s", restg, fname);
     3619                if (does_file_exist(out_path)) {
     3620                    strcpy(out_path, fname);
     3621                }
     3622            }
     3623        }
     3624    }
     3625}
     3626
     3627/**************************************************************************
     3628 *END_FIND_PATHNAME_OF_EXECUTABLE_PREFERABLY_IN_RESTORING                 *
     3629 **************************************************************************/
     3630
     3631static void clean_blkid() {
     3632
     3633    char *tmp1 = NULL;
     3634
     3635    /* Clean up blkid cache file if they exist */
     3636    asprintf(&tmp1,"%s/etc/blkid.tab",bkpinfo->restore_path);
     3637    (void)unlink(tmp1);
     3638    paranoid_free(tmp1);
     3639    asprintf(&tmp1,"%s/etc/blkid.tab.old",bkpinfo->restore_path);
     3640    (void)unlink(tmp1);
     3641    paranoid_free(tmp1);
     3642}
     3643
     3644
     3645
     3646
     3647/**
     3648 * @addtogroup restoreGroup
     3649 * @{
     3650 */
     3651/**
     3652 * Restore the user's data, in a disaster recovery situation, prompting the
     3653 * user about whether or not to do every step.
     3654 * The user can edit the mountlist, choose files to restore, etc.
     3655 * @param bkpinfo The backup information structure. Most fields are used.
     3656 * @param mountlist The mountlist containing information about the user's partitions.
     3657 * @param raidlist The raidlist to go with @p mountlist.
     3658 * @return 0 for success, or the number of errors encountered.
     3659 */
     3660int
     3661interactive_mode(struct mountlist_itself *mountlist,
     3662                 struct raidlist_itself *raidlist)
     3663{
     3664    int retval = 0;
     3665    int res;
     3666    int ptn_errs = 0;
     3667    int fmt_errs = 0;
     3668
     3669    bool done;
     3670    bool restore_all;
     3671
     3672  /** needs malloc **********/
     3673    char *tmp;
     3674    char *fstab_fname;
     3675    char *old_restpath;
     3676
     3677    struct s_node *filelist;
     3678
     3679    /* try to partition and format */
     3680
     3681    log_msg(2, "interactive_mode --- starting (great, assertions OK)");
     3682
     3683    malloc_string(tmp);
     3684    malloc_string(fstab_fname);
     3685    malloc_string(old_restpath);
     3686    assert(bkpinfo != NULL);
     3687    assert(mountlist != NULL);
     3688    assert(raidlist != NULL);
     3689
     3690    log_msg(2, "interactive_mode --- assertions OK");
     3691
     3692    if (g_text_mode) {
     3693        if (!ask_me_yes_or_no
     3694            ("Interactive Mode + textonly = experimental! Proceed anyway?"))
     3695        {
     3696            fatal_error("Wise move.");
     3697        }
     3698    }
     3699
     3700    iamhere("About to load config file");
     3701    get_cfg_file_from_archive_or_bust();
     3702    read_cfg_file_into_bkpinfo(g_mondo_cfg_file);
     3703    iamhere("Done loading config file; resizing ML");
     3704    if (bkpinfo->backup_media_type == nfs) {
     3705        strcpy(tmp, bkpinfo->prefix);
     3706        if (popup_and_get_string
     3707            ("Prefix", "Prefix of your ISO images ?", tmp, MAX_STR_LEN / 4)) {
     3708            strcpy(bkpinfo->prefix, tmp);
     3709            log_msg(1, "Prefix set to %s",bkpinfo->prefix);
     3710        }
     3711    }
     3712   
     3713#ifdef __FreeBSD__
     3714    if (strstr
     3715        (call_program_and_get_last_line_of_output("cat /tmp/cmdline"),
     3716         "noresize"))
     3717#else
     3718    if (strstr
     3719        (call_program_and_get_last_line_of_output("cat /proc/cmdline"),
     3720         "noresize"))
     3721#endif
     3722    {
     3723        log_msg(1, "Not resizing mountlist.");
     3724    } else {
     3725        resize_mountlist_proportionately_to_suit_new_drives(mountlist);
     3726    }
     3727    for (done = FALSE; !done;) {
     3728        iamhere("About to edit mountlist");
     3729        if (g_text_mode) {
     3730            save_mountlist_to_disk(mountlist, g_mountlist_fname);
     3731            sprintf(tmp, "%s %s", find_my_editor(), g_mountlist_fname);
     3732            res = system(tmp);
     3733            load_mountlist(mountlist, g_mountlist_fname);
     3734        } else {
     3735            res = edit_mountlist(g_mountlist_fname, mountlist, raidlist);
     3736        }
     3737        iamhere("Finished editing mountlist");
     3738        if (res) {
     3739            paranoid_MR_finish(1);
     3740        }
     3741        log_msg(2, "Proceeding...");
     3742        save_mountlist_to_disk(mountlist, g_mountlist_fname);
     3743        save_raidlist_to_raidtab(raidlist, RAIDTAB_FNAME);
     3744        mvaddstr_and_log_it(1, 30, "Restoring Interactively");
     3745        if (bkpinfo->differential) {
     3746            log_to_screen("Because this is a differential backup, disk");
     3747            log_to_screen
     3748                (" partitioning and formatting will not take place.");
     3749            done = TRUE;
     3750        } else {
     3751            if (ask_me_yes_or_no
     3752                ("Do you want to erase and partition your hard drives?")) {
     3753                if (partition_table_contains_Compaq_diagnostic_partition
     3754                    (mountlist)) {
     3755                    offer_to_abort_because_Compaq_Proliants_suck();
     3756                    done = TRUE;
     3757                } else {
     3758                    twenty_seconds_til_yikes();
     3759                    g_fprep = fopen("/tmp/prep.sh", "w");
     3760                    ptn_errs = partition_everything(mountlist);
     3761                    if (ptn_errs) {
     3762                        log_to_screen
     3763                            ("Warning. Errors occurred during disk partitioning.");
     3764                    }
     3765
     3766                    fmt_errs = format_everything(mountlist, FALSE, raidlist);
     3767                    if (!fmt_errs) {
     3768                        log_to_screen
     3769                            ("Errors during disk partitioning were handled OK.");
     3770                        log_to_screen
     3771                            ("Partitions were formatted OK despite those errors.");
     3772                        ptn_errs = 0;
     3773                    }
     3774                    if (!ptn_errs && !fmt_errs) {
     3775                        done = TRUE;
     3776                    }
     3777                }
     3778                paranoid_fclose(g_fprep);
     3779            } else {
     3780                mvaddstr_and_log_it(g_currentY++, 0,
     3781                                    "User opted not to partition the devices");
     3782                if (ask_me_yes_or_no
     3783                    ("Do you want to format your hard drives?")) {
     3784                    fmt_errs = format_everything(mountlist, TRUE, raidlist);
     3785                    if (!fmt_errs) {
     3786                        done = TRUE;
     3787                    }
     3788                } else {
     3789                    ptn_errs = fmt_errs = 0;
     3790                    done = TRUE;
     3791                }
     3792            }
     3793            if (fmt_errs) {
     3794                mvaddstr_and_log_it(g_currentY++,
     3795                                    0,
     3796                                    "Errors occurred. Please repartition and format drives manually.");
     3797                done = FALSE;
     3798            }
     3799            if (ptn_errs & !fmt_errs) {
     3800                mvaddstr_and_log_it(g_currentY++,
     3801                                    0,
     3802                                    "Errors occurred during partitioning. Formatting, however, went OK.");
     3803                done = TRUE;
     3804            }
     3805            if (!done) {
     3806                if (!ask_me_yes_or_no("Re-edit the mountlist?")) {
     3807                    retval++;
     3808                    goto end_of_func;
     3809                }
     3810            }
     3811        }
     3812    }
     3813
     3814    /* mount */
     3815    if (mount_all_devices(mountlist, TRUE)) {
     3816        unmount_all_devices(mountlist);
     3817        retval++;
     3818        goto end_of_func;
     3819    }
     3820    /* restore */
     3821    if ((restore_all =
     3822         ask_me_yes_or_no("Do you want me to restore all of your data?")))
     3823    {
     3824        log_msg(1, "Restoring all data");
     3825        retval += restore_everything(NULL);
     3826    } else
     3827        if ((restore_all =
     3828             ask_me_yes_or_no
     3829             ("Do you want me to restore _some_ of your data?"))) {
     3830        strcpy(old_restpath, bkpinfo->restore_path);
     3831        for (done = FALSE; !done;) {
     3832            unlink("/tmp/filelist.full");
     3833            filelist = process_filelist_and_biggielist();
     3834            /* Now you have /tmp/tmpfs/filelist.restore-these and /tmp/tmpfs/biggielist.restore-these;
     3835               the former is a list of regular files; the latter, biggiefiles and imagedevs.
     3836             */
     3837            if (filelist) {
     3838              gotos_suck:
     3839                strcpy(tmp, old_restpath);
     3840// (NB: %s is where your filesystem is mounted now, by default)", MNT_RESTORING);
     3841                if (popup_and_get_string
     3842                    ("Restore path", "Restore files to where?", tmp,
     3843                     MAX_STR_LEN / 4)) {
     3844                    if (!strcmp(tmp, "/")) {
     3845                        if (!ask_me_yes_or_no("Are you sure?")) {
     3846                            goto gotos_suck;
     3847                        }
     3848                        tmp[0] = '\0';  // so we restore to [blank]/file/name :)
     3849                    }
     3850                    strcpy(bkpinfo->restore_path, tmp);
     3851                    log_msg(1, "Restoring subset");
     3852                    retval += restore_everything(filelist);
     3853                    free_filelist(filelist);
     3854                } else {
     3855                    strcpy(bkpinfo->restore_path, old_restpath);
     3856                    free_filelist(filelist);
     3857                }
     3858                if (!ask_me_yes_or_no
     3859                    ("Restore another subset of your backup?")) {
     3860                    done = TRUE;
     3861                }
     3862            } else {
     3863                done = TRUE;
     3864            }
     3865        }
     3866        strcpy(old_restpath, bkpinfo->restore_path);
     3867    } else {
     3868        mvaddstr_and_log_it(g_currentY++,
     3869                            0,
     3870                            "User opted not to restore any data.                                  ");
     3871    }
     3872    if (retval) {
     3873        mvaddstr_and_log_it(g_currentY++,
     3874                            0,
     3875                            "Errors occurred during the restore phase.            ");
     3876    }
     3877
     3878    if (ask_me_yes_or_no("Initialize the boot loader?")) {
     3879        run_boot_loader(TRUE);
     3880    } else {
     3881        mvaddstr_and_log_it(g_currentY++,
     3882                            0,
     3883                            "User opted not to initialize the boot loader.");
     3884    }
     3885
     3886    clean_blkid();
     3887    protect_against_braindead_sysadmins();
     3888    retval += unmount_all_devices(mountlist);
     3889    /*  if (restore_some || restore_all || */
     3890    if (ask_me_yes_or_no
     3891        ("Label/Identify your ext2 and ext3 partitions if necessary?")) {
     3892        mvaddstr_and_log_it(g_currentY, 0,
     3893                            "Using tune2fs to identify your ext2,3 partitions");
     3894        if (does_file_exist("/tmp/fstab.new")) {
     3895            strcpy(fstab_fname, "/tmp/fstab.new");
     3896        } else {
     3897            strcpy(fstab_fname, "/tmp/fstab");
     3898        }
     3899        sprintf(tmp,
     3900                "label-partitions-as-necessary %s < %s >> %s 2>> %s",
     3901                g_mountlist_fname, fstab_fname, MONDO_LOGFILE,
     3902                MONDO_LOGFILE);
     3903        res = system(tmp);
     3904        if (res) {
     3905            log_to_screen
     3906                ("label-partitions-as-necessary returned an error");
     3907            mvaddstr_and_log_it(g_currentY++, 74, "Failed.");
     3908        } else {
     3909            mvaddstr_and_log_it(g_currentY++, 74, "Done.");
     3910        }
     3911        retval += res;
     3912    }
     3913
     3914    iamhere("About to leave interactive_mode()");
     3915    if (retval) {
     3916        mvaddstr_and_log_it(g_currentY++,
     3917                            0,
     3918                            "Warning - errors occurred during the restore phase.");
     3919    }
     3920  end_of_func:
     3921    paranoid_free(tmp);
     3922    paranoid_free(fstab_fname);
     3923    paranoid_free(old_restpath);
     3924    iamhere("Leaving interactive_mode()");
     3925    return (retval);
     3926}
     3927
     3928/**************************************************************************
     3929 *END_INTERACTIVE_MODE                                                    *
     3930 **************************************************************************/
     3931
     3932
     3933
     3934/**
     3935 * Run an arbitrary restore mode (prompt the user), but from ISO images
     3936 * instead of real media.
     3937 * @param mountlist The mountlist containing information about the user's partitions.
     3938 * @param raidlist The raidlist that goes with @p mountlist.
     3939 * @param nuke_me_please If TRUE, we plan to run Nuke Mode.
     3940 * @return 0 for success, or the number of errors encountered.
     3941 */
     3942int
     3943iso_mode(struct mountlist_itself *mountlist,
     3944         struct raidlist_itself *raidlist, bool nuke_me_please)
     3945{
     3946    char c;
     3947    int retval = 0;
     3948
     3949    assert(mountlist != NULL);
     3950    assert(raidlist != NULL);
     3951    if (iso_fiddly_bits(nuke_me_please)) {
     3952        log_msg(1, "iso_mode --- returning w/ error");
     3953        return (1);
     3954    } else {
     3955        c = which_restore_mode();
     3956        if (c == 'I' || c == 'N' || c == 'C') {
     3957            interactively_obtain_media_parameters_from_user(FALSE);
     3958        }
     3959        if (c == 'I') {
     3960            retval += interactive_mode(mountlist, raidlist);
     3961        } else if (c == 'N') {
     3962            retval += nuke_mode(mountlist, raidlist);
     3963        } else if (c == 'C') {
     3964            retval += compare_mode(mountlist, raidlist);
     3965        } else {
     3966            log_to_screen("OK, I shan't restore/compare any files.");
     3967        }
     3968    }
     3969    if (is_this_device_mounted(MNT_CDROM)) {
     3970        paranoid_system("umount " MNT_CDROM);
     3971    }
     3972//  if (! already_mounted)
     3973//    {
     3974    if (system("umount /tmp/isodir 2> /dev/null")) {
     3975        log_to_screen
     3976            ("WARNING - unable to unmount device where the ISO files are stored.");
     3977    }
     3978//    }
     3979    return (retval);
     3980}
     3981
     3982/**************************************************************************
     3983 *END_ISO_MODE                                                            *
     3984 **************************************************************************/
     3985
     3986
     3987/*            MONDO - saving your a$$ since Feb 18th, 2000            */
     3988
     3989
     3990
     3991
     3992/**
     3993 * Restore the user's data automatically (no prompts), after a twenty-second
     3994 * warning period.
     3995 * @param bkpinfo The backup information structure. Most fields are used.
     3996 * @param mountlist The mountlist containing information about the user's partitions.
     3997 * @param raidlist The raidlist that goes with @p mountlist.
     3998 * @return 0 for success, or the number of errors encountered.
     3999 * @warning <b><i>THIS WILL ERASE ALL EXISTING DATA!</i></b>
     4000 */
     4001int
     4002nuke_mode(struct mountlist_itself *mountlist,
     4003          struct raidlist_itself *raidlist)
     4004{
     4005    int retval = 0;
     4006    int res = 0;
     4007    bool boot_loader_installed = FALSE;
     4008  /** malloc **/
     4009    char tmp[MAX_STR_LEN], tmpA[MAX_STR_LEN], tmpB[MAX_STR_LEN],
     4010        tmpC[MAX_STR_LEN];
     4011
     4012    assert(bkpinfo != NULL);
     4013    assert(mountlist != NULL);
     4014    assert(raidlist != NULL);
     4015
     4016    log_msg(2, "nuke_mode --- starting");
     4017
     4018    get_cfg_file_from_archive_or_bust();
     4019    load_mountlist(mountlist, g_mountlist_fname);   // in case read_cfg_file_into_bkpinfo updated the mountlist
     4020#ifdef __FreeBSD__
     4021    if (strstr
     4022        (call_program_and_get_last_line_of_output("cat /tmp/cmdline"),
     4023         "noresize"))
     4024#else
     4025    if (strstr
     4026        (call_program_and_get_last_line_of_output("cat /proc/cmdline"),
     4027         "noresize"))
     4028#endif
     4029    {
     4030        log_msg(2, "Not resizing mountlist.");
     4031    } else {
     4032        resize_mountlist_proportionately_to_suit_new_drives(mountlist);
     4033    }
     4034    if (!evaluate_mountlist(mountlist, tmpA, tmpB, tmpC)) {
     4035        sprintf(tmp,
     4036                "Mountlist analyzed. Result: \"%s %s %s\" Switch to Interactive Mode?",
     4037                tmpA, tmpB, tmpC);
     4038        if (ask_me_yes_or_no(tmp)) {
     4039            retval = interactive_mode(mountlist, raidlist);
     4040            goto after_the_nuke;
     4041        } else {
     4042            fatal_error("Nuke Mode aborted. ");
     4043        }
     4044    }
     4045    save_mountlist_to_disk(mountlist, g_mountlist_fname);
     4046    mvaddstr_and_log_it(1, 30, "Restoring Automatically");
     4047    if (bkpinfo->differential) {
     4048        log_to_screen("Because this is a differential backup, disk");
     4049        log_to_screen("partitioning and formatting will not take place.");
     4050        res = 0;
     4051    } else {
     4052        if (partition_table_contains_Compaq_diagnostic_partition
     4053            (mountlist)) {
     4054            offer_to_abort_because_Compaq_Proliants_suck();
     4055        } else {
     4056            twenty_seconds_til_yikes();
     4057            g_fprep = fopen("/tmp/prep.sh", "w");
     4058#ifdef __FreeBSD__
     4059            if (strstr
     4060                (call_program_and_get_last_line_of_output
     4061                 ("cat /tmp/cmdline"), "nopart"))
     4062#else
     4063            if (strstr
     4064                (call_program_and_get_last_line_of_output
     4065                 ("cat /proc/cmdline"), "nopart"))
     4066#endif
     4067            {
     4068                log_msg(2,
     4069                        "Not partitioning drives due to 'nopart' option.");
     4070                res = 0;
     4071            } else {
     4072                res = partition_everything(mountlist);
     4073                if (res) {
     4074                    log_to_screen
     4075                        ("Warning. Errors occurred during partitioning.");
     4076                    res = 0;
     4077                }
     4078            }
     4079            retval += res;
     4080            if (!res) {
     4081                log_to_screen("Preparing to format your disk(s)");
     4082                sleep(1);
     4083                system("sync");
     4084                log_to_screen("Please wait. This may take a few minutes.");
     4085                res += format_everything(mountlist, FALSE, raidlist);
     4086            }
     4087            paranoid_fclose(g_fprep);
     4088        }
     4089    }
     4090    retval += res;
     4091    if (res) {
     4092        mvaddstr_and_log_it(g_currentY++,
     4093                            0,
     4094                            "Failed to partition and/or format your hard drives.");
     4095
     4096        if (ask_me_yes_or_no("Try in interactive mode instead?")) {
     4097            retval = interactive_mode(mountlist, raidlist);
     4098            goto after_the_nuke;
     4099        } else
     4100            if (!ask_me_yes_or_no
     4101                ("Would you like to try to proceed anyway?")) {
     4102            return (retval);
     4103        }
     4104    }
     4105    retval = mount_all_devices(mountlist, TRUE);
     4106    if (retval) {
     4107        unmount_all_devices(mountlist);
     4108        log_to_screen
     4109            ("Unable to mount all partitions. Sorry, I cannot proceed.");
     4110        return (retval);
     4111    }
     4112    iamhere("Restoring everything");
     4113    retval += restore_everything(NULL);
     4114    if (!run_boot_loader(FALSE)) {
     4115        log_msg(1,
     4116                "Great! Boot loader was installed. No need for msg at end.");
     4117        boot_loader_installed = TRUE;
     4118    }
     4119    clean_blkid();
     4120    protect_against_braindead_sysadmins();
     4121    retval += unmount_all_devices(mountlist);
     4122    mvaddstr_and_log_it(g_currentY,
     4123                        0,
     4124                        "Using tune2fs to identify your ext2,3 partitions");
     4125
     4126    sprintf(tmp, "label-partitions-as-necessary %s < /tmp/fstab",
     4127            g_mountlist_fname);
     4128    res = run_program_and_log_output(tmp, TRUE);
     4129    if (res) {
     4130        log_to_screen("label-partitions-as-necessary returned an error");
     4131        mvaddstr_and_log_it(g_currentY++, 74, "Failed.");
     4132    } else {
     4133        mvaddstr_and_log_it(g_currentY++, 74, "Done.");
     4134    }
     4135    retval += res;
     4136
     4137  after_the_nuke:
     4138    if (retval) {
     4139        log_to_screen("Errors occurred during the nuke phase.");
     4140    } else if (strstr(call_program_and_get_last_line_of_output("cat /proc/cmdline"), "RESTORE")) {
     4141        log_to_screen
     4142            ("PC was restored successfully. Thank you for using Mondo Rescue.");
     4143        log_to_screen
     4144            ("Please visit our website at http://www.mondorescue.org for more information.");
     4145    } else {
     4146        strcpy(tmp,"Mondo has restored your system.\n\nPlease wait for the command prompt. Then remove the backup media and reboot.\n\nPlease visit our website at http://www.mondorescue.org for more information.");
     4147            popup_and_OK(tmp);
     4148        log_to_screen
     4149          ("Mondo has restored your system. Please wait for the command prompt.");
     4150        log_to_screen
     4151            ("Then remove the backup media and reboot.");
     4152        log_to_screen
     4153            ("Please visit our website at http://www.mondorescue.org for more information.");
     4154    }
     4155    g_I_have_just_nuked = TRUE;
     4156/*
     4157  if (!boot_loader_installed && !does_file_exist(DO_MBR_PLEASE))
     4158    {
     4159      log_to_screen("PLEASE RUN 'mondorestore --mbr' NOW TO INITIALIZE YOUR BOOT SECTOR");
     4160      write_one_liner_data_file(DO_MBR_PLEASE, "mondorestore --mbr");
     4161    }
     4162*/
     4163    return (retval);
     4164}
     4165
     4166/**************************************************************************
     4167 *END_NUKE_MODE                                                           *
     4168 **************************************************************************/
     4169
     4170
     4171
     4172/**
     4173 * Restore the user's data (or a subset of it) to the live filesystem.
     4174 * This should not be called if we're booted from CD!
     4175 * @param bkpinfo The backup information structure. Most fields are used.
     4176 * @return 0 for success, or the number of errors encountered.
     4177 */
     4178int restore_to_live_filesystem()
     4179{
     4180    int retval = 0;
     4181
     4182  /** malloc **/
     4183    char *old_restpath;
     4184
     4185    struct mountlist_itself *mountlist;
     4186//  static
     4187    struct raidlist_itself *raidlist;
     4188    struct s_node *filelist;
     4189
     4190    log_msg(1, "restore_to_live_filesystem() - starting");
     4191    assert(bkpinfo != NULL);
     4192    malloc_string(old_restpath);
     4193    mountlist = malloc(sizeof(struct mountlist_itself));
     4194    raidlist = malloc(sizeof(struct raidlist_itself));
     4195    if (!mountlist || !raidlist) {
     4196        fatal_error("Cannot malloc() mountlist and/or raidlist");
     4197    }
     4198
     4199    strcpy(bkpinfo->restore_path, "/");
     4200    if (!g_restoring_live_from_cd && !g_restoring_live_from_nfs) {
     4201        popup_and_OK
     4202            ("Please insert tape/CD/USB Key, then hit 'OK' to continue.");
     4203        sleep(1);
     4204    }
     4205    if (!g_restoring_live_from_nfs) {
     4206        interactively_obtain_media_parameters_from_user(FALSE);
     4207    }
     4208    log_msg(2, "bkpinfo->media_device = %s", bkpinfo->media_device);
     4209    if (!bkpinfo->media_device[0]) {
     4210        log_msg(2, "Warning - failed to find media dev");
     4211    }
     4212
     4213
     4214    log_msg(2, "bkpinfo->isodir = %s", bkpinfo->isodir);
     4215
     4216    open_evalcall_form("Thinking...");
     4217
     4218    get_cfg_file_from_archive_or_bust();
     4219    read_cfg_file_into_bkpinfo(g_mondo_cfg_file);
     4220    load_mountlist(mountlist, g_mountlist_fname);   // in case read_cfg_file_into_bkpinfo
     4221
     4222    close_evalcall_form();
     4223    retval = load_mountlist(mountlist, g_mountlist_fname);
     4224    load_raidtab_into_raidlist(raidlist, RAIDTAB_FNAME);
     4225
     4226    if (!g_restoring_live_from_nfs && (filelist = process_filelist_and_biggielist())) {
     4227        save_filelist(filelist, "/tmp/selected-files.txt");
     4228        strcpy(old_restpath, bkpinfo->restore_path);
     4229        if (popup_and_get_string("Restore path",
     4230                                 "Restore files to where? )",
     4231                                 bkpinfo->restore_path, MAX_STR_LEN / 4)) {
     4232            iamhere("Restoring everything");
     4233            retval += restore_everything(filelist);
     4234            free_filelist(filelist);
     4235            strcpy(bkpinfo->restore_path, old_restpath);
     4236        } else {
     4237            free_filelist(filelist);
     4238        }
     4239        strcpy(bkpinfo->restore_path, old_restpath);
     4240    } else {
     4241        retval += restore_everything(NULL);
     4242    }
     4243    if (IS_THIS_A_STREAMING_BACKUP(bkpinfo->backup_media_type)) {
     4244        log_msg(2,
     4245                "Tape : I don't need to unmount or eject the CD-ROM.");
     4246    } else {
     4247        run_program_and_log_output("umount " MNT_CDROM, FALSE);
     4248        if (!bkpinfo->please_dont_eject) {
     4249            eject_device(bkpinfo->media_device);
     4250        }
     4251    }
     4252    run_program_and_log_output("umount " MNT_CDROM, FALSE);
     4253    if (!bkpinfo->please_dont_eject) {
     4254        eject_device(bkpinfo->media_device);
     4255    }
     4256    paranoid_free(old_restpath);
     4257    free(mountlist);
     4258    free(raidlist);
     4259    return (retval);
     4260}
     4261
     4262/**************************************************************************
     4263 *END_RESTORE_TO_LIVE_FILESYSTEM                                          *
     4264 **************************************************************************/
     4265
     4266/* @} - end of restoreGroup */
     4267
     4268
     4269#include <utime.h>
     4270/**
     4271 * @addtogroup LLrestoreGroup
     4272 * @{
     4273 */
     4274/**
     4275 * Restore biggiefile @p bigfileno from the currently mounted CD.
     4276 * @param bkpinfo The backup information structure. Fields used:
     4277 * - @c bkpinfo->backup_media_type
     4278 * - @c bkpinfo->restore_path
     4279 * @param bigfileno The biggiefile number (starting from 0) to restore.
     4280 * @param filelist The node structure containing the list of files to restore.
     4281 * If the biggiefile is not in this list, it will be skipped (return value will
     4282 * still indicate success).
     4283 * @return 0 for success (or skip), nonzero for failure.
     4284 */
     4285int
     4286restore_a_biggiefile_from_CD(long bigfileno,
     4287                             struct s_node *filelist,
     4288                             char *pathname_of_last_file_restored)
     4289{
     4290    FILE *fin;
     4291    FILE *fout;
     4292    FILE *fbzip2;
     4293
     4294  /** malloc ***/
     4295    char *checksum, *outfile_fname, *tmp, *bzip2_command,
     4296        *ntfsprog_command, *suffix, *sz_devfile;
     4297    char *bigblk;
     4298    char *p;
     4299    int retval = 0;
     4300    int finished = FALSE;
     4301    long sliceno;
     4302    long siz;
     4303    char ntfsprog_fifo[MAX_STR_LEN];
     4304    char *file_to_openout = NULL;
     4305    struct s_filename_and_lstat_info biggiestruct;
     4306    struct utimbuf the_utime_buf, *ubuf;
     4307    bool use_ntfsprog_hack = FALSE;
     4308    pid_t pid;
     4309    int res = 0;
     4310    int old_loglevel;
     4311    char sz_msg[MAX_STR_LEN];
     4312    struct s_node *node;
     4313
     4314    old_loglevel = g_loglevel;
     4315    ubuf = &the_utime_buf;
     4316    assert(bkpinfo != NULL);
     4317
     4318    malloc_string(checksum);
     4319    malloc_string(outfile_fname);
     4320    malloc_string(tmp);
     4321    malloc_string(bzip2_command);
     4322    malloc_string(ntfsprog_command);
     4323    malloc_string(suffix);
     4324    malloc_string(sz_devfile);
     4325
     4326    pathname_of_last_file_restored[0] = '\0';
     4327    if (!(bigblk = malloc(TAPE_BLOCK_SIZE))) {
     4328        fatal_error("Cannot malloc bigblk");
     4329    }
     4330
     4331    if (!(fin = fopen(slice_fname(bigfileno, 0, ARCHIVES_PATH, ""), "r"))) {
     4332        log_to_screen("Cannot even open bigfile's info file");
     4333        return (1);
     4334    }
     4335
     4336    memset((void *) &biggiestruct, 0, sizeof(biggiestruct));
     4337    if (fread((void *) &biggiestruct, 1, sizeof(biggiestruct), fin) <
     4338        sizeof(biggiestruct)) {
     4339        log_msg(2, "Warning - unable to get biggiestruct of bigfile #%d",
     4340                bigfileno + 1);
     4341    }
     4342    paranoid_fclose(fin);
     4343
     4344    strcpy(checksum, biggiestruct.checksum);
     4345
     4346    if (!checksum[0]) {
     4347        sprintf(tmp, "Warning - bigfile %ld does not have a checksum",
     4348                bigfileno + 1);
     4349        log_msg(3, tmp);
     4350        p = checksum;
     4351    }
     4352
     4353    if (!strncmp(biggiestruct.filename, "/dev/", 5))    // Whether NTFS or not :)
     4354    {
     4355        strcpy(outfile_fname, biggiestruct.filename);
     4356    } else {
     4357        sprintf(outfile_fname, "%s/%s", bkpinfo->restore_path,
     4358                biggiestruct.filename);
     4359    }
     4360
     4361    /* skip file if we have a selective restore subset & it doesn't match */
     4362    if (filelist != NULL) {
     4363        node = find_string_at_node(filelist, biggiestruct.filename);
     4364        if (!node) {
     4365            log_msg(0, "Skipping %s (name isn't in filelist)",
     4366                    biggiestruct.filename);
     4367            pathname_of_last_file_restored[0] = '\0';
     4368            return (0);
     4369        } else if (!(node->selected)) {
     4370            log_msg(1, "Skipping %s (name isn't in biggielist subset)",
     4371                    biggiestruct.filename);
     4372            pathname_of_last_file_restored[0] = '\0';
     4373            return (0);
     4374        }
     4375    }
     4376    /* otherwise, continue */
     4377
     4378    log_msg(1, "DEFINITELY restoring %s", biggiestruct.filename);
     4379    if (biggiestruct.use_ntfsprog) {
     4380        if (strncmp(biggiestruct.filename, "/dev/", 5)) {
     4381            log_msg(1,
     4382                    "I was in error when I set biggiestruct.use_ntfsprog to TRUE.");
     4383            log_msg(1, "%s isn't even in /dev", biggiestruct.filename);
     4384            biggiestruct.use_ntfsprog = FALSE;
     4385        }
     4386    }
     4387
     4388    if (biggiestruct.use_ntfsprog)  // if it's an NTFS device
     4389//  if (!strncmp ( biggiestruct.filename, "/dev/", 5))
     4390    {
     4391        g_loglevel = 4;
     4392        use_ntfsprog_hack = TRUE;
     4393        log_msg(2,
     4394                "Calling ntfsclone in background because %s is an NTFS /dev entry",
     4395                outfile_fname);
     4396        sprintf(sz_devfile, "/tmp/%d.%d.000", (int) (random() % 32768),
     4397                (int) (random() % 32768));
     4398        mkfifo(sz_devfile, 0x770);
     4399        strcpy(ntfsprog_fifo, sz_devfile);
     4400        file_to_openout = ntfsprog_fifo;
     4401        switch (pid = fork()) {
     4402        case -1:
     4403            fatal_error("Fork failure");
     4404        case 0:
     4405            log_msg(3,
     4406                    "CHILD - fip - calling feed_outfrom_ntfsprog(%s, %s)",
     4407                    biggiestruct.filename, ntfsprog_fifo);
     4408            res =
     4409                feed_outfrom_ntfsprog(biggiestruct.filename,
     4410                                       ntfsprog_fifo);
     4411//          log_msg(3, "CHILD - fip - exiting");
     4412            exit(res);
     4413            break;
     4414        default:
     4415            log_msg(3,
     4416                    "feed_into_ntfsprog() called in background --- pid=%ld",
     4417                    (long int) (pid));
     4418        }
     4419    } else {
     4420        use_ntfsprog_hack = FALSE;
     4421        ntfsprog_fifo[0] = '\0';
     4422        file_to_openout = outfile_fname;
     4423        if (!does_file_exist(outfile_fname))    // yes, it looks weird with the '!' but it's correct that way
     4424        {
     4425            make_hole_for_file(outfile_fname);
     4426        }
     4427    }
     4428
     4429    sprintf(tmp, "Reassembling big file %ld (%s)", bigfileno + 1,
     4430            outfile_fname);
     4431    log_msg(2, tmp);
     4432
     4433    /*
     4434       last slice is zero-length and uncompressed; when we find it, we stop.
     4435       We DON'T wait until there are no more slices; if we did that,
     4436       We might stop at end of CD, not at last slice (which is 0-len and uncompd)
     4437     */
     4438
     4439    strncpy(pathname_of_last_file_restored, biggiestruct.filename,
     4440            MAX_STR_LEN - 1);
     4441    pathname_of_last_file_restored[MAX_STR_LEN - 1] = '\0';
     4442
     4443    log_msg(3, "file_to_openout = %s", file_to_openout);
     4444    if (!(fout = fopen(file_to_openout, "w"))) {
     4445        log_to_screen("Cannot openout outfile_fname - hard disk full?");
     4446        return (1);
     4447    }
     4448    log_msg(3, "Opened out to %s", outfile_fname);  // CD/DVD --> mondorestore --> ntfsclone --> hard disk itself
     4449
     4450    for (sliceno = 1, finished = FALSE; !finished;) {
     4451        if (!does_file_exist
     4452            (slice_fname(bigfileno, sliceno, ARCHIVES_PATH, ""))
     4453            &&
     4454            !does_file_exist(slice_fname
     4455                             (bigfileno, sliceno, ARCHIVES_PATH, "lzo"))
     4456            &&
     4457            !does_file_exist(slice_fname
     4458                             (bigfileno, sliceno, ARCHIVES_PATH, "gz"))
     4459            &&
     4460            !does_file_exist(slice_fname
     4461                             (bigfileno, sliceno, ARCHIVES_PATH, "bz2"))) {
     4462            log_msg(3,
     4463                    "Cannot find a data slice or terminator slice on CD %d",
     4464                    g_current_media_number);
     4465            g_current_media_number++;
     4466            sprintf(tmp,
     4467                    "Asking for %s #%d so that I may read slice #%ld\n",
     4468                    media_descriptor_string(bkpinfo->backup_media_type),
     4469                    g_current_media_number, sliceno);
     4470            log_msg(2, tmp);
     4471            sprintf(tmp, "Restoring from %s #%d",
     4472                    media_descriptor_string(bkpinfo->backup_media_type),
     4473                    g_current_media_number);
     4474            log_to_screen(tmp);
     4475            insist_on_this_cd_number(g_current_media_number);
     4476            log_to_screen("Continuing to restore.");
     4477        } else {
     4478            strcpy(tmp,
     4479                   slice_fname(bigfileno, sliceno, ARCHIVES_PATH, ""));
     4480            if (does_file_exist(tmp) && length_of_file(tmp) == 0) {
     4481                log_msg(2,
     4482                        "End of bigfile # %ld (slice %ld is the terminator)",
     4483                        bigfileno + 1, sliceno);
     4484                finished = TRUE;
     4485                continue;
     4486            } else {
     4487                if (does_file_exist
     4488                    (slice_fname
     4489                     (bigfileno, sliceno, ARCHIVES_PATH, "lzo"))) {
     4490                    strcpy(bzip2_command, "lzop");
     4491                    strcpy(suffix, "lzo");
     4492                } else
     4493                    if (does_file_exist
     4494                        (slice_fname
     4495                         (bigfileno, sliceno, ARCHIVES_PATH, "gz"))) {
     4496                    strcpy(bzip2_command, "gzip");
     4497                    strcpy(suffix, "gz");
     4498                } else
     4499                    if (does_file_exist
     4500                        (slice_fname
     4501                         (bigfileno, sliceno, ARCHIVES_PATH, "bz2"))) {
     4502                    strcpy(bzip2_command, "bzip2");
     4503                    strcpy(suffix, "bz2");
     4504                } else
     4505                    if (does_file_exist
     4506                        (slice_fname
     4507                         (bigfileno, sliceno, ARCHIVES_PATH, ""))) {
     4508                    strcpy(bzip2_command, "");
     4509                    strcpy(suffix, "");
     4510                } else {
     4511                    log_to_screen("OK, that's pretty fsck0red...");
     4512                    return (1);
     4513                }
     4514            }
     4515            if (bzip2_command[0] != '\0') {
     4516                sprintf(bzip2_command + strlen(bzip2_command),
     4517                        " -dc %s 2>> %s",
     4518                        slice_fname(bigfileno, sliceno, ARCHIVES_PATH,
     4519                                    suffix), MONDO_LOGFILE);
     4520            } else {
     4521                sprintf(bzip2_command, "cat %s 2>> %s",
     4522                        slice_fname(bigfileno, sliceno, ARCHIVES_PATH,
     4523                                    suffix), MONDO_LOGFILE);
     4524            }
     4525            sprintf(tmp, "Working on %s #%d, file #%ld, slice #%ld    ",
     4526                    media_descriptor_string(bkpinfo->backup_media_type),
     4527                    g_current_media_number, bigfileno + 1, sliceno);
     4528            log_msg(2, tmp);
     4529
     4530            if (!g_text_mode) {
     4531                newtDrawRootText(0, g_noof_rows - 2, tmp);
     4532                newtRefresh();
     4533                strip_spaces(tmp);
     4534                update_progress_form(tmp);
     4535            }
     4536            if (!(fbzip2 = popen(bzip2_command, "r"))) {
     4537                fatal_error("Can't run popen command");
     4538            }
     4539            while (!feof(fbzip2)) {
     4540                siz = fread(bigblk, 1, TAPE_BLOCK_SIZE, fbzip2);
     4541                if (siz > 0) {
     4542                    sprintf(sz_msg, "Read %ld from fbzip2", siz);
     4543                    siz = fwrite(bigblk, 1, siz, fout);
     4544                    sprintf(sz_msg + strlen(sz_msg),
     4545                            "; written %ld to fout", siz);
     4546//        log_msg(2. sz_msg);
     4547                }
     4548            }
     4549            paranoid_pclose(fbzip2);
     4550
     4551
     4552            sliceno++;
     4553            g_current_progress++;
     4554        }
     4555    }
     4556/*
     4557  memset(bigblk, TAPE_BLOCK_SIZE, 1); // This all looks very fishy...
     4558  fwrite( bigblk, 1, TAPE_BLOCK_SIZE, fout);
     4559  fwrite( bigblk, 1, TAPE_BLOCK_SIZE, fout);
     4560  fwrite( bigblk, 1, TAPE_BLOCK_SIZE, fout);
     4561  fwrite( bigblk, 1, TAPE_BLOCK_SIZE, fout);
     4562*/
     4563    paranoid_fclose(fout);
     4564    g_loglevel = old_loglevel;
     4565
     4566    if (use_ntfsprog_hack) {
     4567        log_msg(3, "Waiting for ntfsclone to finish");
     4568        sprintf(tmp,
     4569                " ps | grep \" ntfsclone \" | grep -v grep > /dev/null 2> /dev/null");
     4570        while (system(tmp) == 0) {
     4571            sleep(1);
     4572        }
     4573        log_it("OK, ntfsclone has really finished");
     4574    }
     4575
     4576    if (strcmp(outfile_fname, "/dev/null")) {
     4577        chown(outfile_fname, biggiestruct.properties.st_uid,
     4578              biggiestruct.properties.st_gid);
     4579        chmod(outfile_fname, biggiestruct.properties.st_mode);
     4580        ubuf->actime = biggiestruct.properties.st_atime;
     4581        ubuf->modtime = biggiestruct.properties.st_mtime;
     4582        utime(outfile_fname, ubuf);
     4583    }
     4584    paranoid_free(bigblk);
     4585    paranoid_free(checksum);
     4586    paranoid_free(outfile_fname);
     4587    paranoid_free(tmp);
     4588    paranoid_free(bzip2_command);
     4589    paranoid_free(ntfsprog_command);
     4590    paranoid_free(suffix);
     4591    paranoid_free(sz_devfile);
     4592
     4593    return (retval);
     4594}
     4595
     4596/**************************************************************************
     4597 *END_ RESTORE_A_BIGGIEFILE_FROM_CD                                       *
     4598 **************************************************************************/
     4599
     4600
     4601
     4602/**
     4603 * Restore a biggiefile from the currently opened stream.
     4604 * @param bkpinfo The backup information structure. Fields used:
     4605 * - @c bkpinfo->restore_path
     4606 * - @c bkpinfo->zip_exe
     4607 * @param orig_bf_fname The original filename of the biggiefile.
     4608 * @param biggiefile_number The number of the biggiefile (starting from 0).
     4609 * @param orig_checksum Unused.
     4610 * @param biggiefile_size Unused.
     4611 * @param filelist The node structure containing the list of files to be restored.
     4612 * If @p orig_bf_fname is not in the list, it will be ignored.
     4613 * @return 0 for success (or skip), nonzero for failure.
     4614 * @bug orig_checksum and biggiefile_size are unused (except to check that they are non-NULL).
     4615 */
     4616int restore_a_biggiefile_from_stream(char *orig_bf_fname, long biggiefile_number, char *orig_checksum,  //UNUSED
     4617                                     long long biggiefile_size, //UNUSED
     4618                                     struct s_node *filelist,
     4619                                     int use_ntfsprog,
     4620                                     char *pathname_of_last_file_restored)
     4621{
     4622    FILE *pout;
     4623    FILE *fin;
     4624
     4625  /** mallocs ********/
     4626    char *tmp;
     4627    char *command;
     4628    char *outfile_fname;
     4629    char *ntfsprog_command;
     4630    char *sz_devfile;
     4631    char *ntfsprog_fifo;
     4632    char *file_to_openout = NULL;
     4633
     4634    struct s_node *node;
     4635
     4636    int old_loglevel;
     4637    long current_slice_number = 0;
     4638    int retval = 0;
     4639    int res = 0;
     4640    int ctrl_chr = '\0';
     4641    long long slice_siz;
     4642    bool dummy_restore = FALSE;
     4643    bool use_ntfsprog_hack = FALSE;
     4644    pid_t pid;
     4645    struct s_filename_and_lstat_info biggiestruct;
     4646    struct utimbuf the_utime_buf, *ubuf;
     4647    ubuf = &the_utime_buf;
     4648
     4649    malloc_string(tmp);
     4650    malloc_string(ntfsprog_fifo);
     4651    malloc_string(outfile_fname);
     4652    malloc_string(command);
     4653    malloc_string(sz_devfile);
     4654    malloc_string(ntfsprog_command);
     4655    old_loglevel = g_loglevel;
     4656    assert(bkpinfo != NULL);
     4657    assert(orig_bf_fname != NULL);
     4658    assert(orig_checksum != NULL);
     4659
     4660    pathname_of_last_file_restored[0] = '\0';
     4661    if (use_ntfsprog == BLK_START_A_PIHBIGGIE) {
     4662        use_ntfsprog = 1;
     4663        log_msg(1, "%s --- pih=YES", orig_bf_fname);
     4664    } else if (use_ntfsprog == BLK_START_A_NORMBIGGIE) {
     4665        use_ntfsprog = 0;
     4666        log_msg(1, "%s --- pih=NO", orig_bf_fname);
     4667    } else {
     4668        use_ntfsprog = 0;
     4669        log_msg(1, "%s --- pih=NO (weird marker though)", orig_bf_fname);
     4670    }
     4671
     4672    strncpy(pathname_of_last_file_restored, orig_bf_fname,
     4673            MAX_STR_LEN - 1);
     4674    pathname_of_last_file_restored[MAX_STR_LEN - 1] = '\0';
     4675
     4676    /* open out to biggiefile to be restored (or /dev/null if biggiefile is not to be restored) */
     4677
     4678    if (filelist != NULL) {
     4679        node = find_string_at_node(filelist, orig_bf_fname);
     4680        if (!node) {
     4681            dummy_restore = TRUE;
     4682            log_msg(1,
     4683                    "Skipping big file %ld (%s) - not in biggielist subset",
     4684                    biggiefile_number + 1, orig_bf_fname);
     4685            pathname_of_last_file_restored[0] = '\0';
     4686        } else if (!(node->selected)) {
     4687            dummy_restore = TRUE;
     4688            log_msg(1, "Skipping %s (name isn't in biggielist subset)",
     4689                    orig_bf_fname);
     4690            pathname_of_last_file_restored[0] = '\0';
     4691        }
     4692    }
     4693
     4694    if (use_ntfsprog) {
     4695        if (strncmp(orig_bf_fname, "/dev/", 5)) {
     4696            log_msg(1,
     4697                    "I was in error when I set use_ntfsprog to TRUE.");
     4698            log_msg(1, "%s isn't even in /dev", orig_bf_fname);
     4699            use_ntfsprog = FALSE;
     4700        }
     4701    }
     4702
     4703    if (use_ntfsprog) {
     4704        g_loglevel = 4;
     4705        strcpy(outfile_fname, orig_bf_fname);
     4706        use_ntfsprog_hack = TRUE;
     4707        log_msg(2,
     4708                "Calling ntfsclone in background because %s is a /dev entry",
     4709                outfile_fname);
     4710        sprintf(sz_devfile, "%s/%d.%d.000",
     4711                bkpinfo->tmpdir,
     4712                (int) (random() % 32768),
     4713                (int) (random() % 32768));
     4714        mkfifo(sz_devfile, 0x770);
     4715        strcpy(ntfsprog_fifo, sz_devfile);
     4716        file_to_openout = ntfsprog_fifo;
     4717        switch (pid = fork()) {
     4718        case -1:
     4719            fatal_error("Fork failure");
     4720        case 0:
     4721            log_msg(3,
     4722                    "CHILD - fip - calling feed_outfrom_ntfsprog(%s, %s)",
     4723                    outfile_fname, ntfsprog_fifo);
     4724            res =
     4725                feed_outfrom_ntfsprog(outfile_fname, ntfsprog_fifo);
     4726//          log_msg(3, "CHILD - fip - exiting");
     4727            exit(res);
     4728            break;
     4729        default:
     4730            log_msg(3,
     4731                    "feed_into_ntfsprog() called in background --- pid=%ld",
     4732                    (long int) (pid));
     4733        }
     4734    } else {
     4735        if (!strncmp(orig_bf_fname, "/dev/", 5))    // non-NTFS partition
     4736        {
     4737            strcpy(outfile_fname, orig_bf_fname);
     4738        } else                  // biggiefile
     4739        {
     4740            sprintf(outfile_fname, "%s/%s", bkpinfo->restore_path,
     4741                    orig_bf_fname);
     4742        }
     4743        use_ntfsprog_hack = FALSE;
     4744        ntfsprog_fifo[0] = '\0';
     4745        file_to_openout = outfile_fname;
     4746        if (!does_file_exist(outfile_fname))    // yes, it looks weird with the '!' but it's correct that way
     4747        {
     4748            make_hole_for_file(outfile_fname);
     4749        }
     4750        sprintf(tmp, "Reassembling big file %ld (%s)",
     4751                biggiefile_number + 1, orig_bf_fname);
     4752        log_msg(2, tmp);
     4753    }
     4754
     4755    if (dummy_restore) {
     4756        sprintf(outfile_fname, "/dev/null");
     4757    }
     4758
     4759    if (!bkpinfo->zip_exe[0]) {
     4760        sprintf(command, "cat > \"%s\"", file_to_openout);
     4761    } else {
     4762        sprintf(command, "%s -dc > \"%s\" 2>> %s", bkpinfo->zip_exe,
     4763                file_to_openout, MONDO_LOGFILE);
     4764        if (strcmp(bkpinfo->zip_exe, "gzip") == 0) {
     4765            /* Ignore SIGPIPE for gzip as it causes errors on big files
     4766             * Cf: http://trac.mondorescue.org/ticket/244
     4767             */
     4768            signal(SIGPIPE,SIG_IGN);
     4769        }
     4770    }
     4771    sprintf(tmp, "Pipe command = '%s'", command);
     4772    log_msg(3, tmp);
     4773
     4774    /* restore biggiefile, one slice at a time */
     4775    if (!(pout = popen(command, "w"))) {
     4776        fatal_error("Cannot pipe out");
     4777    }
     4778    for (res = read_header_block_from_stream(&slice_siz, tmp, &ctrl_chr);
     4779         ctrl_chr != BLK_STOP_A_BIGGIE;
     4780         res = read_header_block_from_stream(&slice_siz, tmp, &ctrl_chr)) {
     4781        if (ctrl_chr != BLK_START_AN_AFIO_OR_SLICE) {
     4782            wrong_marker(BLK_START_AN_AFIO_OR_SLICE, ctrl_chr);
     4783        }
     4784        sprintf(tmp, "Working on file #%ld, slice #%ld    ",
     4785                biggiefile_number + 1, current_slice_number);
     4786        log_msg(2, tmp);
     4787        if (!g_text_mode) {
     4788            newtDrawRootText(0, g_noof_rows - 2, tmp);
     4789            newtRefresh();
     4790        }
     4791        strip_spaces(tmp);
     4792        update_progress_form(tmp);
     4793        if (current_slice_number == 0) {
     4794            res =
     4795                read_file_from_stream_to_file("/tmp/biggie-blah.txt",
     4796                                              slice_siz);
     4797            if (!(fin = fopen("/tmp/biggie-blah.txt", "r"))) {
     4798                log_OS_error("blah blah");
     4799            } else {
     4800                if (fread
     4801                    ((void *) &biggiestruct, 1, sizeof(biggiestruct),
     4802                     fin) < sizeof(biggiestruct)) {
     4803                    log_msg(2,
     4804                            "Warning - unable to get biggiestruct of bigfile #%d",
     4805                            biggiefile_number + 1);
     4806                }
     4807                paranoid_fclose(fin);
     4808            }
     4809        } else {
     4810            res =
     4811                read_file_from_stream_to_stream(pout, slice_siz);
     4812        }
     4813        retval += res;
     4814        res = read_header_block_from_stream(&slice_siz, tmp, &ctrl_chr);
     4815        if (ctrl_chr != BLK_STOP_AN_AFIO_OR_SLICE) {
     4816            wrong_marker(BLK_STOP_AN_AFIO_OR_SLICE, ctrl_chr);
     4817        }
     4818        current_slice_number++;
     4819        g_current_progress++;
     4820    }
     4821    paranoid_pclose(pout);
     4822
     4823    if (bkpinfo->zip_exe[0]) {
     4824        if (strcmp(bkpinfo->zip_exe, "gzip") == 0) {
     4825            /* Re-enable SIGPIPE for gzip
     4826             */
     4827            signal(SIGPIPE, terminate_daemon);
     4828        }
     4829    }
     4830
     4831    log_msg(1, "pathname_of_last_file_restored is now %s",
     4832            pathname_of_last_file_restored);
     4833
     4834    if (use_ntfsprog_hack) {
     4835        log_msg(3, "Waiting for ntfsclone to finish");
     4836        sprintf(tmp,
     4837                " ps | grep \" ntfsclone \" | grep -v grep > /dev/null 2> /dev/null");
     4838        while (system(tmp) == 0) {
     4839            sleep(1);
     4840        }
     4841        log_msg(3, "OK, ntfsclone has really finished");
     4842    }
     4843
     4844    log_msg(3, "biggiestruct.filename = %s", biggiestruct.filename);
     4845    log_msg(3, "biggiestruct.checksum = %s", biggiestruct.checksum);
     4846    if (strcmp(outfile_fname, "/dev/null")) {
     4847        chmod(outfile_fname, biggiestruct.properties.st_mode);
     4848        chown(outfile_fname, biggiestruct.properties.st_uid,
     4849              biggiestruct.properties.st_gid);
     4850        ubuf->actime = biggiestruct.properties.st_atime;
     4851        ubuf->modtime = biggiestruct.properties.st_mtime;
     4852        utime(outfile_fname, ubuf);
     4853    }
     4854
     4855    paranoid_free(tmp);
     4856    paranoid_free(outfile_fname);
     4857    paranoid_free(command);
     4858    paranoid_free(ntfsprog_command);
     4859    paranoid_free(sz_devfile);
     4860    paranoid_free(ntfsprog_fifo);
     4861    g_loglevel = old_loglevel;
     4862    return (retval);
     4863}
     4864
     4865/**************************************************************************
     4866 *END_RESTORE_A_BIGGIEFILE_FROM_STREAM                                    *
     4867 **************************************************************************/
     4868
     4869
     4870
     4871/**
     4872 * Restore @p tarball_fname from CD.
     4873 * @param tarball_fname The filename of the tarball to restore (in /mnt/cdrom).
     4874 * This will be used unmodified.
     4875 * @param current_tarball_number The number (starting from 0) of the fileset
     4876 * we're restoring now.
     4877 * @param filelist The node structure containing the list of files to be
     4878 * restored. If no file in the afioball is in this list, afio will still be
     4879 * called, but nothing will be written.
     4880 * @return 0 for success, nonzero for failure.
     4881 */
     4882int
     4883restore_a_tarball_from_CD(char *tarball_fname,
     4884                          long current_tarball_number,
     4885                          struct s_node *filelist)
     4886{
     4887    int retval = 0;
     4888    int res;
     4889    char *p;
     4890
     4891  /** malloc **/
     4892    char *command;
     4893    char *tmp;
     4894    char *filelist_name;
     4895    char *filelist_subset_fname;
     4896    char *executable;
     4897    char *temp_log;
     4898    char screen_message[100];
     4899    long matches = 0;
     4900    bool use_star;
     4901    char *xattr_fname;
     4902    char *acl_fname;
     4903//  char files_to_restore_this_time_fname[MAX_STR_LEN];
     4904
     4905    assert_string_is_neither_NULL_nor_zerolength(tarball_fname);
     4906    malloc_string(command);
     4907    malloc_string(tmp);
     4908    malloc_string(filelist_name);
     4909    malloc_string(filelist_subset_fname);
     4910    malloc_string(executable);
     4911    malloc_string(temp_log);
     4912    malloc_string(xattr_fname);
     4913    malloc_string(acl_fname);
     4914
     4915    log_msg(5, "Entering");
     4916    filelist_subset_fname[0] = '\0';
     4917    use_star = (strstr(tarball_fname, ".star")) ? TRUE : FALSE;
     4918//  sprintf(files_to_restore_this_time_fname, "/tmp/ftrttf.%d.%d", (int)getpid(), (int)random());
     4919    sprintf(command, "mkdir -p %s/tmp", MNT_RESTORING);
     4920    run_program_and_log_output(command, 9);
     4921    sprintf(temp_log, "/tmp/%d.%d", (int) (random() % 32768),
     4922            (int) (random() % 32768));
     4923
     4924    sprintf(filelist_name, MNT_CDROM "/archives/filelist.%ld",
     4925            current_tarball_number);
     4926    if (length_of_file(filelist_name) <= 2) {
     4927        log_msg(2, "There are _zero_ files in filelist '%s'",
     4928                filelist_name);
     4929        log_msg(2,
     4930                "This is a bit silly (ask dev-team to fix mondo_makefilelist, please)");
     4931        log_msg(2,
     4932                "but it's non-critical. It's cosmetic. Don't worry about it.");
     4933        retval = 0;
     4934        goto leave_sub;
     4935    }
     4936    if (count_lines_in_file(filelist_name) <= 0
     4937        || length_of_file(tarball_fname) <= 0) {
     4938        log_msg(3, "length_of_file(%s) = %llu", tarball_fname,
     4939                length_of_file(tarball_fname));
     4940        sprintf(tmp, "Unable to restore fileset #%ld (CD I/O error)",
     4941                current_tarball_number);
     4942        log_to_screen(tmp);
     4943        retval = 1;
     4944        goto leave_sub;
     4945    }
     4946
     4947    if (filelist) {
     4948        sprintf(filelist_subset_fname, "/tmp/filelist-subset-%ld.tmp",
     4949                current_tarball_number);
     4950        if ((matches =
     4951             save_filelist_entries_in_common(filelist_name, filelist,
     4952                                             filelist_subset_fname,
     4953                                             use_star))
     4954            <= 0) {
     4955            sprintf(tmp, "Skipping fileset %ld", current_tarball_number);
     4956            log_msg(1, tmp);
     4957        } else {
     4958            log_msg(3, "Saved fileset %ld's subset to %s",
     4959                    current_tarball_number, filelist_subset_fname);
     4960        }
     4961        sprintf(screen_message, "Tarball #%ld --- %ld matches",
     4962                current_tarball_number, matches);
     4963        log_to_screen(screen_message);
     4964    } else {
     4965        filelist_subset_fname[0] = '\0';
     4966    }
     4967
     4968    if (filelist == NULL || matches > 0) {
     4969        if (g_getfattr) {
     4970            sprintf(xattr_fname, XATTR_LIST_FNAME_RAW_SZ,
     4971                MNT_CDROM "/archives", current_tarball_number);
     4972        }
     4973        if (g_getfacl) {
     4974            sprintf(acl_fname, ACL_LIST_FNAME_RAW_SZ, MNT_CDROM "/archives",
     4975                current_tarball_number);
     4976        }
     4977        if (strstr(tarball_fname, ".bz2")) {
     4978            strcpy(executable, "bzip2");
     4979        } else if (strstr(tarball_fname, ".gz")) {
     4980            strcpy(executable, "gzip");
     4981        } else if (strstr(tarball_fname, ".lzo")) {
     4982            strcpy(executable, "lzop");
     4983        } else {
     4984            executable[0] = '\0';
     4985        }
     4986        if (executable[0]) {
     4987            sprintf(tmp, "which %s > /dev/null 2> /dev/null", executable);
     4988            if (run_program_and_log_output(tmp, FALSE)) {
     4989                log_to_screen
     4990                    ("(compare_a_tarball) Compression program not found - oh no!");
     4991                paranoid_MR_finish(1);
     4992            }
     4993            strcpy(tmp, executable);
     4994            sprintf(executable, "-P %s -Z", tmp);
     4995        }
     4996#ifdef __FreeBSD__
     4997#define BUFSIZE 512
     4998#else
     4999#define BUFSIZE (1024L*1024L)/TAPE_BLOCK_SIZE
     5000#endif
     5001
     5002//      if (strstr(tarball_fname, ".star."))
     5003        if (use_star) {
     5004            sprintf(command,
     5005                    "star -x -force-remove -U " STAR_ACL_SZ
     5006                    " errctl= file=%s", tarball_fname);
     5007            if (strstr(tarball_fname, ".bz2")) {
     5008                strcat(command, " -bz");
     5009            }
     5010        } else {
     5011            if (filelist_subset_fname[0] != '\0') {
     5012                sprintf(command,
     5013                        "afio -i -M 8m -b %ld -c %ld %s -w '%s' %s",
     5014                        TAPE_BLOCK_SIZE,
     5015                        BUFSIZE, executable, filelist_subset_fname,
     5016//             files_to_restore_this_time_fname,
     5017                        tarball_fname);
     5018            } else {
     5019                sprintf(command,
     5020                        "afio -i -b %ld -c %ld -M 8m %s %s",
     5021                        TAPE_BLOCK_SIZE,
     5022                        BUFSIZE, executable, tarball_fname);
     5023            }
     5024        }
     5025#undef BUFSIZE
     5026        sprintf(command + strlen(command), " 2>> %s >> %s", temp_log,
     5027                temp_log);
     5028        log_msg(1, "command = '%s'", command);
     5029        unlink(temp_log);
     5030        res = system(command);
     5031        if (res) {
     5032            p = strstr(command, "-acl ");
     5033            if (p) {
     5034                p[0] = p[1] = p[2] = p[3] = ' ';
     5035                log_msg(1, "new command = '%s'", command);
     5036                res = system(command);
     5037            }
     5038        }
     5039        if (res && length_of_file(temp_log) < 5) {
     5040            res = 0;
     5041        }
     5042
     5043        if (g_getfattr) {
     5044            log_msg(1, "Setting fattr list %s", xattr_fname);
     5045            if (length_of_file(xattr_fname) > 0) {
     5046                res = set_fattr_list(filelist_subset_fname, xattr_fname);
     5047                if (res) {
     5048                    log_to_screen
     5049                        ("Errors occurred while setting extended attributes");
     5050                } else {
     5051                    log_msg(1, "I set xattr OK");
     5052                }
     5053                retval += res;
     5054            }
     5055        }
     5056        if (g_getfacl) {
     5057            log_msg(1, "Setting acl list %s", acl_fname);
     5058            if (length_of_file(acl_fname) > 0) {
     5059                res = set_acl_list(filelist_subset_fname, acl_fname);
     5060                if (res) {
     5061                    log_to_screen
     5062                        ("Errors occurred while setting access control lists");
     5063                } else {
     5064                    log_msg(1, "I set ACL OK");
     5065                }
     5066                retval += res;
     5067            }
     5068        }
     5069        if (retval) {
     5070            sprintf(command, "cat %s >> %s", temp_log, MONDO_LOGFILE);
     5071            system(command);
     5072            log_msg(2, "Errors occurred while processing fileset #%d",
     5073                    current_tarball_number);
     5074        } else {
     5075            log_msg(2, "Fileset #%d processed OK", current_tarball_number);
     5076        }
     5077    }
     5078    if (does_file_exist("/PAUSE")) {
     5079        popup_and_OK
     5080            ("Press ENTER to go on. Delete /PAUSE to stop these pauses.");
     5081    }
     5082    unlink(filelist_subset_fname);
     5083    unlink(xattr_fname);
     5084    unlink(acl_fname);
     5085    unlink(temp_log);
     5086
     5087  leave_sub:
     5088    paranoid_free(command);
     5089    paranoid_free(tmp);
     5090    paranoid_free(filelist_name);
     5091    paranoid_free(filelist_subset_fname);
     5092    paranoid_free(executable);
     5093    paranoid_free(temp_log);
     5094    paranoid_free(xattr_fname);
     5095    paranoid_free(acl_fname);
     5096    log_msg(5, "Leaving");
     5097    return (retval);
     5098}
     5099
     5100/**************************************************************************
     5101 *END_RESTORE_A_TARBALL_FROM_CD                                           *
     5102 **************************************************************************/
     5103
     5104
     5105/**
     5106 * Restore a tarball from the currently opened stream.
     5107 * @param bkpinfo The backup information structure. Fields used:
     5108 * - @c bkpinfo->backup_media_type
     5109 * - @c bkpinfo->media_device
     5110 * - @c bkpinfo->zip_exe
     5111 * @param tarball_fname The filename of the afioball to restore.
     5112 * @param current_tarball_number The number (starting from 0) of the fileset
     5113 * we're restoring now.
     5114 * @param filelist The node structure containing the list of files to be
     5115 * restored. If no file in the afioball is in this list, afio will still be
     5116 * called, but nothing will be written.
     5117 * @param size The size (in @b bytes) of the afioball.
     5118 * @return 0 for success, nonzero for failure.
     5119 */
     5120int
     5121restore_a_tarball_from_stream(char *tarball_fname,
     5122                              long current_tarball_number,
     5123                              struct s_node *filelist,
     5124                              long long size, char *xattr_fname,
     5125                              char *acl_fname)
     5126{
     5127    int retval = 0;
     5128    int res = 0;
     5129
     5130  /** malloc add ***/
     5131    char *tmp;
     5132    char *command;
     5133    char *afio_fname;
     5134    char *filelist_fname;
     5135    char *filelist_subset_fname;
     5136    char *executable;
     5137    long matches = 0;
     5138    bool restore_this_fileset = FALSE;
     5139    bool use_star;
     5140
     5141    assert(bkpinfo != NULL);
     5142    assert_string_is_neither_NULL_nor_zerolength(tarball_fname);
     5143    malloc_string(filelist_subset_fname);
     5144    malloc_string(filelist_fname);
     5145    malloc_string(afio_fname);
     5146    malloc_string(executable);
     5147    malloc_string(command);
     5148    malloc_string(tmp);
     5149    filelist_subset_fname[0] = '\0';
     5150    /* to do it with a file... */
     5151    use_star = (strstr(tarball_fname, ".star")) ? TRUE : FALSE;
     5152    sprintf(tmp,
     5153            "Restoring from fileset #%ld (%ld KB) on %s #%d",
     5154            current_tarball_number, (long) size >> 10,
     5155            media_descriptor_string(bkpinfo->backup_media_type),
     5156            g_current_media_number);
     5157    log_msg(2, tmp);
     5158    run_program_and_log_output("mkdir -p " MNT_RESTORING "/tmp", FALSE);
     5159
     5160  /****************************************************************************
     5161   * Use RAMDISK's /tmp; saves time; oh wait, it's too small                  *
     5162   * Well, pipe from tape to afio, then; oh wait, can't do that either: bug   *
     5163   * in afio or someting; oh darn.. OK, use tmpfs :-)                         *
     5164   ****************************************************************************/
     5165    filelist_fname[0] = filelist_subset_fname[0] = '\0';
     5166    sprintf(afio_fname, "/tmp/tmpfs/archive.tmp.%ld",
     5167            current_tarball_number);
     5168    sprintf(filelist_fname, "%s/filelist.%ld", bkpinfo->tmpdir,
     5169            current_tarball_number);
     5170    sprintf(filelist_subset_fname, "%s/filelist-subset-%ld.tmp",
     5171            bkpinfo->tmpdir, current_tarball_number);
     5172//  sprintf(filelist_fname, "/tmp/tmpfs/temp-filelist.%ld", current_tarball_number);
     5173    res = read_file_from_stream_to_file(afio_fname, size);
     5174    if (strstr(tarball_fname, ".star")) {
     5175        bkpinfo->use_star = TRUE;
     5176    }
     5177    if (res) {
     5178        log_msg(1, "Warning - error reading afioball from tape");
     5179    }
     5180    if (bkpinfo->compression_level == 0) {
     5181        executable[0] = '\0';
     5182    } else {
     5183        if (bkpinfo->use_star) {
     5184            strcpy(executable, " -bz");
     5185        } else {
     5186            sprintf(executable, "-P %s -Z", bkpinfo->zip_exe);
     5187        }
     5188    }
     5189
     5190    if (!filelist)              // if unconditional restore then restore entire fileset
     5191    {
     5192        restore_this_fileset = TRUE;
     5193    } else                      // If restoring selectively then get TOC from tarball
     5194    {
     5195        if (strstr(tarball_fname, ".star.")) {
     5196            use_star = TRUE;
     5197            sprintf(command, "star -t file=%s %s", afio_fname, executable);
     5198        } else {
     5199            use_star = FALSE;
     5200            sprintf(command, "afio -t -M 8m -b %ld %s %s", TAPE_BLOCK_SIZE,
     5201                    executable, afio_fname);
     5202        }
     5203        sprintf(command + strlen(command), " > %s 2>> %s", filelist_fname,
     5204                MONDO_LOGFILE);
     5205        log_msg(1, "command = %s", command);
     5206        if (system(command)) {
     5207            log_msg(4, "Warning - error occurred while retrieving TOC");
     5208        }
     5209        if ((matches =
     5210             save_filelist_entries_in_common(filelist_fname, filelist,
     5211                                             filelist_subset_fname,
     5212                                             use_star))
     5213            <= 0 || length_of_file(filelist_subset_fname) < 2) {
     5214            if (length_of_file(filelist_subset_fname) < 2) {
     5215                log_msg(1, "No matches found in fileset %ld",
     5216                        current_tarball_number);
     5217            }
     5218            sprintf(tmp, "Skipping fileset %ld", current_tarball_number);
     5219            log_msg(2, tmp);
     5220            restore_this_fileset = FALSE;
     5221        } else {
     5222            log_msg(5, "%ld matches. Saved fileset %ld's subset to %s",
     5223                    matches, current_tarball_number,
     5224                    filelist_subset_fname);
     5225            restore_this_fileset = TRUE;
     5226        }
     5227    }
     5228
     5229// Concoct the call to star/afio to restore files
     5230    if (strstr(tarball_fname, ".star."))    // star
     5231    {
     5232        sprintf(command, "star -x file=%s %s", afio_fname, executable);
     5233        if (filelist) {
     5234            sprintf(command + strlen(command), " list=%s",
     5235                    filelist_subset_fname);
     5236        }
     5237    } else                      // afio
     5238    {
     5239        sprintf(command, "afio -i -M 8m -b %ld %s", TAPE_BLOCK_SIZE,
     5240                executable);
     5241        if (filelist) {
     5242            sprintf(command + strlen(command), " -w %s",
     5243                    filelist_subset_fname);
     5244        }
     5245        sprintf(command + strlen(command), " %s", afio_fname);
     5246    }
     5247    sprintf(command + strlen(command), " 2>> %s", MONDO_LOGFILE);
     5248
     5249// Call if IF there are files to restore (selectively/unconditionally)
     5250    if (restore_this_fileset) {
     5251        log_msg(1, "Calling command='%s'", command);
     5252        paranoid_system(command);
     5253
     5254        if (g_getfattr) {
     5255            iamhere("Restoring xattr stuff");
     5256            res = set_fattr_list(filelist_subset_fname, xattr_fname);
     5257            if (res) {
     5258                log_msg(1, "Errors occurred while setting xattr");
     5259            } else {
     5260                log_msg(1, "I set xattr OK");
     5261            }
     5262            retval += res;
     5263        }
     5264
     5265        if (g_getfacl) {
     5266            iamhere("Restoring acl stuff");
     5267            res = set_acl_list(filelist_subset_fname, acl_fname);
     5268            if (res) {
     5269                log_msg(1, "Errors occurred while setting ACL");
     5270            } else {
     5271                log_msg(1, "I set ACL OK");
     5272            }
     5273            retval += res;
     5274        }
     5275
     5276    } else {
     5277        log_msg(1, "NOT CALLING '%s'", command);
     5278    }
     5279
     5280    if (does_file_exist("/PAUSE") && current_tarball_number >= 50) {
     5281        log_to_screen("Paused after set %ld", current_tarball_number);
     5282        popup_and_OK("Pausing. Press ENTER to continue.");
     5283    }
     5284
     5285    unlink(filelist_subset_fname);
     5286    unlink(filelist_fname);
     5287    unlink(afio_fname);
     5288
     5289    paranoid_free(filelist_subset_fname);
     5290    paranoid_free(filelist_fname);
     5291    paranoid_free(afio_fname);
     5292    paranoid_free(command);
     5293    paranoid_free(tmp);
     5294    return (retval);
     5295}
     5296
     5297/**************************************************************************
     5298 *END_RESTORE_A_TARBALL_FROM_STREAM                                       *
     5299 **************************************************************************/
     5300
     5301
     5302
     5303
     5304/**
     5305 * Restore all biggiefiles from all media in this CD backup.
     5306 * The CD with the last afioball should be currently mounted.
     5307 * @param bkpinfo The backup information structure. @c backup_media_type is the
     5308 * only field used in this function.
     5309 * @param filelist The node structure containing the list of files to be
     5310 * restored. If a prospective biggiefile is not in this list, it will be ignored.
     5311 * @return 0 for success, nonzero for failure.
     5312 */
     5313int
     5314restore_all_biggiefiles_from_CD(struct s_node *filelist)
     5315{
     5316    int retval = 0;
     5317    int res = 0;
     5318    long noof_biggiefiles, bigfileno = 0, total_slices;
     5319  /** malloc **/
     5320    char *tmp;
     5321    bool just_changed_cds = FALSE;
     5322    char *xattr_fname;
     5323    char *acl_fname;
     5324    char *biggies_whose_EXATs_we_should_set;    // EXtended ATtributes
     5325    char *pathname_of_last_biggie_restored;
     5326    FILE *fbw = NULL;
     5327
     5328    malloc_string(xattr_fname);
     5329    malloc_string(acl_fname);
     5330    malloc_string(tmp);
     5331    malloc_string(biggies_whose_EXATs_we_should_set);
     5332    malloc_string(pathname_of_last_biggie_restored);
     5333    assert(bkpinfo != NULL);
     5334
     5335    sprintf(biggies_whose_EXATs_we_should_set,
     5336            "%s/biggies-whose-EXATs-we-should-set", bkpinfo->tmpdir);
     5337    if (!(fbw = fopen(biggies_whose_EXATs_we_should_set, "w"))) {
     5338        log_msg(1, "Warning - cannot openout %s",
     5339                biggies_whose_EXATs_we_should_set);
     5340    }
     5341
     5342    read_cfg_var(g_mondo_cfg_file, "total-slices", tmp);
     5343    total_slices = atol(tmp);
     5344    sprintf(tmp, "Reassembling large files      ");
     5345    mvaddstr_and_log_it(g_currentY, 0, tmp);
     5346    if (length_of_file(BIGGIELIST) < 6) {
     5347        log_msg(1, "OK, no biggielist; not restoring biggiefiles");
     5348        return (0);
     5349    }
     5350    noof_biggiefiles = count_lines_in_file(BIGGIELIST);
     5351    if (noof_biggiefiles <= 0) {
     5352        log_msg(2,
     5353                "OK, no biggiefiles in biggielist; not restoring biggiefiles");
     5354        return (0);
     5355    }
     5356    sprintf(tmp, "OK, there are %ld biggiefiles in the archives",
     5357            noof_biggiefiles);
     5358    log_msg(2, tmp);
     5359
     5360    open_progress_form("Reassembling large files",
     5361                       "I am now reassembling all the large files.",
     5362                       "Please wait. This may take some time.",
     5363                       "", total_slices);
     5364    for (bigfileno = 0 ; bigfileno < noof_biggiefiles ;) {
     5365        log_msg(2, "Thinking about restoring bigfile %ld", bigfileno + 1);
     5366        if (!does_file_exist(slice_fname(bigfileno, 0, ARCHIVES_PATH, ""))) {
     5367            log_msg(3,
     5368                    "...but its first slice isn't on this CD. Perhaps this was a selective restore?");
     5369            log_msg(3, "Cannot find bigfile #%ld 's first slice on %s #%d",
     5370                    bigfileno + 1,
     5371                    media_descriptor_string(bkpinfo->backup_media_type),
     5372                    g_current_media_number);
     5373            log_msg(3, "Slicename would have been %s",
     5374                    slice_fname(bigfileno, 0, ARCHIVES_PATH, ""));
     5375            // I'm not positive 'just_changed_cds' is even necessary...
     5376            if (just_changed_cds) {
     5377                just_changed_cds = FALSE;
     5378                log_msg(3,
     5379                        "I'll continue to scan this CD for bigfiles to be restored.");
     5380            } else if (does_file_exist(MNT_CDROM "/archives/NOT-THE-LAST")) {
     5381                insist_on_this_cd_number(++g_current_media_number);
     5382                sprintf(tmp, "Restoring from %s #%d",
     5383                        media_descriptor_string(bkpinfo->backup_media_type),
     5384                        g_current_media_number);
     5385                log_to_screen(tmp);
     5386                just_changed_cds = TRUE;
     5387            } else {
     5388                /* That big file doesn't exist, but the followings may */
     5389                /* So we need to continue looping */
     5390                log_msg(2, "There was no bigfile #%ld. That's OK.",
     5391                    bigfileno + 1);
     5392                log_msg(2, "I'm going to stop restoring bigfiles now.");
     5393                retval++;
     5394                bigfileno++;
     5395            }
     5396        } else {
     5397            just_changed_cds = FALSE;
     5398            sprintf(tmp, "Restoring big file %ld", bigfileno + 1);
     5399            update_progress_form(tmp);
     5400            res =
     5401                restore_a_biggiefile_from_CD(bigfileno, filelist, pathname_of_last_biggie_restored);
     5402            iamhere(pathname_of_last_biggie_restored);
     5403            if (fbw && pathname_of_last_biggie_restored[0]) {
     5404                fprintf(fbw, "%s\n", pathname_of_last_biggie_restored);
     5405            }
     5406            retval += res;
     5407            bigfileno++;
     5408
     5409        }
     5410    }
     5411
     5412    if (fbw) {
     5413        fclose(fbw);
     5414        if (g_getfattr) {
     5415            sprintf(xattr_fname, XATTR_BIGGLST_FNAME_RAW_SZ, ARCHIVES_PATH);
     5416            if (length_of_file(xattr_fname) > 0) {
     5417                set_fattr_list(biggies_whose_EXATs_we_should_set, xattr_fname);
     5418            }
     5419        }
     5420        if (g_getfacl) {
     5421            sprintf(acl_fname, ACL_BIGGLST_FNAME_RAW_SZ, ARCHIVES_PATH);
     5422            if (length_of_file(acl_fname) > 0) {
     5423                set_acl_list(biggies_whose_EXATs_we_should_set, acl_fname);
     5424            }
     5425        }
     5426    }
     5427    if (does_file_exist("/PAUSE")) {
     5428        popup_and_OK
     5429            ("Press ENTER to go on. Delete /PAUSE to stop these pauses.");
     5430    }
     5431    close_progress_form();
     5432    if (retval) {
     5433        mvaddstr_and_log_it(g_currentY++, 74, "Errors.");
     5434    } else {
     5435        mvaddstr_and_log_it(g_currentY++, 74, "Done.");
     5436    }
     5437    paranoid_free(xattr_fname);
     5438    paranoid_free(acl_fname);
     5439    paranoid_free(tmp);
     5440    paranoid_free(biggies_whose_EXATs_we_should_set);
     5441    paranoid_free(pathname_of_last_biggie_restored);
     5442    return (retval);
     5443}
     5444
     5445/**************************************************************************
     5446 *END_RESTORE_ALL_BIGGIFILES_FROM_CD                                      *
     5447 **************************************************************************/
     5448
     5449
     5450
     5451/**
     5452 * Restore all afioballs from all CDs in the backup.
     5453 * The first CD should be inserted (if not, it will be asked for).
     5454 * @param bkpinfo The backup information structure. @c backup_media_type is the
     5455 * only field used in @e this function.
     5456 * @param filelist The node structure containing the list of files to be
     5457 * restored. If no file in some particular afioball is in this list, afio will
     5458 * still be called for that fileset, but nothing will be written.
     5459 * @return 0 for success, or the number of filesets that failed.
     5460 */
     5461int
     5462restore_all_tarballs_from_CD(struct s_node *filelist)
     5463{
     5464    int retval = 0;
     5465    int res;
     5466    int attempts;
     5467    long current_tarball_number = 0;
     5468    long max_val;
     5469  /**malloc ***/
     5470    char *tmp;
     5471    char *tarball_fname;
     5472    char *progress_str;
     5473    char *comment;
     5474
     5475    malloc_string(tmp);
     5476    malloc_string(tarball_fname);
     5477    malloc_string(progress_str);
     5478    malloc_string(comment);
     5479
     5480    assert(bkpinfo != NULL);
     5481
     5482    mvaddstr_and_log_it(g_currentY, 0, "Restoring from archives");
     5483    log_msg(2,
     5484            "Insisting on 1st CD, so that I can have a look at LAST-FILELIST-NUMBER");
     5485    if (g_current_media_number != 1) {
     5486        log_msg(3, "OK, that's jacked up.");
     5487        g_current_media_number = 1;
     5488    }
     5489    insist_on_this_cd_number(g_current_media_number);
     5490    read_cfg_var(g_mondo_cfg_file, "last-filelist-number", tmp);
     5491    max_val = atol(tmp) + 1;
     5492    sprintf(progress_str, "Restoring from %s #%d",
     5493            media_descriptor_string(bkpinfo->backup_media_type),
     5494            g_current_media_number);
     5495    log_to_screen(progress_str);
     5496    open_progress_form("Restoring from archives",
     5497                       "Restoring data from the archives.",
     5498                       "Please wait. This may take some time.",
     5499                       progress_str, max_val);
     5500    for (;;) {
     5501        insist_on_this_cd_number(g_current_media_number);
     5502        update_progress_form(progress_str);
     5503        sprintf(tarball_fname, MNT_CDROM "/archives/%ld.afio.bz2",
     5504                current_tarball_number);
     5505        if (!does_file_exist(tarball_fname)) {
     5506            sprintf(tarball_fname, MNT_CDROM "/archives/%ld.afio.gz",
     5507                current_tarball_number);
     5508        }
     5509        if (!does_file_exist(tarball_fname)) {
     5510            sprintf(tarball_fname, MNT_CDROM "/archives/%ld.afio.lzo",
     5511                    current_tarball_number);
     5512        }
     5513        if (!does_file_exist(tarball_fname)) {
     5514            sprintf(tarball_fname, MNT_CDROM "/archives/%ld.afio.",
     5515                    current_tarball_number);
     5516        }
     5517        if (!does_file_exist(tarball_fname)) {
     5518            sprintf(tarball_fname, MNT_CDROM "/archives/%ld.star.bz2",
     5519                    current_tarball_number);
     5520        }
     5521        if (!does_file_exist(tarball_fname)) {
     5522            sprintf(tarball_fname, MNT_CDROM "/archives/%ld.star.",
     5523                    current_tarball_number);
     5524        }
     5525        if (!does_file_exist(tarball_fname)) {
     5526            if (current_tarball_number == 0) {
     5527                log_to_screen
     5528                    ("No tarballs. Strange. Maybe you only backed up freakin' big files?");
     5529                return (0);
     5530            }
     5531            if (!does_file_exist(MNT_CDROM "/archives/NOT-THE-LAST")
     5532                || system("find " MNT_CDROM
     5533                          "/archives/slice* > /dev/null 2> /dev/null") ==
     5534                0) {
     5535                break;
     5536            }
     5537            g_current_media_number++;
     5538            sprintf(progress_str, "Restoring from %s #%d",
     5539                    media_descriptor_string(bkpinfo->backup_media_type),
     5540                    g_current_media_number);
     5541            log_to_screen(progress_str);
     5542        } else {
     5543            sprintf(progress_str, "Restoring from fileset #%ld on %s #%d",
     5544                    current_tarball_number,
     5545                    media_descriptor_string(bkpinfo->backup_media_type),
     5546                    g_current_media_number);
     5547//    log_msg(3, "progress_str = %s", progress_str);
     5548            for (res = 999, attempts = 0; attempts < 3 && res != 0;
     5549                 attempts++) {
     5550                res =
     5551                    restore_a_tarball_from_CD(tarball_fname,
     5552                                              current_tarball_number,
     5553                                              filelist);
     5554            }
     5555            sprintf(tmp, "%s #%d, fileset #%ld - restore ",
     5556                    media_descriptor_string(bkpinfo->backup_media_type),
     5557                    g_current_media_number, current_tarball_number);
     5558            if (res) {
     5559                strcat(tmp, "reported errors");
     5560            } else if (attempts > 1) {
     5561                strcat(tmp, "succeeded");
     5562            } else {
     5563                strcat(tmp, "succeeded");
     5564            }
     5565            if (attempts > 1) {
     5566                sprintf(tmp + strlen(tmp), " (%d attempts) - review logs",
     5567                        attempts);
     5568            }
     5569            strcpy(comment, tmp);
     5570            if (attempts > 1) {
     5571                log_to_screen(comment);
     5572            }
     5573
     5574            retval += res;
     5575            current_tarball_number++;
     5576            g_current_progress++;
     5577        }
     5578    }
     5579    close_progress_form();
     5580    if (retval) {
     5581        mvaddstr_and_log_it(g_currentY++, 74, "Errors.");
     5582    } else {
     5583        mvaddstr_and_log_it(g_currentY++, 74, "Done.");
     5584    }
     5585    paranoid_free(tmp);
     5586    paranoid_free(tarball_fname);
     5587    paranoid_free(progress_str);
     5588    paranoid_free(comment);
     5589
     5590    return (retval);
     5591}
     5592
     5593/**************************************************************************
     5594 *END_RESTORE_ALL_TARBALLS_FROM_CD                                        *
     5595 **************************************************************************/
     5596
     5597
     5598
     5599/**
     5600 * Restore all biggiefiles from the currently opened stream.
     5601 * @param bkpinfo The backup information structure. Passed to other functions.
     5602 * @param filelist The node structure containing the list of files to be
     5603 * restored. If a prospective biggiefile is not in the list, it will be ignored.
     5604 * @return 0 for success, or the number of biggiefiles that failed.
     5605 */
     5606int
     5607restore_all_biggiefiles_from_stream(struct s_node *filelist)
     5608{
     5609    long noof_biggiefiles;
     5610    long current_bigfile_number = 0;
     5611    long total_slices;
     5612
     5613    int retval = 0;
     5614    int res = 0;
     5615    int ctrl_chr;
     5616
     5617  /** malloc add ****/
     5618    char *tmp;
     5619    char *biggie_fname;
     5620    char *biggie_cksum;
     5621    char *xattr_fname;
     5622    char *acl_fname;
     5623    char *p;
     5624    char *pathname_of_last_biggie_restored;
     5625    char *biggies_whose_EXATs_we_should_set;    // EXtended ATtributes
     5626    long long biggie_size;
     5627    FILE *fbw = NULL;
     5628
     5629    malloc_string(tmp);
     5630    malloc_string(biggie_fname);
     5631    malloc_string(biggie_cksum);
     5632    malloc_string(xattr_fname);
     5633    malloc_string(acl_fname);
     5634    malloc_string(biggies_whose_EXATs_we_should_set);
     5635    malloc_string(pathname_of_last_biggie_restored);
     5636    assert(bkpinfo != NULL);
     5637
     5638    read_cfg_var(g_mondo_cfg_file, "total-slices", tmp);
     5639
     5640    total_slices = atol(tmp);
     5641    sprintf(tmp, "Reassembling large files      ");
     5642    if (g_getfattr) {
     5643        sprintf(xattr_fname, XATTR_BIGGLST_FNAME_RAW_SZ, bkpinfo->tmpdir);
     5644    }
     5645    if (g_getfacl) {
     5646        sprintf(acl_fname, ACL_BIGGLST_FNAME_RAW_SZ, bkpinfo->tmpdir);
     5647    }
     5648    mvaddstr_and_log_it(g_currentY, 0, tmp);
     5649    sprintf(biggies_whose_EXATs_we_should_set,
     5650            "%s/biggies-whose-EXATs-we-should-set", bkpinfo->tmpdir);
     5651    if (!(fbw = fopen(biggies_whose_EXATs_we_should_set, "w"))) {
     5652        log_msg(1, "Warning - cannot openout %s",
     5653                biggies_whose_EXATs_we_should_set);
     5654    }
     5655// get xattr and acl files if they're there
     5656    res =
     5657        read_header_block_from_stream(&biggie_size, biggie_fname,
     5658                                      &ctrl_chr);
     5659    if (ctrl_chr == BLK_START_EXTENDED_ATTRIBUTES) {
     5660        res =
     5661            read_EXAT_files_from_tape(&biggie_size, biggie_fname,
     5662                                      &ctrl_chr, xattr_fname, acl_fname);
     5663    }
     5664
     5665    noof_biggiefiles = atol(biggie_fname);
     5666    sprintf(tmp, "OK, there are %ld biggiefiles in the archives",
     5667            noof_biggiefiles);
     5668    log_msg(2, tmp);
     5669    open_progress_form("Reassembling large files",
     5670                       "I am now reassembling all the large files.",
     5671                       "Please wait. This may take some time.",
     5672                       "", total_slices);
     5673
     5674    for (res =
     5675         read_header_block_from_stream(&biggie_size, biggie_fname,
     5676                                       &ctrl_chr);
     5677         ctrl_chr != BLK_STOP_BIGGIEFILES;
     5678         res =
     5679         read_header_block_from_stream(&biggie_size, biggie_fname,
     5680                                       &ctrl_chr)) {
     5681        if (ctrl_chr != BLK_START_A_NORMBIGGIE
     5682            && ctrl_chr != BLK_START_A_PIHBIGGIE) {
     5683            wrong_marker(BLK_START_A_NORMBIGGIE, ctrl_chr);
     5684        }
     5685        p = strrchr(biggie_fname, '/');
     5686        if (!p) {
     5687            p = biggie_fname;
     5688        } else {
     5689            p++;
     5690        }
     5691        sprintf(tmp, "Restoring big file %ld (%lld K)",
     5692                current_bigfile_number + 1, biggie_size / 1024);
     5693        update_progress_form(tmp);
     5694        res = restore_a_biggiefile_from_stream(biggie_fname,
     5695                                               current_bigfile_number,
     5696                                               biggie_cksum,
     5697                                               biggie_size,
     5698                                               filelist, ctrl_chr,
     5699                                               pathname_of_last_biggie_restored);
     5700        log_msg(1, "I believe I have restored %s",
     5701                pathname_of_last_biggie_restored);
     5702        if (fbw && pathname_of_last_biggie_restored[0]) {
     5703            fprintf(fbw, "%s\n", pathname_of_last_biggie_restored);
     5704        }
     5705        retval += res;
     5706        current_bigfile_number++;
     5707
     5708    }
     5709    if (current_bigfile_number != noof_biggiefiles
     5710        && noof_biggiefiles != 0) {
     5711        sprintf(tmp, "Warning - bigfileno=%ld but noof_biggiefiles=%ld\n",
     5712                current_bigfile_number, noof_biggiefiles);
     5713    } else {
     5714        sprintf(tmp,
     5715                "%ld biggiefiles in biggielist.txt; %ld biggiefiles processed today.",
     5716                noof_biggiefiles, current_bigfile_number);
     5717    }
     5718    log_msg(1, tmp);
     5719
     5720    if (fbw) {
     5721        fclose(fbw);
     5722        if (length_of_file(biggies_whose_EXATs_we_should_set) > 2) {
     5723            iamhere("Setting biggie-EXATs");
     5724            if (g_getfattr) {
     5725                if (length_of_file(xattr_fname) > 0) {
     5726                    log_msg(1, "set_fattr_List(%s,%s)",
     5727                        biggies_whose_EXATs_we_should_set, xattr_fname);
     5728                    set_fattr_list(biggies_whose_EXATs_we_should_set,
     5729                               xattr_fname);
     5730                }
     5731            }
     5732            if (g_getfacl) {
     5733                if (length_of_file(acl_fname) > 0) {
     5734                    log_msg(1, "set_acl_list(%s,%s)",
     5735                            biggies_whose_EXATs_we_should_set, acl_fname);
     5736                    set_acl_list(biggies_whose_EXATs_we_should_set, acl_fname);
     5737                }
     5738            }
     5739        } else {
     5740            iamhere
     5741                ("No biggiefiles selected. So, no biggie-EXATs to set.");
     5742        }
     5743    }
     5744    if (does_file_exist("/PAUSE")) {
     5745        popup_and_OK
     5746            ("Press ENTER to go on. Delete /PAUSE to stop these pauses.");
     5747    }
     5748
     5749    close_progress_form();
     5750    if (retval) {
     5751        mvaddstr_and_log_it(g_currentY++, 74, "Errors.");
     5752    } else {
     5753        mvaddstr_and_log_it(g_currentY++, 74, "Done.");
     5754    }
     5755    paranoid_free(biggies_whose_EXATs_we_should_set);
     5756    paranoid_free(pathname_of_last_biggie_restored);
     5757    paranoid_free(biggie_fname);
     5758    paranoid_free(biggie_cksum);
     5759    paranoid_free(xattr_fname);
     5760    paranoid_free(acl_fname);
     5761    paranoid_free(tmp);
     5762    return (retval);
     5763}
     5764
     5765/**************************************************************************
     5766 *END_RESTORE_ALL_BIGGIEFILES_FROM_STREAM                                 *
     5767 **************************************************************************/
     5768
     5769
     5770
     5771
     5772
     5773
     5774/**
     5775 * Restore all afioballs from the currently opened tape stream.
     5776 * @param bkpinfo The backup information structure. Fields used:
     5777 * - @c bkpinfo->backup_media_type
     5778 * - @c bkpinfo->restore_path
     5779 * @param filelist The node structure containing the list of files to be
     5780 * restored. If no file in an afioball is in this list, afio will still be
     5781 * called for that fileset, but nothing will be written.
     5782 * @return 0 for success, or the number of filesets that failed.
     5783 */
     5784int
     5785restore_all_tarballs_from_stream(struct s_node *filelist)
     5786{
     5787    int retval = 0;
     5788    int res;
     5789    long current_afioball_number = 0;
     5790    int ctrl_chr;
     5791    long max_val /*, total_noof_files */ ;
     5792
     5793  /** malloc **/
     5794    char *tmp;
     5795    char *progress_str;
     5796    char *tmp_fname;
     5797    char *xattr_fname;
     5798    char *acl_fname;
     5799
     5800    long long tmp_size;
     5801
     5802    malloc_string(tmp);
     5803    malloc_string(progress_str);
     5804    malloc_string(tmp_fname);
     5805    assert(bkpinfo != NULL);
     5806    malloc_string(xattr_fname);
     5807    malloc_string(acl_fname);
     5808    mvaddstr_and_log_it(g_currentY, 0, "Restoring from archives");
     5809    read_cfg_var(g_mondo_cfg_file, "last-filelist-number", tmp);
     5810    max_val = atol(tmp) + 1;
     5811
     5812    chdir(bkpinfo->restore_path);   /* I don't know why this is needed _here_ but it seems to be. -HR, 02/04/2002 */
     5813
     5814    run_program_and_log_output("pwd", 5);
     5815
     5816    sprintf(progress_str, "Restoring from media #%d",
     5817            g_current_media_number);
     5818    log_to_screen(progress_str);
     5819    open_progress_form("Restoring from archives",
     5820                       "Restoring data from the archives.",
     5821                       "Please wait. This may take some time.",
     5822                       progress_str, max_val);
     5823
     5824    log_msg(3, "hey");
     5825
     5826    res = read_header_block_from_stream(&tmp_size, tmp_fname, &ctrl_chr);
     5827    if (res) {
     5828        log_msg(2, "Warning - error reading afioball from tape");
     5829    }
     5830    retval += res;
     5831    if (ctrl_chr != BLK_START_AFIOBALLS) {
     5832        wrong_marker(BLK_START_AFIOBALLS, ctrl_chr);
     5833    }
     5834    log_msg(2, "ho");
     5835    res = read_header_block_from_stream(&tmp_size, tmp_fname, &ctrl_chr);
     5836    while (ctrl_chr != BLK_STOP_AFIOBALLS) {
     5837        update_progress_form(progress_str);
     5838        if (g_getfattr) {
     5839            sprintf(xattr_fname, "%s/xattr-subset-%ld.tmp", bkpinfo->tmpdir,
     5840                current_afioball_number);
     5841            unlink(xattr_fname);
     5842        }
     5843        if (g_getfacl) {
     5844            sprintf(acl_fname, "%s/acl-subset-%ld.tmp", bkpinfo->tmpdir,
     5845                current_afioball_number);
     5846            unlink(acl_fname);
     5847        }
     5848        if (ctrl_chr == BLK_START_EXTENDED_ATTRIBUTES) {
     5849            iamhere("Reading EXAT files from tape");
     5850            res =
     5851                read_EXAT_files_from_tape(&tmp_size, tmp_fname,
     5852                                          &ctrl_chr, xattr_fname,
     5853                                          acl_fname);
     5854        }
     5855        if (ctrl_chr != BLK_START_AN_AFIO_OR_SLICE) {
     5856            wrong_marker(BLK_START_AN_AFIO_OR_SLICE, ctrl_chr);
     5857        }
     5858        sprintf(tmp,
     5859                "Restoring from fileset #%ld (name=%s, size=%ld K)",
     5860                current_afioball_number, tmp_fname, (long) tmp_size >> 10);
     5861        res =
     5862            restore_a_tarball_from_stream(tmp_fname,
     5863                                          current_afioball_number,
     5864                                          filelist, tmp_size, xattr_fname,
     5865                                          acl_fname);
     5866        retval += res;
     5867        if (res) {
     5868            sprintf(tmp, "Fileset %ld - errors occurred",
     5869                    current_afioball_number);
     5870            log_to_screen(tmp);
     5871        }
     5872        res =
     5873            read_header_block_from_stream(&tmp_size, tmp_fname, &ctrl_chr);
     5874        if (ctrl_chr != BLK_STOP_AN_AFIO_OR_SLICE) {
     5875            wrong_marker(BLK_STOP_AN_AFIO_OR_SLICE, ctrl_chr);
     5876        }
     5877
     5878        current_afioball_number++;
     5879        g_current_progress++;
     5880        sprintf(progress_str, "Restoring from fileset #%ld on %s #%d",
     5881                current_afioball_number,
     5882                media_descriptor_string(bkpinfo->backup_media_type),
     5883                g_current_media_number);
     5884        res =
     5885            read_header_block_from_stream(&tmp_size, tmp_fname, &ctrl_chr);
     5886        if (g_getfattr) {
     5887            unlink(xattr_fname);
     5888        }
     5889        if (g_getfacl) {
     5890            unlink(acl_fname);
     5891        }
     5892    }                           // next
     5893    log_msg(1, "All done with afioballs");
     5894    close_progress_form();
     5895    if (retval) {
     5896        mvaddstr_and_log_it(g_currentY++, 74, "Errors.");
     5897    } else {
     5898        mvaddstr_and_log_it(g_currentY++, 74, "Done.");
     5899    }
     5900    paranoid_free(tmp);
     5901    paranoid_free(progress_str);
     5902    paranoid_free(tmp_fname);
     5903    paranoid_free(xattr_fname);
     5904    paranoid_free(acl_fname);
     5905    return (retval);
     5906}
     5907
     5908/**************************************************************************
     5909 *END_ RESTORE_ALL_TARBALLS_FROM_STREAM                                   *
     5910 **************************************************************************/
     5911
     5912/* @} - end of LLrestoreGroup */
     5913
     5914
     5915/**
     5916 * Restore all files in @p filelist.
     5917 * @param bkpinfo The backup information structure. Most fields are used.
     5918 * @param filelist The node structure containing the list of files to be
     5919 * restored.
     5920 * @return 0 for success, or the number of afioballs and biggiefiles that failed.
     5921 * @ingroup restoreGroup
     5922 */
     5923int restore_everything(struct s_node *filelist)
     5924{
     5925    int resA;
     5926    int resB;
     5927
     5928  /** mallco ***/
     5929    char *cwd;
     5930    char *newpath;
     5931    char *tmp;
     5932    assert(bkpinfo != NULL);
     5933
     5934    malloc_string(cwd);
     5935    malloc_string(newpath);
     5936    malloc_string(tmp);
     5937    log_msg(2, "restore_everything() --- starting");
     5938    g_current_media_number = 1;
     5939    getcwd(cwd, MAX_STR_LEN - 1);
     5940    sprintf(tmp, "mkdir -p %s", bkpinfo->restore_path);
     5941    run_program_and_log_output(tmp, FALSE);
     5942    log_msg(1, "Changing dir to %s", bkpinfo->restore_path);
     5943    chdir(bkpinfo->restore_path);
     5944    getcwd(newpath, MAX_STR_LEN - 1);
     5945    log_msg(1, "path is now %s", newpath);
     5946    log_msg(1, "restoring everything");
     5947    if (!find_home_of_exe("petris") && !g_text_mode) {
     5948        newtDrawRootText(0, g_noof_rows - 2,
     5949                         "Press ALT-<left cursor> twice to play Petris :-) ");
     5950        newtRefresh();
     5951    }
     5952    mvaddstr_and_log_it(g_currentY, 0, "Preparing to read your archives");
     5953    if (IS_THIS_A_STREAMING_BACKUP(bkpinfo->backup_media_type)) {
     5954        mount_media();
     5955        mvaddstr_and_log_it(g_currentY++, 0,
     5956                            "Restoring OS and data from streaming media");
     5957        if (bkpinfo->backup_media_type == cdstream) {
     5958            openin_cdstream();
     5959        } else {
     5960            assert_string_is_neither_NULL_nor_zerolength(bkpinfo->media_device);
     5961            openin_tape();
     5962        }
     5963        resA = restore_all_tarballs_from_stream(filelist);
     5964        resB = restore_all_biggiefiles_from_stream(filelist);
     5965        if (bkpinfo->backup_media_type == cdstream) {
     5966            closein_cdstream();
     5967        } else {
     5968            closein_tape();
     5969        }
     5970    } else {
     5971        mvaddstr_and_log_it(g_currentY++, 0,
     5972                            "Restoring OS and data from CD/USB   ");
     5973        mount_media();
     5974        resA = restore_all_tarballs_from_CD(filelist);
     5975        resB = restore_all_biggiefiles_from_CD(filelist);
     5976    }
     5977    chdir(cwd);
     5978    if (resA + resB) {
     5979        log_to_screen("Errors occurred while data was being restored.");
     5980    }
     5981    if (length_of_file("/etc/raidtab") > 0) {
     5982        log_msg(2, "Copying local raidtab to restored filesystem");
     5983        run_program_and_log_output("cp -f /etc/raidtab " MNT_RESTORING
     5984                                   "/etc/raidtab", FALSE);
     5985    }
     5986    kill_petris();
     5987    log_msg(2, "restore_everything() --- leaving");
     5988    paranoid_free(cwd);
     5989    paranoid_free(newpath);
     5990    paranoid_free(tmp);
     5991    return (resA + resB);
     5992}
     5993
     5994/**************************************************************************
     5995 *END_RESTORE_EVERYTHING                                                  *
     5996 **************************************************************************/
     5997
     5998
     5999
     6000/**
     6001 * @brief Haha. You wish! (This function is not implemented :-)
     6002 */
     6003int
     6004restore_live_from_monitas_server(char *monitas_device,
     6005                                 char *restore_this_directory,
     6006                                 char *restore_here)
     6007     /* NB: bkpinfo hasn't been populated yet, except for ->tmp which is "/tmp" */
     6008{
     6009    FILE *fout;
     6010    int retval = 0;
     6011    int i;
     6012    int j;
     6013    struct mountlist_itself the_mountlist;
     6014    static struct raidlist_itself the_raidlist;
     6015  /** malloc **/
     6016    char tmp[MAX_STR_LEN + 1];
     6017    char command[MAX_STR_LEN + 1];
     6018    char datablock[256 * 1024];
     6019    char datadisks_fname[MAX_STR_LEN + 1];
     6020    long k;
     6021    long length;
     6022    long long llt;
     6023    struct s_node *filelist = NULL;
     6024    assert(bkpinfo != NULL);
     6025    assert_string_is_neither_NULL_nor_zerolength(monitas_device);
     6026    assert(restore_this_directory != NULL);
     6027    assert(restore_here != NULL);
     6028
     6029    sprintf(tmp, "restore_here = '%s'", restore_here);
     6030
     6031    log_msg(2, tmp);
     6032
     6033    log_msg(2, "restore_live_from_monitas_server() - starting");
     6034    unlink("/tmp/mountlist.txt");
     6035    unlink("/tmp/filelist.full");
     6036    unlink("/tmp/biggielist.txt");
     6037    if (restore_here[0] == '\0') {
     6038        strcpy(bkpinfo->restore_path, MNT_RESTORING);
     6039    } else {
     6040        strcpy(bkpinfo->restore_path, restore_here);
     6041    }
     6042    log_msg(3, "FYI FYI FYI FYI FYI FYI FYI FYI FYI FYI FYI");
     6043    sprintf(tmp, "FYI - data will be restored to %s",
     6044            bkpinfo->restore_path);
     6045    log_msg(3, tmp);
     6046    log_msg(3, "FYI FYI FYI FYI FYI FYI FYI FYI FYI FYI FYI");
     6047    sprintf(datadisks_fname, "/tmp/mondorestore.datadisks.%d",
     6048            (int) (random() % 32768));
     6049    chdir(bkpinfo->tmpdir);
     6050
     6051    sprintf(command, "cat %s", monitas_device);
     6052    g_tape_stream = popen(command, "r");    // for compatibility with openin_tape()
     6053    if (!(fout = fopen(datadisks_fname, "w"))) {
     6054        log_OS_error(datadisks_fname);
     6055        return (1);
     6056    }
     6057    for (i = 0; i < 32; i++) {
     6058        for (j = 0; j < 4; j++) {
     6059            for (length = k = 0; length < 256 * 1024; length += k) {
     6060                k = fread(datablock + length, 1, 256 * 1024 - length,
     6061                          g_tape_stream);
     6062            }
     6063            fwrite(datablock, 1, length, fout);
     6064            g_tape_posK += length;
     6065        }
     6066    }
     6067    paranoid_fclose(fout);
     6068    sprintf(command,
     6069            "tar -zxvf %s ./tmp/mondo-restore.cfg ./tmp/mountlist.txt ./tmp/filelist.full ./tmp/biggielist.txt",
     6070            datadisks_fname);
     6071    run_program_and_log_output(command, 4);
     6072    read_header_block_from_stream(&llt, tmp, &i);
     6073    read_header_block_from_stream(&llt, tmp, &i);
     6074
     6075    unlink(datadisks_fname);
     6076    read_cfg_file_into_bkpinfo(g_mondo_cfg_file);
     6077    retval = load_mountlist(&the_mountlist, g_mountlist_fname); // in case read_cfg_file_into_bkpinfo   strcpy(bkpinfo->media_device, monitas_device);
     6078
     6079
     6080    load_raidtab_into_raidlist(&the_raidlist, RAIDTAB_FNAME);
     6081    iamhere("FIXME");
     6082    fatal_error("This will fail");
     6083    sprintf(command,
     6084            "grep -E '^%s.*$' %s > %s",
     6085            restore_this_directory, g_filelist_full, g_filelist_full);
     6086    if (system(command)) {
     6087        retval++;
     6088        log_to_screen
     6089            ("Error(s) occurred while processing filelist and wildcard");
     6090    }
     6091    iamhere("FIXME");
     6092    fatal_error("This will fail");
     6093    sprintf(command,
     6094            "grep -E '^%s.*$' %s > %s",
     6095            restore_this_directory, g_biggielist_txt, g_biggielist_txt);
     6096    if (system(command)) {
     6097        log_msg(1,
     6098                "Error(s) occurred while processing biggielist and wildcard");
     6099    }
     6100    sprintf(command, "touch %s", g_biggielist_txt);
     6101    run_program_and_log_output(command, FALSE);
     6102//  filelist = load_filelist(g_filelist_restthese);  // FIXME --- this probably doesn't work because it doesn't include the biggiefiles
     6103    retval += restore_everything(filelist);
     6104    free_filelist(filelist);
     6105    log_msg(2, "--------End of restore_live_from_monitas_server--------");
     6106    return (retval);
     6107}
     6108
     6109/**************************************************************************
     6110 *END_RESTORE_LIVE_FROM_MONITAS_SERVER                                    *
     6111 **************************************************************************/
     6112
     6113
     6114
     6115
     6116extern void wait_until_software_raids_are_prepped(char *, int);
     6117
     6118
     6119char which_restore_mode(void);
     6120
     6121
     6122/**
     6123 * Log a "don't panic" message to the logfile.
     6124 */
     6125void welcome_to_mondorestore()
     6126{
     6127    log_msg(0, "-------------- Mondo Restore v%s -------------", PACKAGE_VERSION);
     6128    log_msg(0,
     6129            "DON'T PANIC! Mondorestore logs almost everything, so please ");
     6130    log_msg(0,
     6131            "don't break out in a cold sweat just because you see a few  ");
     6132    log_msg(0,
     6133            "error messages in the log. Read them; analyze them; see if  ");
     6134    log_msg(0,
     6135            "they are significant; above all, verify your backups! Please");
     6136    log_msg(0,
     6137            "attach a compressed copy of this log to any e-mail you send ");
     6138    log_msg(0,
     6139            "to the Mondo mailing list when you are seeking technical    ");
     6140    log_msg(0,
     6141            "support. Without it, we can't help you.            - DevTeam");
     6142    log_msg(0,
     6143            "------------------------------------------------------------");
     6144    log_msg(0,
     6145            "BTW, despite (or perhaps because of) the wealth of messages,");
     6146    log_msg(0,
     6147            "some users are inclined to stop reading this log.  If Mondo ");
     6148    log_msg(0,
     6149            "stopped for some reason, chances are it's detailed here.    ");
     6150    log_msg(0,
     6151            "More than likely there's a message at the very end of this  ");
     6152    log_msg(0,
     6153            "log that will tell you what is wrong.  Please read it!      ");
     6154    log_msg(0,
     6155            "------------------------------------------------------------");
     6156}
     6157
     6158
     6159
     6160/**
     6161 * Restore the user's data.
     6162 * What did you think it did, anyway? :-)
     6163 */
     6164int main(int argc, char *argv[])
     6165{
     6166    FILE *fin;
     6167    FILE *fout;
     6168    int retval = 0;
     6169    int res;
     6170//  int c;
     6171    char *tmp;
     6172
     6173    struct mountlist_itself *mountlist;
     6174    struct raidlist_itself *raidlist;
     6175    struct s_node *filelist;
     6176    char *a, *b;
     6177    bool run_postnuke = FALSE;
     6178
     6179  /**************************************************************************
     6180   * hugo-                                                                  *
     6181   * busy stuff here - it needs some comments -stan                           *
     6182   *                                                                        *
     6183   **************************************************************************/
     6184    if (getuid() != 0) {
     6185        fprintf(stderr, "Please run as root.\r\n");
     6186        exit(127);
     6187    }
     6188    if (!
     6189        (bkpinfo = malloc(sizeof(struct s_bkpinfo)))) {
     6190        fatal_error("Cannot malloc bkpinfo");
     6191    }
     6192    reset_bkpinfo();
     6193
     6194    g_loglevel = DEFAULT_MR_LOGLEVEL;
     6195    malloc_string(tmp);
     6196
     6197/* Configure global variables */
     6198#ifdef __FreeBSD__
     6199    if (strstr
     6200        (call_program_and_get_last_line_of_output("cat /tmp/cmdline"),
     6201         "textonly"))
     6202#else
     6203    if (strstr
     6204        (call_program_and_get_last_line_of_output("cat /proc/cmdline"),
     6205         "textonly"))
     6206#endif
     6207    {
     6208        g_text_mode = TRUE;
     6209        log_msg(1, "TEXTONLY MODE");
     6210    } else {
     6211        g_text_mode = FALSE;
     6212    }                           // newt :-)
     6213    if (!(mountlist = malloc(sizeof(struct mountlist_itself)))) {
     6214        fatal_error("Cannot malloc mountlist");
     6215    }
     6216    if (!(raidlist = malloc(sizeof(struct raidlist_itself)))) {
     6217        fatal_error("Cannot malloc raidlist");
     6218    }
     6219
     6220    malloc_libmondo_global_strings();
     6221
     6222    strcpy(g_mondo_home,
     6223           call_program_and_get_last_line_of_output("which mondorestore"));
     6224    sprintf(g_tmpfs_mountpt, "/tmp/tmpfs");
     6225    make_hole_for_dir(g_tmpfs_mountpt);
     6226    g_current_media_number = 1; // precaution
     6227
     6228    run_program_and_log_output("mkdir -p " MNT_CDROM, FALSE);
     6229
     6230    malloc_string(tmp);
     6231    malloc_string(a);
     6232    malloc_string(b);
     6233    setup_MR_global_filenames();    // malloc() and set globals, using bkpinfo->tmpdir etc.
     6234    bkpinfo->backup_media_type = none;  // in case boot disk was made for one backup type but user wants to restore from another backup type
     6235    bkpinfo->restore_data = TRUE;   // Well, yeah :-)
     6236    if (am_I_in_disaster_recovery_mode()) {
     6237        run_program_and_log_output("mount / -o remount,rw", 2);
     6238    }                           // for b0rken distros
     6239    g_main_pid = getpid();
     6240    srandom((int) (time(NULL)));
     6241    register_pid(getpid(), "mondo");
     6242    set_signals(TRUE);
     6243    g_kernel_version = get_kernel_version();
     6244
     6245    log_msg(1, "FYI - g_mountlist_fname = %s", g_mountlist_fname);
     6246    if (strlen(g_mountlist_fname) < 3) {
     6247        fatal_error
     6248            ("Serious error in malloc()'ing. Could be a bug in your glibc.");
     6249    }
     6250    mkdir(MNT_CDROM, 0x770);
     6251    make_hole_for_dir(MONDO_CACHE);
     6252
     6253    /* Backup original mountlist.txt */
     6254    sprintf(tmp, "%s.orig", g_mountlist_fname);
     6255    if (!does_file_exist(g_mountlist_fname)) {
     6256        log_msg(2,
     6257                "%ld: Warning - g_mountlist_fname (%s) does not exist yet",
     6258                __LINE__, g_mountlist_fname);
     6259    } else if (!does_file_exist(tmp)) {
     6260        sprintf(tmp, "cp -f %s %s.orig", g_mountlist_fname,
     6261                g_mountlist_fname);
     6262        run_program_and_log_output(tmp, FALSE);
     6263    }
     6264
     6265    /* Init directories */
     6266    make_hole_for_dir("/var/log");
     6267    make_hole_for_dir("/tmp/tmpfs");    /* just in case... */
     6268    run_program_and_log_output("umount " MNT_CDROM, FALSE);
     6269    /*
     6270    run_program_and_log_output("ln -sf /var/log/mondo-archive.log /tmp/mondorestore.log",
     6271         FALSE);
     6272         */
     6273
     6274    run_program_and_log_output("rm -Rf /tmp/tmpfs/mondo.tmp.*", FALSE);
     6275
     6276    /* Init GUI */
     6277    malloc_libmondo_global_strings();
     6278    setup_newt_stuff();         /* call newtInit and setup screen log */
     6279    welcome_to_mondorestore();
     6280    if (bkpinfo->disaster_recovery) {
     6281        log_msg(1, "I am in disaster recovery mode");
     6282    } else {
     6283        log_msg(1, "I am in normal, live mode");
     6284    }
     6285
     6286    iamhere("what time is it");
     6287
     6288    /* Process command-line parameters */
     6289    if (argc == 2 && strcmp(argv[1], "--edit-mountlist") == 0) {
     6290#ifdef __FreeBSD__
     6291        system("mv -f /tmp/raidconf.txt /etc/raidtab");
     6292        if (!does_file_exist("/etc/raidtab"))
     6293            system("vinum printconfig > /etc/raidtab");
     6294#endif
     6295        load_raidtab_into_raidlist(raidlist, RAIDTAB_FNAME);
     6296        if (!does_file_exist(g_mountlist_fname)) {
     6297            strcpy(g_mountlist_fname, "/tmp/mountlist.txt");
     6298        }
     6299        res = let_user_edit_the_mountlist(mountlist, raidlist);
     6300#ifdef __FreeBSD__
     6301        system("mv -f /etc/raidtab /tmp/raidconf.txt");
     6302#endif
     6303        paranoid_MR_finish(res);
     6304    }
     6305
     6306    g_loglevel = DEFAULT_MR_LOGLEVEL;
     6307    if (argc == 3 && strcmp(argv[1], "--echo-to-screen") == 0) {
     6308        fout = fopen("/tmp/out.txt", "w");
     6309        fput_string_one_char_at_a_time(stderr, argv[2]);
     6310        finish(0);
     6311    }
     6312
     6313    if (argc == 3 && strcmp(argv[1], "--gendf") == 0) {
     6314        make_grub_install_scriptlet(argv[2]);
     6315        finish(0);
     6316    }
     6317
     6318    if (argc >= 2 && strcmp(argv[1], "--pih") == 0) {
     6319        if (system("mount | grep cdrom 2> /dev/null > /dev/null")) {
     6320            system("mount " MNT_CDROM);
     6321        }
     6322        bkpinfo->compression_level = 1;
     6323        g_current_media_number = 2;
     6324        strcpy(bkpinfo->restore_path, "/tmp/TESTING");
     6325        bkpinfo->backup_media_type = dvd;
     6326        open_progress_form("Reassembling /dev/hda1",
     6327                           "Shark is a bit of a silly person.",
     6328                           "Please wait. This may take some time.",
     6329                           "", 1999);
     6330        system("rm -Rf /tmp/*pih*");
     6331
     6332        restore_a_biggiefile_from_CD(42, NULL, tmp);
     6333    }
     6334
     6335    if (argc == 5 && strcmp(argv[1], "--common") == 0) {
     6336        g_loglevel = 6;
     6337        filelist = load_filelist(argv[2]);
     6338        if (!filelist) {
     6339            fatal_error("Failed to load filelist");
     6340        }
     6341        toggle_node_selection(filelist, FALSE);
     6342        toggle_all_root_dirs_on(filelist);
     6343        // BERLIOS: /usr/lib ???
     6344        toggle_path_selection(filelist, "/usr/share", TRUE);
     6345//      show_filelist(filelist);
     6346        save_filelist(filelist, "/tmp/out.txt");
     6347//      finish(0);
     6348//      toggle_path_selection (filelist, "/root/stuff", TRUE);
     6349        strcpy(a, argv[3]);
     6350        strcpy(b, argv[4]);
     6351
     6352        res = save_filelist_entries_in_common(a, filelist, b, FALSE);
     6353        free_filelist(filelist);
     6354        printf("res = %d", res);
     6355        finish(0);
     6356    }
     6357
     6358    if (argc == 3 && strcmp(argv[1], "--popuplist") == 0) {
     6359        popup_changelist_from_file(argv[2]);
     6360        paranoid_MR_finish(0);
     6361    }
     6362
     6363    if (argc == 5 && strcmp(argv[1], "--copy") == 0) {
     6364        log_msg(1, "SCORE");
     6365        g_loglevel = 10;
     6366        if (strstr(argv[2], "save")) {
     6367            log_msg(1, "Saving from %s to %s", argv[3], argv[4]);
     6368            fin = fopen(argv[3], "r");
     6369            fout = fopen(argv[4], "w");
     6370            copy_from_src_to_dest(fin, fout, 'w');
     6371            fclose(fin);
     6372            fin = fopen(argv[3], "r");
     6373            copy_from_src_to_dest(fin, fout, 'w');
     6374            fclose(fout);
     6375            fclose(fin);
     6376        } else if (strstr(argv[2], "restore")) {
     6377            fout = fopen(argv[3], "w");
     6378            fin = fopen(argv[4], "r");
     6379            copy_from_src_to_dest(fout, fin, 'r');
     6380            fclose(fin);
     6381            fin = fopen(argv[4], "r");
     6382            copy_from_src_to_dest(fout, fin, 'r');
     6383            fclose(fout);
     6384            fclose(fin);
     6385        } else {
     6386            fatal_error("Unknown additional param");
     6387        }
     6388        finish(0);
     6389    }
     6390
     6391    if (argc == 3 && strcmp(argv[1], "--mdstat") == 0) {
     6392        wait_until_software_raids_are_prepped(argv[2], 100);
     6393        finish(0);
     6394    }
     6395
     6396    if (argc == 3 && strcmp(argv[1], "--mdconv") == 0) {
     6397        finish(create_raidtab_from_mdstat(argv[2]));
     6398    }
     6399
     6400    if (argc == 3 && strcmp(argv[1], "-p") == 0) {
     6401        strcpy(bkpinfo->prefix,argv[2]);
     6402        log_msg(1,"Prefix forced to %s",bkpinfo->prefix);
     6403    }
     6404
     6405    if (argc == 3 && strcmp(argv[1], "-K") == 0) {
     6406        g_loglevel = atoi(argv[2]);
     6407        log_msg(1,"Loglevel forced to %s",g_loglevel);
     6408    }
     6409
     6410    if (argc == 2 && strcmp(argv[1], "--live-grub") == 0) {
     6411        retval = run_grub(FALSE, "/dev/hda");
     6412        if (retval) {
     6413            log_to_screen("Failed to write Master Boot Record");
     6414        }
     6415        paranoid_MR_finish(0);
     6416    }
     6417    if (argc == 3 && strcmp(argv[1], "--paa") == 0) {
     6418        g_current_media_number = atoi(argv[2]);
     6419        pause_and_ask_for_cdr(5, NULL);
     6420        paranoid_MR_finish(0);
     6421    } else if (!bkpinfo->disaster_recovery) {   // live!
     6422        if (argc != 1) {
     6423            popup_and_OK
     6424                ("Live mode doesn't support command-line parameters yet.");
     6425            paranoid_MR_finish(1);
     6426//    return(1);
     6427        }
     6428        log_msg(1, "I am in normal, live mode.");
     6429        log_msg(2, "FYI, MOUNTLIST_FNAME = %s", g_mountlist_fname);
     6430        mount_boot_if_necessary();  /* for Gentoo users */
     6431        log_msg(2, "Still here.");
     6432        if (argc > 1 && strcmp(argv[argc - 1], "--live-from-cd") == 0) {
     6433            g_restoring_live_from_cd = TRUE;
     6434        }
     6435        if (bkpinfo->backup_media_type == nfs) {
     6436            g_restoring_live_from_nfs = TRUE;
     6437        }
     6438        if (argc == 5 && strcmp(argv[1], "--monitas-live") == 0) {
     6439            retval =
     6440                restore_live_from_monitas_server(argv[2],
     6441                                                 argv[3], argv[4]);
     6442        } else {
     6443            log_msg(2, "Calling restore_to_live_filesystem()");
     6444            retval = restore_to_live_filesystem();
     6445        }
     6446        log_msg(2, "Still here. Yay.");
     6447        if (strlen(bkpinfo->tmpdir) > 0) {
     6448            sprintf(tmp, "rm -Rf %s/*", bkpinfo->tmpdir);
     6449            run_program_and_log_output(tmp, FALSE);
     6450        }
     6451        unmount_boot_if_necessary();    /* for Gentoo users */
     6452        paranoid_MR_finish(retval);
     6453    } else {
     6454        /* Disaster recovery mode (must be) */
     6455        log_msg(1, "I must be in disaster recovery mode.");
     6456        log_msg(2, "FYI, MOUNTLIST_FNAME = %s ", g_mountlist_fname);
     6457        if (argc == 3 && strcmp(argv[1], "--monitas-memorex") == 0) {
     6458            log_to_screen("Uh, that hasn't been implemented yet.");
     6459            paranoid_MR_finish(1);
     6460        }
     6461
     6462        iamhere("About to call load_mountlist and load_raidtab");
     6463        strcpy(bkpinfo->restore_path, MNT_RESTORING);
     6464        read_cfg_file_into_bkpinfo(g_mondo_cfg_file);
     6465        retval = load_mountlist(mountlist, g_mountlist_fname);
     6466        retval += load_raidtab_into_raidlist(raidlist, RAIDTAB_FNAME);
     6467        iamhere
     6468            ("Returned from calling load_mountlist and load_raidtab successfully");
     6469
     6470        if (argc > 1
     6471            && (strcmp(argv[1], "--compare") == 0
     6472                || strcmp(argv[1], "--nuke") == 0)) {
     6473            if (bkpinfo->backup_media_type == nfs
     6474                && !is_this_device_mounted(bkpinfo->nfs_mount)) {
     6475                log_msg(1, "Mounting nfs dir");
     6476                sprintf(bkpinfo->isodir, "/tmp/isodir");
     6477                run_program_and_log_output("mkdir -p /tmp/isodir", 5);
     6478                sprintf(tmp, "mount %s -t nfs -o nolock /tmp/isodir",
     6479                        bkpinfo->nfs_mount);
     6480                run_program_and_log_output(tmp, 1);
     6481            }
     6482        }
     6483
     6484
     6485        if (retval) {
     6486            log_to_screen
     6487                ("Warning - load_raidtab_into_raidlist returned an error");
     6488        }
     6489
     6490
     6491        log_msg(1, "Send in the clowns.");
     6492
     6493        if (argc == 2 && strcmp(argv[1], "--partition-only") == 0) {
     6494            log_msg(0, "Partitioning only.");
     6495            load_raidtab_into_raidlist(raidlist, RAIDTAB_FNAME);
     6496            strcpy(g_mountlist_fname, "/tmp/mountlist.txt");
     6497            load_mountlist(mountlist, g_mountlist_fname);
     6498            res = partition_everything(mountlist);
     6499            finish(res);
     6500        }
     6501
     6502        if (argc == 2 && strcmp(argv[1], "--format-only") == 0) {
     6503            log_msg(0, "Formatting only.");
     6504            load_raidtab_into_raidlist(raidlist, RAIDTAB_FNAME);
     6505            strcpy(g_mountlist_fname, "/tmp/mountlist.txt");
     6506            load_mountlist(mountlist, g_mountlist_fname);
     6507            res = format_everything(mountlist, FALSE, raidlist);
     6508            finish(res);
     6509        }
     6510
     6511        if (argc == 2 && strcmp(argv[1], "--stop-lvm-and-raid") == 0) {
     6512            log_msg(0, "Stopping LVM and RAID");
     6513            load_raidtab_into_raidlist(raidlist, RAIDTAB_FNAME);
     6514            strcpy(g_mountlist_fname, "/tmp/mountlist.txt");
     6515            load_mountlist(mountlist, g_mountlist_fname);
     6516            res = do_my_funky_lvm_stuff(TRUE, FALSE);
     6517            res += stop_all_raid_devices(mountlist);
     6518            finish(res);
     6519        }
     6520
     6521        if (argc == 2 && strcmp(argv[1], "--nuke") == 0) {
     6522            iamhere("nuking");
     6523            retval += nuke_mode(mountlist, raidlist);
     6524        } else if (argc == 2 && strcmp(argv[1], "--interactive") == 0) {
     6525            iamhere("catchall");
     6526            retval += catchall_mode(mountlist, raidlist);
     6527        } else if (argc == 2 && strcmp(argv[1], "--compare") == 0) {
     6528            iamhere("compare");
     6529            retval += compare_mode(mountlist, raidlist);
     6530        } else if (argc == 2 && strcmp(argv[1], "--iso") == 0) {
     6531            iamhere("iso");
     6532            retval = iso_mode(mountlist, raidlist, FALSE);
     6533        } else if (argc == 2 && strcmp(argv[1], "--mbr") == 0) {
     6534            iamhere("mbr");
     6535            retval = mount_all_devices(mountlist, TRUE);
     6536            if (!retval) {
     6537                retval += run_boot_loader(FALSE);
     6538                retval += unmount_all_devices(mountlist);
     6539            }
     6540            if (retval) {
     6541                log_to_screen("Failed to write Master Boot Record");
     6542            }
     6543        } else if (argc == 2 && strcmp(argv[1], "--isonuke") == 0) {
     6544            iamhere("isonuke");
     6545            retval = iso_mode(mountlist, raidlist, TRUE);
     6546        } else if (argc != 1) {
     6547            log_to_screen("Invalid paremeters");
     6548            paranoid_MR_finish(1);
     6549        } else {
     6550            iamhere("catchall (no mode specified in command-line call");
     6551            retval += catchall_mode(mountlist, raidlist);
     6552        }
     6553    }
     6554
     6555    /* clean up at the end */
     6556    if (retval) {
     6557        if (does_file_exist(MONDO_CACHE"/changed.files")) {
     6558            log_to_screen
     6559                ("See "MONDO_CACHE"/changed.files for list of files that have changed.");
     6560        }
     6561        mvaddstr_and_log_it(g_currentY++,
     6562                            0,
     6563                            "Run complete. Errors were reported. Please review the logfile.");
     6564    } else {
     6565        if (IS_THIS_A_STREAMING_BACKUP(bkpinfo->backup_media_type)) {
     6566            mvaddstr_and_log_it(g_currentY++,
     6567                                0,
     6568                                "Run complete. Please remove media and reboot.");
     6569        } else {
     6570            run_program_and_log_output("sync", FALSE);
     6571            if (is_this_device_mounted(MNT_CDROM)) {
     6572                res =
     6573                    run_program_and_log_output("umount " MNT_CDROM, FALSE);
     6574            } else {
     6575                res = 0;
     6576            }
     6577
     6578            if (!bkpinfo->please_dont_eject) {
     6579                res = eject_device("/dev/cdrom");
     6580/*
     6581              if (res)
     6582        {
     6583          log_to_screen( "WARNING - failed to eject CD-ROM disk" );
     6584        }
     6585*/
     6586            }
     6587            mvaddstr_and_log_it(g_currentY++,
     6588                                0,
     6589                                "Run complete. Please remove media and reboot.");
     6590        }
     6591    }
     6592
     6593// g_I_have_just_nuked is set true by nuke_mode() just before it returns
     6594    if (!system("which post-nuke > /dev/null 2> /dev/null")) {
     6595      log_msg(1, "post-nuke found; find out whether we should run it...");
     6596      if (g_I_have_just_nuked || does_file_exist("/POST-NUKE-ANYWAY")) {
     6597        run_postnuke = TRUE;
     6598        log_msg(1, "Yes, will run post-nuke because in nuke mode or file /POST-NUKE-ANYWAY exists.");
     6599      } else if (ask_me_yes_or_no("post-nuke script found. Do you want to run it?")) {
     6600        run_postnuke = TRUE;
     6601        log_msg(1, "Yes, will run post-nuke because user interactively asked for it.");
     6602      } else {
     6603        run_postnuke = FALSE;
     6604        log_msg(1, "No, will not run post-nuke.");
     6605      }
     6606    } else {
     6607      log_msg(1, "No post-nuke found.");
     6608    }
     6609    if (run_postnuke) {
     6610      log_to_screen("Running post-nuke...");
     6611      if (mount_all_devices(mountlist, TRUE)) {
     6612        log_to_screen
     6613          ("Unable to re-mount partitions for post-nuke stuff");
     6614      } else {
     6615        log_msg(1, "Re-mounted partitions for post-nuke stuff");
     6616        sprintf(tmp, "post-nuke %s %d", bkpinfo->restore_path,
     6617            retval);
     6618        log_msg(2, "Calling '%s'", tmp);
     6619        if ((res = run_program_and_log_output(tmp, 0))) {
     6620          log_OS_error(tmp);
     6621        }
     6622        log_msg(1, "post-nuke returned w/ res=%d", res);
     6623      }
     6624      unmount_all_devices(mountlist);
     6625      log_to_screen("I've finished post-nuking.");
     6626    }
     6627
     6628/* 
     6629  log_to_screen("If you are REALLY in a hurry, hit Ctrl-Alt-Del now.");
     6630  log_to_screen("Otherwise, please wait until the RAID disks are done.");
     6631  wait_until_software_raids_are_prepped("/proc/mdstat", 100);
     6632  log_to_screen("Thank you.");
     6633*/
     6634    unlink("/tmp/mondo-run-prog.tmp");
     6635    set_signals(FALSE);
     6636    log_to_screen("Restore log (%s) copied to /var/log on your hard disk", MONDO_LOGFILE);
     6637    sprintf(tmp,
     6638            "Mondo-restore is exiting (retval=%d)                                      ",
     6639            retval);
     6640    log_to_screen(tmp);
     6641    sprintf(tmp, "umount %s", bkpinfo->isodir);
     6642    run_program_and_log_output(tmp, 5);
     6643    paranoid_free(mountlist);
     6644    paranoid_free(raidlist);
     6645    if (am_I_in_disaster_recovery_mode()) {
     6646        run_program_and_log_output("mount / -o remount,rw", 2);
     6647    }                           // for b0rken distros
     6648    sprintf(tmp, "rm -Rf %s", bkpinfo->tmpdir);
     6649    system(tmp);
     6650    paranoid_MR_finish(retval); // frees global stuff plus bkpinfo
     6651    free_libmondo_global_strings(); // it's fine to have this here :) really :)
     6652    paranoid_free(a);
     6653    paranoid_free(b);
     6654    paranoid_free(tmp);
     6655
     6656    unlink("/tmp/filelist.full");
     6657    unlink("/tmp/filelist.full.gz");
     6658
     6659    exit(retval);
     6660}
     6661
     6662/**************************************************************************
     6663 *END_MAIN                                                                *
     6664 **************************************************************************/
     6665
     6666
     6667
     6668
     6669
     6670/**************************************************************************
     6671 *END_MONDO-RESTORE.C                                                     *
     6672 **************************************************************************/
Note: See TracChangeset for help on using the changeset viewer.