]> git.sur5r.net Git - bacula/bacula/commitdiff
Add RunBeforeJob and RunAfterJob -- kes18Jul02
authorKern Sibbald <kern@sibbald.com>
Thu, 18 Jul 2002 17:40:22 +0000 (17:40 +0000)
committerKern Sibbald <kern@sibbald.com>
Thu, 18 Jul 2002 17:40:22 +0000 (17:40 +0000)
git-svn-id: https://bacula.svn.sourceforge.net/svnroot/bacula/trunk@64 91ce42f0-d328-0410-95d8-f526ca767f89

bacula/src/dird/dird_conf.c
bacula/src/dird/dird_conf.h
bacula/src/dird/job.c
bacula/src/lib/message.c
bacula/src/lib/protos.h
bacula/src/lib/util.c
bacula/src/stored/dev.c
bacula/src/stored/device.c

index 1cc6195c4ae98b7c9885f30aef13652e0adb5761..a16f3aa3352e687c76a271d451ac59f2659e3d4f 100644 (file)
@@ -177,6 +177,8 @@ static struct res_items job_items[] = {
    {"prunejobs",   store_yesno, ITEM(res_job.PruneJobs), 1, ITEM_DEFAULT, 0},
    {"prunefiles",  store_yesno, ITEM(res_job.PruneFiles), 1, ITEM_DEFAULT, 0},
    {"prunevolumes", store_yesno, ITEM(res_job.PruneVolumes), 1, ITEM_DEFAULT, 0},
+   {"runbeforejob", store_str,  ITEM(res_job.RunBeforeJob), 0, 0, 0},
+   {"runafterjob",  store_str,  ITEM(res_job.RunAfterJob),  0, 0, 0},
    {NULL, NULL, NULL, 0, 0, 0} 
 };
 
@@ -476,6 +478,12 @@ void dump_resource(int type, RES *reshdr, void sendit(void *sock, char *fmt, ...
         if (res->res_job.RestoreBootstrap) {
             sendit(sock, "  --> Bootstrap=%s\n", NPRT(res->res_job.RestoreBootstrap));
         }
+        if (res->res_job.RunBeforeJob) {
+            sendit(sock, "  --> RunBefore=%s\n", NPRT(res->res_job.RunBeforeJob));
+        }
+        if (res->res_job.RunAfterJob) {
+            sendit(sock, "  --> RunAfter=%s\n", NPRT(res->res_job.RunAfterJob));
+        }
         if (res->res_job.storage) {
             sendit(sock, "  --> ");
            dump_resource(-R_STORAGE, (RES *)res->res_job.storage, sendit, sock);
@@ -703,6 +711,12 @@ void free_resource(int type)
         if (res->res_job.RestoreBootstrap) {
            free(res->res_job.RestoreBootstrap);
         }
+        if (res->res_job.RunBeforeJob) {
+           free(res->res_job.RunBeforeJob);
+        }
+        if (res->res_job.RunAfterJob) {
+           free(res->res_job.RunAfterJob);
+        }
         break;
       case R_MSGS:
         if (res->res_msgs.mail_cmd)
index 603ca943aaccd4075b8f80af0ee9b413028a536a..079b80835a2b5d8e6a4cad05dd24533a01230245 100644 (file)
@@ -156,6 +156,8 @@ struct s_res_job {
    int  RestoreJobId;                /* What -- JobId to restore */
    char *RestoreWhere;               /* Where on disk to restore -- directory */
    char *RestoreBootstrap;           /* Bootstrap file */
+   char *RunBeforeJob;               /* Run program before Job */
+   char *RunAfterJob;                /* Run program after Job */
    int  RestoreOptions;              /* How (overwrite, ..) */
    btime_t MaxRunTime;               /* max run time in seconds */
    btime_t MaxStartDelay;            /* max start delay in seconds */
index 0900b33d9613e949522cfc878425908fdeb4025d..e72bd5e60fb11c54f90f40ebcd5f58e72f15c819 100644 (file)
@@ -31,6 +31,7 @@
 
 /* Forward referenced subroutines */
 static void job_thread(void *arg);
+static char *edit_run_codes(JCR *jcr, char *omsg, char *imsg);
 
 /* Exported subroutines */
 void run_job(JCR *jcr);
@@ -151,6 +152,14 @@ static void job_thread(void *arg)
       /* Run Job */
       jcr->JobStatus = JS_Running;
 
+      if (jcr->job->RunBeforeJob) {
+        POOLMEM *before = get_pool_memory(PM_FNAME);
+        int status;
+        
+        before = edit_run_codes(jcr, before, jcr->job->RunBeforeJob);
+        status = run_program(before, 0, NULL);
+        free_pool_memory(before);
+      }
       switch (jcr->JobType) {
         case JT_BACKUP:
            do_backup(jcr);
@@ -179,6 +188,14 @@ static void job_thread(void *arg)
            break;
         }
    }
+   if (jcr->job->RunAfterJob) {
+      POOLMEM *after = get_pool_memory(PM_FNAME);
+      int status;
+      
+      after = edit_run_codes(jcr, after, jcr->job->RunAfterJob);
+      status = run_program(after, 0, NULL);
+      free_pool_memory(after);
+   }
    Dmsg0(50, "Before free jcr\n");
    free_jcr(jcr);
    Dmsg0(50, "======== End Job ==========\n");
@@ -360,3 +377,84 @@ void set_jcr_defaults(JCR *jcr, JOB *job)
       }
    }
 }
+
+/*
+ * Edit codes into Run command
+ *  %% = %
+ *  %c = Client's name
+ *  %d = Director's name
+ *  %i = JobId
+ *  %e = Job Exit
+ *  %j = Job
+ *  %l = Job Level
+ *  %n = Job name
+ *  %t = Job type
+ *
+ *  omsg = edited output message
+ *  imsg = input string containing edit codes (%x)
+ *
+ */
+static char *edit_run_codes(JCR *jcr, char *omsg, char *imsg) 
+{
+   char *p, *o;
+   const char *str;
+   char add[20];
+
+   Dmsg1(200, "edit_run_codes: %s\n", imsg);
+   add[2] = 0;
+   o = omsg;
+   for (p=imsg; *p; p++) {
+      if (*p == '%') {
+        switch (*++p) {
+         case '%':
+            add[0] = '%';
+           add[1] = 0;
+           str = add;
+           break;
+         case 'c':
+           str = jcr->client_name;
+           if (!str) {
+               str = "";
+           }
+           break;
+         case 'd':
+           str = my_name;
+           break;
+         case 'e':
+           str = job_status_to_str(jcr->JobStatus);
+           break;
+         case 'i':
+            sprintf(add, "%d", jcr->JobId);
+           str = add;
+           break;
+         case 'j':                    /* Job */
+           str = jcr->Job;
+           break;
+         case 'l':
+           str = job_level_to_str(jcr->JobLevel);
+           break;
+         case 'n':
+           str = jcr->job->hdr.name;
+           break;
+         case 't':
+           str = job_type_to_str(jcr->JobType);
+           break;
+        default:
+            add[0] = '%';
+           add[1] = *p;
+           str = add;
+           break;
+        }
+      } else {
+        add[0] = *p;
+        add[1] = 0;
+        str = add;
+      }
+      Dmsg1(200, "add_str %s\n", str);
+      add_str_to_pool_mem(&omsg, &o, (char *)str);
+      *o = 0;
+      Dmsg1(200, "omsg=%s\n", omsg);
+   }
+   *o = 0;
+   return omsg;
+}
index 1408e31b47e1ac36de8fb2e321329b40cd7c5738..6639f0e3b8664ed9b80feada1d16e9e116450500 100755 (executable)
@@ -279,103 +279,6 @@ void rem_msg_dest(MSGS *msg, int dest_code, int msg_type, char *where)
 }
 
 
-/*
- * Convert Job Termination Status into a string
- */
-static char *job_status_to_str(int stat) 
-{
-   char *str;
-
-   switch (stat) {
-   case JS_Terminated:
-      str = "OK";
-      break;
-   case JS_ErrorTerminated:
-   case JS_Error:
-      str = "Error";
-      break;
-   case JS_FatalError:
-      str = "Fatal Error";
-      break;
-   case JS_Cancelled:
-      str = "Cancelled";
-      break;
-   case JS_Differences:
-      str = "Differences";
-      break;
-   default:
-      str = "Unknown term code";
-      break;
-   }
-   return str;
-}
-
-
-/*
- * Convert Job Type into a string
- */
-static char *job_type_to_str(int type) 
-{
-   char *str;
-
-   switch (type) {
-   case JT_BACKUP:
-      str = "Backup";
-      break;
-   case JT_VERIFY:
-      str = "Verify";
-      break;
-   case JT_RESTORE:
-      str = "Restore";
-      break;
-   default:
-      str = "Unknown Job Type";
-      break;
-   }
-   return str;
-}
-
-/*
- * Convert Job Level into a string
- */
-static char *job_level_to_str(int level) 
-{
-   char *str;
-
-   switch (level) {
-   case L_FULL:
-      str = "full";
-      break;
-   case L_INCREMENTAL:
-      str = "incremental";
-      break;
-   case L_DIFFERENTIAL:
-      str = "differential";
-      break;
-   case L_LEVEL:
-      str = "level";
-      break;
-   case L_SINCE:
-      str = "since";
-      break;
-   case L_VERIFY_CATALOG:
-      str = "verify catalog";
-      break;
-   case L_VERIFY_INIT:
-      str = "verify init";
-      break;
-   case L_VERIFY_VOLUME_TO_CATALOG:
-      str = "verify volume to catalog";
-      break;
-   case L_VERIFY_DATA:
-      str = "verify data";
-      break;
-   default:
-      str = "Unknown Job level";
-      break;
-   }
-   return str;
-}
 
 
 /*
@@ -384,6 +287,7 @@ static char *job_level_to_str(int level)
  *  %j = Job name
  *  %t = Job type (Backup, ...)
  *  %e = Job Exit code
+ *  %i = JobId
  *  %l = job level
  *  %c = Client's name
  *  %r = Recipients
@@ -397,7 +301,7 @@ static char *job_level_to_str(int level)
 static char *edit_job_codes(JCR *jcr, char *omsg, char *imsg, char *to)   
 {
    char *p, *o, *str;
-   char add[3];
+   char add[20];
 
    Dmsg1(200, "edit_job_codes: %s\n", imsg);
    add[2] = 0;
@@ -410,29 +314,33 @@ static char *edit_job_codes(JCR *jcr, char *omsg, char *imsg, char *to)
            add[1] = 0;
            str = add;
            break;
-         case 'j':                    /* Job name */
-           str = jcr->Job;
+         case 'c':
+           str = jcr->client_name;
+           if (!str) {
+               str = "";
+           }
+           break;
+         case 'd':
+            str = my_name;            /* Director's name */
            break;
          case 'e':
            str = job_status_to_str(jcr->JobStatus); 
            break;
-         case 't':
-           str = job_type_to_str(jcr->JobType);
+         case 'i':
+            sprintf(add, "%d", jcr->JobId);
+           str = add;
            break;
-         case 'r':
-           str = to;
+         case 'j':                    /* Job name */
+           str = jcr->Job;
            break;
          case 'l':
            str = job_level_to_str(jcr->JobLevel);
            break;
-         case 'c':
-           str = jcr->client_name;
-           if (!str) {
-               str = "";
-           }
+         case 'r':
+           str = to;
            break;
-         case 'd':
-            str = my_name;            /* Director's name */
+         case 't':
+           str = job_type_to_str(jcr->JobType);
            break;
         default:
             add[0] = '%';
index c461784ce13bf99bbed6ea3e53f4e55c5bf17301..2f54983fc048aaa3ceab1a039afdb8dd33492d2a 100644 (file)
  */
 
 /* base64.c */
-void      base64_init            (void);
-int       to_base64              (intmax_t value, char *where);
-int       from_base64            (intmax_t *value, char *where);
-void      encode_stat            (char *buf, struct stat *statp);
-void      decode_stat            (char *buf, struct stat *statp);
-int       bin_to_base64          (char *buf, char *bin, int len);
+void     base64_init            (void);
+int      to_base64              (intmax_t value, char *where);
+int      from_base64            (intmax_t *value, char *where);
+void     encode_stat            (char *buf, struct stat *statp);
+void     decode_stat            (char *buf, struct stat *statp);
+int      bin_to_base64          (char *buf, char *bin, int len);
 
 /* bmisc.c */
-void     *b_malloc               (char *file, int line, size_t size);
+void    *b_malloc               (char *file, int line, size_t size);
 #ifndef DEBUG
-void     *bmalloc                (size_t size);
+void    *bmalloc                (size_t size);
 #endif
-void     *brealloc               (void *buf, size_t size);
-void     *bcalloc                (size_t size1, size_t size2);
-int       bsnprintf              (char *str, size_t size, const  char  *format, ...);
-int       bvsnprintf             (char *str, size_t size, const char  *format, va_list ap);
-int       pool_sprintf           (char *pool_buf, char *fmt, ...);
-void      create_pid_file        (char *dir, char *progname, int port);
-int       delete_pid_file        (char *dir, char *progname, int port);
+void    *brealloc               (void *buf, size_t size);
+void    *bcalloc                (size_t size1, size_t size2);
+int      bsnprintf              (char *str, size_t size, const  char  *format, ...);
+int      bvsnprintf             (char *str, size_t size, const char  *format, va_list ap);
+int      pool_sprintf           (char *pool_buf, char *fmt, ...);
+void     create_pid_file        (char *dir, char *progname, int port);
+int      delete_pid_file        (char *dir, char *progname, int port);
 #ifndef HAVE_STRERROR_R
-int       strerror_r             (int errnum, char *buf, size_t bufsiz);
+int      strerror_r             (int errnum, char *buf, size_t bufsiz);
 #endif
 
 
 /* bnet.c */
-int32_t    bnet_recv             (BSOCK *bsock);
-int        bnet_send             (BSOCK *bsock);
-int        bnet_fsend              (BSOCK *bs, char *fmt, ...);
-int        bnet_set_buffer_size    (BSOCK *bs, uint32_t size, int rw);
-int        bnet_sig                (BSOCK *bs, int sig);
-BSOCK *    bnet_connect            (void *jcr, int retry_interval,
-               int max_retry_time, char *name, char *host, char *service, 
-               int port, int verbose);
-int        bnet_wait_data         (BSOCK *bsock, int sec);
-void       bnet_close            (BSOCK *bsock);
-BSOCK *    init_bsock            (int sockfd, char *who, char *ip, int port);
-BSOCK *    dup_bsock             (BSOCK *bsock);
-void       term_bsock            (BSOCK *bsock);
-char *     bnet_strerror         (BSOCK *bsock);
-char *     bnet_sig_to_ascii     (BSOCK *bsock);
-int        bnet_wait_data        (BSOCK *bsock, int sec);
+int32_t    bnet_recv            (BSOCK *bsock);
+int       bnet_send             (BSOCK *bsock);
+int       bnet_fsend              (BSOCK *bs, char *fmt, ...);
+int       bnet_set_buffer_size    (BSOCK *bs, uint32_t size, int rw);
+int       bnet_sig                (BSOCK *bs, int sig);
+BSOCK *    bnet_connect           (void *jcr, int retry_interval,
+              int max_retry_time, char *name, char *host, char *service, 
+              int port, int verbose);
+int       bnet_wait_data         (BSOCK *bsock, int sec);
+void      bnet_close            (BSOCK *bsock);
+BSOCK *    init_bsock           (int sockfd, char *who, char *ip, int port);
+BSOCK *    dup_bsock            (BSOCK *bsock);
+void      term_bsock            (BSOCK *bsock);
+char *    bnet_strerror         (BSOCK *bsock);
+char *    bnet_sig_to_ascii     (BSOCK *bsock);
+int       bnet_wait_data        (BSOCK *bsock, int sec);
 
 
 /* cram-md5.c */
 int cram_md5_get_auth(BSOCK *bs, char *password);
 int cram_md5_auth(BSOCK *bs, char *password);
 void hmac_md5(uint8_t* text, int text_len, uint8_t*  key,
-              int key_len, uint8_t *hmac);
+             int key_len, uint8_t *hmac);
 
 /* create_file.c */
 int create_file(void *jcr, char *fname, char *ofile, char *lname,
-                       int type, struct stat *statp, int *ofd);
+                      int type, struct stat *statp, int *ofd);
 int set_statp(void *jcr, char *fname, char *ofile, char *lname, int type, 
-                       struct stat *statp);
+                      struct stat *statp);
 
 
 /* crc32.c */
 uint32_t bcrc32(uint8_t *buf, int len);
 
 /* daemon.c */
-void     daemon_start            ();
+void    daemon_start            ();
 
 /* lex.c */
-LEX *     lex_close_file         (LEX *lf);
-LEX *     lex_open_file          (LEX *lf, char *fname, LEX_ERROR_HANDLER *scan_error);
-int       lex_get_char           (LEX *lf);
-void      lex_unget_char         (LEX *lf);
-char *    lex_tok_to_str         (int token);
-int       lex_get_token          (LEX *lf, int expect);
+LEX *    lex_close_file         (LEX *lf);
+LEX *    lex_open_file          (LEX *lf, char *fname, LEX_ERROR_HANDLER *scan_error);
+int      lex_get_char           (LEX *lf);
+void     lex_unget_char         (LEX *lf);
+char *   lex_tok_to_str         (int token);
+int      lex_get_token          (LEX *lf, int expect);
 
 /* makepath.c */
 int make_path(
-           void *jcr,
-           const char *argpath,
-           int mode,
-           int parent_mode,
-           uid_t owner,
-           gid_t group,
-           int preserve_existing,
-           char *verbose_fmt_string);
+          void *jcr,
+          const char *argpath,
+          int mode,
+          int parent_mode,
+          uid_t owner,
+          gid_t group,
+          int preserve_existing,
+          char *verbose_fmt_string);
 
 
 /* message.c */
-void       my_name_is            (int argc, char *argv[], char *name);
-void       init_msg              (void *jcr, MSGS *msg);
-void       term_msg              (void);
-void       close_msg             (void *jcr);
-void       add_msg_dest          (MSGS *msg, int dest, int type, char *where, char *dest_code);
-void       rem_msg_dest          (MSGS *msg, int dest, int type, char *where);
-void       Jmsg                  (void *jcr, int type, int level, char *fmt, ...);
-void       dispatch_message      (void *jcr, int type, int level, char *buf);
-void       init_console_msg      (char *wd);
-void       free_msgs_res         (MSGS *msgs);
+void      my_name_is            (int argc, char *argv[], char *name);
+void      init_msg              (void *jcr, MSGS *msg);
+void      term_msg              (void);
+void      close_msg             (void *jcr);
+void      add_msg_dest          (MSGS *msg, int dest, int type, char *where, char *dest_code);
+void      rem_msg_dest          (MSGS *msg, int dest, int type, char *where);
+void      Jmsg                  (void *jcr, int type, int level, char *fmt, ...);
+void      dispatch_message      (void *jcr, int type, int level, char *buf);
+void      init_console_msg      (char *wd);
+void      free_msgs_res         (MSGS *msgs);
 
 
 /* bnet_server.c */
-void       bnet_thread_server(int port, int max_clients, workq_t *client_wq, 
-                   void handle_client_request(void *bsock));
-void             bnet_server             (int port, void handle_client_request(BSOCK *bsock));
-int              net_connect             (int port);
-BSOCK *          bnet_bind               (int port);
-BSOCK *          bnet_accept             (BSOCK *bsock, char *who);
+void      bnet_thread_server(int port, int max_clients, workq_t *client_wq, 
+                  void handle_client_request(void *bsock));
+void            bnet_server             (int port, void handle_client_request(BSOCK *bsock));
+int             net_connect             (int port);
+BSOCK *         bnet_bind               (int port);
+BSOCK *         bnet_accept             (BSOCK *bsock, char *who);
 
 /* signal.c */
-void             init_signals             (void terminate(int sig));
-void             init_stack_dump          (void);
+void            init_signals             (void terminate(int sig));
+void            init_stack_dump          (void);
 
 /* util.c */
-void             lcase                   (char *str);
-void             bash_spaces             (char *str);
-void             unbash_spaces           (char *str);
-void             strip_trailing_junk     (char *str);
-void             strip_trailing_slashes  (char *dir);
-int              skip_spaces             (char **msg);
-int              skip_nonspaces          (char **msg);
-int              fstrsch                 (char *a, char *b);
-char *           encode_time             (time_t time, char *buf);
-char *           encode_mode             (mode_t mode, char *buf);
-char *           edit_uint64_with_commas   (uint64_t val, char *buf);
-char *           add_commas              (char *val, char *buf);
-char *           edit_uint64             (uint64_t val, char *buf);
-int              do_shell_expansion      (char *name);
-int              is_a_number             (const char *num);
-int              string_to_btime         (char *str, btime_t *value);
-char             *edit_btime             (btime_t val, char *buf);
-void             jobstatus_to_ascii      (int JobStatus, char *msg, int maxlen);
-void             add_str_to_pool_mem     (POOLMEM **base, char **msg, char *str);
-int              run_program             (char *prog, int wait, POOLMEM *results);
+void            lcase                   (char *str);
+void            bash_spaces             (char *str);
+void            unbash_spaces           (char *str);
+void            strip_trailing_junk     (char *str);
+void            strip_trailing_slashes  (char *dir);
+int             skip_spaces             (char **msg);
+int             skip_nonspaces          (char **msg);
+int             fstrsch                 (char *a, char *b);
+char *          encode_time             (time_t time, char *buf);
+char *          encode_mode             (mode_t mode, char *buf);
+char *          edit_uint64_with_commas   (uint64_t val, char *buf);
+char *          add_commas              (char *val, char *buf);
+char *          edit_uint64             (uint64_t val, char *buf);
+int             do_shell_expansion      (char *name);
+int             is_a_number             (const char *num);
+int             string_to_btime         (char *str, btime_t *value);
+char            *edit_btime             (btime_t val, char *buf);
+void            jobstatus_to_ascii      (int JobStatus, char *msg, int maxlen);
+void            add_str_to_pool_mem     (POOLMEM **base, char **msg, char *str);
+int             run_program             (char *prog, int wait, POOLMEM *results);
+char *          job_type_to_str         (int type);
+char *          job_status_to_str       (int stat);
+char *          job_level_to_str        (int level);
 
 
 /*
- *void           print_ls_output         (char *fname, char *lname, int type, struct stat *statp);
+ *void          print_ls_output         (char *fname, char *lname, int type, struct stat *statp);
  */
 
 /* watchdog.c */
index 290563355e17c6b8c651f281f331bc2478cebf26..5bf396db94f877c9fa247ef297353268cf1178d7 100644 (file)
@@ -376,6 +376,105 @@ void jobstatus_to_ascii(int JobStatus, char *msg, int maxlen)
    msg[maxlen-1] = 0;
 }
 
+/*
+ * Convert Job Termination Status into a string
+ */
+char *job_status_to_str(int stat) 
+{
+   char *str;
+
+   switch (stat) {
+   case JS_Terminated:
+      str = "OK";
+      break;
+   case JS_ErrorTerminated:
+   case JS_Error:
+      str = "Error";
+      break;
+   case JS_FatalError:
+      str = "Fatal Error";
+      break;
+   case JS_Cancelled:
+      str = "Cancelled";
+      break;
+   case JS_Differences:
+      str = "Differences";
+      break;
+   default:
+      str = "Unknown term code";
+      break;
+   }
+   return str;
+}
+
+
+/*
+ * Convert Job Type into a string
+ */
+char *job_type_to_str(int type) 
+{
+   char *str;
+
+   switch (type) {
+   case JT_BACKUP:
+      str = "Backup";
+      break;
+   case JT_VERIFY:
+      str = "Verify";
+      break;
+   case JT_RESTORE:
+      str = "Restore";
+      break;
+   default:
+      str = "Unknown Job Type";
+      break;
+   }
+   return str;
+}
+
+/*
+ * Convert Job Level into a string
+ */
+char *job_level_to_str(int level) 
+{
+   char *str;
+
+   switch (level) {
+   case L_FULL:
+      str = "full";
+      break;
+   case L_INCREMENTAL:
+      str = "incremental";
+      break;
+   case L_DIFFERENTIAL:
+      str = "differential";
+      break;
+   case L_LEVEL:
+      str = "level";
+      break;
+   case L_SINCE:
+      str = "since";
+      break;
+   case L_VERIFY_CATALOG:
+      str = "verify catalog";
+      break;
+   case L_VERIFY_INIT:
+      str = "verify init";
+      break;
+   case L_VERIFY_VOLUME_TO_CATALOG:
+      str = "verify volume to catalog";
+      break;
+   case L_VERIFY_DATA:
+      str = "verify data";
+      break;
+   default:
+      str = "Unknown Job level";
+      break;
+   }
+   return str;
+}
+
+
 /***********************************************************************
  * Encode the mode bits into a 10 character string like LS does
  ***********************************************************************/
@@ -549,20 +648,25 @@ int do_shell_expansion(char *name)
 }
 
 #define MAX_ARGV 100
-static char *bargv[MAX_ARGV];
-static int bargc;
-static void build_argc_argv(char *cmd);
+static void build_argc_argv(char *cmd, int *bargc, char *bargv[], int max_arg);
 
+/*
+ * Run an external program. Optionally wait a specified number
+ *   of seconds. Program killed if wait exceeded. Optionally
+ *   return the output from the program (normally a single line).
+ */
 int run_program(char *prog, int wait, POOLMEM *results)
 {
    int stat = ETIME;
    int chldstatus = 0;
    pid_t pid1, pid2;
    int pfd[2];
+   char *bargv[MAX_ARGV];
+   int bargc;
 
    
-   build_argc_argv(prog);
-#ifdef xxxxxxxxxxx
+   build_argc_argv(prog, &bargc, bargv, MAX_ARGV);
+#ifdef xxxxxxxxxx
    printf("argc=%d\n", bargc);
    int i;
    for (i=0; i<bargc; i++) {
@@ -589,45 +693,51 @@ int run_program(char *prog, int wait, POOLMEM *results)
 
    default:                          /* parent */
       /* start timer process */
-      switch (pid2=fork()) {
-      case -1:
-        break;
-      case 0:                        /* child 2 */
-        /* Time the worker process */  
-        sleep(wait);
-        if (kill(pid1, SIGTERM) == 0) { /* time expired kill it */
+      if (wait > 0) {
+        switch (pid2=fork()) {
+        case -1:
+           break;
+        case 0:                         /* child 2 */
+           /* Time the worker process */  
+           sleep(wait);
+           if (kill(pid1, SIGTERM) == 0) { /* time expired kill it */
+              exit(0);
+           }
+           sleep(3);
+           kill(pid1, SIGKILL);
            exit(0);
+        default:                        /* parent */
+           break;
         }
-        sleep(3);
-        kill(pid1, SIGKILL);
-        exit(0);
-      default:                       /* parent */
-        int i;
-        if (results) {
-           i = read(pfd[0], results, sizeof_pool_memory(results) - 1);
-           if (--i < 0) {
-              i = 0;
-           }
-           results[i] = 0;                /* set end of string */
+      }
+
+      /* Parent continues here */
+      int i;
+      if (results) {
+        i = read(pfd[0], results, sizeof_pool_memory(results) - 1);
+        if (--i < 0) {
+           i = 0;
         }
-        /* wait for worker child to exit */
-        for ( ;; ) {
-           pid_t wpid;
-           wpid = waitpid(pid1, &chldstatus, 0);         
-           if (wpid == pid1 || (errno != EINTR)) {
-              break;
-           }
+        results[i] = 0;                /* set end of string */
+      }
+      /* wait for worker child to exit */
+      for ( ;; ) {
+        pid_t wpid;
+        wpid = waitpid(pid1, &chldstatus, 0);         
+        if (wpid == pid1 || (errno != EINTR)) {
+           break;
         }
-        if (WIFEXITED(chldstatus))
-           stat = WEXITSTATUS(chldstatus);
+      }
+      if (WIFEXITED(chldstatus))
+        stat = WEXITSTATUS(chldstatus);
 
+      if (wait > 0) {
         kill(pid2, SIGKILL);           /* kill off timer process */
         waitpid(pid2, &chldstatus, 0); /* reap timer process */
-        if (results) { 
-           close(pfd[0]);              /* close pipe */
-           close(pfd[1]);
-        }
-        break;
+      }
+      if (results) { 
+        close(pfd[0]);              /* close pipe */
+        close(pfd[1]);
       }
       break;
    }
@@ -637,13 +747,14 @@ int run_program(char *prog, int wait, POOLMEM *results)
 /*
  * Build argc and argv from a string
  */
-static void build_argc_argv(char *cmd)
+static void build_argc_argv(char *cmd, int *bargc, char *bargv[], int max_argv)
 {
    int i, quote;
    char *p, *q;
+   int argc = 0;
 
-   bargc = 0;
-   for (i=0; i<MAX_ARGV; i++)
+   argc = 0;
+   for (i=0; i<max_argv; i++)
       bargv[i] = NULL;
 
    p = cmd;
@@ -655,7 +766,7 @@ static void build_argc_argv(char *cmd)
       p++;
    }
    if (*p) {
-      while (*p && bargc < MAX_ARGV) {
+      while (*p && argc < MAX_ARGV) {
         q = p;
         if (quote) {
             while (*q && *q != '\"')
@@ -667,7 +778,7 @@ static void build_argc_argv(char *cmd)
         }
         if (*q)
             *(q++) = '\0';
-        bargv[bargc++] = p;
+        bargv[argc++] = p;
         p = q;
          while (*p && (*p == ' ' || *p == '\t'))
            p++;
@@ -677,4 +788,5 @@ static void build_argc_argv(char *cmd)
         }
       }
    }
+   *bargc = argc;
 }
index 50d460bdad9b0079e0b5f145ce9b1357b37af7ef..f28d5a6bed3a54f59c9fd1733607213484eb1446 100644 (file)
@@ -210,8 +210,10 @@ open_dev(DEVICE *dev, char *VolName, int mode)
         dev->mode = O_RDONLY | O_BINARY;
       }
       timeout = dev->max_open_wait;
+      errno = 0;
       while ((dev->fd = open(dev->dev_name, dev->mode, MODE_RW)) < 0) {
         if (errno == EBUSY && timeout-- > 0) {
+            Dmsg2(100, "Device %s busy. ERR=%s\n", dev->dev_name, strerror(errno));
            sleep(1);
            continue;
         }
@@ -219,8 +221,9 @@ open_dev(DEVICE *dev, char *VolName, int mode)
          Mmsg2(&dev->errmsg, _("stored: unable to open device %s: ERR=%s\n"), 
               dev->dev_name, strerror(dev->dev_errno));
         Emsg0(M_FATAL, 0, dev->errmsg);
+        break;
       }
-      if (dev->fd < 0) {
+      if (dev->fd >= 0) {
         dev->dev_errno = 0;
         dev->state |= ST_OPENED;
         dev->use_count++;
index ef9163425c23300eeac17733ebe88cdf00ff67cf..9ff3b759f44187cec20dd1db4c969877ef67f000 100644 (file)
@@ -833,7 +833,7 @@ static char *edit_device_codes(JCR *jcr, char *omsg, char *imsg, char *cmd)
    const char *str;
    char add[20];
 
-   Dmsg1(200, "edit_job_codes: %s\n", imsg);
+   Dmsg1(200, "edit_device_codes: %s\n", imsg);
    add[2] = 0;
    o = omsg;
    for (p=imsg; *p; p++) {