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

Last change on this file since 1165 was 1165, checked in by bruno, 13 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.