1 Index: src/dird/ua_restore.c
2 ===================================================================
3 --- src/dird/ua_restore.c (révision 4466)
4 +++ src/dird/ua_restore.c (copie de travail)
12 /* Imported functions */
13 extern void print_bsr(UAContext *ua, RBSR *bsr);
17 char *escaped_bsr_name = NULL;
18 char *escaped_where_name = NULL;
19 + bool where_use_regexp = false;
20 + char *strip_prefix, *add_prefix, *add_suffix;
21 + strip_prefix = add_prefix = add_suffix = NULL;
23 memset(&rx, 0, sizeof(rx));
24 rx.path = get_pool_memory(PM_FNAME);
26 i = find_arg_with_value(ua, "where");
28 rx.where = ua->argv[i];
31 + i = find_arg_with_value(ua, "strip_prefix");
33 + strip_prefix = ua->argv[i];
36 + i = find_arg_with_value(ua, "add_prefix");
38 + add_prefix = ua->argv[i];
41 + i = find_arg_with_value(ua, "add_suffix");
43 + add_suffix = ua->argv[i];
46 + if (strip_prefix || add_suffix || add_prefix) {
47 + where_use_regexp = true;
48 + rx.where = bregexp_build_where(strip_prefix, add_prefix, add_suffix);
52 if (!acl_access_ok(ua, Where_ACL, rx.where)) {
53 ua->error_msg(_("\"where\" specification not authorized.\n"));
58 "run job=\"%s\" client=\"%s\" storage=\"%s\" bootstrap=\"%s\""
59 - " where=\"%s\" files=%d catalog=\"%s\"",
60 + " %swhere=\"%s\" files=%d catalog=\"%s\"",
61 job->name(), rx.ClientName, rx.store?rx.store->name():"",
62 escaped_bsr_name ? escaped_bsr_name : jcr->RestoreBootstrap,
63 + where_use_regexp ? "r" : "",
64 escaped_where_name ? escaped_where_name : rx.where,
65 rx.selected_files, ua->catalog->name());
68 if (escaped_where_name != NULL) {
69 bfree(escaped_where_name);
72 + if (where_use_regexp) {
73 + free_pool_memory(rx.where);
76 if (find_arg(ua, NT_("yes")) > 0) {
77 pm_strcat(ua->cmd, " yes"); /* pass it on to the run command */
79 bfree(escaped_where_name);
82 + if (where_use_regexp) {
83 + free_pool_memory(rx.where);
89 Index: src/dird/restore.c
90 ===================================================================
91 --- src/dird/restore.c (révision 4466)
92 +++ src/dird/restore.c (copie de travail)
96 /* Commands sent to File daemon */
97 -static char restorecmd[] = "restore replace=%c prelinks=%d where=%s\n";
98 -static char storaddr[] = "storage address=%s port=%d ssl=0\n";
99 +static char restorecmd[] = "restore replace=%c prelinks=%d where=%s\n";
100 +static char restorecmdR[] = "restore replace=%c prelinks=%d rwhere=%s\n";
101 +static char storaddr[] = "storage address=%s port=%d ssl=0\n";
103 /* Responses received from File daemon */
104 static char OKrestore[] = "2000 OK restore\n";
108 /* Send restore command */
109 - char replace, *where;
110 + char replace, *where, *cmd;
113 if (jcr->replace != 0) {
116 where = ∅ /* None */
119 jcr->prefix_links = jcr->job->PrefixLinks;
121 + if (jcr->where_use_regexp) {
128 - bnet_fsend(fd, restorecmd, replace, jcr->prefix_links, where);
129 + bnet_fsend(fd, cmd, replace, jcr->prefix_links, where);
130 unbash_spaces(where);
132 if (!response(jcr, fd, OKrestore, "Restore", DISPLAY_ERROR)) {
133 Index: src/dird/dird_conf.c
134 ===================================================================
135 --- src/dird/dird_conf.c (révision 4466)
136 +++ src/dird/dird_conf.c (copie de travail)
138 {"run", store_alist_str, ITEM(res_job.run_cmds), 0, 0, 0},
139 /* Root of where to restore files */
140 {"where", store_dir, ITEM(res_job.RestoreWhere), 0, 0, 0},
141 + {"whereuseregexp", store_bool, ITEM(res_job.where_use_regexp), 0, 0, 0},
142 /* Where to find bootstrap during restore */
143 {"bootstrap",store_dir, ITEM(res_job.RestoreBootstrap), 0, 0, 0},
144 /* Where to write bootstrap file during backup */
146 if (res->res_job.RestoreWhere) {
147 sendit(sock, _(" --> Where=%s\n"), NPRT(res->res_job.RestoreWhere));
149 + if (res->res_job.where_use_regexp) {
150 + sendit(sock, _(" --> RWhere=%u\n"), res->res_job.where_use_regexp);
152 if (res->res_job.RestoreBootstrap) {
153 sendit(sock, _(" --> Bootstrap=%s\n"), NPRT(res->res_job.RestoreBootstrap));
155 Index: src/dird/ua_run.c
156 ===================================================================
157 --- src/dird/ua_run.c (révision 4466)
158 +++ src/dird/ua_run.c (copie de travail)
161 int i, j, opt, files = 0;
163 + bool where_use_regexp = false;
165 JOB *verify_job = NULL;
166 JOB *previous_job = NULL;
172 + "rwhere", /* 8 where string as a bregexp */
174 "bootstrap", /* 10 */
177 "cloned", /* 19 cloned */
178 "verifylist", /* 20 verify output list */
179 "migrationjob", /* 21 migration job name */
185 store_name = ua->argv[i];
190 - ua->send_msg(_("Pool specified twice.\n"));
193 - pool_name = ua->argv[i];
197 + where_use_regexp = true;
200 ua->send_msg(_("Where specified twice.\n"));
202 previous_job_name = ua->argv[i];
205 + case 22: /* pool */
207 + ua->send_msg(_("Pool specified twice.\n"));
210 + pool_name = ua->argv[i];
221 jcr->where = bstrdup(where);
222 + jcr->where_use_regexp = where_use_regexp;
226 Index: src/dird/dird_conf.h
227 ===================================================================
228 --- src/dird/dird_conf.h (révision 4466)
229 +++ src/dird/dird_conf.h (copie de travail)
231 int Priority; /* Job priority */
232 int RestoreJobId; /* What -- JobId to restore */
233 char *RestoreWhere; /* Where on disk to restore -- directory */
234 + bool where_use_regexp; /* true if RestoreWhere is a BREGEXP */
235 char *RestoreBootstrap; /* Bootstrap file */
236 alist *RunScripts; /* Run {client} program {after|before} Job */
238 Index: src/filed/job.c
239 ===================================================================
240 --- src/filed/job.c (révision 4467)
241 +++ src/filed/job.c (copie de travail)
246 +#include "lib/breg.h"
248 #if defined(WIN32_VSS)
251 static char sessioncmd[] = "session %127s %ld %ld %ld %ld %ld %ld\n";
252 static char restorecmd[] = "restore replace=%c prelinks=%d where=%s\n";
253 static char restorecmd1[] = "restore replace=%c prelinks=%d where=\n";
254 +static char restorecmdR[] = "restore replace=%c prelinks=%d rwhere=%s\n";
255 static char verifycmd[] = "verify level=%30s";
256 static char estimatecmd[] = "estimate listing=%d";
257 static char runbefore[] = "RunBeforeJob %s";
258 @@ -1586,12 +1588,15 @@
261 if (sscanf(dir->msg, restorecmd, &replace, &prefix_links, where) != 3) {
262 - if (sscanf(dir->msg, restorecmd1, &replace, &prefix_links) != 2) {
263 - pm_strcpy(jcr->errmsg, dir->msg);
264 - Jmsg(jcr, M_FATAL, 0, _("Bad replace command. CMD=%s\n"), jcr->errmsg);
266 + if (sscanf(dir->msg, restorecmdR, &replace, &prefix_links, where) != 3){
267 + if (sscanf(dir->msg, restorecmd1, &replace, &prefix_links) != 2) {
268 + pm_strcpy(jcr->errmsg, dir->msg);
269 + Jmsg(jcr, M_FATAL, 0, _("Bad replace command. CMD=%s\n"), jcr->errmsg);
275 + jcr->where_use_regexp = true;
277 /* Turn / into nothing */
278 if (IsPathSeparator(where[0]) && where[1] == '\0') {
279 @@ -1601,6 +1606,15 @@
280 Dmsg2(150, "Got replace %c, where=%s\n", replace, where);
281 unbash_spaces(where);
282 jcr->where = bstrdup(where);
284 + if (jcr->where_use_regexp) {
285 + jcr->where_bregexp = get_bregexps(jcr->where);
286 + if (!jcr->where_bregexp) {
287 + Jmsg(jcr, M_FATAL, 0, _("Bad where regexp. where=%s\n"), jcr->where);
288 + free_pool_memory(where);
292 free_pool_memory(where);
293 jcr->replace = replace;
294 jcr->prefix_links = prefix_links;
296 ===================================================================
297 --- src/jcr.h (révision 4466)
298 +++ src/jcr.h (copie de travail)
300 MSGS *jcr_msgs; /* Copy of message resource -- actually used */
301 uint32_t ClientId; /* Client associated with Job */
302 char *where; /* prefix to restore files to */
303 + bool where_use_regexp; /* True if where is a bregexp */
304 + alist *where_bregexp; /* BREGEXP alist for path manipulation */
305 int cached_pnl; /* cached path length */
306 POOLMEM *cached_path; /* cached path */
307 bool prefix_links; /* Prefix links with Where path */
308 Index: src/lib/Makefile.in
309 ===================================================================
310 --- src/lib/Makefile.in (révision 4466)
311 +++ src/lib/Makefile.in (copie de travail)
313 res.c rwlock.c scan.c serial.c sha1.c \
314 signal.c smartall.c rblist.c tls.c tree.c \
315 util.c var.c watchdog.c workq.c btimers.c \
316 - address_conf.c pythonlib.c
317 + address_conf.c pythonlib.c breg.c
320 LIBOBJS = attr.o base64.o berrno.o bsys.o bget_msg.o \
322 res.o rwlock.o scan.o serial.o sha1.o \
323 signal.o smartall.o rblist.o tls.o tree.o \
324 util.o var.o watchdog.o workq.o btimers.o \
325 - address_conf.o pythonlib.o
326 + address_conf.o pythonlib.o breg.o
329 EXTRAOBJS = @OBJLIST@
330 Index: src/lib/attr.c
331 ===================================================================
332 --- src/lib/attr.c (révision 4466)
333 +++ src/lib/attr.c (copie de travail)
338 +#include "lib/breg.h"
343 ATTR *attr = (ATTR *)malloc(sizeof(ATTR));
345 * every filename if a prefix is supplied.
349 if (jcr->where[0] == 0) {
350 pm_strcpy(attr->ofname, attr->fname);
351 pm_strcpy(attr->olname, attr->lname);
353 + } else if (jcr->where_bregexp) {
355 + apply_bregexps(attr->fname, jcr->where_bregexp, &ret);
356 + pm_strcpy(attr->ofname, ret);
358 + if (attr->type == FT_LNKSAVED || attr->type == FT_LNK) {
359 + /* Always add prefix to hard links (FT_LNKSAVED) and
360 + * on user request to soft links
363 + if ((attr->type == FT_LNKSAVED || jcr->prefix_links)) {
364 + apply_bregexps(attr->lname, jcr->where_bregexp, &ret);
365 + pm_strcpy(attr->olname, ret);
368 + pm_strcpy(attr->olname, attr->lname);
374 int wherelen = strlen(jcr->where);
376 ===================================================================
377 --- src/lib/jcr.c (révision 4466)
378 +++ src/lib/jcr.c (copie de travail)
380 /* External variables we reference */
381 extern time_t watchdog_time;
383 +/* External referenced functions */
384 +void free_bregexps(alist *bregexps);
386 /* Forward referenced functions */
387 extern "C" void timeout_handler(int sig);
388 static void jcr_timeout_check(watchdog_t *self);
393 + if (jcr->where_bregexp) {
394 + free_bregexps(jcr->where_bregexp);
395 + delete jcr->where_bregexp;
396 + jcr->where_bregexp = NULL;
398 if (jcr->cached_path) {
399 free_pool_memory(jcr->cached_path);
400 jcr->cached_path = NULL;
401 Index: patches/testing/breg.c
402 ===================================================================
403 --- patches/testing/breg.c (révision 4510)
404 +++ patches/testing/breg.c (copie de travail)
405 @@ -393,19 +393,19 @@
407 *str_tmp = *ret = '\0';
409 - if (*strip_prefix) {
410 + if (strip_prefix) {
411 len += bsnprintf(ret, str_size - len, "!%s!!",
412 bregexp_escape_string(str_tmp, strip_prefix, sep));
417 if (len) ret[len++] = ',';
419 len += bsnprintf(ret + len, str_size - len, "!([^/])$!$1%s!",
420 bregexp_escape_string(str_tmp, add_suffix, sep));
425 if (len) ret[len++] = ',';
427 len += bsnprintf(ret + len, str_size - len, "!^!%s!",