source: MondoRescue/branches/stable/mondo/src/common/libmondo-devices.c@ 1166

Last change on this file since 1166 was 1166, checked in by Bruno Cornec, 17 years ago

Suppress g_bkpinfo_DONTUSETHIS (Idea from M. Loiseleur)

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