]> git.sur5r.net Git - bacula/bacula/blob - bacula/patches/testing/file_relocation.patch
ebl add user interface in ua_restore.c
[bacula/bacula] / bacula / patches / testing / file_relocation.patch
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)
5 @@ -43,8 +43,8 @@
6  
7  #include "bacula.h"
8  #include "dird.h"
9 +#include "lib/breg.h"
10  
11 -
12  /* Imported functions */
13  extern void print_bsr(UAContext *ua, RBSR *bsr);
14  
15 @@ -83,6 +83,10 @@
16     JCR *jcr = ua->jcr;
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;
23  
24     memset(&rx, 0, sizeof(rx));
25     rx.path = get_pool_memory(PM_FNAME);
26 @@ -94,6 +98,41 @@
27     i = find_arg_with_value(ua, "where");
28     if (i >= 0) {
29        rx.where = ua->argv[i];
30 +   }
31 +
32 +   i = find_arg_with_value(ua, "strip_prefix");
33 +   if (i >= 0) {
34 +      strip_prefix = ua->argv[i];
35 +   }
36 +
37 +   i = find_arg_with_value(ua, "add_prefix");
38 +   if (i >= 0) {
39 +      add_prefix = ua->argv[i];
40 +   }
41 +
42 +   i = find_arg_with_value(ua, "add_suffix");
43 +   if (i >= 0) {
44 +      add_suffix = ua->argv[i];
45 +   }
46 +
47 +   i = find_arg(ua, "where_use_regexp");
48 +   if (i >= 0) {
49 +      where_use_regexp = true;
50 +   }
51 +
52 +   i = find_arg_with_value(ua, "rwhere");
53 +   if (i >= 0) {
54 +      where_use_regexp = true;
55 +      rx.where = ua->argv[i];
56 +   }
57 +
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;
62 +   }
63 +
64 +   if (rx.where) {
65        if (!acl_access_ok(ua, Where_ACL, rx.where)) {
66           ua->error_msg(_("\"where\" specification not authorized.\n"));
67           goto bail_out;
68 @@ -195,9 +234,10 @@
69  
70        Mmsg(ua->cmd,
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());
79     } else {
80 @@ -216,6 +256,10 @@
81     if (escaped_where_name != NULL) {
82        bfree(escaped_where_name);
83     }
84 +   
85 +   if (have_to_free_where) {
86 +      free_pool_memory(rx.where);
87 +   }
88  
89     if (find_arg(ua, NT_("yes")) > 0) {
90        pm_strcat(ua->cmd, " yes");    /* pass it on to the run command */
91 @@ -235,6 +279,10 @@
92        bfree(escaped_where_name);
93     }
94  
95 +   if (have_to_free_where) {
96 +      free_pool_memory(rx.where);
97 +   }
98 +
99     free_rx(&rx);
100     return 0;
101  
102 @@ -331,23 +379,28 @@
103  
104     const char *kw[] = {
105         /* These keywords are handled in a for loop */
106 -      "jobid",     /* 0 */
107 -      "current",   /* 1 */
108 -      "before",    /* 2 */
109 -      "file",      /* 3 */
110 -      "directory", /* 4 */
111 -      "select",    /* 5 */
112 -      "pool",      /* 6 */
113 -      "all",       /* 7 */
114 +      "jobid",       /* 0 */
115 +      "current",     /* 1 */
116 +      "before",      /* 2 */
117 +      "file",        /* 3 */
118 +      "directory",   /* 4 */
119 +      "select",      /* 5 */
120 +      "pool",        /* 6 */
121 +      "all",         /* 7 */
122  
123        /* The keyword below are handled by individual arg lookups */
124 -      "client",    /* 8 */
125 -      "storage",   /* 9 */
126 -      "fileset",   /* 10 */
127 -      "where",     /* 11 */
128 -      "yes",       /* 12 */
129 -      "bootstrap", /* 13 */
130 -      "done",      /* 14 */
131 +      "client",       /* 8 */
132 +      "storage",      /* 9 */
133 +      "fileset",      /* 10 */
134 +      "where",        /* 11 */
135 +      "yes",          /* 12 */
136 +      "bootstrap",    /* 13 */
137 +      "done",         /* 14 */
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 */
143        NULL
144     };
145  
146 Index: src/dird/restore.c
147 ===================================================================
148 --- src/dird/restore.c  (révision 4466)
149 +++ src/dird/restore.c  (copie de travail)
150 @@ -50,8 +50,9 @@
151  #include "dird.h"
152  
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";
159  
160  /* Responses received from File daemon */
161  static char OKrestore[]   = "2000 OK restore\n";
162 @@ -172,7 +173,7 @@
163     }
164  
165     /* Send restore command */
166 -   char replace, *where;
167 +   char replace, *where, *cmd;
168     char empty = '\0';
169  
170     if (jcr->replace != 0) {
171 @@ -189,9 +190,17 @@
172     } else {
173        where = ∅                 /* None */
174     }
175 +   
176     jcr->prefix_links = jcr->job->PrefixLinks;
177 +
178 +   if (jcr->where_use_regexp) {
179 +      cmd = restorecmdR;
180 +   } else {
181 +      cmd = restorecmd;
182 +   }
183 +
184     bash_spaces(where);
185 -   bnet_fsend(fd, restorecmd, replace, jcr->prefix_links, where);
186 +   bnet_fsend(fd, cmd, replace, jcr->prefix_links, where);
187     unbash_spaces(where);
188  
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)
194 @@ -52,6 +52,7 @@
195  
196  #include "bacula.h"
197  #include "dird.h"
198 +#include "lib/breg.h"
199  
200  /* Define the first and last resource ID record
201   * types. Note, these should be unique for each
202 @@ -268,6 +269,10 @@
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 */
213 @@ -611,6 +616,9 @@
214        if (res->res_job.RestoreWhere) {
215           sendit(sock, _("  --> Where=%s\n"), NPRT(res->res_job.RestoreWhere));
216        }
217 +      if (res->res_job.where_use_regexp) {
218 +         sendit(sock, _("  --> RWhere=%u\n"), res->res_job.where_use_regexp);
219 +      }
220        if (res->res_job.RestoreBootstrap) {
221           sendit(sock, _("  --> Bootstrap=%s\n"), NPRT(res->res_job.RestoreBootstrap));
222        }
223 @@ -1143,6 +1151,15 @@
224        if (res->res_job.RestoreWhere) {
225           free(res->res_job.RestoreWhere);
226        }
227 +      if (res->res_job.strip_prefix) {
228 +         free(res->res_job.strip_prefix);
229 +      }
230 +      if (res->res_job.add_prefix) {
231 +         free(res->res_job.add_prefix);
232 +      }
233 +      if (res->res_job.add_suffix) {
234 +         free(res->res_job.add_suffix);
235 +      }
236        if (res->res_job.RestoreBootstrap) {
237           free(res->res_job.RestoreBootstrap);
238        }
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)
246 +        {
247 +           if (res->res_job.RestoreWhere) {
248 +              free(res->res_job.RestoreWhere);
249 +           }
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 */
255 +        }
256           break;
257        case R_COUNTER:
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)
263 @@ -36,13 +36,14 @@
264  
265  #include "bacula.h"
266  #include "dird.h"
267 +#include "lib/breg.h"
268  
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);
274  
275 -
276  /* Imported variables */
277  extern struct s_kw ReplaceOptions[];
278  
279 @@ -71,6 +72,7 @@
280     int Priority = 0;
281     int i, j, opt, files = 0;
282     bool kw_ok;
283 +   bool where_use_regexp = false;
284     JOB *job = NULL;
285     JOB *verify_job = NULL;
286     JOB *previous_job = NULL;
287 @@ -87,7 +89,7 @@
288        "level",                        /* 5 */
289        "storage",                      /* 6 */
290        "sd",                           /* 7 */
291 -      "pool",                         /* 8 */
292 +      "rwhere",                       /* 8 where string as a bregexp */
293        "where",                        /* 9 */
294        "bootstrap",                    /* 10 */
295        "replace",                      /* 11 */
296 @@ -101,6 +103,7 @@
297        "cloned",                       /* 19 cloned */
298        "verifylist",                   /* 20 verify output list */
299        "migrationjob",                 /* 21 migration job name */
300 +      "pool",                         /* 22 */
301        NULL};
302  
303  #define YES_POS 14
304 @@ -188,14 +191,8 @@
305                 store_name = ua->argv[i];
306                 kw_ok = true;
307                 break;
308 -            case 8: /* pool */
309 -               if (pool_name) {
310 -                  ua->send_msg(_("Pool specified twice.\n"));
311 -                  return 0;
312 -               }
313 -               pool_name = ua->argv[i];
314 -               kw_ok = true;
315 -               break;
316 +            case 8: /* rwhere */
317 +               where_use_regexp = true;
318              case 9: /* where */
319                 if (where) {
320                    ua->send_msg(_("Where specified twice.\n"));
321 @@ -287,8 +284,15 @@
322                 previous_job_name = ua->argv[i];
323                 kw_ok = true;
324                 break;
325 +            case 22: /* pool */
326 +               if (pool_name) {
327 +                  ua->send_msg(_("Pool specified twice.\n"));
328 +                  return 0;
329 +               }
330 +               pool_name = ua->argv[i];
331 +               kw_ok = true;
332 +               break;
333  
334 -
335              default:
336                 break;
337              }
338 @@ -478,6 +482,7 @@
339           free(jcr->where);
340        }
341        jcr->where = bstrdup(where);
342 +      jcr->where_use_regexp = where_use_regexp;
343     }
344  
345     if (when) {
346 @@ -595,8 +600,9 @@
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 */
355        }
356        switch (do_prompt(ua, "", _("Select parameter to modify"), NULL, 0)) {
357        case 0:
358 @@ -719,8 +725,13 @@
359              ua->cmd[0] = 0;
360           }
361           jcr->where = bstrdup(ua->cmd);
362 +        jcr->where_use_regexp = false;
363           goto try_again;
364 -      case 9:
365 +      case 9: 
366 +        /* File relocation */
367 +        select_where_regexp(ua, jcr);
368 +        goto try_again;
369 +      case 10:
370           /* Replace */
371           start_prompt(ua, _("Replace:\n"));
372           for (i=0; ReplaceOptions[i].name; i++) {
373 @@ -731,7 +742,7 @@
374              jcr->replace = ReplaceOptions[opt].token;
375           }
376           goto try_again;
377 -      case 10:
378 +      case 11:
379           /* JobId */
380           jid = NULL;                  /* force reprompt */
381           jcr->RestoreJobId = 0;
382 @@ -775,6 +786,127 @@
383     return 0;                       /* do not run */
384  }
385  
386 +static void select_where_regexp(UAContext *ua, JCR *jcr)
387 +{
388 +   alist *regs;
389 +   char *strip_prefix, *add_prefix, *add_suffix, *rwhere;
390 +   strip_prefix = add_suffix = rwhere = add_prefix = NULL;
391 +
392 +try_again_reg:
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 */
400 +   
401 +   switch (do_prompt(ua, "", _("Select parameter to modify"), NULL, 0)) {
402 +   case 0:
403 +      /* Strip prefix */
404 +      if (get_cmd(ua, _("Please enter path prefix to strip: "))) {
405 +        if (strip_prefix) free(strip_prefix);
406 +        strip_prefix = bstrdup(ua->cmd);
407 +      }
408 +      
409 +      goto try_again_reg;
410 +   case 1:
411 +      /* Add prefix */
412 +      if (get_cmd(ua, _("Please enter path prefix to add (/ for none): "))) {
413 +        if (IsPathSeparator(ua->cmd[0]) && ua->cmd[1] == '\0') {
414 +           ua->cmd[0] = 0;
415 +        }
416 +
417 +        if (add_prefix) free(add_prefix);
418 +        add_prefix = bstrdup(ua->cmd);
419 +      }
420 +      goto try_again_reg;
421 +   case 2:
422 +      /* Add suffix */
423 +      if (get_cmd(ua, _("Please enter file suffix to add: "))) {
424 +        if (add_suffix) free(add_suffix);
425 +        add_suffix = bstrdup(ua->cmd);
426 +      }      
427 +      goto try_again_reg;
428 +   case 3:
429 +      /* Add rwhere */
430 +      if (get_cmd(ua, _("Please enter a valid regexp (!from!to!): "))) {
431 +        if (rwhere) free(rwhere);
432 +        rwhere = bstrdup(ua->cmd);
433 +      }
434 +      
435 +      goto try_again_reg;      
436 +   case 4:
437 +      /* Test regexp */ 
438 +      char *result;
439 +      char *regexp;
440 +      
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));
443 +
444 +
445 +      if (rwhere && rwhere[0] != '\0') {
446 +        regs = get_bregexps(rwhere);
447 +      } else {
448 +        regexp = bregexp_build_where(strip_prefix, add_prefix, add_suffix);
449 +        regs = get_bregexps(regexp);
450 +        free(regexp);
451 +      }
452 +      
453 +      if (!regs) {
454 +        ua->send_msg(_("Cannot use your regexp\n"));
455 +        goto try_again_reg;
456 +      }
457 +
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);
461 +      }
462 +      free_bregexps(regs);
463 +      delete regs;
464 +      goto try_again_reg;
465 +
466 +   case 5:
467 +      /* OK */
468 +      break;
469 +   case -1:                        /* error or cancel */
470 +      goto bail_out_reg;
471 +   default:
472 +      goto try_again_reg;
473 +   }
474 +
475 +   /* replace the existing where */
476 +   if (jcr->where) {
477 +      free(jcr->where);
478 +      jcr->where = NULL;
479 +   }
480 +
481 +   if (rwhere) {
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);
485 +   }
486 +
487 +   regs = get_bregexps(jcr->where);
488 +   if (regs) {
489 +      free_bregexps(regs);
490 +      delete regs;
491 +      jcr->where_use_regexp = true;
492 +   } else {
493 +      if (jcr->where) {
494 +        free(jcr->where);
495 +        jcr->where = NULL;
496 +      }
497 +      ua->send_msg(_("Cannot use your regexp.\n"));
498 +   }
499 +
500 +bail_out_reg:
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);
505 +}
506 +
507  static void select_job_level(UAContext *ua, JCR *jcr)
508  {
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)
514 @@ -356,6 +356,10 @@
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 */
524     union {
525 Index: src/filed/job.c
526 ===================================================================
527 --- src/filed/job.c     (révision 4467)
528 +++ src/filed/job.c     (copie de travail)
529 @@ -36,6 +36,7 @@
530  
531  #include "bacula.h"
532  #include "filed.h"
533 +#include "lib/breg.h"
534  
535  #if defined(WIN32_VSS)
536  #include "vss.h"
537 @@ -115,6 +116,7 @@
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 @@
546     *where = 0;
547  
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);
552 -         return 0;
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);
557 +            return 0;
558 +         }
559 +         *where = 0;
560        }
561 -      *where = 0;
562 +      jcr->where_use_regexp = true;
563     }
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);
570 +
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);
576 +        return 0;
577 +      }
578 +   }
579     free_pool_memory(where);
580     jcr->replace = replace;
581     jcr->prefix_links = prefix_links;
582 Index: src/jcr.h
583 ===================================================================
584 --- src/jcr.h   (révision 4466)
585 +++ src/jcr.h   (copie de travail)
586 @@ -173,6 +173,8 @@
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)
599 @@ -32,7 +32,7 @@
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
605  
606  
607  LIBOBJS = attr.o base64.o berrno.o bsys.o bget_msg.o \
608 @@ -45,7 +45,7 @@
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
614  
615  
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)
621 @@ -35,8 +35,8 @@
622  
623  #include "bacula.h"
624  #include "jcr.h"
625 +#include "lib/breg.h"
626  
627 -
628  ATTR *new_attr()
629  {
630     ATTR *attr = (ATTR *)malloc(sizeof(ATTR));
631 @@ -148,9 +148,30 @@
632      *   every filename if a prefix is supplied.
633      *
634      */
635 +
636     if (jcr->where[0] == 0) {
637        pm_strcpy(attr->ofname, attr->fname);
638        pm_strcpy(attr->olname, attr->lname);
639 +
640 +   } else if (jcr->where_bregexp) { 
641 +      char *ret;
642 +      apply_bregexps(attr->fname, jcr->where_bregexp, &ret);
643 +      pm_strcpy(attr->ofname, ret);
644 +
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
648 +          */
649 +
650 +         if ((attr->type == FT_LNKSAVED || jcr->prefix_links)) {
651 +            apply_bregexps(attr->lname, jcr->where_bregexp, &ret);
652 +            pm_strcpy(attr->olname, ret);
653 +
654 +         } else {
655 +            pm_strcpy(attr->olname, attr->lname);
656 +         }
657 +      }
658 +      
659     } else {
660        const char *fn;
661        int wherelen = strlen(jcr->where);
662 Index: src/lib/jcr.c
663 ===================================================================
664 --- src/lib/jcr.c       (révision 4466)
665 +++ src/lib/jcr.c       (copie de travail)
666 @@ -56,6 +56,9 @@
667  /* External variables we reference */
668  extern time_t watchdog_time;
669  
670 +/* External referenced functions */
671 +void free_bregexps(alist *bregexps);
672 +
673  /* Forward referenced functions */
674  extern "C" void timeout_handler(int sig);
675  static void jcr_timeout_check(watchdog_t *self);
676 @@ -381,6 +384,11 @@
677        free(jcr->where);
678        jcr->where = NULL;
679     }
680 +   if (jcr->where_bregexp) {
681 +      free_bregexps(jcr->where_bregexp);
682 +      delete jcr->where_bregexp;
683 +      jcr->where_bregexp = NULL;
684 +   }
685     if (jcr->cached_path) {
686        free_pool_memory(jcr->cached_path);
687        jcr->cached_path = NULL;