source: MondoRescue/branches/2.2.8/mondo/src/common/libmondo-devices.c@ 2052

Last change on this file since 2052 was 2052, checked in by Bruno Cornec, 15 years ago

Adds support for dm devices in truncate_to_drive_name

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