source: MondoRescue/branches/stable/mondo/src/common/libmondo-tools.c@ 1165

Last change on this file since 1165 was 1165, checked in by Bruno Cornec, 17 years ago

Complementary fx from M. Loiseleur for the change of format of the conf files.

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