source: MondoRescue/trunk/mondo/mondo/common/libmondo-devices.c@ 130

Last change on this file since 130 was 127, checked in by bcornec, 18 years ago

merge -r 125:126 $SVN_M/branches/2.05

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