source: trunk/mondo/src/common/libmondo-devices.c @ 835

Last change on this file since 835 was 835, checked in by bruno, 13 years ago

Fic compilation warnings and errors (trying o get a building trunk again)

  • Property svn:keywords set to Id
File size: 65.4 KB
RevLine 
[688]1/*
2 * $Id: libmondo-devices.c 835 2006-09-25 22:21:21Z bruno $
[171]3 * Subroutines for handling devices
4 */
[1]5/**
6 * @file
7 * Functions to handle interactions with backup devices.
8 */
9
10#include "my-stuff.h"
11#include "mondostructures.h"
12#include "libmondo-files-EXT.h"
13#include "libmondo-devices.h"
14#include "libmondo-string-EXT.h"
15#include "libmondo-tools-EXT.h"
[507]16#include "newt-specific-EXT.h"
[1]17#include "libmondo-fork-EXT.h"
18#include "libmondo-stream-EXT.h"
19
[146]20#include <sys/ioctl.h>
[1]21#include <sys/types.h>
[688]22#include <unistd.h>
[1]23#ifdef __FreeBSD__
24#define DKTYPENAMES
25#define FSTYPENAMES
26#include <sys/disklabel.h>
27#include <sys/disk.h>
28#elif linux
29#define u64 unsigned long long
[59]30#include <linux/fs.h>           /* for BLKGETSIZE64 */
[1]31#include <linux/hdreg.h>
32#endif
33
34/*@unused@*/
[59]35//static char cvsid[] = "$Id: libmondo-devices.c 835 2006-09-25 22:21:21Z bruno $";
[1]36
37extern int g_current_media_number;
38extern double g_kernel_version;
39
40extern bool g_ISO_restore_mode;
41extern struct s_bkpinfo *g_bkpinfo_DONTUSETHIS;
42extern char *g_erase_tmpdir_and_scratchdir;
[75]43extern char *g_selfmounted_isodir;
[1]44
[171]45static char *g_cdrw_drive_is_here = NULL;
46static char *g_cdrom_drive_is_here = NULL;
47static char *g_dvd_drive_is_here = NULL;
[1]48
49
50/**
51 * ????? @bug ?????
52 * @ingroup globalGroup
53 */
[59]54bool g_restoring_live_from_cd = FALSE;
[1]55
[59]56extern t_bkptype g_backup_media_type;   // set by main()
[1]57
58
59
60
61void set_g_cdrom_and_g_dvd_to_bkpinfo_value(struct s_bkpinfo *bkpinfo)
62{
[171]63    if (bkpinfo->media_device != NULL) {
[688]64        paranoid_alloc(g_cdrom_drive_is_here, bkpinfo->media_device);   // just in case
65        paranoid_alloc(g_dvd_drive_is_here, bkpinfo->media_device); // just in case
[171]66    }
[1]67}
68
69
70
71/**
72 * Retract all CD trays and wait for autorun to complete.
73 * @ingroup deviceGroup
74 */
75void retract_CD_tray_and_defeat_autorun(void)
76{
77//  log_it("rctada: Retracting all CD trays", __LINE__);
[59]78    if (strlen(g_cdrom_drive_is_here) > 0) {
79        inject_device(g_cdrom_drive_is_here);
80    }
81    if (strlen(g_dvd_drive_is_here) > 0) {
82        inject_device(g_dvd_drive_is_here);
83    }
84    if (strlen(g_cdrw_drive_is_here) > 0) {
85        inject_device(g_cdrw_drive_is_here);
86    }
[1]87//  log_it("rctada: killing autorun");
88//  run_program_and_log_output("killall autorun", TRUE);
[59]89    if (!run_program_and_log_output("ps | grep autorun | grep -v grep", 5)) {
90        log_it("autorun detected; sleeping for 2 seconds");
91        sleep(2);
92    }
93    log_it("rctada: Unmounting all CD drives", __LINE__);
94    run_program_and_log_output("umount /dev/cdr* /dev/dvd*", 5);
[1]95}
96
97
[783]98/**
99 * Mount the CD-ROM at @p mountpoint.
100 * @param device The device (or file if g_ISO_restore_mode) to mount.
101 * @param mountpoint The place to mount it.
102 * @return TRUE for success, FALSE for failure.
103 */
104bool mount_CDROM_here(char *device, char *mountpoint)
105{
106    /*@ buffer ****************************************************** */
107    char *command = NULL;
108    int retval = 0;
[1]109
[783]110    assert_string_is_neither_NULL_nor_zerolength(device);
111    assert_string_is_neither_NULL_nor_zerolength(mountpoint);
112
113    make_hole_for_dir(mountpoint);
114    if (isdigit(device[0])) {
115        paranoid_free(device);
116        device = find_cdrom_device(FALSE);
117    }
118    if (g_ISO_restore_mode) {
119
120#ifdef __FreeBSD__
121        char *dev = NULL;
122
123        dev = make_vn(device));
124        if (!dev) {
125            asprintf(&command, "Unable to mount ISO (make_vn(%s) failed)",
126                    device);
127            fatal_error(command);
128        }
129        paranoid_free(device);
130        device = dev;
131#endif
132    }
133
134    log_msg(4, "(mount_CDROM_here --- device=%s, mountpoint=%s", device,
135            mountpoint);
136    /*@ end vars *************************************************** */
137
138#ifdef __FreeBSD__
139    asprintf(&command, "mount_cd9660 -r %s %s 2>> %s",
140            device, mountpoint, MONDO_LOGFILE);
141#else
142    asprintf(&command, "mount %s -o ro,loop -t iso9660 %s 2>> %s",
143            device, mountpoint, MONDO_LOGFILE);
144#endif
145
146    log_msg(4, command);
147    if (strncmp(device, "/dev/", 5) == 0) {
148        retract_CD_tray_and_defeat_autorun();
149    }
150    retval = system(command);
151    log_msg(1, "system(%s) returned %d", command, retval);
152    paranoid_free(command);
153
154    if (retval == 0) {
155        return(TRUE);
156    } else {
157        return(FALSE);
158    }
159}
160
161
162
[1]163/**
164 * Determine whether we're booted off a ramdisk.
165 * @return @c TRUE (we are) or @c FALSE (we aren't).
166 * @ingroup utilityGroup
167 */
[59]168bool am_I_in_disaster_recovery_mode(void)
[1]169{
[59]170    char *tmp, *comment;
171    bool is_this_a_ramdisk = FALSE;
[1]172
[146]173    asprintf(&tmp, where_is_root_mounted());
174    asprintf(&comment, "root is mounted at %s\n", tmp);
[59]175    log_msg(0, comment);
[146]176    paranoid_free(comment);
177
[59]178    log_msg(0,
179            "No, Schlomo, that doesn't mean %s is the root partition. It's just a debugging message. Relax. It's part of am_I_in_disaster_recovery_mode().",
180            tmp);
[1]181
182#ifdef __FreeBSD__
[59]183    if (strstr(tmp, "/dev/md")) {
184        is_this_a_ramdisk = TRUE;
185    }
[1]186#else
[59]187    if (!strncmp(tmp, "/dev/ram", 8)
188        || (!strncmp(tmp, "/dev/rd", 7) && !strcmp(tmp, "/dev/rd/")
189            && strncmp(tmp, "/dev/rd/cd", 10)) || strstr(tmp, "rootfs")
190        || !strcmp(tmp, "/dev/root")) {
191        is_this_a_ramdisk = TRUE;
192    } else {
193        is_this_a_ramdisk = FALSE;
194    }
[1]195#endif
[146]196    paranoid_free(tmp);
[1]197
[59]198    if (is_this_a_ramdisk) {
199        if (!does_file_exist("/THIS-IS-A-RAMDISK")
200            && !does_file_exist("/tmp/mountlist.txt.sample")) {
201            log_to_screen
[507]202                (_("Using /dev/root is stupid of you but I'll forgive you."));
[59]203            is_this_a_ramdisk = FALSE;
204        }
205    }
206    if (does_file_exist("/THIS-IS-A-RAMDISK")) {
207        is_this_a_ramdisk = TRUE;
208    }
209    log_msg(1, "Is this a ramdisk? result = %d", is_this_a_ramdisk);
210    return (is_this_a_ramdisk);
[1]211}
212
213
214/**
215 * Turn @c bkpinfo->backup_media_type into a human-readable string.
216 * @return The human readable string (e.g. @c cdr becomes <tt>"cdr"</tt>).
217 * @note The returned string points to static storage that will be overwritten with each call.
218 * @ingroup stringGroup
219 */
[171]220char *bkptype_to_string(t_bkptype bt)
[1]221{
[171]222    char *output = NULL;
[146]223
224    paranoid_free(output);
225
[59]226    switch (bt) {
227    case none:
[507]228        asprintf(&output, _("none"));
[1]229        break;
[59]230    case iso:
[507]231        asprintf(&output, _("iso"));
[1]232        break;
[59]233    case cdr:
[507]234        asprintf(&output, _("cdr"));
[1]235        break;
[59]236    case cdrw:
[507]237        asprintf(&output, _("cdrw"));
[1]238        break;
[59]239    case cdstream:
[507]240        asprintf(&output, _("cdstream"));
[1]241        break;
[59]242    case nfs:
[507]243        asprintf(&output, _("nfs"));
[1]244        break;
[59]245    case tape:
[507]246        asprintf(&output, _("tape"));
[1]247        break;
[59]248    case udev:
[507]249        asprintf(&output, _("udev"));
[1]250        break;
[59]251    default:
[507]252        asprintf(&output, _("default"));
[59]253    }
[147]254    return (output);
[1]255}
256
257
258/**
259 * @addtogroup deviceGroup
260 * @{
261 */
262/**
263 * Eject the tray of the specified CD device.
264 * @param dev The device to eject.
265 * @return the return value of the @c eject command. (0=success, nonzero=failure)
266 */
[59]267int eject_device(char *dev)
[1]268{
[59]269    char *command;
270    int res1 = 0, res2 = 0;
[1]271
[59]272    if (IS_THIS_A_STREAMING_BACKUP(g_backup_media_type)
273        && g_backup_media_type != udev) {
[146]274        asprintf(&command, "mt -f %s offline", dev);
[59]275        res1 = run_program_and_log_output(command, 1);
[146]276        paranoid_free(command);
[59]277    } else {
278        res1 = 0;
279    }
[1]280
281#ifdef __FreeBSD__
[59]282    if (strstr(dev, "acd")) {
[146]283        asprintf(&command, "cdcontrol -f %s eject", dev);
[59]284    } else {
[146]285        asprintf(&command, "camcontrol eject `echo %s | sed 's|/dev/||'`",
[59]286                dev);
287    }
[1]288#else
[146]289    asprintf(&command, "eject %s", dev);
[1]290#endif
291
[59]292    log_msg(3, "Ejecting %s", dev);
293    res2 = run_program_and_log_output(command, 1);
294    paranoid_free(command);
295    if (res1 && res2) {
296        return (1);
297    } else {
298        return (0);
299    }
[1]300}
301
[146]302
[1]303/**
304 * Load (inject) the tray of the specified CD device.
305 * @param dev The device to load/inject.
306 * @return 0 for success, nonzero for failure.
307 */
[59]308int inject_device(char *dev)
[1]309{
[59]310    char *command;
311    int i;
[1]312
313#ifdef __FreeBSD__
[59]314    if (strstr(dev, "acd")) {
[146]315        asprintf(&command, "cdcontrol -f %s close", dev);
[59]316    } else {
[146]317        asprintf(&command, "camcontrol load `echo %s | sed 's|/dev/||'`",
[59]318                dev);
319    }
[1]320#else
[146]321    asprintf(&command, "eject -t %s", dev);
[1]322#endif
[59]323    i = run_program_and_log_output(command, FALSE);
324    paranoid_free(command);
325    return (i);
[1]326}
327
328
329/**
330 * Determine whether the specified @p device (really, you can use any file)
331 * exists.
332 * @return TRUE if it exists, FALSE if it doesn't.
333 */
[59]334bool does_device_exist(char *device)
[1]335{
336
[59]337    /*@ buffers *********************************************************** */
338    char *tmp;
[146]339    bool ret;
[1]340
[59]341    assert_string_is_neither_NULL_nor_zerolength(device);
[1]342
[146]343    asprintf(&tmp, "ls %s > /dev/null 2> /dev/null", device);
[59]344
345    if (system(tmp)) {
[146]346        ret = FALSE;
[59]347    } else {
[146]348        ret = TRUE;
[59]349    }
[146]350    paranoid_free(tmp);
351    return(ret);
[1]352}
353
354
355/**
356 * Determine whether a non-Microsoft partition exists on any connected hard drive.
357 * @return TRUE (there's a Linux/FreeBSD partition) or FALSE (Microsoft has taken over yet another innocent PC).
358 */
[59]359bool does_nonMS_partition_exist(void)
[1]360{
361#if __FreeBSD__
[59]362    return
363        !system
364        ("for drive in /dev/ad? /dev/da?; do fdisk $drive | grep -q FreeBSD && exit 0; done; false");
[1]365#else
[59]366    return
367        !system
[687]368        ("parted2fdisk -l 2>/dev/null | grep '^/dev/' | grep -Eqv '(MS|DOS|FAT|NTFS)'");
[1]369#endif
370}
371
372/**
373 * Determine whether the specified @p partno exists on the specified @p drive.
374 * @param drive The drive to search for the partition in.
375 * @param partno The partition number to look for.
376 * @return 0 if it exists, nonzero otherwise.
377 */
[59]378int does_partition_exist(const char *drive, int partno)
[1]379{
[59]380    /*@ buffers **************************************************** */
381    char *program;
[146]382    char *incoming = NULL;
[59]383    char *searchstr;
[688]384    char *tmp;
[1]385
[59]386    /*@ ints ******************************************************* */
387    int res = 0;
[171]388    size_t n = 0;
[1]389
[59]390    /*@ pointers *************************************************** */
391    FILE *fin;
[1]392
393
[59]394    /*@ end vars *************************************************** */
395    assert_string_is_neither_NULL_nor_zerolength(drive);
396    assert(partno >= 0 && partno < 999);
[1]397
398#ifdef __FreeBSD__
[59]399    // We assume here that this is running from mondorestore. (It is.)
[146]400    asprintf(&program, "ls %s >/dev/null 2>&1", drive);
401    res = system(program);
402    paranoid_free(program);
403    return(res);
[1]404#endif
405
[146]406    asprintf(&program, "parted2fdisk -l %s 2> /dev/null", drive);
[59]407    fin = popen(program, "r");
408    if (!fin) {
409        log_it("program=%s", program);
410        log_OS_error("Cannot popen-in program");
[146]411        paranoid_free(program);
[59]412        return (0);
[1]413    }
[146]414    paranoid_free(program);
415
[688]416    searchstr = build_partition_name(drive, partno);
417    asprintf(&tmp, "%s ", searchstr);
418    paranoid_free(searchstr);
419
[146]420    for (res = 0; !res && getline(&incoming, &n, fin);) {
[688]421        if (strstr(incoming, tmp)) {
[59]422            res = 1;
423        }
424    }
[146]425    paranoid_free(incoming);
426
[59]427    if (pclose(fin)) {
428        log_OS_error("Cannot pclose fin");
429    }
[688]430    paranoid_free(tmp);
[59]431    return (res);
[1]432}
433
434
435/**
436 * Determine whether given NULL-terminated @p str exists in the MBR of @p dev.
437 * @param dev The device to look in.
438 * @param str The string to look for.
439 * @return TRUE if it exists, FALSE if it doesn't.
440 */
[59]441bool does_string_exist_in_boot_block(char *dev, char *str)
[1]442{
[59]443    /*@ buffers **************************************************** */
444    char *command;
[1]445
[59]446    /*@ end vars *************************************************** */
[146]447    int ret;
[1]448
[59]449    assert_string_is_neither_NULL_nor_zerolength(dev);
450    assert_string_is_neither_NULL_nor_zerolength(str);
[1]451
[146]452    asprintf(&command,
[59]453            "dd if=%s bs=446 count=1 2> /dev/null | strings | grep \"%s\" > /dev/null 2> /dev/null",
454            dev, str);
[146]455    ret = system(command);
[59]456    paranoid_free(command);
[146]457    if (ret) {
[59]458        return (FALSE);
459    } else {
460        return (TRUE);
461    }
[1]462}
463
[146]464
[1]465/**
466 * Determine whether specified @p str exists in the first @p n sectors of
467 * @p dev.
468 * @param dev The device to look in.
469 * @param str The string to look for.
470 * @param n The number of 512-byte sectors to search.
471 */
[59]472bool does_string_exist_in_first_N_blocks(char *dev, char *str, int n)
[1]473{
[59]474    /*@ buffers **************************************************** */
475    char *command;
476    /*@ end vars *************************************************** */
[146]477    int ret;
[1]478
[146]479    asprintf(&command,
[59]480            "dd if=%s bs=512 count=%i 2> /dev/null | strings | grep \"%s\" > /dev/null 2> /dev/null",
481            dev, n, str);
[146]482    ret = system(command);
[59]483    paranoid_free(command);
[146]484
485    if (ret) {
[59]486        return (FALSE);
487    } else {
488        return (TRUE);
489    }
[1]490}
491
492
493/**
494 * Try to mount CD-ROM at @p mountpoint. If the CD-ROM is not found or has
495 * not been specified, call find_cdrom_device() to find it.
496 * @param bkpinfo The backup information structure. The only field used is @c bkpinfo->media_device.
497 * @param mountpoint Where to mount the CD-ROM.
498 * @return 0 for success, nonzero for failure.
499 * @see mount_CDROM_here
500 */
[171]501bool find_and_mount_actual_cd(struct s_bkpinfo *bkpinfo, char *mountpoint)
[1]502{
[59]503    /*@ buffers ***************************************************** */
[1]504
[59]505    /*@ int's  ****************************************************** */
[171]506    bool res = TRUE;
507    char *dev = NULL;
[1]508
[59]509    /*@ end vars **************************************************** */
[1]510
[59]511    assert(bkpinfo != NULL);
512    assert_string_is_neither_NULL_nor_zerolength(mountpoint);
[1]513
[59]514    if (g_backup_media_type == dvd) {
[171]515        if (g_dvd_drive_is_here != NULL) {
516            asprintf(&dev, g_dvd_drive_is_here);
517        } else {
518            dev = find_dvd_device();
[59]519        }
520    } else {
[171]521        if (g_cdrom_drive_is_here != NULL) {
522            asprintf(&dev, g_cdrom_drive_is_here);
523        } else {
[688]524            // find_cdrom_device allocates the string
[171]525            dev = find_cdrom_device(FALSE);
[59]526        }
527    }
[1]528
[59]529    if (bkpinfo->backup_media_type != iso) {
530        retract_CD_tray_and_defeat_autorun();
531    }
[1]532
[171]533    if ((dev == NULL) || (! mount_CDROM_here(dev, mountpoint))) {
[688]534        paranoid_free(dev);
[59]535        if (!popup_and_get_string
[688]536            (_("CD-ROM device"), _("Please enter your CD-ROM's /dev device"), dev)) {
[171]537            res = FALSE;
[59]538        } else {
539            res = mount_CDROM_here(dev, mountpoint);
540        }
541    }
542    if (res) {
[507]543        log_msg(1, _("mount failed"));
[59]544    } else {
[507]545        log_msg(1, _("mount succeeded with %s"), dev);
[59]546    }
547    paranoid_free(dev);
[171]548    return(res);
[1]549}
550
551
552/**
553 * Locate a CD-R/W writer's SCSI node.
[171]554 * @param cdrw_device SCSI node will be placed here. Caller needs to free it.
555 * @return the cdrw device or NULL if not found
[1]556 */
[171]557char *find_cdrw_device(void)
[1]558{
[689]559    char *comment = NULL;
560    char *tmp = NULL;
561    char *tmp1 = NULL;
562    char *cdr_exe = NULL;
563    char *command = NULL;
564    char *cdrw_device = NULL;
[1]565
[171]566    if (g_cdrw_drive_is_here != NULL) {
567        asprintf(&cdrw_device, g_cdrw_drive_is_here);
[59]568        log_msg(3, "Been there, done that. Returning %s", cdrw_device);
[171]569        return(cdrw_device);
[59]570    }
571    if (g_backup_media_type == dvd) {
572        log_msg(1,
573                "This is dumb. You're calling find_cdrw_device() but you're backing up to DVD. WTF?");
[171]574        return(NULL);
[59]575    }
576    run_program_and_log_output("insmod ide-scsi", -1);
[689]577    tmp = find_home_of_exe("cdrecord");
578    if (tmp) {
[146]579        asprintf(&cdr_exe, "cdrecord");
[59]580    } else {
[146]581        asprintf(&cdr_exe, "dvdrecord");
[59]582    }
[689]583    paranoid_free(tmp);
584
585    tmp1 = find_home_of_exe(cdr_exe);
586    if (tmp1) {
[146]587        asprintf(&command,
[59]588                "%s -scanbus 2> /dev/null | tr -s '\t' ' ' | grep \"[0-9]*,[0-9]*,[0-9]*\" | grep -v \"[0-9]*) \\*\" | grep CD | cut -d' ' -f2 | head -n1",
589                cdr_exe);
[146]590        asprintf(&tmp, call_program_and_get_last_line_of_output(command));
591        paranoid_free(command);
592    } else {
[171]593        asprintf(&tmp, " ");
[59]594    }
[689]595    paranoid_free(tmp1);
[146]596    paranoid_free(cdr_exe);
597
[59]598    if (strlen(tmp) < 2) {
599        paranoid_free(tmp);
[171]600        return(NULL);
[59]601    } else {
[171]602        cdrw_device = tmp;
[146]603
604        asprintf(&comment, "Found CDRW device - %s", cdrw_device);
[59]605        log_it(comment);
[146]606        paranoid_free(comment);
607
[171]608        paranoid_free(g_cdrw_drive_is_here);
609        asprintf(&g_cdrw_drive_is_here, cdrw_device);
610        return(cdrw_device);
[59]611    }
[1]612}
613
614
615/**
616 * Attempt to locate a CD-ROM device's /dev entry.
617 * Several different methods may be used to find the device, including
618 * calling @c cdrecord, searching @c dmesg, and trial-and-error.
[171]619 * @param output Where to put the located /dev entry. Needs to be freed by the caller.
[1]620 * @param try_to_mount Whether to mount the CD as part of the test; if mount
621 * fails then return failure.
[171]622 * @return output if success or NULL otherwise.
[1]623 */
[171]624char *find_cdrom_device(bool try_to_mount)
[1]625{
[59]626    /*@ pointers **************************************************** */
[688]627    FILE *fin = NULL;
628    char *p = NULL;
629    char *q = NULL;
630    char *r = NULL;
[171]631    char *output = NULL;
632    size_t n = 0;
[1]633
[59]634    /*@ bool's ****************************************************** */
635    bool found_it = FALSE;
[1]636
[59]637    /*@ buffers ***************************************************** */
[146]638    char *tmp = NULL;
[688]639    char *cdr_exe = NULL;
[146]640#ifndef __FreeBSD__
641    char *phrase_two = NULL;
642    char *dvd_last_resort = NULL;
643#endif
[688]644    char *command = NULL;
645    char *mountpoint = NULL;
646    static char *the_last_place_i_found_it = NULL;
[1]647
[59]648    /*@ end vars **************************************************** */
[1]649
[171]650    if ((g_cdrom_drive_is_here != NULL) && !isdigit(g_cdrom_drive_is_here[0])) {
651        asprintf(&output, g_cdrom_drive_is_here);
[59]652        log_msg(3, "Been there, done that. Returning %s", output);
[171]653        return(output);
[59]654    }
[688]655    if ((the_last_place_i_found_it != NULL) && !try_to_mount) {
[171]656        asprintf(&output, the_last_place_i_found_it);
[59]657        log_msg(3,
658                "find_cdrom_device() --- returning last found location - '%s'",
659                output);
[171]660        return(output);
[59]661    }
[1]662
[689]663    tmp = find_home_of_exe("cdrecord");
664    if (tmp) {
[146]665        asprintf(&cdr_exe, "cdrecord");
[59]666    } else {
[146]667        asprintf(&cdr_exe, "dvdrecord");
[59]668    }
[689]669    paranoid_free(tmp);
670
671    tmp = find_home_of_exe(cdr_exe);
672    if (!tmp) {
[171]673        asprintf(&output, "/dev/cdrom");
[59]674        log_msg(4, "Can't find cdrecord; assuming %s", output);
675        if (!does_device_exist(output)) {
676            log_msg(4, "That didn't work. Sorry.");
[146]677            paranoid_free(cdr_exe);
[171]678            paranoid_free(output);
679            return(NULL);
[59]680        } else {
[146]681            paranoid_free(cdr_exe);
[171]682            return(output);
[59]683        }
684    }
[689]685    paranoid_free(tmp);
[59]686
[146]687    asprintf(&command, "%s -scanbus 2> /dev/null", cdr_exe);
[59]688    fin = popen(command, "r");
689    if (!fin) {
690        log_msg(4, "command=%s", command);
691        log_OS_error("Cannot popen command");
[146]692        paranoid_free(cdr_exe);
693        paranoid_free(command);
[171]694        return (NULL);
[59]695    }
[146]696    paranoid_free(command);
697
698    for (getline(&tmp, &n, fin); !feof(fin);
699         getline(&tmp, &n, fin)) {
[59]700        p = strchr(tmp, '\'');
701        if (p) {
702            q = strchr(++p, '\'');
703            if (q) {
704                for (r = q; *(r - 1) == ' '; r--);
705                *r = '\0';
706                p = strchr(++q, '\'');
707                if (p) {
708                    q = strchr(++p, '\'');
709                    if (q) {
710                        while (*(q - 1) == ' ') {
711                            q--;
712                        }
713                        *q = '\0';
[146]714#ifndef __FreeBSD__
715                        paranoid_free(phrase_two);
716                        asprintf(&phrase_two, p);
717#endif
[59]718                    }
719                }
[1]720            }
721        }
722    }
[59]723    paranoid_pclose(fin);
[146]724    paranoid_free(tmp);
725    tmp = NULL;
726    n = 0;
[1]727
728#ifndef __FreeBSD__
[59]729    if (strlen(phrase_two) == 0) {
730        log_msg(4, "Not running phase two. String is empty.");
731    } else {
[146]732        asprintf(&command, "dmesg | grep \"%s\" 2> /dev/null", phrase_two);
[59]733        fin = popen(command, "r");
734        if (!fin) {
735            log_msg(4, "Cannot run 2nd command - non-fatal, fortunately");
736        } else {
[146]737            for (getline(&tmp, &n, fin); !feof(fin);
738                 getline(&tmp, &n, fin)) {
[59]739                log_msg(5, "--> '%s'", tmp);
740                if (tmp[0] != ' ' && tmp[1] != ' ') {
741                    p = strchr(tmp, ':');
742                    if (p) {
743                        *p = '\0';
744                        if (strstr(tmp, "DVD")) {
[146]745                            paranoid_free(dvd_last_resort);
746                            asprintf(&dvd_last_resort, "/dev/%s", tmp);
[59]747                            log_msg(4,
748                                    "Ignoring '%s' because it's a DVD drive",
749                                    tmp);
750                        } else {
[171]751                            asprintf(&output, "/dev/%s", tmp);
[59]752                            found_it = TRUE;
753                        }
754                    }
755                }
756            }
[146]757            paranoid_free(tmp);
[59]758            paranoid_pclose(fin);
759        }
[146]760        paranoid_free(command);
[59]761    }
[146]762    paranoid_free(phrase_two);
[1]763
764#endif
765#ifdef __FreeBSD__
[59]766    if (!found_it) {
767        log_msg(4, "OK, approach 2");
768        if (!(found_it = set_dev_to_this_if_rx_OK(output, "/dev/cdrom"))) {
769            if (!
770                (found_it =
771                 set_dev_to_this_if_rx_OK(output, "/dev/cdrom1"))) {
772                if (!
773                    (found_it =
774                     set_dev_to_this_if_rx_OK(output, "/dev/dvd"))) {
775                    if (!
776                        (found_it =
777                         set_dev_to_this_if_rx_OK(output, "/dev/acd0"))) {
778                        if (!
779                            (found_it =
780                             set_dev_to_this_if_rx_OK(output,
781                                                      "/dev/cd01"))) {
782                            if (!
783                                (found_it =
784                                 set_dev_to_this_if_rx_OK(output,
785                                                          "/dev/acd1"))) {
786                                if (!
787                                    (found_it =
788                                     set_dev_to_this_if_rx_OK(output,
789                                                              "/dev/cd1")))
790                                {
[146]791                                    paranoid_free(cdr_exe);
[171]792                                    return(NULL);
[59]793                                }
794                            }
795                        }
796                    }
797                }
798            }
799        }
800    }
[1]801#else
[146]802    if (dvd_last_resort != NULL) {
803        if (!found_it && strlen(dvd_last_resort) > 0) {
804            log_msg(4, "Well, I'll use the DVD - %s - as a last resort",
805                    dvd_last_resort);
[171]806            paranoid_free(output);
807            asprintf(&output, dvd_last_resort);
[146]808            found_it = TRUE;
809        }
[1]810    }
[146]811    paranoid_free(dvd_last_resort);
812
[59]813    if (found_it) {
[146]814        asprintf(&tmp, "grep \"%s=ide-scsi\" /proc/cmdline &> /dev/null",
[59]815                strrchr(output, '/') + 1);
816        if (system(tmp) == 0) {
817            log_msg(4,
818                    "%s is not right. It's being SCSI-emulated. Continuing.",
819                    output);
820            found_it = FALSE;
[171]821            paranoid_free(output);
[59]822        }
[146]823        paranoid_free(tmp);
[59]824    }
[1]825
[59]826    if (found_it) {
827        log_msg(4, "(find_cdrom_device) --> '%s'", output);
828        if (!does_device_exist(output)) {
[171]829            log_msg(4, "OK, I was wrong, I haven't found it... yet.");
[59]830            found_it = FALSE;
[171]831            paranoid_free(output);
[59]832        }
833    }
[1]834
[59]835    if (!found_it) {
836        log_msg(4, "OK, approach 2");
837        if (!(found_it = set_dev_to_this_if_rx_OK(output, "/dev/scd0"))) {
838            if (!(found_it = set_dev_to_this_if_rx_OK(output, "/dev/sr0"))) {
839                if (!
840                    (found_it =
841                     set_dev_to_this_if_rx_OK(output, "/dev/cdrom"))) {
842                    if (!
843                        (found_it =
844                         set_dev_to_this_if_rx_OK(output,
845                                                  "/dev/cdrom0"))) {
846                        if (!
847                            (found_it =
848                             set_dev_to_this_if_rx_OK(output,
849                                                      "/dev/cdrom1"))) {
850                            if (!
851                                (found_it =
852                                 set_dev_to_this_if_rx_OK(output,
853                                                          "/dev/sr1"))) {
854                                if (!
855                                    (found_it =
856                                     set_dev_to_this_if_rx_OK(output,
857                                                              "/dev/dvd")))
858                                {
859                                    if (!
860                                        (found_it =
861                                         set_dev_to_this_if_rx_OK(output,
862                                                                  g_cdrw_drive_is_here)))
863                                    {
[146]864                                        paranoid_free(cdr_exe);
[171]865                                        return(NULL);
[59]866                                    }
867                                }
868                            }
869                        }
870                    }
871                }
872            }
873        }
874    }
[1]875#endif
876
[146]877    asprintf(&mountpoint, "/tmp/cd.%d", (int) (random() % 32767));
878    make_hole_for_dir(mountpoint);
879
[59]880    if (found_it && try_to_mount) {
[171]881        if (! mount_CDROM_here(output, mountpoint)) {
[59]882            log_msg(4, "[Cardigans] I've changed my mind");
883            found_it = FALSE;
[171]884            paranoid_free(output);
[59]885        } else {
[146]886            asprintf(&tmp, "%s/archives", mountpoint);
[59]887            if (!does_file_exist(tmp)) {
888                log_msg(4, "[Cardigans] I'll take it back");
889                found_it = FALSE;
[171]890                paranoid_free(output);
[59]891            } else {
[146]892                asprintf(&command, "umount %s", output);
[59]893                paranoid_system(command);
[146]894                paranoid_free(command);
[59]895                log_msg(4, "I'm confident the Mondo CD is in %s", output);
896            }
[146]897            paranoid_free(tmp);
[59]898        }
899    }
900    unlink(mountpoint);
[146]901    paranoid_free(mountpoint);
[1]902
[59]903    if (found_it) {
904        if (!does_file_exist(output)) {
905            log_msg(3, "I still haven't found it.");
[171]906            paranoid_free(output);
907            return(NULL);
[59]908        }
909        log_msg(3, "(find_cdrom_device) --> '%s'", output);
[688]910        asprintf(&the_last_place_i_found_it, output);
[171]911        paranoid_free(g_cdrom_drive_is_here);
912        asprintf(&g_cdrom_drive_is_here, output);
913        return(output);
[59]914    }
[1]915
[146]916    asprintf(&command,
[59]917            "%s -scanbus | grep \"[0-9],[0-9],[0-9]\" | grep \"[D|C][V|D]\" | grep -n \"\" | grep \"%s\" | cut -d':' -f2",
918            cdr_exe, g_cdrw_drive_is_here);
[171]919    paranoid_free(cdr_exe);
920
[59]921    log_msg(1, "command=%s", command);
[146]922    asprintf(&tmp, call_program_and_get_last_line_of_output(command));
923    paranoid_free(command);
924
[59]925    if (tmp[0]) {
[171]926        output = tmp;
[59]927        log_msg(4, "Finally found it at %s", output);
928    } else {
[171]929        paranoid_free(tmp);
930        paranoid_free(output);
[59]931        log_msg(4, "Still couldn't find it.");
932    }
[171]933    return(output);
[1]934}
935
936
[171]937char *find_dvd_device()
[1]938{
[688]939    char *tmp = NULL;
[59]940    int retval = 0, devno = -1;
[171]941    char *output = NULL; 
[1]942
[171]943    if (g_dvd_drive_is_here != NULL) {
944        asprintf(&output, g_dvd_drive_is_here);
[59]945        log_msg(3, "Been there, done that. Returning %s", output);
[171]946        return (output);
[59]947    }
[1]948
[146]949    asprintf(&tmp, call_program_and_get_last_line_of_output
[59]950            ("dvdrecord -scanbus 2> /dev/null | grep \") '\" | grep -n \"\" | grep DVD | cut -d':' -f1")
[1]951        );
[59]952    log_msg(5, "tmp = '%s'", tmp);
[146]953    if (!tmp[0]) {
954        paranoid_free(tmp);
955        asprintf(&tmp, call_program_and_get_last_line_of_output
[59]956                ("cdrecord -scanbus 2> /dev/null | grep \") '\" | grep -n \"\" | grep DVD | cut -d':' -f1")
957            );
[146]958    }
[59]959    if (tmp[0]) {
960        devno = atoi(tmp) - 1;
961    }
[146]962    paranoid_free(tmp);
963
[59]964    if (devno >= 0) {
965        retval = 0;
[171]966        asprintf(&output, "/dev/scd%d", devno);
967        paranoid_free(g_dvd_drive_is_here);
968        asprintf(&g_dvd_drive_is_here, output);
[59]969        log_msg(2, "I think DVD is at %s", output);
970    } else {
971        log_msg(2, "I cannot find DVD");
972    }
[1]973
[171]974    return(output);
[1]975}
976
977
978/**
979 * Find the size of the specified @p drive, in megabytes. Uses @c ioctl calls
980 * and @c dmesg.
981 * @param drive The device to find the size of.
982 * @return size in megabytes.
983 */
[59]984long get_phys_size_of_drive(char *drive)
[1]985{
[59]986    int fd;
[1]987#if linux
[59]988    unsigned long long s = 0;
989    int fileid, cylinders = 0, cylindersleft = 0;
990    int cylindersize = 0;
[1]991    int gotgeo = 0;
992
[59]993
994    struct hd_geometry hdgeo;
[1]995#elif __FreeBSD__
[59]996    off_t s;
[1]997#endif
998
[59]999    long outvalA = -1;
1000    long outvalB = -1;
1001    long outvalC = -1;
[1]1002
[59]1003    if ((fd = open(drive, O_RDONLY)) != -1) {
1004        if (ioctl(fd,
[1]1005#if linux
[59]1006#ifdef BLKGETSIZE64
1007                  BLKGETSIZE64,
1008#else
1009                  BLKGETSIZE,
1010#endif
[1]1011#elif __FreeBSD__
[59]1012                  DIOCGMEDIASIZE,
[1]1013#endif
[59]1014                  &s) != -1) {
1015            close(fd);
1016            // s>>11 works for older disks but not for newer ones
1017            outvalB =
[1]1018#if linux
[59]1019#ifdef BLKGETSIZE64
1020                s >> 20
[1]1021#else
[59]1022                s >> 11
[1]1023#endif
[59]1024#else
1025                s >> 20
1026#endif
1027                ;
1028        }
[1]1029    }
1030
[59]1031    if (outvalB <= 0) {
1032        log_msg(1, "Error getting size of %s: %s", drive, strerror(errno));
[1]1033#if linux
[59]1034    fileid = open(drive, O_RDONLY);
[1]1035    if (fileid) {
[59]1036        if (ioctl(fileid, HDIO_GETGEO, &hdgeo) != -1) {
[1]1037            if (hdgeo.cylinders && hdgeo.heads && hdgeo.sectors) {
1038                cylindersleft = cylinders = hdgeo.cylinders;
1039                cylindersize = hdgeo.heads * hdgeo.sectors / 2;
1040                outvalA = cylindersize * cylinders / 1024;
[59]1041                log_msg(2, "Got Harddisk geometry, C:%d, H:%d, S:%d",
1042                        hdgeo.cylinders, hdgeo.heads, hdgeo.sectors);
[1]1043                gotgeo = 1;
1044            } else {
[59]1045                log_msg(1, "Harddisk geometry wrong");
[1]1046            }
1047        } else {
[59]1048            log_msg(1,
1049                    "Error in ioctl() getting new hard disk geometry (%s), resizing in unsafe mode",
1050                    strerror(errno));
[1]1051        }
1052        close(fileid);
1053    } else {
[59]1054        log_msg(1, "Failed to open %s for reading: %s", drive,
1055                strerror(errno));
[1]1056    }
1057    if (!gotgeo) {
[59]1058        log_msg(1, "Failed to get harddisk geometry, using old mode");
[1]1059    }
1060#endif
[162]1061    }
[1]1062// OLDER DISKS will give ridiculously low value for outvalB (so outvalA is returned) :)
1063// NEWER DISKS will give sane value for outvalB (close to outvalA, in other words) :)
1064
[59]1065    outvalC = (outvalA > outvalB) ? outvalA : outvalB;
1066
[1]1067//  log_msg (5, "drive = %s, error = %s", drive, strerror (errno));
1068//  fatal_error ("GPSOD: Unable to get size of drive");
[59]1069    log_msg(1, "%s --> %ld or %ld --> %ld", drive, outvalA, outvalB,
1070            outvalC);
1071
1072    return (outvalC);
[1]1073}
[59]1074
[1]1075
1076/**
1077 * Determine whether @p format is supported by the kernel. Uses /proc/filesystems
1078 * under Linux and @c lsvfs under FreeBSD.
1079 * @param format The format to test.
1080 * @return TRUE if the format is supported, FALSE if not.
1081 */
[59]1082bool is_this_a_valid_disk_format(char *format)
[1]1083{
[688]1084    char *good_formats = NULL;
1085    char *command = NULL;
1086    char *tmp = NULL;
1087    char *format_sz = NULL;
[1]1088
[688]1089    FILE *pin = NULL;
[146]1090    bool retval;
[688]1091    size_t n = 0;
[59]1092    assert_string_is_neither_NULL_nor_zerolength(format);
[1]1093
[146]1094    asprintf(&format_sz, "%s ", format);
[1]1095
1096#ifdef __FreeBSD__
[146]1097    asprintf(&command,
[59]1098            "lsvfs | tr -s '\t' ' ' | grep -v Filesys | grep -v -- -- | cut -d' ' -f1 | tr -s '\n' ' '");
[1]1099#else
[146]1100    asprintf(&command,
[274]1101            "grep -v nodev /proc/filesystems | tr -s '\t' ' ' | cut -d' ' -f2 | tr -s '\n' ' '");
[1]1102#endif
1103
[59]1104    pin = popen(command, "r");
[146]1105    paranoid_free(command);
1106
[59]1107    if (!pin) {
1108        log_OS_error("Unable to read good formats");
[146]1109        retval = FALSE;
[59]1110    } else {
[688]1111        getline(&good_formats, &n , pin);
[59]1112        if (pclose(pin)) {
1113            log_OS_error("Cannot pclose good formats");
1114        }
1115        strip_spaces(good_formats);
[688]1116        // " ntfs 7 " -- um, cheating much? :)
1117        asprintf(&tmp, " %s swap lvm raid ntfs 7 ",good_formats);
1118        paranoid_free(good_formats);
1119        good_formats = tmp;
1120
[59]1121        if (strstr(good_formats, format_sz)) {
[146]1122            retval = TRUE;
[59]1123        } else {
[146]1124            retval = FALSE;
[59]1125        }
[688]1126        paranoid_free(good_formats);
[59]1127    }
1128    paranoid_free(format_sz);
1129    return (retval);
[1]1130}
1131
1132
1133/** @def SWAPLIST_COMMAND The command to list the swap files/partitions in use. */
1134
1135/**
1136 * Determine whether @p device_raw is currently mounted.
1137 * @param device_raw The device to check.
1138 * @return TRUE if it's mounted, FALSE if not.
1139 */
[59]1140bool is_this_device_mounted(char *device_raw)
[1]1141{
1142
[59]1143    /*@ pointers **************************************************** */
1144    FILE *fin;
[1]1145
[59]1146    /*@ buffers ***************************************************** */
[146]1147    char *incoming = NULL;
[59]1148    char *device_with_tab;
1149    char *device_with_space;
1150    char *tmp;
[171]1151    size_t n = 0;
[59]1152
[1]1153#ifdef __FreeBSD__
[59]1154#define SWAPLIST_COMMAND "swapinfo"
[1]1155#else
[59]1156#define SWAPLIST_COMMAND "cat /proc/swaps"
[1]1157#endif
1158
[59]1159    /*@ end vars **************************************************** */
[1]1160
[59]1161    assert(device_raw != NULL);
[1]1162//  assert_string_is_neither_NULL_nor_zerolength(device_raw);
[59]1163    if (device_raw[0] != '/' && !strstr(device_raw, ":/")) {
1164        log_msg(1, "%s needs to have a '/' prefixed - I'll do it",
1165                device_raw);
[146]1166        asprintf(&tmp, "/%s", device_raw);
[59]1167    } else {
[146]1168        asprintf(&tmp, device_raw);
[59]1169    }
1170    log_msg(1, "Is %s mounted?", tmp);
1171    if (!strcmp(tmp, "/proc") || !strcmp(tmp, "proc")) {
1172        log_msg(1,
1173                "I don't know how the heck /proc made it into the mountlist. I'll ignore it.");
[146]1174        return (FALSE);
[59]1175    }
[146]1176    asprintf(&device_with_tab, "%s\t", tmp);
1177    asprintf(&device_with_space, "%s ", tmp);
1178    paranoid_free(tmp);
[1]1179
[59]1180    if (!(fin = popen("mount", "r"))) {
1181        log_OS_error("Cannot popen 'mount'");
1182        return (FALSE);
[1]1183    }
[146]1184    for (getline(&incoming, &n, fin); !feof(fin);
1185         getline(&incoming, &n, fin)) {
[59]1186        if (strstr(incoming, device_with_space) //> incoming
1187            || strstr(incoming, device_with_tab))   // > incoming)
1188        {
1189            paranoid_pclose(fin);
[146]1190            return(TRUE);
[59]1191        }
1192    }
[146]1193    paranoid_free(incoming);
1194    paranoid_free(device_with_tab);
[59]1195    paranoid_pclose(fin);
[146]1196
1197    asprintf(&tmp, "%s | grep -w \"%s\" > /dev/null 2> /dev/null",
[59]1198            SWAPLIST_COMMAND, device_with_space);
[146]1199    paranoid_free(device_with_space);
1200
[59]1201    log_msg(4, "tmp (command) = '%s'", tmp);
1202    if (!system(tmp)) {
[146]1203        paranoid_free(tmp);
1204        return(TRUE);
[59]1205    }
1206    paranoid_free(tmp);
[146]1207    return (FALSE);
[1]1208}
1209
[146]1210
[1]1211#ifdef __FreeBSD__
1212//                       CODE IS FREEBSD-SPECIFIC
1213/**
1214 * Create a loopback device for specified @p fname.
1215 * @param fname The file to associate with a device.
[146]1216 * @return /dev entry for the device (to be freed by the caller),
1217 * or NULL if it couldn't be allocated.
[1]1218 */
[59]1219char *make_vn(char *fname)
[1]1220{
[688]1221    char *device = NULL;
[146]1222    char *mddevice = NULL;
1223    char *command = NULL;
[59]1224    int vndev = 2;
[146]1225
[59]1226    if (atoi
1227        (call_program_and_get_last_line_of_output
1228         ("/sbin/sysctl -n kern.osreldate")) < 500000) {
1229        do {
[146]1230            paranoid_free(mddevice);
1231            asprintf(&mddevice, "vn%ic", vndev++);
1232
1233            paranoid_free(command);
1234            asprintf(&command, "vnconfig %s %s", mddevice, fname);
1235
[59]1236            if (vndev > 10) {
[146]1237                paranoid_free(command);
1238                paranoid_free(mddevice);
[59]1239                return NULL;
1240            }
1241        }
1242        while (system(command));
[146]1243        paranoid_free(command);
[59]1244    } else {
[146]1245        asprintf(&command, "mdconfig -a -t vnode -f %s", fname);
1246        asprintf(&mddevice, call_program_and_get_last_line_of_output(command));
1247        paranoid_free(command);
1248
[59]1249        if (!strstr(mddevice, "md")) {
[146]1250            paranoid_free(mddevice);
[59]1251            return NULL;
1252        }
1253    }
[146]1254    asprintf(&device, "/dev/%s", mddevice);
1255    paranoid_free(mddevice);
1256    return(device);
[1]1257}
1258
1259
1260//                       CODE IS FREEBSD-SPECIFIC
1261/**
1262 * Deallocate specified @p dname.
1263 * This should be called when you are done with the device created by make_vn(),
1264 * so the system does not run out of @c vn devices.
1265 * @param dname The device to deallocate.
1266 * @return 0 for success, nonzero for failure.
1267 */
[59]1268int kick_vn(char *dname)
[1]1269{
[146]1270    char *command;
1271    int ret = 0;
[1]1272
[59]1273    if (strncmp(dname, "/dev/", 5) == 0) {
1274        dname += 5;
1275    }
[1]1276
[59]1277    if (atoi
1278        (call_program_and_get_last_line_of_output
1279         ("/sbin/sysctl -n kern.osreldate")) < 500000) {
[146]1280        asprintf(&command, "vnconfig -d %s", dname);
1281        ret = system(command);
1282        paranoid_free(command);
1283        return(ret);
[59]1284    } else {
[146]1285        asprintf(&command, "mdconfig -d -u %s", dname);
1286        ret = system(command);
1287        paranoid_free(command);
1288        return(ret);
[59]1289    }
1290     /*NOTREACHED*/ return 255;
[1]1291}
1292#endif
1293
1294
1295/**
1296 * Ask the user for CD number @p cd_number_i_want.
1297 * Sets g_current_media_number once the correct CD is inserted.
1298 * @param bkpinfo The backup information structure. Fields used:
1299 * - @c bkpinfo->backup_media_type
[20]1300 * - @c bkpinfo->prefix
[1]1301 * - @c bkpinfo->isodir
1302 * - @c bkpinfo->media_device
1303 * - @c bkpinfo->please_dont_eject_when_restoring
1304 * @param cd_number_i_want The CD number to ask for.
1305 */
1306void
[59]1307insist_on_this_cd_number(struct s_bkpinfo *bkpinfo, int cd_number_i_want)
[1]1308{
1309
[59]1310    /*@ int ************************************************************* */
1311    int res = 0;
[1]1312
1313
[59]1314    /*@ buffers ********************************************************* */
1315    char *tmp;
1316    char *request;
[1]1317
[59]1318    assert(bkpinfo != NULL);
1319    assert(cd_number_i_want > 0);
[1]1320
1321//  log_msg(3, "Insisting on CD number %d", cd_number_i_want);
1322
[59]1323    if (IS_THIS_A_STREAMING_BACKUP(bkpinfo->backup_media_type)) {
1324        log_msg(3,
1325                "No need to insist_on_this_cd_number when the backup type isn't CD-R(W) or NFS or ISO");
1326        return;
1327    }
[146]1328
1329    asprintf(&tmp, "mkdir -p " MNT_CDROM);
[59]1330    run_program_and_log_output(tmp, 5);
[146]1331    paranoid_free(tmp);
1332
[59]1333    if (g_ISO_restore_mode || bkpinfo->backup_media_type == iso
1334        || bkpinfo->backup_media_type == nfs) {
1335        log_msg(3, "Remounting CD");
1336        g_ISO_restore_mode = TRUE;
[1]1337// FIXME --- I'm tempted to do something about this...
1338// Why unmount and remount again and again?
[59]1339        if (is_this_device_mounted(MNT_CDROM)) {
1340            run_program_and_log_output("umount " MNT_CDROM, 5);
1341        }
1342        system("mkdir -p /tmp/isodir &> /dev/null");
[146]1343        asprintf(&tmp, "%s/%s/%s-%d.iso", bkpinfo->isodir,
[59]1344                bkpinfo->nfs_remote_dir, bkpinfo->prefix,
1345                cd_number_i_want);
1346        if (!does_file_exist(tmp)) {
[146]1347            paranoid_free(tmp);
1348            asprintf(&tmp, "/tmp/isodir/%s/%s-%d.iso",
[59]1349                    bkpinfo->nfs_remote_dir, bkpinfo->prefix,
1350                    cd_number_i_want);
1351            if (does_file_exist(tmp)) {
1352                log_msg(1,
1353                        "FIXME - hacking bkpinfo->isodir from '%s' to /tmp/isodir",
1354                        bkpinfo->isodir);
[783]1355                paranoid_alloc(bkpinfo->isodir, "/tmp/isodir");
[59]1356            }
1357        }
1358        log_msg(3, "Mounting %s at %s", tmp, MNT_CDROM);
[171]1359        if (! mount_CDROM_here(tmp, MNT_CDROM)) {
[59]1360            fatal_error("Mommy!");
1361        }
[146]1362        paranoid_free(tmp);
[1]1363    }
[59]1364    if ((res = what_number_cd_is_this(bkpinfo)) != cd_number_i_want) {
1365        log_msg(3, "Currently, we hold %d but we want %d", res,
1366                cd_number_i_want);
[146]1367        asprintf(&tmp, "Insisting on %s #%d",
[783]1368                bkpinfo->backup_media_string,
[59]1369                cd_number_i_want);
[146]1370        asprintf(&request, "Please insert %s #%d and press Enter.",
[783]1371                bkpinfo->backup_media_string,
[59]1372                cd_number_i_want);
1373        log_msg(3, tmp);
[146]1374        paranoid_free(tmp);
1375
[59]1376        while (what_number_cd_is_this(bkpinfo) != cd_number_i_want) {
[688]1377            sync();
[59]1378            if (is_this_device_mounted(MNT_CDROM)) {
1379                res =
1380                    run_program_and_log_output("umount " MNT_CDROM, FALSE);
1381            } else {
1382                res = 0;
1383            }
1384            if (res) {
[507]1385                log_to_screen(_("WARNING - failed to unmount CD-ROM drive"));
[59]1386            }
1387            if (!bkpinfo->please_dont_eject) {
1388                res = eject_device(bkpinfo->media_device);
1389            } else {
1390                res = 0;
1391            }
1392            if (res) {
[507]1393                log_to_screen(_("WARNING - failed to eject CD-ROM disk"));
[59]1394            }
1395            popup_and_OK(request);
1396            if (!bkpinfo->please_dont_eject) {
1397                inject_device(bkpinfo->media_device);
1398            }
[688]1399            sync();
[59]1400        }
[146]1401        paranoid_free(request);
1402
[59]1403        log_msg(1, "Thankyou. Proceeding...");
1404        g_current_media_number = cd_number_i_want;
1405    }
[1]1406}
1407/* @} - end of deviceGroup */
1408
1409
1410/**
1411 * Ask user for details of backup/restore information.
1412 * Called when @c mondoarchive doesn't get any parameters.
1413 * @param bkpinfo The backup information structure to fill out with the user's data.
1414 * @param archiving_to_media TRUE if archiving, FALSE if restoring.
1415 * @return 0, always.
1416 * @bug No point of `int' return value.
1417 * @ingroup archiveGroup
1418 */
[59]1419int interactively_obtain_media_parameters_from_user(struct s_bkpinfo
1420                                                    *bkpinfo,
1421                                                    bool
1422                                                    archiving_to_media)
[1]1423// archiving_to_media is TRUE if I'm being called by mondoarchive
1424// archiving_to_media is FALSE if I'm being called by mondorestore
1425{
[688]1426    char *tmp = NULL;
1427    char *tmp1 = NULL;
1428    char *tmp2 = NULL;
[146]1429    char *sz_size = NULL;
[688]1430    char *command = NULL;
1431    char *comment = NULL;
[146]1432    char *prompt = NULL;
[688]1433    int i = 0;
1434    FILE *fin = NULL;
[1]1435
[59]1436    assert(bkpinfo != NULL);
1437    bkpinfo->nonbootable_backup = FALSE;
[1]1438
1439// Tape, CD, NFS, ...?
[59]1440    srandom(getpid());
1441    bkpinfo->backup_media_type =
1442        (g_restoring_live_from_cd) ? cdr :
1443        which_backup_media_type(bkpinfo->restore_data);
1444    if (bkpinfo->backup_media_type == none) {
[507]1445        log_to_screen(_("User has chosen not to backup the PC"));
[59]1446        finish(1);
1447    }
1448    if (bkpinfo->backup_media_type == tape && bkpinfo->restore_data) {
[507]1449        popup_and_OK(_("Please remove CD/floppy from drive(s)"));
[59]1450    }
[783]1451    bkpinfo->backup_media_string = bkptype_to_string(bkpinfo->backup_media_type);
1452    log_msg(3, "media type = %s",bkpinfo->backup_media_string);
1453
[59]1454    if (archiving_to_media) {
1455        sensibly_set_tmpdir_and_scratchdir(bkpinfo);
1456    }
1457    bkpinfo->cdrw_speed = (bkpinfo->backup_media_type == cdstream) ? 2 : 4;
1458    bkpinfo->compression_level =
1459        (bkpinfo->backup_media_type == cdstream) ? 1 : 5;
1460    bkpinfo->use_lzo =
1461        (bkpinfo->backup_media_type == cdstream) ? TRUE : FALSE;
[1]1462
1463/*
1464  if (find_home_of_exe("star") && (!find_home_of_exe("afio") || find_home_of_exe("selinuxenabled")))
1465    {
1466      bkpinfo->use_star = FALSE;   
1467      bkpinfo->use_lzo = FALSE;
1468      log_to_screen("Using star, not afio");
1469      if (!find_home_of_exe("afio"))
1470    { log_to_screen("...because afio not found"); }
1471      if (find_home_of_exe("selinuxenabled"))
1472    { log_to_screen("...because SELINUX found"); }
1473    }
1474*/
1475
[59]1476    mvaddstr_and_log_it(2, 0, " ");
[1]1477
1478// Find device's /dev (or SCSI) entry
[59]1479    switch (bkpinfo->backup_media_type) {
1480    case cdr:
1481    case cdrw:
1482    case dvd:
1483        if (archiving_to_media) {
[687]1484            if (bkpinfo->backup_media_type != dvd) {
1485                if (ask_me_yes_or_no
1486                    (_("Is your computer a laptop, or does the CD writer incorporate BurnProof technology?")))
1487                {
1488                    bkpinfo->manual_cd_tray = TRUE;
1489                }
[59]1490            }
1491            if ((bkpinfo->compression_level =
1492                 which_compression_level()) == -1) {
[507]1493                log_to_screen(_("User has chosen not to backup the PC"));
[59]1494                finish(1);
1495            }
[507]1496            asprintf(&comment, _("What speed is your %s (re)writer?"),
[783]1497                    bkpinfo->backup_media_string);
[59]1498            if (bkpinfo->backup_media_type == dvd) {
[783]1499                paranoid_free(bkpinfo->media_device);
[171]1500                bkpinfo->media_device = find_dvd_device();
[146]1501                asprintf(&tmp, "1");
1502                asprintf(&sz_size, "%d", DEFAULT_DVD_DISK_SIZE);    // 4.7 salesman's GB = 4.482 real GB = 4582 MB
[59]1503                log_msg(1, "Setting to DVD defaults");
1504            } else {
[171]1505                paranoid_alloc(bkpinfo->media_device,VANILLA_SCSI_CDROM );
[146]1506                asprintf(&tmp, "4");
1507                asprintf(&sz_size, "650");
[59]1508                log_msg(1, "Setting to CD defaults");
1509            }
1510            if (bkpinfo->backup_media_type != dvd) {
[688]1511                if (!popup_and_get_string(_("Speed"), comment, tmp)) {
[507]1512                    log_to_screen(_("User has chosen not to backup the PC"));
[59]1513                    finish(1);
1514                }
1515            }
[146]1516            paranoid_free(comment);
1517
[59]1518            bkpinfo->cdrw_speed = atoi(tmp);    // if DVD then this shouldn't ever be used anyway :)
[146]1519            paranoid_free(tmp);
1520
1521            asprintf(&comment,
[507]1522                    _("How much data (in Megabytes) will each %s store?"),
[783]1523                    bkpinfo->backup_media_string);
[146]1524
[688]1525            if (!popup_and_get_string("Size", comment, sz_size)) {
[507]1526                log_to_screen(_("User has chosen not to backup the PC"));
[59]1527                finish(1);
1528            }
[146]1529            paranoid_free(comment);
1530
[59]1531            for (i = 0; i <= MAX_NOOF_MEDIA; i++) {
1532                bkpinfo->media_size[i] = atoi(sz_size);
1533            }
[688]1534            paranoid_free(sz_size);
1535
[59]1536            if (bkpinfo->media_size[0] <= 0) {
[507]1537                log_to_screen(_("User has chosen not to backup the PC"));
[59]1538                finish(1);
1539            }
1540        }
1541    case cdstream:
1542        if (bkpinfo->disaster_recovery) {
[171]1543            paranoid_alloc(bkpinfo->media_device, "/dev/cdrom");
[59]1544            log_msg(2, "CD-ROM device assumed to be at %s",
1545                    bkpinfo->media_device);
1546        } else if (bkpinfo->restore_data
1547                   || bkpinfo->backup_media_type == dvd) {
[171]1548            if (bkpinfo->media_device == NULL) {
[688]1549                asprintf(&bkpinfo->media_device, "/dev/cdrom");
[59]1550            }                   // just for the heck of it :)
1551            log_msg(1, "bkpinfo->media_device = %s",
1552                    bkpinfo->media_device);
[783]1553            tmp = find_cdrom_device(FALSE);
[171]1554            if ((bkpinfo->backup_media_type == dvd)
[783]1555                || (tmp != NULL)) {
1556                paranoid_alloc(bkpinfo->media_device, tmp);
[59]1557                log_msg(1, "bkpinfo->media_device = %s",
1558                        bkpinfo->media_device);
[146]1559                asprintf(&comment,
[507]1560                        _("Please specify your %s drive's /dev entry"),
[783]1561                        bkpinfo->backup_media_string);
[59]1562                if (!popup_and_get_string
[688]1563                    (_("Device?"), comment, bkpinfo->media_device)) {
[507]1564                    log_to_screen(_("User has chosen not to backup the PC"));
[59]1565                    finish(1);
1566                }
[146]1567                paranoid_free(comment);
[59]1568            }
[783]1569            paranoid_free(tmp);
1570
[59]1571            log_msg(2, "%s device found at %s",
[783]1572                    bkpinfo->backup_media_string,
[59]1573                    bkpinfo->media_device);
1574        } else {
[171]1575            bkpinfo->media_device = find_cdrw_device();
1576            if (bkpinfo->media_device != NULL) {
[146]1577                asprintf(&tmp,
[729]1578                        _("I think I've found your %s burner at SCSI node %s; am I right on the money? Say no if you have an IDE burner and you are running a 2.6 kernel. Instead, specify the IDE burner's /dev address at the next screen."),
[783]1579                        bkpinfo->backup_media_string,
[59]1580                        bkpinfo->media_device);
1581                if (!ask_me_yes_or_no(tmp)) {
[171]1582                    paranoid_free(bkpinfo->media_device);
[59]1583                }
[146]1584                paranoid_free(tmp);
[171]1585            } else {
[59]1586                if (g_kernel_version < 2.6) {
[507]1587                    i = popup_and_get_string(_("Device node?"),
1588                                             _("What is the SCSI node of your CD (re)writer, please?"),
[688]1589                                             bkpinfo->media_device);
[59]1590                } else {
[507]1591                    i = popup_and_get_string(_("/dev entry?"),
1592                                             _("What is the /dev entry of your CD (re)writer, please?"),
[688]1593                                             bkpinfo->media_device);
[59]1594                }
1595                if (!i) {
[507]1596                    log_to_screen(_("User has chosen not to backup the PC"));
[59]1597                    finish(1);
1598                }
1599            }
1600        }
1601        if (bkpinfo->backup_media_type == cdstream) {
1602            for (i = 0; i <= MAX_NOOF_MEDIA; i++) {
1603                bkpinfo->media_size[i] = 650;
1604            }
1605        }
1606        break;
1607    case udev:
1608        if (!ask_me_yes_or_no
[507]1609            (_("This option is for advanced users only. Are you sure?"))) {
1610            log_to_screen(_("User has chosen not to backup the PC"));
[59]1611            finish(1);
1612        }
1613    case tape:
[1]1614
[171]1615        paranoid_free(bkpinfo->media_device);
[59]1616        if (find_tape_device_and_size(bkpinfo->media_device, sz_size)) {
[507]1617            log_msg(3, _("Ok, using vanilla scsi tape."));
[688]1618            paranoid_alloc(bkpinfo->media_device,VANILLA_SCSI_TAPE"0" );
[59]1619            if ((fin = fopen(bkpinfo->media_device, "r"))) {
1620                paranoid_fclose(fin);
1621            } else {
[171]1622                paranoid_alloc(bkpinfo->media_device,"/dev/osst0");
[59]1623            }
1624        }
[171]1625        if (bkpinfo->media_device != NULL) {
[59]1626            if ((fin = fopen(bkpinfo->media_device, "r"))) {
1627                paranoid_fclose(fin);
1628            } else {
1629                if (does_file_exist("/tmp/mondo-restore.cfg")) {
[783]1630                    paranoid_free(bkpinfo->media_device);
[59]1631                    read_cfg_var("/tmp/mondo-restore.cfg", "media-dev",
1632                                 bkpinfo->media_device);
1633                }
1634            }
[146]1635            asprintf(&tmp,
[507]1636                    _("I think I've found your tape streamer at %s; am I right on the money?"),
[59]1637                    bkpinfo->media_device);
1638            if (!ask_me_yes_or_no(tmp)) {
[171]1639                paranoid_free(bkpinfo->media_device);
[59]1640            }
[146]1641            paranoid_free(tmp);
[783]1642        } else {
[59]1643            if (!popup_and_get_string
[507]1644                (_("Device name?"),
1645                 _("What is the /dev entry of your tape streamer?"),
[688]1646                 bkpinfo->media_device)) {
[507]1647                log_to_screen(_("User has chosen not to backup the PC"));
[59]1648                finish(1);
1649            }
1650        }
[146]1651        asprintf(&tmp, "ls -l %s", bkpinfo->media_device);
[59]1652        if (run_program_and_log_output(tmp, FALSE)) {
[507]1653            log_to_screen(_("User has not specified a valid /dev entry"));
[59]1654            finish(1);
1655        }
[146]1656        paranoid_free(tmp);
[59]1657        log_msg(4, "sz_size = %s", sz_size);
[688]1658        paranoid_free(sz_size);
[146]1659        bkpinfo->media_size[0] = 0;
[59]1660        log_msg(4, "media_size[0] = %ld", bkpinfo->media_size[0]);
1661        if (bkpinfo->media_size[0] <= 0) {
1662            bkpinfo->media_size[0] = 0;
1663        }
1664        for (i = 1; i <= MAX_NOOF_MEDIA; i++) {
1665            bkpinfo->media_size[i] = bkpinfo->media_size[0];
1666        }
1667        if (archiving_to_media) {
1668            if ((bkpinfo->compression_level =
1669                 which_compression_level()) == -1) {
[507]1670                log_to_screen(_("User has chosen not to backup the PC"));
[59]1671                finish(1);
1672            }
1673        }
1674        break;
[1]1675
1676
1677
[59]1678    case nfs:
[783]1679        if (bkpinfo->nfs_mount == NULL) {
1680            bkpinfo->nfs_mount = call_program_and_get_last_line_of_output
1681                   ("mount | grep \":\" | cut -d' ' -f1 | head -n1");
[59]1682        }
[1]1683#ifdef __FreeBSD__
[59]1684        if (TRUE)
[1]1685#else
[59]1686        if (!bkpinfo->disaster_recovery)
[1]1687#endif
[59]1688        {
1689            if (!popup_and_get_string
[507]1690                (_("NFS dir."),
1691                 _("Please enter path and directory where archives are stored remotely. (Mondo has taken a guess at the correct value. If it is incorrect, delete it and type the correct one.)"),
[688]1692                 bkpinfo->nfs_mount)) {
[507]1693                log_to_screen(_("User has chosen not to backup the PC"));
[59]1694                finish(1);
1695            }
1696            if (!bkpinfo->restore_data) {
1697                if ((bkpinfo->compression_level =
1698                     which_compression_level()) == -1) {
[507]1699                    log_to_screen(_("User has chosen not to backup the PC"));
[59]1700                    finish(1);
1701                }
1702            }
[75]1703            // check whether already mounted - we better remove
[89]1704            // surrounding spaces and trailing '/' for this
[783]1705            /* BERLIOS: Useless
[89]1706            strip_spaces(bkpinfo->nfs_mount);
[783]1707            */
[75]1708            if (bkpinfo->nfs_mount[strlen(bkpinfo->nfs_mount) - 1] == '/')
[89]1709                bkpinfo->nfs_mount[strlen(bkpinfo->nfs_mount) - 1] = '\0';
[146]1710            asprintf(&command, "mount | grep \"%s \" | cut -d' ' -f3",
[89]1711                    bkpinfo->nfs_mount);
[783]1712            paranoid_free(bkpinfo->isodir);
1713            bkpinfo->isodir = call_program_and_get_last_line_of_output(command);
[146]1714            paranoid_free(command);
[262]1715
1716            asprintf(&comment,
[507]1717                    _("How much data (in Megabytes) will each media store?"));
[688]1718            if (!popup_and_get_string(_("Size"), comment, sz_size)) {
[507]1719                log_to_screen(_("User has chosen not to backup the PC"));
[262]1720                finish(1);
1721            }
1722            for (i = 0; i <= MAX_NOOF_MEDIA; i++) {
1723                bkpinfo->media_size[i] = atoi(sz_size);
1724            }
1725            if (bkpinfo->media_size[0] <= 0) {
[507]1726                log_to_screen(_("User has chosen not to backup the PC"));
[262]1727                finish(1);
1728            }
1729            paranoid_free(comment);
[59]1730        }
1731        if (bkpinfo->disaster_recovery) {
1732            system("umount /tmp/isodir 2> /dev/null");
1733            if (!popup_and_get_string
[507]1734                (_("NFS share"), _("Which remote NFS share should I mount?"),
[688]1735                 bkpinfo->nfs_mount)) {
[507]1736                log_to_screen(_("User has chosen not to backup the PC"));
[59]1737                finish(1);
1738            }
1739        }
1740        if (!is_this_device_mounted(bkpinfo->nfs_mount)) {
[783]1741            paranoid_free(bkpinfo->isodir);
1742            asprintf(&bkpinfo->isodir, "/tmp/isodir.mondo.%d",
[89]1743                    (int) (random() % 32768));
[146]1744            asprintf(&command, "mkdir -p %s", bkpinfo->isodir);
[89]1745            run_program_and_log_output(command, 5);
[146]1746            paranoid_free(command);
1747
[236]1748            asprintf(&tmp, "mount -t nfs -o nolock %s %s", bkpinfo->nfs_mount,
[89]1749                    bkpinfo->isodir);
1750            run_program_and_log_output(tmp, 5);
[146]1751            paranoid_free(tmp);
[783]1752            asprintf(&g_selfmounted_isodir, bkpinfo->isodir);
[59]1753        }
1754        if (!is_this_device_mounted(bkpinfo->nfs_mount)) {
1755            popup_and_OK
[507]1756                (_("Please mount that partition before you try to backup to or restore from it."));
[59]1757            finish(1);
1758        }
1759        if (!popup_and_get_string
[688]1760            (_("Directory"), _("Which directory within that mountpoint?"),bkpinfo->nfs_remote_dir)) {
[507]1761            log_to_screen(_("User has chosen not to backup the PC"));
[59]1762            finish(1);
1763        }
[146]1764
[688]1765        asprintf(&command, "echo hi > '%s/%s/.dummy.txt'", bkpinfo->isodir,
[89]1766                bkpinfo->nfs_remote_dir);
1767        while (run_program_and_log_output(command, FALSE)) {
1768            asprintf(&prompt,
[507]1769                     _("Directory '%s' under mountpoint '%s' does not exist or is not writable. You can fix this or change the directory and retry or cancel the backup."),
[89]1770                     bkpinfo->nfs_remote_dir, bkpinfo->isodir);
1771            if (!popup_and_get_string
[688]1772                (_("Directory"), prompt, bkpinfo->nfs_remote_dir)) {
[507]1773                log_to_screen(_("User has chosen not to backup the PC"));
[89]1774                finish(1);
1775            }
[688]1776            paranoid_free(prompt);
1777
1778            paranoid_free(command);
[89]1779            asprintf(&command, "echo hi > %s/%s/.dummy.txt",
1780                     bkpinfo->isodir, bkpinfo->nfs_remote_dir);
[75]1781        }
[146]1782        paranoid_free(command);
1783
[252]1784        if (!popup_and_get_string
[507]1785            (_("Prefix."),
1786             _("Please enter the prefix that will be prepended to your ISO filename.  Example: machine1 to obtain machine1-[1-9]*.iso files"),
[688]1787            bkpinfo->prefix)) {
[507]1788            log_to_screen(_("User has chosen not to backup the PC"));
[252]1789            finish(1);
1790        }
1791        log_msg(3, "prefix set to %s", bkpinfo->prefix);
1792
[59]1793        for (i = 0; i <= MAX_NOOF_MEDIA; i++) {
1794            bkpinfo->media_size[i] = 650;
1795        }
1796        log_msg(3, "Just set nfs_remote_dir to %s",
1797                bkpinfo->nfs_remote_dir);
1798        log_msg(3, "isodir is still %s", bkpinfo->isodir);
1799        break;
[1]1800
[59]1801    case iso:
1802        if (!bkpinfo->disaster_recovery) {
1803            if (!popup_and_get_string
[507]1804                (_("Storage dir."),
1805                 _("Please enter the full path that contains your ISO images.  Example: /mnt/raid0_0"),
[688]1806                 bkpinfo->isodir)) {
[507]1807                log_to_screen(_("User has chosen not to backup the PC"));
[59]1808                finish(1);
1809            }
1810            if (archiving_to_media) {
1811                if ((bkpinfo->compression_level =
1812                     which_compression_level()) == -1) {
[507]1813                    log_to_screen(_("User has chosen not to backup the PC"));
[59]1814                    finish(1);
1815                }
1816                if (!popup_and_get_string
[507]1817                    (_("ISO size."),
[688]1818                     _("Please enter how big you want each ISO image to be (in megabytes). This should be less than or equal to the size of the CD-R[W]'s or DVD's you plan to backup to."), sz_size)) {
[507]1819                    log_to_screen(_("User has chosen not to backup the PC"));
[59]1820                    finish(1);
1821                }
1822                for (i = 0; i <= MAX_NOOF_MEDIA; i++) {
1823                    bkpinfo->media_size[i] = atoi(sz_size);
1824                }
1825            } else {
1826                for (i = 0; i <= MAX_NOOF_MEDIA; i++) {
1827                    bkpinfo->media_size[i] = 650;
1828                }
1829            }
1830        }
[808]1831        if (!popup_and_get_string
[835]1832            (_("Prefix."),
1833             _("Please enter the prefix that will be prepended to your ISO filename.  Example: machine1 to obtain machine1-[1-9]*.iso files"),
1834             bkpinfo->prefix)) {
[808]1835            log_to_screen("User has chosen not to backup the PC");
1836            finish(1);
1837        }
1838        log_msg(3, "prefix set to %s", bkpinfo->prefix);
[59]1839        break;
1840    default:
1841        fatal_error
1842            ("I, Mojo Jojo, shall defeat those pesky Powerpuff Girls!");
1843    }
1844    if (archiving_to_media) {
[1]1845
[783]1846        if (bkpinfo->boot_device) {
1847            paranoid_free(bkpinfo->boot_device);
1848        }
[1]1849#ifdef __FreeBSD__
[688]1850        bkpinfo->boot_device = call_program_and_get_last_line_of_output
[783]1851               ("mount | grep ' / ' | head -1 | cut -d' ' -f1 | sed 's/\\([0-9]\\).*/\\1/'");
[1]1852#else
[688]1853        bkpinfo->boot_device = call_program_and_get_last_line_of_output
[783]1854               ("mount | grep ' / ' | head -1 | cut -d' ' -f1 | sed 's/[0-9].*//'");
[1]1855#endif
[59]1856        i = which_boot_loader(bkpinfo->boot_device);
1857        if (i == 'U')           // unknown
1858        {
[1]1859
1860#ifdef __FreeBSD__
[59]1861            if (!popup_and_get_string
[507]1862                (_("Boot device"),
1863                 _("What is your boot device? (e.g. /dev/ad0)"),
[688]1864                 bkpinfo->boot_device)) {
[507]1865                log_to_screen(_("User has chosen not to backup the PC"));
[59]1866                finish(1);
1867            }
1868            i = which_boot_loader(bkpinfo->boot_device);
[1]1869#else
[59]1870            if (!popup_and_get_string
[507]1871                (_("Boot device"),
1872                 _("What is your boot device? (e.g. /dev/hda)"),
[688]1873                 bkpinfo->boot_device)) {
[507]1874                log_to_screen(_("User has chosen not to backup the PC"));
[59]1875                finish(1);
1876            }
1877            if (does_string_exist_in_boot_block
1878                (bkpinfo->boot_device, "LILO")) {
1879                i = 'L';
1880            } else
1881                if (does_string_exist_in_boot_block
1882                    (bkpinfo->boot_device, "ELILO")) {
1883                i = 'E';
1884            } else
1885                if (does_string_exist_in_boot_block
1886                    (bkpinfo->boot_device, "GRUB")) {
1887                i = 'G';
1888            } else {
1889                i = 'U';
1890            }
[1]1891#endif
[59]1892            if (i == 'U') {
1893                if (ask_me_yes_or_no
[507]1894                    (_("Unidentified boot loader. Shall I restore it byte-for-byte at restore time and hope for the best?")))
[59]1895                {
1896                    i = 'R';    // raw
1897                } else {
1898                    log_to_screen
[507]1899                        (_("I cannot find your boot loader. Please run mondoarchive with parameters."));
[59]1900                    finish(1);
1901                }
1902            }
[1]1903        }
[59]1904        bkpinfo->boot_loader = i;
[688]1905        asprintf(&bkpinfo->include_paths, "/");
[59]1906        if (!popup_and_get_string
[507]1907            (_("Backup paths"),
1908             _("Please enter paths which you want me to backup. The default is '/' (i.e. everything)."),
[688]1909             bkpinfo->include_paths)) {
[507]1910            log_to_screen(_("User has chosen not to backup the PC"));
[59]1911            finish(1);
[1]1912        }
[688]1913
[146]1914        tmp = list_of_NFS_mounts_only();
[59]1915        if (strlen(tmp) > 2) {
[688]1916            if (bkpinfo->exclude_paths != NULL) {
1917                tmp1 = bkpinfo->exclude_paths;
1918                asprintf(&bkpinfo->exclude_paths, "%s %s", tmp1, tmp);
1919                paranoid_free(tmp1);
1920            } else {
1921                bkpinfo->exclude_paths = tmp;
[59]1922            }
1923        }
[146]1924        paranoid_free(tmp);
[1]1925// NTFS
[688]1926        tmp = call_program_and_get_last_line_of_output
1927               ("parted2fdisk -l | grep -i ntfs | awk '{ print $1};' | tr -s '\\n' ' ' | awk '{ print $0};'");
[59]1928        if (strlen(tmp) > 2) {
1929            if (!popup_and_get_string
[507]1930                (_("NTFS partitions"),
1931                 _("Please enter/confirm the NTFS partitions you wish to backup as well."),
[688]1932                 tmp1)) {
[507]1933                log_to_screen(_("User has chosen not to backup the PC"));
[59]1934                finish(1);
1935            }
[688]1936            if (bkpinfo->image_devs != NULL) {
1937                tmp2 = bkpinfo->image_devs;
1938                asprintf(&bkpinfo->image_devs, "%s %s", tmp2, tmp1);
1939                paranoid_free(tmp2);
1940            } else {
1941                bkpinfo->image_devs = tmp1;
1942            }
1943            paranoid_free(tmp1);
[59]1944        }
[146]1945        paranoid_free(tmp);
[1]1946
[59]1947        if (!popup_and_get_string
[507]1948            (_("Exclude paths"),
1949             _("Please enter paths which you do NOT want to backup. Separate them with spaces. NB: /tmp and /proc are always excluded. :-) Just hit 'Enter' if you want to do a full system backup."),
[688]1950             bkpinfo->exclude_paths)) {
[507]1951            log_to_screen(_("User has chosen not to backup the PC"));
[59]1952            finish(1);
1953        }
1954        bkpinfo->make_cd_use_lilo = FALSE;
1955        bkpinfo->backup_data = TRUE;
1956        bkpinfo->verify_data =
1957            ask_me_yes_or_no
[507]1958            (_("Will you want to verify your backups after Mondo has created them?"));
[1]1959
1960#ifndef __FreeBSD__
[59]1961        if (!ask_me_yes_or_no
[507]1962            (_("Are you confident that your kernel is a sane, sensible, standard Linux kernel? Say 'no' if you are using a Gentoo <1.4 or Debian <3.0, please."))){
[171]1963            paranoid_alloc(bkpinfo->kernel_path, "FAILSAFE");
1964        }
[1]1965#endif
1966
[59]1967        if (!ask_me_yes_or_no
[507]1968            (_("Are you sure you want to proceed? Hit 'no' to abort."))) {
1969            log_to_screen(_("User has chosen not to backup the PC"));
[59]1970            finish(1);
1971        }
1972    } else {
1973        bkpinfo->restore_data = TRUE;   // probably...
1974    }
[1]1975
[59]1976    if (bkpinfo->backup_media_type == iso
1977        || bkpinfo->backup_media_type == nfs) {
1978        g_ISO_restore_mode = TRUE;
1979    }
[1]1980#ifdef __FreeSD__
1981// skip
1982#else
[59]1983    if (bkpinfo->backup_media_type == nfs) {
1984        log_msg(3, "I think the NFS mount is mounted at %s",
1985                bkpinfo->isodir);
1986    }
1987    log_it("isodir = %s", bkpinfo->isodir);
1988    log_it("nfs_mount = '%s'", bkpinfo->nfs_mount);
[1]1989#endif
1990
[59]1991    log_it("media device = %s", bkpinfo->media_device);
1992    log_it("media size = %ld", bkpinfo->media_size[1]);
[783]1993    log_it("media type = %s", bkpinfo->backup_media_string);
1994    paranoid_free(tmp);
[252]1995    log_it("prefix = %s", bkpinfo->prefix);
[59]1996    log_it("compression = %ld", bkpinfo->compression_level);
1997    log_it("include_paths = '%s'", bkpinfo->include_paths);
1998    log_it("exclude_paths = '%s'", bkpinfo->exclude_paths);
1999    log_it("scratchdir = '%s'", bkpinfo->scratchdir);
2000    log_it("tmpdir = '%s'", bkpinfo->tmpdir);
2001    log_it("boot_device = '%s' (loader=%c)", bkpinfo->boot_device,
2002           bkpinfo->boot_loader);
2003    if (bkpinfo->media_size[0] < 0) {
2004        if (archiving_to_media) {
2005            fatal_error("Media size is less than zero.");
2006        } else {
2007            log_msg(2, "Warning - media size is less than zero.");
2008            bkpinfo->media_size[0] = 0;
2009        }
[1]2010    }
[59]2011    return (0);
[1]2012}
2013
2014
2015/**
2016 * Get a space-separated list of NFS mounts.
2017 * @return The list created.
[688]2018 * @note The return value should be freed by caller
[1]2019 * @bug Even though we only want the mounts, the devices are still checked.
2020 */
2021char *list_of_NFS_mounts_only(void)
2022{
[688]2023    return(call_program_and_get_last_line_of_output
[794]2024           ("mount -t coda,ncpfs,nfs,smbfs,cifs,afs,mvfs | tr -s '\t' ' ' | cut -d' ' -f3 | tr -s '\n' ' ' | awk '{print $0;}'"));
[688]2025    /* BERLIOS : Useless
[146]2026    asprintf(&exclude_these_devices,
[59]2027           call_program_and_get_last_line_of_output
[794]2028           ("tr -s '\t' ' ' < /etc/fstab | grep -E '( (coda|ncpfs|nfs|smbfs|cifs|afs|mvfs) )' | cut -d' ' -f1 | tr -s '\n' ' ' | awk '{print $0;}'"));
[688]2029           */
[1]2030}
2031
[146]2032
[1]2033/* @} - end of utilityGroup */
2034
2035/**
2036 * Set the tmpdir and scratchdir to reside on the partition with the most free space.
2037 * Automatically excludes DOS, NTFS, SMB, and NFS filesystems.
2038 * @param bkpinfo The backup information structure. @c bkpinfo->tmpdir and @c bkpinfo->scratchdir will be set.
2039 * @ingroup utilityGroup
2040 */
2041void sensibly_set_tmpdir_and_scratchdir(struct s_bkpinfo *bkpinfo)
2042{
[688]2043    char *tmp = NULL;
2044    char *command = NULL;
2045    char *sz = NULL;
2046    int i = 0;
[1]2047
[59]2048    assert(bkpinfo != NULL);
[1]2049
2050#ifdef __FreeBSD__
[688]2051    tmp = call_program_and_get_last_line_of_output
[794]2052           ("df -m -P -t nonfs,msdosfs,ntfs,smbfs,smb,cifs,afs,mvfs | tr -s '\t' ' ' | grep -vE \"none|Filesystem\" | awk '{printf \"%s %s\\n\", $4, $6;}' | sort -n | tail -n1 | awk '{print $NF;}'");
[1]2053#else
[688]2054    tmp = call_program_and_get_last_line_of_output
[794]2055           ("df -m -P -x nfs -x vfat -x ntfs -x smbfs -x smb -x cifs -x afs -x mvfs | sed 's/                  /devdev/' | tr -s '\t' ' ' | grep -vE \"none|Filesystem|/dev/shm\" | awk '{printf \"%s %s\\n\", $4, $6;}' | sort -n | tail -n1 | awk '{print $NF;}'");
[1]2056#endif
2057
[59]2058    if (tmp[0] != '/') {
[146]2059        asprintf(&sz, "/%s", tmp);
2060        paranoid_free(tmp);
2061        tmp = sz;
[59]2062    }
2063    if (!tmp[0]) {
2064        fatal_error("I couldn't figure out the tempdir!");
2065    }
[688]2066    i = (int) (random() % 32768);
[783]2067    paranoid_free(bkpinfo->tmpdir);
[688]2068    asprintf(&bkpinfo->tmpdir, "%s/mondo.tmp.%d", tmp, i);
[59]2069    log_it("bkpinfo->tmpdir is being set to %s", bkpinfo->tmpdir);
[1]2070
[783]2071    paranoid_free(bkpinfo->scratchdir);
[688]2072    asprintf(&bkpinfo->scratchdir, "%s/mondo.scratch.%d", tmp, i);
[59]2073    log_it("bkpinfo->scratchdir is being set to %s", bkpinfo->scratchdir);
[1]2074
[688]2075    asprintf(&g_erase_tmpdir_and_scratchdir, "rm -Rf %s %s", bkpinfo->tmpdir,
[59]2076            bkpinfo->scratchdir);
2077
[688]2078    asprintf(&command, "rm -Rf %s/mondo.tmp.* %s/mondo.scratch.*", tmp, tmp);
[146]2079    paranoid_free(tmp);
2080
[59]2081    paranoid_system(command);
2082    paranoid_free(command);
[1]2083}
2084
2085
2086/**
2087 * @addtogroup deviceGroup
2088 * @{
2089 */
2090/**
2091 * If we can read @p dev, set @p output to it.
2092 * If @p dev cannot be read, set @p output to "".
2093 * @param dev The device to check for.
[171]2094 * @param output Set to @p dev if @p dev exists, NULL otherwise. Needs to be freed by caller
[1]2095 * @return TRUE if @p dev exists, FALSE if it doesn't.
2096 */
[59]2097bool set_dev_to_this_if_rx_OK(char *output, char *dev)
[1]2098{
[59]2099    char *command;
[1]2100
[171]2101    paranoid_free(output);
[59]2102    if (!dev || dev[0] == '\0') {
2103        return (FALSE);
2104    }
2105    log_msg(10, "Injecting %s", dev);
2106    inject_device(dev);
2107    if (!does_file_exist(dev)) {
2108        log_msg(10, "%s doesn't exist. Returning FALSE.", dev);
2109        return (FALSE);
2110    }
[146]2111    asprintf(&command, "dd bs=%ld count=1 if=%s of=/dev/null &> /dev/null",
[59]2112            512L, dev);
2113    if (!run_program_and_log_output(command, FALSE)
2114        && !run_program_and_log_output(command, FALSE)) {
[171]2115        asprintf(&output, dev);
[59]2116        log_msg(4, "Found it - %s", dev);
[146]2117        paranoid_free(command);
[59]2118        return (TRUE);
2119    } else {
2120        log_msg(4, "It's not %s", dev);
[146]2121        paranoid_free(command);
[59]2122        return (FALSE);
2123    }
[1]2124}
2125
2126
2127/**
2128 * Find out what number CD is in the drive.
2129 * @param bkpinfo The backup information structure. The @c bkpinfo->media_device field is the only one used.
2130 * @return The current CD number, or -1 if it could not be found.
2131 * @note If the CD is not mounted, it will be mounted
2132 * (and remain mounted after this function returns).
2133 */
2134int what_number_cd_is_this(struct s_bkpinfo *bkpinfo)
2135{
[59]2136    int cd_number = -1;
[688]2137    char *mountdev = NULL;
2138    char *tmp = NULL;
2139    char *tmp1 = NULL;
[1]2140
[59]2141    assert(bkpinfo != NULL);
2142    if (g_ISO_restore_mode) {
[146]2143        asprintf(&tmp, "mount | grep iso9660 | awk '{print $3;}'");
[1]2144
[688]2145        tmp1 = call_program_and_get_last_line_of_output(tmp);
[146]2146        paranoid_free(tmp);
2147
[688]2148        asprintf(&mountdev, "%s/archives/THIS-CD-NUMBER", tmp1);
2149        paranoid_free(tmp1);
2150
2151        tmp = last_line_of_file(mountdev);
2152        cd_number = atoi(tmp);
[59]2153        paranoid_free(mountdev);
[688]2154        paranoid_free(tmp);
[146]2155
[59]2156        return (cd_number);
2157    }
[1]2158
[171]2159    if (bkpinfo->media_device == NULL) {
[59]2160        log_it
2161            ("(what_number_cd_is_this) Warning - media_device unknown. Finding out...");
[171]2162        bkpinfo->media_device = find_cdrom_device(FALSE);
[59]2163    }
2164    if (!is_this_device_mounted(MNT_CDROM)) {
[171]2165        (void)mount_CDROM_here(bkpinfo->media_device, MNT_CDROM);
[59]2166    }
[688]2167    tmp = last_line_of_file(MNT_CDROM "/archives/THIS-CD-NUMBER");
2168    cd_number = atoi(tmp);
2169    paranoid_free(tmp);
[59]2170    return (cd_number);
[1]2171}
2172
2173
2174/**
2175 * Find out what device is mounted as root (/).
2176 * @return Root device.
2177 * @note The returned string points to static storage and will be overwritten with every call.
2178 * @bug A bit of a misnomer; it's actually finding out the root device.
2179 * The mountpoint (where it's mounted) will obviously be '/'.
2180 */
[59]2181char *where_is_root_mounted()
[1]2182{
[146]2183    char *tmp;
[1]2184
2185#ifdef __FreeBSD__
[688]2186    tmp = call_program_and_get_last_line_of_output
2187           ("mount | grep \" on / \" | cut -d' ' -f1");
[1]2188#else
[688]2189    tmp = call_program_and_get_last_line_of_output
2190           ("mount | grep \" on / \" | cut -d' ' -f1 | sed s/[0-9]// | sed s/[0-9]//");
[59]2191    if (strstr(tmp, "/dev/cciss/")) {
[146]2192        paranoid_free(tmp);
[688]2193        tmp = call_program_and_get_last_line_of_output
2194               ("mount | grep \" on / \" | cut -d' ' -f1 | cut -dp -f1");
[59]2195    }
2196    if (strstr(tmp, "/dev/md")) {
[146]2197        paranoid_free(tmp);
[688]2198        tmp = call_program_and_get_last_line_of_output
2199               ("mount | grep \" on / \" | cut -d' ' -f1");
[59]2200    }
[1]2201#endif
2202
[59]2203    return (tmp);
[1]2204}
2205
2206
2207/**
2208 * Find out which boot loader is in use.
2209 * @param which_device Device to look for the boot loader on.
2210 * @return 'L' for LILO, 'E'for ELILO, 'G' for GRUB, 'B' or 'D' for FreeBSD boot loaders, or 'U' for Unknown.
2211 * @note Under Linux, all drives are examined, not just @p which_device.
2212 */
2213#ifdef __FreeBSD__
[59]2214char which_boot_loader(char *which_device)
[1]2215{
[59]2216    int count_lilos = 0;
2217    int count_grubs = 0;
2218    int count_boot0s = 0;
2219    int count_dangerouslydedicated = 0;
[1]2220
[59]2221    log_it("looking at drive %s's MBR", which_device);
2222    if (does_string_exist_in_boot_block(which_device, "GRUB")) {
2223        count_grubs++;
2224    }
2225    if (does_string_exist_in_boot_block(which_device, "LILO")) {
2226        count_lilos++;
2227    }
2228    if (does_string_exist_in_boot_block(which_device, "Drive")) {
2229        count_boot0s++;
2230    }
2231    if (does_string_exist_in_first_N_blocks
2232        (which_device, "FreeBSD/i386", 17)) {
2233        count_dangerouslydedicated++;
2234    }
2235    log_it("%d grubs and %d lilos and %d elilos and %d boot0s and %d DD\n",
2236           count_grubs, count_lilos, count_elilos, count_boot0s,
2237           count_dangerouslydedicated);
[1]2238
[59]2239    if (count_grubs && !count_lilos) {
2240        return ('G');
2241    } else if (count_lilos && !count_grubs) {
2242        return ('L');
2243    } else if (count_grubs == 1 && count_lilos == 1) {
2244        log_it("I'll bet you used to use LILO but switched to GRUB...");
2245        return ('G');
2246    } else if (count_boot0s == 1) {
2247        return ('B');
2248    } else if (count_dangerouslydedicated) {
2249        return ('D');
2250    } else {
2251        log_it("Unknown boot loader");
2252        return ('U');
2253    }
[1]2254}
2255
2256#else
2257
[59]2258char which_boot_loader(char *which_device)
[783]2259        /* which_device is allocated here and needs to be freed by caller */
[1]2260{
[59]2261    /*@ buffer ***************************************************** */
2262    char *list_drives_cmd;
[146]2263    char *current_drive = NULL;
[1]2264
[59]2265    /*@ pointers *************************************************** */
2266    FILE *pdrives;
[1]2267
[59]2268    /*@ int ******************************************************** */
2269    int count_lilos = 0;
2270    int count_grubs = 0;
[171]2271    size_t n = 0;
[1]2272
[59]2273    /*@ end vars *************************************************** */
[1]2274
2275#ifdef __IA64__
[59]2276    /* No choice for it */
2277    return ('E');
[1]2278#endif
[59]2279    assert(which_device != NULL);
[146]2280    asprintf(&list_drives_cmd,
[197]2281            "parted2fdisk -l 2>/dev/null | grep \"/dev/.*:\" | tr -s ':' ' ' | tr -s ' ' '\n' | grep /dev/; echo %s",
[59]2282            where_is_root_mounted());
2283    log_it("list_drives_cmd = %s", list_drives_cmd);
[1]2284
[59]2285    if (!(pdrives = popen(list_drives_cmd, "r"))) {
2286        log_OS_error("Unable to open list of drives");
2287        paranoid_free(list_drives_cmd);
2288        return ('\0');
[1]2289    }
[146]2290    paranoid_free(list_drives_cmd);
2291
2292    for (getline(&current_drive, &n, pdrives); !feof(pdrives);
2293         getline(&current_drive, &n, pdrives)) {
[59]2294        strip_spaces(current_drive);
2295        log_it("looking at drive %s's MBR", current_drive);
2296        if (does_string_exist_in_boot_block(current_drive, "GRUB")) {
2297            count_grubs++;
[783]2298            paranoid_alloc(which_device,current_drive);
[59]2299            break;
2300        }
2301        if (does_string_exist_in_boot_block(current_drive, "LILO")) {
2302            count_lilos++;
[783]2303            paranoid_alloc(which_device,current_drive);
[59]2304            break;
2305        }
[1]2306    }
[146]2307
[59]2308    if (pclose(pdrives)) {
2309        log_OS_error("Cannot pclose pdrives");
2310    }
2311    log_it("%d grubs and %d lilos\n", count_grubs, count_lilos);
2312    if (count_grubs && !count_lilos) {
2313        return ('G');
2314    } else if (count_lilos && !count_grubs) {
2315        return ('L');
2316    } else if (count_grubs == 1 && count_lilos == 1) {
2317        log_it("I'll bet you used to use LILO but switched to GRUB...");
2318        return ('G');
2319    } else {
2320        log_it("Unknown boot loader");
2321        return ('U');
2322    }
[1]2323}
2324#endif
2325
2326
2327/**
2328 * Write zeroes over the first 16K of @p device.
2329 * @param device The device to zero.
2330 * @return 0 for success, 1 for failure.
2331 */
[59]2332int zero_out_a_device(char *device)
[1]2333{
[59]2334    FILE *fout;
2335    int i;
[1]2336
[59]2337    assert_string_is_neither_NULL_nor_zerolength(device);
[1]2338
[59]2339    log_it("Zeroing drive %s", device);
2340    if (!(fout = fopen(device, "w"))) {
2341        log_OS_error("Unable to open/write to device");
2342        return (1);
2343    }
2344    for (i = 0; i < 16384; i++) {
2345        fputc('\0', fout);
2346    }
2347    paranoid_fclose(fout);
2348    log_it("Device successfully zeroed.");
2349    return (0);
[1]2350}
2351
[146]2352
[1]2353/**
2354 * Return the device pointed to by @p incoming.
2355 * @param incoming The device to resolve symlinks for.
2356 * @return The path to the real device file.
[146]2357 * @note The returned string points to a storage that need to be freed by the caller
[1]2358 * @bug Won't work with file v4.0; needs to be written in C.
2359 */
[59]2360char *resolve_softlinks_to_get_to_actual_device_file(char *incoming)
[1]2361{
[688]2362    char *output = NULL;
2363    char *command = NULL;
2364    char *curr_fname = NULL;
2365    char *scratch = NULL;
2366    char *tmp = NULL;
2367    char *p = NULL;
[59]2368
2369    struct stat statbuf;
2370    if (!does_file_exist(incoming)) {
2371        log_it
2372            ("resolve_softlinks_to_get_to_actual_device_file --- device not found");
[146]2373        asprintf(&output, incoming);
[59]2374    } else {
[146]2375        asprintf(&curr_fname, incoming);
[59]2376        lstat(curr_fname, &statbuf);
2377        while (S_ISLNK(statbuf.st_mode)) {
2378            log_msg(1, "curr_fname = %s", curr_fname);
[146]2379            asprintf(&command, "file %s", curr_fname);
[688]2380            tmp = call_program_and_get_last_line_of_output(command);
[146]2381            paranoid_free(command);
2382
[59]2383            for (p = tmp + strlen(tmp); p != tmp && *p != '`' && *p != ' ';
2384                 p--);
2385            p++;
[146]2386            asprintf(&scratch, p);
[59]2387            for (p = scratch; *p != '\0' && *p != '\''; p++);
2388            *p = '\0';
[688]2389            log_msg(0, "curr_fname %s --> '%s' --> %s", curr_fname, tmp, scratch);
[146]2390            paranoid_free(tmp);
2391
[59]2392            if (scratch[0] == '/') {
[146]2393                paranoid_free(curr_fname);
2394                asprintf(&curr_fname, scratch); // copy whole thing because it's an absolute softlink
[59]2395            } else {            // copy over the basename cos it's a relative softlink
2396                p = curr_fname + strlen(curr_fname);
2397                while (p != curr_fname && *p != '/') {
2398                    p--;
2399                }
2400                if (*p == '/') {
2401                    p++;
2402                }
[146]2403                *p = '\0';
2404                asprintf(&tmp, "%s%s", curr_fname, scratch);
2405                paranoid_free(curr_fname);
2406                curr_fname = tmp;
[59]2407            }
[146]2408            paranoid_free(scratch);
[59]2409            lstat(curr_fname, &statbuf);
2410        }
[146]2411        asprintf(&output, curr_fname);
[59]2412        log_it("resolved %s to %s", incoming, output);
[146]2413        paranoid_free(curr_fname);
[1]2414    }
[59]2415    return (output);
[1]2416}
2417
2418/* @} - end of deviceGroup */
2419
2420
2421/**
2422 * Return the type of partition format (GPT or MBR)
[146]2423 * Caller needs to free the return value
[1]2424 */
2425char *which_partition_format(const char *drive)
2426{
[688]2427    char *output = NULL;
2428    char *tmp = NULL;
2429    char *command = NULL;
2430    char *fdisk = NULL;
[59]2431
2432    log_msg(0, "Looking for partition table format type");
[197]2433    asprintf(&fdisk, "/sbin/parted2fdisk");
[89]2434    log_msg(1, "Using %s", fdisk);
[146]2435    asprintf(&command, "%s -l %s | grep 'EFI GPT'", fdisk, drive);
2436    paranoid_free(fdisk);
2437
[688]2438    tmp = call_program_and_get_last_line_of_output(command);
[146]2439    paranoid_free(command);
2440
[59]2441    if (strstr(tmp, "GPT") == NULL) {
[146]2442        asprintf(&output, "MBR");
[59]2443    } else {
[146]2444        asprintf(&output, "GPT");
[59]2445    }
[146]2446    paranoid_free(tmp);
[59]2447    log_msg(0, "Found %s partition table format type", output);
2448    return (output);
[1]2449}
2450
2451/* @} - end of deviceGroup */
Note: See TracBrowser for help on using the repository browser.