X-Git-Url: https://git.sur5r.net/?a=blobdiff_plain;f=bacula%2Fsrc%2Fdird%2Finc_conf.c;h=38adb0b838eba656f05ddb86e172584327d3c3f9;hb=3d52afb93a3d89ac9d5aebf2052fc625a3274b75;hp=2b2629090f9990054dc8309101be20e4aa2a27de;hpb=559973d1f1fca4b48d97c19ba67df325ae050ef4;p=bacula%2Fbacula diff --git a/bacula/src/dird/inc_conf.c b/bacula/src/dird/inc_conf.c index 2b2629090f..38adb0b838 100644 --- a/bacula/src/dird/inc_conf.c +++ b/bacula/src/dird/inc_conf.c @@ -1,43 +1,46 @@ /* - * 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 * * Version $Id$ */ /* - Copyright (C) 2000-2003 Kern Sibbald and John Walker + Copyright (C) 2003-2006 Kern Sibbald This program is free software; you can redistribute it and/or - modify it under the terms of the GNU General Public License as - published by the Free Software Foundation; either version 2 of - the License, or (at your option) any later version. + modify it under the terms of the GNU General Public License + version 2 as amended with additional clauses defined in the + file LICENSE in the main source directory. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - General Public License for more details. - - You should have received a copy of the GNU General Public - License along with this program; if not, write to the Free - Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, - MA 02111-1307, USA. + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + the file LICENSE for additional details. */ #include "bacula.h" #include "dird.h" +#ifdef HAVE_REGEX_H +#include +#endif /* 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); - -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); +void store_inc(LEX *lc, RES_ITEM *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_fstype(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 store_reader(LEX *lc, RES_ITEM *item, int index, int pass); +static void store_writer(LEX *lc, RES_ITEM *item, int index, int pass); static void setup_current_opts(void); @@ -49,77 +52,121 @@ 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 - * name handler value code flags default_value +/* + * new Include/Exclude items + * name handler value code flags default_value */ -static struct res_items finc_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}, {"onefs", store_opts, NULL, 0, 0, 0}, {"recurse", store_opts, NULL, 0, 0, 0}, {"sparse", store_opts, NULL, 0, 0, 0}, + {"hardlinks", 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}, + {"mtimeonly", store_opts, NULL, 0, 0, 0}, + {"keepatime", store_opts, NULL, 0, 0, 0}, + {"regex", store_regex, NULL, 0, 0, 0}, + {"regexdir", store_regex, NULL, 1, 0, 0}, + {"regexfile", store_regex, NULL, 2, 0, 0}, {"base", store_base, NULL, 0, 0, 0}, - {NULL, NULL, NULL, 0, 0, 0} + {"wild", store_wild, NULL, 0, 0, 0}, + {"wilddir", store_wild, NULL, 1, 0, 0}, + {"wildfile", store_wild, NULL, 2, 0, 0}, + {"exclude", store_opts, NULL, 0, 0, 0}, + {"aclsupport", store_opts, NULL, 0, 0, 0}, + {"reader", store_reader, NULL, 0, 0, 0}, + {"writer", store_writer, NULL, 0, 0, 0}, + {"ignorecase", store_opts, NULL, 0, 0, 0}, + {"fstype", store_fstype, NULL, 0, 0, 0}, + {"hfsplussupport", store_opts, NULL, 0, 0, 0}, + {NULL, NULL, NULL, 0, 0, 0} }; + /* Define FileSet KeyWord values */ +enum { + INC_KW_NONE, + INC_KW_COMPRESSION, + INC_KW_DIGEST, + INC_KW_ENCRYPTION, + INC_KW_VERIFY, + INC_KW_ONEFS, + INC_KW_RECURSE, + INC_KW_SPARSE, + INC_KW_HARDLINK, + 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, + INC_KW_ACL, + INC_KW_IGNORECASE, + INC_KW_HFSPLUS +}; -#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 - -/* Include keywords -- these are keywords that can appear - * in the options lists of an include ( Include = compression= ...) +/* + * This is the list of options that can be stored by store_opts + * Note, now that the old style Include/Exclude code is gone, + * the INC_KW code could be put into the "code" field of the + * options given above. */ static struct s_kw FS_option_kw[] = { {"compression", INC_KW_COMPRESSION}, - {"signature", INC_KW_SIGNATURE}, + {"signature", INC_KW_DIGEST}, {"encryption", INC_KW_ENCRYPTION}, {"verify", INC_KW_VERIFY}, {"onefs", INC_KW_ONEFS}, {"recurse", INC_KW_RECURSE}, {"sparse", INC_KW_SPARSE}, + {"hardlinks", INC_KW_HARDLINK}, {"replace", INC_KW_REPLACE}, {"readfifo", INC_KW_READFIFO}, {"portable", INC_KW_PORTABLE}, - {NULL, 0} + {"mtimeonly", INC_KW_MTIMEONLY}, + {"keepatime", INC_KW_KEEPATIME}, + {"exclude", INC_KW_EXCLUDE}, + {"aclsupport", INC_KW_ACL}, + {"ignorecase", INC_KW_IGNORECASE}, + {"hfsplussupport", INC_KW_HFSPLUS}, + {NULL, 0} }; /* Options for FileSet keywords */ struct s_fs_opt { - char *name; + const char *name; int keyword; - char *option; + const char *option; }; /* - * Options permitted for each keyword and resulting value. + * Options permitted for each keyword and resulting value. * The output goes into opts, which are then transmitted to * the FD for application as options to the following list of * included files. */ static struct s_fs_opt FS_options[] = { - {"md5", INC_KW_SIGNATURE, "M"}, - {"sha1", INC_KW_SIGNATURE, "S"}, + {"md5", INC_KW_DIGEST, "M"}, + {"sha1", INC_KW_DIGEST, "S"}, + {"sha256", INC_KW_DIGEST, "S2"}, + {"sha512", INC_KW_DIGEST, "S3"}, {"gzip", INC_KW_COMPRESSION, "Z6"}, {"gzip1", INC_KW_COMPRESSION, "Z1"}, {"gzip2", INC_KW_COMPRESSION, "Z2"}, @@ -138,6 +185,8 @@ static struct s_fs_opt FS_options[] = { {"no", INC_KW_RECURSE, "h"}, {"yes", INC_KW_SPARSE, "s"}, {"no", INC_KW_SPARSE, "0"}, + {"yes", INC_KW_HARDLINK, "0"}, + {"no", INC_KW_HARDLINK, "H"}, {"always", INC_KW_REPLACE, "a"}, {"ifnewer", INC_KW_REPLACE, "w"}, {"never", INC_KW_REPLACE, "n"}, @@ -145,49 +194,67 @@ static struct s_fs_opt FS_options[] = { {"no", INC_KW_READFIFO, "0"}, {"yes", INC_KW_PORTABLE, "p"}, {"no", INC_KW_PORTABLE, "0"}, - {NULL, 0, 0} + {"yes", INC_KW_MTIMEONLY, "m"}, + {"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"}, + {"yes", INC_KW_ACL, "A"}, + {"no", INC_KW_ACL, "0"}, + {"yes", INC_KW_IGNORECASE, "i"}, + {"no", INC_KW_IGNORECASE, "0"}, + {"yes", INC_KW_HFSPLUS, "R"}, /* "R" for resource fork */ + {"no", INC_KW_HFSPLUS, "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. + * This code is also used inside an Options resource. */ static void scan_include_options(LEX *lc, int keyword, char *opts, int optlen) { int token, i; char option[3]; + int lcopts = lc->options; - option[0] = 0; /* default option = none */ - option[2] = 0; /* terminate options */ - token = lex_get_token(lc, T_NAME); /* expect at least one option */ + option[0] = 0; /* default option = none */ + option[2] = 0; /* terminate options */ + lc->options |= LOPT_STRING; /* force string */ + token = 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 */ 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); /* - * Standard keyword options for Include/Exclude + * Standard keyword options for Include/Exclude */ } else { for (i=0; FS_options[i].name; i++) { - if (strcasecmp(lc->str, FS_options[i].name) == 0 && FS_options[i].keyword == keyword) { - /* NOTE! maximum 2 letters here or increase option[3] */ - option[0] = FS_options[i].option[0]; - option[1] = FS_options[i].option[1]; - i = 0; - break; - } + if (strcasecmp(lc->str, FS_options[i].name) == 0 && FS_options[i].keyword == keyword) { + /* NOTE! maximum 2 letters here or increase option[3] */ + option[0] = FS_options[i].option[0]; + option[1] = FS_options[i].option[1]; + i = 0; + break; + } } 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(200, "Catopts=%s option=%s optlen=%d\n", opts, option,optlen); + 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 (lc->ch == ',') { @@ -195,168 +262,72 @@ 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 + * NEW style includes are handled in store_newinc() + */ +void store_inc(LEX *lc, RES_ITEM *item, int index, int pass) { - int token, i; - int options = lc->options; - int keyword; - char inc_opts[100]; - int inc_opts_len; - - 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) { - keyword = FS_option_kw[i].token; - break; - } - } - if (keyword == INC_KW_NONE) { - scan_err1(lc, _("Expected a FileSet keyword, got: %s"), lc->str); - } - /* Option keyword should be following by =