Skip to content

Commit

Permalink
Implement missing option printing.
Browse files Browse the repository at this point in the history
Some fileset options are added over time but the config printing code
doesn't know how to print these. This patch adds all missing fileset
options and adds printing of options now using Camel case.

Also added some code for a FIXME that has been there for ages for
Verify, Accurate and Base options checking.

Fixes #347: show all gives errors.
  • Loading branch information
Marco van Wieringen committed Oct 6, 2014
1 parent 1001bfc commit f0ac859
Show file tree
Hide file tree
Showing 3 changed files with 135 additions and 52 deletions.
131 changes: 91 additions & 40 deletions src/dird/dird_conf.c
Expand Up @@ -1148,134 +1148,185 @@ bool FILESETRES::print_config(POOL_MEM &buff)

for (p = &fo->opts[0]; *p; p++) {
switch (*p) {
case '0': /* no option */
break;
case 'a': /* alway replace */
indent_config_item(cfg_str, 3, "replace = always\n");
indent_config_item(cfg_str, 3, "Replace = Always\n");
break;
case '0': /* no option */
case 'C': /* */
indent_config_item(cfg_str, 3, "Accurate = ");
p++; /* skip C */
for (; *p && *p != ':'; p++) {
Mmsg(temp, "%c", *p);
pm_strcat(cfg_str, temp.c_str());
}
pm_strcat(cfg_str, "\n");
break;
case 'd':
switch(*(p + 1)) {
case '1':
indent_config_item(cfg_str, 3, "Shadowing = LocalWarn\n");
p++;
break;
case '2':
indent_config_item(cfg_str, 3, "Shadowing = LocalRemove\n");
p++;
break;
case '3':
indent_config_item(cfg_str, 3, "Shadowing = GlobalWarn\n");
p++;
break;
case '4':
indent_config_item(cfg_str, 3, "Shadowing = GlobalRemove\n");
p++;
break;
}
break;
case 'e':
indent_config_item(cfg_str, 3, "exclude = yes\n");
indent_config_item(cfg_str, 3, "Exclude = yes\n");
break;
case 'f':
indent_config_item(cfg_str, 3, "onefs = no\n");
indent_config_item(cfg_str, 3, "OneFS = no\n");
break;
case 'h': /* no recursion */
indent_config_item(cfg_str, 3, "recurse = no\n");
indent_config_item(cfg_str, 3, "Recurse = no\n");
break;
case 'H': /* no hard link handling */
indent_config_item(cfg_str, 3, "hardlinks = no\n");
indent_config_item(cfg_str, 3, "Hardlinks = no\n");
break;
case 'i':
indent_config_item(cfg_str, 3, "ignorecase = yes\n");
indent_config_item(cfg_str, 3, "IgnoreCase = yes\n");
break;
case 'J': /* Base Job */
indent_config_item(cfg_str, 3, "BaseJob = ");
p++; /* skip J */
for (; *p && *p != ':'; p++) {
Mmsg(temp, "%c", *p);
pm_strcat(cfg_str, temp.c_str());
}
pm_strcat(cfg_str, "\n");
break;
case 'M': /* MD5 */
indent_config_item(cfg_str, 3, "signature = md5\n");
indent_config_item(cfg_str, 3, "Signature = MD5\n");
break;
case 'n':
indent_config_item(cfg_str, 3, "replace = never\n");
indent_config_item(cfg_str, 3, "Replace = Never\n");
break;
case 'p': /* use portable data format */
indent_config_item(cfg_str, 3, "portable = yes\n");
indent_config_item(cfg_str, 3, "Portable = Yes\n");
break;
case 'P': /* strip path */
indent_config_item(cfg_str, 3, "Strip = ");
p++; /* skip P */
for (; *p && *p != ':'; p++) {
Mmsg(temp, "%c", *p);
pm_strcat(cfg_str, temp.c_str());
}
pm_strcat(cfg_str, "\n");
break;
case 'R': /* Resource forks and Finder Info */
indent_config_item(cfg_str, 3, "hfsplussupport = yes\n");
indent_config_item(cfg_str, 3, "HFSPlusSupport = Yes\n");
case 'r': /* read fifo */
indent_config_item(cfg_str, 3, "readfifo = yes\n");
indent_config_item(cfg_str, 3, "ReadFifo = Yes\n");
break;
case 'S':
switch(*(p + 1)) {
case ' ':
/* Old director did not specify SHA variant */
break;
case '1':
indent_config_item(cfg_str, 3, "signature = sha1\n");
indent_config_item(cfg_str, 3, "Signature = SHA1\n");
p++;
break;
#ifdef HAVE_SHA2
case '2':
indent_config_item(cfg_str, 3, "signature = sha256\n");
indent_config_item(cfg_str, 3, "Signature = SHA256\n");
p++;
break;
case '3':
indent_config_item(cfg_str, 3, "signature = sha512\n");
indent_config_item(cfg_str, 3, "Signature = SHA512\n");
p++;
break;
#endif
default:
/* Automatically downgrade to SHA-1 if an unsupported
* SHA variant is specified */
indent_config_item(cfg_str, 3, "signature = sha1\n");
indent_config_item(cfg_str, 3, "Signature = SHA1\n");
p++;
break;
}
break;
case 's':
indent_config_item(cfg_str, 3, "sparse = yes\n");
indent_config_item(cfg_str, 3, "Sparse = Yes\n");
break;
case 'm':
indent_config_item(cfg_str, 3, "mtimeonly = yes\n");
indent_config_item(cfg_str, 3, "MtimeOnly = Yes\n");
break;
case 'k':
indent_config_item(cfg_str, 3, "keepatime = yes\n");
indent_config_item(cfg_str, 3, "KeepAtime = Yes\n");
break;
case 'K':
indent_config_item(cfg_str, 3, "NoAtime = Yes\n");
break;
case 'A':
indent_config_item(cfg_str, 3, "aclsupport = yes\n");
indent_config_item(cfg_str, 3, "AclSupport = Yes\n");
break;
case 'V': /* verify options */
indent_config_item(cfg_str, 3, "verify = ");

/*
* Copy Verify Options
*/
//for (int j = 0; *p && *p != ':'; p++) {
indent_config_item(cfg_str, 3, "Verify = ");
p++; /* skip V */
for (; *p && *p != ':'; p++) {
Mmsg(temp, "%c", *p);
pm_strcat(cfg_str, temp.c_str());
//fo->VerifyOpts[j] = *p;
//if (j < (int)sizeof(fo->VerifyOpts) - 1) {
// j++;
//}
}
//fo->VerifyOpts[j] = 0;
pm_strcat(cfg_str, "\n");
break;
case 'w':
indent_config_item(cfg_str, 3, "replace = ifnewer\n");
indent_config_item(cfg_str, 3, "Replace = IfNewer\n");
break;
case 'W':
indent_config_item(cfg_str, 3, "enhancedwild = yes\n");
indent_config_item(cfg_str, 3, "EnhancedWild = Yes\n");
break;
case 'z': /* size */
indent_config_item(cfg_str, 3, "Size = ");
p++; /* skip z */
for (; *p && *p != ':'; p++) {
Mmsg(temp, "%c", *p);
pm_strcat(cfg_str, temp.c_str());
}
pm_strcat(cfg_str, "\n");
break;
case 'Z': /* compression */
indent_config_item(cfg_str, 3, "compression = ");
indent_config_item(cfg_str, 3, "Compression = ");
p++; /* skip Z */
if (*p >= '0' && *p <= '9') {
Mmsg(temp, "gzip\n");
Mmsg(temp, "GZIP\n");
pm_strcat(cfg_str, temp.c_str());
Mmsg(temp, "%c\n", *p);
pm_strcat(cfg_str, temp.c_str());
p++; /* skip number */
} else if (*p == 'o') {
Mmsg(temp, "lzo\n");
Mmsg(temp, "LZO\n");
pm_strcat(cfg_str, temp.c_str());
break;
} else if (*p == 'f') {
p++;
if (*p == 'f') {
Mmsg(temp, "lzfast\n");
Mmsg(temp, "LZFAST\n");
pm_strcat(cfg_str, temp.c_str());
break;
} else if (*p == '4') {
Mmsg(temp, "lz4\n");
Mmsg(temp, "LZ4\n");
pm_strcat(cfg_str, temp.c_str());
break;
} else if (*p == 'h') {
Mmsg(temp, "lz4hc\n");
Mmsg(temp, "LZ4HC\n");
pm_strcat(cfg_str, temp.c_str());
break;
}
}
break;
case 'X':
indent_config_item(cfg_str, 3, "xattr = yes\n");
indent_config_item(cfg_str, 3, "Xattr = Yes\n");
break;
default:
Emsg1(M_ERROR, 0, _("Unknown include/exclude option: %c\n"), *p);
Expand Down
51 changes: 39 additions & 12 deletions src/dird/inc_conf.c
Expand Up @@ -160,10 +160,35 @@ void find_used_compressalgos(POOL_MEM *compressalgos, JCR *jcr)
}
}

/*
* Check if the configured options are valid.
*/
static inline void is_in_permitted_set(LEX *lc, const char *set_type, const char *permitted_set)
{
const char *p, *q;
bool found;

for (p = lc->str; *p; p++) {
found = false;
for (q = permitted_set; *q; q++) {
if (*p == *q) {
found = true;
break;
}
}

if (!found) {
scan_err3(lc, _("Illegal %s option %c, got option string: %s:"),
set_type, *p, lc->str);
}
}
}

/*
* Scan for right hand side of Include options (keyword=option) is
* converted into one or two characters. Verifyopts=xxxx is Vxxxx:
* Whatever is found is concatenated to the opts string.
* converted into one or two characters. Verifyopts=xxxx is Vxxxx:
* Whatever is found is concatenated to the opts string.
*
* This code is also used inside an Options resource.
*/
static void scan_include_options(LEX *lc, int keyword, char *opts, int optlen)
Expand All @@ -174,37 +199,37 @@ static void scan_include_options(LEX *lc, int keyword, char *opts, int optlen)
struct s_sz_matching size_matching;

memset(option, 0, sizeof(option));
lc->options |= LOPT_STRING; /* force string */
lex_get_token(lc, T_STRING); /* expect at least one option */
if (keyword == INC_KW_VERIFY) { /* special case */
/* ***FIXME**** ensure these are in permitted set */
lc->options |= LOPT_STRING; /* force string */
lex_get_token(lc, T_STRING); /* expect at least one option */
if (keyword == INC_KW_VERIFY) { /* special case */
is_in_permitted_set(lc, _("verify"), PERMITTED_VERIFY_OPTIONS);
bstrncat(opts, "V", optlen); /* indicate Verify */
bstrncat(opts, lc->str, optlen);
bstrncat(opts, ":", optlen); /* terminate it */
Dmsg3(900, "Catopts=%s option=%s optlen=%d\n", opts, option,optlen);
} else if (keyword == INC_KW_ACCURATE) { /* special case */
/* ***FIXME**** ensure these are in permitted set */
is_in_permitted_set(lc, _("accurate"), PERMITTED_ACCURATE_OPTIONS);
bstrncat(opts, "C", optlen); /* indicate Accurate */
bstrncat(opts, lc->str, optlen);
bstrncat(opts, ":", optlen); /* terminate it */
Dmsg3(900, "Catopts=%s option=%s optlen=%d\n", opts, option,optlen);
} else if (keyword == INC_KW_BASEJOB) { /* special case */
/* ***FIXME**** ensure these are in permitted set */
is_in_permitted_set(lc, _("base job"), PERMITTED_BASEJOB_OPTIONS);
bstrncat(opts, "J", optlen); /* indicate BaseJob */
bstrncat(opts, lc->str, optlen);
bstrncat(opts, ":", optlen); /* terminate it */
Dmsg3(900, "Catopts=%s option=%s optlen=%d\n", opts, option,optlen);
} else if (keyword == INC_KW_STRIPPATH) { /* special case */
if (!is_an_integer(lc->str)) {
scan_err1(lc, _("Expected a strip path positive integer, got:%s:"), lc->str);
scan_err1(lc, _("Expected a strip path positive integer, got: %s:"), lc->str);
}
bstrncat(opts, "P", optlen); /* indicate strip path */
bstrncat(opts, lc->str, optlen);
bstrncat(opts, ":", optlen); /* terminate it */
Dmsg3(900, "Catopts=%s option=%s optlen=%d\n", opts, option,optlen);
} else if (keyword == INC_KW_SIZE) { /* special case */
if (!parse_size_match(lc->str, &size_matching)) {
scan_err1(lc, _("Expected a parseable size, got:%s:"), lc->str);
scan_err1(lc, _("Expected a parseable size, got: %s:"), lc->str);
}
bstrncat(opts, "z", optlen); /* indicate size */
bstrncat(opts, lc->str, optlen);
Expand All @@ -222,15 +247,17 @@ static void scan_include_options(LEX *lc, int keyword, char *opts, int optlen)
}
}
if (i != 0) {
scan_err1(lc, _("Expected a FileSet option keyword, got:%s:"), lc->str);
scan_err1(lc, _("Expected a FileSet option keyword, got: %s:"), lc->str);
} else { /* add option */
bstrncat(opts, option, optlen);
Dmsg3(900, "Catopts=%s option=%s optlen=%d\n", opts, option,optlen);
}
}
lc->options = lcopts;

/* If option terminated by comma, eat it */
/*
* If option terminated by comma, eat it
*/
if (lc->ch == ',') {
lex_get_token(lc, T_ALL); /* yes, eat comma */
}
Expand Down
5 changes: 5 additions & 0 deletions src/dird/inc_conf.h
Expand Up @@ -177,4 +177,9 @@ static struct s_fs_opt FS_options[] = {
{ "none", INC_KW_SHADOWING, "0" },
{ NULL, 0, 0 }
};

#define PERMITTED_VERIFY_OPTIONS (const char *)"ipnugsamcd51"
#define PERMITTED_ACCURATE_OPTIONS (const char *)"ipnugsamcd51A"
#define PERMITTED_BASEJOB_OPTIONS (const char *)"ipnugsamcd51"

#endif /* _INC_CONF_H */

0 comments on commit f0ac859

Please sign in to comment.