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 + rx.where = bregexp_build_where(strip_prefix, add_prefix, add_suffix);
60 + where_use_regexp = true;
61 + have_to_free_where = true;
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)
267 +#include "lib/breg.h"
269 /* Forward referenced subroutines */
270 static void select_job_level(UAContext *ua, JCR *jcr);
271 static bool display_job_parameters(UAContext *ua, JCR *jcr, JOB *job, char *verify_list,
272 char *jid, const char *replace);
273 +static void select_where_regexp(UAContext *ua, JCR *jcr);
276 /* Imported variables */
277 extern struct s_kw ReplaceOptions[];
281 int i, j, opt, files = 0;
283 + bool where_use_regexp = false;
285 JOB *verify_job = NULL;
286 JOB *previous_job = NULL;
292 + "rwhere", /* 8 where string as a bregexp */
294 "bootstrap", /* 10 */
297 "cloned", /* 19 cloned */
298 "verifylist", /* 20 verify output list */
299 "migrationjob", /* 21 migration job name */
305 store_name = ua->argv[i];
310 - ua->send_msg(_("Pool specified twice.\n"));
313 - pool_name = ua->argv[i];
316 + case 8: /* rwhere */
317 + where_use_regexp = true;
320 ua->send_msg(_("Where specified twice.\n"));
322 previous_job_name = ua->argv[i];
325 + case 22: /* pool */
327 + ua->send_msg(_("Pool specified twice.\n"));
330 + pool_name = ua->argv[i];
341 jcr->where = bstrdup(where);
342 + jcr->where_use_regexp = where_use_regexp;
347 } else if (jcr->JobType == JT_RESTORE) {
348 add_prompt(ua, _("Bootstrap")); /* 7 */
349 add_prompt(ua, _("Where")); /* 8 */
350 - add_prompt(ua, _("Replace")); /* 9 */
351 - add_prompt(ua, _("JobId")); /* 10 */
352 + add_prompt(ua, _("File Relocation"));/* 9 */
353 + add_prompt(ua, _("Replace")); /* 10 */
354 + add_prompt(ua, _("JobId")); /* 11 */
356 switch (do_prompt(ua, "", _("Select parameter to modify"), NULL, 0)) {
361 jcr->where = bstrdup(ua->cmd);
362 + jcr->where_use_regexp = false;
366 + /* File relocation */
367 + select_where_regexp(ua, jcr);
371 start_prompt(ua, _("Replace:\n"));
372 for (i=0; ReplaceOptions[i].name; i++) {
374 jcr->replace = ReplaceOptions[opt].token;
380 jid = NULL; /* force reprompt */
381 jcr->RestoreJobId = 0;
382 @@ -775,6 +786,127 @@
383 return 0; /* do not run */
386 +static void select_where_regexp(UAContext *ua, JCR *jcr)
389 + char *strip_prefix, *add_prefix, *add_suffix, *rwhere;
390 + strip_prefix = add_suffix = rwhere = add_prefix = NULL;
393 + start_prompt(ua, _("This will replace your current Where value\n"));
394 + add_prompt(ua, _("Strip prefix")); /* 0 */
395 + add_prompt(ua, _("Add prefix")); /* 1 */
396 + add_prompt(ua, _("Add file suffix")); /* 2 */
397 + add_prompt(ua, _("Enter a regexp")); /* 3 */
398 + add_prompt(ua, _("Test filename manipulation")); /* 4 */
399 + add_prompt(ua, _("Use this ?")); /* 5 */
401 + switch (do_prompt(ua, "", _("Select parameter to modify"), NULL, 0)) {
404 + if (get_cmd(ua, _("Please enter path prefix to strip: "))) {
405 + if (strip_prefix) free(strip_prefix);
406 + strip_prefix = bstrdup(ua->cmd);
409 + goto try_again_reg;
412 + if (get_cmd(ua, _("Please enter path prefix to add (/ for none): "))) {
413 + if (IsPathSeparator(ua->cmd[0]) && ua->cmd[1] == '\0') {
417 + if (add_prefix) free(add_prefix);
418 + add_prefix = bstrdup(ua->cmd);
420 + goto try_again_reg;
423 + if (get_cmd(ua, _("Please enter file suffix to add: "))) {
424 + if (add_suffix) free(add_suffix);
425 + add_suffix = bstrdup(ua->cmd);
427 + goto try_again_reg;
430 + if (get_cmd(ua, _("Please enter a valid regexp (!from!to!): "))) {
431 + if (rwhere) free(rwhere);
432 + rwhere = bstrdup(ua->cmd);
435 + goto try_again_reg;
441 + ua->send_msg(_("rwhere=%s strip_prefix=%s add_prefix=%s add_suffix=%\n"),
442 + NPRT(rwhere), NPRT(strip_prefix), NPRT(add_prefix), NPRT(add_suffix));
445 + if (rwhere && rwhere[0] != '\0') {
446 + regs = get_bregexps(rwhere);
448 + regexp = bregexp_build_where(strip_prefix, add_prefix, add_suffix);
449 + regs = get_bregexps(regexp);
454 + ua->send_msg(_("Cannot use your regexp\n"));
455 + goto try_again_reg;
458 + while (get_cmd(ua, _("Please enter filename to test: "))) {
459 + apply_bregexps(ua->cmd, regs, &result);
460 + ua->send_msg(_("%s -> %s\n"), ua->cmd, result);
462 + free_bregexps(regs);
464 + goto try_again_reg;
469 + case -1: /* error or cancel */
472 + goto try_again_reg;
475 + /* replace the existing where */
482 + jcr->where = bstrdup(rwhere);
483 + } else if (strip_prefix || add_prefix || add_suffix) {
484 + jcr->where = bregexp_build_where(strip_prefix, add_prefix, add_suffix);
487 + regs = get_bregexps(jcr->where);
489 + free_bregexps(regs);
491 + jcr->where_use_regexp = true;
497 + ua->send_msg(_("Cannot use your regexp.\n"));
501 + if (strip_prefix) free(strip_prefix);
502 + if (add_prefix) free(add_prefix);
503 + if (add_suffix) free(add_suffix);
504 + if (rwhere) free(rwhere);
507 static void select_job_level(UAContext *ua, JCR *jcr)
509 if (jcr->JobType == JT_BACKUP) {
510 Index: src/dird/dird_conf.h
511 ===================================================================
512 --- src/dird/dird_conf.h (révision 4466)
513 +++ src/dird/dird_conf.h (copie de travail)
515 int Priority; /* Job priority */
516 int RestoreJobId; /* What -- JobId to restore */
517 char *RestoreWhere; /* Where on disk to restore -- directory */
518 + char *strip_prefix; /* remove prefix from filename */
519 + char *add_prefix; /* add prefix to filename */
520 + char *add_suffix; /* add suffix to filename -- .old */
521 + bool where_use_regexp; /* true if RestoreWhere is a BREGEXP */
522 char *RestoreBootstrap; /* Bootstrap file */
523 alist *RunScripts; /* Run {client} program {after|before} Job */
525 Index: src/filed/job.c
526 ===================================================================
527 --- src/filed/job.c (révision 4467)
528 +++ src/filed/job.c (copie de travail)
533 +#include "lib/breg.h"
535 #if defined(WIN32_VSS)
538 static char sessioncmd[] = "session %127s %ld %ld %ld %ld %ld %ld\n";
539 static char restorecmd[] = "restore replace=%c prelinks=%d where=%s\n";
540 static char restorecmd1[] = "restore replace=%c prelinks=%d where=\n";
541 +static char restorecmdR[] = "restore replace=%c prelinks=%d rwhere=%s\n";
542 static char verifycmd[] = "verify level=%30s";
543 static char estimatecmd[] = "estimate listing=%d";
544 static char runbefore[] = "RunBeforeJob %s";
545 @@ -1586,12 +1588,15 @@
548 if (sscanf(dir->msg, restorecmd, &replace, &prefix_links, where) != 3) {
549 - if (sscanf(dir->msg, restorecmd1, &replace, &prefix_links) != 2) {
550 - pm_strcpy(jcr->errmsg, dir->msg);
551 - Jmsg(jcr, M_FATAL, 0, _("Bad replace command. CMD=%s\n"), jcr->errmsg);
553 + if (sscanf(dir->msg, restorecmdR, &replace, &prefix_links, where) != 3){
554 + if (sscanf(dir->msg, restorecmd1, &replace, &prefix_links) != 2) {
555 + pm_strcpy(jcr->errmsg, dir->msg);
556 + Jmsg(jcr, M_FATAL, 0, _("Bad replace command. CMD=%s\n"), jcr->errmsg);
562 + jcr->where_use_regexp = true;
564 /* Turn / into nothing */
565 if (IsPathSeparator(where[0]) && where[1] == '\0') {
566 @@ -1601,6 +1606,15 @@
567 Dmsg2(150, "Got replace %c, where=%s\n", replace, where);
568 unbash_spaces(where);
569 jcr->where = bstrdup(where);
571 + if (jcr->where_use_regexp) {
572 + jcr->where_bregexp = get_bregexps(jcr->where);
573 + if (!jcr->where_bregexp) {
574 + Jmsg(jcr, M_FATAL, 0, _("Bad where regexp. where=%s\n"), jcr->where);
575 + free_pool_memory(where);
579 free_pool_memory(where);
580 jcr->replace = replace;
581 jcr->prefix_links = prefix_links;
583 ===================================================================
584 --- src/jcr.h (révision 4466)
585 +++ src/jcr.h (copie de travail)
587 MSGS *jcr_msgs; /* Copy of message resource -- actually used */
588 uint32_t ClientId; /* Client associated with Job */
589 char *where; /* prefix to restore files to */
590 + bool where_use_regexp; /* True if where is a bregexp */
591 + alist *where_bregexp; /* BREGEXP alist for path manipulation */
592 int cached_pnl; /* cached path length */
593 POOLMEM *cached_path; /* cached path */
594 bool prefix_links; /* Prefix links with Where path */
595 Index: src/lib/Makefile.in
596 ===================================================================
597 --- src/lib/Makefile.in (révision 4466)
598 +++ src/lib/Makefile.in (copie de travail)
600 res.c rwlock.c scan.c serial.c sha1.c \
601 signal.c smartall.c rblist.c tls.c tree.c \
602 util.c var.c watchdog.c workq.c btimers.c \
603 - address_conf.c pythonlib.c
604 + address_conf.c pythonlib.c breg.c
607 LIBOBJS = attr.o base64.o berrno.o bsys.o bget_msg.o \
609 res.o rwlock.o scan.o serial.o sha1.o \
610 signal.o smartall.o rblist.o tls.o tree.o \
611 util.o var.o watchdog.o workq.o btimers.o \
612 - address_conf.o pythonlib.o
613 + address_conf.o pythonlib.o breg.o
616 EXTRAOBJS = @OBJLIST@
617 Index: src/lib/attr.c
618 ===================================================================
619 --- src/lib/attr.c (révision 4466)
620 +++ src/lib/attr.c (copie de travail)
625 +#include "lib/breg.h"
630 ATTR *attr = (ATTR *)malloc(sizeof(ATTR));
632 * every filename if a prefix is supplied.
636 if (jcr->where[0] == 0) {
637 pm_strcpy(attr->ofname, attr->fname);
638 pm_strcpy(attr->olname, attr->lname);
640 + } else if (jcr->where_bregexp) {
642 + apply_bregexps(attr->fname, jcr->where_bregexp, &ret);
643 + pm_strcpy(attr->ofname, ret);
645 + if (attr->type == FT_LNKSAVED || attr->type == FT_LNK) {
646 + /* Always add prefix to hard links (FT_LNKSAVED) and
647 + * on user request to soft links
650 + if ((attr->type == FT_LNKSAVED || jcr->prefix_links)) {
651 + apply_bregexps(attr->lname, jcr->where_bregexp, &ret);
652 + pm_strcpy(attr->olname, ret);
655 + pm_strcpy(attr->olname, attr->lname);
661 int wherelen = strlen(jcr->where);
663 ===================================================================
664 --- src/lib/jcr.c (révision 4466)
665 +++ src/lib/jcr.c (copie de travail)
667 /* External variables we reference */
668 extern time_t watchdog_time;
670 +/* External referenced functions */
671 +void free_bregexps(alist *bregexps);
673 /* Forward referenced functions */
674 extern "C" void timeout_handler(int sig);
675 static void jcr_timeout_check(watchdog_t *self);
680 + if (jcr->where_bregexp) {
681 + free_bregexps(jcr->where_bregexp);
682 + delete jcr->where_bregexp;
683 + jcr->where_bregexp = NULL;
685 if (jcr->cached_path) {
686 free_pool_memory(jcr->cached_path);
687 jcr->cached_path = NULL;