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, *regexp;
21 + strip_prefix = add_prefix = add_suffix = regexp = 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 + i = find_arg(ua, "where_use_regexp");
48 + where_use_regexp = true;
51 + i = find_arg_with_value(ua, "rwhere");
53 + where_use_regexp = true;
54 + rx.where = ua->argv[i];
57 + if (strip_prefix || add_suffix || add_prefix) {
58 + int len = bregexp_get_build_where_size(strip_prefix, add_prefix, add_suffix);
59 + regexp = (char *) bmalloc (len * sizeof(char));
61 + bregexp_build_where(regexp, len, strip_prefix, add_prefix, add_suffix);
62 + where_use_regexp = true;
68 if (!acl_access_ok(ua, Where_ACL, rx.where)) {
69 ua->error_msg(_("\"where\" specification not authorized.\n"));
74 "run job=\"%s\" client=\"%s\" storage=\"%s\" bootstrap=\"%s\""
75 - " where=\"%s\" files=%d catalog=\"%s\"",
76 + " %swhere=\"%s\" files=%d catalog=\"%s\"",
77 job->name(), rx.ClientName, rx.store?rx.store->name():"",
78 escaped_bsr_name ? escaped_bsr_name : jcr->RestoreBootstrap,
79 + where_use_regexp ? "r" : "",
80 escaped_where_name ? escaped_where_name : rx.where,
81 rx.selected_files, ua->catalog->name());
84 if (escaped_where_name != NULL) {
85 bfree(escaped_where_name);
92 if (find_arg(ua, NT_("yes")) > 0) {
93 pm_strcat(ua->cmd, " yes"); /* pass it on to the run command */
95 bfree(escaped_where_name);
105 @@ -331,23 +382,28 @@
108 /* These keywords are handled in a for loop */
113 - "directory", /* 4 */
121 + "directory", /* 4 */
126 /* The keyword below are handled by individual arg lookups */
129 - "fileset", /* 10 */
132 - "bootstrap", /* 13 */
136 + "fileset", /* 10 */
139 + "bootstrap", /* 13 */
141 + "strip_prefix", /* 15 */
142 + "add_prefix", /* 16 */
143 + "add_suffix", /* 17 */
144 + "where_use_regexp",/* 18 */
145 + "rwhere", /* 19 like where + where_use_regexp */
149 Index: src/dird/restore.c
150 ===================================================================
151 --- src/dird/restore.c (révision 4466)
152 +++ src/dird/restore.c (copie de travail)
156 /* Commands sent to File daemon */
157 -static char restorecmd[] = "restore replace=%c prelinks=%d where=%s\n";
158 -static char storaddr[] = "storage address=%s port=%d ssl=0\n";
159 +static char restorecmd[] = "restore replace=%c prelinks=%d where=%s\n";
160 +static char restorecmdR[] = "restore replace=%c prelinks=%d rwhere=%s\n";
161 +static char storaddr[] = "storage address=%s port=%d ssl=0\n";
163 /* Responses received from File daemon */
164 static char OKrestore[] = "2000 OK restore\n";
168 /* Send restore command */
169 - char replace, *where;
170 + char replace, *where, *cmd;
173 if (jcr->replace != 0) {
176 where = ∅ /* None */
179 jcr->prefix_links = jcr->job->PrefixLinks;
181 + if (jcr->where_use_regexp) {
188 - bnet_fsend(fd, restorecmd, replace, jcr->prefix_links, where);
189 + bnet_fsend(fd, cmd, replace, jcr->prefix_links, where);
190 unbash_spaces(where);
192 if (!response(jcr, fd, OKrestore, "Restore", DISPLAY_ERROR)) {
193 Index: src/dird/dird_conf.c
194 ===================================================================
195 --- src/dird/dird_conf.c (révision 4466)
196 +++ src/dird/dird_conf.c (copie de travail)
201 +#include "lib/breg.h"
203 /* Define the first and last resource ID record
204 * types. Note, these should be unique for each
206 {"run", store_alist_str, ITEM(res_job.run_cmds), 0, 0, 0},
207 /* Root of where to restore files */
208 {"where", store_dir, ITEM(res_job.RestoreWhere), 0, 0, 0},
209 + {"whereuseregexp", store_bool, ITEM(res_job.where_use_regexp), 0, 0, 0},
210 + {"stripprefix", store_str, ITEM(res_job.strip_prefix), 0, 0, 0},
211 + {"addprefix", store_str, ITEM(res_job.add_prefix), 0, 0, 0},
212 + {"addsuffix", store_str, ITEM(res_job.add_suffix), 0, 0, 0},
213 /* Where to find bootstrap during restore */
214 {"bootstrap",store_dir, ITEM(res_job.RestoreBootstrap), 0, 0, 0},
215 /* Where to write bootstrap file during backup */
217 if (res->res_job.RestoreWhere) {
218 sendit(sock, _(" --> Where=%s\n"), NPRT(res->res_job.RestoreWhere));
220 + if (res->res_job.where_use_regexp) {
221 + sendit(sock, _(" --> RWhere=%u\n"), res->res_job.where_use_regexp);
223 if (res->res_job.RestoreBootstrap) {
224 sendit(sock, _(" --> Bootstrap=%s\n"), NPRT(res->res_job.RestoreBootstrap));
226 @@ -1143,6 +1151,15 @@
227 if (res->res_job.RestoreWhere) {
228 free(res->res_job.RestoreWhere);
230 + if (res->res_job.strip_prefix) {
231 + free(res->res_job.strip_prefix);
233 + if (res->res_job.add_prefix) {
234 + free(res->res_job.add_prefix);
236 + if (res->res_job.add_suffix) {
237 + free(res->res_job.add_suffix);
239 if (res->res_job.RestoreBootstrap) {
240 free(res->res_job.RestoreBootstrap);
242 @@ -1299,6 +1316,19 @@
243 res->res_job.jobdefs = res_all.res_job.jobdefs;
244 res->res_job.run_cmds = res_all.res_job.run_cmds;
245 res->res_job.RunScripts = res_all.res_job.RunScripts;
246 + if (res->res_job.strip_prefix ||
247 + res->res_job.add_suffix ||
248 + res->res_job.add_prefix)
250 + if (res->res_job.RestoreWhere) {
251 + free(res->res_job.RestoreWhere);
253 + res->res_job.where_use_regexp = true;
254 + res->res_job.RestoreWhere=bregexp_build_where(res->res_job.strip_prefix,
255 + res->res_job.add_prefix,
256 + res->res_job.add_suffix);
257 + /* TODO: test bregexp */
261 if ((res = (URES *)GetResWithName(R_COUNTER, res_all.res_counter.hdr.name)) == NULL) {
262 Index: src/dird/ua_run.c
263 ===================================================================
264 --- src/dird/ua_run.c (révision 4466)
265 +++ src/dird/ua_run.c (copie de travail)
270 +#include "lib/breg.h"
272 /* Forward referenced subroutines */
273 static void select_job_level(UAContext *ua, JCR *jcr);
274 static bool display_job_parameters(UAContext *ua, JCR *jcr, JOB *job, char *verify_list,
275 char *jid, const char *replace);
276 +static void select_where_regexp(UAContext *ua, JCR *jcr);
279 /* Imported variables */
280 extern struct s_kw ReplaceOptions[];
284 int i, j, opt, files = 0;
286 + bool where_use_regexp = false;
288 JOB *verify_job = NULL;
289 JOB *previous_job = NULL;
295 + "rwhere", /* 8 where string as a bregexp */
297 "bootstrap", /* 10 */
300 "cloned", /* 19 cloned */
301 "verifylist", /* 20 verify output list */
302 "migrationjob", /* 21 migration job name */
308 store_name = ua->argv[i];
313 - ua->send_msg(_("Pool specified twice.\n"));
316 - pool_name = ua->argv[i];
319 + case 8: /* rwhere */
320 + where_use_regexp = true;
323 ua->send_msg(_("Where specified twice.\n"));
325 previous_job_name = ua->argv[i];
328 + case 22: /* pool */
330 + ua->send_msg(_("Pool specified twice.\n"));
333 + pool_name = ua->argv[i];
344 jcr->where = bstrdup(where);
345 + jcr->where_use_regexp = where_use_regexp;
350 } else if (jcr->JobType == JT_RESTORE) {
351 add_prompt(ua, _("Bootstrap")); /* 7 */
352 add_prompt(ua, _("Where")); /* 8 */
353 - add_prompt(ua, _("Replace")); /* 9 */
354 - add_prompt(ua, _("JobId")); /* 10 */
355 + add_prompt(ua, _("File Relocation"));/* 9 */
356 + add_prompt(ua, _("Replace")); /* 10 */
357 + add_prompt(ua, _("JobId")); /* 11 */
359 switch (do_prompt(ua, "", _("Select parameter to modify"), NULL, 0)) {
364 jcr->where = bstrdup(ua->cmd);
365 + jcr->where_use_regexp = false;
369 + /* File relocation */
370 + select_where_regexp(ua, jcr);
374 start_prompt(ua, _("Replace:\n"));
375 for (i=0; ReplaceOptions[i].name; i++) {
377 jcr->replace = ReplaceOptions[opt].token;
383 jid = NULL; /* force reprompt */
384 jcr->RestoreJobId = 0;
385 @@ -775,6 +786,127 @@
386 return 0; /* do not run */
389 +static void select_where_regexp(UAContext *ua, JCR *jcr)
392 + char *strip_prefix, *add_prefix, *add_suffix, *rwhere;
393 + strip_prefix = add_suffix = rwhere = add_prefix = NULL;
396 + start_prompt(ua, _("This will replace your current Where value\n"));
397 + add_prompt(ua, _("Strip prefix")); /* 0 */
398 + add_prompt(ua, _("Add prefix")); /* 1 */
399 + add_prompt(ua, _("Add file suffix")); /* 2 */
400 + add_prompt(ua, _("Enter a regexp")); /* 3 */
401 + add_prompt(ua, _("Test filename manipulation")); /* 4 */
402 + add_prompt(ua, _("Use this ?")); /* 5 */
404 + switch (do_prompt(ua, "", _("Select parameter to modify"), NULL, 0)) {
407 + if (get_cmd(ua, _("Please enter path prefix to strip: "))) {
408 + if (strip_prefix) free(strip_prefix);
409 + strip_prefix = bstrdup(ua->cmd);
412 + goto try_again_reg;
415 + if (get_cmd(ua, _("Please enter path prefix to add (/ for none): "))) {
416 + if (IsPathSeparator(ua->cmd[0]) && ua->cmd[1] == '\0') {
420 + if (add_prefix) free(add_prefix);
421 + add_prefix = bstrdup(ua->cmd);
423 + goto try_again_reg;
426 + if (get_cmd(ua, _("Please enter file suffix to add: "))) {
427 + if (add_suffix) free(add_suffix);
428 + add_suffix = bstrdup(ua->cmd);
430 + goto try_again_reg;
433 + if (get_cmd(ua, _("Please enter a valid regexp (!from!to!): "))) {
434 + if (rwhere) free(rwhere);
435 + rwhere = bstrdup(ua->cmd);
438 + goto try_again_reg;
444 + ua->send_msg(_("rwhere=%s strip_prefix=%s add_prefix=%s add_suffix=%\n"),
445 + NPRT(rwhere), NPRT(strip_prefix), NPRT(add_prefix), NPRT(add_suffix));
448 + if (rwhere && rwhere[0] != '\0') {
449 + regs = get_bregexps(rwhere);
451 + regexp = bregexp_build_where(strip_prefix, add_prefix, add_suffix);
452 + regs = get_bregexps(regexp);
457 + ua->send_msg(_("Cannot use your regexp\n"));
458 + goto try_again_reg;
461 + while (get_cmd(ua, _("Please enter filename to test: "))) {
462 + apply_bregexps(ua->cmd, regs, &result);
463 + ua->send_msg(_("%s -> %s\n"), ua->cmd, result);
465 + free_bregexps(regs);
467 + goto try_again_reg;
472 + case -1: /* error or cancel */
475 + goto try_again_reg;
478 + /* replace the existing where */
485 + jcr->where = bstrdup(rwhere);
486 + } else if (strip_prefix || add_prefix || add_suffix) {
487 + jcr->where = bregexp_build_where(strip_prefix, add_prefix, add_suffix);
490 + regs = get_bregexps(jcr->where);
492 + free_bregexps(regs);
494 + jcr->where_use_regexp = true;
500 + ua->send_msg(_("Cannot use your regexp.\n"));
504 + if (strip_prefix) free(strip_prefix);
505 + if (add_prefix) free(add_prefix);
506 + if (add_suffix) free(add_suffix);
507 + if (rwhere) free(rwhere);
510 static void select_job_level(UAContext *ua, JCR *jcr)
512 if (jcr->JobType == JT_BACKUP) {
513 Index: src/dird/dird_conf.h
514 ===================================================================
515 --- src/dird/dird_conf.h (révision 4466)
516 +++ src/dird/dird_conf.h (copie de travail)
518 int Priority; /* Job priority */
519 int RestoreJobId; /* What -- JobId to restore */
520 char *RestoreWhere; /* Where on disk to restore -- directory */
521 + char *strip_prefix; /* remove prefix from filename */
522 + char *add_prefix; /* add prefix to filename */
523 + char *add_suffix; /* add suffix to filename -- .old */
524 + bool where_use_regexp; /* true if RestoreWhere is a BREGEXP */
525 char *RestoreBootstrap; /* Bootstrap file */
526 alist *RunScripts; /* Run {client} program {after|before} Job */
528 Index: src/filed/job.c
529 ===================================================================
530 --- src/filed/job.c (révision 4467)
531 +++ src/filed/job.c (copie de travail)
536 +#include "lib/breg.h"
538 #if defined(WIN32_VSS)
541 static char sessioncmd[] = "session %127s %ld %ld %ld %ld %ld %ld\n";
542 static char restorecmd[] = "restore replace=%c prelinks=%d where=%s\n";
543 static char restorecmd1[] = "restore replace=%c prelinks=%d where=\n";
544 +static char restorecmdR[] = "restore replace=%c prelinks=%d rwhere=%s\n";
545 static char verifycmd[] = "verify level=%30s";
546 static char estimatecmd[] = "estimate listing=%d";
547 static char runbefore[] = "RunBeforeJob %s";
548 @@ -1586,12 +1588,15 @@
551 if (sscanf(dir->msg, restorecmd, &replace, &prefix_links, where) != 3) {
552 - if (sscanf(dir->msg, restorecmd1, &replace, &prefix_links) != 2) {
553 - pm_strcpy(jcr->errmsg, dir->msg);
554 - Jmsg(jcr, M_FATAL, 0, _("Bad replace command. CMD=%s\n"), jcr->errmsg);
556 + if (sscanf(dir->msg, restorecmdR, &replace, &prefix_links, where) != 3){
557 + if (sscanf(dir->msg, restorecmd1, &replace, &prefix_links) != 2) {
558 + pm_strcpy(jcr->errmsg, dir->msg);
559 + Jmsg(jcr, M_FATAL, 0, _("Bad replace command. CMD=%s\n"), jcr->errmsg);
565 + jcr->where_use_regexp = true;
567 /* Turn / into nothing */
568 if (IsPathSeparator(where[0]) && where[1] == '\0') {
569 @@ -1601,6 +1606,15 @@
570 Dmsg2(150, "Got replace %c, where=%s\n", replace, where);
571 unbash_spaces(where);
572 jcr->where = bstrdup(where);
574 + if (jcr->where_use_regexp) {
575 + jcr->where_bregexp = get_bregexps(jcr->where);
576 + if (!jcr->where_bregexp) {
577 + Jmsg(jcr, M_FATAL, 0, _("Bad where regexp. where=%s\n"), jcr->where);
578 + free_pool_memory(where);
582 free_pool_memory(where);
583 jcr->replace = replace;
584 jcr->prefix_links = prefix_links;
586 ===================================================================
587 --- src/jcr.h (révision 4466)
588 +++ src/jcr.h (copie de travail)
590 MSGS *jcr_msgs; /* Copy of message resource -- actually used */
591 uint32_t ClientId; /* Client associated with Job */
592 char *where; /* prefix to restore files to */
593 + bool where_use_regexp; /* True if where is a bregexp */
594 + alist *where_bregexp; /* BREGEXP alist for path manipulation */
595 int cached_pnl; /* cached path length */
596 POOLMEM *cached_path; /* cached path */
597 bool prefix_links; /* Prefix links with Where path */
598 Index: src/lib/Makefile.in
599 ===================================================================
600 --- src/lib/Makefile.in (révision 4466)
601 +++ src/lib/Makefile.in (copie de travail)
603 res.c rwlock.c scan.c serial.c sha1.c \
604 signal.c smartall.c rblist.c tls.c tree.c \
605 util.c var.c watchdog.c workq.c btimers.c \
606 - address_conf.c pythonlib.c
607 + address_conf.c pythonlib.c breg.c
610 LIBOBJS = attr.o base64.o berrno.o bsys.o bget_msg.o \
612 res.o rwlock.o scan.o serial.o sha1.o \
613 signal.o smartall.o rblist.o tls.o tree.o \
614 util.o var.o watchdog.o workq.o btimers.o \
615 - address_conf.o pythonlib.o
616 + address_conf.o pythonlib.o breg.o
619 EXTRAOBJS = @OBJLIST@
620 Index: src/lib/attr.c
621 ===================================================================
622 --- src/lib/attr.c (révision 4466)
623 +++ src/lib/attr.c (copie de travail)
628 +#include "lib/breg.h"
633 ATTR *attr = (ATTR *)malloc(sizeof(ATTR));
635 * every filename if a prefix is supplied.
639 if (jcr->where[0] == 0) {
640 pm_strcpy(attr->ofname, attr->fname);
641 pm_strcpy(attr->olname, attr->lname);
643 + } else if (jcr->where_bregexp) {
645 + apply_bregexps(attr->fname, jcr->where_bregexp, &ret);
646 + pm_strcpy(attr->ofname, ret);
648 + if (attr->type == FT_LNKSAVED || attr->type == FT_LNK) {
649 + /* Always add prefix to hard links (FT_LNKSAVED) and
650 + * on user request to soft links
653 + if ((attr->type == FT_LNKSAVED || jcr->prefix_links)) {
654 + apply_bregexps(attr->lname, jcr->where_bregexp, &ret);
655 + pm_strcpy(attr->olname, ret);
658 + pm_strcpy(attr->olname, attr->lname);
664 int wherelen = strlen(jcr->where);
666 ===================================================================
667 --- src/lib/jcr.c (révision 4466)
668 +++ src/lib/jcr.c (copie de travail)
670 /* External variables we reference */
671 extern time_t watchdog_time;
673 +/* External referenced functions */
674 +void free_bregexps(alist *bregexps);
676 /* Forward referenced functions */
677 extern "C" void timeout_handler(int sig);
678 static void jcr_timeout_check(watchdog_t *self);
683 + if (jcr->where_bregexp) {
684 + free_bregexps(jcr->where_bregexp);
685 + delete jcr->where_bregexp;
686 + jcr->where_bregexp = NULL;
688 if (jcr->cached_path) {
689 free_pool_memory(jcr->cached_path);
690 jcr->cached_path = NULL;