]> git.sur5r.net Git - bacula/bacula/blob - bacula/patches/testing/file_relocation.patch
ebl fix compilation
[bacula/bacula] / bacula / patches / testing / file_relocation.patch
1 Index: patches/testing/breg.c
2 ===================================================================
3 --- patches/testing/breg.c      (révision 4529)
4 +++ patches/testing/breg.c      (copie de travail)
5 @@ -7,7 +7,7 @@
6   *
7   */
8  /*
9 -   Bacula® - The Network Backup Solution
10 +   Bacula\81Â\81® - The Network Backup Solution
11  
12     Copyright (C) 2006-2006 Free Software Foundation Europe e.V.
13  
14 @@ -28,9 +28,9 @@
15     Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
16     02110-1301, USA.
17  
18 -   Bacula® is a registered trademark of John Walker.
19 +   Bacula\81Â\81® is a registered trademark of John Walker.
20     The licensor of Bacula is the Free Software Foundation Europe
21 -   (FSFE), Fiduciary Program, Sumatrastrasse 25, 8006 Zürich,
22 +   (FSFE), Fiduciary Program, Sumatrastrasse 25, 8006 Z\81Ã\81¼rich,
23     Switzerland, email:ftf@fsfeurope.org.
24  */
25  
26 @@ -383,10 +383,11 @@
27      * add_prefix   = !^!add_prefix!          5 bytes
28      * add_suffix   = !([^/])$!$1add_suffix! 13 bytes
29      */
30 -   int str_size = (strip_prefix?strlen(strip_prefix)+4:0 +
31 -                  add_prefix?strlen(add_prefix)+5:0     + /* escape + 3*, + \0 */ 
32 -                  add_suffix?strlen(add_suffix)+14:0     )     * 2  + 3   + 1;
33 +   int str_size = ((strip_prefix?strlen(strip_prefix)+4:0) +
34 +                  (add_prefix?strlen(add_prefix)+5    :0) + /* escape + 3*, + \0 */ 
35 +                  (add_suffix?strlen(add_suffix)+14   :0) )   * 2     + 3   + 1;
36  
37 +   Dmsg1(1, "bregexp_get_build_where_size = %i\n", str_size);
38     return str_size;
39  }
40  
41 @@ -432,7 +433,7 @@
42  
43     free_pool_memory(str_tmp);
44  
45 -   return ret;
46 +   return dest;
47  }
48  
49  
50 Index: patches/testing/bregtest.c
51 ===================================================================
52 --- patches/testing/bregtest.c  (révision 4529)
53 +++ patches/testing/bregtest.c  (copie de travail)
54 @@ -5,7 +5,7 @@
55   *
56   */
57  /*
58 -   Bacula® - The Network Backup Solution
59 +   Bacula\81Â\81® - The Network Backup Solution
60  
61     Copyright (C) 2006-2006 Free Software Foundation Europe e.V.
62  
63 @@ -26,9 +26,9 @@
64     Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
65     02110-1301, USA.
66  
67 -   Bacula® is a registered trademark of John Walker.
68 +   Bacula\81Â\81® is a registered trademark of John Walker.
69     The licensor of Bacula is the Free Software Foundation Europe
70 -   (FSFE), Fiduciary Program, Sumatrastrasse 25, 8006 Zürich,
71 +   (FSFE), Fiduciary Program, Sumatrastrasse 25, 8006 Z\81Ã\81¼rich,
72     Switzerland, email:ftf@fsfeurope.org.
73  */
74  
75 @@ -62,8 +62,11 @@
76  
77  int main(int argc, char *const *argv)
78  {
79 -       printf("%s\n", bregexp_build_where("/tmp", NULL, ".old"));
80 -       exit(0);
81 +   char tab[500];
82 +   int len = bregexp_get_build_where_size("/tmp", "/tmp/toto", ".old");
83 +   
84 +   printf("%s\n", bregexp_build_where(tab, len, "/tmp", "/tmp/toto!", ".old"));
85 +   exit(0);
86  
87  
88     regex_t preg;
89 Index: patches/testing/breg.h
90 ===================================================================
91 --- patches/testing/breg.h      (révision 4529)
92 +++ patches/testing/breg.h      (copie de travail)
93 @@ -4,7 +4,7 @@
94   * Version $Id$
95   */
96  /*
97 -   Bacula® - The Network Backup Solution
98 +   Bacula\81Â\81® - The Network Backup Solution
99  
100     Copyright (C) 2006-2006 Free Software Foundation Europe e.V.
101  
102 @@ -25,9 +25,9 @@
103     Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
104     02110-1301, USA.
105  
106 -   Bacula® is a registered trademark of John Walker.
107 +   Bacula\81Â\81® is a registered trademark of John Walker.
108     The licensor of Bacula is the Free Software Foundation Europe
109 -   (FSFE), Fiduciary Program, Sumatrastrasse 25, 8006 Zürich,
110 +   (FSFE), Fiduciary Program, Sumatrastrasse 25, 8006 Z\81Ã\81¼rich,
111     Switzerland, email:ftf@fsfeurope.org.
112  */
113  
114 @@ -98,8 +98,16 @@
115  /* foreach_alist free RUNSCRIPT */
116  void free_bregexps(alist *bregexps); /* you have to free alist */
117  
118 -/* get a bregexp string from user arguments */
119 -char *bregexp_build_where(char *strip_prefix, 
120 +/* get regexp size */
121 +int bregexp_get_build_where_size(char *strip_prefix, 
122 +                                char *add_prefix, 
123 +                                char *add_suffix);
124 +
125 +/* get a bregexp string from user arguments 
126 + * you must allocate it with bregexp_get_build_where_size();
127 + */
128 +char *bregexp_build_where(char *dest, int str_size,
129 +                         char *strip_prefix, 
130                            char *add_prefix, 
131                            char *add_suffix);
132  
133 Index: src/dird/ua_restore.c
134 ===================================================================
135 --- src/dird/ua_restore.c       (révision 4529)
136 +++ src/dird/ua_restore.c       (copie de travail)
137 @@ -43,8 +43,8 @@
138  
139  #include "bacula.h"
140  #include "dird.h"
141 +#include "lib/breg.h"
142  
143 -
144  /* Imported functions */
145  extern void print_bsr(UAContext *ua, RBSR *bsr);
146  
147 @@ -83,6 +83,9 @@
148     JCR *jcr = ua->jcr;
149     char *escaped_bsr_name = NULL;
150     char *escaped_where_name = NULL;
151 +   bool where_use_regexp = false;
152 +   char *strip_prefix, *add_prefix, *add_suffix, *regexp;
153 +   strip_prefix = add_prefix = add_suffix = regexp = NULL;
154  
155     memset(&rx, 0, sizeof(rx));
156     rx.path = get_pool_memory(PM_FNAME);
157 @@ -94,6 +97,45 @@
158     i = find_arg_with_value(ua, "where");
159     if (i >= 0) {
160        rx.where = ua->argv[i];
161 +   }
162 +
163 +   i = find_arg_with_value(ua, "strip_prefix");
164 +   if (i >= 0) {
165 +      strip_prefix = ua->argv[i];
166 +   }
167 +
168 +   i = find_arg_with_value(ua, "add_prefix");
169 +   if (i >= 0) {
170 +      add_prefix = ua->argv[i];
171 +   }
172 +
173 +   i = find_arg_with_value(ua, "add_suffix");
174 +   if (i >= 0) {
175 +      add_suffix = ua->argv[i];
176 +   }
177 +
178 +   i = find_arg(ua, "where_use_regexp");
179 +   if (i >= 0) {
180 +      where_use_regexp = true;
181 +   }
182 +
183 +   i = find_arg_with_value(ua, "rwhere");
184 +   if (i >= 0) {
185 +      where_use_regexp = true;
186 +      rx.where = ua->argv[i];
187 +   }
188 +
189 +   if (strip_prefix || add_suffix || add_prefix) {
190 +      int len = bregexp_get_build_where_size(strip_prefix, add_prefix, add_suffix);
191 +      regexp = (char *) bmalloc (len * sizeof(char));
192 +
193 +      bregexp_build_where(regexp, len, strip_prefix, add_prefix, add_suffix);
194 +      where_use_regexp = true;
195 +      
196 +      rx.where = regexp;
197 +   }
198 +
199 +   if (rx.where) {
200        if (!acl_access_ok(ua, Where_ACL, rx.where)) {
201           ua->error_msg(_("\"where\" specification not authorized.\n"));
202           goto bail_out;
203 @@ -195,9 +237,10 @@
204  
205        Mmsg(ua->cmd,
206            "run job=\"%s\" client=\"%s\" storage=\"%s\" bootstrap=\"%s\""
207 -          " where=\"%s\" files=%d catalog=\"%s\"",
208 +          " %swhere=\"%s\" files=%d catalog=\"%s\"",
209            job->name(), rx.ClientName, rx.store?rx.store->name():"",
210            escaped_bsr_name ? escaped_bsr_name : jcr->RestoreBootstrap,
211 +          where_use_regexp ? "r" : "",
212            escaped_where_name ? escaped_where_name : rx.where,
213            rx.selected_files, ua->catalog->name());
214     } else {
215 @@ -216,6 +259,10 @@
216     if (escaped_where_name != NULL) {
217        bfree(escaped_where_name);
218     }
219 +   
220 +   if (regexp) {
221 +      bfree(regexp);
222 +   }
223  
224     if (find_arg(ua, NT_("yes")) > 0) {
225        pm_strcat(ua->cmd, " yes");    /* pass it on to the run command */
226 @@ -235,6 +282,10 @@
227        bfree(escaped_where_name);
228     }
229  
230 +   if (regexp) {
231 +      bfree(regexp);
232 +   }
233 +
234     free_rx(&rx);
235     return 0;
236  
237 @@ -333,23 +384,28 @@
238  
239     const char *kw[] = {
240         /* These keywords are handled in a for loop */
241 -      "jobid",     /* 0 */
242 -      "current",   /* 1 */
243 -      "before",    /* 2 */
244 -      "file",      /* 3 */
245 -      "directory", /* 4 */
246 -      "select",    /* 5 */
247 -      "pool",      /* 6 */
248 -      "all",       /* 7 */
249 +      "jobid",       /* 0 */
250 +      "current",     /* 1 */
251 +      "before",      /* 2 */
252 +      "file",        /* 3 */
253 +      "directory",   /* 4 */
254 +      "select",      /* 5 */
255 +      "pool",        /* 6 */
256 +      "all",         /* 7 */
257  
258        /* The keyword below are handled by individual arg lookups */
259 -      "client",    /* 8 */
260 -      "storage",   /* 9 */
261 -      "fileset",   /* 10 */
262 -      "where",     /* 11 */
263 -      "yes",       /* 12 */
264 -      "bootstrap", /* 13 */
265 -      "done",      /* 14 */
266 +      "client",       /* 8 */
267 +      "storage",      /* 9 */
268 +      "fileset",      /* 10 */
269 +      "where",        /* 11 */
270 +      "yes",          /* 12 */
271 +      "bootstrap",    /* 13 */
272 +      "done",         /* 14 */
273 +      "strip_prefix", /* 15 */
274 +      "add_prefix",   /* 16 */
275 +      "add_suffix",   /* 17 */
276 +      "where_use_regexp",/* 18 */
277 +      "rwhere",       /* 19 like where + where_use_regexp */
278        NULL
279     };
280  
281 Index: src/dird/restore.c
282 ===================================================================
283 --- src/dird/restore.c  (révision 4529)
284 +++ src/dird/restore.c  (copie de travail)
285 @@ -50,8 +50,9 @@
286  #include "dird.h"
287  
288  /* Commands sent to File daemon */
289 -static char restorecmd[]   = "restore replace=%c prelinks=%d where=%s\n";
290 -static char storaddr[]     = "storage address=%s port=%d ssl=0\n";
291 +static char restorecmd[]        = "restore replace=%c prelinks=%d where=%s\n";
292 +static char restorecmdR[] = "restore replace=%c prelinks=%d rwhere=%s\n";
293 +static char storaddr[]   = "storage address=%s port=%d ssl=0\n";
294  
295  /* Responses received from File daemon */
296  static char OKrestore[]   = "2000 OK restore\n";
297 @@ -172,7 +173,7 @@
298     }
299  
300     /* Send restore command */
301 -   char replace, *where;
302 +   char replace, *where, *cmd;
303     char empty = '\0';
304  
305     if (jcr->replace != 0) {
306 @@ -189,9 +190,17 @@
307     } else {
308        where = ∅                 /* None */
309     }
310 +   
311     jcr->prefix_links = jcr->job->PrefixLinks;
312 +
313 +   if (jcr->where_use_regexp) {
314 +      cmd = restorecmdR;
315 +   } else {
316 +      cmd = restorecmd;
317 +   }
318 +
319     bash_spaces(where);
320 -   bnet_fsend(fd, restorecmd, replace, jcr->prefix_links, where);
321 +   bnet_fsend(fd, cmd, replace, jcr->prefix_links, where);
322     unbash_spaces(where);
323  
324     if (!response(jcr, fd, OKrestore, "Restore", DISPLAY_ERROR)) {
325 Index: src/dird/dird_conf.c
326 ===================================================================
327 --- src/dird/dird_conf.c        (révision 4529)
328 +++ src/dird/dird_conf.c        (copie de travail)
329 @@ -52,6 +52,7 @@
330  
331  #include "bacula.h"
332  #include "dird.h"
333 +#include "lib/breg.h"
334  
335  /* Define the first and last resource ID record
336   * types. Note, these should be unique for each
337 @@ -268,6 +269,10 @@
338     {"run",       store_alist_str, ITEM(res_job.run_cmds), 0, 0, 0},
339     /* Root of where to restore files */
340     {"where",    store_dir,      ITEM(res_job.RestoreWhere), 0, 0, 0},
341 +   {"whereuseregexp", store_bool, ITEM(res_job.where_use_regexp), 0, 0, 0},
342 +   {"stripprefix",    store_str,  ITEM(res_job.strip_prefix), 0, 0, 0},
343 +   {"addprefix",    store_str,  ITEM(res_job.add_prefix), 0, 0, 0},
344 +   {"addsuffix",    store_str,  ITEM(res_job.add_suffix), 0, 0, 0},
345     /* Where to find bootstrap during restore */
346     {"bootstrap",store_dir,      ITEM(res_job.RestoreBootstrap), 0, 0, 0},
347     /* Where to write bootstrap file during backup */
348 @@ -611,6 +616,9 @@
349        if (res->res_job.RestoreWhere) {
350           sendit(sock, _("  --> Where=%s\n"), NPRT(res->res_job.RestoreWhere));
351        }
352 +      if (res->res_job.where_use_regexp) {
353 +         sendit(sock, _("  --> RWhere=%u\n"), res->res_job.where_use_regexp);
354 +      }
355        if (res->res_job.RestoreBootstrap) {
356           sendit(sock, _("  --> Bootstrap=%s\n"), NPRT(res->res_job.RestoreBootstrap));
357        }
358 @@ -1143,6 +1151,15 @@
359        if (res->res_job.RestoreWhere) {
360           free(res->res_job.RestoreWhere);
361        }
362 +      if (res->res_job.strip_prefix) {
363 +         free(res->res_job.strip_prefix);
364 +      }
365 +      if (res->res_job.add_prefix) {
366 +         free(res->res_job.add_prefix);
367 +      }
368 +      if (res->res_job.add_suffix) {
369 +         free(res->res_job.add_suffix);
370 +      }
371        if (res->res_job.RestoreBootstrap) {
372           free(res->res_job.RestoreBootstrap);
373        }
374 @@ -1299,6 +1316,25 @@
375           res->res_job.jobdefs    = res_all.res_job.jobdefs;
376           res->res_job.run_cmds   = res_all.res_job.run_cmds;
377           res->res_job.RunScripts = res_all.res_job.RunScripts;
378 +        if (res->res_job.strip_prefix ||
379 +            res->res_job.add_suffix   ||
380 +            res->res_job.add_prefix)
381 +        {
382 +           if (res->res_job.RestoreWhere) {
383 +              free(res->res_job.RestoreWhere);
384 +           }
385 +           int len = bregexp_get_build_where_size(res->res_job.strip_prefix,
386 +                                                  res->res_job.add_prefix,
387 +                                                  res->res_job.add_suffix);
388 +           res->res_job.RestoreWhere = (char *) bmalloc (len * sizeof(char));
389 +           bregexp_build_where(res->res_job.RestoreWhere, len,
390 +                               res->res_job.strip_prefix,
391 +                               res->res_job.add_prefix,
392 +                               res->res_job.add_suffix);
393 +           res->res_job.where_use_regexp = true;
394 +
395 +           /* TODO: test bregexp */
396 +        }
397           break;
398        case R_COUNTER:
399           if ((res = (URES *)GetResWithName(R_COUNTER, res_all.res_counter.hdr.name)) == NULL) {
400 Index: src/dird/ua_run.c
401 ===================================================================
402 --- src/dird/ua_run.c   (révision 4529)
403 +++ src/dird/ua_run.c   (copie de travail)
404 @@ -36,11 +36,13 @@
405  
406  #include "bacula.h"
407  #include "dird.h"
408 +#include "lib/breg.h"
409  
410  /* Forward referenced subroutines */
411  static void select_job_level(UAContext *ua, JCR *jcr);
412  static bool display_job_parameters(UAContext *ua, JCR *jcr, JOB *job, char *verify_list, 
413     char *jid, const char *replace);
414 +static void select_where_regexp(UAContext *ua, JCR *jcr);
415  
416  
417  /* Imported variables */
418 @@ -71,6 +73,7 @@
419     int Priority = 0;
420     int i, j, opt, files = 0;
421     bool kw_ok;
422 +   bool where_use_regexp = false;
423     JOB *job = NULL;
424     JOB *verify_job = NULL;
425     JOB *previous_job = NULL;
426 @@ -87,7 +90,7 @@
427        "level",                        /* 5 */
428        "storage",                      /* 6 */
429        "sd",                           /* 7 */
430 -      "pool",                         /* 8 */
431 +      "rwhere",                       /* 8 where string as a bregexp */
432        "where",                        /* 9 */
433        "bootstrap",                    /* 10 */
434        "replace",                      /* 11 */
435 @@ -101,6 +104,7 @@
436        "cloned",                       /* 19 cloned */
437        "verifylist",                   /* 20 verify output list */
438        "migrationjob",                 /* 21 migration job name */
439 +      "pool",                         /* 22 */
440        NULL};
441  
442  #define YES_POS 14
443 @@ -188,15 +192,10 @@
444                 store_name = ua->argv[i];
445                 kw_ok = true;
446                 break;
447 -            case 8: /* pool */
448 -               if (pool_name) {
449 -                  ua->send_msg(_("Pool specified twice.\n"));
450 -                  return 0;
451 -               }
452 -               pool_name = ua->argv[i];
453 -               kw_ok = true;
454 -               break;
455 +            case 8: /* rwhere */
456              case 9: /* where */
457 +              where_use_regexp = (j == 9)?false:true; /* rwhere or where ? */
458 +
459                 if (where) {
460                    ua->send_msg(_("Where specified twice.\n"));
461                    return 0;
462 @@ -287,8 +286,15 @@
463                 previous_job_name = ua->argv[i];
464                 kw_ok = true;
465                 break;
466 +            case 22: /* pool */
467 +               if (pool_name) {
468 +                  ua->send_msg(_("Pool specified twice.\n"));
469 +                  return 0;
470 +               }
471 +               pool_name = ua->argv[i];
472 +               kw_ok = true;
473 +               break;
474  
475 -
476              default:
477                 break;
478              }
479 @@ -478,6 +484,7 @@
480           free(jcr->where);
481        }
482        jcr->where = bstrdup(where);
483 +      jcr->where_use_regexp = where_use_regexp;
484     }
485  
486     if (when) {
487 @@ -595,8 +602,9 @@
488        } else if (jcr->JobType == JT_RESTORE) {
489           add_prompt(ua, _("Bootstrap"));     /* 7 */
490           add_prompt(ua, _("Where"));         /* 8 */
491 -         add_prompt(ua, _("Replace"));       /* 9 */
492 -         add_prompt(ua, _("JobId"));         /* 10 */
493 +         add_prompt(ua, _("File Relocation"));/* 9 */   
494 +         add_prompt(ua, _("Replace"));       /* 10 */
495 +         add_prompt(ua, _("JobId"));         /* 11 */
496        }
497        switch (do_prompt(ua, "", _("Select parameter to modify"), NULL, 0)) {
498        case 0:
499 @@ -719,8 +727,13 @@
500              ua->cmd[0] = 0;
501           }
502           jcr->where = bstrdup(ua->cmd);
503 +        jcr->where_use_regexp = false;
504           goto try_again;
505 -      case 9:
506 +      case 9: 
507 +        /* File relocation */
508 +        select_where_regexp(ua, jcr);
509 +        goto try_again;
510 +      case 10:
511           /* Replace */
512           start_prompt(ua, _("Replace:\n"));
513           for (i=0; ReplaceOptions[i].name; i++) {
514 @@ -731,7 +744,7 @@
515              jcr->replace = ReplaceOptions[opt].token;
516           }
517           goto try_again;
518 -      case 10:
519 +      case 11:
520           /* JobId */
521           jid = NULL;                  /* force reprompt */
522           jcr->RestoreJobId = 0;
523 @@ -775,6 +788,131 @@
524     return 0;                       /* do not run */
525  }
526  
527 +static void select_where_regexp(UAContext *ua, JCR *jcr)
528 +{
529 +   alist *regs;
530 +   char *strip_prefix, *add_prefix, *add_suffix, *rwhere;
531 +   strip_prefix = add_suffix = rwhere = add_prefix = NULL;
532 +
533 +try_again_reg:
534 +   start_prompt(ua, _("This will replace your current Where value\n"));
535 +   add_prompt(ua, _("Strip prefix"));                /* 0 */
536 +   add_prompt(ua, _("Add prefix"));                  /* 1 */
537 +   add_prompt(ua, _("Add file suffix"));             /* 2 */
538 +   add_prompt(ua, _("Enter a regexp"));              /* 3 */
539 +   add_prompt(ua, _("Test filename manipulation"));  /* 4 */
540 +   add_prompt(ua, _("Use this ?"));                  /* 5 */
541 +   
542 +   switch (do_prompt(ua, "", _("Select parameter to modify"), NULL, 0)) {
543 +   case 0:
544 +      /* Strip prefix */
545 +      if (get_cmd(ua, _("Please enter path prefix to strip: "))) {
546 +        if (strip_prefix) bfree(strip_prefix);
547 +        strip_prefix = bstrdup(ua->cmd);
548 +      }
549 +      
550 +      goto try_again_reg;
551 +   case 1:
552 +      /* Add prefix */
553 +      if (get_cmd(ua, _("Please enter path prefix to add (/ for none): "))) {
554 +        if (IsPathSeparator(ua->cmd[0]) && ua->cmd[1] == '\0') {
555 +           ua->cmd[0] = 0;
556 +        }
557 +
558 +        if (add_prefix) bfree(add_prefix);
559 +        add_prefix = bstrdup(ua->cmd);
560 +      }
561 +      goto try_again_reg;
562 +   case 2:
563 +      /* Add suffix */
564 +      if (get_cmd(ua, _("Please enter file suffix to add: "))) {
565 +        if (add_suffix) bfree(add_suffix);
566 +        add_suffix = bstrdup(ua->cmd);
567 +      }      
568 +      goto try_again_reg;
569 +   case 3:
570 +      /* Add rwhere */
571 +      if (get_cmd(ua, _("Please enter a valid regexp (!from!to!): "))) {
572 +        if (rwhere) bfree(rwhere);
573 +        rwhere = bstrdup(ua->cmd);
574 +      }
575 +      
576 +      goto try_again_reg;      
577 +   case 4:
578 +      /* Test regexp */ 
579 +      char *result;
580 +      char *regexp;
581 +      
582 +      if (rwhere && rwhere[0] != '\0') {
583 +        regs = get_bregexps(rwhere);
584 +        ua->send_msg(_("rwhere=%s\n"), NPRT(rwhere));
585 +      } else {
586 +        int len = bregexp_get_build_where_size(strip_prefix, add_prefix, add_suffix);
587 +        regexp = (char *) bmalloc (len * sizeof(char));
588 +        bregexp_build_where(regexp, len, strip_prefix, add_prefix, add_suffix);
589 +        regs = get_bregexps(regexp);
590 +        ua->send_msg(_("strip_prefix=%s add_prefix=%s add_suffix=%s result=%s\n"),
591 +                     NPRT(strip_prefix), NPRT(add_prefix), NPRT(add_suffix), NPRT(regexp));
592 +        
593 +        bfree(regexp);
594 +      }
595 +
596 +      if (!regs) {
597 +        ua->send_msg(_("Cannot use your regexp\n"));
598 +        goto try_again_reg;
599 +      }
600 +
601 +      while (get_cmd(ua, _("Please enter filename to test: "))) {
602 +        apply_bregexps(ua->cmd, regs, &result);
603 +        ua->send_msg(_("%s -> %s\n"), ua->cmd, result);
604 +      }
605 +      free_bregexps(regs);
606 +      delete regs;
607 +      goto try_again_reg;
608 +
609 +   case 5:
610 +      /* OK */
611 +      break;
612 +   case -1:                        /* error or cancel */
613 +      goto bail_out_reg;
614 +   default:
615 +      goto try_again_reg;
616 +   }
617 +
618 +   /* replace the existing where */
619 +   if (jcr->where) {
620 +      bfree(jcr->where);
621 +      jcr->where = NULL;
622 +   }
623 +
624 +   if (rwhere) {
625 +      jcr->where = bstrdup(rwhere);
626 +   } else if (strip_prefix || add_prefix || add_suffix) {
627 +      int len = bregexp_get_build_where_size(strip_prefix, add_prefix, add_suffix);
628 +      jcr->where = (char *) bmalloc(len*sizeof(char));
629 +      bregexp_build_where(jcr->where, len, strip_prefix, add_prefix, add_suffix);
630 +   }
631 +
632 +   regs = get_bregexps(jcr->where);
633 +   if (regs) {
634 +      free_bregexps(regs);
635 +      delete regs;
636 +      jcr->where_use_regexp = true;
637 +   } else {
638 +      if (jcr->where) {
639 +        bfree(jcr->where);
640 +        jcr->where = NULL;
641 +      }
642 +      ua->send_msg(_("Cannot use your regexp.\n"));
643 +   }
644 +
645 +bail_out_reg:
646 +   if (strip_prefix) bfree(strip_prefix);
647 +   if (add_prefix)   bfree(add_prefix);
648 +   if (add_suffix)   bfree(add_suffix);
649 +   if (rwhere)       bfree(rwhere);
650 +}
651 +
652  static void select_job_level(UAContext *ua, JCR *jcr)
653  {
654     if (jcr->JobType == JT_BACKUP) {
655 Index: src/dird/dird_conf.h
656 ===================================================================
657 --- src/dird/dird_conf.h        (révision 4529)
658 +++ src/dird/dird_conf.h        (copie de travail)
659 @@ -356,6 +356,10 @@
660     int   Priority;                    /* Job priority */
661     int   RestoreJobId;                /* What -- JobId to restore */
662     char *RestoreWhere;                /* Where on disk to restore -- directory */
663 +   char *strip_prefix;                /* remove prefix from filename  */
664 +   char *add_prefix;                  /* add prefix to filename  */
665 +   char *add_suffix;                  /* add suffix to filename -- .old */
666 +   bool  where_use_regexp;            /* true if RestoreWhere is a BREGEXP */
667     char *RestoreBootstrap;            /* Bootstrap file */
668     alist *RunScripts;                 /* Run {client} program {after|before} Job */
669     union {
670 Index: src/filed/job.c
671 ===================================================================
672 --- src/filed/job.c     (révision 4529)
673 +++ src/filed/job.c     (copie de travail)
674 @@ -36,6 +36,7 @@
675  
676  #include "bacula.h"
677  #include "filed.h"
678 +#include "lib/breg.h"
679  
680  #if defined(WIN32_VSS)
681  #include "vss.h"
682 @@ -115,6 +116,7 @@
683  static char sessioncmd[]  = "session %127s %ld %ld %ld %ld %ld %ld\n";
684  static char restorecmd[]  = "restore replace=%c prelinks=%d where=%s\n";
685  static char restorecmd1[] = "restore replace=%c prelinks=%d where=\n";
686 +static char restorecmdR[] = "restore replace=%c prelinks=%d rwhere=%s\n";
687  static char verifycmd[]   = "verify level=%30s";
688  static char estimatecmd[] = "estimate listing=%d";
689  static char runbefore[]   = "RunBeforeJob %s";
690 @@ -1586,12 +1588,15 @@
691     *where = 0;
692  
693     if (sscanf(dir->msg, restorecmd, &replace, &prefix_links, where) != 3) {
694 -      if (sscanf(dir->msg, restorecmd1, &replace, &prefix_links) != 2) {
695 -         pm_strcpy(jcr->errmsg, dir->msg);
696 -         Jmsg(jcr, M_FATAL, 0, _("Bad replace command. CMD=%s\n"), jcr->errmsg);
697 -         return 0;
698 +      if (sscanf(dir->msg, restorecmdR, &replace, &prefix_links, where) != 3){
699 +         if (sscanf(dir->msg, restorecmd1, &replace, &prefix_links) != 2) {
700 +            pm_strcpy(jcr->errmsg, dir->msg);
701 +            Jmsg(jcr, M_FATAL, 0, _("Bad replace command. CMD=%s\n"), jcr->errmsg);
702 +            return 0;
703 +         }
704 +         *where = 0;
705        }
706 -      *where = 0;
707 +      jcr->where_use_regexp = true;
708     }
709     /* Turn / into nothing */
710     if (IsPathSeparator(where[0]) && where[1] == '\0') {
711 @@ -1601,6 +1606,15 @@
712     Dmsg2(150, "Got replace %c, where=%s\n", replace, where);
713     unbash_spaces(where);
714     jcr->where = bstrdup(where);
715 +
716 +   if (jcr->where_use_regexp) {
717 +      jcr->where_bregexp = get_bregexps(jcr->where);
718 +      if (!jcr->where_bregexp) {
719 +        Jmsg(jcr, M_FATAL, 0, _("Bad where regexp. where=%s\n"), jcr->where);
720 +        free_pool_memory(where);
721 +        return 0;
722 +      }
723 +   }
724     free_pool_memory(where);
725     jcr->replace = replace;
726     jcr->prefix_links = prefix_links;
727 Index: src/jcr.h
728 ===================================================================
729 --- src/jcr.h   (révision 4529)
730 +++ src/jcr.h   (copie de travail)
731 @@ -173,6 +173,8 @@
732     MSGS *jcr_msgs;                    /* Copy of message resource -- actually used */
733     uint32_t ClientId;                 /* Client associated with Job */
734     char *where;                       /* prefix to restore files to */
735 +   bool where_use_regexp;             /* True if where is a bregexp */
736 +   alist *where_bregexp;              /* BREGEXP alist for path manipulation */
737     int cached_pnl;                    /* cached path length */
738     POOLMEM *cached_path;              /* cached path */
739     bool prefix_links;                 /* Prefix links with Where path */
740 Index: src/lib/Makefile.in
741 ===================================================================
742 --- src/lib/Makefile.in (révision 4529)
743 +++ src/lib/Makefile.in (copie de travail)
744 @@ -32,7 +32,7 @@
745           res.c rwlock.c scan.c serial.c sha1.c \
746           signal.c smartall.c rblist.c tls.c tree.c \
747           util.c var.c watchdog.c workq.c btimers.c \
748 -         address_conf.c pythonlib.c
749 +         address_conf.c pythonlib.c breg.c
750  
751  
752  LIBOBJS = attr.o base64.o berrno.o bsys.o bget_msg.o \
753 @@ -45,7 +45,7 @@
754           res.o rwlock.o scan.o serial.o sha1.o \
755           signal.o smartall.o rblist.o tls.o tree.o \
756           util.o var.o watchdog.o workq.o btimers.o \
757 -         address_conf.o pythonlib.o
758 +         address_conf.o pythonlib.o breg.o
759  
760  
761  EXTRAOBJS = @OBJLIST@
762 Index: src/lib/attr.c
763 ===================================================================
764 --- src/lib/attr.c      (révision 4529)
765 +++ src/lib/attr.c      (copie de travail)
766 @@ -35,8 +35,8 @@
767  
768  #include "bacula.h"
769  #include "jcr.h"
770 +#include "lib/breg.h"
771  
772 -
773  ATTR *new_attr()
774  {
775     ATTR *attr = (ATTR *)malloc(sizeof(ATTR));
776 @@ -148,9 +148,30 @@
777      *   every filename if a prefix is supplied.
778      *
779      */
780 +
781     if (jcr->where[0] == 0) {
782        pm_strcpy(attr->ofname, attr->fname);
783        pm_strcpy(attr->olname, attr->lname);
784 +
785 +   } else if (jcr->where_bregexp) { 
786 +      char *ret;
787 +      apply_bregexps(attr->fname, jcr->where_bregexp, &ret);
788 +      pm_strcpy(attr->ofname, ret);
789 +
790 +      if (attr->type == FT_LNKSAVED || attr->type == FT_LNK) {
791 +         /* Always add prefix to hard links (FT_LNKSAVED) and
792 +          *  on user request to soft links
793 +          */
794 +
795 +         if ((attr->type == FT_LNKSAVED || jcr->prefix_links)) {
796 +            apply_bregexps(attr->lname, jcr->where_bregexp, &ret);
797 +            pm_strcpy(attr->olname, ret);
798 +
799 +         } else {
800 +            pm_strcpy(attr->olname, attr->lname);
801 +         }
802 +      }
803 +      
804     } else {
805        const char *fn;
806        int wherelen = strlen(jcr->where);
807 Index: src/lib/jcr.c
808 ===================================================================
809 --- src/lib/jcr.c       (révision 4529)
810 +++ src/lib/jcr.c       (copie de travail)
811 @@ -56,6 +56,9 @@
812  /* External variables we reference */
813  extern time_t watchdog_time;
814  
815 +/* External referenced functions */
816 +void free_bregexps(alist *bregexps);
817 +
818  /* Forward referenced functions */
819  extern "C" void timeout_handler(int sig);
820  static void jcr_timeout_check(watchdog_t *self);
821 @@ -381,6 +384,11 @@
822        free(jcr->where);
823        jcr->where = NULL;
824     }
825 +   if (jcr->where_bregexp) {
826 +      free_bregexps(jcr->where_bregexp);
827 +      delete jcr->where_bregexp;
828 +      jcr->where_bregexp = NULL;
829 +   }
830     if (jcr->cached_path) {
831        free_pool_memory(jcr->cached_path);
832        jcr->cached_path = NULL;