X-Git-Url: https://git.sur5r.net/?a=blobdiff_plain;f=bacula%2Fsrc%2Fdird%2Finc_conf.c;h=ff76230b9c67792dbf925331eb8d8bcccf32ea8a;hb=9f01506e19567ce5c8fae5699016a1d512647f55;hp=9d09e1a535b3a096051d32e5eb3ce56270cf0cbb;hpb=ff8f6a055709010d9d698b2f98e52e3a7148389c;p=bacula%2Fbacula diff --git a/bacula/src/dird/inc_conf.c b/bacula/src/dird/inc_conf.c index 9d09e1a535..ff76230b9c 100644 --- a/bacula/src/dird/inc_conf.c +++ b/bacula/src/dird/inc_conf.c @@ -7,7 +7,7 @@ * Version $Id$ */ /* - Copyright (C) 2000-2003 Kern Sibbald and John Walker + Copyright (C) 2003-2004 Kern Sibbald and John Walker This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as @@ -31,13 +31,15 @@ /* Forward referenced subroutines */ -void store_inc(LEX *lc, struct res_items *item, int index, int pass); +void store_inc(LEX *lc, RES_ITEM *item, int index, int pass); -static void store_newinc(LEX *lc, struct res_items *item, int index, int pass); -static void store_match(LEX *lc, struct res_items *item, int index, int pass); -static void store_opts(LEX *lc, struct res_items *item, int index, int pass); -static void store_fname(LEX *lc, struct res_items *item, int index, int pass); -static void store_base(LEX *lc, struct res_items *item, int index, int pass); +static void store_newinc(LEX *lc, RES_ITEM *item, int index, int pass); +static void store_regex(LEX *lc, RES_ITEM *item, int index, int pass); +static void store_wild(LEX *lc, RES_ITEM *item, int index, int pass); +static void store_opts(LEX *lc, RES_ITEM *item, int index, int pass); +static void store_fname(LEX *lc, RES_ITEM *item, int index, int pass); +static void options_res(LEX *lc, RES_ITEM *item, int index, int pass); +static void store_base(LEX *lc, RES_ITEM *item, int index, int pass); static void setup_current_opts(void); @@ -54,9 +56,18 @@ static INCEXE res_incexe; /* * new Include/Exclude items - * name handler value code flags default_value + * name handler value code flags default_value */ -static struct res_items newinc_items[] = { +static RES_ITEM newinc_items[] = { + {"file", store_fname, NULL, 0, 0, 0}, + {"options", options_res, NULL, 0, 0, 0}, + {NULL, NULL, NULL, 0, 0, 0} +}; + +/* + * Items that are valid in an Options resource + */ +static RES_ITEM options_items[] = { {"compression", store_opts, NULL, 0, 0, 0}, {"signature", store_opts, NULL, 0, 0, 0}, {"verify", store_opts, NULL, 0, 0, 0}, @@ -66,29 +77,35 @@ static struct res_items newinc_items[] = { {"readfifo", store_opts, NULL, 0, 0, 0}, {"replace", store_opts, NULL, 0, 0, 0}, {"portable", store_opts, NULL, 0, 0, 0}, - {"match", store_match, NULL, 0, 0, 0}, - {"file", store_fname, NULL, 0, 0, 0}, + {"regex", store_regex, NULL, 0, 0, 0}, {"base", store_base, NULL, 0, 0, 0}, + {"wild", store_wild, NULL, 0, 0, 0}, + {"exclude", store_opts, NULL, 0, 0, 0}, {NULL, NULL, NULL, 0, 0, 0} }; + /* Define FileSet KeyWord values */ -#define INC_KW_NONE 0 -#define INC_KW_COMPRESSION 1 -#define INC_KW_SIGNATURE 2 -#define INC_KW_ENCRYPTION 3 -#define INC_KW_VERIFY 4 -#define INC_KW_ONEFS 5 -#define INC_KW_RECURSE 6 -#define INC_KW_SPARSE 7 -#define INC_KW_REPLACE 8 /* restore options */ -#define INC_KW_READFIFO 9 /* Causes fifo data to be read */ -#define INC_KW_PORTABLE 10 -#define INC_KW_MTIMEONLY 11 -#define INC_KW_KEEPATIME 12 - -/* Include keywords -- these are keywords that can appear +enum { + INC_KW_NONE, + INC_KW_COMPRESSION, + INC_KW_SIGNATURE, + INC_KW_ENCRYPTION, + INC_KW_VERIFY, + INC_KW_ONEFS, + INC_KW_RECURSE, + INC_KW_SPARSE, + INC_KW_REPLACE, /* restore options */ + INC_KW_READFIFO, /* Causes fifo data to be read */ + INC_KW_PORTABLE, + INC_KW_MTIMEONLY, + INC_KW_KEEPATIME, + INC_KW_EXCLUDE +}; + +/* + * Include keywords -- these are keywords that can appear * in the options lists of an old include ( Include = compression= ...) */ static struct s_kw FS_option_kw[] = { @@ -104,6 +121,7 @@ static struct s_kw FS_option_kw[] = { {"portable", INC_KW_PORTABLE}, {"mtimeonly", INC_KW_MTIMEONLY}, {"keepatime", INC_KW_KEEPATIME}, + {"exclude", INC_KW_EXCLUDE}, {NULL, 0} }; @@ -153,6 +171,8 @@ static struct s_fs_opt FS_options[] = { {"no", INC_KW_MTIMEONLY, "0"}, {"yes", INC_KW_KEEPATIME, "k"}, {"no", INC_KW_KEEPATIME, "0"}, + {"yes", INC_KW_EXCLUDE, "e"}, + {"no", INC_KW_EXCLUDE, "0"}, {NULL, 0, 0} }; @@ -162,6 +182,7 @@ static struct s_fs_opt FS_options[] = { * 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. + * This code is also used inside an Options resource. */ static void scan_include_options(LEX *lc, int keyword, char *opts, int optlen) { @@ -205,8 +226,11 @@ static void scan_include_options(LEX *lc, int keyword, char *opts, int optlen) } } -/* Store FileSet Include/Exclude info */ -void store_inc(LEX *lc, struct res_items *item, int index, int pass) +/* + * + * Store FileSet Include/Exclude info + */ +void store_inc(LEX *lc, RES_ITEM *item, int index, int pass) { int token, i; int options = lc->options; @@ -216,7 +240,7 @@ void store_inc(LEX *lc, struct res_items *item, int index, int pass) /* * Decide if we are doing a new Include or an old include. The - * new Include is followed immediately by {, whereas the + * new Include is followed immediately by open brace, whereas the * old include has options following the Include. */ token = lex_get_token(lc, T_ALL); @@ -335,20 +359,21 @@ void store_inc(LEX *lc, struct res_items *item, int index, int pass) /* * Store FileSet FInclude/FExclude info * Note, when this routine is called, we are inside a FileSet - * resource. We treat the Finclude/Fexeclude like a sort of + * resource. We treat the Include/Execlude like a sort of * mini-resource within the FileSet resource. */ -static void store_newinc(LEX *lc, struct res_items *item, int index, int pass) +static void store_newinc(LEX *lc, RES_ITEM *item, int index, int pass) { int token, i; INCEXE *incexe; + bool options; if (!res_all.res_fs.have_MD5) { MD5Init(&res_all.res_fs.md5c); res_all.res_fs.have_MD5 = TRUE; } memset(&res_incexe, 0, sizeof(INCEXE)); - res_all.res_fs.new_include = TRUE; + res_all.res_fs.new_include = true; while ((token = lex_get_token(lc, T_ALL)) != T_EOF) { if (token == T_EOL) { continue; @@ -360,10 +385,13 @@ static void store_newinc(LEX *lc, struct res_items *item, int index, int pass) scan_err1(lc, _("Expecting keyword, got: %s\n"), lc->str); } for (i=0; newinc_items[i].name; i++) { + options = strcasecmp(lc->str, "options") == 0; if (strcasecmp(newinc_items[i].name, lc->str) == 0) { - token = lex_get_token(lc, T_ALL); - if (token != T_EQUALS) { - scan_err1(lc, "expected an equals, got: %s", lc->str); + if (!options) { + token = lex_get_token(lc, T_ALL); + if (token != T_EQUALS) { + scan_err1(lc, "expected an equals, got: %s", lc->str); + } } /* Call item handler */ newinc_items[i].handler(lc, &newinc_items[i], i, pass); @@ -404,24 +432,25 @@ static void store_newinc(LEX *lc, struct res_items *item, int index, int pass) } -/* Store Match info */ -static void store_match(LEX *lc, struct res_items *item, int index, int pass) +/* Store regex info */ +static void store_regex(LEX *lc, RES_ITEM *item, int index, int pass) { int token; if (pass == 1) { - /* Pickup Match string + /* Pickup regex string */ token = lex_get_token(lc, T_ALL); switch (token) { case T_IDENTIFIER: case T_UNQUOTED_STRING: case T_QUOTED_STRING: - setup_current_opts(); - res_incexe.current_opts->match.append(bstrdup(lc->str)); + res_incexe.current_opts->regex.append(bstrdup(lc->str)); + Dmsg3(200, "set regex %p size=%d %s\n", + res_incexe.current_opts, res_incexe.current_opts->regex.size(),lc->str); break; default: - scan_err1(lc, _("Expected a filename, got: %s\n"), lc->str); + scan_err1(lc, _("Expected a regex string, got: %s\n"), lc->str); } } else { /* pass 2 */ lex_get_token(lc, T_ALL); @@ -430,28 +459,57 @@ static void store_match(LEX *lc, struct res_items *item, int index, int pass) } /* Store Base info */ -static void store_base(LEX *lc, struct res_items *item, int index, int pass) +static void store_base(LEX *lc, RES_ITEM *item, int index, int pass) { int token; if (pass == 1) { - setup_current_opts(); /* * Pickup Base Job Name */ token = lex_get_token(lc, T_NAME); - res_incexe.current_opts->base_list.append(bstrdup(lc->str)); + res_incexe.current_opts->base.append(bstrdup(lc->str)); } else { /* pass 2 */ lex_get_token(lc, T_ALL); } scan_to_eol(lc); } + + +/* Store Wild-card info */ +static void store_wild(LEX *lc, RES_ITEM *item, int index, int pass) +{ + int token; + + if (pass == 1) { + /* + * Pickup Wild-card string + */ + token = lex_get_token(lc, T_ALL); + switch (token) { + case T_IDENTIFIER: + case T_UNQUOTED_STRING: + case T_QUOTED_STRING: + res_incexe.current_opts->wild.append(bstrdup(lc->str)); + Dmsg3(200, "set wild %p size=%d %s\n", + res_incexe.current_opts, res_incexe.current_opts->wild.size(),lc->str); + break; + default: + scan_err1(lc, _("Expected a wild-card string, got: %s\n"), lc->str); + } + } else { /* pass 2 */ + lex_get_token(lc, T_ALL); + } + scan_to_eol(lc); +} + + /* * Store Filename info. Note, for minor efficiency reasons, we * always increase the name buffer by 10 items because we expect * to add more entries. */ -static void store_fname(LEX *lc, struct res_items *item, int index, int pass) +static void store_fname(LEX *lc, RES_ITEM *item, int index, int pass) { int token; INCEXE *incexe; @@ -483,10 +541,56 @@ static void store_fname(LEX *lc, struct res_items *item, int index, int pass) scan_to_eol(lc); } +/* + * Come here when Options seen in Include/Exclude + */ +static void options_res(LEX *lc, RES_ITEM *item, int index, int pass) +{ + int token, i; + + token = lex_get_token(lc, T_ALL); + if (token != T_BOB) { + scan_err1(lc, "Expecting open brace. Got %s", lc->str); + } + + if (pass == 1) { + setup_current_opts(); + } + + while ((token = lex_get_token(lc, T_ALL)) != T_EOF) { + if (token == T_EOL) { + continue; + } + if (token == T_EOB) { + break; + } + if (token != T_IDENTIFIER) { + scan_err1(lc, _("Expecting keyword, got: %s\n"), lc->str); + } + for (i=0; options_items[i].name; i++) { + if (strcasecmp(options_items[i].name, lc->str) == 0) { + token = lex_get_token(lc, T_ALL); + if (token != T_EQUALS) { + scan_err1(lc, "expected an equals, got: %s", lc->str); + } + /* Call item handler */ + options_items[i].handler(lc, &options_items[i], i, pass); + i = -1; + break; + } + } + if (i >=0) { + scan_err1(lc, "Keyword %s not permitted in this resource", lc->str); + } + } + scan_to_eol(lc); +} + + /* * New style options come here */ -static void store_opts(LEX *lc, struct res_items *item, int index, int pass) +static void store_opts(LEX *lc, RES_ITEM *item, int index, int pass) { int i; int keyword; @@ -507,8 +611,7 @@ static void store_opts(LEX *lc, struct res_items *item, int index, int pass) /* Now scan for the value */ scan_include_options(lc, keyword, inc_opts, sizeof(inc_opts)); if (pass == 1) { - setup_current_opts(); - bstrncpy(res_incexe.current_opts->opts, inc_opts, MAX_FOPTS); + bstrncat(res_incexe.current_opts->opts, inc_opts, MAX_FOPTS); Dmsg2(100, "new pass=%d incexe opts=%s\n", pass, res_incexe.current_opts->opts); } scan_to_eol(lc); @@ -519,13 +622,17 @@ static void store_opts(LEX *lc, struct res_items *item, int index, int pass) /* If current_opts not defined, create first entry */ static void setup_current_opts(void) { - if (res_incexe.current_opts == NULL) { - res_incexe.current_opts = (FOPTS *)malloc(sizeof(FOPTS)); - memset(res_incexe.current_opts, 0, sizeof(FOPTS)); - res_incexe.current_opts->match.init(1, true); - res_incexe.current_opts->base_list.init(1, true); - res_incexe.num_opts = 1; + FOPTS *fo = (FOPTS *)malloc(sizeof(FOPTS)); + memset(fo, 0, sizeof(FOPTS)); + fo->regex.init(1, true); + fo->wild.init(1, true); + fo->base.init(1, true); + res_incexe.current_opts = fo; + if (res_incexe.num_opts == 0) { res_incexe.opts_list = (FOPTS **)malloc(sizeof(FOPTS *)); - res_incexe.opts_list[0] = res_incexe.current_opts; + } else { + res_incexe.opts_list = (FOPTS **)realloc(res_incexe.opts_list, + sizeof(FOPTS *) * (res_incexe.num_opts + 1)); } + res_incexe.opts_list[res_incexe.num_opts++] = fo; }