source: MondoRescue/branches/2.2.9/mondo/src/common/libmondo-tools.c@ 2194

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

Some SuSE have ramdisk as modules, so modprobe brd first before testing for ramdisk presence

  • Property svn:keywords set to Id
File size: 39.6 KB
RevLine 
[2030]1/*
[99]2 $Id: libmondo-tools.c 2194 2009-05-08 00:22:10Z bruno $
[1]3*/
4
5
6/**
7 * @file
8 * Miscellaneous tools that didn't really fit anywhere else.
9 */
10
11#include "my-stuff.h"
12#include "mondostructures.h"
[541]13#include "lib-common-externs.h"
[1]14#include "libmondo-tools.h"
[541]15#include "libmondo-gui-EXT.h"
[1]16#include "libmondo-files-EXT.h"
17#include "libmondo-fork-EXT.h"
18#include "libmondo-raid-EXT.h"
[1917]19#include "libmondo-devices-EXT.h"
[1]20#include <sys/socket.h>
21#include <netdb.h>
[1653]22#include <stdlib.h>
[1]23#include <netinet/in.h>
24#include <arpa/inet.h>
[1375]25#include <sys/utsname.h>
[1]26
27/*@unused@*/
[99]28//static char cvsid[] = "$Id: libmondo-tools.c 2194 2009-05-08 00:22:10Z bruno $";
[1]29
30extern int g_tape_buffer_size_MB;
31extern char *g_serial_string;
32extern bool g_text_mode;
33extern int g_currentY;
34extern int g_current_media_number;
[1316]35extern char *MONDO_LOGFILE;
[1]36
[1645]37/* Reference to global bkpinfo */
38extern struct s_bkpinfo *bkpinfo;
39
[1]40/**
41 * @addtogroup globalGroup
42 * @{
43 */
[128]44bool g_remount_cdrom_at_end, ///< TRUE if we unmounted the CD-ROM and should remount it when done with the backup.
45 g_remount_floppy_at_end; ///< TRUE if we unmounted the floppy and should remount it when done with the backup.
46bool g_cd_recovery; ///< TRUE if we're making an "autonuke" backup.
[1]47double g_kernel_version;
48
49/**
50 * The place where /boot is mounted.
51 */
[128]52char *g_boot_mountpt = NULL;
[1]53
54/**
55 * The location of Mondo's home directory.
56 */
[128]57char *g_mondo_home = 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.
[2030]66char *g_tmpfs_mountpt = NULL;
[1]67 */
[128]68char *g_magicdev_command = NULL;
[1]69
70/**
71 * The default maximum level to log messages at or below.
72 */
[128]73int g_loglevel = DEFAULT_DEBUG_LEVEL;
[1]74
75/* @} - end of globalGroup */
76
77
78extern pid_t g_buffer_pid;
79extern pid_t g_main_pid;
80
81extern t_bkptype g_backup_media_type;
82
83extern bool am_I_in_disaster_recovery_mode(void);
84
[1917]85/* Return a string containing the date */
86char *mr_date(void) {
[1]87
[1917]88 time_t tcurr;
89
90 tcurr = time(NULL);
91 return(ctime(&tcurr));
92}
93
94/*-----------------------------------------------------------*/
95
96
[1]97/**
98 * @addtogroup utilityGroup
99 * @{
100 */
101/**
102 * Assertion handler. Prints a friendly message to the user,
103 * offering to ignore all, dump core, break to debugger,
104 * exit, or ignore. Intended to be used with an assert() macro.
105 *
106 * @param file The file in which the assertion triggered.
107 * @param function The function (@c __FUNCTION__) in which the assertion triggered.
108 * @param line The line number of the assert() statement.
109 * @param exp The expression that failed (as a string).
110 */
[128]111void _mondo_assert_fail(const char *file,
112 const char *function, int line, const char *exp)
[1]113{
[128]114 static int ignoring_assertions = 0;
115 bool is_valid = TRUE;
[1]116
[128]117 log_it("ASSERTION FAILED: `%s' at %s:%d in %s", exp, file, line,
118 function);
119 if (ignoring_assertions) {
120 log_it("Well, the user doesn't care...");
121 return;
122 }
[1]123#ifndef _XWIN
[128]124 if (!g_text_mode)
125 newtSuspend();
[1]126#endif
[541]127 printf("ASSERTION FAILED: `%s'\n", exp);
128 printf("\tat %s:%d in %s\n\n", file, line, function);
129 printf("(I)gnore, ignore (A)ll, (D)ebug, a(B)ort, or (E)xit? ");
[128]130 do {
131 is_valid = TRUE;
132 switch (toupper(getchar())) {
133 case 'A': // ignore (A)ll
134 ignoring_assertions = 1;
135 break;
136 case 'B': // a(B)ort
137 signal(SIGABRT, SIG_DFL); /* prevent SIGABRT handler from running */
138 raise(SIGABRT);
139 break; /* "can't get here" */
140 case 'D': // (D)ebug, aka asm("int 3")
[1]141#ifdef __IA32__
[128]142 __asm__ __volatile__("int $3"); // break to debugger
[1]143#endif
[128]144 break;
145 case 'E': // (E)xit
146 fatal_error("Failed assertion -- see above for details");
147 break; /* "can't get here" */
148 case 'I': // (I)gnore
149 break;
150 /* These next two work as follows:
151 the `default' catches the user's invalid choice and says so;
152 the '\n' catches the newline on the end and prints the prompt again.
153 */
154 case '\n':
155 printf
[541]156 ("(I)gnore, ignore (A)ll, (D)ebug, a(B)ort, or (E)xit? ");
[128]157 break;
158 default:
159 is_valid = FALSE;
[541]160 printf("Invalid choice.\n");
[128]161 break;
162 }
163 } while (!is_valid);
164
165 if (ignoring_assertions) {
166 log_it("Ignoring ALL assertions from now on.");
167 } else {
168 log_it("Ignoring assertion: %s", exp);
[1]169 }
170
[128]171 getchar(); // skip \n
[1]172
173#ifndef _XWIN
[128]174 if (!g_text_mode)
175 newtResume();
[1]176#endif
177}
178
179/**
180 * Clean's up users' KDE desktops.
181 * @bug Details about this function are unknown.
182 */
183void clean_up_KDE_desktop_if_necessary(void)
184{
[128]185 char *tmp;
[1]186
[128]187 malloc_string(tmp);
188 strcpy(tmp,
189 "for i in `find /root /home -type d -name Desktop -maxdepth 2`; do \
[1]190file=$i/.directory; if [ -f \"$file\" ] ; then mv -f $file $file.old ; \
[273]191awk '{if (index($0, \"rootimagesmindi\")) { while (length($0)>2) { getline;} ; } \
[275]192else { print $0;};}' $file.old > $file ; fi ; done");
[128]193 run_program_and_log_output(tmp, 5);
194 paranoid_free(tmp);
[1]195}
196
197
198/**
199 * Locate mondoarchive's home directory. Searches in /usr/local/mondo, /usr/share/mondo,
200 * /usr/local/share/mondo, /opt, or if all else fails, search /usr.
201 *
202 * @param home_sz String to store the home directory ("" if it could not be found).
203 * @return 0 for success, nonzero for failure.
204 */
205int find_and_store_mondoarchives_home(char *home_sz)
206{
[128]207 assert(home_sz != NULL);
[424]208 strcpy(home_sz, MONDO_SHARE);
[182]209 return (0);
[1]210}
211
212
[1375]213char *get_architecture(void) {
[1]214#ifdef __IA32__
[1375]215# ifdef __X86_64__
216 return ("x86_64");
217# else
218 return ("i386");
219# endif
[1]220#endif
221#ifdef __IA64__
[128]222 return ("ia64");
[1]223#endif
[128]224 return ("unknown");
[1]225}
226
227
[1375]228char *get_uname_m(void) {
[1]229
[1375]230 struct utsname utsn;
231 char *tmp = NULL;
232
233 uname(&utsn);
[2190]234 asprintf(&tmp, "%s", utsn.machine);
[1375]235 return (tmp);
236}
237
238
239
240double get_kernel_version(void)
[1]241{
[128]242 char *p, tmp[200];
243 double d;
[1]244#ifdef __FreeBSD__
[128]245 // JOSH - FIXME :)
246 d = 5.2; // :-)
[1]247#else
[128]248 strcpy(tmp, call_program_and_get_last_line_of_output("uname -r"));
249 p = strchr(tmp, '.');
250 if (p) {
251 p = strchr(++p, '.');
252 if (p) {
253 while (*p) {
254 *p = *(p + 1);
255 p++;
256 }
257 }
258 }
[1]259// log_msg(1, "tmp = '%s'", tmp);
[128]260 d = atof(tmp);
[1]261#endif
[128]262 log_msg(1, "g_kernel_version = %f", d);
263 return (d);
[1]264}
265
266
267
268
269
270/**
271 * Get the current time.
272 * @return number of seconds since the epoch.
273 */
[128]274long get_time()
[1]275{
[128]276 return (long) time((void *) 0);
[1]277}
278
279
280
281
282
283
284
285/**
286 * Initialize a RAID volume structure, setting fields to zero. The
287 * actual hard drive is unaffected.
288 *
289 * @param raidrec The RAID volume structure to initialize.
290 * @note This function is system dependent.
291 */
292#ifdef __FreeBSD__
[128]293void initialize_raidrec(struct vinum_volume *raidrec)
[1]294{
[128]295 int i, j;
296 raidrec->volname[0] = '\0';
297 raidrec->plexes = 0;
298 for (i = 0; i < 9; ++i) {
299 raidrec->plex[i].raidlevel = -1;
300 raidrec->plex[i].stripesize = 0;
301 raidrec->plex[i].subdisks = 0;
302 for (j = 0; j < 9; ++j) {
303 strcpy(raidrec->plex[i].sd[j].which_device, "");
304 }
305 }
[1]306}
307#else
[128]308void initialize_raidrec(struct raid_device_record *raidrec)
[1]309{
[128]310 assert(raidrec != NULL);
311 raidrec->raid_device[0] = '\0';
[558]312 raidrec->raid_level = -9;
[128]313 raidrec->persistent_superblock = 1;
[558]314 raidrec->chunk_size = 64;
315 raidrec->parity = -1;
[128]316 raidrec->data_disks.entries = 0;
317 raidrec->spare_disks.entries = 0;
318 raidrec->parity_disks.entries = 0;
319 raidrec->failed_disks.entries = 0;
320 raidrec->additional_vars.entries = 0;
[1]321}
322#endif
323
324
325
326
327/**
328 * Insert modules that Mondo requires.
[1236]329 * Currently inserts @c msdos, @c vfat, and @c loop for Linux;
[1]330 * @c msdosfs and @c ext2fs for FreeBSD.
331 */
332void insmod_crucial_modules(void)
333{
334#ifdef __FreeBSD__
[128]335 system("kldstat | grep msdosfs || kldload msdosfs 2> /dev/null");
336 system("kldstat | grep ext2fs || kldload ext2fs 2> /dev/null");
[1]337#else
[1236]338 system("modprobe -a msdos vfat loop &> /dev/null");
[1]339#endif
340}
341
342
343/**
[541]344 * Log a trace message to the trace file.
345 * @bug This function seems orphaned. Please remove.
346 */
347void log_trace(char *o)
348{
349 /*@ pointers **************************************************** */
350 FILE *fout;
351
352 /*@ buffers ***************************************************** */
353 char output[MAX_STR_LEN];
354
355 /*@ int ****************************************************** */
356 int i;
357
358 /*@ end vars *************************************************** */
359
360 if (o[0] == '\0') {
361 return;
362 }
363 strcpy(output, o);
364 i = (int) strlen(output);
365 if (i <= 0) {
366 return;
367 }
368 if (output[i - 1] < 32) {
369 output[i - 1] = '\0';
370 }
371 if (g_text_mode
372 /* && !strstr(last_line_of_file(MONDO_LOGFILE),output) */ ) {
373 printf("%s\n", output);
374 }
375
376 fout = fopen(MONDO_TRACEFILE, "a");
377 if (fout) {
378 fprintf(fout, "%s\n", output);
379 paranoid_fclose(fout);
380 } else {
381 log_OS_error("Cannot write to tracefile");
382 }
383}
384
385
386
387
388
389/**
[1]390 * Finish configuring the backup information structure. Call this function
391 * to set the parameters that depend on those that can be given on the command
392 * line.
393 *
394 * @param bkpinfo The backup information structure. Fields modified/used:
395 * - Used: @c bkpinfo->backup_data
396 * - Used: @c bkpinfo->backup_media_type
397 * - Used: @c bkpinfo->cdrw_speed
398 * - Used: @c bkpinfo->compression_level
399 * - Used: @c bkpinfo->include_paths
[20]400 * - Used: @c bkpinfo->prefix
[1]401 * - Used: @c bkpinfo->isodir
402 * - Used: @c bkpinfo->manual_cd_tray
403 * - Used: @c bkpinfo->make_cd_use_lilo
404 * - Used: @c bkpinfo->media_device
405 * - Used: @c bkpinfo->nfs_mount
406 * - Used: @c bkpinfo->nonbootable_backup
407 * - Used: @c bkpinfo->scratchdir
408 * - Used: @c bkpinfo->tmpdir
409 * - Used: @c bkpinfo->use_lzo
410 * - Modified: @c bkpinfo->call_before_iso
411 * - Modified: @c bkpinfo->call_make_iso
412 * - Modified: @c bkpinfo->optimal_set_size
413 * - Modified: @c bkpinfo->zip_exe
414 * - Modified: @c bkpinfo->zip_suffix
415 *
416 * @return number of errors, or 0 for success.
417 * @note Also creates directories that are specified in the @c bkpinfo structure but
418 * do not exist.
419 */
[1645]420int post_param_configuration()
[1]421{
[128]422 char *extra_cdrom_params;
423 char *mondo_mkisofs_sz;
424 char *command;
425 char *mtpt;
426 char *hostname, *ip_address;
427 int retval = 0;
428 char *colon;
429 char *cdr_exe;
430 char *tmp;
[163]431 char call_before_iso_user[MAX_STR_LEN] = "\0";
[2030]432 /*
433 long avm = 0;
[128]434 int rdsiz_MB;
[2030]435 */
[128]436 char *iso_dev;
437 char *iso_mnt;
438 char *iso_tmp;
439 char *iso_path;
[1]440
[128]441 assert(bkpinfo != NULL);
442 malloc_string(extra_cdrom_params);
443 malloc_string(mondo_mkisofs_sz);
444 malloc_string(command);
445 malloc_string(mtpt);
446 malloc_string(hostname);
447 malloc_string(ip_address);
448 malloc_string(cdr_exe);
449 malloc_string(tmp);
450 malloc_string(iso_dev);
451 malloc_string(iso_mnt);
452 malloc_string(iso_tmp);
453 malloc_string(iso_path);
454 bkpinfo->optimal_set_size =
[686]455 (IS_THIS_A_STREAMING_BACKUP(bkpinfo->backup_media_type) ? 16 : 16) *
[128]456 1024;
[1]457
[128]458 log_msg(1, "Foo");
459 if (bkpinfo->backup_media_type == tape) {
460 log_msg(1, "Bar");
461 sprintf(tmp, "mt -f %s status", bkpinfo->media_device);
462 log_msg(1, "tmp = '%s'", tmp);
463 if (run_program_and_log_output(tmp, 3)) {
464 fatal_error
465 ("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.");
466 }
[1]467 }
[128]468 make_hole_for_dir(bkpinfo->scratchdir);
469 if (bkpinfo->backup_media_type == iso)
470 make_hole_for_dir(bkpinfo->isodir);
[1]471
[128]472 run_program_and_log_output("uname -a", 5);
[678]473 run_program_and_log_output("cat /etc/*-release", 5);
[128]474 run_program_and_log_output("cat /etc/*issue*", 5);
[1]475#ifdef __FreeBSD__
476#else
[128]477 run_program_and_log_output("cat /proc/cpuinfo", 5);
478 run_program_and_log_output
479 ("rpm -q newt newt-devel slang slang-devel ncurses ncurses-devel gcc",
480 5);
[1]481#endif
[128]482
483 if (bkpinfo->use_lzo) {
484 strcpy(bkpinfo->zip_exe, "lzop");
485 strcpy(bkpinfo->zip_suffix, "lzo");
[998]486 } else if (bkpinfo->use_gzip) {
487 strcpy(bkpinfo->zip_exe, "gzip");
488 strcpy(bkpinfo->zip_suffix, "gz");
[128]489 } else if (bkpinfo->compression_level != 0) {
490 strcpy(bkpinfo->zip_exe, "bzip2");
491 strcpy(bkpinfo->zip_suffix, "bz2");
492 } else {
493 bkpinfo->zip_exe[0] = bkpinfo->zip_suffix[0] = '\0';
[1]494 }
495
496// DVD
497
[128]498 if (bkpinfo->backup_media_type == dvd) {
499 extra_cdrom_params[0] = '\0';
500 mondo_mkisofs_sz[0] = '\0';
501 if (find_home_of_exe("growisofs")) {
502 strcpy(cdr_exe, "growisofs");
503 } // unlikely to be used
504 else {
505 fatal_error("Please install growisofs.");
506 }
507 if (bkpinfo->nonbootable_backup) {
508 strcat(mondo_mkisofs_sz, MONDO_GROWISOFS_NONBOOT);
509 } else if
[1]510#ifdef __FreeBSD__
[128]511 (TRUE)
[1]512#else
[128]513 (bkpinfo->make_cd_use_lilo)
[1]514#endif
515#ifdef __IA64__
[128]516 {
517 strcat(mondo_mkisofs_sz, MONDO_GROWISOFS_REGULAR_ELILO);
518 }
[1]519#else
520 {
[128]521 strcat(mondo_mkisofs_sz, MONDO_GROWISOFS_REGULAR_LILO);
[1]522 }
[128]523#endif
524 else
525 {
526 strcat(mondo_mkisofs_sz, MONDO_GROWISOFS_REGULAR_SYSLINUX);
527 }
528 if (bkpinfo->manual_cd_tray) {
529 fatal_error("Manual CD tray + DVD not supported yet.");
530 // -m isn't supported by growisofs, BTW...
531 } else {
532 sprintf(bkpinfo->call_make_iso,
533 "%s %s -Z %s . 2>> _ERR_",
534 mondo_mkisofs_sz,
535 extra_cdrom_params, bkpinfo->media_device);
536 }
[153]537 if (getenv ("SUDO_COMMAND")) {
[679]538 sprintf(command, "strings `which growisofs` | grep -c SUDO_COMMAND");
539 if (!strcmp(call_program_and_get_last_line_of_output(command), "1")) {
540 popup_and_OK("Fatal Error: Can't write DVDs as sudo because growisofs doesn't support this - see the growisofs manpage for details.");
541 fatal_error("Can't write DVDs as sudo because growisofs doesn't support this - see the growisofs manpage for details.");
542 }
[153]543 }
[128]544 log_msg(2, "call_make_iso (DVD res) is ... %s",
545 bkpinfo->call_make_iso);
546 } // end of DVD code
[1]547
548// CD-R or CD-RW
[128]549 if (bkpinfo->backup_media_type == cdrw
550 || bkpinfo->backup_media_type == cdr) {
551 extra_cdrom_params[0] = '\0';
552 if (!bkpinfo->manual_cd_tray) {
553 strcat(extra_cdrom_params, "-waiti ");
554 }
555 if (bkpinfo->backup_media_type == cdrw) {
556 strcat(extra_cdrom_params, "blank=fast ");
557 }
558 if (find_home_of_exe("cdrecord")) {
559 strcpy(cdr_exe, "cdrecord");
560 } else if (find_home_of_exe("dvdrecord")) {
561 strcpy(cdr_exe, "dvdrecord");
562 } else {
563 fatal_error("Please install either cdrecord or dvdrecord.");
564 }
565 if (bkpinfo->nonbootable_backup) {
566 strcpy(mondo_mkisofs_sz, MONDO_MKISOFS_NONBOOT);
567 } else if
[1]568#ifdef __FreeBSD__
[128]569 (TRUE)
[1]570#else
[128]571 (bkpinfo->make_cd_use_lilo)
[1]572#endif
573#ifdef __IA64__
574 {
[128]575 strcat(mondo_mkisofs_sz, MONDO_MKISOFS_REGULAR_ELILO);
[1]576 }
[128]577#else
[1]578 {
[128]579 strcpy(mondo_mkisofs_sz, MONDO_MKISOFS_REGULAR_LILO);
[1]580 }
[128]581#endif
582 else
583 {
584 strcpy(mondo_mkisofs_sz, MONDO_MKISOFS_REGULAR_SYSLINUX);
585 }
586 if (bkpinfo->manual_cd_tray) {
[163]587 if (bkpinfo->call_before_iso[0] == '\0') {
[128]588 sprintf(bkpinfo->call_before_iso,
[1666]589 "%s -o %s/"MONDO_TMPISOS" . 2>> _ERR_",
[163]590 mondo_mkisofs_sz, bkpinfo->tmpdir);
591 } else {
592 strncpy(call_before_iso_user, bkpinfo->call_before_iso, MAX_STR_LEN);
593 sprintf (bkpinfo->call_before_iso,
[1666]594 "( %s -o %s/"MONDO_TMPISOS" . 2>> _ERR_ ; %s )",
[163]595 mondo_mkisofs_sz, bkpinfo->tmpdir, call_before_iso_user);
596 }
597 log_it("bkpinfo->call_before_iso = %s", bkpinfo->call_before_iso);
[128]598 sprintf(bkpinfo->call_make_iso,
[1666]599 "%s %s -v %s fs=4m dev=%s speed=%d %s/"MONDO_TMPISOS,
[128]600 cdr_exe, (bkpinfo->please_dont_eject) ? " " : "-eject",
601 extra_cdrom_params, bkpinfo->media_device,
602 bkpinfo->cdrw_speed, bkpinfo->tmpdir);
603 } else {
604 sprintf(bkpinfo->call_make_iso,
605 "%s . 2>> _ERR_ | %s %s %s fs=4m dev=%s speed=%d -",
606 mondo_mkisofs_sz, cdr_exe,
607 (bkpinfo->please_dont_eject) ? " " : "-eject",
608 extra_cdrom_params, bkpinfo->media_device,
609 bkpinfo->cdrw_speed);
610 }
611 } // end of CD code
[1]612
[128]613 /*
614 if (bkpinfo->backup_data && bkpinfo->backup_media_type == tape)
615 {
616 sprintf (tmp,
617 "dd if=/dev/zero of=%s bs=%ld count=32 2> /dev/null",
618 bkpinfo->media_device, bkpinfo->internal_tape_block_size);
619 if (system(tmp))
620 {
621 retval++;
622 fprintf (stderr,
623 "Cannot write to tape device. Is the tape set read-only?\n");
624 }
625 } // end of tape code
626 */
[1]627
628
[128]629 if (bkpinfo->backup_media_type == iso) {
630
[1]631/* Patch by Conor Daly <conor.daly@met.ie>
632 * 23-june-2004
633 * Break up isodir into iso_mnt and iso_path
634 * These will be used along with iso-dev at restore time
635 * to locate the ISOs where ever they're mounted
636 */
637
[128]638 log_it("isodir = %s", bkpinfo->isodir);
[165]639 sprintf(command, "df -P %s | tail -n1 | cut -d' ' -f1",
[128]640 bkpinfo->isodir);
641 log_it("command = %s", command);
642 log_it("res of it = %s",
643 call_program_and_get_last_line_of_output(command));
644 sprintf(iso_dev, "%s",
645 call_program_and_get_last_line_of_output(command));
646 sprintf(tmp, "%s/ISO-DEV", bkpinfo->tmpdir);
647 write_one_liner_data_file(tmp,
648 call_program_and_get_last_line_of_output
649 (command));
[1]650
[128]651 sprintf(command, "mount | grep -w %s | tail -n1 | cut -d' ' -f3",
652 iso_dev);
653 log_it("command = %s", command);
654 log_it("res of it = %s",
655 call_program_and_get_last_line_of_output(command));
656 sprintf(iso_mnt, "%s",
657 call_program_and_get_last_line_of_output(command));
658 sprintf(tmp, "%s/ISO-MNT", bkpinfo->tmpdir);
659 write_one_liner_data_file(tmp,
660 call_program_and_get_last_line_of_output
661 (command));
662 log_it("isomnt: %s, %d", iso_mnt, strlen(iso_mnt));
663 sprintf(iso_tmp, "%s", bkpinfo->isodir);
664 if (strlen(iso_tmp) < strlen(iso_mnt)) {
665 iso_path[0] = '\0';
666 } else {
667 sprintf(iso_path, "%s", iso_tmp + strlen(iso_mnt));
668 }
669 sprintf(tmp, "%s/ISODIR", bkpinfo->tmpdir);
670 write_one_liner_data_file(tmp, iso_path);
671 log_it("isodir: %s", iso_path);
[148]672 sprintf(tmp, "%s/ISO-PREFIX", bkpinfo->tmpdir);
673 write_one_liner_data_file(tmp, bkpinfo->prefix);
674 log_it("iso-prefix: %s", bkpinfo->prefix);
[1]675
676/* End patch */
[128]677 } // end of iso code
[1]678
[128]679 if (bkpinfo->backup_media_type == nfs) {
680 strcpy(hostname, bkpinfo->nfs_mount);
681 colon = strchr(hostname, ':');
682 if (!colon) {
683 log_it("nfs mount doesn't have a colon in it");
684 retval++;
685 } else {
686 struct hostent *hent;
[1]687
[128]688 *colon = '\0';
689 hent = gethostbyname(hostname);
690 if (!hent) {
691 log_it("Can't resolve NFS mount (%s): %s", hostname,
692 hstrerror(h_errno));
693 retval++;
694 } else {
695 strcpy(ip_address, inet_ntoa
696 ((struct in_addr)
697 *((struct in_addr *) hent->h_addr)));
698 strcat(ip_address, strchr(bkpinfo->nfs_mount, ':'));
699 strcpy(bkpinfo->nfs_mount, ip_address);
700 }
701 }
[1645]702 store_nfs_config();
[128]703 }
[1]704
[128]705 log_it("Finished processing incoming params");
706 if (retval) {
707 fprintf(stderr, "Type 'man mondoarchive' for help.\n");
708 }
709 if (strlen(bkpinfo->tmpdir) < 2 || strlen(bkpinfo->scratchdir) < 2) {
710 log_it("tmpdir or scratchdir are blank/missing");
711 retval++;
712 }
713 if (bkpinfo->include_paths[0] == '\0') {
714 // fatal_error ("Why no backup path?");
715 strcpy(bkpinfo->include_paths, "/");
716 }
717 chmod(bkpinfo->scratchdir, 0700);
718 g_backup_media_type = bkpinfo->backup_media_type;
719 paranoid_free(mtpt);
720 paranoid_free(extra_cdrom_params);
721 paranoid_free(mondo_mkisofs_sz);
722 paranoid_free(command);
723 paranoid_free(hostname);
724 paranoid_free(ip_address);
725 paranoid_free(cdr_exe);
726 paranoid_free(tmp);
727 paranoid_free(iso_dev);
728 paranoid_free(iso_mnt);
729 paranoid_free(iso_tmp);
730 paranoid_free(iso_path);
731 return (retval);
[1]732}
733
734
735
736/**
737 * Do some miscellaneous setup tasks to be performed before filling @c bkpinfo.
738 * Seeds the random-number generator, loads important modules, checks the sanity
739 * of the user's Linux distribution, and deletes logfile.
740 * @param bkpinfo The backup information structure. Will be initialized.
741 * @return number of errors (0 for success)
742 */
[1645]743int pre_param_configuration()
[1]744{
[128]745 int res = 0;
[1652]746 char *tmp = NULL;
[1]747
[128]748 make_hole_for_dir(MNT_CDROM);
749 assert(bkpinfo != NULL);
750 srandom((unsigned long) (time(NULL)));
751 insmod_crucial_modules();
752 if (bkpinfo->disaster_recovery) {
753 if (!does_nonMS_partition_exist()) {
754 fatal_error
755 ("I am in disaster recovery mode\nPlease don't run mondoarchive.");
756 }
757 }
[1]758
[128]759 unlink(MONDO_TRACEFILE);
[1747]760 asprintf(&tmp,"rm -Rf %s/changed.files*",MONDO_CACHE);
[1652]761 run_program_and_log_output(tmp, FALSE);
762 paranoid_free(tmp);
[128]763 if (find_and_store_mondoarchives_home(g_mondo_home)) {
764 fprintf(stderr,
765 "Cannot find Mondo's homedir. I think you have >1 'mondo' directory on your hard disk. Please delete the superfluous 'mondo' directories and try again\n");
766 res++;
767 return (res);
768 }
769 res += some_basic_system_sanity_checks();
770 if (res) {
771 log_it("Your distribution did not pass Mondo's sanity test.");
772 }
773 g_current_media_number = 1;
774 bkpinfo->postnuke_tarball[0] = bkpinfo->nfs_mount[0] = '\0';
775 return (res);
[1]776}
777
[1655]778void setup_tmpdir(char *path) {
[1967]779
[1653]780 char *tmp = NULL;
[1654]781 char *p = NULL;
[1]782
[1999]783 if ((bkpinfo->tmpdir != NULL) && (strstr(bkpinfo->tmpdir,"mondo.tmp.") != NULL)) {
[1655]784 /* purging a potential old tmpdir */
785 asprintf(&tmp,"rm -Rf %s",bkpinfo->tmpdir);
[1657]786 system(tmp);
[1655]787 paranoid_free(tmp);
788 }
[1967]789
[1657]790 if (path != NULL) {
791 asprintf(&tmp, "%s/mondo.tmp.XXXXXX", path);
792 } else if (getenv("TMPDIR")) {
[1653]793 asprintf(&tmp, "%s/mondo.tmp.XXXXXX", getenv("TMPDIR"));
794 } else if (getenv("TMP")) {
795 asprintf(&tmp, "%s/mondo.tmp.XXXXXX", getenv("TMP"));
796 } else {
797 asprintf(&tmp, "/tmp/mondo.tmp.XXXXXX");
798 }
[1654]799 p = mkdtemp(tmp);
800 if (p == NULL) {
801 log_it("Failed to create global tmp directory %s for Mondo.",tmp);
[1653]802 finish(-1);
803 }
[1654]804 strcpy(bkpinfo->tmpdir,p);
805 paranoid_free(tmp);
[1653]806}
[1]807
808
809/**
810 * Reset all fields of the backup information structure to a sensible default.
811 * @param bkpinfo The @c bkpinfo to reset.
812 */
[1645]813void reset_bkpinfo()
[1]814{
[128]815 int i;
[1]816
[128]817 log_msg(1, "Hi");
818 assert(bkpinfo != NULL);
819 memset((void *) bkpinfo, 0, sizeof(struct s_bkpinfo));
[1653]820
[128]821 bkpinfo->media_device[0] = '\0';
822 for (i = 0; i <= MAX_NOOF_MEDIA; i++) {
823 bkpinfo->media_size[i] = -1;
824 }
825 bkpinfo->boot_loader = '\0';
826 bkpinfo->boot_device[0] = '\0';
827 bkpinfo->zip_exe[0] = '\0';
828 bkpinfo->zip_suffix[0] = '\0';
[1966]829 bkpinfo->image_devs[0] = '\0';
830 bkpinfo->compression_level = 3;
[128]831 bkpinfo->use_lzo = FALSE;
[998]832 bkpinfo->use_gzip = FALSE;
[128]833 bkpinfo->do_not_compress_these[0] = '\0';
834 bkpinfo->verify_data = FALSE;
835 bkpinfo->backup_data = FALSE;
836 bkpinfo->restore_data = FALSE;
[1966]837 bkpinfo->use_star = FALSE;
838 bkpinfo->internal_tape_block_size = DEFAULT_INTERNAL_TAPE_BLOCK_SIZE;
[128]839 bkpinfo->disaster_recovery =
840 (am_I_in_disaster_recovery_mode()? TRUE : FALSE);
841 if (bkpinfo->disaster_recovery) {
842 strcpy(bkpinfo->isodir, "/");
843 } else {
[2059]844 strcpy(bkpinfo->isodir, MONDO_CACHE);
[128]845 }
[148]846 strcpy(bkpinfo->prefix, STD_PREFIX);
[1966]847 sensibly_set_tmpdir_and_scratchdir();
[1]848
[128]849 bkpinfo->optimal_set_size = 0;
850 strcpy(bkpinfo->include_paths, "/");
[1966]851 bkpinfo->make_filelist = TRUE; // unless -J supplied to mondoarchive
852 bkpinfo->include_paths[0] = '\0';
[128]853 bkpinfo->exclude_paths[0] = '\0';
[1966]854 bkpinfo->restore_path[0] = '\0';
[128]855 bkpinfo->call_before_iso[0] = '\0';
856 bkpinfo->call_make_iso[0] = '\0';
857 bkpinfo->call_burn_iso[0] = '\0';
858 bkpinfo->call_after_iso[0] = '\0';
859 bkpinfo->kernel_path[0] = '\0';
860 bkpinfo->nfs_mount[0] = '\0';
861 bkpinfo->nfs_remote_dir[0] = '\0';
[1966]862 bkpinfo->postnuke_tarball[0] = '\0';
[128]863 bkpinfo->wipe_media_first = FALSE;
[1966]864 bkpinfo->differential = 0;
865 bkpinfo->please_dont_eject = FALSE;
[128]866 bkpinfo->cdrw_speed = 0;
[1966]867 bkpinfo->manual_cd_tray = FALSE;
868 bkpinfo->nonbootable_backup = FALSE;
869 bkpinfo->make_cd_use_lilo = FALSE;
870 bkpinfo->use_obdr = FALSE;
[1967]871 bkpinfo->restore_mode = interactive;
[1]872}
873
874
875
876
877/**
878 * Get the remaining free space (in MB) on @p partition.
879 * @param partition The partition to check free space on (either a device or a mountpoint).
880 * @return The free space on @p partition, in MB.
881 */
[128]882long free_space_on_given_partition(char *partition)
[1]883{
[128]884 char command[MAX_STR_LEN], out_sz[MAX_STR_LEN];
885 long res;
[1]886
[128]887 assert_string_is_neither_NULL_nor_zerolength(partition);
[1]888
[1744]889 sprintf(command, "df -m -P %s 1> /dev/null 2> /dev/null", partition);
[128]890 if (system(command)) {
891 return (-1);
892 } // partition does not exist
[305]893 sprintf(command, "df -m -P %s | tail -n1 | tr -s ' ' '\t' | cut -f4",
[128]894 partition);
895 strcpy(out_sz, call_program_and_get_last_line_of_output(command));
896 if (strlen(out_sz) == 0) {
897 return (-1);
898 } // error within df, probably
899 res = atol(out_sz);
900 return (res);
[1]901}
902
903
904
905/**
906 * Check the user's system for sanity. Checks performed:
907 * - make sure user has enough RAM (32mb required, 64mb recommended)
908 * - make sure user has enough free space in @c /
909 * - check kernel for ramdisk support
910 * - make sure afio, cdrecord, mkisofs, bzip2, awk, md5sum, strings, mindi, and buffer exist
911 * - make sure CD-ROM is unmounted
912 * - make sure user's mountlist is OK by running <tt>mindi --makemountlist</tt>
913 *
914 * @return number of problems with the user's setup (0 for success)
915 */
[128]916int some_basic_system_sanity_checks()
[1]917{
918
[128]919 /*@ buffers ************ */
920 char tmp[MAX_STR_LEN];
921 // char command[MAX_STR_LEN];
[1]922
[128]923 /*@ int's *************** */
924 int retval = 0;
[1]925
[128]926 mvaddstr_and_log_it(g_currentY, 0,
927 "Checking sanity of your Linux distribution");
[1]928#ifndef __FreeBSD__
[1737]929 if (system("which mkfs.vfat 2> /dev/null 1> /dev/null")
930 && !system("which mkfs.msdos 2> /dev/null 1> /dev/null")) {
[128]931 log_it
932 ("OK, you've got mkfs.msdos but not mkfs.vfat; time for the fairy to wave her magic wand...");
933 run_program_and_log_output
934 ("ln -sf `which mkfs.msdos` /sbin/mkfs.vfat", FALSE);
935 }
936 strcpy(tmp,
937 call_program_and_get_last_line_of_output
938 ("free | grep Mem | head -n1 | tr -s ' ' '\t' | cut -f2"));
939 if (atol(tmp) < 35000) {
940 retval++;
[541]941 log_to_screen("You must have at least 32MB of RAM to use Mondo.");
[128]942 }
943 if (atol(tmp) < 66000) {
944 log_to_screen
[541]945 ("WARNING! You have very little RAM. Please upgrade to 64MB or more.");
[128]946 }
[1]947#endif
948
[128]949 if (system("which " MKE2FS_OR_NEWFS " > /dev/null 2> /dev/null")) {
950 retval++;
951 log_to_screen
952 ("Unable to find " MKE2FS_OR_NEWFS " in system path.");
953 fatal_error
954 ("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. :)");
955 }
[1]956#ifndef __FreeBSD__
[128]957 if (run_program_and_log_output
[273]958 ("grep ramdisk /proc/devices", FALSE)) {
[2194]959 /* Some SuSE have ramdisk as modules, so insert it first, then test again */
960 run_program_and_log_output("modprobe brd 2> /dev/null > /dev/null");
961 if (run_program_and_log_output
962 ("grep ramdisk /proc/devices", FALSE)) {
963 if (!ask_me_yes_or_no
964 ("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?"))
965 {
966 // retval++;
967 log_to_screen
968 ("It looks as if your kernel lacks ramdisk and initrd support.");
969 log_to_screen
970 ("I'll allow you to proceed but FYI, if I'm right, your kernel is broken.");
971 }
[128]972 }
973 }
[1]974#endif
[128]975 retval += whine_if_not_found(MKE2FS_OR_NEWFS);
976 retval += whine_if_not_found("mkisofs");
977 if (system("which dvdrecord > /dev/null 2> /dev/null")) {
978 retval += whine_if_not_found("cdrecord");
979 }
980 retval += whine_if_not_found("bzip2");
[998]981 retval += whine_if_not_found("gzip");
[128]982 retval += whine_if_not_found("awk");
983 retval += whine_if_not_found("md5sum");
984 retval += whine_if_not_found("strings");
985 retval += whine_if_not_found("mindi");
986 retval += whine_if_not_found("buffer");
[1]987
[128]988 // abort if Windows partition but no ms-sys and parted
[1855]989 if (!run_program_and_log_output("mount | grep -Ew 'vfat|fat|dos' | grep -vE \"/dev/fd|nexdisk\"", 0)) {
[541]990 log_to_screen("I think you have a Windows 9x partition.");
[128]991 retval += whine_if_not_found("parted");
[1]992 }
993
[128]994 if (!find_home_of_exe("cmp")) {
995 if (!find_home_of_exe("true")) {
996 whine_if_not_found("cmp");
997 } else {
998 log_to_screen
[541]999 ("Your system lacks the 'cmp' binary. I'll create a dummy cmp for you.");
[128]1000 if (run_program_and_log_output
1001 ("cp -f `which true` /usr/bin/cmp", 0)) {
1002 fatal_error("Failed to create dummy 'cmp' file.");
1003 }
1004 }
[1]1005 }
[128]1006 run_program_and_log_output
1007 ("umount `mount | grep cdr | cut -d' ' -f3 | tr '\n' ' '`", 5);
1008 strcpy(tmp,
1009 call_program_and_get_last_line_of_output
1010 ("mount | grep -E \"cdr(om|w)\""));
1011 if (strcmp("", tmp)) {
1012 if (strstr(tmp, "autofs")) {
1013 log_to_screen
[541]1014 ("Your CD-ROM is mounted via autofs. I therefore cannot tell");
[128]1015 log_to_screen
[541]1016 ("if a CD actually is inserted. If a CD is inserted, please");
1017 log_to_screen("eject it. Thank you.");
[128]1018 log_it
1019 ("Ignoring autofs CD-ROM 'mount' since we hope nothing's in it.");
1020 } else
1021 if (run_program_and_log_output("uname -a | grep Knoppix", 5)) {
1022 retval++;
1023 fatal_error
1024 ("Your CD-ROM drive is mounted. Please unmount it.");
1025 }
1026 }
[1]1027
[128]1028 run_program_and_log_output("cat /etc/fstab", 5);
[1]1029#ifdef __FreeBSD__
[128]1030 run_program_and_log_output("vinum printconfig", 5);
[1]1031#else
[128]1032 run_program_and_log_output("cat /etc/raidtab", 5);
[1]1033#endif
1034
[128]1035 if (run_program_and_log_output("mindi -V", 1)) {
[541]1036 log_to_screen("Could not ascertain mindi's version number.");
[128]1037 log_to_screen
[541]1038 ("You have not installed Mondo and/or Mindi properly.");
1039 log_to_screen("Please uninstall and reinstall them both.");
[128]1040 fatal_error("Please reinstall Mondo and Mindi.");
1041 }
[1644]1042 sprintf(tmp, "mindi --makemountlist %s/mountlist.txt.test", bkpinfo->tmpdir);
1043 if (run_program_and_log_output(tmp, 5)) {
1044 sprintf(tmp, "mindi --makemountlist %s/mountlist.txt.test failed for some reason.", bkpinfo->tmpdir);
1045 log_to_screen(tmp);
[128]1046 log_to_screen
[541]1047 ("Please run that command by hand and examine /var/log/mindi.log");
[128]1048 log_to_screen
[541]1049 ("for more information. Perhaps your /etc/fstab file is insane.");
[128]1050 log_to_screen
[541]1051 ("Perhaps Mindi's MakeMountlist() subroutine has a bug. We'll see.");
[128]1052 retval++;
1053 }
[1]1054
[196]1055 if (!run_program_and_log_output("parted2fdisk -l | grep -i raid", 1)
[128]1056 && !does_file_exist("/etc/raidtab")) {
1057 log_to_screen
[541]1058 ("You have RAID partitions but no /etc/raidtab - creating one from /proc/mdstat");
[558]1059 create_raidtab_from_mdstat("/etc/raidtab");
[128]1060 }
1061
1062 if (retval) {
[541]1063 mvaddstr_and_log_it(g_currentY++, 74, "Failed.");
[128]1064 } else {
[541]1065 mvaddstr_and_log_it(g_currentY++, 74, "Done.");
[128]1066 }
1067 return (retval);
[1]1068}
1069
1070/**
1071 * Retrieve the line containing @p label from the config file.
1072 * @param config_file The file to read from, usually @c /tmp/mondo-restore.cfg.
1073 * @param label What to read from the file.
1074 * @param value Where to put it.
1075 * @return 0 for success, 1 for failure.
1076 */
[128]1077int read_cfg_var(char *config_file, char *label, char *value)
[1]1078{
[128]1079 /*@ buffer ****************************************************** */
1080 char command[MAX_STR_LEN * 2];
1081 char tmp[MAX_STR_LEN];
[1]1082
[128]1083 /*@ end vars *************************************************** */
[1]1084
[128]1085 assert_string_is_neither_NULL_nor_zerolength(config_file);
1086 assert_string_is_neither_NULL_nor_zerolength(label);
1087 if (!does_file_exist(config_file)) {
1088 sprintf(tmp, "(read_cfg_var) Cannot find %s config file",
1089 config_file);
1090 log_to_screen(tmp);
1091 value[0] = '\0';
1092 return (1);
[1279]1093 } else if ((value != NULL) && (strstr(value, "/dev/") && strstr(value, "t0") && !strcmp(label, "media-dev"))) {
1094 log_msg(2, "FYI, I can't read new value for %s - already got %s", label, value);
[128]1095 return (0);
1096 } else {
[148]1097 sprintf(command, "grep '%s .*' %s| cut -d' ' -f2,3,4,5",
1098 label, config_file);
[128]1099 strcpy(value, call_program_and_get_last_line_of_output(command));
1100 if (strlen(value) == 0) {
1101 return (1);
1102 } else {
1103 return (0);
1104 }
[1]1105 }
1106}
1107
1108
1109
1110/**
1111 * Remount @c supermount if it was unmounted earlier.
1112 */
1113void remount_supermounts_if_necessary()
1114{
[128]1115 if (g_remount_cdrom_at_end) {
1116 run_program_and_log_output("mount " MNT_CDROM, FALSE);
1117 }
1118 if (g_remount_floppy_at_end) {
1119 run_program_and_log_output("mount " MNT_FLOPPY, FALSE);
1120 }
[1]1121}
1122
1123/**
1124 * Unmount @c supermount if it's mounted.
1125 */
1126void unmount_supermounts_if_necessary()
1127{
[128]1128 if (run_program_and_log_output
1129 ("mount | grep cdrom | grep super", FALSE) == 0) {
1130 g_remount_cdrom_at_end = TRUE;
1131 run_program_and_log_output("umount " MNT_CDROM, FALSE);
1132 }
1133 if (run_program_and_log_output
1134 ("mount | grep floppy | grep super", FALSE) == 0) {
1135 g_remount_floppy_at_end = TRUE;
1136 run_program_and_log_output("umount " MNT_FLOPPY, FALSE);
1137 }
[1]1138}
1139
1140/**
1141 * Whether we had to stop autofs (if so, restart it at end).
1142 */
[128]1143bool g_autofs_stopped = FALSE;
[1]1144
1145/**
1146 * Path to the autofs initscript ("" if none exists).
1147 */
1148char g_autofs_exe[MAX_STR_LEN];
1149
1150/**
1151 * Autofs initscript in Xandros Linux distribution.
1152 */
1153#define XANDROS_AUTOFS_FNAME "/etc/init.d/xandros-autofs"
1154
1155/**
1156 * Autofs initscript in most Linux distributions.
1157 */
1158#define STOCK_AUTOFS_FNAME "/etc/rc.d/init.d/autofs"
1159
1160/**
1161 * If autofs is mounted, stop it (restart at end).
1162 */
1163void stop_autofs_if_necessary()
1164{
[128]1165 char tmp[MAX_STR_LEN];
1166
1167 g_autofs_exe[0] = '\0';
1168 if (does_file_exist(XANDROS_AUTOFS_FNAME)) {
1169 strcpy(g_autofs_exe, XANDROS_AUTOFS_FNAME);
1170 } else if (does_file_exist(STOCK_AUTOFS_FNAME)) {
1171 strcpy(g_autofs_exe, STOCK_AUTOFS_FNAME);
1172 }
1173
1174 if (!g_autofs_exe[0]) {
1175 log_msg(3, "No autofs detected.");
1176 } else {
1177 log_msg(3, "%s --- autofs detected", g_autofs_exe);
[1]1178// FIXME -- only disable it if it's running --- sprintf(tmp, "%s status", autofs_exe);
[128]1179 sprintf(tmp, "%s stop", g_autofs_exe);
1180 if (run_program_and_log_output(tmp, 2)) {
1181 log_it("Failed to stop autofs - I assume it wasn't running");
1182 } else {
1183 g_autofs_stopped = TRUE;
1184 log_it("Stopped autofs OK");
1185 }
1186 }
[1]1187}
1188
1189/**
1190 * If autofs was stopped earlier, restart it.
1191 */
1192void restart_autofs_if_necessary()
1193{
[128]1194 char tmp[MAX_STR_LEN];
1195
1196 if (!g_autofs_stopped || !g_autofs_exe[0]) {
1197 log_msg(3, "No autofs detected.");
1198 return;
1199 }
1200 sprintf(tmp, "%s start", g_autofs_exe);
1201 if (run_program_and_log_output(tmp, 2)) {
1202 log_it("Failed to start autofs");
1203 } else {
1204 g_autofs_stopped = FALSE;
1205 log_it("Started autofs OK");
1206 }
[1]1207}
1208
1209
1210/**
1211 * If this is a distribution like Gentoo that doesn't keep /boot mounted, mount it.
1212 */
1213void mount_boot_if_necessary()
1214{
[128]1215 char tmp[MAX_STR_LEN];
1216 char command[MAX_STR_LEN];
[1]1217
[128]1218 log_msg(1, "Started sub");
1219 log_msg(4, "About to set g_boot_mountpt[0] to '\\0'");
1220 g_boot_mountpt[0] = '\0';
1221 log_msg(4, "Done. Great. Seeting command to something");
1222 strcpy(command,
[911]1223 "grep -v \":\" /etc/fstab | grep -vE '^#.*$' | grep -E \"[ ]/boot[ ]\" | tr -s ' ' '\t' | cut -f1 | head -n1");
[128]1224 log_msg(4, "Cool. Command = '%s'", command);
1225 strcpy(tmp, call_program_and_get_last_line_of_output(command));
1226 log_msg(4, "tmp = '%s'", tmp);
1227 if (tmp[0]) {
1228 log_it("/boot is at %s according to /etc/fstab", tmp);
[1791]1229 strcpy(command, "mount | grep -Ew '/boot'");
1230 strcpy(tmp, call_program_and_get_last_line_of_output(command));
[1818]1231 if (!strcmp(tmp,"")) {
[1791]1232 if ((strstr(tmp, "LABEL=") || strstr(tmp,"UUID="))) {
1233 if (!run_program_and_log_output("mount /boot", 5)) {
1234 strcpy(g_boot_mountpt, "/boot");
1235 log_msg(1, "Mounted /boot");
1236 } else {
1237 log_it("...ignored cos it's a label or uuid :-)");
1238 }
[128]1239 } else {
[1791]1240 sprintf(command, "mount | grep -E '^%s'", tmp);
1241 log_msg(3, "command = %s", command);
1242 if (run_program_and_log_output(command, 5)) {
1243 strcpy(g_boot_mountpt, tmp);
1244 sprintf(tmp,
1245 "%s (your /boot partition) is not mounted. I'll mount it before backing up",
1246 g_boot_mountpt);
1247 log_it(tmp);
1248 sprintf(tmp, "mount %s", g_boot_mountpt);
1249 if (run_program_and_log_output(tmp, 5)) {
1250 g_boot_mountpt[0] = '\0';
1251 log_msg(1, "Plan B");
1252 if (!run_program_and_log_output("mount /boot", 5)) {
1253 strcpy(g_boot_mountpt, "/boot");
1254 log_msg(1, "Plan B worked");
1255 } else {
1256 log_msg(1,
[128]1257 "Plan B failed. Unable to mount /boot for backup purposes. This probably means /boot is mounted already, or doesn't have its own partition.");
[1791]1258 }
[128]1259 }
1260 }
1261 }
1262 }
[1]1263 }
[128]1264 log_msg(1, "Ended sub");
[1]1265}
1266
1267
1268/**
1269 * If we mounted /boot earlier, unmount it.
1270 */
1271void unmount_boot_if_necessary()
1272{
[128]1273 char tmp[MAX_STR_LEN];
[1]1274
[128]1275 log_msg(3, "starting");
1276 if (g_boot_mountpt[0]) {
1277 sprintf(tmp, "umount %s", g_boot_mountpt);
1278 if (run_program_and_log_output(tmp, 5)) {
1279 log_it("WARNING - unable to unmount /boot");
1280 }
1281 }
1282 log_msg(3, "leaving");
[1]1283}
1284
1285
1286
1287/**
1288 * Write a line to a configuration file. Writes a line of the form,
1289 * @c label @c value.
1290 * @param config_file The file to write to. Usually @c mondo-restore.cfg.
1291 * @param label What to call this bit of data you're writing.
1292 * @param value The bit of data you're writing.
1293 * @return 0 for success, 1 for failure.
1294 */
[128]1295int write_cfg_var(char *config_file, char *label, char *value)
[1]1296{
[128]1297 /*@ buffers ***************************************************** */
1298 char command[MAX_STR_LEN * 2];
1299 char tempfile[MAX_STR_LEN];
1300 char tmp[MAX_STR_LEN];
[1]1301
1302
[128]1303 /*@ end vars *************************************************** */
1304 assert_string_is_neither_NULL_nor_zerolength(config_file);
1305 assert_string_is_neither_NULL_nor_zerolength(label);
1306 assert(value != NULL);
1307 if (!does_file_exist(config_file)) {
1308 sprintf(tmp, "(write_cfg_file) Cannot find %s config file",
1309 config_file);
1310 log_to_screen(tmp);
1311 return (1);
1312 }
[1644]1313 sprintf(tempfile, "%s/mojo-jojo.blah", bkpinfo->tmpdir);
[128]1314 if (does_file_exist(config_file)) {
[911]1315 sprintf(command, "grep -vE '^%s .*$' %s > %s",
[148]1316 label, config_file, tempfile);
[128]1317 paranoid_system(command);
1318 }
1319 sprintf(command, "echo \"%s %s\" >> %s", label, value, tempfile);
1320 paranoid_system(command);
1321 sprintf(command, "mv -f %s %s", tempfile, config_file);
1322 paranoid_system(command);
1323 unlink(tempfile);
1324 return (0);
[1]1325}
1326
[541]1327
[1]1328/**
[541]1329 * The standard log_debug_msg() (log_msg() also due to a macro). Writes some describing
1330 * information to the logfile.
1331 */
1332void standard_log_debug_msg(int debug_level, const char *szFile,
1333 const char *szFunction, int nLine,
1334 const char *fmt, ...)
1335{
1336 va_list args;
1337 int i;
1338 static int depth = 0;
1339 char *tmp;
1340 FILE *fout;
1341
1342 if (depth > 5) {
1343 depth--;
1344 return;
1345 }
1346 depth++;
1347
1348 malloc_string(tmp);
1349
1350 if (debug_level <= g_loglevel) {
1351 va_start(args, fmt);
1352 if (!(fout = fopen(MONDO_LOGFILE, "a"))) {
1353 return;
[1946]1354 } // fatal_error("Failed to openout to logfile - sheesh..."); }
[541]1355
1356 // add tabs to distinguish log levels
1357 if (debug_level > 0) {
1358 for (i = 1; i < debug_level; i++)
1359 fprintf(fout, "\t");
1360 if (getpid() == g_main_pid)
1361 fprintf(fout, "[Main] %s->%s#%d: ", szFile, szFunction,
1362 nLine);
1363 else if (getpid() == g_buffer_pid && g_buffer_pid > 0)
1364 fprintf(fout, "[Buff] %s->%s#%d: ", szFile, szFunction,
1365 nLine);
1366 else
1367 fprintf(fout, "[TH=%d] %s->%s#%d: ", getpid(), szFile,
1368 szFunction, nLine);
1369 }
1370 vfprintf(fout, fmt, args);
1371
1372 // do not slow down the progran if standard debug level
1373 // must be enabled: if no flush, the log won't be up-to-date if there
1374 // is a segfault
1375 //if (g_dwDebugLevel != 1)
1376
1377 va_end(args);
1378 fprintf(fout, "\n");
1379 paranoid_fclose(fout);
1380 }
1381 depth--;
1382 paranoid_free(tmp);
1383}
1384
1385/**
1386 * Function pointer to the @c log_debug_msg function to use. Points to standard_log_debug_msg() by default.
1387 */
1388void (*log_debug_msg) (int, const char *, const char *, int, const char *,
1389 ...) = standard_log_debug_msg;
1390
1391
1392/**
[1]1393 * If @p y, malloc @p x, else free @p x.
1394 * @bug This function seems orphaned. Please remove.
1395 */
1396#define do_alloc_or_free_depending(x,y) { if(y) {x=malloc(MAX_STR_LEN);} else {paranoid_free(x);} }
1397
1398/**
1399 * Allocate or free important globals, depending on @p mal.
1400 * @param mal If TRUE, malloc; if FALSE, free.
1401 */
1402void do_libmondo_global_strings_thing(int mal)
1403{
[128]1404 if (mal) {
1405 malloc_string(g_boot_mountpt);
1406 malloc_string(g_mondo_home);
[2030]1407 /*
[128]1408 malloc_string(g_tmpfs_mountpt);
[2030]1409 */
[128]1410 malloc_string(g_serial_string);
1411 malloc_string(g_magicdev_command);
1412 } else {
1413 paranoid_free(g_boot_mountpt);
1414 paranoid_free(g_mondo_home);
[2030]1415 /*
[128]1416 paranoid_free(g_tmpfs_mountpt);
[2030]1417 */
[128]1418 paranoid_free(g_serial_string);
1419 paranoid_free(g_magicdev_command);
1420 }
[541]1421
1422 /*
1423 char**list_of_arrays[] = {
1424 &g_boot_mountpt,
1425 &g_mondo_home,
1426 &g_tmpfs_mountpt,
1427 &g_serial_string,
1428 &g_magicdev_command,
1429 NULL};
1430
1431 char**ppcurr;
1432 int i;
1433
1434 for(i=0;list_of_arrays[i];i++)
1435 {
1436 log_msg(5, "Allocating %d", i);
1437 ppcurr = list_of_arrays[i];
1438 if (mal)
1439 { *ppcurr = malloc(MAX_STR_LEN); }
1440 else
1441 {
1442 if (*ppcurr)
1443 {
1444 free(*ppcurr);
1445 }
1446 }
1447 }
1448 log_msg(5, "Returning");
1449 */
[1]1450}
1451
1452/**
1453 * Allocate important globals.
1454 * @see do_libmondo_global_strings_thing
1455 */
1456void malloc_libmondo_global_strings(void)
1457{
[128]1458 do_libmondo_global_strings_thing(1);
[1]1459}
1460
1461/**
1462 * Free important globals.
1463 * @see do_libmondo_global_strings_thing
1464 */
1465void free_libmondo_global_strings(void)
1466{
[128]1467 do_libmondo_global_strings_thing(0);
[1]1468}
1469
1470
1471
1472/**
1473 * Stop @c magicdev if it's running.
1474 * The command used to start it is saved in @p g_magicdev_command.
1475 */
1476void stop_magicdev_if_necessary()
1477{
[128]1478 strcpy(g_magicdev_command,
1479 call_program_and_get_last_line_of_output
1480 ("ps ax | grep -w magicdev | grep -v grep | tr -s '\t' ' '| cut -d' ' -f6-99"));
1481 if (g_magicdev_command[0]) {
1482 log_msg(1, "g_magicdev_command = '%s'", g_magicdev_command);
1483 paranoid_system("killall magicdev");
1484 }
[1]1485}
1486
1487
1488/**
1489 * Restart magicdev if it was stopped.
1490 */
1491void restart_magicdev_if_necessary()
1492{
[128]1493 char *tmp;
1494
1495 malloc_string(tmp);
1496 if (g_magicdev_command && g_magicdev_command[0]) {
1497 sprintf(tmp, "%s &", g_magicdev_command);
1498 paranoid_system(tmp);
1499 }
1500 paranoid_free(tmp);
[1]1501}
1502
1503/* @} - end of utilityGroup */
Note: See TracBrowser for help on using the repository browser.