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 + bool have_to_free_where = false;
21 + char *strip_prefix, *add_prefix, *add_suffix;
22 + strip_prefix = add_prefix = add_suffix = NULL;
24 memset(&rx, 0, sizeof(rx));
25 rx.path = get_pool_memory(PM_FNAME);
27 i = find_arg_with_value(ua, "where");
29 rx.where = ua->argv[i];
32 + i = find_arg_with_value(ua, "strip_prefix");
34 + strip_prefix = ua->argv[i];
37 + i = find_arg_with_value(ua, "add_prefix");
39 + add_prefix = ua->argv[i];
42 + i = find_arg_with_value(ua, "add_suffix");
44 + add_suffix = ua->argv[i];
47 + i = find_arg(ua, "where_use_regexp");
49 + where_use_regexp = true;
52 + i = find_arg_with_value(ua, "rwhere");
54 + where_use_regexp = true;
55 + rx.where = ua->argv[i];
58 + if (strip_prefix || add_suffix || add_prefix) {
59 + where_use_regexp = true;
60 + have_to_free_where = true;
61 + rx.where = bregexp_build_where(strip_prefix, add_prefix, add_suffix);
65 if (!acl_access_ok(ua, Where_ACL, rx.where)) {
66 ua->error_msg(_("\"where\" specification not authorized.\n"));
71 "run job=\"%s\" client=\"%s\" storage=\"%s\" bootstrap=\"%s\""
72 - " where=\"%s\" files=%d catalog=\"%s\"",
73 + " %swhere=\"%s\" files=%d catalog=\"%s\"",
74 job->name(), rx.ClientName, rx.store?rx.store->name():"",
75 escaped_bsr_name ? escaped_bsr_name : jcr->RestoreBootstrap,
76 + where_use_regexp ? "r" : "",
77 escaped_where_name ? escaped_where_name : rx.where,
78 rx.selected_files, ua->catalog->name());
81 if (escaped_where_name != NULL) {
82 bfree(escaped_where_name);
85 + if (have_to_free_where) {
86 + free_pool_memory(rx.where);
89 if (find_arg(ua, NT_("yes")) > 0) {
90 pm_strcat(ua->cmd, " yes"); /* pass it on to the run command */
92 bfree(escaped_where_name);
95 + if (have_to_free_where) {
96 + free_pool_memory(rx.where);
102 @@ -331,23 +379,28 @@
105 /* These keywords are handled in a for loop */
110 - "directory", /* 4 */
118 + "directory", /* 4 */
123 /* The keyword below are handled by individual arg lookups */
126 - "fileset", /* 10 */
129 - "bootstrap", /* 13 */
133 + "fileset", /* 10 */
136 + "bootstrap", /* 13 */
138 + "strip_prefix", /* 15 */
139 + "add_prefix", /* 16 */
140 + "add_suffix", /* 17 */
141 + "where_use_regexp",/* 18 */
142 + "rwhere", /* 19 like where + where_use_regexp */
146 Index: src/dird/restore.c
147 ===================================================================
148 --- src/dird/restore.c (révision 4466)
149 +++ src/dird/restore.c (copie de travail)
153 /* Commands sent to File daemon */
154 -static char restorecmd[] = "restore replace=%c prelinks=%d where=%s\n";
155 -static char storaddr[] = "storage address=%s port=%d ssl=0\n";
156 +static char restorecmd[] = "restore replace=%c prelinks=%d where=%s\n";
157 +static char restorecmdR[] = "restore replace=%c prelinks=%d rwhere=%s\n";
158 +static char storaddr[] = "storage address=%s port=%d ssl=0\n";
160 /* Responses received from File daemon */
161 static char OKrestore[] = "2000 OK restore\n";
165 /* Send restore command */
166 - char replace, *where;
167 + char replace, *where, *cmd;
170 if (jcr->replace != 0) {
173 where = ∅ /* None */
176 jcr->prefix_links = jcr->job->PrefixLinks;
178 + if (jcr->where_use_regexp) {
185 - bnet_fsend(fd, restorecmd, replace, jcr->prefix_links, where);
186 + bnet_fsend(fd, cmd, replace, jcr->prefix_links, where);
187 unbash_spaces(where);
189 if (!response(jcr, fd, OKrestore, "Restore", DISPLAY_ERROR)) {
190 Index: src/dird/dird_conf.c
191 ===================================================================
192 --- src/dird/dird_conf.c (révision 4466)
193 +++ src/dird/dird_conf.c (copie de travail)
198 +#include "lib/breg.h"
200 /* Define the first and last resource ID record
201 * types. Note, these should be unique for each
203 {"run", store_alist_str, ITEM(res_job.run_cmds), 0, 0, 0},
204 /* Root of where to restore files */
205 {"where", store_dir, ITEM(res_job.RestoreWhere), 0, 0, 0},
206 + {"whereuseregexp", store_bool, ITEM(res_job.where_use_regexp), 0, 0, 0},
207 + {"stripprefix", store_str, ITEM(res_job.strip_prefix), 0, 0, 0},
208 + {"addprefix", store_str, ITEM(res_job.add_prefix), 0, 0, 0},
209 + {"addsuffix", store_str, ITEM(res_job.add_suffix), 0, 0, 0},
210 /* Where to find bootstrap during restore */
211 {"bootstrap",store_dir, ITEM(res_job.RestoreBootstrap), 0, 0, 0},
212 /* Where to write bootstrap file during backup */
214 if (res->res_job.RestoreWhere) {
215 sendit(sock, _(" --> Where=%s\n"), NPRT(res->res_job.RestoreWhere));
217 + if (res->res_job.where_use_regexp) {
218 + sendit(sock, _(" --> RWhere=%u\n"), res->res_job.where_use_regexp);
220 if (res->res_job.RestoreBootstrap) {
221 sendit(sock, _(" --> Bootstrap=%s\n"), NPRT(res->res_job.RestoreBootstrap));
223 @@ -1143,6 +1151,15 @@
224 if (res->res_job.RestoreWhere) {
225 free(res->res_job.RestoreWhere);
227 + if (res->res_job.strip_prefix) {
228 + free(res->res_job.strip_prefix);
230 + if (res->res_job.add_prefix) {
231 + free(res->res_job.add_prefix);
233 + if (res->res_job.add_suffix) {
234 + free(res->res_job.add_suffix);
236 if (res->res_job.RestoreBootstrap) {
237 free(res->res_job.RestoreBootstrap);
239 @@ -1299,6 +1316,19 @@
240 res->res_job.jobdefs = res_all.res_job.jobdefs;
241 res->res_job.run_cmds = res_all.res_job.run_cmds;
242 res->res_job.RunScripts = res_all.res_job.RunScripts;
243 + if (res->res_job.strip_prefix ||
244 + res->res_job.add_suffix ||
245 + res->res_job.add_prefix)
247 + if (res->res_job.RestoreWhere) {
248 + free(res->res_job.RestoreWhere);
250 + res->res_job.where_use_regexp = true;
251 + res->res_job.RestoreWhere=bregexp_build_where(res->res_job.strip_prefix,
252 + res->res_job.add_prefix,
253 + res->res_job.add_suffix);
254 + /* TODO: test bregexp */
258 if ((res = (URES *)GetResWithName(R_COUNTER, res_all.res_counter.hdr.name)) == NULL) {
259 Index: src/dird/ua_run.c
260 ===================================================================
261 --- src/dird/ua_run.c (révision 4466)
262 +++ src/dird/ua_run.c (copie de travail)
265 int i, j, opt, files = 0;
267 + bool where_use_regexp = false;
269 JOB *verify_job = NULL;
270 JOB *previous_job = NULL;
276 + "rwhere", /* 8 where string as a bregexp */
278 "bootstrap", /* 10 */
281 "cloned", /* 19 cloned */
282 "verifylist", /* 20 verify output list */
283 "migrationjob", /* 21 migration job name */
289 store_name = ua->argv[i];
294 - ua->send_msg(_("Pool specified twice.\n"));
297 - pool_name = ua->argv[i];
300 + case 8: /* rwhere */
301 + where_use_regexp = true;
304 ua->send_msg(_("Where specified twice.\n"));
306 previous_job_name = ua->argv[i];
309 + case 22: /* pool */
311 + ua->send_msg(_("Pool specified twice.\n"));
314 + pool_name = ua->argv[i];
325 jcr->where = bstrdup(where);
326 + jcr->where_use_regexp = where_use_regexp;
330 Index: src/dird/dird_conf.h
331 ===================================================================
332 --- src/dird/dird_conf.h (révision 4466)
333 +++ src/dird/dird_conf.h (copie de travail)
335 int Priority; /* Job priority */
336 int RestoreJobId; /* What -- JobId to restore */
337 char *RestoreWhere; /* Where on disk to restore -- directory */
338 + char *strip_prefix; /* remove prefix from filename */
339 + char *add_prefix; /* add prefix to filename */
340 + char *add_suffix; /* add suffix to filename -- .old */
341 + bool where_use_regexp; /* true if RestoreWhere is a BREGEXP */
342 char *RestoreBootstrap; /* Bootstrap file */
343 alist *RunScripts; /* Run {client} program {after|before} Job */
345 Index: src/filed/job.c
346 ===================================================================
347 --- src/filed/job.c (révision 4467)
348 +++ src/filed/job.c (copie de travail)
353 +#include "lib/breg.h"
355 #if defined(WIN32_VSS)
358 static char sessioncmd[] = "session %127s %ld %ld %ld %ld %ld %ld\n";
359 static char restorecmd[] = "restore replace=%c prelinks=%d where=%s\n";
360 static char restorecmd1[] = "restore replace=%c prelinks=%d where=\n";
361 +static char restorecmdR[] = "restore replace=%c prelinks=%d rwhere=%s\n";
362 static char verifycmd[] = "verify level=%30s";
363 static char estimatecmd[] = "estimate listing=%d";
364 static char runbefore[] = "RunBeforeJob %s";
365 @@ -1586,12 +1588,15 @@
368 if (sscanf(dir->msg, restorecmd, &replace, &prefix_links, where) != 3) {
369 - if (sscanf(dir->msg, restorecmd1, &replace, &prefix_links) != 2) {
370 - pm_strcpy(jcr->errmsg, dir->msg);
371 - Jmsg(jcr, M_FATAL, 0, _("Bad replace command. CMD=%s\n"), jcr->errmsg);
373 + if (sscanf(dir->msg, restorecmdR, &replace, &prefix_links, where) != 3){
374 + if (sscanf(dir->msg, restorecmd1, &replace, &prefix_links) != 2) {
375 + pm_strcpy(jcr->errmsg, dir->msg);
376 + Jmsg(jcr, M_FATAL, 0, _("Bad replace command. CMD=%s\n"), jcr->errmsg);
382 + jcr->where_use_regexp = true;
384 /* Turn / into nothing */
385 if (IsPathSeparator(where[0]) && where[1] == '\0') {
386 @@ -1601,6 +1606,15 @@
387 Dmsg2(150, "Got replace %c, where=%s\n", replace, where);
388 unbash_spaces(where);
389 jcr->where = bstrdup(where);
391 + if (jcr->where_use_regexp) {
392 + jcr->where_bregexp = get_bregexps(jcr->where);
393 + if (!jcr->where_bregexp) {
394 + Jmsg(jcr, M_FATAL, 0, _("Bad where regexp. where=%s\n"), jcr->where);
395 + free_pool_memory(where);
399 free_pool_memory(where);
400 jcr->replace = replace;
401 jcr->prefix_links = prefix_links;
403 ===================================================================
404 --- src/jcr.h (révision 4466)
405 +++ src/jcr.h (copie de travail)
407 MSGS *jcr_msgs; /* Copy of message resource -- actually used */
408 uint32_t ClientId; /* Client associated with Job */
409 char *where; /* prefix to restore files to */
410 + bool where_use_regexp; /* True if where is a bregexp */
411 + alist *where_bregexp; /* BREGEXP alist for path manipulation */
412 int cached_pnl; /* cached path length */
413 POOLMEM *cached_path; /* cached path */
414 bool prefix_links; /* Prefix links with Where path */
415 Index: src/lib/Makefile.in
416 ===================================================================
417 --- src/lib/Makefile.in (révision 4466)
418 +++ src/lib/Makefile.in (copie de travail)
420 res.c rwlock.c scan.c serial.c sha1.c \
421 signal.c smartall.c rblist.c tls.c tree.c \
422 util.c var.c watchdog.c workq.c btimers.c \
423 - address_conf.c pythonlib.c
424 + address_conf.c pythonlib.c breg.c
427 LIBOBJS = attr.o base64.o berrno.o bsys.o bget_msg.o \
429 res.o rwlock.o scan.o serial.o sha1.o \
430 signal.o smartall.o rblist.o tls.o tree.o \
431 util.o var.o watchdog.o workq.o btimers.o \
432 - address_conf.o pythonlib.o
433 + address_conf.o pythonlib.o breg.o
436 EXTRAOBJS = @OBJLIST@
437 Index: src/lib/attr.c
438 ===================================================================
439 --- src/lib/attr.c (révision 4466)
440 +++ src/lib/attr.c (copie de travail)
445 +#include "lib/breg.h"
450 ATTR *attr = (ATTR *)malloc(sizeof(ATTR));
452 * every filename if a prefix is supplied.
456 if (jcr->where[0] == 0) {
457 pm_strcpy(attr->ofname, attr->fname);
458 pm_strcpy(attr->olname, attr->lname);
460 + } else if (jcr->where_bregexp) {
462 + apply_bregexps(attr->fname, jcr->where_bregexp, &ret);
463 + pm_strcpy(attr->ofname, ret);
465 + if (attr->type == FT_LNKSAVED || attr->type == FT_LNK) {
466 + /* Always add prefix to hard links (FT_LNKSAVED) and
467 + * on user request to soft links
470 + if ((attr->type == FT_LNKSAVED || jcr->prefix_links)) {
471 + apply_bregexps(attr->lname, jcr->where_bregexp, &ret);
472 + pm_strcpy(attr->olname, ret);
475 + pm_strcpy(attr->olname, attr->lname);
481 int wherelen = strlen(jcr->where);
483 ===================================================================
484 --- src/lib/jcr.c (révision 4466)
485 +++ src/lib/jcr.c (copie de travail)
487 /* External variables we reference */
488 extern time_t watchdog_time;
490 +/* External referenced functions */
491 +void free_bregexps(alist *bregexps);
493 /* Forward referenced functions */
494 extern "C" void timeout_handler(int sig);
495 static void jcr_timeout_check(watchdog_t *self);
500 + if (jcr->where_bregexp) {
501 + free_bregexps(jcr->where_bregexp);
502 + delete jcr->where_bregexp;
503 + jcr->where_bregexp = NULL;
505 if (jcr->cached_path) {
506 free_pool_memory(jcr->cached_path);
507 jcr->cached_path = NULL;
508 Index: patches/testing/file_relocation.patch
509 ===================================================================
510 --- patches/testing/file_relocation.patch (révision 4515)
511 +++ patches/testing/file_relocation.patch (copie de travail)
513 + " %swhere=\"%s\" files=%d catalog=\"%s\"",
514 job->name(), rx.ClientName, rx.store?rx.store->name():"",
515 escaped_bsr_name ? escaped_bsr_name : jcr->RestoreBootstrap,
516 -+ where_use_regexp ? "r" : "",
517 ++ where_use_regexp ? "r" : "",
518 escaped_where_name ? escaped_where_name : rx.where,
519 rx.selected_files, ua->catalog->name());
522 - pool_name = ua->argv[i];
526 -+ where_use_regexp = true;
527 ++ case 8: /* rwhere */
528 ++ where_use_regexp = true;
531 ua->send_msg(_("Where specified twice.\n"));
532 @@ -371,12 +371,12 @@
533 - Jmsg(jcr, M_FATAL, 0, _("Bad replace command. CMD=%s\n"), jcr->errmsg);
535 + if (sscanf(dir->msg, restorecmdR, &replace, &prefix_links, where) != 3){
536 -+ if (sscanf(dir->msg, restorecmd1, &replace, &prefix_links) != 2) {
537 -+ pm_strcpy(jcr->errmsg, dir->msg);
538 -+ Jmsg(jcr, M_FATAL, 0, _("Bad replace command. CMD=%s\n"), jcr->errmsg);
542 ++ if (sscanf(dir->msg, restorecmd1, &replace, &prefix_links) != 2) {
543 ++ pm_strcpy(jcr->errmsg, dir->msg);
544 ++ Jmsg(jcr, M_FATAL, 0, _("Bad replace command. CMD=%s\n"), jcr->errmsg);
550 + jcr->where_use_regexp = true;
551 @@ -467,13 +467,13 @@
552 + * on user request to soft links
555 -+ if ((attr->type == FT_LNKSAVED || jcr->prefix_links)) {
556 -+ apply_bregexps(attr->lname, jcr->where_bregexp, &ret);
557 -+ pm_strcpy(attr->olname, ret);
558 ++ if ((attr->type == FT_LNKSAVED || jcr->prefix_links)) {
559 ++ apply_bregexps(attr->lname, jcr->where_bregexp, &ret);
560 ++ pm_strcpy(attr->olname, ret);
563 -+ pm_strcpy(attr->olname, attr->lname);
566 ++ pm_strcpy(attr->olname, attr->lname);
571 @@ -505,253 +505,3 @@
572 if (jcr->cached_path) {
573 free_pool_memory(jcr->cached_path);
574 jcr->cached_path = NULL;
575 -Index: patches/testing/file_relocation.patch
576 -===================================================================
577 ---- patches/testing/file_relocation.patch (révision 4514)
578 -+++ patches/testing/file_relocation.patch (copie de travail)
580 - /* Imported functions */
581 - extern void print_bsr(UAContext *ua, RBSR *bsr);
585 - JCR *jcr = ua->jcr;
586 - char *escaped_bsr_name = NULL;
587 - char *escaped_where_name = NULL;
588 - + bool where_use_regexp = false;
589 -++ bool have_to_free_where = false;
590 - + char *strip_prefix, *add_prefix, *add_suffix;
591 - + strip_prefix = add_prefix = add_suffix = NULL;
593 - memset(&rx, 0, sizeof(rx));
594 - rx.path = get_pool_memory(PM_FNAME);
597 - i = find_arg_with_value(ua, "where");
599 - rx.where = ua->argv[i];
601 - + add_suffix = ua->argv[i];
604 -++ i = find_arg(ua, "where_use_regexp");
606 -++ where_use_regexp = true;
609 -++ i = find_arg_with_value(ua, "rwhere");
611 -++ where_use_regexp = true;
612 -++ rx.where = ua->argv[i];
615 - + if (strip_prefix || add_suffix || add_prefix) {
616 - + where_use_regexp = true;
617 -++ have_to_free_where = true;
618 - + rx.where = bregexp_build_where(strip_prefix, add_prefix, add_suffix);
622 - if (!acl_access_ok(ua, Where_ACL, rx.where)) {
623 - ua->error_msg(_("\"where\" specification not authorized.\n"));
625 --@@ -195,9 +221,10 @@
626 -+@@ -195,9 +234,10 @@
629 - "run job=\"%s\" client=\"%s\" storage=\"%s\" bootstrap=\"%s\""
631 - escaped_where_name ? escaped_where_name : rx.where,
632 - rx.selected_files, ua->catalog->name());
634 --@@ -216,6 +243,10 @@
635 -+@@ -216,6 +256,10 @@
636 - if (escaped_where_name != NULL) {
637 - bfree(escaped_where_name);
640 --+ if (where_use_regexp) {
641 -++ if (have_to_free_where) {
642 - + free_pool_memory(rx.where);
645 - if (find_arg(ua, NT_("yes")) > 0) {
646 - pm_strcat(ua->cmd, " yes"); /* pass it on to the run command */
647 --@@ -235,6 +266,10 @@
648 -+@@ -235,6 +279,10 @@
649 - bfree(escaped_where_name);
652 --+ if (where_use_regexp) {
653 -++ if (have_to_free_where) {
654 - + free_pool_memory(rx.where);
660 -+@@ -331,23 +379,28 @@
662 -+ const char *kw[] = {
663 -+ /* These keywords are handled in a for loop */
665 -+- "current", /* 1 */
666 -+- "before", /* 2 */
668 -+- "directory", /* 4 */
669 -+- "select", /* 5 */
673 -++ "current", /* 1 */
674 -++ "before", /* 2 */
676 -++ "directory", /* 4 */
677 -++ "select", /* 5 */
681 -+ /* The keyword below are handled by individual arg lookups */
682 -+- "client", /* 8 */
683 -+- "storage", /* 9 */
684 -+- "fileset", /* 10 */
685 -+- "where", /* 11 */
687 -+- "bootstrap", /* 13 */
689 -++ "client", /* 8 */
690 -++ "storage", /* 9 */
691 -++ "fileset", /* 10 */
692 -++ "where", /* 11 */
694 -++ "bootstrap", /* 13 */
696 -++ "strip_prefix", /* 15 */
697 -++ "add_prefix", /* 16 */
698 -++ "add_suffix", /* 17 */
699 -++ "where_use_regexp",/* 18 */
700 -++ "rwhere", /* 19 like where + where_use_regexp */
704 - Index: src/dird/restore.c
705 - ===================================================================
706 - --- src/dird/restore.c (révision 4466)
707 -@@ -134,15 +191,26 @@
708 - ===================================================================
709 - --- src/dird/dird_conf.c (révision 4466)
710 - +++ src/dird/dird_conf.c (copie de travail)
711 --@@ -268,6 +268,7 @@
714 -+ #include "bacula.h"
716 -++#include "lib/breg.h"
718 -+ /* Define the first and last resource ID record
719 -+ * types. Note, these should be unique for each
720 -+@@ -268,6 +269,10 @@
721 - {"run", store_alist_str, ITEM(res_job.run_cmds), 0, 0, 0},
722 - /* Root of where to restore files */
723 - {"where", store_dir, ITEM(res_job.RestoreWhere), 0, 0, 0},
724 - + {"whereuseregexp", store_bool, ITEM(res_job.where_use_regexp), 0, 0, 0},
725 -++ {"stripprefix", store_str, ITEM(res_job.strip_prefix), 0, 0, 0},
726 -++ {"addprefix", store_str, ITEM(res_job.add_prefix), 0, 0, 0},
727 -++ {"addsuffix", store_str, ITEM(res_job.add_suffix), 0, 0, 0},
728 - /* Where to find bootstrap during restore */
729 - {"bootstrap",store_dir, ITEM(res_job.RestoreBootstrap), 0, 0, 0},
730 - /* Where to write bootstrap file during backup */
731 --@@ -611,6 +612,9 @@
732 -+@@ -611,6 +616,9 @@
733 - if (res->res_job.RestoreWhere) {
734 - sendit(sock, _(" --> Where=%s\n"), NPRT(res->res_job.RestoreWhere));
736 -@@ -152,6 +220,42 @@
737 - if (res->res_job.RestoreBootstrap) {
738 - sendit(sock, _(" --> Bootstrap=%s\n"), NPRT(res->res_job.RestoreBootstrap));
740 -+@@ -1143,6 +1151,15 @@
741 -+ if (res->res_job.RestoreWhere) {
742 -+ free(res->res_job.RestoreWhere);
744 -++ if (res->res_job.strip_prefix) {
745 -++ free(res->res_job.strip_prefix);
747 -++ if (res->res_job.add_prefix) {
748 -++ free(res->res_job.add_prefix);
750 -++ if (res->res_job.add_suffix) {
751 -++ free(res->res_job.add_suffix);
753 -+ if (res->res_job.RestoreBootstrap) {
754 -+ free(res->res_job.RestoreBootstrap);
756 -+@@ -1299,6 +1316,19 @@
757 -+ res->res_job.jobdefs = res_all.res_job.jobdefs;
758 -+ res->res_job.run_cmds = res_all.res_job.run_cmds;
759 -+ res->res_job.RunScripts = res_all.res_job.RunScripts;
760 -++ if (res->res_job.strip_prefix ||
761 -++ res->res_job.add_suffix ||
762 -++ res->res_job.add_prefix)
764 -++ if (res->res_job.RestoreWhere) {
765 -++ free(res->res_job.RestoreWhere);
767 -++ res->res_job.where_use_regexp = true;
768 -++ res->res_job.RestoreWhere=bregexp_build_where(res->res_job.strip_prefix,
769 -++ res->res_job.add_prefix,
770 -++ res->res_job.add_suffix);
771 -++ /* TODO: test bregexp */
775 -+ if ((res = (URES *)GetResWithName(R_COUNTER, res_all.res_counter.hdr.name)) == NULL) {
776 - Index: src/dird/ua_run.c
777 - ===================================================================
778 - --- src/dird/ua_run.c (révision 4466)
779 -@@ -227,10 +331,13 @@
780 - ===================================================================
781 - --- src/dird/dird_conf.h (révision 4466)
782 - +++ src/dird/dird_conf.h (copie de travail)
783 --@@ -356,6 +356,7 @@
784 -+@@ -356,6 +356,10 @@
785 - int Priority; /* Job priority */
786 - int RestoreJobId; /* What -- JobId to restore */
787 - char *RestoreWhere; /* Where on disk to restore -- directory */
788 -++ char *strip_prefix; /* remove prefix from filename */
789 -++ char *add_prefix; /* add prefix to filename */
790 -++ char *add_suffix; /* add suffix to filename -- .old */
791 - + bool where_use_regexp; /* true if RestoreWhere is a BREGEXP */
792 - char *RestoreBootstrap; /* Bootstrap file */
793 - alist *RunScripts; /* Run {client} program {after|before} Job */
794 -@@ -398,30 +505,3 @@
795 - if (jcr->cached_path) {
796 - free_pool_memory(jcr->cached_path);
797 - jcr->cached_path = NULL;
798 --Index: patches/testing/breg.c
799 --===================================================================
800 ----- patches/testing/breg.c (révision 4510)
801 --+++ patches/testing/breg.c (copie de travail)
802 --@@ -393,19 +393,19 @@
804 -- *str_tmp = *ret = '\0';
806 --- if (*strip_prefix) {
807 --+ if (strip_prefix) {
808 -- len += bsnprintf(ret, str_size - len, "!%s!!",
809 -- bregexp_escape_string(str_tmp, strip_prefix, sep));
812 --- if (*add_suffix) {
813 --+ if (add_suffix) {
814 -- if (len) ret[len++] = ',';
816 -- len += bsnprintf(ret + len, str_size - len, "!([^/])$!$1%s!",
817 -- bregexp_escape_string(str_tmp, add_suffix, sep));
820 --- if (*add_prefix) {
821 --+ if (add_prefix) {
822 -- if (len) ret[len++] = ',';
824 -- len += bsnprintf(ret + len, str_size - len, "!^!%s!",