]> git.sur5r.net Git - bacula/bacula/blobdiff - bacula/src/filed/job.c
- Add .status [current|last] command to filed and stored
[bacula/bacula] / bacula / src / filed / job.c
index e08f11d4f61549e542d3a58a85d1daf251969b9c..86bdfab4bc818c0b10b265bf8877f414b537a5cb 100644 (file)
@@ -34,7 +34,8 @@ extern CLIENT *me;                  /* our client resource */
                        
 /* Imported functions */
 extern int status_cmd(JCR *jcr);
-                                  
+extern int qstatus_cmd(JCR *jcr);
+
 /* Forward referenced functions */
 static int backup_cmd(JCR *jcr);
 static int bootstrap_cmd(JCR *jcr);
@@ -64,7 +65,7 @@ static void set_options(findFOPTS *fo, const char *opts);
 /* Exported functions */
 
 struct s_cmds {
-   char *cmd;
+   const char *cmd;
    int (*func)(JCR *);
 };
 
@@ -85,6 +86,7 @@ static struct s_cmds cmds[] = {
    {"restore",      restore_cmd},
    {"session",      session_cmd},
    {"status",       status_cmd},
+   {".status",      qstatus_cmd},
    {"storage ",     storage_cmd},
    {"verify",       verify_cmd},
    {"bootstrap",    bootstrap_cmd},
@@ -161,7 +163,8 @@ static char read_close[]   = "read close session %d\n";
  */
 void *handle_client_request(void *dirp)
 {
-   int i, found, quit;
+   int i; 
+   bool found, quit;
    JCR *jcr;
    BSOCK *dir = (BSOCK *)dirp;
 
@@ -178,7 +181,7 @@ void *handle_client_request(void *dirp)
 
    /**********FIXME******* add command handler error code */
 
-   for (quit=0; !quit;) {
+   for (quit=false; !quit;) {
 
       /* Read command */
       if (bnet_recv(dir) < 0) {
@@ -186,24 +189,25 @@ void *handle_client_request(void *dirp)
       }
       dir->msg[dir->msglen] = 0;
       Dmsg1(100, "<dird: %s", dir->msg);
-      found = FALSE;
+      found = false;
       for (i=0; cmds[i].cmd; i++) {
         if (strncmp(cmds[i].cmd, dir->msg, strlen(cmds[i].cmd)) == 0) {
            if (!jcr->authenticated && cmds[i].func != hello_cmd) {
               bnet_fsend(dir, no_auth);
               break;
            }
-           found = TRUE;                /* indicate command found */
+           found = true;                /* indicate command found */
+            Dmsg1(100, "Executing %s command.\n", cmds[i].cmd);
            if (!cmds[i].func(jcr)) {    /* do command */
-              quit = TRUE;              /* error or fully terminated,  get out */
-               Dmsg0(20, "Command error or Job done.\n");
+              quit = true;              /* error or fully terminated,  get out */
+               Dmsg0(20, "Quit command loop due to command error or Job done.\n");
            }
            break;
         }
       }
       if (!found) {                  /* command not found */
         bnet_fsend(dir, errmsg);
-        quit = TRUE;
+        quit = true;
         break;
       }
    }
@@ -224,15 +228,24 @@ void *handle_client_request(void *dirp)
    FF_PKT *ff = (FF_PKT *)jcr->ff;
    findFILESET *fileset = ff->fileset;
    if (fileset) {
-      int i, j;
+      int i, j, k;
       /* Delete FileSet Include lists */
       for (i=0; i<fileset->include_list.size(); i++) {
         findINCEXE *incexe = (findINCEXE *)fileset->include_list.get(i);
         for (j=0; j<incexe->opts_list.size(); j++) {
            findFOPTS *fo = (findFOPTS *)incexe->opts_list.get(j);
+           for (k=0; k<fo->regex.size(); k++) {
+              regfree((regex_t *)fo->regex.get(k));
+           }
            fo->regex.destroy();
            fo->wild.destroy();
            fo->base.destroy();
+           if (fo->reader) {
+              free(fo->reader);
+           }
+           if (fo->writer) {
+              free(fo->writer);
+           }
         }
         incexe->opts_list.destroy();
         incexe->name_list.destroy();
@@ -273,7 +286,7 @@ static int hello_cmd(JCR *jcr)
       return 0;
    }
    Dmsg0(120, "OK Authenticate\n");
-   jcr->authenticated = TRUE;
+   jcr->authenticated = true;
    return 1;
 }
 
@@ -518,8 +531,9 @@ static void add_fname_to_list(JCR *jcr, char *fname, int list)
    case '<':
       p++;                     /* skip over < */
       if ((ffd = fopen(p, "r")) == NULL) {
+        berrno be;
          Jmsg(jcr, M_FATAL, 0, _("Cannot open %s file: %s. ERR=%s\n"),
-            list==INC_LIST?"included":"excluded", p, strerror(errno));
+            list==INC_LIST?"included":"excluded", p, be.strerror());
         return;
       }
       /* Copy File options */
@@ -610,6 +624,62 @@ static findFOPTS *start_options(FF_PKT *ff)
 
 }
 
+/*
+ * Add fname to include/exclude fileset list. First check for
+ * | and < and if necessary perform command.
+ */
+static void add_file_to_fileset(JCR *jcr, const char *fname, findFILESET *fileset)
+{
+   char *p;
+   BPIPE *bpipe;
+   POOLMEM *fn;
+   FILE *ffd;
+   char buf[1000];
+   int stat;
+
+   p = (char *)fname;
+   switch (*p) {
+   case '|':
+      p++;                           /* skip over | */
+      fn = get_pool_memory(PM_FNAME);
+      fn = edit_job_codes(jcr, fn, p, "");
+      bpipe = open_bpipe(fn, 0, "r");
+      free_pool_memory(fn);
+      if (!bpipe) {
+         Jmsg(jcr, M_FATAL, 0, _("Cannot run program: %s. ERR=%s\n"),
+           p, strerror(errno));
+        return;
+      }
+      while (fgets(buf, sizeof(buf), bpipe->rfd)) {
+        strip_trailing_junk(buf);
+        fileset->incexe->name_list.append(bstrdup(buf));
+      }
+      if ((stat=close_bpipe(bpipe)) != 0) {
+         Jmsg(jcr, M_FATAL, 0, _("Error running program: %s. RtnStat=%d ERR=%s\n"),
+           p, stat, strerror(errno));
+        return;
+      }
+      break;
+   case '<':
+      p++;                     /* skip over < */
+      if ((ffd = fopen(p, "r")) == NULL) {
+        berrno be;
+         Jmsg(jcr, M_FATAL, 0, _("Cannot open FileSet input file: %s. ERR=%s\n"),
+           p, be.strerror());
+        return;
+      }
+      while (fgets(buf, sizeof(buf), ffd)) {
+        strip_trailing_junk(buf);
+        fileset->incexe->name_list.append(bstrdup(buf));
+      }
+      fclose(ffd);
+      break;
+   default:
+      fileset->incexe->name_list.append(bstrdup(fname));
+      break;
+   }
+}
+
    
 static void add_fileset(JCR *jcr, const char *item)
 {
@@ -618,6 +688,7 @@ static void add_fileset(JCR *jcr, const char *item)
    int state = fileset->state;
    findFOPTS *current_opts;
 
+   Dmsg1(100, "%s\n", item);
    int code = item[0];
    if (item[1] == ' ') {              /* If string follows */
       item += 2;                     /* point to string */
@@ -647,13 +718,26 @@ static void add_fileset(JCR *jcr, const char *item)
       state = state_none;
       break;
    case 'F':
-      /* File item */
+      /* File item to either include/include list */
       state = state_include;
-      fileset->incexe->name_list.append(bstrdup(item));
+      add_file_to_fileset(jcr, item, fileset);
       break;
    case 'R':
       current_opts = start_options(ff);
-      current_opts->regex.append(bstrdup(item));
+      regex_t *preg;
+      int rc;
+      char prbuf[500];
+      preg = (regex_t *)malloc(sizeof(regex_t));
+      rc = regcomp(preg, item, REG_EXTENDED);
+      if (rc != 0) {
+        regerror(rc, preg, prbuf, sizeof(prbuf));
+        regfree(preg);
+        free(preg);
+         Jmsg(jcr, M_FATAL, 0, "REGEX %s compile error. ERR=%s\n", item, prbuf);
+        state = state_error;
+        break;
+      }
+      current_opts->regex.append(preg);
       state = state_options;
       break;
    case 'B':
@@ -671,6 +755,16 @@ static void add_fileset(JCR *jcr, const char *item)
       set_options(current_opts, item);
       state = state_options;
       break;
+   case 'D':
+      current_opts = start_options(ff);
+      current_opts->reader = bstrdup(item);
+      state = state_options;
+      break;
+   case 'T':
+      current_opts = start_options(ff);
+      current_opts->writer = bstrdup(item);
+      state = state_options;
+      break;
    default:
       Jmsg(jcr, M_FATAL, 0, "Invalid FileSet command: %s\n", item);
       state = state_error;
@@ -699,6 +793,12 @@ static bool term_fileset(JCR *jcr)
         for (k=0; k<fo->base.size(); k++) {
             Dmsg1(400, "B %s\n", (char *)fo->base.get(k));
         }
+        if (fo->reader) {
+            Dmsg1(400, "D %s\n", fo->reader);
+        }
+        if (fo->writer) {
+            Dmsg1(400, "T %s\n", fo->writer);
+        }
       }
       for (j=0; j<incexe->name_list.size(); j++) {
          Dmsg1(400, "F %s\n", (char *)incexe->name_list.get(j));
@@ -852,12 +952,13 @@ static int bootstrap_cmd(JCR *jcr)
       unlink(jcr->RestoreBootstrap);
       free_pool_memory(jcr->RestoreBootstrap);
    }
-   Mmsg(&fname, "%s/%s.%s.bootstrap", me->working_directory, me->hdr.name,
+   Mmsg(fname, "%s/%s.%s.bootstrap", me->working_directory, me->hdr.name,
       jcr->Job);
    Dmsg1(400, "bootstrap=%s\n", fname);
    jcr->RestoreBootstrap = fname;
    bs = fopen(fname, "a+");           /* create file */
    if (!bs) {
+      berrno be;
       /* 
        * Suck up what he is sending to us so that he will then
        *   read our error message.
@@ -866,7 +967,7 @@ static int bootstrap_cmd(JCR *jcr)
        {  }
 
       Jmsg(jcr, M_FATAL, 0, _("Could not create bootstrap file %s: ERR=%s\n"),
-        jcr->RestoreBootstrap, strerror(errno));
+        jcr->RestoreBootstrap, be.strerror());
       free_pool_memory(jcr->RestoreBootstrap);
       jcr->RestoreBootstrap = NULL;
       set_jcr_job_status(jcr, JS_ErrorTerminated);
@@ -960,7 +1061,7 @@ static int level_cmd(JCR *jcr)
         his_time = str_to_uint64(buf);
         rt = get_current_btime() - bt_start; /* compute round trip time */
         bt_adj -= his_time - bt_start - rt/2;
-         Dmsg2(100, "rt=%s adj=%s\n", edit_uint64(rt, ed1), edit_uint64(bt_adj, ed2));
+         Dmsg2(200, "rt=%s adj=%s\n", edit_uint64(rt, ed1), edit_uint64(bt_adj, ed2));
       }
 
       bt_adj = bt_adj / 8;           /* compute average time */
@@ -974,7 +1075,7 @@ static int level_cmd(JCR *jcr)
 
       Dmsg2(100, "adj = %d since_time=%d\n", (int)adj, (int)since_time);
       jcr->incremental = 1;          /* set incremental or decremental backup */
-      jcr->mtime = since_time;       /* set since time */
+      jcr->mtime = (time_t)since_time; /* set since time */
    } else {
       Jmsg1(jcr, M_FATAL, 0, "Unknown backup level: %s\n", level);
       free_memory(level);
@@ -1036,13 +1137,16 @@ static int storage_cmd(JCR *jcr)
    Dmsg3(110, "Open storage: %s:%d ssl=%d\n", jcr->stored_addr, stored_port, enable_ssl);
    /* Open command communications with Storage daemon */
    /* Try to connect for 1 hour at 10 second intervals */
-   sd = bnet_connect(jcr, 10, me->SDConnectTimeout, _("Storage daemon"), 
+   sd = bnet_connect(jcr, 10, (int)me->SDConnectTimeout, _("Storage daemon"), 
                     jcr->stored_addr, NULL, stored_port, 1);
    if (sd == NULL) {
       Jmsg(jcr, M_FATAL, 0, _("Failed to connect to Storage daemon: %s:%d\n"),
          jcr->stored_addr, stored_port);
+      Dmsg2(100, "Failed to connect to Storage daemon: %s:%d\n",
+         jcr->stored_addr, stored_port);
       return 0;
    }
+   Dmsg0(110, "Connection OK to SD.\n");
 
    jcr->store_bsock = sd;
 
@@ -1122,6 +1226,7 @@ static int backup_cmd(JCR *jcr)
    if (!blast_data_to_storage_daemon(jcr, NULL)) {
       set_jcr_job_status(jcr, JS_ErrorTerminated);
       bnet_suppress_error_messages(sd, 1);
+      Dmsg0(110, "Error in blast_data.\n");
    } else {
       set_jcr_job_status(jcr, JS_Terminated);
       if (jcr->JobStatus != JS_Terminated) {
@@ -1167,10 +1272,10 @@ static int backup_cmd(JCR *jcr)
    }
 
 cleanup:
-
    bnet_fsend(dir, EndJob, jcr->JobStatus, jcr->JobFiles, 
       edit_uint64(jcr->ReadBytes, ed1), 
       edit_uint64(jcr->JobBytes, ed2), jcr->Errors);   
+   Dmsg1(110, "End FD msg: %s\n", dir->msg);
 
    return 0;                         /* return and stop command loop */
 }
@@ -1461,7 +1566,7 @@ static int send_bootstrap_file(JCR *jcr)
    FILE *bs;
    char buf[2000];
    BSOCK *sd = jcr->store_bsock;
-   char *bootstrap = "bootstrap\n";
+   const char *bootstrap = "bootstrap\n";
    int stat = 0;
 
    Dmsg1(400, "send_bootstrap_file: %s\n", jcr->RestoreBootstrap);
@@ -1470,8 +1575,9 @@ static int send_bootstrap_file(JCR *jcr)
    }
    bs = fopen(jcr->RestoreBootstrap, "r");
    if (!bs) {
+      berrno be;
       Jmsg(jcr, M_FATAL, 0, _("Could not open bootstrap file %s: ERR=%s\n"), 
-        jcr->RestoreBootstrap, strerror(errno));
+        jcr->RestoreBootstrap, be.strerror());
       set_jcr_job_status(jcr, JS_ErrorTerminated);
       goto bail_out;
    }
@@ -1479,7 +1585,7 @@ static int send_bootstrap_file(JCR *jcr)
    sd->msglen = strlen(sd->msg);
    bnet_send(sd);
    while (fgets(buf, sizeof(buf), bs)) {
-      sd->msglen = Mmsg(&sd->msg, "%s", buf);
+      sd->msglen = Mmsg(sd->msg, "%s", buf);
       bnet_send(sd);      
    }
    bnet_sig(sd, BNET_EOD);