]> git.sur5r.net Git - bacula/bacula/commitdiff
bootstrap improvements -- kes19Jun02
authorKern Sibbald <kern@sibbald.com>
Wed, 19 Jun 2002 19:44:57 +0000 (19:44 +0000)
committerKern Sibbald <kern@sibbald.com>
Wed, 19 Jun 2002 19:44:57 +0000 (19:44 +0000)
git-svn-id: https://bacula.svn.sourceforge.net/svnroot/bacula/trunk@45 91ce42f0-d328-0410-95d8-f526ca767f89

16 files changed:
bacula/src/baconfig.h
bacula/src/dird/authenticate.c
bacula/src/filed/authenticate.c
bacula/src/jcr.h
bacula/src/lib/lex.c
bacula/src/lib/lex.h
bacula/src/lib/parse_conf.c
bacula/src/lib/watchdog.c
bacula/src/stored/Makefile.in
bacula/src/stored/authenticate.c
bacula/src/stored/bsr.h
bacula/src/stored/match_bsr.c
bacula/src/stored/parse_bsr.c
bacula/src/stored/read.c
bacula/src/stored/stored.h
bacula/src/version.h

index 5472c7f651b5705956be9a66cf671efc96f73a9f..b36517f2c3dbb7fc10d32c318d788b7800b81953 100644 (file)
@@ -182,7 +182,11 @@ extern void _v(char *file, int line, pthread_mutex_t *m);
 #define Dmsg6(lvl, msg, a1, a2, a3, a4, a5, a6) d_msg(__FILE__, __LINE__, lvl, msg, a1, a2, a3, a4, a5, a6)
 #define Dmsg7(lvl, msg, a1, a2, a3, a4, a5, a6, a7) d_msg(__FILE__, __LINE__, lvl, msg, a1, a2, a3, a4, a5, a6, a7)
 #define Dmsg8(lvl, msg, a1, a2, a3, a4, a5, a6, a7, a8) d_msg(__FILE__, __LINE__, lvl, msg, a1, a2, a3, a4, a5, a6, a7, a8)
+#define Dmsg9(lvl,msg,a1,a2,a3,a4,a5,a6,a7,a8,a9) d_msg(__FILE__,__LINE__,lvl,msg,a1,a2,a3,a4,a5,a6,a7,a8,a9)
+#define Dmsg10(lvl,msg,a1,a2,a3,a4,a5,a6,a7,a8,a9,a10) d_msg(__FILE__,__LINE__,lvl,msg,a1,a2,a3,a4,a5,a6,a7,a8,a9,a10)
 #define Dmsg11(lvl,msg,a1,a2,a3,a4,a5,a6,a7,a8,a9,a10,a11) d_msg(__FILE__,__LINE__,lvl,msg,a1,a2,a3,a4,a5,a6,a7,a8,a9,a10,a11)
+#define Dmsg12(lvl,msg,a1,a2,a3,a4,a5,a6,a7,a8,a9,a10,a11,a12) d_msg(__FILE__,__LINE__,lvl,msg,a1,a2,a3,a4,a5,a6,a7,a8,a9,a10,a11,a12)
+#define Dmsg13(lvl,msg,a1,a2,a3,a4,a5,a6,a7,a8,a9,a10,a11,a12,a13) d_msg(__FILE__,__LINE__,lvl,msg,a1,a2,a3,a4,a5,a6,a7,a8,a9,a10,a11,a12,a13)
 #else
 #define Dmsg0(lvl, msg)
 #define Dmsg1(lvl, msg, a1)
@@ -194,6 +198,8 @@ extern void _v(char *file, int line, pthread_mutex_t *m);
 #define Dmsg7(lvl, msg, a1, a2, a3, a4, a5, a6, a7)
 #define Dmsg8(lvl, msg, a1, a2, a3, a4, a5, a6, a7, a8)
 #define Dmsg11(lvl,msg,a1,a2,a3,a4,a5,a6,a7,a8,a9,a10,a11)
+#define Dmsg12(lvl,msg,a1,a2,a3,a4,a5,a6,a7,a8,a9,a10,a11,a12)
+#define Dmsg13(lvl,msg,a1,a2,a3,a4,a5,a6,a7,a8,a9,a10,a11,a12,a13)
 #endif /* DEBUG */
        
 /* Daemon Error Messages that are delivered according to the message resource */
index 16c3da759ad23577b3dad1e4dd8df34b670ade54..7f7fd6b7ee8093827eef8d02e235a037b06c1e1a 100644 (file)
@@ -60,11 +60,12 @@ int authenticate_storage_daemon(JCR *jcr)
     * Send my name to the Storage daemon then do authentication
     */
    if (!bnet_fsend(sd, hello, director->hdr.name)) {
-      Emsg1(M_FATAL, 0, _("Auth send error. ERR=%s\n"), bnet_strerror(sd));
+      Jmsg(jcr, M_FATAL, 0, _("Error sending Hello to Storage daemon. ERR=%s\n"), bnet_strerror(sd));
+      return 0;
    }
    if (!cram_md5_get_auth(sd, jcr->store->password) || 
        !cram_md5_auth(sd, jcr->store->password)) {
-      Emsg0(M_FATAL, 0, _("Storage daemon authorization failed.\n"));
+      Jmsg0(jcr, M_FATAL, 0, _("Director and Storage daemon passwords not the same.\n"));
       return 0;
    }
    Dmsg1(6, ">stored: %s", sd->msg);
@@ -91,21 +92,24 @@ int authenticate_file_daemon(JCR *jcr)
    /* 
     * Send my name to the File daemon then do authentication
     */
-   bnet_fsend(fd, hello, director->hdr.name);
+   if (!bnet_fsend(fd, hello, director->hdr.name)) {
+      Jmsg(jcr, M_FATAL, 0, _("Error sending Hello to File daemon. ERR=%s\n"), bnet_strerror(fd));
+      return 0;
+   }
    if (!cram_md5_get_auth(fd, jcr->client->password) || 
        !cram_md5_auth(fd, jcr->client->password)) {
-      Emsg0(M_FATAL, 0, _("File daemon authentication failed.\n"));
+      Jmsg(jcr, M_FATAL, 0, _("Director and File daemon passwords not the same.\n"));
       return 0;
    }
    Dmsg1(6, ">filed: %s", fd->msg);
    if (bnet_recv(fd) <= 0) {
-      Emsg1(M_FATAL, 0, _("bdird<filed: bad response to Hello command: ERR=%s\n"),
+      Jmsg(jcr, M_FATAL, 0, _("bdird<filed: bad response to Hello command: ERR=%s\n"),
         bnet_strerror(fd));
       return 0;
    }
    Dmsg1(10, "<stored: %s", fd->msg);
    if (strncmp(fd->msg, FDOKhello, sizeof(FDOKhello)) != 0) {
-      Emsg0(M_FATAL, 0, _("File daemon rejected Hello command\n"));
+      Jmsg(jcr, M_FATAL, 0, _("File daemon rejected Hello command\n"));
       return 0;
    }
    return 1;
@@ -131,6 +135,7 @@ int authenticate_user_agent(BSOCK *ua)
    if (!ok) {
       bnet_fsend(ua, "%s", _(Dir_sorry));
       Emsg0(M_WARNING, 0, _("Unable to authenticate User Agent\n"));
+      sleep(5);
       return 0;
    }
    bnet_fsend(ua, "1000 OK: %s Version: " VERSION " (" DATE ")\n", my_name);
index 1a2b6b4d7242ffb85ac8a722bc3afdb89d2aa6ef..8c99fdeb4278901c093bc8ad52771c03a8fce17d 100644 (file)
@@ -50,7 +50,7 @@ static int authenticate(int rcode, BSOCK *bs)
 
    if (sscanf(bs->msg, "Hello Director %s calling\n", name) != 1) {
       free_pool_memory(name);
-      Emsg1(M_FATAL, 0, _("Authentication failure: %s"), bs->msg);
+      Emsg1(M_FATAL, 0, _("Bad Hello command from Director: %s"), bs->msg);
       return 0;
    }
    director = NULL;
@@ -60,8 +60,14 @@ static int authenticate(int rcode, BSOCK *bs)
         break;
    }
    UnlockRes();
-   if (director && (!cram_md5_auth(bs, director->password) ||
-       !cram_md5_get_auth(bs, director->password))) {
+   if (!director) {
+      Emsg1(M_FATAL, 0, _("Connection from unknown Director %s rejected.\n"), name);
+      free_pool_memory(name);
+      return 0;
+   }
+   if (!cram_md5_auth(bs, director->password) ||
+       !cram_md5_get_auth(bs, director->password)) {
+      Emsg0(M_FATAL, 0, _("Incorrect password given by Director.\n"));
       director = NULL;
    }
    free_pool_memory(name);
@@ -82,7 +88,8 @@ int authenticate_director(JCR *jcr)
 
    if (!authenticate(R_DIRECTOR, dir)) {
       bnet_fsend(dir, "%s", Dir_sorry);
-      Emsg0(M_ERROR, 0, _("Unable to authenticate Director\n"));
+      Emsg0(M_FATAL, 0, _("Unable to authenticate Director\n"));
+      sleep(5);
       return 0;
    }
    return bnet_fsend(dir, "%s", OK_hello);
@@ -95,7 +102,12 @@ int authenticate_director(JCR *jcr)
 int authenticate_storagedaemon(JCR *jcr)
 {
    BSOCK *sd = jcr->store_bsock;
+   int stat;
 
-   return cram_md5_get_auth(sd, jcr->sd_auth_key) &&
+   stat = cram_md5_get_auth(sd, jcr->sd_auth_key) &&
          cram_md5_auth(sd, jcr->sd_auth_key);
+   if (!stat) {
+      Jmsg(jcr, M_FATAL, 0, _("Authorization key rejected by Storage daemon.\n"));
+   }
+   return stat;
 }
index 31a3536069d03e478ae7cd038ab3ac9a71279b59..3b7139621dc70aa5000f9742ce542e364a4f17cb 100644 (file)
@@ -188,6 +188,7 @@ struct s_jcr {
    uint32_t end_file;                 /* End file written */
 
    /* Parmaters for Open Read Session */
+   BSR *bsr;                          /* Bootstrap record -- has everything */
    uint32_t read_VolSessionId;
    uint32_t read_VolSessionTime;
    uint32_t read_StartFile;
index c25697fc3086caaf913314b5c099bcb6edd6aaf4..51a6784842f636e429691aa0f2d935c9b1bd6779 100644 (file)
@@ -38,7 +38,10 @@ void scan_to_eol(LEX *lc)
 {
    int token;
    Dmsg0(150, "start scan to eof\n");
-   while ((token = lex_get_token(lc)) != T_EOL) {
+   lc->expect = 0;                   /* clear expectations */
+   if (token != T_EOL) {
+      while ((token = lex_get_token(lc)) != T_EOL) {
+      }
    }
    Dmsg0(150, "done scan to eof\n");
 }
@@ -56,7 +59,7 @@ void s_err(char *file, int line, LEX *lc, char *msg, ...)
    bvsnprintf(buf, sizeof(buf), msg, arg_ptr);
    va_end(arg_ptr);
      
-   e_msg(file, line, M_ERROR_TERM, 0, "Config error: %s,\n\
+   e_msg(file, line, M_ERROR_TERM, 0, "Config error: %s\n\
             : Line %d, col %d of file %s\n%s\n",
       buf, lc->line_no, lc->col_no, lc->fname, lc->line);
 }
@@ -240,6 +243,21 @@ lex_tok_to_str(int token)
    }
 }
 
+static uint32_t scan_pint(LEX *lf, char *str)
+{
+   double dval;
+   if (!is_a_number(str)) {
+      scan_err1(lf, "expected a positive integer number, got: %s", str);
+   } else {
+      errno = 0;
+      dval = strtod(str, NULL);
+      if (errno != 0 || dval < 0) {
+         scan_err1(lf, "expected a postive integer number, got: %s", str);
+      }
+   }
+   return (uint32_t)dval;
+}
+
 /*       
  * 
  * Get the next token from the input
@@ -417,5 +435,76 @@ lex_get_token(LEX *lf)
    }
    Dmsg2(290, "lex returning: line %d token: %s\n", lf->line_no, lex_tok_to_str(token));
    lf->token = token;
+
+   /* 
+    * Here is where we check to see if the user has set certain 
+    *  expectations (e.g. 32 bit integer). If so, we do type checking
+    *  and possible additional scanning (e.g. for range).
+    */
+   switch (lf->expect) {
+   case T_PINT32:
+      lf->pint32_val = scan_pint(lf, lf->str);
+      lf->pint32_val2 = lf->pint32_val;
+      token = T_PINT32;
+      break;
+
+   case T_PINT32_RANGE:
+      if (token == T_NUMBER) {
+        lf->pint32_val = scan_pint(lf, lf->str);
+        lf->pint32_val2 = lf->pint32_val;
+        token = T_PINT32;
+      } else {
+         char *p = strchr(lf->str, '-');
+        if (!p) {
+            scan_err1(lf, "expected an integer or a range, got: %s", lf->str);
+        }
+        *p++ = 0;                       /* terminate first half of range */
+        lf->pint32_val  = scan_pint(lf, lf->str);
+        lf->pint32_val2 = scan_pint(lf, p);
+        token = T_PINT32_RANGE;
+      }
+      break;
+
+   case T_INT32:
+      if (token != T_NUMBER || !is_a_number(lf->str)) {
+         scan_err1(lf, "expected an integer number, got: %s", lf->str);
+      } else {
+        errno = 0;
+        lf->int32_val = (int32_t)strtod(lf->str, NULL);
+        if (errno != 0) {
+            scan_err1(lf, "expected an integer number, got: %s", lf->str);
+        }
+      }
+      token = T_INT32;
+      break;
+
+   case T_INT64:
+      Dmsg2(400, "int64=:%s: %f\n", lf->str, strtod(lf->str, NULL)); 
+      if (token != T_NUMBER || !is_a_number(lf->str)) {
+         scan_err1(lf, "expected an integer number, got: %s", lf->str);
+      } else {
+        errno = 0;
+        lf->int64_val = (int64_t)strtod(lf->str, NULL);
+        if (errno != 0) {
+            scan_err1(lf, "expected an integer number, got: %s", lf->str);
+        }
+      }
+      token = T_INT64;
+      break;
+
+   case T_NAME:
+      if (token != T_IDENTIFIER && token != T_STRING && token != T_QUOTED_STRING) {
+         scan_err1(lf, "expected a name: %s", lf->str);
+      } else if (lf->str_len > MAX_RES_NAME_LENGTH) {
+         scan_err3(lf, "name %s length %d too long, max is %d\n", lf->str, 
+           lf->str_len, MAX_RES_NAME_LENGTH);
+      }
+      token = T_NAME;
+      break;
+
+   default:
+      break;                         /* no expectation given */
+   }
+   lf->token = token;                /* set possible new token */
    return token;
 }
index 4b52291818c1d86488e25e43cc5aa80cce3ae365..ec642a95be9e4ad79bbdbe6c7ab29c4ec1d57909 100644 (file)
 #define _LEX_H
 
 /* Lex get_char() return values */
-#define L_EOF                        (-1)
-#define L_EOL                        (-2)
+#define L_EOF                         (-1)
+#define L_EOL                         (-2)
 
 /* Internal tokens */
-#define T_NONE                       100                              
+#define T_NONE                        100                              
 
 /* Tokens returned by get_token() */
-#define T_EOF                        101
-#define T_NUMBER                     102
-#define T_IPADDR                     103
-#define T_IDENTIFIER                 104
-#define T_STRING                     105
-#define T_QUOTED_STRING              106
-#define T_BOB                        108  /* begin block */
-#define T_EOB                        109  /* end of block */
-#define T_EQUALS                     110
-#define T_COMMA                      111
-#define T_EOL                        112
-#define T_SEMI                       113
-#define T_ERROR                      200
+#define T_EOF                         101
+#define T_NUMBER                      102
+#define T_IPADDR                      103
+#define T_IDENTIFIER                  104
+#define T_STRING                      105
+#define T_QUOTED_STRING               106
+#define T_BOB                         108  /* begin block */
+#define T_EOB                         109  /* end of block */
+#define T_EQUALS                      110
+#define T_COMMA                       111
+#define T_EOL                         112
+#define T_SEMI                        113
+#define T_ERROR                       200
+/*
+ * The following will be returned only if
+ * the appropriate expect flag has been set   
+ */
+#define T_PINT32                      114  /* positive integer */
+#define T_PINT32_RANGE                115  /* positive integer range */
+#define T_INT32                       116  /* integer */
+#define T_INT64                       117  /* 64 bit integer */
+#define T_NAME                        118  /* resource name */
 
 /* Lexical state */
 enum lex_state {
@@ -66,22 +75,27 @@ enum lex_state {
 };
 
 /* Lex scan options */
-#define LOPT_NO_IDENT           0x1  /* No Identifiers -- use string */
+#define LOPT_NO_IDENT            0x1  /* No Identifiers -- use string */
 
 /* Lexical context */
 typedef struct s_lex_context {
-   int options;                      /* scan options */
-   char *fname;                      /* filename */
-   FILE *fd;                         /* file descriptor */
-   char line[MAXSTRING];             /* input line */
-   char str[MAXSTRING];              /* string being scanned */
-   int str_len;                      /* length of string */
-   int line_no;                      /* file line number */
-   int col_no;                       /* char position on line */
-   enum lex_state state;             /* lex_state variable */
-   int ch;                           /* last char/L_VAL returned by get_char */
+   struct s_lex_context *next;        /* pointer to next lexical context */
+   int options;                       /* scan options */
+   int expect;                        /* types expected */
+   char *fname;                       /* filename */
+   FILE *fd;                          /* file descriptor */
+   char line[MAXSTRING];              /* input line */
+   char str[MAXSTRING];               /* string being scanned */
+   int str_len;                       /* length of string */
+   int line_no;                       /* file line number */
+   int col_no;                        /* char position on line */
+   enum lex_state state;              /* lex_state variable */
+   int ch;                            /* last char/L_VAL returned by get_char */
    int token;
-   struct s_lex_context *next;       /* pointer to next lexical context */
+   uint32_t pint32_val;
+   uint32_t pint32_val2;
+   int32_t int32_val;
+   int64_t int64_val;
 } LEX;
 
 #endif /* _LEX_H */
index 61f7d7eadca27802426ffd1fd52c978d18b7ca83..e063b6f84e905323e54f89ef5ca3eb5a1802ff62 100755 (executable)
@@ -333,16 +333,10 @@ void store_name(LEX *lc, struct res_items *item, int index, int pass)
 {
    int token;
 
+   lc->expect = T_NAME;
    token = lex_get_token(lc);
-   if (token != T_IDENTIFIER && token != T_STRING && token != T_QUOTED_STRING) {
-      scan_err1(lc, "expected an identifier or string, got: %s", lc->str);
-   } else if (lc->str_len > MAX_RES_NAME_LENGTH) {
-      scan_err3(lc, "name %s length %d too long, max is %d\n", lc->str, 
-        lc->str_len, MAX_RES_NAME_LENGTH);
-   } else {
-      /* Store the name both pass 1 and pass 2 */
-      *(item->value) = bstrdup(lc->str);
-   }
+   /* Store the name both pass 1 and pass 2 */
+   *(item->value) = bstrdup(lc->str);
    scan_to_eol(lc);
    set_bit(index, res_all.hdr.item_present);
 }
@@ -356,16 +350,11 @@ void store_strname(LEX *lc, struct res_items *item, int index, int pass)
 {
    int token;
 
+   lc->expect = T_NAME;
    token = lex_get_token(lc);
-   if (token != T_IDENTIFIER && token != T_STRING && token != T_QUOTED_STRING) {
-      scan_err1(lc, "expected an identifier or string, got: %s", lc->str);
-   } else if (lc->str_len > MAX_RES_NAME_LENGTH) {
-      scan_err3(lc, "name %s length %d too long, max is %d\n", lc->str, 
-        lc->str_len, MAX_RES_NAME_LENGTH);
-   } else {
-      /* Store the name */
-      if (pass == 1)
-        *(item->value) = bstrdup(lc->str);
+   /* Store the name */
+   if (pass == 1) {
+      *(item->value) = bstrdup(lc->str);
    }
    scan_to_eol(lc);
    set_bit(index, res_all.hdr.item_present);
@@ -488,17 +477,9 @@ void store_pint(LEX *lc, struct res_items *item, int index, int pass)
 {
    int token;
 
+   lc->expect = T_PINT32;
    token = lex_get_token(lc);
-   if (token != T_NUMBER || !is_a_number(lc->str)) {
-      scan_err1(lc, "expected a positive integer number, got: %s", lc->str);
-   } else {
-      errno = 0;
-      token = (int)strtod(lc->str, NULL);
-      if (errno != 0 || token < 0) {
-         scan_err1(lc, "expected a postive integer number, got: %s", lc->str);
-      }
-      *(int *)(item->value) = token;
-   }
+   *(int *)(item->value) = lc->pint32_val;
    scan_to_eol(lc);
    set_bit(index, res_all.hdr.item_present);
 }
@@ -509,16 +490,9 @@ void store_int64(LEX *lc, struct res_items *item, int index, int pass)
 {
    int token;
 
+   lc->expect = T_INT64;
    token = lex_get_token(lc);
-   Dmsg2(400, "int64=:%s: %f\n", lc->str, strtod(lc->str, NULL)); 
-   if (token != T_NUMBER || !is_a_number(lc->str)) {
-      scan_err1(lc, "expected an integer number, got: %s", lc->str);
-   } else {
-      errno = 0;
-      *(int64_t *)(item->value) = (int64_t)strtod(lc->str, NULL);
-      if (errno != 0)
-         scan_err1(lc, "expected an integer number, got: %s", lc->str);
-   }
+   *(int64_t *)(item->value) = lc->int64_val;
    scan_to_eol(lc);
    set_bit(index, res_all.hdr.item_present);
 }
index 9cda310aa75cfbd11d676c78350b21cd4bef6c3b..7d345d5fe8fd8698d27e2e51a9e1eab0bccce99f 100755 (executable)
@@ -134,6 +134,7 @@ static void *watchdog_thread(void *arg)
    for ( ;!quit; ) {
       struct timeval tv;
       struct timezone tz;
+      time_t timer_start;
 
       Dmsg0(200, "Top of for loop\n");
 
@@ -149,21 +150,30 @@ static void *watchdog_thread(void *arg)
            continue;
         }
         fd = jcr->store_bsock;
-        if (fd && fd->timer_start && (watchdog_time - fd->timer_start) > fd->timeout) {
+        timer_start = fd->timer_start;
+        if (fd && timer_start && (watchdog_time - timer_start) > fd->timeout) {
            fd->timed_out = TRUE;
-            Jmsg(jcr, M_ERROR, 0, "Watchdog sending kill to thread stalled reading Storage daemon.\n");
+           Jmsg(jcr, M_ERROR, 0, _(
+"Watchdog sending kill after %d secs to thread stalled reading Storage daemon.\n"),
+                watchdog_time - timer_start);
            pthread_kill(jcr->my_thread_id, TIMEOUT_SIGNAL);
         }
         fd = jcr->file_bsock;
-        if (fd && fd->timer_start && (watchdog_time - fd->timer_start) > fd->timeout) {
+        timer_start = fd->timer_start;
+        if (fd && timer_start && (watchdog_time - timer_start) > fd->timeout) {
            fd->timed_out = TRUE;
-            Jmsg(jcr, M_ERROR, 0, "Watchdog sending kill to thread stalled reading File daemon.\n");
+           Jmsg(jcr, M_ERROR, 0, _(
+"Watchdog sending kill after %d secs to thread stalled reading File daemon.\n"),
+                watchdog_time - timer_start);
            pthread_kill(jcr->my_thread_id, TIMEOUT_SIGNAL);
         }
         fd = jcr->dir_bsock;
-        if (fd && fd->timer_start && (watchdog_time - fd->timer_start) > fd->timeout) {
+        timer_start = fd->timer_start;
+        if (fd && timer_start && (watchdog_time - timer_start) > fd->timeout) {
            fd->timed_out = TRUE;
-            Jmsg(jcr, M_ERROR, 0, "Watchdog sending kill to thread stalled reading Director.\n");
+           Jmsg(jcr, M_ERROR, 0, _(
+"Watchdog sending kill after %d secs to thread stalled reading Director.\n"),
+                watchdog_time - timer_start);
            pthread_kill(jcr->my_thread_id, TIMEOUT_SIGNAL);
         }
 
index 21dad53ec70bc35b8921c6ed2fe0623eb9357ca7..35ea4a20bf5a63a5f69b964719e266640dec748f 100644 (file)
@@ -80,7 +80,7 @@ btape:        $(TAPEOBJS) ../lib/libbac.a ../cats/libsql.a
 bls:   ../findlib/libfind.a $(BLSOBJS) ../lib/libbac.a
        $(CXX) $(LDFLAGS) -L../lib -L../findlib -o $@ $(BLSOBJS) $(LIBS) $(DLIB) -lbac -lfind -lm
 
-bextract: ../findlib/libfind.a $(BEXTOBJS)
+bextract: ../findlib/libfind.a $(BEXTOBJS) ../lib/libbac.a
        $(CXX) $(LDFLAGS) -L../lib -L../findlib -o $@ $(BEXTOBJS) $(LIBS) $(DLIB) $(FDLIBS) -lbac -lfind -lm
 
 bscan: ../findlib/libfind.a $(SCNOBJS) ../cats/libsql.a
index 77a41a97035752afbb2f860bc1819bd6f77a244f..be18fb9ca0f6020b653c7371f45d218a518e640e 100644 (file)
@@ -40,7 +40,7 @@ static char OK_hello[]  = "3000 OK Hello\n";
 static int authenticate(int rcode, BSOCK *bs)
 {
    char *name;
-   DIRRES *director;
+   DIRRES *director = NULL;
 
    if (rcode != R_DIRECTOR) {
       Emsg1(M_FATAL, 0, _("I only authenticate Directors, not %d\n"), rcode);
@@ -50,8 +50,7 @@ static int authenticate(int rcode, BSOCK *bs)
    name = (char *) check_pool_memory_size(name, bs->msglen);
 
    if (sscanf(bs->msg, "Hello Director %127s calling\n", name) != 1) {
-      free_pool_memory(name);
-      Emsg1(M_FATAL, 0, _("Authentication failure: %s\n"), bs->msg);
+      Emsg1(M_FATAL, 0, _("Bad Hello command from Director: %s\n"), bs->msg);
       return 0;
    }
    director = NULL;
@@ -61,12 +60,21 @@ static int authenticate(int rcode, BSOCK *bs)
         break;
    }
    UnlockRes();
-   if (director && (!cram_md5_auth(bs, director->password) ||
-       !cram_md5_get_auth(bs, director->password))) {
-      director = NULL;
+   if (!director) {
+      Emsg1(M_FATAL, 0, _("Connection from unknown Director %s rejected.\n"), name);
+      goto bail_out;
    }
+   if (!cram_md5_auth(bs, director->password) ||
+       !cram_md5_get_auth(bs, director->password)) {
+      Emsg0(M_FATAL, 0, _("Incorrect password given by Director.\n"));
+      goto bail_out;
+   }
+   free_pool_memory(name);
+   return 1;
+
+bail_out:
    free_pool_memory(name);
-   return (director != NULL);
+   return 0;
 }
 
 /*
@@ -88,6 +96,7 @@ int authenticate_director(JCR *jcr)
    if (!authenticate(R_DIRECTOR, dir)) {
       bnet_fsend(dir, "%s", Dir_sorry);
       Emsg0(M_ERROR, 0, _("Unable to authenticate Director\n"));
+      sleep(5);
       return 0;
    }
    return bnet_fsend(dir, "%s", OK_hello);
@@ -101,5 +110,8 @@ int authenticate_filed(JCR *jcr)
        cram_md5_get_auth(fd, jcr->sd_auth_key)) {
       jcr->authenticated = TRUE;
    }
+   if (!jcr->authenticated) {
+      Jmsg(jcr, M_FATAL, 0, _("Incorrect authorization key from File daemon rejected.\n"));
+   }
    return jcr->authenticated;
 }
index c6728e17fd93d24c7bcf207092cc9a05d00b7368..6e08841214f47a1907ea3c164f2d9b6a7850f5b0 100644 (file)
@@ -48,12 +48,19 @@ typedef struct s_bsr_client {
 
 typedef struct s_bsr_sessid {
    struct s_bsr_sessid *next;
-   int type;
-   uint32_t sessid1;
+   uint32_t sessid;
    uint32_t sessid2;
    int found;
 } BSR_SESSID;
 
+typedef struct s_bsr_volfile {
+   struct s_bsr_volfile *next;
+   uint32_t sfile;                    /* start file */
+   uint32_t efile;                    /* end file */
+   int found;
+} BSR_VOLFILE;
+
+
 typedef struct s_bsr_sesstime {
    struct s_bsr_sesstime *next;
    uint32_t sesstime;
@@ -62,13 +69,15 @@ typedef struct s_bsr_sesstime {
 
 typedef struct s_bsr_findex {
    struct s_bsr_findex *next;
-   int32_t FileIndex;
+   int32_t findex;                    /* start file index */
+   int32_t findex2;                   /* end file index */
    int found;
 } BSR_FINDEX;
 
 typedef struct s_bsr_jobid {
    struct s_bsr_jobid *next;
    uint32_t JobId;
+   uint32_t JobId2;
    int found;
 } BSR_JOBID;
 
@@ -101,6 +110,7 @@ typedef struct s_bsr {
    BSR_JOBID    *JobId;
    BSR_JOBTYPE  *JobType;
    BSR_JOBLEVEL *JobLevel;
+   BSR_VOLFILE  *volfile;
    FF_PKT *ff;                        /* include/exclude */
 } BSR;
 
index 2bdcbcb8ae97f675a1b40799a5dba33b830ee5a4..2038f5ef4564eab578961572b4a7b7f53bb50458 100755 (executable)
@@ -169,7 +169,7 @@ static int match_file_index(BSR_FINDEX *findex, DEV_RECORD *rec)
    if (!findex) {
       return 1;                      /* no specification matches all */
    }
-   if (findex->FileIndex == rec->FileIndex) {
+   if (findex->findex >= rec->FileIndex && findex->findex2 <= rec->FileIndex) {
       findex->found++;
       return 1;
    }
@@ -185,7 +185,7 @@ static int match_sessid(BSR_SESSID *sessid, DEV_RECORD *rec)
    if (!sessid) {
       return 1;                      /* no specification matches all */
    }
-   if (sessid->sessid1 == rec->VolSessionId) {
+   if (sessid->sessid >= rec->VolSessionId && sessid->sessid2 <= rec->VolSessionId) {
       sessid->found++;
       return 1;
    }
index e26ad8af47f1b62ecf0816e0e71a9c268cb7eaba..0a32e9cdc825c5adf9fa01408a06d3c3c59390ab 100755 (executable)
@@ -40,6 +40,7 @@ static BSR *store_jobtype(LEX *lc, BSR *bsr);
 static BSR *store_joblevel(LEX *lc, BSR *bsr);
 static BSR *store_file_index(LEX *lc, BSR *bsr);
 static BSR *store_sessid(LEX *lc, BSR *bsr);
+static BSR *store_volfile(LEX *lc, BSR *bsr);
 static BSR *store_sesstime(LEX *lc, BSR *bsr);
 static BSR *store_include(LEX *lc, BSR *bsr);
 static BSR *store_exclude(LEX *lc, BSR *bsr);
@@ -61,6 +62,7 @@ struct kw_items items[] = {
    {"volsessiontime", store_sesstime},
    {"include", store_include},
    {"exclude", store_exclude},
+   {"volfile", store_volfile},
    {NULL, NULL}
 
 };
@@ -101,7 +103,7 @@ BSR *parse_bsr(char *cf)
            if (token != T_EQUALS) {
                scan_err1(lc, "expected an equals, got: %s", lc->str);
            }
-            Dmsg1(150, "calling handler for %s\n", items[i].name);
+            Dmsg1(100, "calling handler for %s\n", items[i].name);
            /* Call item handler */
            bsr = items[i].handler(lc, bsr);
            i = -1;
@@ -145,13 +147,9 @@ static BSR *store_client(LEX *lc, BSR *bsr)
    int token;
    BSR_CLIENT *client;
     
-   token = lex_get_token(lc);
-   if (token != T_IDENTIFIER && token != T_STRING && token != T_QUOTED_STRING) {
-      scan_err1(lc, "expected an identifier or string, got: %s", lc->str);
-   } else if (lc->str_len > MAX_RES_NAME_LENGTH) {
-      scan_err3(lc, "name %s length %d too long, max is %d\n", lc->str, 
-        lc->str_len, MAX_RES_NAME_LENGTH);
-   } else {
+   for (;;) {
+      lc->expect = T_NAME;
+      token = lex_get_token(lc);
       client = (BSR_CLIENT *)malloc(sizeof(BSR_CLIENT));
       memset(client, 0, sizeof(BSR_CLIENT));
       client->ClientName = bstrdup(lc->str);
@@ -169,8 +167,13 @@ static BSR *store_client(LEX *lc, BSR *bsr)
            }
         }
       }
+      lc->expect = 0;
+      token = lex_get_token(lc);
+      if (token != T_COMMA) {
+        break;
+      }
    }
-   scan_to_eol(lc);
+// scan_to_eol(lc);
    return bsr;
 }
 
@@ -179,26 +182,20 @@ static BSR *store_job(LEX *lc, BSR *bsr)
    int token;
    BSR_JOB *job;
     
+   lc->expect = T_NAME;
    token = lex_get_token(lc);
-   if (token != T_IDENTIFIER && token != T_STRING && token != T_QUOTED_STRING) {
-      scan_err1(lc, "expected an identifier or string, got: %s", lc->str);
-   } else if (lc->str_len > MAX_RES_NAME_LENGTH) {
-      scan_err3(lc, "name %s length %d too long, max is %d\n", lc->str, 
-        lc->str_len, MAX_RES_NAME_LENGTH);
+   job = (BSR_JOB *)malloc(sizeof(BSR_JOB));
+   memset(job, 0, sizeof(BSR_JOB));
+   job->Job = bstrdup(lc->str);
+   /* Add it to the end of the client chain */
+   if (!bsr->job) {
+      bsr->job = job;
    } else {
-      job = (BSR_JOB *)malloc(sizeof(BSR_JOB));
-      memset(job, 0, sizeof(BSR_JOB));
-      job->Job = bstrdup(lc->str);
-      /* Add it to the end of the client chain */
-      if (!bsr->job) {
-        bsr->job = job;
-      } else {
-        /* Add to end of chain */
-        BSR_JOB *bc = bsr->job;
-        for ( ;bc->next; bc=bc->next)
-           { }
-        bc->next = job;
-      }
+      /* Add to end of chain */
+      BSR_JOB *bc = bsr->job;
+      for ( ;bc->next; bc=bc->next)
+        { }
+      bc->next = job;
    }
    scan_to_eol(lc);
    return bsr;
@@ -207,22 +204,15 @@ static BSR *store_job(LEX *lc, BSR *bsr)
 static BSR *store_file_index(LEX *lc, BSR *bsr)
 {
    int token;
-   int32_t FileIndex;
    BSR_FINDEX *findex;
 
-
-   token = lex_get_token(lc);
-   if (token != T_NUMBER || !is_a_number(lc->str)) {
-      scan_err1(lc, "expected a positive integer number, got: %s", lc->str);
-   } else {
-      errno = 0;
-      FileIndex = strtoul(lc->str, NULL, 10);
-      if (errno != 0) {
-         scan_err1(lc, "expected a integer number, got: %s", lc->str);
-      }
+   for (;;) {
+      lc->expect = T_PINT32_RANGE;
+      token = lex_get_token(lc);
       findex = (BSR_FINDEX *)malloc(sizeof(BSR_FINDEX));
       memset(findex, 0, sizeof(BSR_FINDEX));
-      findex->FileIndex = FileIndex;
+      findex->findex = lc->pint32_val;
+      findex->findex2 = lc->pint32_val2;
       /* Add it to the end of the chain */
       if (!bsr->FileIndex) {
         bsr->FileIndex = findex;
@@ -233,8 +223,13 @@ static BSR *store_file_index(LEX *lc, BSR *bsr)
           {  }
         bs->next = findex;
       }
+      lc->expect = 0;
+      token = lex_get_token(lc);
+      if (token != T_COMMA) {
+        break;
+      }
    }
-   scan_to_eol(lc);
+// scan_to_eol(lc);
    return bsr;
 }
 
@@ -242,22 +237,15 @@ static BSR *store_file_index(LEX *lc, BSR *bsr)
 static BSR *store_jobid(LEX *lc, BSR *bsr)
 {
    int token;
-   uint32_t JobId;    
    BSR_JOBID *jobid;
 
-
-   token = lex_get_token(lc);
-   if (token != T_NUMBER || !is_a_number(lc->str)) {
-      scan_err1(lc, "expected a positive integer number, got: %s", lc->str);
-   } else {
-      errno = 0;
-      JobId = strtoul(lc->str, NULL, 10);
-      if (errno != 0) {
-         scan_err1(lc, "expected a integer number, got: %s", lc->str);
-      }
+   for (;;) {
+      lc->expect = T_PINT32_RANGE;
+      token = lex_get_token(lc);
       jobid = (BSR_JOBID *)malloc(sizeof(BSR_JOBID));
       memset(jobid, 0, sizeof(BSR_JOBID));
-      jobid->JobId = JobId;
+      jobid->JobId = lc->pint32_val;
+      jobid->JobId2 = lc->pint32_val2;
       /* Add it to the end of the chain */
       if (!bsr->JobId) {
         bsr->JobId = jobid;
@@ -268,8 +256,13 @@ static BSR *store_jobid(LEX *lc, BSR *bsr)
           {  }
         bs->next = jobid;
       }
+      lc->expect = 0;
+      token = lex_get_token(lc);
+      if (token != T_COMMA) {
+        break;
+      }
    }
-   scan_to_eol(lc);
+// scan_to_eol(lc);
    return bsr;
 }
 
@@ -290,25 +283,56 @@ static BSR *store_joblevel(LEX *lc, BSR *bsr)
 
 
 
+
+/*
+ * Routine to handle Volume start/end file   
+ */
+static BSR *store_volfile(LEX *lc, BSR *bsr)
+{
+   int token;
+   BSR_VOLFILE *volfile;
+
+   for (;;) {
+      lc->expect = T_PINT32_RANGE;
+      token = lex_get_token(lc);
+      volfile = (BSR_VOLFILE *)malloc(sizeof(BSR_VOLFILE));
+      memset(volfile, 0, sizeof(BSR_VOLFILE));
+      volfile->sfile = lc->pint32_val;
+      volfile->efile = lc->pint32_val2;
+      /* Add it to the end of the chain */
+      if (!bsr->volfile) {
+        bsr->volfile = volfile;
+      } else {
+        /* Add to end of chain */
+        BSR_VOLFILE *bs = bsr->volfile;
+        for ( ;bs->next; bs=bs->next)
+          {  }
+        bs->next = volfile;
+      }
+      lc->expect = 0;
+      token = lex_get_token(lc);
+      if (token != T_COMMA) {
+        break;
+      }
+   }
+// scan_to_eol(lc);
+   return bsr;
+}
+
+
+
 static BSR *store_sessid(LEX *lc, BSR *bsr)
 {
    int token;
-   uint32_t sessid1;
    BSR_SESSID *sid;
 
-
-   token = lex_get_token(lc);
-   if (token != T_NUMBER || !is_a_number(lc->str)) {
-      scan_err1(lc, "expected a positive integer number, got: %s", lc->str);
-   } else {
-      errno = 0;
-      sessid1 = strtoul(lc->str, NULL, 10);
-      if (errno != 0) {
-         scan_err1(lc, "expected a integer number, got: %s", lc->str);
-      }
+   for (;;) {
+      lc->expect = T_PINT32_RANGE;
+      token = lex_get_token(lc);
       sid = (BSR_SESSID *)malloc(sizeof(BSR_SESSID));
       memset(sid, 0, sizeof(BSR_SESSID));
-      sid->sessid1 = sessid1;
+      sid->sessid = lc->pint32_val;
+      sid->sessid2 = lc->pint32_val2;
       /* Add it to the end of the chain */
       if (!bsr->sessid) {
         bsr->sessid = sid;
@@ -319,40 +343,35 @@ static BSR *store_sessid(LEX *lc, BSR *bsr)
           {  }
         bs->next = sid;
       }
+      lc->expect = 0;
+      token = lex_get_token(lc);
+      if (token != T_COMMA) {
+        break;
+      }
    }
-   scan_to_eol(lc);
+// scan_to_eol(lc);
    return bsr;
 }
 
 static BSR *store_sesstime(LEX *lc, BSR *bsr)
 {
    int token;
-   uint32_t sesstime;
    BSR_SESSTIME *stime;
 
-
+   lc->expect = T_PINT32;
    token = lex_get_token(lc);
-   if (token != T_NUMBER || !is_a_number(lc->str)) {
-      scan_err1(lc, "expected a positive integer number, got: %s", lc->str);
+   stime = (BSR_SESSTIME *)malloc(sizeof(BSR_SESSTIME));
+   memset(stime, 0, sizeof(BSR_SESSTIME));
+   stime->sesstime = lc->pint32_val;
+   /* Add it to the end of the chain */
+   if (!bsr->sesstime) {
+      bsr->sesstime = stime;
    } else {
-      errno = 0;
-      sesstime = strtoul(lc->str, NULL, 10);
-      if (errno != 0) {
-         scan_err1(lc, "expected a integer number, got: %s", lc->str);
-      }
-      stime = (BSR_SESSTIME *)malloc(sizeof(BSR_SESSTIME));
-      memset(stime, 0, sizeof(BSR_SESSTIME));
-      stime->sesstime = sesstime;
-      /* Add it to the end of the chain */
-      if (!bsr->sesstime) {
-        bsr->sesstime = stime;
-      } else {
-        /* Add to end of chain */
-        BSR_SESSTIME *bs = bsr->sesstime;
-        for ( ;bs->next; bs=bs->next)
-           { }
-        bs->next = stime;
-      }
+      /* Add to end of chain */
+      BSR_SESSTIME *bs = bsr->sesstime;
+      for ( ;bs->next; bs=bs->next)
+        { }
+      bs->next = stime;
    }
    scan_to_eol(lc);
    return bsr;
@@ -370,29 +389,105 @@ static BSR *store_exclude(LEX *lc, BSR *bsr)
    return bsr;
 }
 
+void dump_volfile(BSR_VOLFILE *volfile)
+{
+   if (!volfile) {
+      return;
+   }
+   Dmsg2(-1,
+"VolFile     : %u-%u\n", volfile->sfile, volfile->efile);
+   dump_volfile(volfile->next);
+}
+
+void dump_findex(BSR_FINDEX *FileIndex)
+{
+   if (!FileIndex) {
+      return;
+   }
+   if (FileIndex->findex == FileIndex->findex2) {
+      Dmsg1(-1, "FileIndex   : %u\n", FileIndex->findex);
+   } else {
+      Dmsg2(-1, "FileIndex   : %u-%u\n", FileIndex->findex, FileIndex->findex2);
+   }
+   dump_findex(FileIndex->next);
+}
+
+void dump_jobid(BSR_JOBID *jobid)
+{
+   if (!jobid) {
+      return;
+   }
+   if (jobid->JobId == jobid->JobId2) {
+      Dmsg1(-1, "JobId       : %u\n", jobid->JobId);
+   } else {
+      Dmsg2(-1, "JobId       : %u-%u\n", jobid->JobId, jobid->JobId2);
+   }
+   dump_jobid(jobid->next);
+}
+
+void dump_sessid(BSR_SESSID *sessid)
+{
+   if (!sessid) {
+      return;
+   }
+   if (sessid->sessid == sessid->sessid2) {
+      Dmsg1(-1, "SessId      : %u\n", sessid->sessid);
+   } else {
+      Dmsg2(-1, "SessId      : %u-%u\n", sessid->sessid, sessid->sessid2);
+   }
+   dump_sessid(sessid->next);
+}
+
+
+void dump_client(BSR_CLIENT *client)
+{
+   if (!client) {
+      return;
+   }
+   Dmsg1(-1, "Client      : %s\n", client->ClientName);
+   dump_client(client->next);
+}
+
+void dump_job(BSR_JOB *job)
+{
+   if (!job) {
+      return;
+   }
+   Dmsg1(-1, "Job          : %s\n", job->Job);
+   dump_job(job->next);
+}
+
+void dump_sesstime(BSR_SESSTIME *sesstime)
+{
+   if (!sesstime) {
+      return;
+   }
+   Dmsg1(-1, "SessTime    : %u\n", sesstime->sesstime);
+   dump_sesstime(sesstime->next);
+}
+
+
+
+
+
 void dump_bsr(BSR *bsr)
 {
    if (!bsr) {
       Dmsg0(-1, "BSR is NULL\n");
       return;
    }
-   Dmsg8(-1,   
+   Dmsg2(-1,   
 "Next        : 0x%x\n"
-"VolumeName  : %s\n"
-"Client      : %s\n"
-"Job         : %s\n"
-"JobId       : %u\n"
-"SessId      : %u\n"
-"SessTime    : %u\n"
-"FileIndex   : %d\n",
+"VolumeName  : %s\n",
                 bsr->next,
-                 bsr->VolumeName ? bsr->VolumeName : "*None*",
-                 bsr->client ? bsr->client->ClientName : "*None*",
-                 bsr->job ? bsr->job->Job : "*None*",
-                bsr->JobId ? bsr->JobId->JobId : 0,
-                bsr->sessid ? bsr->sessid->sessid1 : 0,
-                bsr->sesstime ? bsr->sesstime->sesstime : 0,
-                bsr->FileIndex ? bsr->FileIndex->FileIndex : 0);
+                 bsr->VolumeName ? bsr->VolumeName : "*None*");
+   dump_sessid(bsr->sessid);
+   dump_sesstime(bsr->sesstime);
+   dump_volfile(bsr->volfile);
+   dump_client(bsr->client);
+   dump_jobid(bsr->JobId);
+   dump_job(bsr->job);
+   dump_findex(bsr->FileIndex);
    if (bsr->next) {
       Dmsg0(-1, "\n");
       dump_bsr(bsr->next);
@@ -400,6 +495,7 @@ void dump_bsr(BSR *bsr)
 }
 
 
+
 /*********************************************************************
  *
  *     Free bsr resources
@@ -422,6 +518,7 @@ void free_bsr(BSR *bsr)
    free_bsr_item((BSR *)bsr->client);
    free_bsr_item((BSR *)bsr->sessid);
    free_bsr_item((BSR *)bsr->sesstime);
+   free_bsr_item((BSR *)bsr->volfile);
    if (bsr->VolumeName) {
       free(bsr->VolumeName);
    }
index 8d3c719de873be4a0963d2291605b7b4f86eeabb..d956494a103b38e51941b6fbc879b0966358bac0 100644 (file)
@@ -109,6 +109,7 @@ int do_read_data(JCR *jcr)
     */
    for ( ;ok; ) {
       DEV_RECORD *record;            /* for reading label of multi-volumes */
+      SESSION_LABEL sessrec;          /* session record */
 
       if (job_cancelled(jcr)) {
         ok = FALSE;
@@ -156,6 +157,34 @@ int do_read_data(JCR *jcr)
 
       /* Some sort of label? */ 
       if (rec.FileIndex < 0) {
+        char *rtype;
+        switch (rec.FileIndex) {
+           case PRE_LABEL:
+               rtype = "Fresh Volume Label";   
+              break;
+           case VOL_LABEL:
+               rtype = "Volume Label";
+              unser_volume_label(dev, &rec);
+              break;
+           case SOS_LABEL:
+               rtype = "Begin Session";
+              unser_session_label(&sessrec, &rec);
+              break;
+           case EOS_LABEL:
+               rtype = "End Session";
+              break;
+           case EOM_LABEL:
+               rtype = "End of Media";
+              break;
+           default:
+               rtype = "Unknown";
+              break;
+        }
+        if (debug_level > 0) {
+            printf("%s Record: VolSessionId=%d VolSessionTime=%d JobId=%d DataLen=%d\n",
+              rtype, rec.VolSessionId, rec.VolSessionTime, rec.Stream, rec.data_len);
+        }
+
          Dmsg1(40, "Got label = %d\n", rec.FileIndex);
         if (rec.FileIndex == EOM_LABEL) { /* end of tape? */
             Dmsg0(40, "Get EOM LABEL\n");
@@ -164,6 +193,12 @@ int do_read_data(JCR *jcr)
         continue;                         /* ignore other labels */
       }
 
+      /* ****FIXME***** make sure we REALLY have a session record */
+      if (jcr->bsr && !match_bsr(jcr->bsr, &rec, &dev->VolHdr, &sessrec)) {
+         Dmsg0(50, "BSR rejected record\n");
+        continue;
+      }
+
       if (rec.VolSessionId != jcr->read_VolSessionId ||
          rec.VolSessionTime != jcr->read_VolSessionTime) {
          Dmsg0(50, "Ignore record ids not equal\n");
index 91d274510dffb1ee5ceea30408011f3507eb3e52..022f3ee62fe2e7330239aaf7db260a66501c9579 100644 (file)
@@ -31,8 +31,8 @@
 #include "record.h"
 #include "dev.h"
 #include "stored_conf.h"
-#include "jcr.h"
 #include "bsr.h"
+#include "jcr.h"
 #include "protos.h"
 #ifdef HAVE_LIBZ
 #include <zlib.h>                     /* compression headers */
index 9125719d82c8af86dabc0328c7d24b0e78bb39fd..073aee4e8172284366a406f4902700d33690b8f6 100644 (file)
@@ -1,8 +1,8 @@
 /* */
 #define VERSION "1.22"
 #define VSTRING "1"
-#define DATE    "15 June 2002"
-#define LSMDATE "15Jun02"
+#define DATE    "19 June 2002"
+#define LSMDATE "19Jun02"
 
 /* Debug flags */
 #define DEBUG 1