+/*
+ Bacula® - The Network Backup Solution
+
+ Copyright (C) 2000-2007 Free Software Foundation Europe e.V.
+
+ 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 two of the GNU General Public
+ License as published by the Free Software Foundation plus additions
+ that are listed 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
+ 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., 51 Franklin Street, Fifth Floor, Boston, MA
+ 02110-1301, USA.
+
+ Bacula® is a registered trademark of John Walker.
+ 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
*
* Version $Id$
*/
-/*
- Copyright (C) 2003-2005 Kern Sibbald
-
- This program is free software; you can redistribute it and/or
- 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
- the file LICENSE for additional details.
-
- */
#include "bacula.h"
#include "dird.h"
-#ifdef HAVE_REGEX_H
+#ifndef HAVE_REGEX_H
+#include "lib/bregex.h"
+#else
#include <regex.h>
#endif
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_fname(LEX *lc, RES_ITEM *item, int index, int pass);
static void options_res(LEX *lc, RES_ITEM *item, int index, int pass);
* 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;
+#endif
extern int res_all_size;
/* We build the current new Include and Exclude items here */
* name handler value code flags default_value
*/
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}
+ {"file", store_fname, {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, 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},
- {"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},
- {"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}
+ {"compression", store_opts, {0}, 0, 0, 0},
+ {"signature", 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},
+ {"reader", store_reader, {0}, 0, 0, 0},
+ {"writer", store_writer, {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},
+ {NULL, NULL, {0}, 0, 0, 0}
};
enum {
INC_KW_NONE,
INC_KW_COMPRESSION,
- INC_KW_SIGNATURE,
+ INC_KW_DIGEST,
INC_KW_ENCRYPTION,
INC_KW_VERIFY,
INC_KW_ONEFS,
INC_KW_EXCLUDE,
INC_KW_ACL,
INC_KW_IGNORECASE,
- INC_KW_HFSPLUS
+ INC_KW_HFSPLUS,
+ INC_KW_NOATIME,
+ INC_KW_ENHANCEDWILD
};
/*
*/
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},
{"aclsupport", INC_KW_ACL},
{"ignorecase", INC_KW_IGNORECASE},
{"hfsplussupport", INC_KW_HFSPLUS},
+ {"noatime", INC_KW_NOATIME},
+ {"enhancedwild", INC_KW_ENHANCEDWILD},
{NULL, 0}
};
* 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"},
{"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"},
{NULL, 0, 0}
};
*/
} else {
for (i=0; FS_options[i].name; i++) {
- if (strcasecmp(lc->str, FS_options[i].name) == 0 && FS_options[i].keyword == keyword) {
+ 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];
res_incexe.current_opts->wilddir.append(bstrdup(lc->str));
newsize = res_incexe.current_opts->wilddir.size();
} else if (item->code == 2) {
- type = "wildfile";
- res_incexe.current_opts->wildfile.append(bstrdup(lc->str));
- newsize = res_incexe.current_opts->wildfile.size();
+ if (strpbrk(lc->str, "/\\") != NULL) {
+ type = "wildfile";
+ res_incexe.current_opts->wildfile.append(bstrdup(lc->str));
+ newsize = res_incexe.current_opts->wildfile.size();
+ } else {
+ type = "wildbase";
+ res_incexe.current_opts->wildbase.append(bstrdup(lc->str));
+ newsize = res_incexe.current_opts->wildbase.size();
+ }
} else {
type = "wild";
res_incexe.current_opts->wild.append(bstrdup(lc->str));
scan_to_eol(lc);
}
+/* Store drivetype info */
+static void store_drivetype(LEX *lc, RES_ITEM *item, int index, int pass)
+{
+ int token;
+
+ token = lex_get_token(lc, T_SKIP_EOL);
+ if (pass == 1) {
+ /* Pickup drivetype string */
+ switch (token) {
+ case T_IDENTIFIER:
+ case T_UNQUOTED_STRING:
+ case T_QUOTED_STRING:
+ res_incexe.current_opts->drivetype.append(bstrdup(lc->str));
+ Dmsg3(900, "set drivetype %p size=%d %s\n",
+ res_incexe.current_opts, res_incexe.current_opts->drivetype.size(), lc->str);
+ break;
+ default:
+ scan_err1(lc, _("Expected an drivetype string, got: %s\n"), lc->str);
+ }
+ }
+ scan_to_eol(lc);
+}
+
/*
* Store Filename info. Note, for minor efficiency reasons, we
* always increase the name buffer by 10 items because we expect
/* Pickup Filename string
*/
switch (token) {
- 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);
- }
- incexe = &res_incexe;
- if (incexe->name_list.size() == 0) {
- incexe->name_list.init(10, true);
- }
- incexe->name_list.append(bstrdup(lc->str));
- Dmsg1(900, "Add to name_list %s\n", lc->str);
- break;
- default:
- scan_err1(lc, _("Expected a filename, got: %s"), lc->str);
+ case T_IDENTIFIER:
+ case T_UNQUOTED_STRING:
+ if (strchr(lc->str, '\\')) {
+ scan_err1(lc, _("Backslash found. Use forward slashes or quote the string.: %s\n"), lc->str);
+ /* NOT REACHED */
+ }
+ case T_QUOTED_STRING:
+ if (res_all.res_fs.have_MD5) {
+ MD5Update(&res_all.res_fs.md5c, (unsigned char *)lc->str, lc->str_len);
+ }
+ incexe = &res_incexe;
+ if (incexe->name_list.size() == 0) {
+ incexe->name_list.init(10, true);
+ }
+ incexe->name_list.append(bstrdup(lc->str));
+ Dmsg1(900, "Add to name_list %s\n", lc->str);
+ break;
+ default:
+ scan_err1(lc, _("Expected a filename, got: %s"), lc->str);
}
}
scan_to_eol(lc);
fo->wild.init(1, true);
fo->wilddir.init(1, true);
fo->wildfile.init(1, true);
+ fo->wildbase.init(1, true);
fo->base.init(1, true);
fo->fstype.init(1, true);
+ fo->drivetype.init(1, true);
res_incexe.current_opts = fo;
if (res_incexe.num_opts == 0) {
res_incexe.opts_list = (FOPTS **)malloc(sizeof(FOPTS *));