2003-12-xxx Version 1.33  xxNov03
+28Dec03
+- Find commonset of c_iflags that work with FreeBSD tcsetattr on terminals.
+- Remove comments from string concatenation -- doesn't work on FreeBSD
+  compiler.
+- Moderately improve bpipe_close() errors. Must rethink status return.
+- Eliminate some Emsgs in favor of Jmsgs.
+27Dec03
+- Add optional Pool keyword on restore command line. If specified, the pool
+  used will be restricted to the specified pool.
+- "Finish" implementation of JobDefs.
+- Fix directory for chmod of cats scripts.
+26Dec03
+- Implement foreach_res() #define and start replacing old code.
+- Work some more on jobdefs -- more to be done.
+- Implement bstrftime_nc() bstrftime with no century.
+- Fix static console problem in gnome2 and gnome directories reported by Alan 
+  Brown.
+- Add code to test for valid Resource Names. Permitted characters are now
+  alpha, numeric, colon, period, minus, underscore, space.
+- Turnoff some unused code in timers.c
+- Start adding code to dev.c to prevent infinite loops if fast forward space
+  file (MTFSF) is configured on but not properly supported by OS.
 24Nov03
 - Sort FileSet selection list by CreateTime.
 - Add "lsmark", and "estimate" to tree routines.
 
 
           Release Notes for Bacula 1.33
 
-  Bacula code: Total files = 281 Total lines = 83,612 (*.h *.c *.in)
+  Bacula code: Total files = 281 Total lines = 83,815 (*.h *.c *.in)
 
 Most Significant Changes since 1.32d
 - Implement "update slots scan" that reads the volume label(s).
   tape block, so the tape is not recognized.
 
 Other Changes since 1.32d
+- Implement conio.c to use in console program -- mini-readline.
 - Enhance "fill" command of btape -- simpler output. Use -v to
   cause last block to be dumped after write and after re-read.
 - Added an autochanger test to the btape "test" command. It is 
 
 #else
 #include <stdio.h>
 #include <unistd.h>
+#include <stdlib.h>
 #include <signal.h>
 #include <string.h>
 #include <ctype.h> 
       return;
    }
    if (tcgetattr(0, &old_term_params) != 0) {
-      printf(_("conio: Cannot tcgetattr()\n"));
+      printf("conio: Cannot tcgetattr()\n");
       exit(1);
    }
    old_term_params_set = true;
    t.c_cc[VTIME] = 0;
    t.c_iflag &= ~(BRKINT | IGNPAR | PARMRK | INPCK | 
                  ISTRIP | ICRNL | IXON | IXOFF | INLCR | IGNCR);     
-   t.c_iflag |= IGNBRK | ISIG;
-// t.c_oflag &= ~(OPOST);    /* no output processing */       
+   t.c_iflag |= IGNBRK;
    t.c_oflag |= ONLCR;
    t.c_lflag &= ~(ECHO | ECHOE | ECHOK | ECHONL | ICANON |
                  NOFLSH | TOSTOP);
       printf("Cannot tcsetattr()\n");
    }
 
-// signal(SIGQUIT, SIG_IGN);
-// signal(SIGHUP, SIG_IGN);
+   signal(SIGQUIT, SIG_IGN);
+   signal(SIGHUP, SIG_IGN);
 // signal(SIGSTOP, SIG_IGN);
    signal(SIGINT, sigintcatcher);
-// signal(SIGWINCH, SIG_IGN);  
-// signal(SIGQUIT, SIG_IGN);
-// signal(SIGCHLD, SIG_IGN);
+   signal(SIGWINCH, SIG_IGN);  
+   signal(SIGQUIT, SIG_IGN);
+   signal(SIGCHLD, SIG_IGN);
 // signal(SIGTSTP, SIG_IGN);
 
    if (!termtype) {
 static int
 /*FCN*/t_gnc()
 {
-    int ch;
-
-    while ((ch=t_getch()) == 0) ;     /* get next input character */
-    return(ch);
+    return t_getch();
 }
 
 
 {
    t_send(t_dl);
 }
-
 
    "AND JobMedia.MediaId=Media.MediaId "
    "AND Job.FileSetId=FileSet.FileSetId "
    "AND FileSet.FileSet='%s' "
-   "%s"                               /* dynamically added PoolId selection */
+   "%s"
    "ORDER BY Job.JobTDate DESC LIMIT 1";
 
 char *uar_full = 
    "AND JobMedia.MediaId=Media.MediaId "
    "AND Job.Level IN ('I', 'D') AND JobStatus='T' "
    "AND Job.FileSetId=FileSet.FileSetId "
-   "%s"                               /* dynamically added PoolId selection */
+   "%s"
    "AND FileSet.FileSet='%s' ";
 
 char *uar_list_temp = 
 
    } else {
       P(ip_mutex);
       if ((hp = gethostbyname(host)) == NULL) {
-         Jmsg2(jcr, M_ERROR, 0, "gethostbyname() for %s failed: ERR=%s\n", 
+         Jmsg2(jcr, M_ERROR, 0, "gethostbyname() for host \"%s\" failed: ERR=%s\n", 
               host, gethost_strerror());
         V(ip_mutex);
         return NULL;
 
    return stat;
 }
 
-/* Close both pipes and free resources */
+/* 
+ * Close both pipes and free resources  
+ *
+ *  Returns: 0 on success
+ *          errno on failure
+ */
 int close_bpipe(BPIPE *bpipe) 
 {
    int chldstatus = 0;
         bmicrosleep(1, 0);            /* wait one second */
         remaining_wait--;
       } else {
-        stat = 1;                    /* set error status */
-        errno = ETIME;               /* set timed out */
+        stat = ETIME;                /* set error status */
         wpid = -1;
          break;                       /* don't wait any longer */
       }
    if (wpid > 0) {
       if (WIFEXITED(chldstatus)) {          /* process exit()ed */
         stat = WEXITSTATUS(chldstatus);
-          Dmsg1(200, "status =%d\n", stat);
+        if (stat != 0) {
+           stat = ECHILD;
+        }
+         Dmsg1(200, "status =%d\n", stat);
       } else if (WIFSIGNALED(chldstatus)) {  /* process died */
-        stat = 1;
+        stat = ECHILD;
          Dmsg0(200, "Signaled\n");
       }
-      if (stat != 0) {
-        errno = ECHILD;              /* set child errno */
-      }
    }  
    if (bpipe->timer_id) {
       stop_child_timer(bpipe->timer_id);
  * Contrary to my normal calling conventions, this program 
  *
  *  Returns: 0 on success
- *          non-zero on error
+ *          non-zero on error == errno
  */
 int run_program(char *prog, int wait, POOLMEM *results)
 {
    mode = (char *)(results != NULL ? "r" : "");
    bpipe = open_bpipe(prog, wait, mode);
    if (!bpipe) {
-      return 0;
+      return ENOENT;
    }
    if (results) {
       mp_chr(results)[0] = 0;
 
            stat = close_bpipe(bpipe);
            if (stat != 0 && msgs != daemon_msgs) {
                Dmsg1(150, "Calling emsg. CMD=%s\n", cmd);
-               Jmsg2(jcr, M_ERROR, 0, _("Mail program terminated in error. stat=%d\n"
-                                        "CMD=%s\n"), stat, cmd);
+               Jmsg3(jcr, M_ERROR, 0, _("Mail program terminated in error. stat=%d\n"
+                                        "CMD=%s\n"
+                                        "ERR=%s\n"), stat, cmd, strerror(stat));
            }
            free_memory(line);
 rem_temp_file:
                   /* Messages to the operator go one at a time */
                   stat = close_bpipe(bpipe);
                   if (stat != 0) {
-                      Emsg1(M_ERROR, 0, _("Operator mail program terminated in error.\nCMD=%s\n"),
-                        mcmd);
+                      Jmsg2(jcr, M_ERROR, 0, _("Operator mail program terminated in error.\n"
+                            "CMD=%s\n"
+                            "ERR=%s\n"), mcmd, strerror(stat));
                   }
                }
                free_pool_memory(mcmd);
                    d->fd = fopen(mp_chr(name), "w+");
                   if (!d->fd) {
                      d->fd = stdout;
-                      Emsg2(M_ERROR, 0, "fopen %s failed: ERR=%s\n", name, strerror(errno));
+                      Jmsg2(jcr, M_ERROR, 0, "fopen %s failed: ERR=%s\n", name, strerror(errno));
                      d->fd = NULL;
                      free_pool_memory(name);
                      break;
                    d->fd = fopen(d->where, "w+");
                   if (!d->fd) {
                      d->fd = stdout;
-                      Emsg2(M_ERROR, 0, "fopen %s failed: ERR=%s\n", d->where, strerror(errno));
+                      Jmsg2(jcr, M_ERROR, 0, "fopen %s failed: ERR=%s\n", d->where, strerror(errno));
                      d->fd = NULL;
                      break;
                   }
                    d->fd = fopen(d->where, "a");
                   if (!d->fd) {
                      d->fd = stdout;
-                      Emsg2(M_ERROR, 0, "fopen %s failed: ERR=%s\n", d->where, strerror(errno));
+                      Jmsg2(jcr, M_ERROR, 0, "fopen %s failed: ERR=%s\n", d->where, strerror(errno));
                      d->fd = NULL;
                      break;
                   }
           bsnprintf(buf, sizeof(buf), "%s/bacula.trace", working_directory);
           trace_fd = fopen(buf, "a+");
          if (!trace_fd) {
-             Emsg2(M_ABORT, 0, _("Cannot open %s: ERR=%s\n"),
+             Emsg2(M_ABORT, 0, _("Cannot open trace file \"%s\": ERR=%s\n"),
                  buf, strerror(errno));
          }
        }
           bsnprintf(buf, sizeof(buf), "%s/bacula.trace", working_directory);
           trace_fd = fopen(buf, "a+");
          if (!trace_fd) {
-             Emsg2(M_ABORT, 0, _("Cannot open %s: ERR=%s\n"),
+             Emsg2(M_ABORT, 0, _("Cannot open trace file \"%s\": ERR=%s\n"),
                  buf, strerror(errno));
          }
        }
 
 #undef  VERSION
 #define VERSION "1.33"
 #define VSTRING "1"
-#define BDATE   "26 Dec 2003"
-#define LSMDATE "26Dec03"
+#define BDATE   "28 Dec 2003"
+#define LSMDATE "28Dec03"
 
 /* Debug flags */
 #undef  DEBUG