X-Git-Url: https://git.sur5r.net/?a=blobdiff_plain;f=bacula%2Fsrc%2Fdird%2Finc_conf.c;h=7df0be1a49a6517dcc2906fa87d0ef7eb9392316;hb=9a3364827b9ac8d05ba038e24226d41e2cd0f0d6;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..7df0be1a49 100644 --- a/bacula/src/dird/inc_conf.c +++ b/bacula/src/dird/inc_conf.c @@ -1,125 +1,223 @@ /* - * Configuration file parser for Include, Exclude, Finclude - * and FExclude records. - * - * Kern Sibbald, March MMIII - * - * Version $Id$ - */ -/* - Copyright (C) 2000-2003 Kern Sibbald and John Walker + Bacula® - The Network Backup Solution + + Copyright (C) 2000-2009 Free Software Foundation Europe e.V. - 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. + The main author of Bacula is Kern Sibbald, with contributions from + many others, a complete list can be found in the file AUTHORS. + This program is Free Software; you can redistribute it and/or + modify it under the terms of version three of the GNU Affero General Public + License as published by the Free Software Foundation and included + in the file LICENSE. - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of + 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. + You should have received a copy of the GNU Affero General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA + 02110-1301, USA. + Bacula® is a registered trademark of Kern Sibbald. + The licensor of Bacula is the Free Software Foundation Europe + (FSFE), Fiduciary Program, Sumatrastrasse 25, 8006 Zürich, + Switzerland, email:ftf@fsfeurope.org. +*/ +/* + * Configuration file parser for new and old Include and + * Exclude records + * + * Kern Sibbald, March MMIII + * + * Version $Id$ */ #include "bacula.h" #include "dird.h" +#ifndef HAVE_REGEX_H +#include "lib/bregex.h" +#else +#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); +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_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_drivetype(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_base(LEX *lc, RES_ITEM *item, int index, int pass); +static void store_plugin(LEX *lc, RES_ITEM *item, int index, int pass); static void setup_current_opts(void); +/* Include and Exclude items */ +static void store_fname(LEX *lc, RES_ITEM2 *item, int index, int pass, bool exclude); +static void store_plugin_name(LEX *lc, RES_ITEM2 *item, int index, int pass, bool exclude); +static void options_res(LEX *lc, RES_ITEM2 *item, int index, int pass, bool exclude); +static void store_excludedir(LEX *lc, RES_ITEM2 *item, int index, int pass, bool exclude); + /* We build the current resource here as we are * scanning the resource configuration definition, * then move it to allocated memory when the resource * scan is complete. */ +#if defined(_MSC_VER) +extern "C" { // work around visual compiler mangling variables + extern URES res_all; +} +#else extern URES res_all; -extern int res_all_size; +#endif +extern int32_t 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[] = { - {"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}, - {"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}, - {NULL, NULL, NULL, 0, 0, 0} +static RES_ITEM2 newinc_items[] = { + {"file", store_fname, {0}, 0, 0, 0}, + {"plugin", store_plugin_name, {0}, 0, 0, 0}, + {"excludedircontaining", store_excludedir, {0}, 0, 0, 0}, + {"options", options_res, {0}, 0, 0, 0}, + {NULL, NULL, {0}, 0, 0, 0} }; +/* + * Items that are valid in an Options resource + */ +static RES_ITEM options_items[] = { + {"compression", store_opts, {0}, 0, 0, 0}, + {"signature", store_opts, {0}, 0, 0, 0}, + {"basejob", store_opts, {0}, 0, 0, 0}, + {"accurate", store_opts, {0}, 0, 0, 0}, + {"verify", store_opts, {0}, 0, 0, 0}, + {"onefs", store_opts, {0}, 0, 0, 0}, + {"recurse", store_opts, {0}, 0, 0, 0}, + {"sparse", store_opts, {0}, 0, 0, 0}, + {"hardlinks", store_opts, {0}, 0, 0, 0}, + {"readfifo", store_opts, {0}, 0, 0, 0}, + {"replace", store_opts, {0}, 0, 0, 0}, + {"portable", store_opts, {0}, 0, 0, 0}, + {"mtimeonly", store_opts, {0}, 0, 0, 0}, + {"keepatime", store_opts, {0}, 0, 0, 0}, + {"regex", store_regex, {0}, 0, 0, 0}, + {"regexdir", store_regex, {0}, 1, 0, 0}, + {"regexfile", store_regex, {0}, 2, 0, 0}, + {"base", store_base, {0}, 0, 0, 0}, + {"wild", store_wild, {0}, 0, 0, 0}, + {"wilddir", store_wild, {0}, 1, 0, 0}, + {"wildfile", store_wild, {0}, 2, 0, 0}, + {"exclude", store_opts, {0}, 0, 0, 0}, + {"aclsupport", store_opts, {0}, 0, 0, 0}, + {"plugin", store_plugin, {0}, 0, 0, 0}, + {"ignorecase", store_opts, {0}, 0, 0, 0}, + {"fstype", store_fstype, {0}, 0, 0, 0}, + {"hfsplussupport", store_opts, {0}, 0, 0, 0}, + {"noatime", store_opts, {0}, 0, 0, 0}, + {"enhancedwild", store_opts, {0}, 0, 0, 0}, + {"drivetype", store_drivetype, {0}, 0, 0, 0}, + {"checkfilechanges",store_opts, {0}, 0, 0, 1}, + {"strippath", store_opts, {0}, 0, 0, 0}, + {"honornodumpflag", store_opts, {0}, 0, 0, 0}, + {"xattrsupport", store_opts, {0}, 0, 0, 0}, + {NULL, NULL, {0}, 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_BASEJOB, + INC_KW_ACCURATE, + 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, + INC_KW_NOATIME, + INC_KW_ENHANCEDWILD, + INC_KW_CHKCHANGES, + INC_KW_STRIPPATH, + INC_KW_HONOR_NODUMP, + INC_KW_XATTR +}; -#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}, + {"basejob", INC_KW_BASEJOB}, + {"accurate", INC_KW_ACCURATE}, {"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}, + {"noatime", INC_KW_NOATIME}, + {"enhancedwild", INC_KW_ENHANCEDWILD}, + {"checkfilechanges", INC_KW_CHKCHANGES}, + {"strippath", INC_KW_STRIPPATH}, + {"honornodumpflag", INC_KW_HONOR_NODUMP}, + {"xattrsupport", INC_KW_XATTR}, + {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"}, @@ -130,6 +228,7 @@ static struct s_fs_opt FS_options[] = { {"gzip7", INC_KW_COMPRESSION, "Z7"}, {"gzip8", INC_KW_COMPRESSION, "Z8"}, {"gzip9", INC_KW_COMPRESSION, "Z9"}, + {"lzo", INC_KW_COMPRESSION, "Zo"}, {"blowfish", INC_KW_ENCRYPTION, "B"}, /* ***FIXME*** not implemented */ {"3des", INC_KW_ENCRYPTION, "3"}, /* ***FIXME*** not implemented */ {"yes", INC_KW_ONEFS, "0"}, @@ -138,6 +237,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,218 +246,169 @@ 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"}, + {"yes", INC_KW_NOATIME, "K"}, + {"no", INC_KW_NOATIME, "0"}, + {"yes", INC_KW_ENHANCEDWILD, "K"}, + {"no", INC_KW_ENHANCEDWILD, "0"}, + {"yes", INC_KW_CHKCHANGES, "c"}, + {"no", INC_KW_CHKCHANGES, "0"}, + {"yes", INC_KW_HONOR_NODUMP, "N"}, + {"no", INC_KW_HONOR_NODUMP, "0"}, + {"yes", INC_KW_XATTR, "X"}, + {"no", INC_KW_XATTR, "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; + int 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 */ + 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); + } else if (keyword == INC_KW_ACCURATE) { /* special case */ + /* ***FIXME**** ensure these are in permitted set */ + 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 */ + 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) { /* another special case */ + if (!is_an_integer(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); /* - * 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 (FS_options[i].keyword == keyword && strcasecmp(lc->str, FS_options[i].name) == 0) { + /* 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 == ',') { - token = lex_get_token(lc, T_ALL); /* yes, eat comma */ + lex_get_token(lc, T_ALL); /* yes, eat comma */ } } -/* 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 =