From 7ac5e4328e2037aad11014457a03d5f86b1f60ae Mon Sep 17 00:00:00 2001 From: Eric Bollengier Date: Tue, 24 Apr 2007 20:08:06 +0000 Subject: [PATCH] ebl commit file relocation to trunk git-svn-id: https://bacula.svn.sourceforge.net/svnroot/bacula/trunk@4623 91ce42f0-d328-0410-95d8-f526ca767f89 --- bacula/patches/testing/breg.c | 458 ------------ bacula/patches/testing/breg.h | 120 --- bacula/patches/testing/bregtest.c | 162 ---- bacula/patches/testing/file_relocation.patch | 738 ------------------- 4 files changed, 1478 deletions(-) delete mode 100644 bacula/patches/testing/breg.c delete mode 100644 bacula/patches/testing/breg.h delete mode 100644 bacula/patches/testing/bregtest.c delete mode 100644 bacula/patches/testing/file_relocation.patch diff --git a/bacula/patches/testing/breg.c b/bacula/patches/testing/breg.c deleted file mode 100644 index 6c9a4ef560..0000000000 --- a/bacula/patches/testing/breg.c +++ /dev/null @@ -1,458 +0,0 @@ -/* - * Manipulation routines for BREGEXP list - * - * Eric Bollengier, March 2007 - * - * Version $Id$ - * - */ -/* - BaculaÂ® - The Network Backup Solution - - Copyright (C) 2006-2006 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. -*/ - - -#include "bacula.h" - -#include "breg.h" -#include "mem_pool.h" - -BREGEXP *new_bregexp(const char *motif) -{ - Dmsg0(500, "bregexp: creating new bregexp object\n"); - BREGEXP *self = (BREGEXP *)bmalloc(sizeof(BREGEXP)); - memset(self, 0, sizeof(BREGEXP)); - - if (!self->extract_regexp(motif)) { - Dmsg0(100, "bregexp: extract_regexp error\n"); - free_bregexp(self); - return NULL; - } - - self->result = get_pool_memory(PM_FNAME); - self->result[0] = '\0'; - -#ifdef HAVE_REGEX_H - /* TODO: que devient cette memoire... */ - self->_regs_match = (int *) bmalloc (2*RE_NREGS * sizeof(int)); - - self->regs.num_regs = RE_NREGS; - self->regs.start = self->_regs_match; - self->regs.end = self->_regs_match+(RE_NREGS * sizeof(int)); -#endif - - return self; -} - -void free_bregexp(BREGEXP *self) -{ - Dmsg0(500, "bregexp: freeing BREGEXP object\n"); - - if (!self) { - return; - } - - if (self->expr) { - bfree(self->expr); - } - if (self->result) { - free_pool_memory(self->result); - } - if (self->_regs_match) { - bfree(self->_regs_match); - } - - regfree(&self->preg); - bfree(self); -} - -/* Free a bregexps alist - */ -void free_bregexps(alist *bregexps) -{ - Dmsg0(500, "bregexp: freeing all BREGEXP object\n"); - - BREGEXP *elt; - foreach_alist(elt, bregexps) { - free_bregexp(elt); - } -} - -/* Apply all regexps to fname - */ -bool apply_bregexps(const char *fname, alist *bregexps, char **result) -{ - BREGEXP *elt; - bool ok=false; - - char *ret = (char *) fname; - foreach_alist(elt, bregexps) { - ret = elt->replace(ret); - ok = ok || elt->success; - } - Dmsg2(500, "bregexp: fname=%s ret=%s\n", fname, ret); - - *result = ret; - return ok; -} - -/* return an alist of BREGEXP or return NULL if it's not a - * where=!tmp!opt!ig,!temp!opt!i - */ -alist *get_bregexps(const char *where) -{ - char *p = (char *)where; - alist *list = New(alist(10, not_owned_by_alist)); - BREGEXP *reg; - - reg = new_bregexp(p); - - while(reg) { - p = reg->eor; - list->append(reg); - reg = new_bregexp(p); - } - - if (list->size()) { - return list; - } else { - delete list; - return NULL; - } -} - -bool BREGEXP::extract_regexp(const char *motif) -{ - if ( !motif ) { - return false; - } - - char sep = motif[0]; - - if (!(sep == '!' || - sep == ':' || - sep == ';' || - sep == '|' || - sep == ',' || - sep == '&' || - sep == '%' || - sep == '=' || - sep == '~' || - sep == '/' || - sep == '#' )) - { - return false; - } - - char *search = (char *) motif + 1; - int options = REG_EXTENDED | REG_NEWLINE; - bool ok = false; - - /* extract 1st part */ - char *dest = expr = bstrdup(motif); - - while (*search && !ok) { - if (search[0] == '\\' && search[1] == sep) { - *dest++ = *++search; /* we skip separator */ - - } else if (search[0] == '\\' && search[1] == '\\') { - *dest++ = *++search; /* we skip the second \ */ - - } else if (*search == sep) { /* we found end of expression */ - *dest++ = '\0'; - - if (subst) { /* already have found motif */ - ok = true; - - } else { - *dest++ = *++search; /* we skip separator */ - subst = dest; /* get replaced string */ - } - - } else { - *dest++ = *search++; - } - } - *dest = '\0'; /* in case of */ - - if (!ok || !subst) { - /* bad regexp */ - return false; - } - - ok = false; - /* find options */ - while (*search && !ok) { - if (*search == 'i') { - options |= REG_ICASE; - - } else if (*search == 'g') { - /* recherche multiple*/ - - } else if (*search == sep) { - /* skip separator */ - - } else { /* end of options */ - ok = true; - } - search++; - } - - int rc = regcomp(&preg, expr, options); - if (rc != 0) { - char prbuf[500]; - regerror(rc, &preg, prbuf, sizeof(prbuf)); - Dmsg1(100, "bregexp: compile error: %s\n", prbuf); - return false; - } - - eor = search; /* useful to find the next regexp in where */ - - return true; -} - -#ifndef HAVE_REGEX_H - #define BREGEX_CAST unsigned -#else - #define BREGEX_CAST const -#endif - -/* return regexp->result */ -char *BREGEXP::replace(const char *fname) -{ - success = false; /* use this.success to known if it's ok */ - int flen = strlen(fname); -#ifndef HAVE_REGEX_H - int i; - check_pool_memory_size(lcase, flen); - for(i=0; fname[i] ; i++) { - lcase[i] = tolower(fname[i]); - } - lcase[i] = '\0'; - int rc = re_search(&preg, (BREGEX_CAST char*) lcase, flen, 0, flen, ®s); -#else - int rc = re_search(&preg, (BREGEX_CAST char*) fname, flen, 0, flen, ®s); -#endif - - if (rc < 0) { - Dmsg0(500, "bregexp: regex mismatch\n"); - return return_fname(fname, flen); - } - - int len = compute_dest_len(fname, ®s); - - if (len) { - result = check_pool_memory_size(result, len); - edit_subst(fname, ®s); - success = true; - Dmsg2(500, "bregexp: len = %i, result_len = %i\n", len, strlen(result)); - - } else { /* error in substitution */ - Dmsg0(100, "bregexp: error in substitution\n"); - return return_fname(fname, flen); - } - - return result; -} - -char *BREGEXP::return_fname(const char *fname, int len) -{ - result = check_pool_memory_size(result, len+1); - strcpy(result,fname); - return result; -} - -int BREGEXP::compute_dest_len(const char *fname, struct re_registers *regs) -{ - int len=0; - char *p; - char *psubst = subst; - int no; - - if (!fname || !regs) { - return 0; - } - - /* match failed ? */ - if (regs->start[0] < 0) { - return 0; - } - - for (p = psubst++; *p ; p = psubst++) { - /* match $1 \1 back references */ - if ((*p == '$' || *p == '\\') && ('0' <= *psubst && *psubst <= '9')) { - no = *psubst++ - '0'; - - /* we check if the back reference exists */ - /* references can not match if we are using (..)? */ - - if (regs->start[no] >= 0 && regs->end[no] >= 0) { - len += regs->end[no] - regs->start[no]; - } - - } else { - len++; - } - } - - /* $0 is replaced by subst */ - len -= regs->end[0] - regs->start[0]; - len += strlen(fname) + 1; - - return len; -} - -char *BREGEXP::edit_subst(const char *fname, struct re_registers *regs) -{ - int i; - char *p; - char *psubst = subst; - int no; - int len; - - /* il faut recopier fname dans dest - * on recopie le debut fname -> regs->start[0] - */ - - for (i = 0; i < regs->start[0] ; i++) { - result[i] = fname[i]; - } - - /* on recopie le motif de remplacement (avec tous les $x) */ - - for (p = psubst++; *p ; p = psubst++) { - /* match $1 \1 back references */ - if ((*p == '$' || *p == '\\') && ('0' <= *psubst && *psubst <= '9')) { - no = *psubst++ - '0'; - - /* have a back reference ? */ - if (regs->start[no] >= 0 && regs->end[no] >= 0) { - len = regs->end[no] - regs->start[no]; - bstrncpy(result + i, fname + regs->start[no], len + 1); - i += len ; - } - - } else { - result[i++] = *p; - } - } - - /* we copy what is out of the match */ - strcpy(result + i, fname + regs->end[0]); - - return result; -} - -/* escape sep char and \ - * dest must be long enough (src*2+1) - * return end of the string */ -char *bregexp_escape_string(char *dest, char *src, char sep) -{ - char *ret = dest; - while (*src) - { - if (*src == sep) { - *dest++ = '\\'; - } else if (*src == '\\') { - *dest++ = '\\'; - } - *dest++ = *src++; - } - *dest = '\0'; - - return ret; -} - -static char regexp_sep = '!'; -static char *str_strip_prefix = "!%s!!i"; -static char *str_add_prefix = "!^!%s!"; -static char *str_add_suffix = "!([^/])$!$1%s!"; - -int bregexp_get_build_where_size(char *strip_prefix, - char *add_prefix, - char *add_suffix) -{ - int str_size = ((strip_prefix?strlen(strip_prefix)+strlen(str_strip_prefix):0) + - (add_prefix?strlen(add_prefix)+strlen(str_add_prefix) :0) + - (add_suffix?strlen(add_suffix)+strlen(str_add_suffix) :0) ) - /* escape + 3*, + \0 */ - * 2 + 3 + 1; - - Dmsg1(1, "bregexp_get_build_where_size = %i\n", str_size); - return str_size; -} - -/* build a regexp string with user arguments - * Usage : - * - * int len = bregexp_get_build_where_size(a,b,c) ; - * char *dest = (char *) bmalloc (len * sizeof(char)); - * bregexp_build_where(dest, len, a, b, c); - * bfree(dest); - * - */ -char *bregexp_build_where(char *dest, int str_size, - char *strip_prefix, - char *add_prefix, - char *add_suffix) -{ - int len=0; - - POOLMEM *str_tmp = get_memory(str_size); - - *str_tmp = *dest = '\0'; - - if (strip_prefix) { - len += bsnprintf(dest, str_size - len, str_strip_prefix, - bregexp_escape_string(str_tmp, strip_prefix, regexp_sep)); - } - - if (add_suffix) { - if (len) dest[len++] = ','; - - len += bsnprintf(dest + len, str_size - len, str_add_suffix, - bregexp_escape_string(str_tmp, add_suffix, regexp_sep)); - } - - if (add_prefix) { - if (len) dest[len++] = ','; - - len += bsnprintf(dest + len, str_size - len, str_add_prefix, - bregexp_escape_string(str_tmp, add_prefix, regexp_sep)); - } - - free_pool_memory(str_tmp); - - return dest; -} - - -void BREGEXP::debug() -{ - printf("expr=[%s]\n", expr); - printf("subst=[%s]\n", subst); - printf("result=%s\n", NPRT(result)); -} diff --git a/bacula/patches/testing/breg.h b/bacula/patches/testing/breg.h deleted file mode 100644 index fa639f17a8..0000000000 --- a/bacula/patches/testing/breg.h +++ /dev/null @@ -1,120 +0,0 @@ -/* - * Bacula BREGEXP Structure definition for FileDaemon - * Eric Bollengier March 2007 - * Version $Id$ - */ -/* - Bacula® - The Network Backup Solution - - Copyright (C) 2006-2006 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. -*/ - - -#ifndef __BREG_H_ -#define __BREG_H_ 1 - -//#undef HAVE_REGEX_H - -#ifndef HAVE_REGEX_H -#include "bregex.h" -#else -#include -#endif - -/* Usage: - * - * #include "lib/breg.h" - * - * BREGEXP *breg = new_bregexp("!/prod!/test!"); - * char *filename = breg->replace("/prod/data.dat"); - * or - * char *filename = breg->result; - * free_bregexp(breg); - */ - -/* - * Structure for BREGEXP ressource - */ -class BREGEXP { -public: - POOLMEM *result; /* match result */ - bool success; /* match is ok */ - - char *replace(const char *fname); /* return this.result */ - void debug(); - - /* private */ - POOLMEM *expr; /* search epression */ - POOLMEM *subst; /* substitution */ - POOLMEM *lcase; /* fname in lower case when using bregexp.c */ - regex_t preg; /* regex_t result of regcomp() */ - struct re_registers regs; /* contains match */ - char *eor; /* end of regexp in expr */ - - int *_regs_match; - - char *return_fname(const char *fname, int len); /* return fname as result */ - char *edit_subst(const char *fname, struct re_registers *regs); - int compute_dest_len(const char *fname, struct re_registers *regs); - bool extract_regexp(const char *motif); -}; - -/* create new BREGEXP and compile regex_t */ -BREGEXP *new_bregexp(const char *motif); - -/* launch each bregexp on filename */ -int run_bregexp(alist *bregexps, const char *fname); - -/* free BREGEXP (and all POOLMEM) */ -void free_bregexp(BREGEXP *script); - -/* fill an alist with BREGEXP from where */ -alist *get_bregexps(const char *where); - -/* apply every regexps from the alist */ -bool apply_bregexps(const char *fname, alist *bregexps, char **result); - -/* foreach_alist free RUNSCRIPT */ -void free_bregexps(alist *bregexps); /* you have to free alist */ - -/* get regexp size */ -int bregexp_get_build_where_size(char *strip_prefix, - char *add_prefix, - char *add_suffix); - -/* get a bregexp string from user arguments - * you must allocate it with bregexp_get_build_where_size(); - */ -char *bregexp_build_where(char *dest, int str_size, - char *strip_prefix, - char *add_prefix, - char *add_suffix); - -/* escape a string to regexp format (sep and \) - * dest must be long enough (dest = 2*src + 1) - */ -char *bregexp_escape_string(char *dest, char *src, char sep); - -#endif /* __BREG_H_ */ diff --git a/bacula/patches/testing/bregtest.c b/bacula/patches/testing/bregtest.c deleted file mode 100644 index 52073ea00f..0000000000 --- a/bacula/patches/testing/bregtest.c +++ /dev/null @@ -1,162 +0,0 @@ -/* - * Test program for testing regular expressions. - * - * Kern Sibbald, MMVI - * - */ -/* - BaculaÂ® - The Network Backup Solution - - Copyright (C) 2006-2006 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. -*/ - -/* - * If you define BACULA_REGEX, bregex will be built with the - * Bacula bregex library, which is the same code that we - * use on Win32, thus using Linux, you can test your Win32 - * expressions. Otherwise, this program will link with the - * system library routines. - */ -//#define BACULA_REGEX - -#include "bacula.h" -#include -#include "lib/breg.h" - - -static void usage() -{ - fprintf(stderr, -"\n" -"Usage: bregex [-d debug_level] -f -e /test/test2/\n" -" -f specify file of data to be matched\n" -" -e specify expression\n" -" -? print this message.\n" -"\n"); - - exit(1); -} - - -int main(int argc, char *const *argv) -{ - char tab[500]; - int len = bregexp_get_build_where_size("/tmp", "/tmp/toto", ".old"); - - printf("%s\n", bregexp_build_where(tab, len, "/tmp", "/tmp/toto!", ".old")); - exit(0); - - - regex_t preg; - char prbuf[500]; - char *fname = NULL; - char *expr = NULL; - int rc, ch; - char data[1000]; - char pat[500]; - FILE *fd; - bool match_only = true; - int lineno; - bool no_linenos = false; - - - setlocale(LC_ALL, ""); - bindtextdomain("bacula", LOCALEDIR); - textdomain("bacula"); - - while ((ch = getopt(argc, argv, "d:f:e:")) != -1) { - switch (ch) { - case 'd': /* set debug level */ - debug_level = atoi(optarg); - if (debug_level <= 0) { - debug_level = 1; - } - break; - - case 'f': /* data */ - fname = optarg; - break; - - case 'e': - expr = optarg; - break; - - case '?': - default: - usage(); - - } - } - argc -= optind; - argv += optind; - - if (!fname) { - printf("A data file must be specified.\n"); - usage(); - } - - if (!expr) { - printf("An expression must be specified.\n"); - usage(); - } - - OSDependentInit(); - - alist *list; - char *p; - - list = get_bregexps(expr); - - if (!list) { - printf("Can't use %s as 'sed' expression\n", expr); - exit (1); - } - - fd = fopen(fname, "r"); - if (!fd) { - printf(_("Could not open data file: %s\n"), fname); - exit(1); - } - - while (fgets(data, sizeof(data)-1, fd)) { - strip_trailing_newline(data); - apply_bregexps(data, list, &p); - printf("%s => %s\n", data, p); - } - fclose(fd); - free_bregexps(list); - delete list; - exit(0); -} -/* - TODO: - - ajout /g - - - tests - * test avec /i - * test avec un sed et faire un diff - * test avec une boucle pour voir les fuites - -*/ diff --git a/bacula/patches/testing/file_relocation.patch b/bacula/patches/testing/file_relocation.patch deleted file mode 100644 index 8570dcf1d1..0000000000 --- a/bacula/patches/testing/file_relocation.patch +++ /dev/null @@ -1,738 +0,0 @@ -Index: src/dird/ua_restore.c -=================================================================== ---- src/dird/ua_restore.c (révision 4588) -+++ src/dird/ua_restore.c (copie de travail) -@@ -44,7 +44,6 @@ - #include "bacula.h" - #include "dird.h" - -- - /* Imported functions */ - extern void print_bsr(UAContext *ua, RBSR *bsr); - -@@ -83,6 +82,9 @@ - JCR *jcr = ua->jcr; - char *escaped_bsr_name = NULL; - char *escaped_where_name = NULL; -+ bool where_use_regexp = false; -+ char *strip_prefix, *add_prefix, *add_suffix, *regexp; -+ strip_prefix = add_prefix = add_suffix = regexp = NULL; - - memset(&rx, 0, sizeof(rx)); - rx.path = get_pool_memory(PM_FNAME); -@@ -94,6 +96,45 @@ - i = find_arg_with_value(ua, "where"); - if (i >= 0) { - rx.where = ua->argv[i]; -+ } -+ -+ i = find_arg_with_value(ua, "strip_prefix"); -+ if (i >= 0) { -+ strip_prefix = ua->argv[i]; -+ } -+ -+ i = find_arg_with_value(ua, "add_prefix"); -+ if (i >= 0) { -+ add_prefix = ua->argv[i]; -+ } -+ -+ i = find_arg_with_value(ua, "add_suffix"); -+ if (i >= 0) { -+ add_suffix = ua->argv[i]; -+ } -+ -+ i = find_arg(ua, "where_use_regexp"); -+ if (i >= 0) { -+ where_use_regexp = true; -+ } -+ -+ i = find_arg_with_value(ua, "rwhere"); -+ if (i >= 0) { -+ where_use_regexp = true; -+ rx.where = ua->argv[i]; -+ } -+ -+ if (strip_prefix || add_suffix || add_prefix) { -+ int len = bregexp_get_build_where_size(strip_prefix, add_prefix, add_suffix); -+ regexp = (char *) bmalloc (len * sizeof(char)); -+ -+ bregexp_build_where(regexp, len, strip_prefix, add_prefix, add_suffix); -+ where_use_regexp = true; -+ -+ rx.where = regexp; -+ } -+ -+ if (rx.where) { - if (!acl_access_ok(ua, Where_ACL, rx.where)) { - ua->error_msg(_("\"where\" specification not authorized.\n")); - goto bail_out; -@@ -195,9 +236,10 @@ - - Mmsg(ua->cmd, - "run job=\"%s\" client=\"%s\" storage=\"%s\" bootstrap=\"%s\"" -- " where=\"%s\" files=%d catalog=\"%s\"", -+ " %swhere=\"%s\" files=%d catalog=\"%s\"", - job->name(), rx.ClientName, rx.store?rx.store->name():"", - escaped_bsr_name ? escaped_bsr_name : jcr->RestoreBootstrap, -+ where_use_regexp ? "r" : "", - escaped_where_name ? escaped_where_name : rx.where, - rx.selected_files, ua->catalog->name()); - } else { -@@ -216,6 +258,10 @@ - if (escaped_where_name != NULL) { - bfree(escaped_where_name); - } -+ -+ if (regexp) { -+ bfree(regexp); -+ } - - if (find_arg(ua, NT_("yes")) > 0) { - pm_strcat(ua->cmd, " yes"); /* pass it on to the run command */ -@@ -235,6 +281,10 @@ - bfree(escaped_where_name); - } - -+ if (regexp) { -+ bfree(regexp); -+ } -+ - free_rx(&rx); - return 0; - -@@ -333,23 +383,28 @@ - - const char *kw[] = { - /* These keywords are handled in a for loop */ -- "jobid", /* 0 */ -- "current", /* 1 */ -- "before", /* 2 */ -- "file", /* 3 */ -- "directory", /* 4 */ -- "select", /* 5 */ -- "pool", /* 6 */ -- "all", /* 7 */ -+ "jobid", /* 0 */ -+ "current", /* 1 */ -+ "before", /* 2 */ -+ "file", /* 3 */ -+ "directory", /* 4 */ -+ "select", /* 5 */ -+ "pool", /* 6 */ -+ "all", /* 7 */ - - /* The keyword below are handled by individual arg lookups */ -- "client", /* 8 */ -- "storage", /* 9 */ -- "fileset", /* 10 */ -- "where", /* 11 */ -- "yes", /* 12 */ -- "bootstrap", /* 13 */ -- "done", /* 14 */ -+ "client", /* 8 */ -+ "storage", /* 9 */ -+ "fileset", /* 10 */ -+ "where", /* 11 */ -+ "yes", /* 12 */ -+ "bootstrap", /* 13 */ -+ "done", /* 14 */ -+ "strip_prefix", /* 15 */ -+ "add_prefix", /* 16 */ -+ "add_suffix", /* 17 */ -+ "where_use_regexp",/* 18 */ -+ "rwhere", /* 19 like where + where_use_regexp */ - NULL - }; - -Index: src/dird/restore.c -=================================================================== ---- src/dird/restore.c (révision 4588) -+++ src/dird/restore.c (copie de travail) -@@ -50,8 +50,9 @@ - #include "dird.h" - - /* Commands sent to File daemon */ --static char restorecmd[] = "restore replace=%c prelinks=%d where=%s\n"; --static char storaddr[] = "storage address=%s port=%d ssl=0\n"; -+static char restorecmd[] = "restore replace=%c prelinks=%d where=%s\n"; -+static char restorecmdR[] = "restore replace=%c prelinks=%d rwhere=%s\n"; -+static char storaddr[] = "storage address=%s port=%d ssl=0\n"; - - /* Responses received from File daemon */ - static char OKrestore[] = "2000 OK restore\n"; -@@ -172,7 +173,7 @@ - } - - /* Send restore command */ -- char replace, *where; -+ char replace, *where, *cmd; - char empty = '\0'; - - if (jcr->replace != 0) { -@@ -189,9 +190,17 @@ - } else { - where = ∅ /* None */ - } -+ - jcr->prefix_links = jcr->job->PrefixLinks; -+ -+ if (jcr->where_use_regexp) { -+ cmd = restorecmdR; -+ } else { -+ cmd = restorecmd; -+ } -+ - bash_spaces(where); -- bnet_fsend(fd, restorecmd, replace, jcr->prefix_links, where); -+ bnet_fsend(fd, cmd, replace, jcr->prefix_links, where); - unbash_spaces(where); - - if (!response(jcr, fd, OKrestore, "Restore", DISPLAY_ERROR)) { -Index: src/dird/dird.h -=================================================================== ---- src/dird/dird.h (révision 4588) -+++ src/dird/dird.h (copie de travail) -@@ -34,6 +34,7 @@ - */ - - #include "lib/runscript.h" -+#include "lib/breg.h" - #include "dird_conf.h" - - #define DIRECTOR_DAEMON 1 -Index: src/dird/dird_conf.c -=================================================================== ---- src/dird/dird_conf.c (révision 4588) -+++ src/dird/dird_conf.c (copie de travail) -@@ -268,6 +268,10 @@ - {"run", store_alist_str, ITEM(res_job.run_cmds), 0, 0, 0}, - /* Root of where to restore files */ - {"where", store_dir, ITEM(res_job.RestoreWhere), 0, 0, 0}, -+ {"whereuseregexp", store_bool, ITEM(res_job.where_use_regexp), 0, 0, 0}, -+ {"stripprefix", store_str, ITEM(res_job.strip_prefix), 0, 0, 0}, -+ {"addprefix", store_str, ITEM(res_job.add_prefix), 0, 0, 0}, -+ {"addsuffix", store_str, ITEM(res_job.add_suffix), 0, 0, 0}, - /* Where to find bootstrap during restore */ - {"bootstrap",store_dir, ITEM(res_job.RestoreBootstrap), 0, 0, 0}, - /* Where to write bootstrap file during backup */ -@@ -611,6 +615,9 @@ - if (res->res_job.RestoreWhere) { - sendit(sock, _(" --> Where=%s\n"), NPRT(res->res_job.RestoreWhere)); - } -+ if (res->res_job.where_use_regexp) { -+ sendit(sock, _(" --> RWhere=%u\n"), res->res_job.where_use_regexp); -+ } - if (res->res_job.RestoreBootstrap) { - sendit(sock, _(" --> Bootstrap=%s\n"), NPRT(res->res_job.RestoreBootstrap)); - } -@@ -1143,6 +1150,15 @@ - if (res->res_job.RestoreWhere) { - free(res->res_job.RestoreWhere); - } -+ if (res->res_job.strip_prefix) { -+ free(res->res_job.strip_prefix); -+ } -+ if (res->res_job.add_prefix) { -+ free(res->res_job.add_prefix); -+ } -+ if (res->res_job.add_suffix) { -+ free(res->res_job.add_suffix); -+ } - if (res->res_job.RestoreBootstrap) { - free(res->res_job.RestoreBootstrap); - } -@@ -1299,6 +1315,25 @@ - res->res_job.jobdefs = res_all.res_job.jobdefs; - res->res_job.run_cmds = res_all.res_job.run_cmds; - res->res_job.RunScripts = res_all.res_job.RunScripts; -+ if (res->res_job.strip_prefix || -+ res->res_job.add_suffix || -+ res->res_job.add_prefix) -+ { -+ if (res->res_job.RestoreWhere) { -+ free(res->res_job.RestoreWhere); -+ } -+ int len = bregexp_get_build_where_size(res->res_job.strip_prefix, -+ res->res_job.add_prefix, -+ res->res_job.add_suffix); -+ res->res_job.RestoreWhere = (char *) bmalloc (len * sizeof(char)); -+ bregexp_build_where(res->res_job.RestoreWhere, len, -+ res->res_job.strip_prefix, -+ res->res_job.add_prefix, -+ res->res_job.add_suffix); -+ res->res_job.where_use_regexp = true; -+ -+ /* TODO: test bregexp */ -+ } - break; - case R_COUNTER: - if ((res = (URES *)GetResWithName(R_COUNTER, res_all.res_counter.hdr.name)) == NULL) { -Index: src/dird/ua_run.c -=================================================================== ---- src/dird/ua_run.c (révision 4588) -+++ src/dird/ua_run.c (copie de travail) -@@ -41,6 +41,7 @@ - static void select_job_level(UAContext *ua, JCR *jcr); - static bool display_job_parameters(UAContext *ua, JCR *jcr, JOB *job, char *verify_list, - char *jid, const char *replace); -+static void select_where_regexp(UAContext *ua, JCR *jcr); - - - /* Imported variables */ -@@ -71,6 +72,7 @@ - int Priority = 0; - int i, j, opt, files = 0; - bool kw_ok; -+ bool where_use_regexp = false; - JOB *job = NULL; - JOB *verify_job = NULL; - JOB *previous_job = NULL; -@@ -87,7 +89,7 @@ - "level", /* 5 */ - "storage", /* 6 */ - "sd", /* 7 */ -- "pool", /* 8 */ -+ "rwhere", /* 8 where string as a bregexp */ - "where", /* 9 */ - "bootstrap", /* 10 */ - "replace", /* 11 */ -@@ -101,6 +103,7 @@ - "cloned", /* 19 cloned */ - "verifylist", /* 20 verify output list */ - "migrationjob", /* 21 migration job name */ -+ "pool", /* 22 */ - NULL}; - - #define YES_POS 14 -@@ -188,15 +191,11 @@ - store_name = ua->argv[i]; - kw_ok = true; - break; -- case 8: /* pool */ -- if (pool_name) { -- ua->send_msg(_("Pool specified twice.\n")); -- return 0; -- } -- pool_name = ua->argv[i]; -- kw_ok = true; -- break; -+ case 8: /* rwhere */ - case 9: /* where */ -+ /* TODO: this is ugly ... */ -+ where_use_regexp = (j == 9)?false:true; /* rwhere or where ? */ -+ - if (where) { - ua->send_msg(_("Where specified twice.\n")); - return 0; -@@ -287,8 +286,15 @@ - previous_job_name = ua->argv[i]; - kw_ok = true; - break; -+ case 22: /* pool */ -+ if (pool_name) { -+ ua->send_msg(_("Pool specified twice.\n")); -+ return 0; -+ } -+ pool_name = ua->argv[i]; -+ kw_ok = true; -+ break; - -- - default: - break; - } -@@ -478,6 +484,7 @@ - free(jcr->where); - } - jcr->where = bstrdup(where); -+ jcr->where_use_regexp = where_use_regexp; - } - - if (when) { -@@ -595,8 +602,9 @@ - } else if (jcr->JobType == JT_RESTORE) { - add_prompt(ua, _("Bootstrap")); /* 7 */ - add_prompt(ua, _("Where")); /* 8 */ -- add_prompt(ua, _("Replace")); /* 9 */ -- add_prompt(ua, _("JobId")); /* 10 */ -+ add_prompt(ua, _("File Relocation"));/* 9 */ -+ add_prompt(ua, _("Replace")); /* 10 */ -+ add_prompt(ua, _("JobId")); /* 11 */ - } - switch (do_prompt(ua, "", _("Select parameter to modify"), NULL, 0)) { - case 0: -@@ -719,8 +727,13 @@ - ua->cmd[0] = 0; - } - jcr->where = bstrdup(ua->cmd); -+ jcr->where_use_regexp = false; - goto try_again; -- case 9: -+ case 9: -+ /* File relocation */ -+ select_where_regexp(ua, jcr); -+ goto try_again; -+ case 10: - /* Replace */ - start_prompt(ua, _("Replace:\n")); - for (i=0; ReplaceOptions[i].name; i++) { -@@ -731,7 +744,7 @@ - jcr->replace = ReplaceOptions[opt].token; - } - goto try_again; -- case 10: -+ case 11: - /* JobId */ - jid = NULL; /* force reprompt */ - jcr->RestoreJobId = 0; -@@ -775,6 +788,134 @@ - return 0; /* do not run */ - } - -+static void select_where_regexp(UAContext *ua, JCR *jcr) -+{ -+ alist *regs; -+ char *strip_prefix, *add_prefix, *add_suffix, *rwhere; -+ strip_prefix = add_suffix = rwhere = add_prefix = NULL; -+ -+try_again_reg: -+ ua->send_msg(_("strip_prefix=%s add_prefix=%s add_suffix=%s\n"), -+ NPRT(strip_prefix), NPRT(add_prefix), NPRT(add_suffix)); -+ -+ start_prompt(ua, _("This will replace your current Where value\n")); -+ add_prompt(ua, _("Strip prefix")); /* 0 */ -+ add_prompt(ua, _("Add prefix")); /* 1 */ -+ add_prompt(ua, _("Add file suffix")); /* 2 */ -+ add_prompt(ua, _("Enter a regexp")); /* 3 */ -+ add_prompt(ua, _("Test filename manipulation")); /* 4 */ -+ add_prompt(ua, _("Use this ?")); /* 5 */ -+ -+ switch (do_prompt(ua, "", _("Select parameter to modify"), NULL, 0)) { -+ case 0: -+ /* Strip prefix */ -+ if (get_cmd(ua, _("Please enter path prefix to strip: "))) { -+ if (strip_prefix) bfree(strip_prefix); -+ strip_prefix = bstrdup(ua->cmd); -+ } -+ -+ goto try_again_reg; -+ case 1: -+ /* Add prefix */ -+ if (get_cmd(ua, _("Please enter path prefix to add (/ for none): "))) { -+ if (IsPathSeparator(ua->cmd[0]) && ua->cmd[1] == '\0') { -+ ua->cmd[0] = 0; -+ } -+ -+ if (add_prefix) bfree(add_prefix); -+ add_prefix = bstrdup(ua->cmd); -+ } -+ goto try_again_reg; -+ case 2: -+ /* Add suffix */ -+ if (get_cmd(ua, _("Please enter file suffix to add: "))) { -+ if (add_suffix) bfree(add_suffix); -+ add_suffix = bstrdup(ua->cmd); -+ } -+ goto try_again_reg; -+ case 3: -+ /* Add rwhere */ -+ if (get_cmd(ua, _("Please enter a valid regexp (!from!to!): "))) { -+ if (rwhere) bfree(rwhere); -+ rwhere = bstrdup(ua->cmd); -+ } -+ -+ goto try_again_reg; -+ case 4: -+ /* Test regexp */ -+ char *result; -+ char *regexp; -+ -+ if (rwhere && rwhere[0] != '\0') { -+ regs = get_bregexps(rwhere); -+ ua->send_msg(_("rwhere=%s\n"), NPRT(rwhere)); -+ } else { -+ int len = bregexp_get_build_where_size(strip_prefix, add_prefix, add_suffix); -+ regexp = (char *) bmalloc (len * sizeof(char)); -+ bregexp_build_where(regexp, len, strip_prefix, add_prefix, add_suffix); -+ regs = get_bregexps(regexp); -+ ua->send_msg(_("strip_prefix=%s add_prefix=%s add_suffix=%s result=%s\n"), -+ NPRT(strip_prefix), NPRT(add_prefix), NPRT(add_suffix), NPRT(regexp)); -+ -+ bfree(regexp); -+ } -+ -+ if (!regs) { -+ ua->send_msg(_("Cannot use your regexp\n")); -+ goto try_again_reg; -+ } -+ -+ while (get_cmd(ua, _("Please enter filename to test: "))) { -+ apply_bregexps(ua->cmd, regs, &result); -+ ua->send_msg(_("%s -> %s\n"), ua->cmd, result); -+ } -+ free_bregexps(regs); -+ delete regs; -+ goto try_again_reg; -+ -+ case 5: -+ /* OK */ -+ break; -+ case -1: /* error or cancel */ -+ goto bail_out_reg; -+ default: -+ goto try_again_reg; -+ } -+ -+ /* replace the existing where */ -+ if (jcr->where) { -+ bfree(jcr->where); -+ jcr->where = NULL; -+ } -+ -+ if (rwhere) { -+ jcr->where = bstrdup(rwhere); -+ } else if (strip_prefix || add_prefix || add_suffix) { -+ int len = bregexp_get_build_where_size(strip_prefix, add_prefix, add_suffix); -+ jcr->where = (char *) bmalloc(len*sizeof(char)); -+ bregexp_build_where(jcr->where, len, strip_prefix, add_prefix, add_suffix); -+ } -+ -+ regs = get_bregexps(jcr->where); -+ if (regs) { -+ free_bregexps(regs); -+ delete regs; -+ jcr->where_use_regexp = true; -+ } else { -+ if (jcr->where) { -+ bfree(jcr->where); -+ jcr->where = NULL; -+ } -+ ua->send_msg(_("Cannot use your regexp.\n")); -+ } -+ -+bail_out_reg: -+ if (strip_prefix) bfree(strip_prefix); -+ if (add_prefix) bfree(add_prefix); -+ if (add_suffix) bfree(add_suffix); -+ if (rwhere) bfree(rwhere); -+} -+ - static void select_job_level(UAContext *ua, JCR *jcr) - { - if (jcr->JobType == JT_BACKUP) { -@@ -938,7 +1079,7 @@ - ua->send_msg(_("Run Restore job\n" - "JobName: %s\n" - "Bootstrap: %s\n" -- "Where: %s\n" -+ "%s %s\n" /* Where or RWhere */ - "Replace: %s\n" - "FileSet: %s\n" - "Client: %s\n" -@@ -948,6 +1089,7 @@ - "Priority: %d\n"), - job->name(), - NPRT(jcr->RestoreBootstrap), -+ jcr->where_use_regexp?"RWhere:":"Where: ", - jcr->where?jcr->where:NPRT(job->RestoreWhere), - replace, - jcr->fileset->name(), -@@ -961,7 +1103,7 @@ - ua->send_msg(_("Run Restore job\n" - "JobName: %s\n" - "Bootstrap: %s\n" -- "Where: %s\n" -+ "%s %s\n" /* Where or RWhere */ - "Replace: %s\n" - "Client: %s\n" - "Storage: %s\n" -@@ -971,6 +1113,7 @@ - "Priority: %d\n"), - job->name(), - NPRT(jcr->RestoreBootstrap), -+ jcr->where_use_regexp?"RWhere:":"Where: ", - jcr->where?jcr->where:NPRT(job->RestoreWhere), - replace, - jcr->client->name(), -Index: src/dird/dird_conf.h -=================================================================== ---- src/dird/dird_conf.h (révision 4588) -+++ src/dird/dird_conf.h (copie de travail) -@@ -356,6 +356,10 @@ - int Priority; /* Job priority */ - int RestoreJobId; /* What -- JobId to restore */ - char *RestoreWhere; /* Where on disk to restore -- directory */ -+ char *strip_prefix; /* remove prefix from filename */ -+ char *add_prefix; /* add prefix to filename */ -+ char *add_suffix; /* add suffix to filename -- .old */ -+ bool where_use_regexp; /* true if RestoreWhere is a BREGEXP */ - char *RestoreBootstrap; /* Bootstrap file */ - alist *RunScripts; /* Run {client} program {after|before} Job */ - union { -Index: src/filed/job.c -=================================================================== ---- src/filed/job.c (révision 4588) -+++ src/filed/job.c (copie de travail) -@@ -115,6 +115,7 @@ - static char sessioncmd[] = "session %127s %ld %ld %ld %ld %ld %ld\n"; - static char restorecmd[] = "restore replace=%c prelinks=%d where=%s\n"; - static char restorecmd1[] = "restore replace=%c prelinks=%d where=\n"; -+static char restorecmdR[] = "restore replace=%c prelinks=%d rwhere=%s\n"; - static char verifycmd[] = "verify level=%30s"; - static char estimatecmd[] = "estimate listing=%d"; - static char runbefore[] = "RunBeforeJob %s"; -@@ -1586,12 +1587,15 @@ - *where = 0; - - if (sscanf(dir->msg, restorecmd, &replace, &prefix_links, where) != 3) { -- if (sscanf(dir->msg, restorecmd1, &replace, &prefix_links) != 2) { -- pm_strcpy(jcr->errmsg, dir->msg); -- Jmsg(jcr, M_FATAL, 0, _("Bad replace command. CMD=%s\n"), jcr->errmsg); -- return 0; -+ if (sscanf(dir->msg, restorecmdR, &replace, &prefix_links, where) != 3){ -+ if (sscanf(dir->msg, restorecmd1, &replace, &prefix_links) != 2) { -+ pm_strcpy(jcr->errmsg, dir->msg); -+ Jmsg(jcr, M_FATAL, 0, _("Bad replace command. CMD=%s\n"), jcr->errmsg); -+ return 0; -+ } -+ *where = 0; - } -- *where = 0; -+ jcr->where_use_regexp = true; - } - /* Turn / into nothing */ - if (IsPathSeparator(where[0]) && where[1] == '\0') { -@@ -1601,6 +1605,15 @@ - Dmsg2(150, "Got replace %c, where=%s\n", replace, where); - unbash_spaces(where); - jcr->where = bstrdup(where); -+ -+ if (jcr->where_use_regexp) { -+ jcr->where_bregexp = get_bregexps(jcr->where); -+ if (!jcr->where_bregexp) { -+ Jmsg(jcr, M_FATAL, 0, _("Bad where regexp. where=%s\n"), jcr->where); -+ free_pool_memory(where); -+ return 0; -+ } -+ } - free_pool_memory(where); - jcr->replace = replace; - jcr->prefix_links = prefix_links; -Index: src/filed/filed.h -=================================================================== ---- src/filed/filed.h (révision 4588) -+++ src/filed/filed.h (copie de travail) -@@ -40,6 +40,7 @@ - #include "acl.h" - #include "protos.h" /* file daemon prototypes */ - #include "lib/runscript.h" -+#include "lib/breg.h" - #ifdef HAVE_LIBZ - #include /* compression headers */ - #else -Index: src/jcr.h -=================================================================== ---- src/jcr.h (révision 4588) -+++ src/jcr.h (copie de travail) -@@ -173,6 +173,8 @@ - MSGS *jcr_msgs; /* Copy of message resource -- actually used */ - uint32_t ClientId; /* Client associated with Job */ - char *where; /* prefix to restore files to */ -+ bool where_use_regexp; /* True if where is a bregexp */ -+ alist *where_bregexp; /* BREGEXP alist for path manipulation */ - int cached_pnl; /* cached path length */ - POOLMEM *cached_path; /* cached path */ - bool prefix_links; /* Prefix links with Where path */ -Index: src/lib/Makefile.in -=================================================================== ---- src/lib/Makefile.in (révision 4588) -+++ src/lib/Makefile.in (copie de travail) -@@ -32,7 +32,7 @@ - res.c rwlock.c scan.c serial.c sha1.c \ - signal.c smartall.c rblist.c tls.c tree.c \ - util.c var.c watchdog.c workq.c btimers.c \ -- address_conf.c pythonlib.c -+ address_conf.c pythonlib.c breg.c - - - LIBOBJS = attr.o base64.o berrno.o bsys.o bget_msg.o \ -@@ -45,7 +45,7 @@ - res.o rwlock.o scan.o serial.o sha1.o \ - signal.o smartall.o rblist.o tls.o tree.o \ - util.o var.o watchdog.o workq.o btimers.o \ -- address_conf.o pythonlib.o -+ address_conf.o pythonlib.o breg.o - - - EXTRAOBJS = @OBJLIST@ -Index: src/lib/attr.c -=================================================================== ---- src/lib/attr.c (révision 4588) -+++ src/lib/attr.c (copie de travail) -@@ -35,8 +35,8 @@ - - #include "bacula.h" - #include "jcr.h" -+#include "lib/breg.h" - -- - ATTR *new_attr() - { - ATTR *attr = (ATTR *)malloc(sizeof(ATTR)); -@@ -148,9 +148,30 @@ - * every filename if a prefix is supplied. - * - */ -+ - if (jcr->where[0] == 0) { - pm_strcpy(attr->ofname, attr->fname); - pm_strcpy(attr->olname, attr->lname); -+ -+ } else if (jcr->where_bregexp) { -+ char *ret; -+ apply_bregexps(attr->fname, jcr->where_bregexp, &ret); -+ pm_strcpy(attr->ofname, ret); -+ -+ if (attr->type == FT_LNKSAVED || attr->type == FT_LNK) { -+ /* Always add prefix to hard links (FT_LNKSAVED) and -+ * on user request to soft links -+ */ -+ -+ if ((attr->type == FT_LNKSAVED || jcr->prefix_links)) { -+ apply_bregexps(attr->lname, jcr->where_bregexp, &ret); -+ pm_strcpy(attr->olname, ret); -+ -+ } else { -+ pm_strcpy(attr->olname, attr->lname); -+ } -+ } -+ - } else { - const char *fn; - int wherelen = strlen(jcr->where); -Index: src/lib/jcr.c -=================================================================== ---- src/lib/jcr.c (révision 4588) -+++ src/lib/jcr.c (copie de travail) -@@ -56,6 +56,9 @@ - /* External variables we reference */ - extern time_t watchdog_time; - -+/* External referenced functions */ -+void free_bregexps(alist *bregexps); -+ - /* Forward referenced functions */ - extern "C" void timeout_handler(int sig); - static void jcr_timeout_check(watchdog_t *self); -@@ -381,6 +384,11 @@ - free(jcr->where); - jcr->where = NULL; - } -+ if (jcr->where_bregexp) { -+ free_bregexps(jcr->where_bregexp); -+ delete jcr->where_bregexp; -+ jcr->where_bregexp = NULL; -+ } - if (jcr->cached_path) { - free_pool_memory(jcr->cached_path); - jcr->cached_path = NULL; -- 2.39.5