1 Index: patches/testing/breg.c
2 ===================================================================
3 --- patches/testing/breg.c (révision 4529)
4 +++ patches/testing/breg.c (copie de travail)
6 * add_prefix = !^!add_prefix! 5 bytes
7 * add_suffix = !([^/])$!$1add_suffix! 13 bytes
9 - int str_size = (strip_prefix?strlen(strip_prefix)+4:0 +
10 - add_prefix?strlen(add_prefix)+5:0 + /* escape + 3*, + \0 */
11 - add_suffix?strlen(add_suffix)+14:0 ) * 2 + 3 + 1;
12 + int str_size = ((strip_prefix?strlen(strip_prefix)+4:0) +
13 + (add_prefix?strlen(add_prefix)+5 :0) + /* escape + 3*, + \0 */
14 + (add_suffix?strlen(add_suffix)+14 :0) ) * 2 + 3 + 1;
16 + Dmsg1(1, "bregexp_get_build_where_size = %i\n", str_size);
22 free_pool_memory(str_tmp);
29 Index: patches/testing/bregtest.c
30 ===================================================================
31 --- patches/testing/bregtest.c (révision 4529)
32 +++ patches/testing/bregtest.c (copie de travail)
35 int main(int argc, char *const *argv)
37 - printf("%s\n", bregexp_build_where("/tmp", NULL, ".old"));
40 + int len = bregexp_get_build_where_size("/tmp", "/tmp/toto", ".old");
42 + printf("%s\n", bregexp_build_where(tab, len, "/tmp", "/tmp/toto!", ".old"));
47 Index: patches/testing/breg.h
48 ===================================================================
49 --- patches/testing/breg.h (révision 4529)
50 +++ patches/testing/breg.h (copie de travail)
52 /* foreach_alist free RUNSCRIPT */
53 void free_bregexps(alist *bregexps); /* you have to free alist */
55 -/* get a bregexp string from user arguments */
56 -char *bregexp_build_where(char *strip_prefix,
57 +/* get regexp size */
58 +int bregexp_get_build_where_size(char *strip_prefix,
62 +/* get a bregexp string from user arguments
63 + * you must allocate it with bregexp_get_build_where_size();
65 +char *bregexp_build_where(char *dest, int str_size,
70 Index: src/dird/ua_restore.c
71 ===================================================================
72 --- src/dird/ua_restore.c (révision 4529)
73 +++ src/dird/ua_restore.c (copie de travail)
78 +#include "lib/breg.h"
81 /* Imported functions */
82 extern void print_bsr(UAContext *ua, RBSR *bsr);
86 char *escaped_bsr_name = NULL;
87 char *escaped_where_name = NULL;
88 + bool where_use_regexp = false;
89 + char *strip_prefix, *add_prefix, *add_suffix, *regexp;
90 + strip_prefix = add_prefix = add_suffix = regexp = NULL;
92 memset(&rx, 0, sizeof(rx));
93 rx.path = get_pool_memory(PM_FNAME);
95 i = find_arg_with_value(ua, "where");
97 rx.where = ua->argv[i];
100 + i = find_arg_with_value(ua, "strip_prefix");
102 + strip_prefix = ua->argv[i];
105 + i = find_arg_with_value(ua, "add_prefix");
107 + add_prefix = ua->argv[i];
110 + i = find_arg_with_value(ua, "add_suffix");
112 + add_suffix = ua->argv[i];
115 + i = find_arg(ua, "where_use_regexp");
117 + where_use_regexp = true;
120 + i = find_arg_with_value(ua, "rwhere");
122 + where_use_regexp = true;
123 + rx.where = ua->argv[i];
126 + if (strip_prefix || add_suffix || add_prefix) {
127 + int len = bregexp_get_build_where_size(strip_prefix, add_prefix, add_suffix);
128 + regexp = (char *) bmalloc (len * sizeof(char));
130 + bregexp_build_where(regexp, len, strip_prefix, add_prefix, add_suffix);
131 + where_use_regexp = true;
137 if (!acl_access_ok(ua, Where_ACL, rx.where)) {
138 ua->error_msg(_("\"where\" specification not authorized.\n"));
143 "run job=\"%s\" client=\"%s\" storage=\"%s\" bootstrap=\"%s\""
144 - " where=\"%s\" files=%d catalog=\"%s\"",
145 + " %swhere=\"%s\" files=%d catalog=\"%s\"",
146 job->name(), rx.ClientName, rx.store?rx.store->name():"",
147 escaped_bsr_name ? escaped_bsr_name : jcr->RestoreBootstrap,
148 + where_use_regexp ? "r" : "",
149 escaped_where_name ? escaped_where_name : rx.where,
150 rx.selected_files, ua->catalog->name());
153 if (escaped_where_name != NULL) {
154 bfree(escaped_where_name);
161 if (find_arg(ua, NT_("yes")) > 0) {
162 pm_strcat(ua->cmd, " yes"); /* pass it on to the run command */
164 bfree(escaped_where_name);
174 @@ -333,23 +384,28 @@
177 /* These keywords are handled in a for loop */
182 - "directory", /* 4 */
190 + "directory", /* 4 */
195 /* The keyword below are handled by individual arg lookups */
198 - "fileset", /* 10 */
201 - "bootstrap", /* 13 */
205 + "fileset", /* 10 */
208 + "bootstrap", /* 13 */
210 + "strip_prefix", /* 15 */
211 + "add_prefix", /* 16 */
212 + "add_suffix", /* 17 */
213 + "where_use_regexp",/* 18 */
214 + "rwhere", /* 19 like where + where_use_regexp */
218 Index: src/dird/restore.c
219 ===================================================================
220 --- src/dird/restore.c (révision 4529)
221 +++ src/dird/restore.c (copie de travail)
225 /* Commands sent to File daemon */
226 -static char restorecmd[] = "restore replace=%c prelinks=%d where=%s\n";
227 -static char storaddr[] = "storage address=%s port=%d ssl=0\n";
228 +static char restorecmd[] = "restore replace=%c prelinks=%d where=%s\n";
229 +static char restorecmdR[] = "restore replace=%c prelinks=%d rwhere=%s\n";
230 +static char storaddr[] = "storage address=%s port=%d ssl=0\n";
232 /* Responses received from File daemon */
233 static char OKrestore[] = "2000 OK restore\n";
237 /* Send restore command */
238 - char replace, *where;
239 + char replace, *where, *cmd;
242 if (jcr->replace != 0) {
245 where = ∅ /* None */
248 jcr->prefix_links = jcr->job->PrefixLinks;
250 + if (jcr->where_use_regexp) {
257 - bnet_fsend(fd, restorecmd, replace, jcr->prefix_links, where);
258 + bnet_fsend(fd, cmd, replace, jcr->prefix_links, where);
259 unbash_spaces(where);
261 if (!response(jcr, fd, OKrestore, "Restore", DISPLAY_ERROR)) {
262 Index: src/dird/dird_conf.c
263 ===================================================================
264 --- src/dird/dird_conf.c (révision 4529)
265 +++ src/dird/dird_conf.c (copie de travail)
270 +#include "lib/breg.h"
272 /* Define the first and last resource ID record
273 * types. Note, these should be unique for each
275 {"run", store_alist_str, ITEM(res_job.run_cmds), 0, 0, 0},
276 /* Root of where to restore files */
277 {"where", store_dir, ITEM(res_job.RestoreWhere), 0, 0, 0},
278 + {"whereuseregexp", store_bool, ITEM(res_job.where_use_regexp), 0, 0, 0},
279 + {"stripprefix", store_str, ITEM(res_job.strip_prefix), 0, 0, 0},
280 + {"addprefix", store_str, ITEM(res_job.add_prefix), 0, 0, 0},
281 + {"addsuffix", store_str, ITEM(res_job.add_suffix), 0, 0, 0},
282 /* Where to find bootstrap during restore */
283 {"bootstrap",store_dir, ITEM(res_job.RestoreBootstrap), 0, 0, 0},
284 /* Where to write bootstrap file during backup */
286 if (res->res_job.RestoreWhere) {
287 sendit(sock, _(" --> Where=%s\n"), NPRT(res->res_job.RestoreWhere));
289 + if (res->res_job.where_use_regexp) {
290 + sendit(sock, _(" --> RWhere=%u\n"), res->res_job.where_use_regexp);
292 if (res->res_job.RestoreBootstrap) {
293 sendit(sock, _(" --> Bootstrap=%s\n"), NPRT(res->res_job.RestoreBootstrap));
295 @@ -1143,6 +1151,15 @@
296 if (res->res_job.RestoreWhere) {
297 free(res->res_job.RestoreWhere);
299 + if (res->res_job.strip_prefix) {
300 + free(res->res_job.strip_prefix);
302 + if (res->res_job.add_prefix) {
303 + free(res->res_job.add_prefix);
305 + if (res->res_job.add_suffix) {
306 + free(res->res_job.add_suffix);
308 if (res->res_job.RestoreBootstrap) {
309 free(res->res_job.RestoreBootstrap);
311 @@ -1299,6 +1316,25 @@
312 res->res_job.jobdefs = res_all.res_job.jobdefs;
313 res->res_job.run_cmds = res_all.res_job.run_cmds;
314 res->res_job.RunScripts = res_all.res_job.RunScripts;
315 + if (res->res_job.strip_prefix ||
316 + res->res_job.add_suffix ||
317 + res->res_job.add_prefix)
319 + if (res->res_job.RestoreWhere) {
320 + free(res->res_job.RestoreWhere);
322 + int len = bregexp_get_build_where_size(res->res_job.strip_prefix,
323 + res->res_job.add_prefix,
324 + res->res_job.add_suffix);
325 + res->res_job.RestoreWhere = (char *) bmalloc (len * sizeof(char));
326 + bregexp_build_where(res->res_job.RestoreWhere, len,
327 + res->res_job.strip_prefix,
328 + res->res_job.add_prefix,
329 + res->res_job.add_suffix);
330 + res->res_job.where_use_regexp = true;
332 + /* TODO: test bregexp */
336 if ((res = (URES *)GetResWithName(R_COUNTER, res_all.res_counter.hdr.name)) == NULL) {
337 Index: src/dird/ua_run.c
338 ===================================================================
339 --- src/dird/ua_run.c (révision 4529)
340 +++ src/dird/ua_run.c (copie de travail)
345 +#include "lib/breg.h"
347 /* Forward referenced subroutines */
348 static void select_job_level(UAContext *ua, JCR *jcr);
349 static bool display_job_parameters(UAContext *ua, JCR *jcr, JOB *job, char *verify_list,
350 char *jid, const char *replace);
351 +static void select_where_regexp(UAContext *ua, JCR *jcr);
354 /* Imported variables */
357 int i, j, opt, files = 0;
359 + bool where_use_regexp = false;
361 JOB *verify_job = NULL;
362 JOB *previous_job = NULL;
368 + "rwhere", /* 8 where string as a bregexp */
370 "bootstrap", /* 10 */
373 "cloned", /* 19 cloned */
374 "verifylist", /* 20 verify output list */
375 "migrationjob", /* 21 migration job name */
380 @@ -188,15 +192,10 @@
381 store_name = ua->argv[i];
386 - ua->send_msg(_("Pool specified twice.\n"));
389 - pool_name = ua->argv[i];
392 + case 8: /* rwhere */
394 + where_use_regexp = (j == 9)?false:true; /* rwhere or where ? */
397 ua->send_msg(_("Where specified twice.\n"));
400 previous_job_name = ua->argv[i];
403 + case 22: /* pool */
405 + ua->send_msg(_("Pool specified twice.\n"));
408 + pool_name = ua->argv[i];
419 jcr->where = bstrdup(where);
420 + jcr->where_use_regexp = where_use_regexp;
425 } else if (jcr->JobType == JT_RESTORE) {
426 add_prompt(ua, _("Bootstrap")); /* 7 */
427 add_prompt(ua, _("Where")); /* 8 */
428 - add_prompt(ua, _("Replace")); /* 9 */
429 - add_prompt(ua, _("JobId")); /* 10 */
430 + add_prompt(ua, _("File Relocation"));/* 9 */
431 + add_prompt(ua, _("Replace")); /* 10 */
432 + add_prompt(ua, _("JobId")); /* 11 */
434 switch (do_prompt(ua, "", _("Select parameter to modify"), NULL, 0)) {
439 jcr->where = bstrdup(ua->cmd);
440 + jcr->where_use_regexp = false;
444 + /* File relocation */
445 + select_where_regexp(ua, jcr);
449 start_prompt(ua, _("Replace:\n"));
450 for (i=0; ReplaceOptions[i].name; i++) {
452 jcr->replace = ReplaceOptions[opt].token;
458 jid = NULL; /* force reprompt */
459 jcr->RestoreJobId = 0;
460 @@ -775,6 +788,131 @@
461 return 0; /* do not run */
464 +static void select_where_regexp(UAContext *ua, JCR *jcr)
467 + char *strip_prefix, *add_prefix, *add_suffix, *rwhere;
468 + strip_prefix = add_suffix = rwhere = add_prefix = NULL;
471 + start_prompt(ua, _("This will replace your current Where value\n"));
472 + add_prompt(ua, _("Strip prefix")); /* 0 */
473 + add_prompt(ua, _("Add prefix")); /* 1 */
474 + add_prompt(ua, _("Add file suffix")); /* 2 */
475 + add_prompt(ua, _("Enter a regexp")); /* 3 */
476 + add_prompt(ua, _("Test filename manipulation")); /* 4 */
477 + add_prompt(ua, _("Use this ?")); /* 5 */
479 + switch (do_prompt(ua, "", _("Select parameter to modify"), NULL, 0)) {
482 + if (get_cmd(ua, _("Please enter path prefix to strip: "))) {
483 + if (strip_prefix) bfree(strip_prefix);
484 + strip_prefix = bstrdup(ua->cmd);
487 + goto try_again_reg;
490 + if (get_cmd(ua, _("Please enter path prefix to add (/ for none): "))) {
491 + if (IsPathSeparator(ua->cmd[0]) && ua->cmd[1] == '\0') {
495 + if (add_prefix) bfree(add_prefix);
496 + add_prefix = bstrdup(ua->cmd);
498 + goto try_again_reg;
501 + if (get_cmd(ua, _("Please enter file suffix to add: "))) {
502 + if (add_suffix) bfree(add_suffix);
503 + add_suffix = bstrdup(ua->cmd);
505 + goto try_again_reg;
508 + if (get_cmd(ua, _("Please enter a valid regexp (!from!to!): "))) {
509 + if (rwhere) bfree(rwhere);
510 + rwhere = bstrdup(ua->cmd);
513 + goto try_again_reg;
519 + if (rwhere && rwhere[0] != '\0') {
520 + regs = get_bregexps(rwhere);
521 + ua->send_msg(_("rwhere=%s\n"), NPRT(rwhere));
523 + int len = bregexp_get_build_where_size(strip_prefix, add_prefix, add_suffix);
524 + regexp = (char *) bmalloc (len * sizeof(char));
525 + bregexp_build_where(regexp, len, strip_prefix, add_prefix, add_suffix);
526 + regs = get_bregexps(regexp);
527 + ua->send_msg(_("strip_prefix=%s add_prefix=%s add_suffix=%s result=%s\n"),
528 + NPRT(strip_prefix), NPRT(add_prefix), NPRT(add_suffix), NPRT(regexp));
534 + ua->send_msg(_("Cannot use your regexp\n"));
535 + goto try_again_reg;
538 + while (get_cmd(ua, _("Please enter filename to test: "))) {
539 + apply_bregexps(ua->cmd, regs, &result);
540 + ua->send_msg(_("%s -> %s\n"), ua->cmd, result);
542 + free_bregexps(regs);
544 + goto try_again_reg;
549 + case -1: /* error or cancel */
552 + goto try_again_reg;
555 + /* replace the existing where */
562 + jcr->where = bstrdup(rwhere);
563 + } else if (strip_prefix || add_prefix || add_suffix) {
564 + int len = bregexp_get_build_where_size(strip_prefix, add_prefix, add_suffix);
565 + jcr->where = (char *) bmalloc(len*sizeof(char));
566 + bregexp_build_where(jcr->where, len, strip_prefix, add_prefix, add_suffix);
569 + regs = get_bregexps(jcr->where);
571 + free_bregexps(regs);
573 + jcr->where_use_regexp = true;
579 + ua->send_msg(_("Cannot use your regexp.\n"));
583 + if (strip_prefix) bfree(strip_prefix);
584 + if (add_prefix) bfree(add_prefix);
585 + if (add_suffix) bfree(add_suffix);
586 + if (rwhere) bfree(rwhere);
589 static void select_job_level(UAContext *ua, JCR *jcr)
591 if (jcr->JobType == JT_BACKUP) {
592 Index: src/dird/dird_conf.h
593 ===================================================================
594 --- src/dird/dird_conf.h (révision 4529)
595 +++ src/dird/dird_conf.h (copie de travail)
597 int Priority; /* Job priority */
598 int RestoreJobId; /* What -- JobId to restore */
599 char *RestoreWhere; /* Where on disk to restore -- directory */
600 + char *strip_prefix; /* remove prefix from filename */
601 + char *add_prefix; /* add prefix to filename */
602 + char *add_suffix; /* add suffix to filename -- .old */
603 + bool where_use_regexp; /* true if RestoreWhere is a BREGEXP */
604 char *RestoreBootstrap; /* Bootstrap file */
605 alist *RunScripts; /* Run {client} program {after|before} Job */
607 Index: src/filed/job.c
608 ===================================================================
609 --- src/filed/job.c (révision 4529)
610 +++ src/filed/job.c (copie de travail)
615 +#include "lib/breg.h"
617 #if defined(WIN32_VSS)
620 static char sessioncmd[] = "session %127s %ld %ld %ld %ld %ld %ld\n";
621 static char restorecmd[] = "restore replace=%c prelinks=%d where=%s\n";
622 static char restorecmd1[] = "restore replace=%c prelinks=%d where=\n";
623 +static char restorecmdR[] = "restore replace=%c prelinks=%d rwhere=%s\n";
624 static char verifycmd[] = "verify level=%30s";
625 static char estimatecmd[] = "estimate listing=%d";
626 static char runbefore[] = "RunBeforeJob %s";
627 @@ -1586,12 +1588,15 @@
630 if (sscanf(dir->msg, restorecmd, &replace, &prefix_links, where) != 3) {
631 - if (sscanf(dir->msg, restorecmd1, &replace, &prefix_links) != 2) {
632 - pm_strcpy(jcr->errmsg, dir->msg);
633 - Jmsg(jcr, M_FATAL, 0, _("Bad replace command. CMD=%s\n"), jcr->errmsg);
635 + if (sscanf(dir->msg, restorecmdR, &replace, &prefix_links, where) != 3){
636 + if (sscanf(dir->msg, restorecmd1, &replace, &prefix_links) != 2) {
637 + pm_strcpy(jcr->errmsg, dir->msg);
638 + Jmsg(jcr, M_FATAL, 0, _("Bad replace command. CMD=%s\n"), jcr->errmsg);
644 + jcr->where_use_regexp = true;
646 /* Turn / into nothing */
647 if (IsPathSeparator(where[0]) && where[1] == '\0') {
648 @@ -1601,6 +1606,15 @@
649 Dmsg2(150, "Got replace %c, where=%s\n", replace, where);
650 unbash_spaces(where);
651 jcr->where = bstrdup(where);
653 + if (jcr->where_use_regexp) {
654 + jcr->where_bregexp = get_bregexps(jcr->where);
655 + if (!jcr->where_bregexp) {
656 + Jmsg(jcr, M_FATAL, 0, _("Bad where regexp. where=%s\n"), jcr->where);
657 + free_pool_memory(where);
661 free_pool_memory(where);
662 jcr->replace = replace;
663 jcr->prefix_links = prefix_links;
665 ===================================================================
666 --- src/jcr.h (révision 4529)
667 +++ src/jcr.h (copie de travail)
669 MSGS *jcr_msgs; /* Copy of message resource -- actually used */
670 uint32_t ClientId; /* Client associated with Job */
671 char *where; /* prefix to restore files to */
672 + bool where_use_regexp; /* True if where is a bregexp */
673 + alist *where_bregexp; /* BREGEXP alist for path manipulation */
674 int cached_pnl; /* cached path length */
675 POOLMEM *cached_path; /* cached path */
676 bool prefix_links; /* Prefix links with Where path */
677 Index: src/lib/Makefile.in
678 ===================================================================
679 --- src/lib/Makefile.in (révision 4529)
680 +++ src/lib/Makefile.in (copie de travail)
682 res.c rwlock.c scan.c serial.c sha1.c \
683 signal.c smartall.c rblist.c tls.c tree.c \
684 util.c var.c watchdog.c workq.c btimers.c \
685 - address_conf.c pythonlib.c
686 + address_conf.c pythonlib.c breg.c
689 LIBOBJS = attr.o base64.o berrno.o bsys.o bget_msg.o \
691 res.o rwlock.o scan.o serial.o sha1.o \
692 signal.o smartall.o rblist.o tls.o tree.o \
693 util.o var.o watchdog.o workq.o btimers.o \
694 - address_conf.o pythonlib.o
695 + address_conf.o pythonlib.o breg.o
698 EXTRAOBJS = @OBJLIST@
699 Index: src/lib/attr.c
700 ===================================================================
701 --- src/lib/attr.c (révision 4529)
702 +++ src/lib/attr.c (copie de travail)
707 +#include "lib/breg.h"
712 ATTR *attr = (ATTR *)malloc(sizeof(ATTR));
714 * every filename if a prefix is supplied.
718 if (jcr->where[0] == 0) {
719 pm_strcpy(attr->ofname, attr->fname);
720 pm_strcpy(attr->olname, attr->lname);
722 + } else if (jcr->where_bregexp) {
724 + apply_bregexps(attr->fname, jcr->where_bregexp, &ret);
725 + pm_strcpy(attr->ofname, ret);
727 + if (attr->type == FT_LNKSAVED || attr->type == FT_LNK) {
728 + /* Always add prefix to hard links (FT_LNKSAVED) and
729 + * on user request to soft links
732 + if ((attr->type == FT_LNKSAVED || jcr->prefix_links)) {
733 + apply_bregexps(attr->lname, jcr->where_bregexp, &ret);
734 + pm_strcpy(attr->olname, ret);
737 + pm_strcpy(attr->olname, attr->lname);
743 int wherelen = strlen(jcr->where);
745 ===================================================================
746 --- src/lib/jcr.c (révision 4529)
747 +++ src/lib/jcr.c (copie de travail)
749 /* External variables we reference */
750 extern time_t watchdog_time;
752 +/* External referenced functions */
753 +void free_bregexps(alist *bregexps);
755 /* Forward referenced functions */
756 extern "C" void timeout_handler(int sig);
757 static void jcr_timeout_check(watchdog_t *self);
762 + if (jcr->where_bregexp) {
763 + free_bregexps(jcr->where_bregexp);
764 + delete jcr->where_bregexp;
765 + jcr->where_bregexp = NULL;
767 if (jcr->cached_path) {
768 free_pool_memory(jcr->cached_path);
769 jcr->cached_path = NULL;