]> git.sur5r.net Git - bacula/bacula/blobdiff - bacula/src/dird/ua_run.c
Update ReleaseNotes
[bacula/bacula] / bacula / src / dird / ua_run.c
index eb776e428f1b9dad2d81bd5ab67017586f9fa00a..7bbafe5e60f7bfa7a0fe020867cfd5d57d00fb32 100644 (file)
@@ -1,11 +1,3 @@
-/*
- *
- *   Bacula Director -- Run Command
- *
- *     Kern Sibbald, December MMI
- *
- *   Version $Id$
- */
 /*
    Bacula® - The Network Backup Solution
 
    (FSFE), Fiduciary Program, Sumatrastrasse 25, 8006 Zürich,
    Switzerland, email:ftf@fsfeurope.org.
 */
+/*
+ *
+ *   Bacula Director -- Run Command
+ *
+ *     Kern Sibbald, December MMI
+ *
+ *   Version $Id$
+ */
 
 #include "bacula.h"
 #include "dird.h"
 
 /* Forward referenced subroutines */
 static void select_job_level(UAContext *ua, JCR *jcr);
-static bool display_job_parameters(UAContext *ua, JCR *jcr, JOB *job, char *verify_list, 
-   char *jid, const char *replace);
+static bool display_job_parameters(UAContext *ua, JCR *jcr, JOB *job, 
+                char *verify_list, char *jid, const char *replace,
+                char *client_name);
 static void select_where_regexp(UAContext *ua, JCR *jcr);
 
 
@@ -62,7 +63,8 @@ int run_cmd(UAContext *ua, const char *cmd)
 {
    JCR *jcr;
    char *job_name, *level_name, *jid, *store_name, *pool_name;
-   char *where, *fileset_name, *client_name, *bootstrap;
+   char *where, *fileset_name, *client_name, *bootstrap, *regexwhere;
+   char *restore_client_name;
    const char *replace;
    char *when, *verify_job_name, *catalog_name;
    char *previous_job_name;
@@ -72,7 +74,6 @@ int run_cmd(UAContext *ua, const char *cmd)
    int Priority = 0;
    int i, j, opt, files = 0;
    bool kw_ok;
-   bool where_use_regexp = false;
    JOB *job = NULL;
    JOB *verify_job = NULL;
    JOB *previous_job = NULL;
@@ -104,6 +105,8 @@ int run_cmd(UAContext *ua, const char *cmd)
       "verifylist",                   /* 20 verify output list */
       "migrationjob",                 /* 21 migration job name */
       "pool",                         /* 22 */
+      "backupclient",                 /* 23 */
+      "restoreclient",                /* 24 */
       NULL};
 
 #define YES_POS 14
@@ -118,8 +121,10 @@ int run_cmd(UAContext *ua, const char *cmd)
    store_name = NULL;
    pool_name = NULL;
    where = NULL;
+   regexwhere = NULL;
    when = NULL;
    client_name = NULL;
+   restore_client_name = NULL;
    fileset_name = NULL;
    bootstrap = NULL;
    replace = NULL;
@@ -192,12 +197,20 @@ int run_cmd(UAContext *ua, const char *cmd)
                kw_ok = true;
                break;
             case 8: /* regexwhere */
-            case 9: /* where */
-               /* TODO: this is ugly ... */
-               where_use_regexp = (j == 9)?false:true;/*regexwhere or where ?*/
-
-               if (where) {
-                  ua->send_msg(_("Where specified twice.\n"));
+                if (regexwhere || where) {
+                  ua->send_msg(_("RegexWhere or Where specified twice.\n"));
+                  return 0;
+               }
+               regexwhere = ua->argv[i];
+               if (!acl_access_ok(ua, Where_ACL, regexwhere)) {
+                  ua->send_msg(_("Forbidden \"regexwhere\" specified.\n"));
+                  return 0;
+               }
+               kw_ok = true;
+               break;
+           case 9: /* where */
+               if (where || regexwhere) {
+                  ua->send_msg(_("Where or RegexWhere specified twice.\n"));
                   return 0;
                }
                where = ua->argv[i];
@@ -294,7 +307,22 @@ int run_cmd(UAContext *ua, const char *cmd)
                pool_name = ua->argv[i];
                kw_ok = true;
                break;
-
+            case 23: /* backupclient */
+               if (client_name) {
+                  ua->send_msg(_("Client specified twice.\n"));
+                  return 0;
+               }
+               client_name = ua->argv[i];
+               kw_ok = true;
+               break;
+            case 24: /* restoreclient */
+               if (restore_client_name) {
+                  ua->send_msg(_("Restore Client specified twice.\n"));
+                  return 0;
+               }
+               restore_client_name = ua->argv[i];
+               kw_ok = true;
+               break;
             default:
                break;
             }
@@ -421,6 +449,27 @@ int run_cmd(UAContext *ua, const char *cmd)
    }
    Dmsg1(800, "Using client=%s\n", client->name());
 
+   if (restore_client_name) {
+      client = (CLIENT *)GetResWithName(R_CLIENT, restore_client_name);
+      if (!client) {
+         if (*restore_client_name != 0) {
+            ua->warning_msg(_("Restore Client \"%s\" not found.\n"), restore_client_name);
+         }
+         client = select_client_resource(ua);
+      }
+   } else {
+      client = job->client;           /* use default */
+   }
+   if (!client) {
+      return 0;
+   } else if (!acl_access_ok(ua, Client_ACL, client->name())) {
+      ua->error_msg(_("No authorization. Client \"%s\".\n"),
+               client->name());
+      return 0;
+   }
+   Dmsg1(800, "Using restore client=%s\n", client->name());
+
+
    if (fileset_name) {
       fileset = (FILESET *)GetResWithName(R_FILESET, fileset_name);
       if (!fileset) {
@@ -484,7 +533,13 @@ int run_cmd(UAContext *ua, const char *cmd)
          free(jcr->where);
       }
       jcr->where = bstrdup(where);
-      jcr->where_use_regexp = where_use_regexp;
+   }
+
+   if (regexwhere) {
+      if (jcr->RegexWhere) {
+         free(jcr->RegexWhere);
+      }
+      jcr->RegexWhere = bstrdup(regexwhere);       
    }
 
    if (when) {
@@ -570,7 +625,8 @@ try_again:
     * Prompt User to see if all run job parameters are correct, and
     *   allow him to modify them.
     */
-   if (!display_job_parameters(ua, jcr, job, verify_list, jid, replace)) {
+   if (!display_job_parameters(ua, jcr, job, verify_list, jid, replace,
+        client_name)) {
       goto bail_out;
    }
 
@@ -589,7 +645,11 @@ try_again:
       add_prompt(ua, _("Storage"));          /* 1 */
       add_prompt(ua, _("Job"));              /* 2 */
       add_prompt(ua, _("FileSet"));          /* 3 */
-      add_prompt(ua, _("Client"));           /* 4 */
+      if (jcr->JobType == JT_RESTORE) {
+         add_prompt(ua, _("Restore Client"));   /* 4 */
+      } else {
+         add_prompt(ua, _("Client"));        /* 4 */
+      }
       add_prompt(ua, _("When"));             /* 5 */
       add_prompt(ua, _("Priority"));         /* 6 */
       if (jcr->JobType == JT_BACKUP ||
@@ -602,7 +662,7 @@ try_again:
       } else if (jcr->JobType == JT_RESTORE) {
          add_prompt(ua, _("Bootstrap"));     /* 7 */
          add_prompt(ua, _("Where"));         /* 8 */
-         add_prompt(ua, _("File Relocation"));/* 9 */   
+         add_prompt(ua, _("File Relocation"));/* 9 */    
          add_prompt(ua, _("Replace"));       /* 10 */
          add_prompt(ua, _("JobId"));         /* 11 */
       }
@@ -719,6 +779,10 @@ try_again:
          if (!get_cmd(ua, _("Please enter path prefix for restore (/ for none): "))) {
             break;
          }
+         if (jcr->RegexWhere) { /* cannot use regexwhere and where */
+            free(jcr->RegexWhere);
+            jcr->RegexWhere = NULL;
+         }
          if (jcr->where) {
             free(jcr->where);
             jcr->where = NULL;
@@ -727,12 +791,11 @@ try_again:
             ua->cmd[0] = 0;
          }
          jcr->where = bstrdup(ua->cmd);
-        jcr->where_use_regexp = false;
          goto try_again;
       case 9: 
-        /* File relocation */
-        select_where_regexp(ua, jcr);
-        goto try_again;
+         /* File relocation */
+         select_where_regexp(ua, jcr);
+         goto try_again;
       case 10:
          /* Replace */
          start_prompt(ua, _("Replace:\n"));
@@ -796,7 +859,7 @@ static void select_where_regexp(UAContext *ua, JCR *jcr)
 
 try_again_reg:
    ua->send_msg(_("strip_prefix=%s add_prefix=%s add_suffix=%s\n"),
-               NPRT(strip_prefix), NPRT(add_prefix), NPRT(add_suffix));
+                NPRT(strip_prefix), NPRT(add_prefix), NPRT(add_suffix));
 
    start_prompt(ua, _("This will replace your current Where value\n"));
    add_prompt(ua, _("Strip prefix"));                /* 0 */
@@ -810,34 +873,34 @@ try_again_reg:
    case 0:
       /* Strip prefix */
       if (get_cmd(ua, _("Please enter path prefix to strip: "))) {
-        if (strip_prefix) bfree(strip_prefix);
-        strip_prefix = bstrdup(ua->cmd);
+         if (strip_prefix) bfree(strip_prefix);
+         strip_prefix = bstrdup(ua->cmd);
       }
       
       goto try_again_reg;
    case 1:
       /* Add prefix */
       if (get_cmd(ua, _("Please enter path prefix to add (/ for none): "))) {
-        if (IsPathSeparator(ua->cmd[0]) && ua->cmd[1] == '\0') {
-           ua->cmd[0] = 0;
-        }
+         if (IsPathSeparator(ua->cmd[0]) && ua->cmd[1] == '\0') {
+            ua->cmd[0] = 0;
+         }
 
-        if (add_prefix) bfree(add_prefix);
-        add_prefix = bstrdup(ua->cmd);
+         if (add_prefix) bfree(add_prefix);
+         add_prefix = bstrdup(ua->cmd);
       }
       goto try_again_reg;
    case 2:
       /* Add suffix */
       if (get_cmd(ua, _("Please enter file suffix to add: "))) {
-        if (add_suffix) bfree(add_suffix);
-        add_suffix = bstrdup(ua->cmd);
+         if (add_suffix) bfree(add_suffix);
+         add_suffix = bstrdup(ua->cmd);
       }      
       goto try_again_reg;
    case 3:
       /* Add rwhere */
       if (get_cmd(ua, _("Please enter a valid regexp (!from!to!): "))) {
-        if (rwhere) bfree(rwhere);
-        rwhere = bstrdup(ua->cmd);
+         if (rwhere) bfree(rwhere);
+         rwhere = bstrdup(ua->cmd);
       }
       
       goto try_again_reg;      
@@ -847,27 +910,27 @@ try_again_reg:
       char *regexp;
       
       if (rwhere && rwhere[0] != '\0') {
-        regs = get_bregexps(rwhere);
-        ua->send_msg(_("regexwhere=%s\n"), NPRT(rwhere));
+         regs = get_bregexps(rwhere);
+         ua->send_msg(_("regexwhere=%s\n"), NPRT(rwhere));
       } else {
-        int len = bregexp_get_build_where_size(strip_prefix, add_prefix, add_suffix);
-        regexp = (char *) bmalloc (len * sizeof(char));
-        bregexp_build_where(regexp, len, strip_prefix, add_prefix, add_suffix);
-        regs = get_bregexps(regexp);
-        ua->send_msg(_("strip_prefix=%s add_prefix=%s add_suffix=%s result=%s\n"),
-                     NPRT(strip_prefix), NPRT(add_prefix), NPRT(add_suffix), NPRT(regexp));
-        
-        bfree(regexp);
+         int len = bregexp_get_build_where_size(strip_prefix, add_prefix, add_suffix);
+         regexp = (char *) bmalloc (len * sizeof(char));
+         bregexp_build_where(regexp, len, strip_prefix, add_prefix, add_suffix);
+         regs = get_bregexps(regexp);
+         ua->send_msg(_("strip_prefix=%s add_prefix=%s add_suffix=%s result=%s\n"),
+                      NPRT(strip_prefix), NPRT(add_prefix), NPRT(add_suffix), NPRT(regexp));
+         
+         bfree(regexp);
       }
 
       if (!regs) {
-        ua->send_msg(_("Cannot use your regexp\n"));
-        goto try_again_reg;
+         ua->send_msg(_("Cannot use your regexp\n"));
+         goto try_again_reg;
       }
 
       while (get_cmd(ua, _("Please enter filename to test: "))) {
-        apply_bregexps(ua->cmd, regs, &result);
-        ua->send_msg(_("%s -> %s\n"), ua->cmd, result);
+         apply_bregexps(ua->cmd, regs, &result);
+         ua->send_msg(_("%s -> %s\n"), ua->cmd, result);
       }
       free_bregexps(regs);
       delete regs;
@@ -888,23 +951,28 @@ try_again_reg:
       jcr->where = NULL;
    }
 
+   /* replace the existing regexwhere */
+   if (jcr->RegexWhere) {
+      bfree(jcr->RegexWhere);
+      jcr->RegexWhere = NULL;
+   }
+
    if (rwhere) {
-      jcr->where = bstrdup(rwhere);
+      jcr->RegexWhere = bstrdup(rwhere);
    } else if (strip_prefix || add_prefix || add_suffix) {
       int len = bregexp_get_build_where_size(strip_prefix, add_prefix, add_suffix);
-      jcr->where = (char *) bmalloc(len*sizeof(char));
-      bregexp_build_where(jcr->where, len, strip_prefix, add_prefix, add_suffix);
+      jcr->RegexWhere = (char *) bmalloc(len*sizeof(char));
+      bregexp_build_where(jcr->RegexWhere, len, strip_prefix, add_prefix, add_suffix);
    }
 
-   regs = get_bregexps(jcr->where);
+   regs = get_bregexps(jcr->RegexWhere);
    if (regs) {
       free_bregexps(regs);
       delete regs;
-      jcr->where_use_regexp = true;
    } else {
-      if (jcr->where) {
-        bfree(jcr->where);
-        jcr->where = NULL;
+      if (jcr->RegexWhere) {
+         bfree(jcr->RegexWhere);
+         jcr->RegexWhere = NULL;
       }
       ua->send_msg(_("Cannot use your regexp.\n"));
    }
@@ -977,7 +1045,7 @@ static void select_job_level(UAContext *ua, JCR *jcr)
 }
 
 static bool display_job_parameters(UAContext *ua, JCR *jcr, JOB *job, char *verify_list,
-   char *jid, const char *replace) 
+   char *jid, const char *replace, char *client_name
 {
    Dmsg1(800, "JobType=%c\n", jcr->JobType);
    switch (jcr->JobType) {
@@ -1075,46 +1143,83 @@ static bool display_job_parameters(UAContext *ua, JCR *jcr, JOB *job, char *veri
       jcr->JobLevel = L_FULL;      /* default level */
       Dmsg1(800, "JobId to restore=%d\n", jcr->RestoreJobId);
       if (jcr->RestoreJobId == 0) {
+         if (ua->api) ua->signal(BNET_RUN_CMD);   
+         /* RegexWhere is take before RestoreWhere */
+         if (jcr->RegexWhere || (job->RegexWhere && !jcr->where)) {
+            ua->send_msg(_("Run Restore job\n"
+                        "JobName:        f%s\n"
+                        "Bootstrap:       %s\n"
+                        "RegexWhere:      %s\n"
+                        "Replace:         %s\n"
+                        "FileSet:         %s\n"
+                        "Backup Client:   %s\n"
+                        "Restore Client:  %s\n"
+                        "Storage:         %s\n"
+                        "When:            %s\n"
+                        "Catalog:         %s\n"
+                        "Priority:        %d\n"),
+                 job->name(),
+                 NPRT(jcr->RestoreBootstrap), 
+                 jcr->RegexWhere?jcr->RegexWhere:job->RegexWhere,
+                 replace,
+                 jcr->fileset->name(),
+                 client_name,
+                 jcr->client->name(),
+                 jcr->rstore->name(),
+                 bstrutime(dt, sizeof(dt), jcr->sched_time),
+                 jcr->catalog->name(),
+                 jcr->JobPriority);
+
+         } else {
+            ua->send_msg(_("Run Restore job\n"
+                        "JobName:         %s\n"
+                        "Bootstrap:       %s\n"
+                        "Where:           %s\n"
+                        "Replace:         %s\n"
+                        "FileSet:         %s\n"
+                        "Backup Client:   %s\n"
+                        "Restore Client:  %s\n"
+                        "Storage:         %s\n"
+                        "When:            %s\n"
+                        "Catalog:         %s\n"
+                        "Priority:        %d\n"),
+                 job->name(),
+                 NPRT(jcr->RestoreBootstrap), 
+                 jcr->where?jcr->where:NPRT(job->RestoreWhere), 
+                 replace,
+                 jcr->fileset->name(),
+                 client_name,
+                 jcr->client->name(),
+                 jcr->rstore->name(),
+                 bstrutime(dt, sizeof(dt), jcr->sched_time),
+                 jcr->catalog->name(),
+                 jcr->JobPriority);
+         }
+
+      } else {
          if (ua->api) ua->signal(BNET_RUN_CMD);   
          ua->send_msg(_("Run Restore job\n"
                         "JobName:    %s\n"
-                        "Bootstrap:  %s\n"
-                        "%s %s\n"             /* Where or RegexWhere */
-                        "Replace:    %s\n"
-                        "FileSet:    %s\n"
+                        "Bootstrap:  %s\n"),
+                      job->name(),
+                      NPRT(jcr->RestoreBootstrap));
+                      
+         /* RegexWhere is take before RestoreWhere */
+         if (jcr->RegexWhere || (job->RegexWhere && !jcr->where)) {
+            ua->send_msg(_("RegexWhere: %s\n"),
+                         jcr->RegexWhere?jcr->RegexWhere:job->RegexWhere);
+         } else {
+            ua->send_msg(_("Where:      %s\n"),
+                         jcr->where?jcr->where:NPRT(job->RestoreWhere));
+         }
+
+         ua->send_msg(_("Replace:    %s\n"
                         "Client:     %s\n"
                         "Storage:    %s\n"
+                        "JobId:      %s\n"
                         "When:       %s\n"
                         "Catalog:    %s\n"
                         "Priority:   %d\n"),
-              job->name(),
-              NPRT(jcr->RestoreBootstrap),
-              jcr->where_use_regexp?"RegexWhere:":"Where:     ",
-              jcr->where?jcr->where:NPRT(job->RestoreWhere),
-              replace,
-              jcr->fileset->name(),
-              jcr->client->name(),
-              jcr->rstore->name(),
-              bstrutime(dt, sizeof(dt), jcr->sched_time),
-              jcr->catalog->name(),
-              jcr->JobPriority);
-      } else {
-         if (ua->api) ua->signal(BNET_RUN_CMD);   
-         ua->send_msg(_("Run Restore job\n"
-                       "JobName:    %s\n"
-                       "Bootstrap:  %s\n"
-                       "%s %s\n"             /* Where or RegexWhere */
-                       "Replace:    %s\n"
-                       "Client:     %s\n"
-                       "Storage:    %s\n"
-                       "JobId:      %s\n"
-                       "When:       %s\n"
-                       "Catalog:    %s\n"
-                       "Priority:   %d\n"),
-              job->name(),
-              NPRT(jcr->RestoreBootstrap),
-              jcr->where_use_regexp?"RegexWhere:":"Where:     ",
-              jcr->where?jcr->where:NPRT(job->RestoreWhere),
               replace,
               jcr->client->name(),
               jcr->rstore->name(),