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

Last change on this file since 1770 was 1770, checked in by Bruno Cornec, 16 years ago
  • Better output for mindi-busybox revision
  • Remove dummy file created on NFS - report from Arnaud Tiger <arnaud.tiger_at_hp.com>
  • strace useful for debug
  • fix new versions for pb (2.0.0 for mindi and 1.7.2 for mindi-busybox)
  • fix build process for mindi-busybox + options used in that version (dd for label-partitions-as-necessary)
  • fix typo in label-partitions-as-necessary which doesn't seem to work
  • Update to busybox 1.7.2
  • perl is now required at restore time to support uuid swap partitions (and will be used for many other thigs

in the future for sure)

  • next mindi version will be 2.0.0 due to all the changes made in it (udev may break working distros)
  • small optimization in mindi on keyboard handling (one single find instead of multiple)
  • better interaction for USB device when launching mindi manually
  • attempt to automatically guess block disk size for ramdisk
  • fix typos in bkphw
  • Fix the remaining problem with UUID support for swap partitions
  • Updates mondoarchive man page for USB support
  • Adds preliminary Hardware support to mindi (Proliant SSSTK)
  • Tries to add udev support also for rhel4
  • Fix UUID support which was still broken.
  • Be conservative in test for the start-nfs script
  • Update config file for mindi-busybox for 1.7.2 migration
  • Try to run around a busybox bug (1.2.2 pb on inexistant links)
  • Add build content for mindi-busybox in pb
  • Remove distributions content for mindi-busybox
  • Fix a warning on inexistant raidtab
  • Solve problem on tmpfs in restore init (Problem of inexistant symlink and busybox)
  • Create MONDO_CACHE and use it everywhere + creation at start
  • Really never try to eject a USB device
  • Fix a issue with &> usage (replaced with 1> and 2>)
  • Adds magic file to depllist in order to have file working + ldd which helps for debugging issues
  • tty modes correct to avoid sh error messages
  • Use ext3 normally and not ext2 instead
  • USB device should be corrected after reading (take 1st part)
  • Adds a mount_USB_here function derived from mount_CDROM_here
  • usb detection place before /dev detection in device name at restore time
  • Fix when restoring from USB: media is asked in interactive mode
  • Adds USB support for mondorestore
  • mount_cdrom => mount_media
  • elilo.efi is now searched throughout /boot/efi and not in a fixed place as there is no standard
  • untar-and-softlink => untar (+ interface change)
  • suppress useless softlinks creation/removal in boot process
  • avoids udevd messages on groups
  • Increase # of disks to 99 as in mindi at restore time (should be a conf file parameter)
  • skip existing big file creation
  • seems to work correctly for USB mindi boot
  • Adds group and tty link to udev conf
  • Always load usb-torage (even 2.6) to initiate USB bus discovery
  • Better printing of messages
  • Attempt to fix a bug in supporting OpenSusE 10.3 kernel for initramfs (mindi may now use multiple regex for kernel initrd detection)
  • Links were not correctly done as non relative for modules in mindi
  • exclusion of modules denied now works
  • Also create modules in their ordinary place, so that classical modprobe works + copy modules.dep
  • Fix bugs for DENY_MODS handling
  • Add device /dev/console for udev
  • ide-generic should now really be excluded
  • Fix a bug in major number for tty
  • If udev then adds modprobe/insmod to rootfs
  • tty0 is also cretaed with udev
  • ide-generic put rather in DENY_MODS
  • udevd remove from deplist s handled in mindi directly
  • better default for mindi when using --usb
  • Handles dynamically linked busybox (in case we want to use it soon ;-)
  • Adds fixed devices to create for udev
  • ide-generic should not be part of the initrd when using libata v2
  • support a dynamically linked udev (case on Ubuntu 7.10 and Mandriva 2008.0 so should be quite generic) This will give incitation to move to dyn. linked binaries in the initrd which will help for other tasks (ia6 4)
  • Improvement in udev support (do not use cl options not available in busybox)
  • Udev in mindi
    • auto creation of the right links at boot time with udev-links.conf(from Mandriva 2008.0)
    • rework startup of udev as current makes kernel crash (from Mandriva 2008.0)
    • add support for 64 bits udev
  • Try to render MyInsmod silent at boot time
  • Adds udev support (mandatory for newest distributions to avoid remapping of devices in a different way as on the original system)
  • We also need vaft format support for USB boot
  • Adds libusual support (Ubuntu 7.10 needs it for USB)
  • Improve Ubuntu/Debian keyboard detection and support
  • pbinit adapted to new pb (0.8.10). Filtering of docs done in it
  • Suppress some mondo warnings and errors on USB again
  • Tries to fix lack of files in deb mindi package
  • Verify should now work for USB devices
  • More log/mesages improvement for USB support
  • - Supress g_erase_tmpdir_and_scratchdir
  • Improve some log messages for USB support
  • Try to improve install in mindi to avoid issues with isolinux.cfg not installed vene if in the pkg :-(
  • Improve mindi-busybox build
  • In conformity with pb 0.8.9
  • Add support for Ubuntu 7.10 in build process
  • Add USB Key button to Menu UI (CD streamer removed)
  • Attempt to fix error messages on tmp/scratch files at the end by removing those dir at the latest possible.
  • Fix a bug linked to the size of the -E param which could be used (Arnaud Tiger/René Ribaud).
  • Integrate ~/.pbrc content into mondorescue.pb (required project-builder >= 0.8.7)
  • Put mondorescue in conformity with new pb filtering rules
  • Add USB support at restore time (no test done yet). New start-usb script PB varibale added where useful
  • Unmounting USB device before removal of temporary scratchdir
  • Stil refining USB copy back to mondo (one command was not executed)
  • No need to have the image subdor in the csratchdir when USB.
  • umount the USB partition before attempting to use it
  • Remove useless copy from mindi to mondo at end of USB handling

(risky merge, we are raising the limits of 2 diverging branches. The status of stable is not completely sure as such. Will need lots of tests, but it's not yet done :-()
(merge -r1692:1769 $SVN_M/branches/2.2.5)

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