source: MondoRescue/branches/stable/mondo/src/common/libmondo-tools.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: 35.7 KB
RevLine 
[1178]1/* $Id: libmondo-tools.c 1770 2007-11-06 10:01:53Z bruno $
2misc tools
[1]3*/
4
5/**
6 * @file
7 * Miscellaneous tools that didn't really fit anywhere else.
8 */
9
10#include "my-stuff.h"
[1080]11#include "mr_mem.h"
[1123]12#include "mr_msg.h"
[1087]13#include "mr_file.h"
[1549]14#include "mr_gettext.h"
[1592]15#include "mr_conf.h"
[1095]16
[1]17#include "mondostructures.h"
18#include "libmondo-tools.h"
[1178]19#include "newt-specific-EXT.h"
[1]20#include "libmondo-files-EXT.h"
21#include "libmondo-fork-EXT.h"
22#include "libmondo-raid-EXT.h"
23#include <sys/socket.h>
24#include <netdb.h>
[1663]25#include <stdlib.h>
[1]26#include <netinet/in.h>
27#include <arpa/inet.h>
[1377]28#include <sys/utsname.h>
[1]29
30/*@unused@*/
[99]31//static char cvsid[] = "$Id: libmondo-tools.c 1770 2007-11-06 10:01:53Z bruno $";
[1]32
33extern int g_tape_buffer_size_MB;
34extern char *g_serial_string;
35extern bool g_text_mode;
36extern int g_currentY;
37extern int g_current_media_number;
[1344]38extern char *MONDO_LOGFILE;
[1]39
[1592]40extern struct mr_ar_conf *mr_conf;
41
[1663]42/* Reference to global bkpinfo */
43extern struct s_bkpinfo *bkpinfo;
44
[1]45/**
46 * @addtogroup globalGroup
47 * @{
48 */
[128]49bool g_remount_cdrom_at_end, ///< TRUE if we unmounted the CD-ROM and should remount it when done with the backup.
50 g_remount_floppy_at_end; ///< TRUE if we unmounted the floppy and should remount it when done with the backup.
51bool g_cd_recovery; ///< TRUE if we're making an "autonuke" backup.
[1]52double g_kernel_version;
53
54/**
[1178]55 * The place where /boot is mounted. - Used locally only
[1]56 */
[1178]57static char *g_boot_mountpt = NULL;
[1]58
59/**
60 * The serial string (used to differentiate between backups) of the current backup.
61 */
[128]62char *g_serial_string = NULL;
[1]63
64/**
65 * The location where tmpfs is mounted, or "" if it's not mounted.
66 */
[128]67char *g_tmpfs_mountpt = NULL;
68char *g_magicdev_command = NULL;
[1]69
70/* @} - end of globalGroup */
71
72
73extern pid_t g_buffer_pid;
74extern pid_t g_main_pid;
75
76extern t_bkptype g_backup_media_type;
[1178]77extern char *g_backup_media_string;
[1]78
79extern bool am_I_in_disaster_recovery_mode(void);
80
81
82/**
83 * @addtogroup utilityGroup
84 * @{
85 */
86/**
87 * Assertion handler. Prints a friendly message to the user,
88 * offering to ignore all, dump core, break to debugger,
89 * exit, or ignore. Intended to be used with an assert() macro.
90 *
91 * @param file The file in which the assertion triggered.
92 * @param function The function (@c __FUNCTION__) in which the assertion triggered.
93 * @param line The line number of the assert() statement.
94 * @param exp The expression that failed (as a string).
95 */
[128]96void _mondo_assert_fail(const char *file,
97 const char *function, int line, const char *exp)
[1]98{
[128]99 static int ignoring_assertions = 0;
100 bool is_valid = TRUE;
[1]101
[128]102 log_it("ASSERTION FAILED: `%s' at %s:%d in %s", exp, file, line,
103 function);
104 if (ignoring_assertions) {
105 log_it("Well, the user doesn't care...");
106 return;
107 }
[1]108#ifndef _XWIN
[128]109 if (!g_text_mode)
110 newtSuspend();
[1]111#endif
[1178]112 printf(_("ASSERTION FAILED: `%s'\n"), exp);
113 printf(_("\tat %s:%d in %s\n\n"), file, line, function);
114 printf(_("(I)gnore, ignore (A)ll, (D)ebug, a(B)ort, or (E)xit? "));
[128]115 do {
116 is_valid = TRUE;
117 switch (toupper(getchar())) {
118 case 'A': // ignore (A)ll
119 ignoring_assertions = 1;
120 break;
121 case 'B': // a(B)ort
122 signal(SIGABRT, SIG_DFL); /* prevent SIGABRT handler from running */
123 raise(SIGABRT);
124 break; /* "can't get here" */
125 case 'D': // (D)ebug, aka asm("int 3")
[1]126#ifdef __IA32__
[128]127 __asm__ __volatile__("int $3"); // break to debugger
[1]128#endif
[128]129 break;
130 case 'E': // (E)xit
131 fatal_error("Failed assertion -- see above for details");
132 break; /* "can't get here" */
133 case 'I': // (I)gnore
134 break;
135 /* These next two work as follows:
136 the `default' catches the user's invalid choice and says so;
137 the '\n' catches the newline on the end and prints the prompt again.
138 */
139 case '\n':
140 printf
[1178]141 (_("(I)gnore, ignore (A)ll, (D)ebug, a(B)ort, or (E)xit? "));
[128]142 break;
143 default:
144 is_valid = FALSE;
[1178]145 printf(_("Invalid choice.\n"));
[128]146 break;
147 }
148 } while (!is_valid);
149
150 if (ignoring_assertions) {
151 log_it("Ignoring ALL assertions from now on.");
152 } else {
153 log_it("Ignoring assertion: %s", exp);
[1]154 }
155
[128]156 getchar(); // skip \n
[1]157
158#ifndef _XWIN
[128]159 if (!g_text_mode)
160 newtResume();
[1]161#endif
162}
163
164/**
165 * Clean's up users' KDE desktops.
166 * @bug Details about this function are unknown.
167 */
168void clean_up_KDE_desktop_if_necessary(void)
169{
[128]170 char *tmp;
[1]171
[1178]172 mr_asprintf(&tmp,
173 "for i in `find /root /home -type d -name Desktop -maxdepth 2`; do \
[1]174file=$i/.directory; if [ -f \"$file\" ] ; then mv -f $file $file.old ; \
[273]175awk '{if (index($0, \"rootimagesmindi\")) { while (length($0)>2) { getline;} ; } \
[275]176else { print $0;};}' $file.old > $file ; fi ; done");
[128]177 run_program_and_log_output(tmp, 5);
[1080]178 mr_free(tmp);
[1]179}
180
181
182/**
[1061]183 * Locate mondoarchive's home directory. Searches in /usr/share/mondo,
[1]184 * /usr/local/share/mondo, /opt, or if all else fails, search /usr.
185 *
186 * @param home_sz String to store the home directory ("" if it could not be found).
187 * @return 0 for success, nonzero for failure.
188 */
189int find_and_store_mondoarchives_home(char *home_sz)
190{
[128]191 assert(home_sz != NULL);
[424]192 strcpy(home_sz, MONDO_SHARE);
[182]193 return (0);
[1]194}
195
196
[1377]197char *get_architecture(void) {
[1]198#ifdef __IA32__
[1377]199# ifdef __X86_64__
200 return ("x86_64");
201# else
202 return ("i386");
203# endif
[1]204#endif
[1178]205#ifdef __X86_64__
206 return ("x86_64");
207#endif
[1]208#ifdef __IA64__
[128]209 return ("ia64");
[1]210#endif
[128]211 return ("unknown");
[1]212}
213
214
[1377]215char *get_uname_m(void) {
216
217 struct utsname utsn;
218 char *tmp = NULL;
219
220 uname(&utsn);
221 mr_asprintf(&tmp, utsn.machine);
222 return (tmp);
223}
224
225
226
[1178]227/* BERLIOS: Use uname instead */
[1152]228double get_kernel_version(void)
[1]229{
[128]230 char *p, tmp[200];
231 double d;
[1]232#ifdef __FreeBSD__
[128]233 // JOSH - FIXME :)
234 d = 5.2; // :-)
[1]235#else
[128]236 strcpy(tmp, call_program_and_get_last_line_of_output("uname -r"));
237 p = strchr(tmp, '.');
238 if (p) {
239 p = strchr(++p, '.');
240 if (p) {
241 while (*p) {
242 *p = *(p + 1);
243 p++;
244 }
245 }
246 }
[1107]247// mr_msg(1, "tmp = '%s'", tmp);
[128]248 d = atof(tmp);
[1]249#endif
[1107]250 mr_msg(1, "g_kernel_version = %f", d);
[128]251 return (d);
[1]252}
253
254
255/**
256 * Get the current time.
257 * @return number of seconds since the epoch.
258 */
[1152]259long get_time(void)
[1]260{
[128]261 return (long) time((void *) 0);
[1]262}
263
264
265/**
266 * Initialize a RAID volume structure, setting fields to zero. The
267 * actual hard drive is unaffected.
268 *
269 * @param raidrec The RAID volume structure to initialize.
270 * @note This function is system dependent.
271 */
272#ifdef __FreeBSD__
[128]273void initialize_raidrec(struct vinum_volume *raidrec)
[1]274{
[128]275 int i, j;
276 raidrec->volname[0] = '\0';
277 raidrec->plexes = 0;
278 for (i = 0; i < 9; ++i) {
279 raidrec->plex[i].raidlevel = -1;
280 raidrec->plex[i].stripesize = 0;
281 raidrec->plex[i].subdisks = 0;
282 for (j = 0; j < 9; ++j) {
283 strcpy(raidrec->plex[i].sd[j].which_device, "");
284 }
285 }
[1]286}
287#else
[128]288void initialize_raidrec(struct raid_device_record *raidrec)
[1]289{
[128]290 assert(raidrec != NULL);
291 raidrec->raid_device[0] = '\0';
[558]292 raidrec->raid_level = -9;
[128]293 raidrec->persistent_superblock = 1;
[558]294 raidrec->chunk_size = 64;
295 raidrec->parity = -1;
[128]296 raidrec->data_disks.entries = 0;
297 raidrec->spare_disks.entries = 0;
298 raidrec->parity_disks.entries = 0;
299 raidrec->failed_disks.entries = 0;
300 raidrec->additional_vars.entries = 0;
[1]301}
302#endif
303
304
305/**
306 * Insert modules that Mondo requires.
[1221]307 * Currently inserts @c msdos, @c vfat, and @c loop for Linux;
[1]308 * @c msdosfs and @c ext2fs for FreeBSD.
309 */
310void insmod_crucial_modules(void)
311{
312#ifdef __FreeBSD__
[128]313 system("kldstat | grep msdosfs || kldload msdosfs 2> /dev/null");
314 system("kldstat | grep ext2fs || kldload ext2fs 2> /dev/null");
[1]315#else
[1221]316 system("modprobe -a msdos vfat loop &> /dev/null");
[1]317#endif
318}
319
320
321/**
322 * Finish configuring the backup information structure. Call this function
323 * to set the parameters that depend on those that can be given on the command
324 * line.
325 *
326 * @param bkpinfo The backup information structure. Fields modified/used:
327 * - Used: @c bkpinfo->backup_data
328 * - Used: @c bkpinfo->backup_media_type
[1594]329 * - Used: @c bkpinfo->writer_speed
[1]330 * - Used: @c bkpinfo->include_paths
[20]331 * - Used: @c bkpinfo->prefix
[1]332 * - Used: @c bkpinfo->isodir
[1609]333 * - Used: @c bkpinfo->manual_tray
[1]334 * - Used: @c bkpinfo->make_cd_use_lilo
335 * - Used: @c bkpinfo->media_device
336 * - Used: @c bkpinfo->nfs_mount
337 * - Used: @c bkpinfo->nonbootable_backup
338 * - Used: @c bkpinfo->scratchdir
339 * - Used: @c bkpinfo->tmpdir
340 * - Modified: @c bkpinfo->call_before_iso
341 * - Modified: @c bkpinfo->call_make_iso
342 * - Modified: @c bkpinfo->optimal_set_size
343 *
344 * @return number of errors, or 0 for success.
345 * @note Also creates directories that are specified in the @c bkpinfo structure but
346 * do not exist.
347 */
[1663]348int post_param_configuration()
[1]349{
[1178]350 char *extra_cdrom_params = NULL;
351 char *mondo_mkisofs_sz = NULL;
352 char *command = NULL;
353 char *hostname = NULL;
354 char *ip_address = NULL;
[128]355 int retval = 0;
356 long avm = 0;
[1178]357 char *colon = NULL;
358 char *tmp = NULL;
359 char *call_before_iso_user = NULL;
[128]360 int rdsiz_MB;
[1178]361 char *iso_dev = NULL;
362 char *iso_mnt = NULL;
363 char *iso_tmp = NULL;
364 char *iso_path = NULL;
[1087]365 FILE *fd1 = NULL;
[1]366
[128]367 assert(bkpinfo != NULL);
368 bkpinfo->optimal_set_size =
[686]369 (IS_THIS_A_STREAMING_BACKUP(bkpinfo->backup_media_type) ? 16 : 16) *
[128]370 1024;
[1]371
[1107]372 mr_msg(1, "Foo");
[128]373 if (bkpinfo->backup_media_type == tape) {
[1107]374 mr_msg(1, "Bar");
[1178]375 mr_asprintf(&tmp, "mt -f %s status", bkpinfo->media_device);
[1107]376 mr_msg(1, "tmp = '%s'", tmp);
[128]377 if (run_program_and_log_output(tmp, 3)) {
378 fatal_error
379 ("Unable to open tape device. If you haven't specified it with -d, do so. If you already have, check your parameter. I think it's wrong.");
380 }
[1178]381 mr_free(tmp);
[1]382 }
[128]383 make_hole_for_dir(bkpinfo->scratchdir);
384 if (bkpinfo->backup_media_type == iso)
385 make_hole_for_dir(bkpinfo->isodir);
[1]386
[128]387 run_program_and_log_output("uname -a", 5);
[678]388 run_program_and_log_output("cat /etc/*-release", 5);
[128]389 sprintf(g_tmpfs_mountpt, "%s/tmpfs", bkpinfo->tmpdir);
[1178]390 mr_asprintf(&command, "mkdir -p %s", g_tmpfs_mountpt);
[128]391 paranoid_system(command);
[1178]392 mr_free(command);
[128]393 rdsiz_MB = PPCFG_RAMDISK_SIZE + g_tape_buffer_size_MB;
[1]394#ifdef __FreeBSD__
[1178]395 mr_asprintf(&tmp,
[128]396 call_program_and_get_last_line_of_output
397 ("vmstat | tail -1 | tr -s ' ' | cut -d' ' -f6"));
398 avm += atol(tmp);
[1178]399 mr_free(tmp);
400 mr_asprintf(&tmp,
[128]401 call_program_and_get_last_line_of_output
402 ("swapinfo | grep -v Device | tr -s ' ' | cut -d' ' -f4 | tr '\n' '+' | sed 's/+$//' | bc"));
403 avm += atol(tmp);
[1178]404 mr_free(tmp);
405 mr_asprintf(&command, "mdmfs -s %d%c md9 %s", rdsiz_MB, 'm',
406 g_tmpfs_mountpt);
[1]407#else
[1178]408 mr_asprintf(&tmp,
[128]409 call_program_and_get_last_line_of_output
[911]410 ("free | grep ':' | tr -s ' ' '\t' | cut -f2 | head -n1"));
[128]411 avm += atol(tmp);
[1178]412 mr_free(tmp);
413 mr_asprintf(&command, "mount /dev/shm -t tmpfs %s -o size=%d%c",
[128]414 g_tmpfs_mountpt, rdsiz_MB, 'm');
415 run_program_and_log_output("cat /proc/cpuinfo", 5);
[1178]416 /* BERLIOS: rpm is not necessarily there ! */
[128]417 run_program_and_log_output
418 ("rpm -q newt newt-devel slang slang-devel ncurses ncurses-devel gcc",
419 5);
[1]420#endif
[128]421 if (avm / 1024 > rdsiz_MB * 3) {
422 if (run_program_and_log_output(command, 5)) {
423 g_tmpfs_mountpt[0] = '\0';
424 log_it("Failed to mount tmpfs");
425 } else {
426 log_it("Tmpfs mounted OK - %d MB", rdsiz_MB);
427 }
428 } else {
429 g_tmpfs_mountpt[0] = '\0';
430 log_it("It doesn't seem you have enough swap to use tmpfs. Fine.");
[1]431 }
[1178]432 mr_free(command);
[128]433
[1592]434// CD-R or CD-RW or DVD
[128]435 if (bkpinfo->backup_media_type == cdrw
[1592]436 || bkpinfo->backup_media_type == dvd
437 || bkpinfo->backup_media_type == iso
438 || bkpinfo->backup_media_type == nfs
[128]439 || bkpinfo->backup_media_type == cdr) {
[1609]440 if (!bkpinfo->manual_tray) {
[1178]441 mr_strcat(extra_cdrom_params, "-waiti ");
[128]442 }
443 if (bkpinfo->backup_media_type == cdrw) {
[1178]444 mr_strcat(extra_cdrom_params, "blank=fast ");
[128]445 }
446 if (bkpinfo->nonbootable_backup) {
[1592]447 mr_asprintf(&mondo_mkisofs_sz, "%s -no-boot", mr_conf->iso_creation_opt);
[128]448 } else if
[1]449#ifdef __FreeBSD__
[128]450 (TRUE)
[1]451#else
[128]452 (bkpinfo->make_cd_use_lilo)
[1]453#endif
454#ifdef __IA64__
455 {
[1592]456 mr_asprintf(&mondo_mkisofs_sz, "%s -b images/mindi-boot.2880.img -c boot.cat", mr_conf->iso_creation_opt);
[1]457 }
[128]458#else
[1]459 {
[1592]460 mr_asprintf(&mondo_mkisofs_sz, "%s -b isolinux.bin -c boot.cat", mr_conf->iso_creation_opt);
[1]461 }
[128]462#endif
[1592]463 else {
464 mr_asprintf(&mondo_mkisofs_sz, "%s -b isolinux.bin -c boot.cat", mr_conf->iso_creation_opt);
[128]465 }
[1609]466 if (bkpinfo->manual_tray) {
[1594]467 if (strstr(mr_conf->iso_burning_cmd,"growisofs") != NULL) {
[1592]468 fatal_error("Unable to use manual CD tray with growisofs");
469 }
[163]470 if (bkpinfo->call_before_iso[0] == '\0') {
[1592]471 sprintf(bkpinfo->call_before_iso,
[1670]472 "%s %s -o %s/"MONDO_TMPISOS" . 2>> %s",
[1592]473 mr_conf->iso_creation_cmd,mondo_mkisofs_sz, bkpinfo->tmpdir, MONDO_LOGFILE);
[1178]474 } else {
475 mr_asprintf(&call_before_iso_user, bkpinfo->call_before_iso);
[163]476 sprintf (bkpinfo->call_before_iso,
[1670]477 "(%s %s -o %s/"MONDO_TMPISOS" . 2>> %s ; %s )",
[1592]478 mr_conf->iso_creation_cmd,mondo_mkisofs_sz, bkpinfo->tmpdir, MONDO_LOGFILE, call_before_iso_user);
[1178]479 mr_free(call_before_iso_user);
[163]480 }
481 log_it("bkpinfo->call_before_iso = %s", bkpinfo->call_before_iso);
[128]482 sprintf(bkpinfo->call_make_iso,
[1670]483 "%s %s %s dev=%s speed=%d %s/"MONDO_TMPISOS,
[1594]484 mr_conf->iso_burning_cmd,
[1592]485 extra_cdrom_params,
[1594]486 mr_conf->iso_burning_opt,
487 bkpinfo->iso_burning_dev,
488 bkpinfo->writer_speed,
[1592]489 bkpinfo->tmpdir);
[128]490 } else {
[1594]491 if (bkpinfo->backup_media_type == iso) {
492 sprintf(bkpinfo->call_make_iso,
493 "%s %s . 2>> %s",
494 mr_conf->iso_creation_cmd,
495 mondo_mkisofs_sz,
496 MONDO_LOGFILE);
497 } else {
498 if (strstr(mr_conf->iso_burning_cmd,"growisofs") != NULL) {
499 if (getenv ("SUDO_COMMAND")) {
500 mr_asprintf(&command, "strings %s | grep -c SUDO_COMMAND", mr_conf->iso_burning_cmd);
501 if (!strcmp(call_program_and_get_last_line_of_output(command), "1")) {
502 fatal_error("Can't write DVDs as sudo because growisofs doesn't support this - see the growisofs manpage for details.");
503 }
504 mr_free(command);
[1592]505 }
[1594]506 sprintf(bkpinfo->call_make_iso,
507 "%s %s %s %s -Z %s -speed=%d . 2>> %s",
508 mr_conf->iso_burning_cmd,
509 mondo_mkisofs_sz,
510 extra_cdrom_params,
511 mr_conf->iso_burning_opt,
512 bkpinfo->iso_burning_dev,
513 bkpinfo->writer_speed,
514 MONDO_LOGFILE);
515 } else {
516 sprintf(bkpinfo->call_make_iso,
517 "%s %s . 2>> %s | %s %s %s dev=%s speed=%d -",
518 mr_conf->iso_creation_cmd,
519 mondo_mkisofs_sz,
520 MONDO_LOGFILE,
521 mr_conf->iso_burning_cmd,
522 extra_cdrom_params,
523 mr_conf->iso_burning_opt,
524 bkpinfo->iso_burning_dev,
525 bkpinfo->writer_speed);
[1592]526 }
[1594]527 mr_free(mondo_mkisofs_sz);
528 mr_free(extra_cdrom_params);
[1592]529 }
[128]530 }
531 } // end of CD code
[1]532
[128]533 if (bkpinfo->backup_media_type == iso) {
534
[1]535/* Patch by Conor Daly <conor.daly@met.ie>
536 * 23-june-2004
537 * Break up isodir into iso_mnt and iso_path
538 * These will be used along with iso-dev at restore time
539 * to locate the ISOs where ever they're mounted
540 */
541
[128]542 log_it("isodir = %s", bkpinfo->isodir);
[1178]543 mr_asprintf(&command, "df -P %s | tail -n1 | cut -d' ' -f1",
544 bkpinfo->isodir);
[128]545 log_it("command = %s", command);
[1178]546 mr_asprintf(&iso_dev, call_program_and_get_last_line_of_output(command));
547 mr_free(command);
[1087]548 log_it("res of it = %s", iso_dev);
[1]549
[1087]550 fd1 = mr_fopen(MONDORESTORECFG, "a");
[1158]551 mr_fprintf(fd1, "iso-dev=%s\n", iso_dev);
[1087]552
[1178]553 mr_asprintf(&command, "mount | grep -w %s | tail -n1 | cut -d' ' -f3",
554 iso_dev);
555 mr_free(iso_dev);
556
[128]557 log_it("command = %s", command);
[1178]558 mr_asprintf(&iso_mnt,call_program_and_get_last_line_of_output(command));
559 mr_free(command);
[1087]560
561 log_it("res of it = %s", iso_mnt);
[1158]562 mr_fprintf(fd1, "iso-mnt=%s\n", iso_mnt);
[128]563 log_it("isomnt: %s, %d", iso_mnt, strlen(iso_mnt));
[1087]564
[1178]565 mr_asprintf(&iso_tmp, "%s", bkpinfo->isodir);
566 if (strlen(iso_tmp) >= strlen(iso_mnt)) {
567 mr_asprintf(&iso_path, "%s", iso_tmp + strlen(iso_mnt));
[128]568 } else {
[1178]569 mr_asprintf(&iso_path, "");
[128]570 }
[1178]571 mr_free(iso_tmp);
572 mr_free(iso_mnt);
573
[128]574 log_it("isodir: %s", iso_path);
[1158]575 mr_fprintf(fd1, "isodir=%s\n", iso_path);
[1178]576 mr_free(iso_path);
[1087]577
[148]578 log_it("iso-prefix: %s", bkpinfo->prefix);
[1158]579 mr_fprintf(fd1, "iso-prefix=%s\n", bkpinfo->prefix);
[1]580
[1095]581 mr_fclose(fd1);
[128]582 } // end of iso code
[1]583
[128]584 if (bkpinfo->backup_media_type == nfs) {
[1178]585 mr_asprintf(&hostname, bkpinfo->nfs_mount);
[128]586 colon = strchr(hostname, ':');
587 if (!colon) {
588 log_it("nfs mount doesn't have a colon in it");
589 retval++;
590 } else {
591 struct hostent *hent;
[1]592
[128]593 *colon = '\0';
594 hent = gethostbyname(hostname);
595 if (!hent) {
596 log_it("Can't resolve NFS mount (%s): %s", hostname,
597 hstrerror(h_errno));
598 retval++;
599 } else {
[1178]600 mr_asprintf(&ip_address, "%s%s", inet_ntoa((struct in_addr)
601 *((struct in_addr *) hent->h_addr)),
602 strchr(bkpinfo->nfs_mount, ':'));
[128]603 strcpy(bkpinfo->nfs_mount, ip_address);
[1178]604 mr_free(ip_address);
[128]605 }
606 }
[1663]607 store_nfs_config();
[1178]608 mr_free(hostname);
[128]609 }
[1]610
[128]611 log_it("Finished processing incoming params");
612 if (retval) {
613 fprintf(stderr, "Type 'man mondoarchive' for help.\n");
614 }
[1178]615
[128]616 if (strlen(bkpinfo->tmpdir) < 2 || strlen(bkpinfo->scratchdir) < 2) {
617 log_it("tmpdir or scratchdir are blank/missing");
618 retval++;
619 }
620 if (bkpinfo->include_paths[0] == '\0') {
621 // fatal_error ("Why no backup path?");
622 strcpy(bkpinfo->include_paths, "/");
623 }
624 chmod(bkpinfo->scratchdir, 0700);
625 g_backup_media_type = bkpinfo->backup_media_type;
[1178]626 g_backup_media_string = bkpinfo->backup_media_string;
[128]627 return (retval);
[1]628}
629
630
631/**
632 * Do some miscellaneous setup tasks to be performed before filling @c bkpinfo.
633 * Seeds the random-number generator, loads important modules, checks the sanity
634 * of the user's Linux distribution, and deletes logfile.
635 * @param bkpinfo The backup information structure. Will be initialized.
636 * @return number of errors (0 for success)
637 */
[1663]638int pre_param_configuration()
[1]639{
[128]640 int res = 0;
[1663]641 char *tmp = NULL;
[1]642
[128]643 make_hole_for_dir(MNT_CDROM);
644 assert(bkpinfo != NULL);
645 srandom((unsigned long) (time(NULL)));
646 insmod_crucial_modules();
647 if (bkpinfo->disaster_recovery) {
648 if (!does_nonMS_partition_exist()) {
649 fatal_error
650 ("I am in disaster recovery mode\nPlease don't run mondoarchive.");
651 }
652 }
[1]653
[1770]654 asprintf(&tmp,"rm -Rf %s/changed.files*",MONDO_CACHE);
[1663]655 run_program_and_log_output(tmp, FALSE);
656 paranoid_free(tmp);
[128]657 res += some_basic_system_sanity_checks();
658 if (res) {
659 log_it("Your distribution did not pass Mondo's sanity test.");
660 }
661 g_current_media_number = 1;
662 bkpinfo->postnuke_tarball[0] = bkpinfo->nfs_mount[0] = '\0';
663 return (res);
[1]664}
665
[1663]666void setup_tmpdir(char *path) {
667
668 char *tmp = NULL;
669 char *p = NULL;
[1]670
[1663]671 if (bkpinfo->tmpdir != NULL) {
672 /* purging a potential old tmpdir */
673 asprintf(&tmp,"rm -Rf %s",bkpinfo->tmpdir);
674 system(tmp);
675 paranoid_free(tmp);
676 }
677
678 if (path != NULL) {
679 asprintf(&tmp, "%s/mondo.tmp.XXXXXX", path);
680 } else if (getenv("TMPDIR")) {
681 asprintf(&tmp, "%s/mondo.tmp.XXXXXX", getenv("TMPDIR"));
682 } else if (getenv("TMP")) {
683 asprintf(&tmp, "%s/mondo.tmp.XXXXXX", getenv("TMP"));
684 } else {
685 asprintf(&tmp, "/tmp/mondo.tmp.XXXXXX");
686 }
687 p = mkdtemp(tmp);
688 if (p == NULL) {
689 log_it("Failed to create global tmp directory %s for Mondo.",tmp);
690 finish(-1);
691 }
692 strcpy(bkpinfo->tmpdir,p);
693 paranoid_free(tmp);
[1]694
[1663]695 //sprintf(bkpinfo->tmpdir, "%s/tmpfs/mondo.tmp.%d", "/tmp", (int) (random() % 32768)); // for mondorestore
696}
[1]697
[1663]698
[1]699/**
700 * Reset all fields of the backup information structure to a sensible default.
701 * @param bkpinfo The @c bkpinfo to reset.
702 */
[1663]703void reset_bkpinfo()
[1]704{
[1594]705 char *tmp = NULL;
706
[1107]707 mr_msg(1, "Hi");
[1178]708
[128]709 assert(bkpinfo != NULL);
[1178]710 /* BERLIOS : Useless ?? */
[128]711 memset((void *) bkpinfo, 0, sizeof(struct s_bkpinfo));
[1178]712
[1663]713 /* special case for tmpdir as used eveywhere after */
714 setup_tmpdir(NULL);
715
[1609]716 bkpinfo->manual_tray = mr_conf->manual_tray;
[1638]717 bkpinfo->internal_tape_block_size = mr_conf->internal_tape_blocksize;
[1769]718 bkpinfo->compression_level = mr_conf->compression_level;
719 mr_asprintf(&tmp,mr_conf->compression_suffix);
720 bkpinfo->compression_suffix = tmp;
721 mr_asprintf(&tmp,mr_conf->compression_tool);
722 bkpinfo->compression_tool = tmp;
[1594]723 mr_asprintf(&tmp,mr_conf->media_device);
724 bkpinfo->media_device = tmp;
725 mr_asprintf(&tmp,mr_conf->iso_burning_dev);
726 bkpinfo->iso_burning_dev = tmp;
727
728 bkpinfo->media_size = mr_conf->iso_burning_speed;
[1669]729 mr_asprintf(&tmp,mr_conf->kernel);
730 bkpinfo->kernel_path = tmp;
731
[1671]732 if (strcmp(mr_conf->boot_loader,"LILO") == 0) {
733 bkpinfo->boot_loader = 'L';
734 } else if (strcmp(mr_conf->boot_loader,"GRUB") == 0) {
735 bkpinfo->boot_loader = 'G';
736 } else if (strcmp(mr_conf->boot_loader,"ELILO") == 0) {
737 bkpinfo->boot_loader = 'E';
738 } else if (strcmp(mr_conf->boot_loader,"RAW") == 0) {
739 bkpinfo->boot_loader = 'R';
740 } else if (strcmp(mr_conf->boot_loader,"DD") == 0) {
741 bkpinfo->boot_loader = 'D';
742 } else if (strcmp(mr_conf->boot_loader,"BOOT0") == 0) {
743 bkpinfo->boot_loader = 'B';
744 } else if (strcmp(mr_conf->boot_loader,"NATIVE") == 0) {
745 bkpinfo->boot_loader = '\0';
746 } else{
747 mr_msg("Boot Loader %s unknown\n",mr_conf->boot_loader);
748 fatal_error("Unknown Boot Loader in conf file");
749 }
[128]750 bkpinfo->boot_device[0] = '\0';
751 bkpinfo->restore_path[0] = '\0';
752 bkpinfo->do_not_compress_these[0] = '\0';
753 bkpinfo->verify_data = FALSE;
754 bkpinfo->backup_data = FALSE;
755 bkpinfo->restore_data = FALSE;
756 bkpinfo->disaster_recovery =
757 (am_I_in_disaster_recovery_mode()? TRUE : FALSE);
758 if (bkpinfo->disaster_recovery) {
759 strcpy(bkpinfo->isodir, "/");
760 } else {
[1178]761 strcpy(bkpinfo->isodir, "/var/cache/mondo/iso");
[128]762 }
[1628]763 mr_asprintf(&tmp,mr_conf->prefix);
764 bkpinfo->prefix = tmp;
[1]765
[128]766 bkpinfo->scratchdir[0] = '\0';
767 bkpinfo->make_filelist = TRUE; // unless -J supplied to mondoarchive
768 bkpinfo->optimal_set_size = 0;
769 bkpinfo->backup_media_type = none;
[1178]770 bkpinfo->backup_media_string[0] = '\0';
[128]771 strcpy(bkpinfo->include_paths, "/");
772 bkpinfo->exclude_paths[0] = '\0';
773 bkpinfo->call_before_iso[0] = '\0';
774 bkpinfo->call_make_iso[0] = '\0';
775 bkpinfo->call_after_iso[0] = '\0';
776 bkpinfo->image_devs[0] = '\0';
777 bkpinfo->postnuke_tarball[0] = '\0';
778 bkpinfo->nfs_mount[0] = '\0';
779 bkpinfo->nfs_remote_dir[0] = '\0';
780 bkpinfo->wipe_media_first = FALSE;
781 bkpinfo->differential = FALSE;
[1594]782 bkpinfo->writer_speed = mr_conf->iso_burning_speed;
[1]783}
784
785
786/**
787 * Get the remaining free space (in MB) on @p partition.
788 * @param partition The partition to check free space on (either a device or a mountpoint).
789 * @return The free space on @p partition, in MB.
790 */
[128]791long free_space_on_given_partition(char *partition)
[1]792{
[1178]793 char *command = NULL;
794 char *out_sz = NULL;
795 long res = 0L;
[1]796
[128]797 assert_string_is_neither_NULL_nor_zerolength(partition);
[1]798
[1770]799 mr_asprintf(&command, "df -m -P %s 1> /dev/null 2> /dev/null", partition);
[128]800 if (system(command)) {
801 return (-1);
802 } // partition does not exist
[1178]803 mr_free(command);
804
805 mr_asprintf(&command, "df -m -P %s | tail -n1 | tr -s ' ' '\t' | cut -f4",
[128]806 partition);
[1178]807 mr_asprintf(&out_sz, call_program_and_get_last_line_of_output(command));
808 mr_free(command);
809
[128]810 if (strlen(out_sz) == 0) {
811 return (-1);
812 } // error within df, probably
813 res = atol(out_sz);
[1178]814 mr_free(out_sz);
[128]815 return (res);
[1]816}
817
818
819/**
820 * Check the user's system for sanity. Checks performed:
821 * - make sure user has enough RAM (32mb required, 64mb recommended)
822 * - make sure user has enough free space in @c /
823 * - check kernel for ramdisk support
[1592]824 * - make sure afio, cdrecord, bzip2, awk, md5sum, strings, mindi, and buffer exist
[1]825 * - make sure CD-ROM is unmounted
826 * - make sure /etc/modules.conf exists
827 * - make sure user's mountlist is OK by running <tt>mindi --makemountlist</tt>
828 *
829 * @return number of problems with the user's setup (0 for success)
830 */
[128]831int some_basic_system_sanity_checks()
[1]832{
833
[128]834 /*@ buffers ************ */
[1178]835 char *tmp = NULL;
[1]836
[128]837 /*@ int's *************** */
838 int retval = 0;
[1]839
[1178]840 mvaddstr_and_log_it(g_currentY, 0,
841 "Checking sanity of your Linux distribution");
[1]842#ifndef __FreeBSD__
[1770]843 if (system("which mkfs.vfat 2> /dev/null 1> /dev/null")
844 && !system("which mkfs.msdos 2> /dev/null 1> /dev/null")) {
[128]845 log_it
846 ("OK, you've got mkfs.msdos but not mkfs.vfat; time for the fairy to wave her magic wand...");
847 run_program_and_log_output
848 ("ln -sf `which mkfs.msdos` /sbin/mkfs.vfat", FALSE);
849 }
[1178]850 mr_asprintf(&tmp,
[128]851 call_program_and_get_last_line_of_output
852 ("free | grep Mem | head -n1 | tr -s ' ' '\t' | cut -f2"));
853 if (atol(tmp) < 35000) {
854 retval++;
[1178]855 log_to_screen(_("You must have at least 32MB of RAM to use Mondo."));
[128]856 }
857 if (atol(tmp) < 66000) {
858 log_to_screen
[1178]859 (_("WARNING! You have very little RAM. Please upgrade to 64MB or more."));
[128]860 }
[1178]861 mr_free(tmp);
[1]862#endif
863
[1438]864 Lres = free_space_on_given_partition(MONDO_CACHE);
[128]865 log_it("Free space on given partition = %ld MB", Lres);
[1]866
[128]867 if (Lres < 50) {
[1438]868 fatal_error("Your "MONDO_CACHE" partition has <50MB free. Please adjust your partition table to something saner or make "MONDO_CACHE" a symbolic link");
[128]869 }
[1]870
[128]871 if (system("which " MKE2FS_OR_NEWFS " > /dev/null 2> /dev/null")) {
872 retval++;
873 log_to_screen
874 ("Unable to find " MKE2FS_OR_NEWFS " in system path.");
875 fatal_error
876 ("Please use \"su -\", not \"su\" to become root. OK? ...and please don't e-mail the mailing list or me about this. Just read the message. :)");
877 }
[1]878#ifndef __FreeBSD__
[128]879 if (run_program_and_log_output
[273]880 ("grep ramdisk /proc/devices", FALSE)) {
[128]881 if (!ask_me_yes_or_no
[1178]882 (_("Your kernel has no ramdisk support. That's mind-numbingly stupid but I'll allow it if you're planning to use a failsafe kernel. Are you?")))
[128]883 {
884 // retval++;
885 log_to_screen
[1178]886 (_("It looks as if your kernel lacks ramdisk and initrd support."));
[128]887 log_to_screen
[1178]888 (_("I'll allow you to proceed but FYI, if I'm right, your kernel is broken."));
[128]889 }
890 }
[1]891#endif
[1594]892 retval += whine_if_not_found(mr_conf->iso_creation_cmd);
893 retval += whine_if_not_found(mr_conf->iso_burning_cmd);
[128]894 retval += whine_if_not_found(MKE2FS_OR_NEWFS);
[1769]895 retval += whine_if_not_found(mr_conf->compresstion_tool);
[998]896 retval += whine_if_not_found("gzip");
[128]897 retval += whine_if_not_found("awk");
898 retval += whine_if_not_found("md5sum");
899 retval += whine_if_not_found("strings");
900 retval += whine_if_not_found("mindi");
901 retval += whine_if_not_found("buffer");
[1]902
[128]903 // abort if Windows partition but no ms-sys and parted
904 if (!run_program_and_log_output
[680]905 ("mount | grep -w vfat | grep -vE \"/dev/fd|nexdisk\"", 0)
[128]906 ||
907 !run_program_and_log_output
[680]908 ("mount | grep -w dos | grep -vE \"/dev/fd|nexdisk\"", 0)) {
[1178]909 log_to_screen(_("I think you have a Windows 9x partition."));
[128]910 retval += whine_if_not_found("parted");
[1]911#ifndef __IA64__
[128]912 /* IA64 always has one vfat partition for EFI even without Windows */
913 // retval +=
914 if (!find_home_of_exe("ms-sys")) {
[541]915 log_to_screen("Please install ms-sys just in case.");
[128]916 }
917#endif
[1]918 }
919
[128]920 if (!find_home_of_exe("cmp")) {
921 if (!find_home_of_exe("true")) {
922 whine_if_not_found("cmp");
923 } else {
924 log_to_screen
[541]925 ("Your system lacks the 'cmp' binary. I'll create a dummy cmp for you.");
[128]926 if (run_program_and_log_output
927 ("cp -f `which true` /usr/bin/cmp", 0)) {
928 fatal_error("Failed to create dummy 'cmp' file.");
929 }
930 }
[1]931 }
[128]932 run_program_and_log_output
933 ("umount `mount | grep cdr | cut -d' ' -f3 | tr '\n' ' '`", 5);
[1178]934 mr_asprintf(&tmp,
[128]935 call_program_and_get_last_line_of_output
936 ("mount | grep -E \"cdr(om|w)\""));
937 if (strcmp("", tmp)) {
938 if (strstr(tmp, "autofs")) {
939 log_to_screen
[1178]940 (_("Your CD-ROM is mounted via autofs. I therefore cannot tell"));
[128]941 log_to_screen
[1178]942 (_("if a CD actually is inserted. If a CD is inserted, please"));
943 log_to_screen(_("eject it. Thank you."));
[128]944 log_it
945 ("Ignoring autofs CD-ROM 'mount' since we hope nothing's in it.");
946 } else
947 if (run_program_and_log_output("uname -a | grep Knoppix", 5)) {
948 retval++;
949 fatal_error
950 ("Your CD-ROM drive is mounted. Please unmount it.");
951 }
952 }
[1178]953 mr_free(tmp);
[1]954#ifndef __FreeBSD__
[128]955 if (!does_file_exist("/etc/modules.conf")) {
956 if (does_file_exist("/etc/conf.modules")) {
957 log_it("Linking /etc/modules.conf to /etc/conf.modules");
958 run_program_and_log_output
959 ("ln -sf /etc/conf.modules /etc/modules.conf", 5);
960 } else if (does_file_exist("/etc/modprobe.d")) {
961 log_it
962 ("Directory /etc/modprobe.d found. mindi will use its contents.");
963 } else if (does_file_exist("/etc/modprobe.conf")) {
964 log_it("Linking /etc/modules.conf to /etc/modprobe.conf");
965 run_program_and_log_output
966 ("ln -sf /etc/modprobe.conf /etc/modules.conf", 5);
967 } else {
968 retval++;
969 log_to_screen
[1178]970 (_("Please find out what happened to /etc/modules.conf"));
[128]971 }
[1]972 }
973#endif
974
[128]975 run_program_and_log_output("cat /etc/fstab", 5);
[1]976#ifdef __FreeBSD__
[128]977 run_program_and_log_output("vinum printconfig", 5);
[1]978#else
[128]979 run_program_and_log_output("cat /etc/raidtab", 5);
[1]980#endif
981
[128]982 if (run_program_and_log_output("mindi -V", 1)) {
[1178]983 log_to_screen(_("Could not ascertain mindi's version number."));
[128]984 log_to_screen
[1178]985 (_("You have not installed Mondo and/or Mindi properly."));
986 log_to_screen(_("Please uninstall and reinstall them both."));
[128]987 fatal_error("Please reinstall Mondo and Mindi.");
988 }
[1663]989 mr_asprintf(&tmp, "mindi --makemountlist %s/mountlist.txt.test", bkpinfo->tmpdir);
990 if (run_program_and_log_output(tmp, 5)) {
991 log_to_screen(tmp);
[128]992 log_to_screen
[1663]993 (_("failed for some reason."));
[128]994 log_to_screen
[1178]995 (_("Please run that command by hand and examine /var/log/mindi.log"));
[128]996 log_to_screen
[1178]997 (_("for more information. Perhaps your /etc/fstab file is insane."));
[128]998 log_to_screen
[1178]999 (_("Perhaps Mindi's MakeMountlist() subroutine has a bug. We'll see."));
[128]1000 retval++;
1001 }
[1663]1002 mr_free(tmp);
[1]1003
[196]1004 if (!run_program_and_log_output("parted2fdisk -l | grep -i raid", 1)
[128]1005 && !does_file_exist("/etc/raidtab")) {
1006 log_to_screen
[1252]1007 (_("You have RAID partitions but no /etc/raidtab - creating one from "MDSTAT_FILE));
[558]1008 create_raidtab_from_mdstat("/etc/raidtab");
[128]1009 }
1010
1011 if (retval) {
[1178]1012 mvaddstr_and_log_it(g_currentY++, 74, _("Failed."));
[128]1013 } else {
[1178]1014 mvaddstr_and_log_it(g_currentY++, 74, _("Done."));
[128]1015 }
1016 return (retval);
[1]1017}
1018
1019/**
1020 * Retrieve the line containing @p label from the config file.
1021 * @param config_file The file to read from, usually @c /tmp/mondo-restore.cfg.
1022 * @param label What to read from the file.
1023 * @param value Where to put it.
1024 * @return 0 for success, 1 for failure.
1025 */
[128]1026int read_cfg_var(char *config_file, char *label, char *value)
[1]1027{
[128]1028 /*@ buffer ****************************************************** */
[1178]1029 char *command = NULL;
1030 char *tmp = NULL;
[1]1031
[128]1032 /*@ end vars *************************************************** */
[1]1033
[128]1034 assert_string_is_neither_NULL_nor_zerolength(config_file);
1035 assert_string_is_neither_NULL_nor_zerolength(label);
[1178]1036
[128]1037 if (!does_file_exist(config_file)) {
[1178]1038 mr_asprintf(&tmp, "(read_cfg_var) Cannot find %s config file",
1039 config_file);
[128]1040 log_to_screen(tmp);
[1178]1041 mr_free(tmp);
[128]1042 value[0] = '\0';
1043 return (1);
[1178]1044 /* } BERLIOS: Useless:
1045 else if (strstr(value, "/dev/") && strstr(value, "t0")
[128]1046 && !strcmp(label, "media-dev")) {
[1107]1047 mr_msg(2, "FYI, I shan't read new value for %s - already got %s",
[128]1048 label, value);
1049 return (0);
[1178]1050 */ } else {
1051 mr_asprintf(&command, "grep '%s .*' %s| cut -d'=' -f2,3,4,5",
[148]1052 label, config_file);
[128]1053 strcpy(value, call_program_and_get_last_line_of_output(command));
[1178]1054 mr_free(command);
[128]1055 if (strlen(value) == 0) {
1056 return (1);
1057 } else {
1058 return (0);
1059 }
[1]1060 }
1061}
1062
1063
1064/**
1065 * Remount @c supermount if it was unmounted earlier.
1066 */
1067void remount_supermounts_if_necessary()
1068{
[128]1069 if (g_remount_cdrom_at_end) {
1070 run_program_and_log_output("mount " MNT_CDROM, FALSE);
1071 }
[1]1072}
1073
1074/**
1075 * Unmount @c supermount if it's mounted.
1076 */
1077void unmount_supermounts_if_necessary()
1078{
[128]1079 if (run_program_and_log_output
1080 ("mount | grep cdrom | grep super", FALSE) == 0) {
1081 g_remount_cdrom_at_end = TRUE;
1082 run_program_and_log_output("umount " MNT_CDROM, FALSE);
1083 }
[1]1084}
1085
1086/**
1087 * If this is a distribution like Gentoo that doesn't keep /boot mounted, mount it.
1088 */
1089void mount_boot_if_necessary()
1090{
[1178]1091 char *tmp = NULL;
1092 char *tmp1 = NULL;
1093 char *command = NULL;
[1]1094
[1107]1095 mr_msg(1, "Started sub");
1096 mr_msg(4, "About to set g_boot_mountpt[0] to '\\0'");
[128]1097 g_boot_mountpt[0] = '\0';
[1178]1098 mr_msg(4, "Done. Great. Setting command to something");
1099 mr_asprintf(&command,
1100 "grep -v ':' /etc/fstab | grep -vE '^#.*$' | grep -E \"[ ]/boot[ ]\" | tr -s ' ' '\t' | cut -f1 | head -n1");
[1107]1101 mr_msg(4, "Cool. Command = '%s'", command);
[1178]1102 mr_asprintf(&tmp, call_program_and_get_last_line_of_output(command));
1103 mr_free(command);
1104
[1107]1105 mr_msg(4, "tmp = '%s'", tmp);
[128]1106 if (tmp[0]) {
1107 log_it("/boot is at %s according to /etc/fstab", tmp);
[1373]1108 if ((strstr(tmp, "LABEL=") || strstr(tmp,"UUID="))) {
[128]1109 if (!run_program_and_log_output("mount /boot", 5)) {
1110 strcpy(g_boot_mountpt, "/boot");
[1107]1111 mr_msg(1, "Mounted /boot");
[128]1112 } else {
[1373]1113 log_it("...ignored cos it's a label or uuid :-)");
[128]1114 }
1115 } else {
[1178]1116 mr_asprintf(&command, "mount | grep -E '^%s'", tmp);
[1107]1117 mr_msg(3, "command = %s", command);
[128]1118 if (run_program_and_log_output(command, 5)) {
1119 strcpy(g_boot_mountpt, tmp);
[1178]1120 mr_asprintf(&tmp1,
[128]1121 "%s (your /boot partition) is not mounted. I'll mount it before backing up",
1122 g_boot_mountpt);
[1178]1123 log_it(tmp1);
1124 mr_free(tmp1);
1125
1126 mr_asprintf(&tmp1, "mount %s", g_boot_mountpt);
1127 if (run_program_and_log_output(tmp1, 5)) {
[128]1128 g_boot_mountpt[0] = '\0';
[1107]1129 mr_msg(1, "Plan B");
[128]1130 if (!run_program_and_log_output("mount /boot", 5)) {
1131 strcpy(g_boot_mountpt, "/boot");
[1107]1132 mr_msg(1, "Plan B worked");
[128]1133 } else {
[1107]1134 mr_msg(1,
[128]1135 "Plan B failed. Unable to mount /boot for backup purposes. This probably means /boot is mounted already, or doesn't have its own partition.");
1136 }
1137 }
[1178]1138 mr_free(tmp1);
[128]1139 }
[1178]1140 mr_free(command);
[128]1141 }
[1]1142 }
[1178]1143 mr_free(tmp);
[1107]1144 mr_msg(1, "Ended sub");
[1]1145}
1146
1147
1148/**
1149 * If we mounted /boot earlier, unmount it.
1150 */
1151void unmount_boot_if_necessary()
1152{
[1178]1153 char *tmp;
[1]1154
[1107]1155 mr_msg(3, "starting");
[128]1156 if (g_boot_mountpt[0]) {
[1178]1157 mr_asprintf(&tmp, "umount %s", g_boot_mountpt);
[128]1158 if (run_program_and_log_output(tmp, 5)) {
1159 log_it("WARNING - unable to unmount /boot");
1160 }
[1178]1161 mr_free(tmp);
[128]1162 }
[1107]1163 mr_msg(3, "leaving");
[1]1164}
1165
1166
1167/**
1168 * Write a line to a configuration file. Writes a line of the form,
1169 * @c label @c value.
1170 * @param config_file The file to write to. Usually @c mondo-restore.cfg.
1171 * @param label What to call this bit of data you're writing.
1172 * @param value The bit of data you're writing.
1173 * @return 0 for success, 1 for failure.
1174 */
[128]1175int write_cfg_var(char *config_file, char *label, char *value)
[1]1176{
[128]1177 /*@ buffers ***************************************************** */
[1178]1178 char *command = NULL;
1179 char *tempfile = NULL;
1180 char *tmp = NULL;
[1]1181
1182
[128]1183 /*@ end vars *************************************************** */
1184 assert_string_is_neither_NULL_nor_zerolength(config_file);
1185 assert_string_is_neither_NULL_nor_zerolength(label);
1186 assert(value != NULL);
[1178]1187
[128]1188 if (!does_file_exist(config_file)) {
[1178]1189 mr_asprintf(&tmp, "(write_cfg_file) Cannot find %s config file",
1190 config_file);
[128]1191 log_to_screen(tmp);
[1178]1192 mr_free(tmp);
[128]1193 return (1);
1194 }
[1663]1195 mr_asprintf(&tempfile, "%s/mojo-jojo.blah", bkpinfo->tmpdir);
[128]1196 if (does_file_exist(config_file)) {
[1178]1197 mr_asprintf(&command, "grep -vE '^%s .*$' %s > %s",
[148]1198 label, config_file, tempfile);
[128]1199 paranoid_system(command);
[1178]1200 mr_free(command);
[128]1201 }
[1178]1202 mr_asprintf(&command, "echo \"%s %s\" >> %s", label, value, tempfile);
[128]1203 paranoid_system(command);
[1178]1204 mr_free(command);
1205
1206 mr_asprintf(&command, "mv -f %s %s", tempfile, config_file);
[128]1207 paranoid_system(command);
[1178]1208 mr_free(command);
[128]1209 unlink(tempfile);
[1178]1210 mr_free(tempfile);
[128]1211 return (0);
[1]1212}
1213
[541]1214
[1]1215/**
1216 * Allocate or free important globals, depending on @p mal.
1217 * @param mal If TRUE, malloc; if FALSE, free.
1218 */
1219void do_libmondo_global_strings_thing(int mal)
1220{
[128]1221 if (mal) {
1222 malloc_string(g_boot_mountpt);
1223 malloc_string(g_tmpfs_mountpt);
1224 malloc_string(g_serial_string);
1225 malloc_string(g_magicdev_command);
1226 } else {
[1080]1227 mr_free(g_boot_mountpt);
1228 mr_free(g_tmpfs_mountpt);
1229 mr_free(g_serial_string);
1230 mr_free(g_magicdev_command);
[128]1231 }
[1]1232}
1233
1234/**
1235 * Allocate important globals.
1236 * @see do_libmondo_global_strings_thing
1237 */
1238void malloc_libmondo_global_strings(void)
1239{
[128]1240 do_libmondo_global_strings_thing(1);
[1]1241}
1242
1243/**
1244 * Free important globals.
1245 * @see do_libmondo_global_strings_thing
1246 */
1247void free_libmondo_global_strings(void)
1248{
[128]1249 do_libmondo_global_strings_thing(0);
[1]1250}
1251
1252
1253
1254/**
1255 * Stop @c magicdev if it's running.
1256 * The command used to start it is saved in @p g_magicdev_command.
1257 */
1258void stop_magicdev_if_necessary()
1259{
[128]1260 strcpy(g_magicdev_command,
1261 call_program_and_get_last_line_of_output
1262 ("ps ax | grep -w magicdev | grep -v grep | tr -s '\t' ' '| cut -d' ' -f6-99"));
1263 if (g_magicdev_command[0]) {
[1107]1264 mr_msg(1, "g_magicdev_command = '%s'", g_magicdev_command);
[128]1265 paranoid_system("killall magicdev");
1266 }
[1]1267}
1268
1269
1270/**
1271 * Restart magicdev if it was stopped.
1272 */
1273void restart_magicdev_if_necessary()
1274{
[1178]1275 char *tmp = NULL;
[128]1276
1277 if (g_magicdev_command && g_magicdev_command[0]) {
[1178]1278 mr_asprintf(&tmp, "%s &", g_magicdev_command);
[128]1279 paranoid_system(tmp);
[1178]1280 mr_free(tmp);
[128]1281 }
[1]1282}
1283
1284/* @} - end of utilityGroup */
Note: See TracBrowser for help on using the repository browser.