X-Git-Url: https://git.sur5r.net/?a=blobdiff_plain;f=bacula%2Fsrc%2Fdird%2Finc_conf.c;h=5b1b5c66a542323c9c4e3e6dd7164e345da1cc60;hb=b8b2ed2a6db4fb8436647d438185a364951375fc;hp=78836276184bf4710c31f218f07793fa7abe08e2;hpb=7996a8e6221c890f0d2144c7d05d873bbe9b5777;p=bacula%2Fbacula diff --git a/bacula/src/dird/inc_conf.c b/bacula/src/dird/inc_conf.c index 7883627618..5b1b5c66a5 100644 --- a/bacula/src/dird/inc_conf.c +++ b/bacula/src/dird/inc_conf.c @@ -1,6 +1,6 @@ /* - * Configuration file parser for Include, Exclude, Finclude - * and FExclude records. + * Configuration file parser for new and old Include and + * Exclude records * * Kern Sibbald, March MMIII * @@ -31,13 +31,13 @@ /* Forward referenced subroutines */ -void store_inc(LEX *lc, struct res_items *item, int index, int pass); -void store_finc(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_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_match(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 store_base(LEX *lc, RES_ITEM *item, int index, int pass); static void setup_current_opts(void); @@ -49,14 +49,14 @@ static void setup_current_opts(void); extern URES res_all; extern int res_all_size; -/* We build the current Finclude Fexclude item here */ +/* We build the current new Include and Exclude items here */ static INCEXE res_incexe; /* - * FInclude/FExclude items + * new Include/Exclude items * name handler value code flags default_value */ -static struct res_items finc_items[] = { +static RES_ITEM newinc_items[] = { {"compression", store_opts, NULL, 0, 0, 0}, {"signature", store_opts, NULL, 0, 0, 0}, {"verify", store_opts, NULL, 0, 0, 0}, @@ -65,6 +65,7 @@ static struct res_items finc_items[] = { {"sparse", store_opts, NULL, 0, 0, 0}, {"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}, {"base", store_base, NULL, 0, 0, 0}, @@ -83,9 +84,12 @@ static struct res_items finc_items[] = { #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 - * in the options lists of an include ( Include = compression= ...) + * in the options lists of an old include ( Include = compression= ...) */ static struct s_kw FS_option_kw[] = { {"compression", INC_KW_COMPRESSION}, @@ -97,6 +101,9 @@ static struct s_kw FS_option_kw[] = { {"sparse", INC_KW_SPARSE}, {"replace", INC_KW_REPLACE}, {"readfifo", INC_KW_READFIFO}, + {"portable", INC_KW_PORTABLE}, + {"mtimeonly", INC_KW_MTIMEONLY}, + {"keepatime", INC_KW_KEEPATIME}, {NULL, 0} }; @@ -140,14 +147,21 @@ static struct s_fs_opt FS_options[] = { {"never", INC_KW_REPLACE, "n"}, {"yes", INC_KW_READFIFO, "r"}, {"no", INC_KW_READFIFO, "0"}, + {"yes", INC_KW_PORTABLE, "p"}, + {"no", INC_KW_PORTABLE, "0"}, + {"yes", INC_KW_MTIMEONLY, "m"}, + {"no", INC_KW_MTIMEONLY, "0"}, + {"yes", INC_KW_KEEPATIME, "k"}, + {"no", INC_KW_KEEPATIME, "0"}, {NULL, 0, 0} }; /* - * Scan for Include options (keyword=option) is converted into one or - * two characters. Verifyopts=xxxx is Vxxxx: + * 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. */ static void scan_include_options(LEX *lc, int keyword, char *opts, int optlen) { @@ -162,6 +176,7 @@ static void scan_include_options(LEX *lc, int keyword, char *opts, int optlen) bstrncat(opts, "V", optlen); /* indicate Verify */ bstrncat(opts, lc->str, optlen); bstrncat(opts, ":", optlen); /* terminate it */ + Dmsg3(100, "Catopts=%s option=%s optlen=%d\n", opts, option,optlen); /* * Standard keyword options for Include/Exclude @@ -180,7 +195,7 @@ static void scan_include_options(LEX *lc, int keyword, char *opts, int optlen) scan_err1(lc, "Expected a FileSet option keyword, got:%s:", lc->str); } else { /* add option */ bstrncat(opts, option, optlen); - Dmsg3(200, "Catopts=%s option=%s optlen=%d\n", opts, option,optlen); + Dmsg3(100, "Catopts=%s option=%s optlen=%d\n", opts, option,optlen); } } @@ -191,7 +206,7 @@ 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) +void store_inc(LEX *lc, RES_ITEM *item, int index, int pass) { int token, i; int options = lc->options; @@ -199,12 +214,26 @@ void store_inc(LEX *lc, struct res_items *item, int index, int pass) char inc_opts[100]; int inc_opts_len; + /* + * Decide if we are doing a new Include or an old include. The + * new Include is followed immediately by {, whereas the + * old include has options following the Include. + */ + token = lex_get_token(lc, T_ALL); + if (token == T_BOB) { + store_newinc(lc, item, index, pass); + return; + } + if (token != T_EQUALS) { + scan_err1(lc, _("Expecting an equals sign, got: %s\n"), lc->str); + } lc->options |= LOPT_NO_IDENT; /* make spaces significant */ memset(&res_incexe, 0, sizeof(INCEXE)); /* Get include options */ inc_opts[0] = 0; while ((token=lex_get_token(lc, T_ALL)) != T_BOB) { + keyword = INC_KW_NONE; for (i=0; FS_option_kw[i].name; i++) { if (strcasecmp(lc->str, FS_option_kw[i].name) == 0) { @@ -219,12 +248,14 @@ void store_inc(LEX *lc, struct res_items *item, int index, int pass) if ((token=lex_get_token(lc, T_ALL)) != T_EQUALS) { scan_err1(lc, _("expected an = following keyword, got: %s"), lc->str); } else { + /* Scan right hand side of option */ scan_include_options(lc, keyword, inc_opts, sizeof(inc_opts)); } if (token == T_BOB) { break; } } + if (!inc_opts[0]) { strcat(inc_opts, "0"); /* set no options */ } @@ -238,7 +269,7 @@ void store_inc(LEX *lc, struct res_items *item, int index, int pass) } setup_current_opts(); bstrncpy(res_incexe.current_opts->opts, inc_opts, MAX_FOPTS); - Dmsg1(200, "incexe opts=%s\n", res_incexe.current_opts->opts); + Dmsg2(100, "old pass=%d incexe opts=%s\n", pass, res_incexe.current_opts->opts); /* Create incexe structure */ Dmsg0(200, "Create INCEXE structure\n"); @@ -250,7 +281,7 @@ void store_inc(LEX *lc, struct res_items *item, int index, int pass) res_all.res_fs.include_items = (INCEXE **)malloc(sizeof(INCEXE *)); } else { res_all.res_fs.include_items = (INCEXE **)realloc(res_all.res_fs.include_items, - sizeof(INCEXE *) * res_all.res_fs.num_includes + 1); + sizeof(INCEXE *) * (res_all.res_fs.num_includes + 1)); } res_all.res_fs.include_items[res_all.res_fs.num_includes++] = incexe; Dmsg1(200, "num_includes=%d\n", res_all.res_fs.num_includes); @@ -259,7 +290,7 @@ void store_inc(LEX *lc, struct res_items *item, int index, int pass) res_all.res_fs.exclude_items = (INCEXE **)malloc(sizeof(INCEXE *)); } else { res_all.res_fs.exclude_items = (INCEXE **)realloc(res_all.res_fs.exclude_items, - sizeof(INCEXE *) * res_all.res_fs.num_excludes + 1); + sizeof(INCEXE *) * (res_all.res_fs.num_excludes + 1)); } res_all.res_fs.exclude_items[res_all.res_fs.num_excludes++] = incexe; Dmsg1(200, "num_excludes=%d\n", res_all.res_fs.num_excludes); @@ -270,34 +301,28 @@ void store_inc(LEX *lc, struct res_items *item, int index, int pass) */ while ((token = lex_get_token(lc, T_ALL)) != T_EOB) { switch (token) { - case T_COMMA: - case T_EOL: - continue; - - case T_IDENTIFIER: - case T_UNQUOTED_STRING: - case T_QUOTED_STRING: - if (res_all.res_fs.have_MD5) { - MD5Update(&res_all.res_fs.md5c, (unsigned char *)lc->str, lc->str_len); - } - if (incexe->num_names == incexe->max_names) { - incexe->max_names += 10; - if (incexe->name_list == NULL) { - incexe->name_list = (char **)malloc(sizeof(char *) * incexe->max_names); - } else { - incexe->name_list = (char **)realloc(incexe->name_list, - sizeof(char *) * incexe->max_names); - } - } - incexe->name_list[incexe->num_names++] = bstrdup(lc->str); - Dmsg1(200, "Add to name_list %s\n", incexe->name_list[incexe->num_names -1]); - break; - default: - scan_err1(lc, "Expected a filename, got: %s", lc->str); + case T_COMMA: + case T_EOL: + continue; + + case T_IDENTIFIER: + case T_UNQUOTED_STRING: + case T_QUOTED_STRING: + if (res_all.res_fs.have_MD5) { + MD5Update(&res_all.res_fs.md5c, (unsigned char *)lc->str, lc->str_len); + } + if (incexe->name_list.size() == 0) { + incexe->name_list.init(10, true); + } + incexe->name_list.append(bstrdup(lc->str)); + Dmsg1(200, "Add to name_list %s\n", lc->str); + break; + default: + scan_err1(lc, "Expected a filename, got: %s", lc->str); } } /* Note, MD5Final is done in backup.c */ - } else { /* pass 1 */ + } else { /* pass 2 */ while (lex_get_token(lc, T_ALL) != T_EOB) {} } @@ -313,17 +338,17 @@ void store_inc(LEX *lc, struct res_items *item, int index, int pass) * resource. We treat the Finclude/Fexeclude like a sort of * mini-resource within the FileSet resource. */ -void store_finc(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; - res_all.res_fs.finclude = TRUE; - token = lex_get_token(lc, T_ALL); - if (token != T_BOB) { - scan_err1(lc, _("Expecting a beginning brace, got: %s\n"), lc->str); + 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; while ((token = lex_get_token(lc, T_ALL)) != T_EOF) { if (token == T_EOL) { continue; @@ -334,14 +359,14 @@ void store_finc(LEX *lc, struct res_items *item, int index, int pass) if (token != T_IDENTIFIER) { scan_err1(lc, _("Expecting keyword, got: %s\n"), lc->str); } - for (i=0; finc_items[i].name; i++) { - if (strcasecmp(finc_items[i].name, lc->str) == 0) { + for (i=0; newinc_items[i].name; i++) { + 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); } /* Call item handler */ - finc_items[i].handler(lc, &finc_items[i], i, pass); + newinc_items[i].handler(lc, &newinc_items[i], i, pass); i = -1; break; } @@ -359,7 +384,7 @@ void store_finc(LEX *lc, struct res_items *item, int index, int pass) res_all.res_fs.include_items = (INCEXE **)malloc(sizeof(INCEXE *)); } else { res_all.res_fs.include_items = (INCEXE **)realloc(res_all.res_fs.include_items, - sizeof(INCEXE *) * res_all.res_fs.num_includes + 1); + sizeof(INCEXE *) * (res_all.res_fs.num_includes + 1)); } res_all.res_fs.include_items[res_all.res_fs.num_includes++] = incexe; Dmsg1(200, "num_includes=%d\n", res_all.res_fs.num_includes); @@ -368,7 +393,7 @@ void store_finc(LEX *lc, struct res_items *item, int index, int pass) res_all.res_fs.exclude_items = (INCEXE **)malloc(sizeof(INCEXE *)); } else { res_all.res_fs.exclude_items = (INCEXE **)realloc(res_all.res_fs.exclude_items, - sizeof(INCEXE *) * res_all.res_fs.num_excludes + 1); + sizeof(INCEXE *) * (res_all.res_fs.num_excludes + 1)); } res_all.res_fs.exclude_items[res_all.res_fs.num_excludes++] = incexe; Dmsg1(200, "num_excludes=%d\n", res_all.res_fs.num_excludes); @@ -380,7 +405,7 @@ void store_finc(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) +static void store_match(LEX *lc, RES_ITEM *item, int index, int pass) { int token; @@ -389,17 +414,14 @@ static void store_match(LEX *lc, struct res_items *item, int index, int pass) */ token = lex_get_token(lc, T_ALL); switch (token) { - case T_IDENTIFIER: - case T_UNQUOTED_STRING: - case T_QUOTED_STRING: - setup_current_opts(); - if (res_incexe.current_opts->match) { - scan_err0(lc, _("More than one match specified.\n")); - } - res_incexe.current_opts->match = bstrdup(lc->str); - break; - default: - scan_err1(lc, _("Expected a filename, got: %s\n"), lc->str); + case T_IDENTIFIER: + case T_UNQUOTED_STRING: + case T_QUOTED_STRING: + setup_current_opts(); + res_incexe.current_opts->match.append(bstrdup(lc->str)); + break; + default: + scan_err1(lc, _("Expected a filename, got: %s\n"), lc->str); } } else { /* pass 2 */ lex_get_token(lc, T_ALL); @@ -408,10 +430,9 @@ 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; - FOPTS *copt; if (pass == 1) { setup_current_opts(); @@ -419,14 +440,7 @@ static void store_base(LEX *lc, struct res_items *item, int index, int pass) * Pickup Base Job Name */ token = lex_get_token(lc, T_NAME); - copt = res_incexe.current_opts; - if (copt->base_list == NULL) { - copt->base_list = (char **)malloc(sizeof(char *)); - } else { - copt->base_list = (char **)realloc(copt->base_list, - sizeof(char *) * (copt->num_base+1)); - } - copt->base_list[copt->num_base++] = bstrdup(lc->str); + res_incexe.current_opts->base_list.append(bstrdup(lc->str)); } else { /* pass 2 */ lex_get_token(lc, T_ALL); } @@ -437,7 +451,7 @@ static void store_base(LEX *lc, struct res_items *item, int index, int pass) * 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; @@ -454,17 +468,11 @@ static void store_fname(LEX *lc, struct res_items *item, int index, int pass) MD5Update(&res_all.res_fs.md5c, (unsigned char *)lc->str, lc->str_len); } incexe = &res_incexe; - if (incexe->num_names == incexe->max_names) { - incexe->max_names += 10; - if (incexe->name_list == NULL) { - incexe->name_list = (char **)malloc(sizeof(char *) * incexe->max_names); - } else { - incexe->name_list = (char **)realloc(incexe->name_list, - sizeof(char *) * incexe->max_names); - } + if (incexe->name_list.size() == 0) { + incexe->name_list.init(10, true); } - incexe->name_list[incexe->num_names++] = bstrdup(lc->str); - Dmsg1(200, "Add to name_list %s\n", incexe->name_list[incexe->num_names -1]); + incexe->name_list.append(bstrdup(lc->str)); + Dmsg1(200, "Add to name_list %s\n", lc->str); break; default: scan_err1(lc, _("Expected a filename, got: %s"), lc->str); @@ -475,8 +483,10 @@ static void store_fname(LEX *lc, struct res_items *item, int index, int pass) scan_to_eol(lc); } - -static void store_opts(LEX *lc, struct res_items *item, int index, int pass) +/* + * New style options come here + */ +static void store_opts(LEX *lc, RES_ITEM *item, int index, int pass) { int i; int keyword; @@ -484,6 +494,7 @@ static void store_opts(LEX *lc, struct res_items *item, int index, int pass) inc_opts[0] = 0; keyword = INC_KW_NONE; + /* Look up the keyword */ for (i=0; FS_option_kw[i].name; i++) { if (strcasecmp(item->name, FS_option_kw[i].name) == 0) { keyword = FS_option_kw[i].token; @@ -493,15 +504,13 @@ static void store_opts(LEX *lc, struct res_items *item, int index, int pass) if (keyword == INC_KW_NONE) { scan_err1(lc, "Expected a FileSet keyword, got: %s", lc->str); } - Dmsg2(200, "keyword=%d %s\n", keyword, FS_option_kw[keyword].name); + /* Now scan for the value */ scan_include_options(lc, keyword, inc_opts, sizeof(inc_opts)); - if (pass == 1) { setup_current_opts(); - - bstrncat(res_incexe.current_opts->opts, inc_opts, MAX_FOPTS); + bstrncpy(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); } @@ -513,6 +522,8 @@ 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; res_incexe.opts_list = (FOPTS **)malloc(sizeof(FOPTS *)); res_incexe.opts_list[0] = res_incexe.current_opts;