source: MondoRescue/branches/2.2.10/mondo/src/common/libmondo-cli.c@ 2508

Last change on this file since 2508 was 2508, checked in by Bruno Cornec, 14 years ago

r3287@localhost (orig r2285): bruno | 2009-07-20 11:36:47 +0200

r3285@localhost: bruno | 2009-07-20 11:17:35 +0200
Apply fix in 2.2.10 around multi USB device handling to 2.2.9 as well


r3291@localhost (orig r2288): bruno | 2009-07-21 16:48:31 +0200
Copy 2.2.10 test script in to 2.2.9 for memory problm analysis


r3293@localhost (orig r2290): bruno | 2009-07-22 14:03:44 +0200

  • Fix a printing error in mindi for the tar command
  • Fix all mr_asprintf which had no second param as a string


r3295@localhost (orig r2292): bruno | 2009-07-22 16:55:00 +0200

  • Fix #160 and #346 by rewriting the message.txt file with more valid information gathered in mindi


r3300@localhost (orig r2294): bruno | 2009-07-23 01:58:08 +0200

Man pages patch from Joe Ross (joe.ross_at_gmail.com)


r3303@localhost (orig r2297): bruno | 2009-07-23 17:43:49 +0200
Fix a remaining display error for 2.2.9. That version has been tested OK in a lab.


r3304@localhost (orig r2298): bruno | 2009-07-23 18:18:27 +0200

  • Remove memory leak for the last modification


r3308@localhost (orig r2302): bruno | 2009-07-24 21:18:50 +0200
Improve logging of mountlist.txt


r3310@localhost (orig r2304): bruno | 2009-07-27 19:45:10 +0200

  • popup_and_get_string needs an allocated buffer for the moment so fixing the calls with dyn. ones
  • Fix a bug in mem.c for mr_strcat, which wasn't modifying the right pointer level


r3311@localhost (orig r2305): bruno | 2009-07-27 19:49:35 +0200
Avoid a memory leak in the previous patch


r3314@localhost (orig r2308): bruno | 2009-07-27 20:59:06 +0200
Fix a bug in mr_strcat backported from 2.2.10. Should solve our seg faults.


r3315@localhost (orig r2309): bruno | 2009-07-28 02:14:23 +0200
Cosmetic changes to allow for quality to not giv false positive


r3343@localhost (orig r2311): bruno | 2009-08-18 02:13:43 +0200
Fix for initramfs detection with 2.6.30 (Hugo Vanwoerkom hvw59601_at_care2.com)


r3367@localhost (orig r2333): bruno | 2009-08-18 16:26:26 +0200
Adds a precision for -U option in man page on raw device usage and not partition name


r3373@localhost (orig r2336): bruno | 2009-08-20 17:37:41 +0200

  • Precise the combined usage of -E and -I in mondoarchive (Case 4601017223)


r3379@localhost (orig r2342): bruno | 2009-08-21 16:27:10 +0200


r3383@localhost (orig r2344): bruno | 2009-08-24 13:37:09 +0200

r3382@localhost: bruno | 2009-08-24 13:30:25 +0200
In NFS mode also propose access to expert, interactive, ... entry at boot prompt


r3388@localhost (orig r2346): bruno | 2009-08-27 11:41:16 +0200
Adds fdisk -l result in Log File at restore time


r3389@localhost (orig r2347): bruno | 2009-08-27 13:51:00 +0200

  • Solve tmp dir creation which sometimes was trying to create /%xx dirs. Should fix #293 for good


r3390@localhost (orig r2348): bruno | 2009-08-27 13:54:25 +0200
Improve logging (minor)


r3394@localhost (orig r2350): bruno | 2009-08-28 02:24:19 +0200
Change inerface of evaluate_mountlist and spread_flaws_across_three_lines in order to solve bugs linked to strings management in these functions. May fix a restoration crash seen by some customers


r3397@localhost (orig r2353): bruno | 2009-08-28 19:03:45 +0200

  • Addition of a nomd option to avoid starting mdadm
  • mpath is now already started if there was a mpath entry in mountlist


r3399@localhost (orig r2355): bruno | 2009-08-29 00:56:50 +0200
Remove function spread_flaws_across_three_lines and expand it at the single place where it was useful, and fix memory allocation issues in it.


r3402@localhost (orig r2358): bruno | 2009-09-01 19:02:35 +0200
P2V doc updated (Lester Wade lester.wade_at_hp.com)


r3404@localhost (orig r2360): bruno | 2009-09-01 19:26:53 +0200
Website update to refer to new P2V document


r3405@localhost (orig r2361): bruno | 2009-09-03 13:54:25 +0200

  • Fix a case where the NFS dir in restore mode was mounted rw (linked to bug #291 could create a huge problem)


r3407@localhost (orig r2363): bruno | 2009-09-03 14:46:46 +0200
More verbose at installation of additional tools


r3409@localhost (orig r2365): bruno | 2009-09-03 18:08:32 +0200

  • New update from Lester Wade (lester.wade_at_hp.com) for P2V doc


r3410@localhost (orig r2366): bruno | 2009-09-05 01:28:18 +0200
place the code of mondo_makefilelist before its call



r3411@localhost (orig r2367): bruno | 2009-09-06 01:51:26 +0200

  • Advertising for project-builder on the website added


r3412@localhost (orig r2368): bruno | 2009-09-07 15:36:23 +0200
Fix compilation issue


r3413@localhost (orig r2369): bruno | 2009-09-07 18:03:40 +0200
Another compilation issue fixed.


r3415@localhost (orig r2371): bruno | 2009-09-08 13:40:25 +0200

  • Fix a problem a error detection in evaluate_mountlist which casued nuke mode to abort. Error string should also be better now.


r3417@localhost (orig r2373): bruno | 2009-09-08 13:55:31 +0200
Avoid asking the Prefix name in NFS mode twice


r3418@localhost (orig r2374): bruno | 2009-09-08 20:04:07 +0200

  • Try to fix garbled screen progression in text mode based on 2.2.10 modifications which are working


r3424@localhost (orig r2380): bruno | 2009-09-09 20:30:47 +0200

  • Change NFS support into a NetFS support to allow for multiple protocol in addition to NFS (NEEDS TESTING)
  • Better logging to detect a potential nuke issue


r3425@localhost (orig r2381): bruno | 2009-09-10 02:05:55 +0200
Fix a missing param for sshfs call


r3428@localhost (orig r2384): bruno | 2009-09-10 13:02:56 +0200

  • Remove separate function look_for_duplicate_mountpoints used only once and whose interface created problems with caller


r3430@localhost (orig r2386): bruno | 2009-09-10 16:06:52 +0200
Be compatible on backup type by making old nfs recognized as netfs and proto forced


r3431@localhost (orig r2387): bruno | 2009-09-10 18:40:47 +0200
Fix a problem in netfs analysis in mondoarchive


r3432@localhost (orig r2388): bruno | 2009-09-10 20:25:13 +0200
Fix mondoarchive CLI analysis for NETFS type of requests


r3434@localhost (orig r2390): bruno | 2009-09-11 03:05:20 +0200

  • Adds ext3 initrd support for 2.6.30


r3437@localhost (orig r2393): bruno | 2009-09-11 11:56:52 +0200

  • Tries to add support for bzip2 and lzma initramfs (preliminary, not tested) for 2.6.30


r3438@localhost (orig r2394): bruno | 2009-09-12 02:53:02 +0200
Fix interface of evaluate_mountlist (remove 2nd param useless) and fix nuke mode which wasn't working.


r3441@localhost (orig r2397): bruno | 2009-09-14 18:54:34 +0200
Fix a format issue in text mode on percentage


r3452@localhost (orig r2398): bruno | 2009-09-15 16:00:13 +0200

  • Fix a bug where flaws_str could be NULL and wasn't tested correctly.


r3453@localhost (orig r2399): bruno | 2009-09-15 19:28:39 +0200

  • Use protocol name when displaying restore progress instead of netfs
  • Ask for network protocol name at restore time


r3455@localhost (orig r2401): bruno | 2009-09-15 19:34:19 +0200
Wrong structure member name was used


r3456@localhost (orig r2402): bruno | 2009-09-16 13:04:17 +0200
Use dir for shell related commands and dir1 for C related actions in open_and_list_dir to avoid missing some files with { in names e.g.


r3457@localhost (orig r2403): bruno | 2009-09-16 16:32:03 +0200

  • At restore time read the netfs protocol in the conf file


r3462@localhost (orig r2408): bruno | 2009-09-18 15:17:08 +0200
Remove useless script


r3463@localhost (orig r2409): bruno | 2009-09-18 15:25:35 +0200

  • Split deplist.txt into multiple conf files under deplist.d in the conf dir. This will allow to have a minimal.conf file for initrd content to analyze to improve support of new embedded feature in the future (sshfs, live install). The other conf files contain the additional commands to put in the all.tar.gz. For the moment, mindi is still working the same. THis infra will allow that support in a near future. deplist.txt is now reserved for the admin additional commands.


r3465@localhost (orig r2410): bruno | 2009-09-18 19:10:54 +0200

  • Better list of mandatory tools
  • Adds fuse and sshfs support in initrd


r3466@localhost (orig r2411): bruno | 2009-09-18 20:32:47 +0200
sshfs also needs ssh at restore time in initrd


r3478@localhost (orig r2418): bruno | 2009-09-23 23:22:39 +0200
Modify getfattr call to have all extended attributes, including non user ones. (patch from Kevin Ritzenthaler Kevin.Ritzenthaler_at_hp.com) and fix #357


r3479@localhost (orig r2419): bruno | 2009-09-23 23:50:34 +0200
star only supports ACL when used with exustar mode. Fix #356.


r3482@localhost (orig r2422): bruno | 2009-09-24 16:53:24 +0200

  • Adds support for bnx2x (BL 460 G6) and auth_rpcgss (Debian 2.6.31)


r3485@localhost (orig r2423): bruno | 2009-09-25 16:38:40 +0200
Fix an issue in is_this_device_mounted (string freed before last usage)


r3486@localhost (orig r2424): bruno | 2009-09-25 18:44:01 +0200

  • analyze-my-lvm now removes excluded devices from list coming from mondoarchive
  • new mr_make_devlist_from_pathlist which handle the new bkpinfo->exclude_devs field containing the excluded devices and remove corresponding code from libmondo-cli.c
  • Move DSF code into libmondo-devices.c for coherency, and only the previous function is made externally available
  • Remove dev_to_exclude in libmondo-archive.c which wasn't working correctly and replace it with bkpinfo->exclude_devs


r3487@localhost (orig r2425): bruno | 2009-09-25 18:58:23 +0200

  • Improving ssh support at restore time by providing a shadow file


r3489@localhost (orig r2426): bruno | 2009-09-25 19:42:09 +0200

  • Attempt to stay backward compatible without protocol for -n option


r3490@localhost (orig r2427): bruno | 2009-09-28 02:08:06 +0200
Avoids null param for excludes_devs for mindi call


r3492@localhost (orig r2429): bruno | 2009-09-28 11:46:16 +0200

  • Simplify GetInitrdFilesystemToUse which doesn't need to detect everything, but just know if it's initramfs (new mode) or a compressed FS ext2/3 (older mode) as initrd is anyway re-made by mindi. Should fix #353


r3494@localhost (orig r2431): bruno | 2009-09-28 13:16:18 +0200

  • Use only the AWK veriable everywhere and not the awk command


r3495@localhost (orig r2432): bruno | 2009-09-28 14:16:31 +0200
Warning emited in case of duplicate mountpoints or devices in fstab found


r3496@localhost (orig r2433): bruno | 2009-09-28 15:55:17 +0200
ssh in the restore env needs some dlopened libs (libnss_compat|files)


r3497@localhost (orig r2434): bruno | 2009-09-28 16:33:14 +0200
Compiler warning fixed


r3498@localhost (orig r2435): bruno | 2009-09-28 17:55:26 +0200
Improve user management for NetFS cases


r3499@localhost (orig r2436): bruno | 2009-09-29 01:48:32 +0200

  • Improve deplist.d/* files
  • adds libnss for ssh support in boot disk
  • Solve a memory management issue in DSF module (strtok => mr_strtok)
  • DSF now also supports partitions in addition to full disks
  • Adds debug in open_and_list_dir


r3500@localhost (orig r2437): bruno | 2009-09-29 10:41:56 +0200

  • Fix udev support in init for Mandriva 2009.1 (udevadm settle is blocking)


r3501@localhost (orig r2438): bruno | 2009-09-29 14:41:36 +0200

  • Improvements on sshfs/ssh management in restore mode
  • Include now all minimal requirements for sshfs


r3502@localhost (orig r2439): bruno | 2009-09-29 18:46:08 +0200

  • Avoids error message if some ssh conf files do not exist


r3503@localhost (orig r2440): bruno | 2009-09-29 18:57:13 +0200

  • Avoids comment analysis in the new code handling deplist.d


r3504@localhost (orig r2441): bruno | 2009-09-29 19:34:34 +0200

  • fuse device is needed at restore time for sshfs


r3505@localhost (orig r2442): bruno | 2009-09-29 20:02:36 +0200

  • Improves udev timeout handling


r3506@localhost (orig r2443): bruno | 2009-09-29 20:43:38 +0200

  • priority given to env var for tmpdir
  • fuse FS excluded from tmpdir computation


r3518@localhost (orig r2447): bruno | 2009-10-04 01:58:08 +0200

  • Iprove USB log in case of error by adding the conf file


r3519@localhost (orig r2448): bruno | 2009-10-05 11:06:13 +0200


r3520@localhost (orig r2449): bruno | 2009-10-06 01:10:35 +0200

  • Adds support for grub2 conf file grub.cfg in addition to menu.lst


r3521@localhost (orig r2450): bruno | 2009-10-06 01:24:02 +0200

  • Fix a mr_asprintf usage without & causing a seg fault.


r3523@localhost (orig r2452): bruno | 2009-10-06 12:47:56 +0200
CIFS mounts shouldn't be part of the mountlist analysis (should help solving #288)


r3524@localhost (orig r2453): bruno | 2009-10-07 10:17:03 +0200

  • Fix a bug in handling of -E option with real devices (bad report in function mr_make_devlist_from_pathlist of the test between -E and -I)


r3525@localhost (orig r2454): bruno | 2009-10-07 10:19:02 +0200

  • Fix an error in the test for grub conf files (or used instead of and)


r3526@localhost (orig r2455): bruno | 2009-10-07 16:14:59 +0200
afio is under /bin on Debian


r3527@localhost (orig r2456): bruno | 2009-10-07 17:31:26 +0200

  • Adds support for libcrc32c (needed by bnx2x)


r3532@localhost (orig r2457): bruno | 2009-10-09 13:33:44 +0200

  • Apply path from Matthew Cline (matt_at_nightrealms.com) in order to fix #359


r3533@localhost (orig r2458): bruno | 2009-10-09 13:41:02 +0200
Adds a conf file example for mindi and fix #360


r3535@localhost (orig r2459): bruno | 2009-10-09 15:13:01 +0200
MOde of conf file


r3546@localhost (orig r2461): bruno | 2009-10-14 01:12:24 +0200

  • umount freshly created VFAT partition on USB key as Ubunu has an automounter mounting it as soon as created (Steffen Neumann sneumann_at_ipb-halle.de)


r3566@localhost (orig r2463): bruno | 2009-10-26 01:34:16 +0100

  • Reset an error counter before blanking a DVD to avoid always returning an error (Vincent Raman vincent.raman_at_macqel.eu)


r3567@localhost (orig r2464): bruno | 2009-10-26 13:57:14 +0100
bzip2 is under /bin on Debian


r3568@localhost (orig r2465): bruno | 2009-10-28 01:46:30 +0100
some distro hold lvm commands under /usr/sbin


r3595@localhost (orig r2469): bruno | 2009-11-10 12:22:10 +0100
/dev/shm is now part of the default exclude list


r3596@localhost (orig r2470): bruno | 2009-11-10 12:32:40 +0100
Remove useless pb_log and MONDO_TRACEFILE


r3597@localhost (orig r2471): bruno | 2009-11-10 12:57:58 +0100
Improve analysis of kernel modules by printing whether it's a live or extra module which has not been found (Matthew Cline) as reported in #362


r3598@localhost (orig r2472): bruno | 2009-11-10 13:21:46 +0100

  • Default to DVD size when in iso or netfs mode


r3599@localhost (orig r2473): bruno | 2009-11-10 14:13:10 +0100

  • Fix #363 where exclude_paths was extended up to memory limit dumping core


r3600@localhost (orig r2474): bruno | 2009-11-10 14:31:14 +0100

  • Update deplist for Debian support


r3602@localhost (orig r2476): bruno | 2009-11-11 02:44:42 +0100

  • small improvement for loging in USB case


r3603@localhost (orig r2477): bruno | 2009-11-11 13:29:27 +0100

  • Adds a nolvm boot option at restore time


r3604@localhost (orig r2478): bruno | 2009-11-11 19:54:51 +0100

  • Fix #367 - the for loop doesn't make any test now, as it was computed before entering the loop, leading to an error, and was also made inside the loop anyway.


r3605@localhost (orig r2479): bruno | 2009-11-12 00:32:45 +0100

  • Add support for diskdumplib driver useful for RHEL 3 and IBM xseries 336


r3606@localhost (orig r2480): bruno | 2009-11-12 01:09:40 +0100

  • If using nolvm, mondorestore should also not nalyze and handle i-want-my-lvm


r3608@localhost (orig r2482): bruno | 2009-11-14 12:54:11 +0100
Fix bunzip2 on debian as well


r3610@localhost (orig r2484): bruno | 2009-11-15 00:44:19 +0100

  • Adds support for variable serial port console, with defalut to /dev/ttyS0, and a boot param to change it with serial=/dev/ttySx


r3615@localhost (orig r2485): bruno | 2009-11-15 01:34:33 +0100

r3614@localhost: bruno | 2009-11-15 01:34:12 +0100
Adds a space in exclude paths


r3623@localhost (orig r2487): bruno | 2009-11-18 20:41:40 +0100

r3620@localhost: bruno | 2009-11-18 10:31:36 +0100

  • Only link /dev/tty to serial port when there is indeed a serial port. If not breaks mondorestore on normal console


r3631@localhost (orig r2490): bruno | 2009-11-24 01:48:29 +0100
Put news below in the main page to make it more readable


r3648@localhost (orig r2492): bruno | 2009-11-25 23:50:13 +0100

r3647@localhost: bruno | 2009-11-25 23:49:11 +0100

  • Add warning for -f and SW Raid as in 2.2.10


r3650@localhost (orig r2493): bruno | 2009-11-26 00:19:52 +0100

r3649@localhost: bruno | 2009-11-26 00:18:27 +0100

  • Addition of the german translation made by Magnus Rasche (Magnus.rasche_at_gmx.de) and Website inclusion


r3652@localhost (orig r2495): bruno | 2009-11-27 15:55:55 +0100
cosmetic display fix
r3659@localhost (orig r2498): bruno | 2009-12-05 17:53:03 +0100
nfsopt restore boot time option added to support custom mount options for network restore


r3684@localhost (orig r2501): bruno | 2009-12-17 00:35:08 +0100
Fix #375 mondo will segfault if the partition in sensibly_set_tmpdir_and_scratchdir() is read-only (cylau)


r3685@localhost (orig r2502): bruno | 2009-12-17 01:02:47 +0100

  • Fix an issue in the function listing kernel modules when not found


r3686@localhost (orig r2503): bruno | 2009-12-17 01:15:01 +0100
Adds scsi_dump_register to mindi SCSI_MODS for RHEL3 + IBM servers


r3701@localhost (orig r2504): bruno | 2009-12-23 02:24:33 +0100

  • Addition of the Lab for Mondorescue


r3702@localhost (orig r2505): bruno | 2009-12-23 02:41:17 +0100
Web site update for Lab MondoRescue delivery


r3706@localhost (orig r2506): bruno | 2010-01-04 11:31:53 +0100

  • Fix a bug when isodir is / only when splitting it in iso_path and iso_mnt


r3707@localhost (orig r2507): bruno | 2010-01-04 13:22:49 +0100

  • Fix #377: Segfault in pause_and_ask_for_cdr() (ggeens)


  • Property svn:keywords set to Id
File size: 30.7 KB
Line 
1/***************************************************************************
2$Id: libmondo-cli.c 2508 2010-01-04 18:21:55Z bruno $
3*******************************************************************/
4
5/**
6 * @file
7 * Functions for handling command-line arguments passed to mondoarchive.
8 */
9
10/** @def BOOT_LOADER_CHARS The characters allowed for boot loader on this platform. */
11
12#include <pthread.h>
13#include "my-stuff.h"
14#include "mr_mem.h"
15#include "mr_str.h"
16#include "mondostructures.h"
17#include "libmondo-cli-EXT.h"
18#include "libmondo.h"
19
20extern int g_loglevel;
21extern bool g_text_mode;
22extern char g_startdir[MAX_STR_LEN]; ///< ????? @bug ?????
23extern char *MONDO_OPTIONS;
24
25/*@ file pointer **************************************************/
26extern FILE *g_tape_stream;
27
28/*@ long long *****************************************************/
29extern long long g_tape_posK;
30
31/*@ long **********************************************************/
32extern long g_noof_sets;
33
34/*@ bool******** **************************************************/
35bool g_debugging = FALSE; ///< ????? @bug ????? @ingroup globalGroup
36bool g_running_live = FALSE; ///< ????? @bug ????? @ingroup globalGroup
37extern bool g_cd_recovery;
38
39extern void setup_tmpdir(char *path);
40void mr_make_devlist_from_pathlist(char *pathlist, char mode);
41extern double g_kernel_version;
42extern int g_current_media_number;
43extern pid_t g_main_pid;
44extern char *resolve_softlinks_to_get_to_actual_device_file(char *);
45
46/* Do we use extended attributes and acl ?
47 * By default no, use --acl & --attr options to force their usage */
48extern char *g_getfacl;
49extern char *g_getfattr;
50
51/* Reference to global bkpinfo */
52extern struct s_bkpinfo *bkpinfo;
53
54extern void free_MR_global_filenames(void);
55
56/**
57 * @addtogroup cliGroup
58 * @{
59 */
60/**
61 * Populate @p bkpinfo from the command-line parameters stored in @p argc and @p argv.
62 * @param argc The argument count, including the program name; @p argc passed to main().
63 * @param argv The argument vector; @p argv passed to main().
64 * @param bkpinfo The backup information structure to populate.
65 * @return The number of problems with the command line (0 for success).
66 */
67int
68handle_incoming_parameters(int argc, char *argv[])
69{
70 /*@ int *** */
71 int res = 0;
72 int retval = 0;
73 int i = 0, j;
74
75 /*@ buffers *************** */
76 char *tmp = NULL;
77 char flag_val[128][MAX_STR_LEN];
78 bool flag_set[128];
79
80 for (i = 0; i < 128; i++) {
81 flag_val[i][0] = '\0';
82 flag_set[i] = FALSE;
83 }
84 for (j = 1; j <= MAX_NOOF_MEDIA; j++) {
85 bkpinfo->media_size[j] = 650;
86 } /* default */
87 res = retrieve_switches_from_command_line(argc, argv, flag_val, flag_set);
88 retval += res;
89 if (!retval) {
90 res = process_switches(flag_val, flag_set);
91 retval += res;
92 }
93 log_msg(3, "Switches:-");
94 for (i = 0; i < 128; i++) {
95 if (flag_set[i]) {
96 log_msg(3, "-%c %s", i, flag_val[i]);
97 }
98 }
99 mr_asprintf(tmp, "mkdir -p %s/tmpfs", bkpinfo->tmpdir);
100 paranoid_system(tmp);
101 mr_free(tmp);
102
103 mr_asprintf(tmp, "mkdir -p %s", bkpinfo->scratchdir);
104 paranoid_system(tmp);
105 mr_free(tmp);
106 return (retval);
107}
108
109
110
111
112/**
113 * Store the sizespec(s) stored in @p value into @p bkpinfo.
114 * @param bkpinfo The backup information structure; the @c bkpinfo->media_size field will be populated.
115 * @param value The sizespec (e.g. "2g", "40m").
116 * @return 0, always.
117 * @bug Return code not needed.
118 */
119int process_the_s_switch(char *value)
120{
121 int j;
122 char tmp[MAX_STR_LEN], *p;
123
124 assert(bkpinfo != NULL);
125 assert(value != NULL);
126
127 bkpinfo->media_size[0] = -1; /* dummy value */
128 for (j = 1, p = value; j < MAX_NOOF_MEDIA && strchr(p, ',');
129 j++, p = strchr(p, ',') + 1) {
130 strncpy(tmp, p, MAX_STR_LEN);
131 *(strchr(tmp, ',')) = '\0';
132 bkpinfo->media_size[j] = friendly_sizestr_to_sizelong(tmp);
133 log_msg(3, "media_size[%d] = %ld", j, bkpinfo->media_size[j]);
134 }
135 for (; j <= MAX_NOOF_MEDIA; j++) {
136 bkpinfo->media_size[j] = friendly_sizestr_to_sizelong(p);
137 }
138 for (j = 1; j <= MAX_NOOF_MEDIA; j++) {
139 if (bkpinfo->media_size[j] <= 0) {
140 log_msg(1, "You gave media #%d an invalid size\n", j);
141 return (-1);
142 }
143 }
144 return (0);
145}
146
147/**
148 * Process mondoarchive's command-line switches.
149 * @param bkpinfo The backup information structure to populate.
150 * @param flag_val An array of the argument passed to each switch (the letter is the index).
151 * If a switch is not set or has no argument, the field in @p flag_val doesn't matter.
152 * @param flag_set An array of <tt>bool</tt>s indexed by switch letter: TRUE if it's set,
153 * FALSE if it's not.
154 * @return The number of problems with the switches, or 0 for success.
155 * @bug Maybe include a list of all switches (inc. intentionally undocumented ones not in the manual!) here?
156 */
157int
158process_switches(char flag_val[128][MAX_STR_LEN], bool flag_set[128])
159{
160
161 /*@ ints *** */
162 int i = 0;
163 int retval = 0;
164 int percent = 0;
165 int lastpos = 0;
166
167 /*@ buffers ** */
168 char *tmp1 = NULL;
169 char *tmp2 = NULL;
170 char *psz = NULL;
171 char *p = NULL;
172 char *q = NULL;
173
174 long itbs = 0L;
175
176 struct stat buf;
177
178 assert(bkpinfo != NULL);
179 assert(flag_val != NULL);
180 assert(flag_set != NULL);
181
182 bkpinfo->internal_tape_block_size = DEFAULT_INTERNAL_TAPE_BLOCK_SIZE;
183
184 /* compulsory */
185 i = flag_set['c'] + flag_set['i'] + flag_set['n'] +
186 flag_set['t'] + flag_set['u'] + flag_set['r'] +
187 flag_set['w'] + flag_set['C'] + flag_set['U'];
188 if ((i == 0) && (! bkpinfo->restore_data)) {
189 retval++;
190 log_to_screen("You must specify the media type\n");
191 }
192 if (i > 1) {
193 retval++;
194 log_to_screen("Please specify only one media type\n");
195 }
196
197 if (flag_set['K']) {
198 g_loglevel = atoi(flag_val['K']);
199 log_msg(1,"Loglevel forced to %d",g_loglevel);
200 if (g_loglevel < 3) {
201 g_loglevel = 3;
202 }
203 }
204
205 if ((flag_set['L'] && flag_set['0']) && (! bkpinfo->restore_data)) {
206 retval++;
207 log_to_screen("You cannot have 'no compression' _and_ LZOP.\n");
208 }
209 if (! bkpinfo->restore_data) {
210 bkpinfo->backup_data = flag_set['O'];
211 }
212 bkpinfo->verify_data = flag_set['V'];
213
214 if (flag_set['I'] && !bkpinfo->backup_data) {
215 log_to_screen("-I switch is ignored if just verifying");
216 }
217 if (flag_set['E'] && !bkpinfo->backup_data) {
218 log_to_screen("-E switch is ignored if just verifying");
219 }
220
221 tmp1 = find_home_of_exe("afio");
222 if (!tmp1) {
223 mr_free(tmp1);
224 tmp1 = find_home_of_exe("star");
225 if (tmp1) {
226 mr_free(tmp1);
227 flag_set['R'] = TRUE;
228 log_msg(1, "Using star instead of afio");
229 } else {
230 mr_free(tmp1);
231 fatal_error("Neither afio nor star is installed. Please install at least one.");
232 }
233 }
234 mr_free(tmp1);
235
236 if (flag_set['R']) {
237 bkpinfo->use_star = TRUE;
238 if (flag_set['L']) {
239 fatal_error("You may not use star and lzop at the same time.");
240 }
241 tmp1 = find_home_of_exe("star");
242 if (!tmp1) {
243 mr_free(tmp1);
244 fatal_error("Please install 'star' RPM or tarball if you are going to use -R. Thanks.");
245 }
246 mr_free(tmp1);
247 }
248
249 if ((flag_set['W']) && (! bkpinfo->restore_data)) {
250 bkpinfo->nonbootable_backup = TRUE;
251 log_to_screen("Warning - you have opted for non-bootable backup");
252 if (flag_set['f'] || flag_set['l']) {
253 log_to_screen
254 ("You don't need to specify bootloader or bootdevice");
255 }
256 }
257
258 if (flag_set['I']) {
259 if (bkpinfo->include_paths && bkpinfo->include_paths[0] == '-') {
260 retval++;
261 log_to_screen("Please supply a sensible value with '-I'\n");
262 }
263
264 mr_asprintf(tmp1, "%s", flag_val['I']);
265 p = tmp1;
266 q = tmp1;
267
268 /* Cut the flag_val['I'] in parts containing all paths to test them */
269 while (p != NULL) {
270 q = strchr(p, ' ');
271 if (q != NULL) {
272 *q = '\0';
273 if ((stat(p, &buf) != 0) && (! bkpinfo->restore_data)) {
274 log_msg(1, "ERROR ! %s doesn't exist", p);
275 fatal_error("ERROR ! You specified a directory to include which doesn't exist");
276 }
277 p = q+1 ;
278 } else {
279 if ((stat(p, &buf) != 0) && (! bkpinfo->restore_data)) {
280 log_msg(1, "ERROR ! %s doesn't exist", p);
281 fatal_error("ERROR ! You specified a directory to include which doesn't exist");
282 }
283 p = NULL;
284 }
285 }
286 mr_free(tmp1);
287 mr_make_devlist_from_pathlist(flag_val['I'], 'I');
288 log_msg(4, "Finished with the -I option");
289 }
290
291 if (g_kernel_version >= 2.6 && !flag_set['d'] && (flag_set['c'] || flag_set['w']) && (! bkpinfo->restore_data)) {
292 fatal_error("If you are using the 2.6.x kernel, please specify the CD-R(W) device.");
293 }
294
295
296 if (flag_set['J']) {
297 if (flag_set['I']) {
298 retval++;
299 log_to_screen("Please do not use -J in combination with -I. If you want to make a list of files to backup, that's fine, use -J <filename> but please don't muddy the waters by combining -J with -I. Thanks. :-)");
300 }
301 bkpinfo->make_filelist = FALSE;
302 mr_asprintf(bkpinfo->include_paths, "%s", flag_val['J']);
303 }
304
305 if ((flag_set['c'] || flag_set['w'] || flag_set['C'] || flag_set['r']) && (! bkpinfo->restore_data)) {
306 if (!flag_set['r'] && g_kernel_version <= 2.5 && strstr(flag_val['d'], "/dev/")) {
307 fatal_error("Please don't give a /dev entry. Give a SCSI node for the parameter of the -d flag.");
308 }
309 if (flag_set['r'] && g_kernel_version <= 2.5 && !strstr(flag_val['d'], "/dev/")) {
310 fatal_error("Please give a /dev entry, not a SCSI node, as the parameter of the -d flag.");
311 }
312 if (g_kernel_version >= 2.6 && !strstr(flag_val['d'], "/dev/")) {
313 log_to_screen("Linus says 2.6 has a broken ide-scsi module. Proceed at your own risk...");
314 }
315
316 if (system("which cdrecord > /dev/null 2> /dev/null") && system("which dvdrecord > /dev/null 2> /dev/null")) {
317 fatal_error("Please install dvdrecord/cdrecord and try again.");
318 }
319 if (flag_set['C']) {
320 bkpinfo->cdrw_speed = atoi(flag_val['C']);
321 if (bkpinfo->cdrw_speed < 1) {
322 fatal_error("You specified a silly speed for a CD-R[W] drive");
323 }
324 if (!flag_set['L']) {
325 log_to_screen("You must use -L with -C. Therefore I am setting it for you.");
326 flag_set['L'] = 1;
327 flag_val['L'][0] = '\0';
328 }
329 } else {
330 log_msg(3, "flag_val['c'] = %s", flag_val['c']);
331 log_msg(3, "flag_val['w'] = %s", flag_val['w']);
332 if (flag_set['c']) {
333 bkpinfo->cdrw_speed = atoi(flag_val['c']);
334 } else if (flag_set['w']) {
335 bkpinfo->cdrw_speed = atoi(flag_val['w']);
336 } else if (flag_set['r']) {
337 bkpinfo->cdrw_speed = 1; /*atoi(flag_val['r']); */
338 }
339
340 if (bkpinfo->cdrw_speed < 1) {
341 fatal_error("You specified a silly speed for a CD-R[W] drive");
342 }
343 }
344 }
345
346 if ((flag_set['t'] && !flag_set['d']) && (! bkpinfo->restore_data)) {
347 log_it("Hmm! No tape drive specified. Let's see what we can do.");
348 if ((tmp1 = mr_find_tape_device()) == NULL) {
349 fatal_error("Tape device not specified. I couldn't find it either.");
350 }
351 strcpy(flag_val['d'], tmp1);
352 mr_free(tmp1);
353 flag_set['d'] = TRUE;
354 strcpy(flag_val['d'], p);
355 mr_free(p);
356 log_to_screen("You didn't specify a tape streamer device. I'm assuming %s", flag_val['d']);
357 percent = 0;
358 }
359
360 if (flag_set['U']) // USB
361 {
362 if (! flag_set['d']) {
363 fatal_error("You need to specify a device file with -d for bootable USB device usage");
364 }
365 if ((!flag_set['s']) && (! bkpinfo->restore_data)) {
366 fatal_error("You did not specify a size (-s) for your USB device. Aborting");
367 }
368 }
369
370 if (flag_set['r']) // DVD
371 {
372 if (flag_set['m']) {
373 fatal_error("Manual CD tray (-m) not yet supported in conjunction w/ DVD drives. Drop -m.");
374 }
375 if (!flag_set['d']) {
376 if ((tmp1 = find_dvd_device(flag_val['d'])) != NULL) {
377 strcpy(flag_val['d'],tmp1);
378 mr_free(tmp1);
379 flag_set['d'] = TRUE;
380 log_to_screen("I guess DVD drive is at %s", flag_val['d']);
381 }
382 }
383 if (strchr(flag_val['d'], ',')) {
384 fatal_error("Please don't give a SCSI node. Give a _device_, preferably a /dev entry, for the parameter of the -d flag.");
385 }
386 if (! bkpinfo->restore_data) {
387 tmp1 = find_home_of_exe("growisofs");
388 if (!tmp1) {
389 mr_free(tmp1);
390 fatal_error("Please install growisofs (probably part of dvd+rw-tools). If you want DVD support, you need it.");
391 }
392 mr_free(tmp1);
393
394 tmp1 = find_home_of_exe("dvd+rw-format");
395 if (!tmp1) {
396 mr_free(tmp1);
397 fatal_error("Please install dvd+rw-format (probably part of dvd+rw-tools). If you want DVD support, you need it.");
398 }
399 mr_free(tmp1);
400
401 if (!flag_set['s']) {
402 sprintf(flag_val['s'], "%d", DEFAULT_DVD_DISK_SIZE); // 4.7 salesman's GB = 4.482 real GB = 4582 MB
403 strcat(flag_val['s'], "m");
404 log_to_screen("You did not specify a size (-s) for DVD. I'm guessing %s.", flag_val['s']);
405 flag_set['s'] = 1;
406 }
407 }
408 }
409
410 if (flag_set['t'] || flag_set['u']) { /* tape size */
411 if (strchr(flag_val['d'], ',')) {
412 fatal_error("Please don't give a SCSI node. Give a _device_, preferably a /dev entry, for the parameter of the -d flag.");
413 }
414 if ((flag_set['O']) && (! bkpinfo->restore_data)) {
415 if (flag_set['s']) {
416 if (flag_set['t']) {
417 fatal_error("For the moment, please don't specify a tape size. Mondo should handle end-of-tape gracefully anyway.");
418 }
419 if (process_the_s_switch(flag_val['s'])) {
420 fatal_error("Bad -s switch");
421 }
422 } else if (flag_set['u'] || flag_set['t']) {
423 for (i = 0; i <= MAX_NOOF_MEDIA; i++) {
424 bkpinfo->media_size[i] = 0;
425 }
426 } else {
427 retval++;
428 log_to_screen("Tape size not specified.\n");
429 }
430 }
431 } else if (! bkpinfo->restore_data) { /* CD|USB size */
432 if (flag_set['s']) {
433 if (process_the_s_switch(flag_val['s'])) {
434 fatal_error("Bad -s switch");
435 }
436 }
437 if (flag_set['w']) {
438 bkpinfo->wipe_media_first = TRUE;
439 } /* CD-RW */
440 }
441
442 if (flag_set['n']) {
443 mr_free(bkpinfo->netfs_mount);
444 mr_asprintf(bkpinfo->netfs_mount, "%s", flag_val['n']);
445 if (!flag_set['d']) {
446 mr_free(bkpinfo->netfs_remote_dir);
447 mr_asprintf(bkpinfo->netfs_remote_dir, "/");
448 }
449 /* test for protocol */
450 p = strstr(bkpinfo->netfs_mount, "://");
451 if (p == NULL) {
452 /* protocol not found assuming NFS for compatibility */
453 mr_asprintf(q,"nfs");
454
455 p = strchr(bkpinfo->netfs_mount, ':');
456 if (p == NULL) {
457 fatal_error("No protocol specified for remote share mount, nor any old NFS syntax found.\nPlease do man mondoarchive as syntax changed");
458 }
459 /* p points on to the string server:/path */
460 p = bkpinfo->netfs_mount;
461
462 } else {
463 /* Isolate the protocol */
464 *p = '\0';
465 mr_asprintf(q,"%s",bkpinfo->netfs_mount);
466
467 /* Skip proto now */
468 p++;
469 p++;
470 p++;
471 }
472 /* whatever done before proto is pointed to by q */
473 bkpinfo->netfs_proto = q;
474
475 /* p points on to the string server:/path */
476 /* Store the 2 values */
477 bkpinfo->netfs_mount = p;
478
479 /* test if we specified a user */
480 p = strchr(bkpinfo->netfs_mount, '@');
481 if (p != NULL) {
482 /* User found. Store the 2 values */
483 bkpinfo->netfs_user = bkpinfo->netfs_mount;
484 p++;
485 /* new netfs mount */
486 bkpinfo->netfs_mount = p;
487 p--;
488 *p = '\0';
489 }
490 mr_asprintf(tmp1, "mount | grep -E \"^[%s@]*%s[/]* .*\" | cut -d' ' -f3", bkpinfo->netfs_user, bkpinfo->netfs_mount);
491 mr_free(bkpinfo->isodir);
492 bkpinfo->isodir = call_program_and_get_last_line_of_output(tmp1);
493 mr_free(tmp1);
494
495 if (strlen(bkpinfo->isodir) < 3) {
496 log_to_screen("Network share is not mounted. Trying to mount it for you.\n");
497 if (strstr(bkpinfo->netfs_proto, "sshfs")) {
498 mr_asprintf(tmp1, "sshfs %s", bkpinfo->netfs_mount);
499 } else {
500 mr_asprintf(tmp1, "mount %s", bkpinfo->netfs_mount);
501 }
502 i = system(tmp1);
503 mr_free(tmp1);
504 if (i) {
505 log_to_screen("Unable to mount Network share %s. Please mount manually.\n", bkpinfo->netfs_mount);
506 retval++;
507 } else {
508 mr_asprintf(tmp1, "mount | grep -E \"^[%s@]*%s[/]* .*\" | cut -d' ' -f3", bkpinfo->netfs_user, bkpinfo->netfs_mount);
509 mr_free(bkpinfo->isodir);
510 bkpinfo->isodir = call_program_and_get_last_line_of_output(tmp1);
511 mr_free(tmp1);
512
513 if (strlen(bkpinfo->isodir) < 3) {
514 retval++;
515 log_to_screen("Network share %s is strangely not mounted. Please mount manually...\n", bkpinfo->netfs_mount);
516 }
517 }
518 }
519 log_msg(3, "proto = %s", bkpinfo->netfs_proto);
520 log_msg(3, "mount = %s", bkpinfo->netfs_mount);
521 if (bkpinfo->netfs_user) {
522 log_msg(3, "user = %s", bkpinfo->netfs_user);
523 }
524 log_msg(3, "isodir= %s", bkpinfo->isodir);
525 }
526
527 if (flag_set['c']) {
528 bkpinfo->backup_media_type = cdr;
529 }
530 if (flag_set['C']) {
531 bkpinfo->backup_media_type = cdstream;
532 }
533 if (flag_set['i']) {
534 bkpinfo->backup_media_type = iso;
535 }
536 if (flag_set['n']) {
537 bkpinfo->backup_media_type = netfs;
538 /* Never try to eject a Network device */
539 bkpinfo->please_dont_eject = TRUE;
540 }
541 if (flag_set['r']) {
542 bkpinfo->backup_media_type = dvd;
543 }
544 if (flag_set['t']) {
545 bkpinfo->backup_media_type = tape;
546 }
547 if (flag_set['u']) {
548 bkpinfo->backup_media_type = udev;
549 }
550 if (flag_set['w']) {
551 bkpinfo->backup_media_type = cdrw;
552 }
553 if (flag_set['U']) {
554 bkpinfo->backup_media_type = usb;
555 /* Never try to eject a USB device */
556 bkpinfo->please_dont_eject = TRUE;
557 }
558 if (flag_set['z']) {
559 tmp1 = find_home_of_exe("getfattr");
560 if (tmp1) {
561 mr_asprintf(g_getfattr,"getfattr");
562 }
563 mr_free(tmp1);
564
565 tmp1 = find_home_of_exe("getfacl");
566 if (tmp1) {
567 mr_asprintf(g_getfacl,"getfacl");
568 }
569 mr_free(tmp1);
570 }
571
572 /* optional, popular */
573 if (flag_set['g']) {
574 g_text_mode = FALSE;
575 }
576
577 if (flag_set['E']) {
578 if (bkpinfo->exclude_paths && bkpinfo->exclude_paths[0] == '-') {
579 retval++;
580 log_to_screen("Please supply a sensible value with '-E'\n");
581 }
582 mr_asprintf(tmp1, "%s", flag_val['E']);
583
584 p = tmp1;
585 q = tmp1;
586
587 /* Cut the flag_val['E'] in parts containing all paths to test them */
588 while (p != NULL) {
589 q = strchr(p, ' ');
590 if (q != NULL) {
591 *q = '\0';
592 /* Fix bug 14 where ending / cause a problem later
593 * so handled here for the moment */
594 q--;
595 if (*q == '/') {
596 *q = '\0';
597 }
598 q++;
599 /* End of bug fix */
600 if ((stat(p, &buf) != 0) && (! bkpinfo->restore_data)) {
601 log_msg(1, "WARNING ! %s doesn't exist", p);
602 }
603 p = q+1 ;
604 } else {
605 if ((stat(p, &buf) != 0) && (! bkpinfo->restore_data)) {
606 log_msg(1, "WARNING ! %s doesn't exist", p);
607 }
608 p = NULL;
609 }
610 }
611 mr_free(tmp1);
612 lastpos = 0;
613
614 mr_make_devlist_from_pathlist(flag_val['E'], 'E');
615 log_msg(4, "Finished with the -E option");
616 }
617
618 if (flag_set['e']) {
619 bkpinfo->please_dont_eject = TRUE;
620 }
621
622 if ((flag_set['N']) && (! bkpinfo->restore_data)) // exclude Network mounts & devices
623 {
624 mr_asprintf(psz, "%s", list_of_NETFS_mounts_only());
625 mr_strcat(bkpinfo->exclude_paths, " %s ", psz);
626 mr_free(psz);
627
628 if (bkpinfo->exclude_paths != NULL) {
629 log_msg(3, "-N means we're now excluding %s", bkpinfo->exclude_paths);
630 }
631 }
632
633 if (flag_set['b']) {
634 mr_asprintf(psz, "%s", flag_val['b']);
635 log_msg(1, "psz = '%s'", psz);
636 if (psz[strlen(psz) - 1] == 'k') {
637 psz[strlen(psz) - 1] = '\0';
638 itbs = atol(psz) * 1024L;
639 } else {
640 itbs = atol(psz);
641 }
642 mr_free(psz);
643 log_msg(1, "'%s' --> %ld", flag_val['b'], itbs);
644 log_msg(1, "Internal tape block size is now %ld bytes", itbs);
645 if (itbs % 512 != 0 || itbs < 256 || itbs > 1024L * 1024) {
646 fatal_error("Are you nuts? Silly, your internal tape block size is. Abort, I shall.");
647 }
648 bkpinfo->internal_tape_block_size = itbs;
649 }
650
651 if ((flag_set['D']) && (! bkpinfo->restore_data)) {
652 bkpinfo->differential = 1;
653// bkpinfo->differential = atoi (flag_val['D']);
654 if ((bkpinfo->differential < 1) || (bkpinfo->differential > 9)) {
655 fatal_error("The D option should be between 1 and 9 inclusive");
656 }
657 }
658
659 if (flag_set['x']) {
660 mr_asprintf(bkpinfo->image_devs, "%s", flag_val['x']);
661 if ((run_program_and_log_output("which ntfsclone", 2)) && (! bkpinfo->restore_data)) {
662 fatal_error("Please install ntfsprogs package/tarball.");
663 }
664 }
665
666 if (flag_set['m']) {
667 bkpinfo->manual_cd_tray = TRUE;
668 }
669
670 if ((flag_set['k']) && (! bkpinfo->restore_data)) {
671 mr_free(bkpinfo->kernel_path);
672 mr_asprintf(bkpinfo->kernel_path, "%s", flag_val['k']);
673 if (!does_file_exist(bkpinfo->kernel_path)) {
674 retval++;
675 log_to_screen("You specified kernel '%s', which does not exist\n", bkpinfo->kernel_path);
676 }
677 }
678
679 if (flag_set['p']) {
680 mr_free(bkpinfo->prefix);
681 mr_asprintf(bkpinfo->prefix, "%s", flag_val['p']);
682 log_msg(1,"Prefix forced to %s",bkpinfo->prefix);
683 }
684
685 if (flag_set['d']) { /* backup directory (if ISO/NETFS) */
686 if (flag_set['i']) {
687 mr_free(bkpinfo->isodir);
688 mr_asprintf(bkpinfo->isodir, "%s", flag_val['d']);
689 mr_asprintf(tmp1, "ls -l %s", bkpinfo->isodir);
690 if (run_program_and_log_output(tmp1, 2)) {
691 mr_free(tmp1);
692 fatal_error("output folder does not exist - please create it");
693 }
694 mr_free(tmp1);
695 } else if (flag_set['n']) {
696 mr_free(bkpinfo->netfs_remote_dir);
697 mr_asprintf(bkpinfo->netfs_remote_dir, "%s", flag_val['d']);
698 } else { /* backup device (if tape/CD-R/CD-RW) */
699 mr_free(bkpinfo->media_device);
700 mr_asprintf(bkpinfo->media_device, "%s", flag_val['d']);
701 }
702 }
703
704 if ((flag_set['n']) && (! bkpinfo->restore_data)) {
705 mr_asprintf(tmp1,"%s/%s/.dummy.txt", bkpinfo->isodir,bkpinfo->netfs_remote_dir);
706 if ((bkpinfo->netfs_user) && (strstr(bkpinfo->netfs_proto,"nfs"))) {
707 mr_asprintf(tmp2, "su - %s -c \"echo hi > %s\"", bkpinfo->netfs_user, tmp1);
708 } else {
709 mr_asprintf(tmp2, "echo hi > %s", tmp1);
710 }
711 i = run_program_and_log_output(tmp2, 2);
712 mr_free(tmp2);
713
714 if (i) {
715 retval++;
716 log_to_screen(tmp2, "Are you sure directory '%s' exists in remote dir '%s'?\nIf so, do you have rights to write to it?\n", bkpinfo->netfs_remote_dir, bkpinfo->netfs_mount);
717 }
718 unlink(tmp1);
719 mr_free(tmp1);
720 }
721
722 if (!flag_set['d'] && (flag_set['c'] || flag_set['w'] || flag_set['C'])) {
723 if (g_kernel_version >= 2.6) {
724 tmp2 = popup_and_get_string("Device", "Please specify the device", bkpinfo->media_device);
725 if (tmp2 == NULL) {
726 fatal_error("User opted to cancel.");
727 }
728 bkpinfo->media_device = tmp2;
729 } else {
730 bkpinfo->media_device = find_cdrw_device();
731 if (bkpinfo->media_device == NULL) {
732 retval++;
733 log_to_screen("Tried and failed to find CD-R[W] drive automatically.\n");
734 } else {
735 flag_set['d'] = TRUE;
736 strncpy(flag_val['d'], bkpinfo->media_device, MAX_STR_LEN / 4);
737 }
738 }
739 }
740
741 if ((!flag_set['d'] && !flag_set['n'] && !flag_set['C']) && (! bkpinfo->restore_data)) {
742 retval++;
743 log_to_screen("Please specify the backup device/directory.\n");
744 fatal_error("You didn't use -d to specify the backup device/directory.");
745 }
746
747 for (i = '0'; i <= '9'; i++) {
748 if (flag_set[i]) {
749 bkpinfo->compression_level = i - '0';
750 } /* not '\0' but '0' */
751 }
752
753 if (flag_set['S']) {
754 mr_asprintf(bkpinfo->scratchdir, "%s/mondo.scratch.%ld", flag_val['S'], random() % 32768);
755 }
756
757 if (flag_set['T']) {
758 setup_tmpdir(flag_val['T']);
759 mr_asprintf(tmp1, "touch %s/.foo.dat", bkpinfo->tmpdir);
760 i = run_program_and_log_output(tmp1, 1);
761 mr_free(tmp1);
762
763 if (i) {
764 log_to_screen("Please specify a tempdir which I can write to. :)");
765 fatal_error("I cannot write to the tempdir you specified.");
766 }
767 mr_asprintf(tmp1, "ln -sf %s/.foo.dat %s/.bar.dat", bkpinfo->tmpdir, bkpinfo->tmpdir);
768 i = run_program_and_log_output(tmp1, 1);
769 mr_free(tmp1);
770
771 if (i) {
772 retval++;
773 log_to_screen("Please don't specify a SAMBA or VFAT or NFS tmpdir.");
774 fatal_error("I cannot write to the tempdir you specified.");
775 }
776 }
777
778 if ((flag_set['A']) && (! bkpinfo->restore_data)) {
779 mr_asprintf(bkpinfo->call_after_iso, "%s", flag_val['A']);
780 }
781
782 if ((flag_set['B']) && (! bkpinfo->restore_data)) {
783 mr_asprintf(bkpinfo->call_before_iso, "%s", flag_val['B']);
784 }
785
786 if ((flag_set['H']) && (! bkpinfo->restore_data)) {
787 g_cd_recovery = TRUE;
788 }
789
790 if ((flag_set['l']) && (! bkpinfo->restore_data)) {
791#ifdef __FreeBSD__
792# define BOOT_LOADER_CHARS "GLBMR"
793#else
794# ifdef __IA64__
795# define BOOT_LOADER_CHARS "GER"
796# else
797# define BOOT_LOADER_CHARS "GLR"
798# endif
799#endif
800 if (!strchr(BOOT_LOADER_CHARS, (bkpinfo->boot_loader = flag_val['l'][0]))) {
801 log_msg(1, "%c? What is %c? I need G, L, E or R.", bkpinfo->boot_loader, bkpinfo->boot_loader);
802 fatal_error("Please specify GRUB, LILO, ELILO or RAW with the -l switch");
803 }
804#undef BOOT_LOADER_CHARS
805 }
806
807 if (flag_set['f']) {
808 mr_free(bkpinfo->boot_device);
809 bkpinfo->boot_device = resolve_softlinks_to_get_to_actual_device_file(flag_val['f']);
810 }
811
812 if ((flag_set['P']) && (! bkpinfo->restore_data)) {
813 mr_free(bkpinfo->postnuke_tarball);
814 mr_asprintf(bkpinfo->postnuke_tarball, "%s", flag_val['P']);
815 }
816
817 if (flag_set['Q']) {
818 i = which_boot_loader(NULL);
819 log_msg(3, "boot loader is %c", i);
820 printf("boot loader is %c\n", i);
821 finish(0);
822 }
823
824 if ((flag_set['L']) && (! bkpinfo->restore_data)) {
825 bkpinfo->use_lzo = TRUE;
826 if (run_program_and_log_output("which lzop", 2)) {
827 retval++;
828 log_to_screen("Please install LZOP. You can't use '-L' until you do.\n");
829 }
830 }
831
832 if ((flag_set['G']) && (! bkpinfo->restore_data)) {
833 bkpinfo->use_gzip = TRUE;
834 if (run_program_and_log_output("which gzip", 2)) {
835 retval++;
836 log_to_screen("Please install gzip. You can't use '-G' until you do.\n");
837 }
838 }
839
840 if ((flag_set['Y']) && (! bkpinfo->restore_data)) {
841 bkpinfo->use_lzma = TRUE;
842 if (run_program_and_log_output("which lzma", 2)) {
843 retval++;
844 log_to_screen("Please install lzma. You can't use '-Y' until you do.\n");
845 }
846 }
847
848 bkpinfo->use_obdr = FALSE;
849 if (flag_set['o']) {
850 if ((!flag_set['t']) && (! bkpinfo->restore_data)) {
851 log_to_screen("OBDR support is only available for tapes. Use the -t option");
852 fatal_error("Aborting");
853 }
854 bkpinfo->use_obdr = TRUE;
855 }
856
857#ifndef __FreeBSD__
858 if ((!is_this_a_valid_disk_format("vfat")) && (! bkpinfo->restore_data)) {
859 bkpinfo->make_cd_use_lilo = TRUE;
860 log_to_screen("Your kernel appears not to support vfat filesystems. I am therefore");
861 log_to_screen("using LILO instead of SYSLINUX as the media boot loader.");
862 }
863 if ((run_program_and_log_output("which mkfs.vfat", 2)) && (! bkpinfo->restore_data)) {
864 bkpinfo->make_cd_use_lilo = TRUE;
865#ifdef __IA32__
866 log_to_screen("Your filesystem is missing 'mkfs.vfat', so I cannot use SYSLINUX as");
867 log_to_screen("your boot loader. I shall therefore use LILO instead.");
868#endif
869#ifdef __IA64__
870 log_to_screen("Your filesystem is missing 'mkfs.vfat', so I cannot prepare the EFI");
871 log_to_screen("environment correctly. Please install it.");
872 fatal_error("Aborting");
873#endif
874 }
875#ifdef __IA64__
876 /* We force ELILO usage on IA64 */
877 bkpinfo->make_cd_use_lilo = TRUE;
878#endif
879#endif
880
881 if (! bkpinfo->restore_data) {
882 i = flag_set['O'] + flag_set['V'];
883 if (i == 0) {
884 retval++;
885 log_to_screen("Specify backup (-O), verify (-V) or both (-OV).\n");
886 }
887 }
888
889 if ((! bkpinfo->restore_data) && (flag_set['Z'])) {
890 fatal_error("The -Z switch is only valid in restore mode");
891 }
892
893 if (flag_set['Z']) {
894 if (! strcmp(flag_val['Z'], "nuke")) {
895 bkpinfo->restore_mode = nuke;
896 } else if (! strcmp(flag_val['Z'], "interactive")) {
897 bkpinfo->restore_mode = interactive;
898 } else if (! strcmp(flag_val['Z'], "compare")) {
899 bkpinfo->restore_mode = compare;
900 } else if (! strcmp(flag_val['Z'], "mbr")) {
901 bkpinfo->restore_mode = mbr;
902 } else if (! strcmp(flag_val['Z'], "iso")) {
903 bkpinfo->restore_mode = isoonly;
904 } else if (! strcmp(flag_val['Z'], "isonuke")) {
905 bkpinfo->restore_mode = isonuke;
906 } else {
907 bkpinfo->restore_mode = interactive;
908 }
909 }
910
911/* and finally... */
912
913 return (retval);
914}
915
916
917
918/**
919 * Get the switches from @p argc and @p argv using getopt() and place them in
920 * @p flag_set and @p flag_val.
921 * @param argc The argument count (@p argc passed to main()).
922 * @param argv The argument vector (@p argv passed to main()).
923 * @param flag_val An array indexed by switch letter - if a switch is set and
924 * has an argument then set flag_val[switch] to that argument.
925 * @param flag_set An array indexed by switch letter - if a switch is set then
926 * set flag_set[switch] to TRUE, else set it to FALSE.
927 * @return The number of problems with the command line (0 for success).
928 */
929int retrieve_switches_from_command_line(int argc, char *argv[], char flag_val[128][MAX_STR_LEN], bool flag_set[128])
930{
931 /*@ ints ** */
932 int opt = 0;
933 int i = 0;
934 int len;
935
936 /*@ bools *** */
937 bool bad_switches = FALSE;
938
939 assert(flag_val != NULL);
940 assert(flag_set != NULL);
941
942 for (i = 0; i < 128; i++) {
943 flag_val[i][0] = '\0';
944 flag_set[i] = FALSE;
945 }
946 while ((opt = getopt(argc, argv, MONDO_OPTIONS)) != -1) {
947 if (opt == '?') {
948 bad_switches = TRUE;
949 } else {
950 if (flag_set[opt]) {
951 bad_switches = TRUE;
952 log_to_screen("Switch -%c previously defined as %s\n", opt, flag_val[opt]);
953 } else {
954 flag_set[opt] = TRUE;
955 if (optarg) {
956 len = strlen(optarg);
957 if (optarg[0] != '/' && optarg[len - 1] == '/') {
958 optarg[--len] = '\0';
959 log_to_screen
960 ("Warning - param '%s' should not have trailing slash!",
961 optarg);
962 }
963 if (opt == 'd') {
964 if (strchr(flag_val[opt], '/')
965 && flag_val[opt][0] != '/') {
966 log_to_screen("-%c flag --- must be absolute path --- '%s' isn't absolute", opt, flag_val[opt]);
967 bad_switches = TRUE;
968 }
969 }
970 strcpy(flag_val[opt], optarg);
971 }
972 }
973 }
974 }
975 for (i = optind; i < argc; i++) {
976 bad_switches = TRUE;
977 log_to_screen("Invalid arg -- %s\n", argv[i]);
978 }
979 return (bad_switches);
980}
981
982
983
984
985/**
986 * Print a not-so-helpful help message and exit.
987 */
988void help_screen()
989{
990 log_msg(1, "Type 'man mondoarchive' for more information\n");
991 exit(1);
992}
993
994
995/**
996 * Terminate Mondo in response to a signal.
997 * @param sig The signal number received.
998 */
999void terminate_daemon(int sig)
1000{
1001 char *tmp = NULL;
1002 char *tmp2 = NULL;
1003
1004 switch (sig) {
1005 case SIGINT:
1006 mr_asprintf(tmp, "SIGINT");
1007 mr_asprintf(tmp2, "You interrupted me :-)");
1008 break;
1009 case SIGKILL:
1010 mr_asprintf(tmp, "SIGKILL");
1011 mr_asprintf(tmp2, "I seriously have no clue how this signal even got to me. Something's wrong with your system.");
1012 break;
1013 case SIGTERM:
1014 mr_asprintf(tmp, "SIGTERM");
1015 mr_asprintf(tmp2, "Got terminate signal");
1016 break;
1017 case SIGHUP:
1018 mr_asprintf(tmp, "SIGHUP");
1019 mr_asprintf(tmp2, "Hangup on line");
1020 break;
1021 case SIGSEGV:
1022 mr_asprintf(tmp, "SIGSEGV");
1023 mr_asprintf(tmp2, "Internal programming error. Please send a backtrace as well as your log.");
1024 break;
1025 case SIGPIPE:
1026 mr_asprintf(tmp, "SIGPIPE");
1027 mr_asprintf(tmp2, "Pipe was broken");
1028 break;
1029 case SIGABRT:
1030 mr_asprintf(tmp, "SIGABRT");
1031 mr_asprintf(tmp2, "Abort - probably failed assertion. I'm sleeping for a few seconds so you can read the message.");
1032 break;
1033 default:
1034 mr_asprintf(tmp, "(Unknown)");
1035 mr_asprintf(tmp2, "(Unknown)");
1036 }
1037
1038 mr_strcat(tmp, " signal received from OS");
1039 log_to_screen(tmp);
1040 mr_free(tmp);
1041
1042 log_to_screen(tmp2);
1043 mr_free(tmp2);
1044 if (sig == SIGABRT) {
1045 sleep(10);
1046 }
1047 kill_buffer();
1048
1049 free_MR_global_filenames();
1050
1051 fatal_error("MondoRescue is terminating in response to a signal from the OS");
1052 finish(254); // just in case
1053}
1054
1055
1056
1057
1058/**
1059 * Turn signal-trapping on or off.
1060 * @param on If TRUE, turn it on; if FALSE, turn it off (we still trap it, just don't do as much).
1061 */
1062void set_signals(int on)
1063{
1064 int signals[] = { SIGTERM, SIGHUP, SIGTRAP, SIGABRT, SIGINT, SIGKILL, SIGSTOP, 0 };
1065 int i;
1066
1067 signal(SIGPIPE, sigpipe_occurred);
1068 for (i = 0; signals[i]; i++) {
1069 if (on) {
1070 signal(signals[i], terminate_daemon);
1071 } else {
1072 signal(signals[i], termination_in_progress);
1073 }
1074 }
1075}
1076
1077
1078
1079
1080/**
1081 * Exit immediately without cleaning up.
1082 * @param sig The signal we are exiting due to.
1083 */
1084void termination_in_progress(int sig)
1085{
1086 log_msg(1, "Termination in progress");
1087 usleep(1000);
1088 pthread_exit(0);
1089}
1090
1091/* @} - end of cliGroup */
Note: See TracBrowser for help on using the repository browser.