]> git.sur5r.net Git - bacula/bacula/commitdiff
lex_get_token update -- kes20Jun02
authorKern Sibbald <kern@sibbald.com>
Thu, 20 Jun 2002 15:35:58 +0000 (15:35 +0000)
committerKern Sibbald <kern@sibbald.com>
Thu, 20 Jun 2002 15:35:58 +0000 (15:35 +0000)
git-svn-id: https://bacula.svn.sourceforge.net/svnroot/bacula/trunk@46 91ce42f0-d328-0410-95d8-f526ca767f89

17 files changed:
bacula/src/dird/dird_conf.c
bacula/src/dird/run_conf.c
bacula/src/lib/Makefile.in
bacula/src/lib/lex.c
bacula/src/lib/lex.h
bacula/src/lib/lib.h
bacula/src/lib/parse_conf.c
bacula/src/lib/protos.h
bacula/src/lib/signal.c
bacula/src/lib/tree.c [new file with mode: 0755]
bacula/src/lib/tree.h [new file with mode: 0644]
bacula/src/stored/bsr.h
bacula/src/stored/match_bsr.c
bacula/src/stored/parse_bsr.c
bacula/src/stored/record.c
bacula/src/stored/record.h
bacula/src/version.h

index 7193bafd722f14068f03de7e81f4d8f2e5f643d8..b9ea61ae1d0926b94555b7b6b7c4d6baaaa98e2b 100644 (file)
@@ -867,22 +867,18 @@ static void store_jobtype(LEX *lc, struct res_items *item, int index, int pass)
 {
    int token, i;   
 
-   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 {
-      /* Store the type both pass 1 and pass 2 */
-      for (i=0; jobtypes[i].type_name; i++) {
-        if (strcasecmp(lc->str, jobtypes[i].type_name) == 0) {
-           ((JOB *)(item->value))->JobType = jobtypes[i].job_type;
-           i = 0;
-           break;
-        }
-      }
-      if (i != 0) {
-         scan_err1(lc, "Expected a Job Type keyword, got: %s", lc->str);
+   token = lex_get_token(lc, T_NAME);
+   /* Store the type both pass 1 and pass 2 */
+   for (i=0; jobtypes[i].type_name; i++) {
+      if (strcasecmp(lc->str, jobtypes[i].type_name) == 0) {
+        ((JOB *)(item->value))->JobType = jobtypes[i].job_type;
+        i = 0;
+        break;
       }
    }
+   if (i != 0) {
+      scan_err1(lc, "Expected a Job Type keyword, got: %s", lc->str);
+   }
    scan_to_eol(lc);
    set_bit(index, res_all.hdr.item_present);
 }
@@ -895,22 +891,18 @@ static void store_level(LEX *lc, struct res_items *item, int index, int pass)
 {
    int token, i;
 
-   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 {
-      /* Store the level pass 2 so that type is defined */
-      for (i=0; joblevels[i].level_name; i++) {
-        if (strcasecmp(lc->str, joblevels[i].level_name) == 0) {
-           ((JOB *)(item->value))->level = joblevels[i].level;
-           i = 0;
-           break;
-        }
-      }
-      if (i != 0) {
-         scan_err1(lc, "Expected a Job Level keyword, got: %s", lc->str);
+   token = lex_get_token(lc, T_NAME);
+   /* Store the level pass 2 so that type is defined */
+   for (i=0; joblevels[i].level_name; i++) {
+      if (strcasecmp(lc->str, joblevels[i].level_name) == 0) {
+        ((JOB *)(item->value))->level = joblevels[i].level;
+        i = 0;
+        break;
       }
    }
+   if (i != 0) {
+      scan_err1(lc, "Expected a Job Level keyword, got: %s", lc->str);
+   }
    scan_to_eol(lc);
    set_bit(index, res_all.hdr.item_present);
 }
@@ -934,69 +926,65 @@ static void store_backup(LEX *lc, struct res_items *item, int index, int pass)
 
    
    ((JOB *)(item->value))->JobType = item->code;
-   while ((token = lex_get_token(lc)) != T_EOL) {
+   while ((token = lex_get_token(lc, T_ALL)) != T_EOL) {
       int found;
 
       if (token != T_IDENTIFIER && token != T_STRING && token != T_QUOTED_STRING) {
          scan_err1(lc, "Expected a backup/verify keyword, got: %s", lc->str);
-      } else {
-         Dmsg1(190, "Got keyword: %s\n", lc->str);
-        found = FALSE;
-        for (i=0; BakVerFields[i].name; i++) {
-           if (strcasecmp(lc->str, BakVerFields[i].name) == 0) {
-              found = TRUE;
-              if (lex_get_token(lc) != T_EQUALS) {
-                  scan_err1(lc, "Expected an equals, got: %s", lc->str);
-              }
-              token = lex_get_token(lc);
-              if (token != T_IDENTIFIER && token != T_STRING && token != T_QUOTED_STRING) {
-                  scan_err1(lc, "Expected a keyword name, got: %s", lc->str);
-              }
-               Dmsg1(190, "Got value: %s\n", lc->str);
-              switch (BakVerFields[i].token) {
-                  case 'C':
-                    /* Find Client Resource */
-                    if (pass == 2) {
-                       res = GetResWithName(R_CLIENT, lc->str);
-                       if (res == NULL) {
-                           scan_err1(lc, "Could not find specified Client Resource: %s",
-                                     lc->str);
-                       }
-                       res_all.res_job.client = (CLIENT *)res;
-                    }
-                    break;
-                  case 'F':
-                    /* Find FileSet Resource */
-                    if (pass == 2) {
-                       res = GetResWithName(R_FILESET, lc->str);
-                       if (res == NULL) {
-                           scan_err1(lc, "Could not find specified FileSet Resource: %s\n",
-                                      lc->str);
-                       }
-                       res_all.res_job.fs = (FILESET *)res;
+      }
+      Dmsg1(190, "Got keyword: %s\n", lc->str);
+      found = FALSE;
+      for (i=0; BakVerFields[i].name; i++) {
+        if (strcasecmp(lc->str, BakVerFields[i].name) == 0) {
+           found = TRUE;
+           if (lex_get_token(lc, T_ALL) != T_EQUALS) {
+               scan_err1(lc, "Expected an equals, got: %s", lc->str);
+           }
+           token = lex_get_token(lc, T_NAME);
+            Dmsg1(190, "Got value: %s\n", lc->str);
+           switch (BakVerFields[i].token) {
+               case 'C':
+                 /* Find Client Resource */
+                 if (pass == 2) {
+                    res = GetResWithName(R_CLIENT, lc->str);
+                    if (res == NULL) {
+                        scan_err1(lc, "Could not find specified Client Resource: %s",
+                                  lc->str);
                     }
-                    break;
-                  case 'L':
-                    /* Get level */
-                    for (i=0; joblevels[i].level_name; i++) {
-                       if (joblevels[i].job_type == item->code && 
-                            strcasecmp(lc->str, joblevels[i].level_name) == 0) {
-                          ((JOB *)(item->value))->level = joblevels[i].level;
-                          i = 0;
-                          break;
-                       }
+                    res_all.res_job.client = (CLIENT *)res;
+                 }
+                 break;
+               case 'F':
+                 /* Find FileSet Resource */
+                 if (pass == 2) {
+                    res = GetResWithName(R_FILESET, lc->str);
+                    if (res == NULL) {
+                        scan_err1(lc, "Could not find specified FileSet Resource: %s\n",
+                                   lc->str);
                     }
-                    if (i != 0) {
-                        scan_err1(lc, "Expected a Job Level keyword, got: %s", lc->str);
+                    res_all.res_job.fs = (FILESET *)res;
+                 }
+                 break;
+               case 'L':
+                 /* Get level */
+                 for (i=0; joblevels[i].level_name; i++) {
+                    if (joblevels[i].job_type == item->code && 
+                         strcasecmp(lc->str, joblevels[i].level_name) == 0) {
+                       ((JOB *)(item->value))->level = joblevels[i].level;
+                       i = 0;
+                       break;
                     }
-                    break;
-              } /* end switch */
-              break;
-           } /* end if strcmp() */
-        } /* end for */
-        if (!found) {
-            scan_err1(lc, "%s not a valid Backup/verify keyword", lc->str);
-        }
+                 }
+                 if (i != 0) {
+                     scan_err1(lc, "Expected a Job Level keyword, got: %s", lc->str);
+                 }
+                 break;
+           } /* end switch */
+           break;
+        } /* end if strcmp() */
+      } /* end for */
+      if (!found) {
+         scan_err1(lc, "%s not a valid Backup/verify keyword", lc->str);
       }
    } /* end while */
    lc->options = options;            /* reset original options */
@@ -1020,90 +1008,89 @@ static void store_restore(LEX *lc, struct res_items *item, int index, int pass)
    Dmsg0(190, "Enter store_restore()\n");
    
    ((JOB *)(item->value))->JobType = item->code;
-   while ((token = lex_get_token(lc)) != T_EOL) {
+   while ((token = lex_get_token(lc, T_ALL)) != T_EOL) {
       int found; 
 
-      if (token != T_IDENTIFIER && token != T_STRING && token != T_QUOTED_STRING) {
-         scan_err1(lc, "Expected a Restore keyword, got: %s", lc->str);
-      } else {
-        found = FALSE;
-        for (i=0; RestoreFields[i].name; i++) {
-            Dmsg1(190, "Restore kw=%s\n", lc->str);
-           if (strcasecmp(lc->str, RestoreFields[i].name) == 0) {
-              found = TRUE;
-              if (lex_get_token(lc) != T_EQUALS) {
-                  scan_err1(lc, "Expected an equals, got: %s", lc->str);
-              }
-              token = lex_get_token(lc);
-               Dmsg1(190, "Restore value=%s\n", lc->str);
-              switch (RestoreFields[i].token) {
-                  case 'C':
-                    /* Find Client Resource */
-                    if (pass == 2) {
-                       res = GetResWithName(R_CLIENT, lc->str);
-                       if (res == NULL) {
-                           scan_err1(lc, "Could not find specified Client Resource: %s",
-                                     lc->str);
-                       }
-                       res_all.res_job.client = (CLIENT *)res;
-                    }
-                    break;
-                  case 'F':
-                    /* Find FileSet Resource */
-                    if (pass == 2) {
-                       res = GetResWithName(R_FILESET, lc->str);
-                       if (res == NULL) {
-                           scan_err1(lc, "Could not find specified FileSet Resource: %s\n",
-                                      lc->str);
-                       }
-                       res_all.res_job.fs = (FILESET *)res;
-                    }
-                    break;
-                  case 'J':
-                    /* JobId */
-                    if (token != T_NUMBER) {
-                        scan_err1(lc, "expected an integer number, got: %s", lc->str);
-                    }
-                    errno = 0;
-                    res_all.res_job.RestoreJobId = strtol(lc->str, NULL, 0);
-                     Dmsg1(190, "RestorJobId=%d\n", res_all.res_job.RestoreJobId);
-                    if (errno != 0) {
-                        scan_err1(lc, "expected an integer number, got: %s", lc->str);
-                    }
-                    break;
-                  case 'W':
-                    /* Where */
-                    if (token != T_IDENTIFIER && token != T_STRING && token != T_QUOTED_STRING) {
-                        scan_err1(lc, "Expected a Restore root directory, got: %s", lc->str);
-                    }
-                    if (pass == 1) {
-                       res_all.res_job.RestoreWhere = bstrdup(lc->str);
-                    }
-                    break;
-                  case 'R':
-                    /* Replacement options */
-                    if (token != T_IDENTIFIER && token != T_STRING && token != T_QUOTED_STRING) {
-                        scan_err1(lc, "Expected a keyword name, got: %s", lc->str);
+      if (token != T_IDENTIFIER && token != T_UNQUOTED_STRING && token != T_QUOTED_STRING) {
+         scan_err1(lc, "expected a name, got: %s", lc->str);
+      }
+      found = FALSE;
+      for (i=0; RestoreFields[i].name; i++) {
+         Dmsg1(190, "Restore kw=%s\n", lc->str);
+        if (strcasecmp(lc->str, RestoreFields[i].name) == 0) {
+           found = TRUE;
+           if (lex_get_token(lc, T_ALL) != T_EQUALS) {
+               scan_err1(lc, "Expected an equals, got: %s", lc->str);
+           }
+           token = lex_get_token(lc, T_ALL);
+            Dmsg1(190, "Restore value=%s\n", lc->str);
+           switch (RestoreFields[i].token) {
+               case 'C':
+                 /* Find Client Resource */
+                 if (pass == 2) {
+                    res = GetResWithName(R_CLIENT, lc->str);
+                    if (res == NULL) {
+                        scan_err1(lc, "Could not find specified Client Resource: %s",
+                                  lc->str);
                     }
-                    /* Fix to scan Replacement options */
-                    for (i=0; ReplaceOptions[i].name; i++) {
-                       if (strcasecmp(lc->str, ReplaceOptions[i].name) == 0) {
-                           ((JOB *)(item->value))->RestoreOptions = ReplaceOptions[i].token;
-                          i = 0;
-                          break;
-                       }
+                    res_all.res_job.client = (CLIENT *)res;
+                 }
+                 break;
+               case 'F':
+                 /* Find FileSet Resource */
+                 if (pass == 2) {
+                    res = GetResWithName(R_FILESET, lc->str);
+                    if (res == NULL) {
+                        scan_err1(lc, "Could not find specified FileSet Resource: %s\n",
+                                   lc->str);
                     }
-                    if (i != 0) {
-                        scan_err1(lc, "Expected a Restore replacement option, got: %s", lc->str);
+                    res_all.res_job.fs = (FILESET *)res;
+                 }
+                 break;
+               case 'J':
+                 /* JobId */
+                 if (token != T_NUMBER) {
+                     scan_err1(lc, "expected an integer number, got: %s", lc->str);
+                 }
+                 errno = 0;
+                 res_all.res_job.RestoreJobId = strtol(lc->str, NULL, 0);
+                  Dmsg1(190, "RestorJobId=%d\n", res_all.res_job.RestoreJobId);
+                 if (errno != 0) {
+                     scan_err1(lc, "expected an integer number, got: %s", lc->str);
+                 }
+                 break;
+               case 'W':
+                 /* Where */
+                 if (token != T_IDENTIFIER && token != T_UNQUOTED_STRING && token != T_QUOTED_STRING) {
+                     scan_err1(lc, "Expected a Restore root directory, got: %s", lc->str);
+                 }
+                 if (pass == 1) {
+                    res_all.res_job.RestoreWhere = bstrdup(lc->str);
+                 }
+                 break;
+               case 'R':
+                 /* Replacement options */
+                 if (token != T_IDENTIFIER && token != T_UNQUOTED_STRING && token != T_QUOTED_STRING) {
+                     scan_err1(lc, "Expected a keyword name, got: %s", lc->str);
+                 }
+                 /* Fix to scan Replacement options */
+                 for (i=0; ReplaceOptions[i].name; i++) {
+                    if (strcasecmp(lc->str, ReplaceOptions[i].name) == 0) {
+                        ((JOB *)(item->value))->RestoreOptions = ReplaceOptions[i].token;
+                       i = 0;
+                       break;
                     }
-                    break;
-              } /* end switch */
-              break;
-           } /* end if strcmp() */
-        } /* end for */
-        if (!found) {
-            scan_err1(lc, "%s not a valid Restore keyword", lc->str);
-        }
+                 }
+                 if (i != 0) {
+                     scan_err1(lc, "Expected a Restore replacement option, got: %s", lc->str);
+                 }
+                 break;
+           } /* end switch */
+           break;
+        } /* end if strcmp() */
+      } /* end for */
+      if (!found) {
+         scan_err1(lc, "%s not a valid Restore keyword", lc->str);
       }
    } /* end while */
    lc->options = options;            /* reset original options */
@@ -1125,10 +1112,7 @@ static char *scan_fs_options(LEX *lc, int keyword)
    option[0] = 0;                    /* default option = none */
    opts[0] = option[2] = 0;          /* terminate options */
    for (;;) {
-      token = lex_get_token(lc);            /* expect at least one option */       
-      if (token != T_IDENTIFIER && token != T_STRING && token != T_QUOTED_STRING) {
-         scan_err1(lc, "expected a FileSet option, got: %s", lc->str);
-      }
+      token = lex_get_token(lc, T_NAME);            /* expect at least one option */       
       if (keyword == FS_KW_VERIFY) { /* special case */
         /* ***FIXME**** ensure these are in permitted set */
          strcpy(option, "V");         /* indicate Verify */
@@ -1153,7 +1137,7 @@ static char *scan_fs_options(LEX *lc, int keyword)
       if (lc->ch != ',') {
         break;                       /* no, get out */
       }
-      token = lex_get_token(lc);      /* yes, eat comma */
+      token = lex_get_token(lc, T_ALL);      /* yes, eat comma */
    }
 
    return opts;
@@ -1174,23 +1158,19 @@ static void store_inc(LEX *lc, struct res_items *item, int index, int pass)
 
    /* Get include options */
    strcpy(inc_opts, "0");             /* set no options */
-   while ((token=lex_get_token(lc)) != T_BOB) {
-      if (token != T_STRING) {
-         scan_err1(lc, "expected a FileSet option keyword, got: %s", lc->str);
-      } else {
-        keyword = FS_KW_NONE;
-        for (i=0; FS_option_kw[i].name; i++) {
-           if (strcasecmp(lc->str, FS_option_kw[i].name) == 0) {
-              keyword = FS_option_kw[i].token;
-              break;
-           }
-        }
-        if (keyword == FS_KW_NONE) {
-            scan_err1(lc, "Expected a FileSet keyword, got: %s", lc->str);
+   while ((token=lex_get_token(lc, T_ALL)) != T_BOB) {
+      keyword = FS_KW_NONE;
+      for (i=0; FS_option_kw[i].name; i++) {
+        if (strcasecmp(lc->str, FS_option_kw[i].name) == 0) {
+           keyword = FS_option_kw[i].token;
+           break;
         }
       }
+      if (keyword == FS_KW_NONE) {
+         scan_err1(lc, "Expected a FileSet keyword, got: %s", lc->str);
+      }
       /* Option keyword should be following by = <option> */
-      if ((token=lex_get_token(lc)) != T_EQUALS) {
+      if ((token=lex_get_token(lc, T_ALL)) != T_EQUALS) {
          scan_err1(lc, "expected an = following keyword, got: %s", lc->str);
       }
       strcat(inc_opts, scan_fs_options(lc, keyword));
@@ -1213,14 +1193,14 @@ static void store_inc(LEX *lc, struct res_items *item, int index, int pass)
        *     a "0 " (zero) indicates no options,
        * and fname is the file/directory name given
        */
-      while ((token = lex_get_token(lc)) != T_EOB) {
+      while ((token = lex_get_token(lc, T_ALL)) != T_EOB) {
         switch (token) {
            case T_COMMA:
            case T_EOL:
               continue;
 
            case T_IDENTIFIER:
-           case T_STRING:
+           case T_UNQUOTED_STRING:
            case T_QUOTED_STRING:
               fname = (char *) malloc(lc->str_len + inc_opts_len + 1);
               strcpy(fname, inc_opts);
@@ -1259,7 +1239,7 @@ static void store_inc(LEX *lc, struct res_items *item, int index, int pass)
         }                                 
       }
    } else { /* pass 2 */
-      while (lex_get_token(lc) != T_EOB) 
+      while (lex_get_token(lc, T_ALL) != T_EOB) 
         {}
    }
    scan_to_eol(lc);
index 1ff22e5ebedc74df1b449acc9594479f572d1dc2..b9e307bad332253d086d3884d6ec38c1db48ce67 100644 (file)
@@ -184,20 +184,14 @@ void store_run(LEX *lc, struct res_items *item, int index, int pass)
    /* scan for Job level "full", "incremental", ... */
    for (found=TRUE; found; ) {
       found = FALSE;
-      token = lex_get_token(lc);
-      if (token != T_IDENTIFIER && token != T_STRING && token != T_QUOTED_STRING) {
-         scan_err1(lc, "Expected a keyword name, got: %s", lc->str);
-      }
+      token = lex_get_token(lc, T_NAME);
       for (i=0; RunFields[i].name; i++) {
         if (strcasecmp(lc->str, RunFields[i].name) == 0) {
            found = TRUE;
-           if (lex_get_token(lc) != T_EQUALS) {
+           if (lex_get_token(lc, T_ALL) != T_EQUALS) {
                scan_err1(lc, "Expected an equals, got: %s", lc->str);
            }
-           token = lex_get_token(lc);
-           if (token != T_IDENTIFIER && token != T_STRING && token != T_QUOTED_STRING) {
-               scan_err1(lc, "Expected a keyword name, got: %s", lc->str);
-           }
+           token = lex_get_token(lc, T_NAME);
            switch (RunFields[i].token) {
             case 'L':                 /* level */
               for (j=0; joblevels[j].level_name; j++) {
@@ -270,7 +264,7 @@ void store_run(LEX *lc, struct res_items *item, int index, int pass)
    state = s_none;
    set_defaults();
 
-   for ( ; token != T_EOL; (token = lex_get_token(lc))) {
+   for ( ; token != T_EOL; (token = lex_get_token(lc, T_ALL))) {
       int len, pm;
       switch (token) {
         case T_NUMBER:
@@ -280,7 +274,8 @@ void store_run(LEX *lc, struct res_items *item, int index, int pass)
                scan_err0(lc, _("Day number out of range (1-31)"));
            }
            break;
-        case T_STRING:
+        case T_NAME:                 /* this handles drop through from keyword */
+        case T_UNQUOTED_STRING:
             if (strchr(lc->str, (int)'-')) {
               state = s_range;
               break;
@@ -305,7 +300,7 @@ void store_run(LEX *lc, struct res_items *item, int index, int pass)
         case T_COMMA:
            continue;
         default:
-            scan_err1(lc, _("Unexpected token: %s"), lc->str);
+            scan_err2(lc, _("Unexpected token: %d:%s"), token, lc->str);
            break;
       }
       switch (state) {
index 3e55a917b19f022848326ae71e43962d2c8105ef..62c6f4eec8da1ac9dd03743df7c7e236511a45e4 100644 (file)
@@ -38,7 +38,7 @@ LIBSRCS = alloc.c base64.c bmisc.c bnet.c bnet_server.c \
          makepath.c \
          md5.c message.c mem_pool.c parse_conf.c \
          queue.c rwlock.c save-cwd.c serial.c \
-         signal.c smartall.c util.c watchdog.c workq.c  
+         signal.c smartall.c tree.c util.c watchdog.c workq.c  
 
 #        immortal.c filesys.c
 
@@ -49,7 +49,7 @@ LIBOBJS = alloc.o base64.o bmisc.o bnet.o bnet_server.o \
          makepath.o \
          md5.o message.o mem_pool.o parse_conf.o \
          queue.o rwlock.o save-cwd.o serial.o \
-         signal.o smartall.o util.o watchdog.o workq.o
+         signal.o smartall.o tree.o util.o watchdog.o workq.o
 
 #        immortal.o filesys.o
 
index 51a6784842f636e429691aa0f2d935c9b1bd6779..5352934fc5827008824420e01721f953a765321f 100644 (file)
@@ -38,9 +38,8 @@ void scan_to_eol(LEX *lc)
 {
    int token;
    Dmsg0(150, "start scan to eof\n");
-   lc->expect = 0;                   /* clear expectations */
    if (token != T_EOL) {
-      while ((token = lex_get_token(lc)) != T_EOL) {
+      while ((token = lex_get_token(lc, T_ALL)) != T_EOL) {
       }
    }
    Dmsg0(150, "done scan to eof\n");
@@ -224,22 +223,22 @@ char *
 lex_tok_to_str(int token)
 {
    switch(token) {
-      case L_EOF:           return "L_EOF";
-      case L_EOL:           return "L_EOL";
-      case T_NONE:          return "T_NONE";
-      case T_NUMBER:        return "T_NUMBER";
-      case T_IPADDR:        return "T_IPADDR";
-      case T_IDENTIFIER:    return "T_IDENTIFIER";
-      case T_STRING:        return "T_STRING";
-      case T_QUOTED_STRING: return "T_QUOTED_STRING";
-      case T_BOB:           return "T_BOB";
-      case T_EOB:           return "T_EOB";
-      case T_EQUALS:        return "T_EQUALS";
-      case T_ERROR:         return "T_ERROR";
-      case T_EOF:           return "T_EOF";
-      case T_COMMA:         return "T_COMMA";
-      case T_EOL:           return "T_EOL";
-      default:              return "??????";
+      case L_EOF:             return "L_EOF";
+      case L_EOL:             return "L_EOL";
+      case T_NONE:            return "T_NONE";
+      case T_NUMBER:          return "T_NUMBER";
+      case T_IPADDR:          return "T_IPADDR";
+      case T_IDENTIFIER:      return "T_IDENTIFIER";
+      case T_UNQUOTED_STRING: return "T_UNQUOTED_STRING";
+      case T_QUOTED_STRING:   return "T_QUOTED_STRING";
+      case T_BOB:             return "T_BOB";
+      case T_EOB:             return "T_EOB";
+      case T_EQUALS:          return "T_EQUALS";
+      case T_ERROR:           return "T_ERROR";
+      case T_EOF:             return "T_EOF";
+      case T_COMMA:           return "T_COMMA";
+      case T_EOL:             return "T_EOL";
+      default:                return "??????";
    }
 }
 
@@ -264,7 +263,7 @@ static uint32_t scan_pint(LEX *lf, char *str)
  *
  */
 int
-lex_get_token(LEX *lf)
+lex_get_token(LEX *lf, int expect)
 {
    int ch;
    int token = T_NONE;
@@ -369,7 +368,7 @@ lex_get_token(LEX *lf)
             if (ch == '\n' || ch == L_EOL || ch == '=' || ch == '}' || ch == '{' ||
                 ch == ';' || ch == ',' || ch == '#' || (ISSPACE(ch)) ) {
               lex_unget_char(lf);    
-              token = T_STRING;
+              token = T_UNQUOTED_STRING;
               lf->state = lex_none;
               break;
            } 
@@ -441,7 +440,7 @@ lex_get_token(LEX *lf)
     *  expectations (e.g. 32 bit integer). If so, we do type checking
     *  and possible additional scanning (e.g. for range).
     */
-   switch (lf->expect) {
+   switch (expect) {
    case T_PINT32:
       lf->pint32_val = scan_pint(lf, lf->str);
       lf->pint32_val2 = lf->pint32_val;
@@ -493,7 +492,7 @@ lex_get_token(LEX *lf)
       break;
 
    case T_NAME:
-      if (token != T_IDENTIFIER && token != T_STRING && token != T_QUOTED_STRING) {
+      if (token != T_IDENTIFIER && token != T_UNQUOTED_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, 
@@ -502,6 +501,14 @@ lex_get_token(LEX *lf)
       token = T_NAME;
       break;
 
+   case T_STRING:
+      if (token != T_IDENTIFIER && token != T_UNQUOTED_STRING && token != T_QUOTED_STRING) {
+         scan_err1(lf, "expected a name: %s", lf->str);
+      }
+      token = T_STRING;
+      break;
+
+
    default:
       break;                         /* no expectation given */
    }
index ec642a95be9e4ad79bbdbe6c7ab29c4ec1d57909..795d31cbcf573291d08662faaefc4d8860c65a98 100644 (file)
@@ -43,7 +43,7 @@
 #define T_NUMBER                      102
 #define T_IPADDR                      103
 #define T_IDENTIFIER                  104
-#define T_STRING                      105
+#define T_UNQUOTED_STRING             105
 #define T_QUOTED_STRING               106
 #define T_BOB                         108  /* begin block */
 #define T_EOB                         109  /* end of block */
 #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 */
+#define T_NAME                        118  /* name max 128 chars */
+#define T_STRING                      119  /* string */
+
+#define T_ALL                           0  /* no expectations */
 
 /* Lexical state */
 enum lex_state {
@@ -81,7 +84,6 @@ enum lex_state {
 typedef struct s_lex_context {
    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 */
index f6698aeb91b4d8bbb9afb9b72052d0caca24ea87..e3d12d09c4d3eb3192c5a73eb5e26488a931b245 100644 (file)
@@ -45,5 +45,6 @@
 #include "fnmatch.h"
 #endif
 #include "md5.h"
+#include "tree.h"
 
 #include "protos.h"
index e063b6f84e905323e54f89ef5ca3eb5a1802ff62..18f1073847648d708df93b84b965568253bdeda3 100755 (executable)
@@ -211,10 +211,7 @@ void store_msgs(LEX *lc, struct res_items *item, int index, int pass)
            dest[0] = 0;
            /* Pick up comma separated list of destinations */
            for ( ;; ) {
-              token = lex_get_token(lc);    /* scan destination */
-              if (token != T_IDENTIFIER && token != T_STRING && token != T_QUOTED_STRING) {
-                  scan_err1(lc, "expected a message destination, got: %s", lc->str);
-              }
+              token = lex_get_token(lc, T_NAME);   /* scan destination */
               dest = (char *) check_pool_memory_size(dest, dest_len + lc->str_len + 2);
               if (dest[0] != 0) {
                   strcat(dest, " ");  /* separate multiple destinations with space */
@@ -223,7 +220,7 @@ void store_msgs(LEX *lc, struct res_items *item, int index, int pass)
               strcat(dest, lc->str);
               dest_len += lc->str_len;
                Dmsg2(100, "store_msgs newdest=%s: dest=%s:\n", lc->str, dest);
-              token = lex_get_token(lc);
+              token = lex_get_token(lc, T_ALL);
               if (token == T_COMMA) { 
                  continue;           /* get another destination */
               }
@@ -241,14 +238,11 @@ void store_msgs(LEX *lc, struct res_items *item, int index, int pass)
         case MD_APPEND:              /* append */
            dest = get_pool_memory(PM_MESSAGE);
            /* Pick up a single destination */
-           token = lex_get_token(lc);    /* scan destination */
-           if (token != T_IDENTIFIER && token != T_STRING && token != T_QUOTED_STRING) {
-               scan_err1(lc, "expected a message destination, got: %s", lc->str);
-           }
+           token = lex_get_token(lc, T_NAME);   /* scan destination */
            dest = check_pool_memory_size(dest, dest_len + lc->str_len + 2);
            strcpy(dest, lc->str);
            dest_len = lc->str_len;
-           token = lex_get_token(lc);
+           token = lex_get_token(lc, T_ALL);
             Dmsg1(200, "store_msgs dest=%s:\n", dest);
            if (token != T_EQUALS) {
                scan_err1(lc, "expected an =, got: %s", lc->str); 
@@ -281,10 +275,7 @@ static void scan_types(LEX *lc, MSGS *msg, int dest_code, char *where, char *cmd
    char *str;
 
    for (quit=0; !quit;) {
-      token = lex_get_token(lc);            /* expect at least one type */       
-      if (token != T_IDENTIFIER && token != T_STRING && token != T_QUOTED_STRING) {
-         scan_err1(lc, "expected a message type, got: %s", lc->str);
-      }
+      token = lex_get_token(lc, T_NAME);           /* expect at least one type */       
       found = FALSE;
       if (lc->str[0] == '!') {
         is_not = TRUE;
@@ -319,7 +310,7 @@ static void scan_types(LEX *lc, MSGS *msg, int dest_code, char *where, char *cmd
         break;
       }
       Dmsg0(200, "call lex_get_token() to eat comma\n");
-      token = lex_get_token(lc);         /* eat comma */
+      token = lex_get_token(lc, T_ALL);         /* eat comma */
    }
    Dmsg0(200, "Done scan_types()\n");
 }
@@ -333,8 +324,7 @@ void store_name(LEX *lc, struct res_items *item, int index, int pass)
 {
    int token;
 
-   lc->expect = T_NAME;
-   token = lex_get_token(lc);
+   token = lex_get_token(lc, T_NAME);
    /* Store the name both pass 1 and pass 2 */
    *(item->value) = bstrdup(lc->str);
    scan_to_eol(lc);
@@ -350,8 +340,7 @@ void store_strname(LEX *lc, struct res_items *item, int index, int pass)
 {
    int token;
 
-   lc->expect = T_NAME;
-   token = lex_get_token(lc);
+   token = lex_get_token(lc, T_NAME);
    /* Store the name */
    if (pass == 1) {
       *(item->value) = bstrdup(lc->str);
@@ -367,13 +356,9 @@ void store_str(LEX *lc, struct res_items *item, int index, int pass)
 {
    int token;
 
-   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 (pass == 1) {
-        *(item->value) = bstrdup(lc->str);
-      }
+   token = lex_get_token(lc, T_STRING);
+   if (pass == 1) {
+      *(item->value) = bstrdup(lc->str);
    }
    scan_to_eol(lc);
    set_bit(index, res_all.hdr.item_present);
@@ -384,14 +369,10 @@ void store_dir(LEX *lc, struct res_items *item, int index, int pass)
 {
    int token;
 
-   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 (pass == 1) {
-        do_shell_expansion(lc->str);
-        *(item->value) = bstrdup(lc->str);
-      }
+   token = lex_get_token(lc, T_STRING);
+   if (pass == 1) {
+      do_shell_expansion(lc->str);
+      *(item->value) = bstrdup(lc->str);
    }
    scan_to_eol(lc);
    set_bit(index, res_all.hdr.item_present);
@@ -407,20 +388,16 @@ void store_password(LEX *lc, struct res_items *item, int index, int pass)
    char sig[100];
 
 
-   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\n", lc->str);
-   } else {
-      if (pass == 1) {
-        MD5Init(&md5c);
-        MD5Update(&md5c, (unsigned char *) (lc->str), lc->str_len);
-        MD5Final(signature, &md5c);
-        for (i = j = 0; i < sizeof(signature); i++) {
-            sprintf(&sig[j], "%02x", signature[i]); 
-           j += 2;
-        }
-        *(item->value) = bstrdup(sig);
+   token = lex_get_token(lc, T_STRING);
+   if (pass == 1) {
+      MD5Init(&md5c);
+      MD5Update(&md5c, (unsigned char *) (lc->str), lc->str_len);
+      MD5Final(signature, &md5c);
+      for (i = j = 0; i < sizeof(signature); i++) {
+         sprintf(&sig[j], "%02x", signature[i]); 
+        j += 2;
       }
+      *(item->value) = bstrdup(sig);
    }
    scan_to_eol(lc);
    set_bit(index, res_all.hdr.item_present);
@@ -436,10 +413,7 @@ void store_res(LEX *lc, struct res_items *item, int index, int pass)
    int token;
    RES *res;
 
-   token = lex_get_token(lc);
-   if (token != T_IDENTIFIER && token != T_STRING && token != T_QUOTED_STRING) {
-      scan_err1(lc, "expected a Resource name, got: %s", lc->str);
-   }
+   token = lex_get_token(lc, T_NAME);
    if (pass == 2) {
      res = GetResWithName(item->code, lc->str);
      if (res == NULL) {
@@ -458,16 +432,8 @@ void store_int(LEX *lc, struct res_items *item, int index, int pass)
 {
    int token;
 
-   token = lex_get_token(lc);
-   if (token != T_NUMBER || !is_a_number(lc->str)) {
-      scan_err1(lc, "expected an integer number, got: %s", lc->str);
-   } else {
-      errno = 0;
-      *(int *)(item->value) = (int)strtod(lc->str, NULL);
-      if (errno != 0) {
-         scan_err1(lc, "expected an integer number, got: %s", lc->str);
-      }
-   }
+   token = lex_get_token(lc, T_INT32);
+   *(int *)(item->value) = lc->int32_val;
    scan_to_eol(lc);
    set_bit(index, res_all.hdr.item_present);
 }
@@ -477,8 +443,7 @@ void store_pint(LEX *lc, struct res_items *item, int index, int pass)
 {
    int token;
 
-   lc->expect = T_PINT32;
-   token = lex_get_token(lc);
+   token = lex_get_token(lc, T_PINT32);
    *(int *)(item->value) = lc->pint32_val;
    scan_to_eol(lc);
    set_bit(index, res_all.hdr.item_present);
@@ -490,8 +455,7 @@ void store_int64(LEX *lc, struct res_items *item, int index, int pass)
 {
    int token;
 
-   lc->expect = T_INT64;
-   token = lex_get_token(lc);
+   token = lex_get_token(lc, T_INT64);
    *(int64_t *)(item->value) = lc->int64_val;
    scan_to_eol(lc);
    set_bit(index, res_all.hdr.item_present);
@@ -518,7 +482,7 @@ void store_size(LEX *lc, struct res_items *item, int index, int pass)
 #endif
 
    Dmsg0(400, "Enter store_size\n");
-   token = lex_get_token(lc);
+   token = lex_get_token(lc, T_ALL);
    errno = 0;
    switch (token) {
    case T_NUMBER:
@@ -530,7 +494,7 @@ void store_size(LEX *lc, struct res_items *item, int index, int pass)
       *(uint64_t *)(item->value) = value;
       break;
    case T_IDENTIFIER:
-   case T_STRING:
+   case T_UNQUOTED_STRING:
       /* Look for modifier */
       ch = lc->str[lc->str_len - 1];
       i = 0;
@@ -576,7 +540,7 @@ void store_time(LEX *lc, struct res_items *item, int index, int pass)
    int token; 
    btime_t value;
 
-   token = lex_get_token(lc);
+   token = lex_get_token(lc, T_ALL);
    errno = 0;
    switch (token) {
    case T_NUMBER:
@@ -587,7 +551,7 @@ void store_time(LEX *lc, struct res_items *item, int index, int pass)
       *(btime_t *)(item->value) = value;
       break;
    case T_IDENTIFIER:
-   case T_STRING:
+   case T_UNQUOTED_STRING:
       if (!string_to_btime(lc->str, &value)) {
          scan_err1(lc, "expected a time period, got: %s", lc->str);
       }
@@ -607,10 +571,8 @@ void store_yesno(LEX *lc, struct res_items *item, int index, int pass)
 {
    int token;
 
-   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 (strcasecmp(lc->str, "yes") == 0) {
+   token = lex_get_token(lc, T_NAME);
+   if (strcasecmp(lc->str, "yes") == 0) {
       *(int *)(item->value) |= item->code;
    } else if (strcasecmp(lc->str, "no") == 0) {
       *(int *)(item->value) &= ~(item->code);
@@ -708,7 +670,7 @@ parse_config(char *cf)
    for (pass=1; pass <= 2; pass++) {
       Dmsg1(200, "parse_config pass %d\n", pass);
       lc = lex_open_file(lc, cf);
-      while ((token=lex_get_token(lc)) != T_EOF) {
+      while ((token=lex_get_token(lc, T_ALL)) != T_EOF) {
          Dmsg1(150, "parse got token=%s\n", lex_tok_to_str(token));
         switch (state) {
            case p_none:
@@ -741,7 +703,7 @@ parse_config(char *cf)
                     }
                     for (i=0; items[i].name; i++) {
                        if (strcasecmp(items[i].name, lc->str) == 0) {
-                          token = lex_get_token(lc);
+                          token = lex_get_token(lc, T_ALL);
                            Dmsg1 (150, "in T_IDENT got token=%s\n", lex_tok_to_str(token));
                           if (token != T_EQUALS) {
                               scan_err1(lc, "expected an equals, got: %s", lc->str);
index 5d2b3426d7780587578b613a6bd6d317d3ce85a2..43926b72d5749a169b03ae2429adabf0c7eef562 100644 (file)
@@ -88,7 +88,7 @@ LEX *     lex_open_file          (LEX *lf, char *fname);
 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       lex_get_token          (LEX *lf, int expect);
 
 /* makepath.c */
 int make_path(
index 0b9fe5bc792cf2d232474782e611483619403c1a..26bd5495c9ed42e443cd2a6bfebe3dad989f5574 100644 (file)
@@ -80,7 +80,8 @@ static void signal_handler(int sig)
       static char btpath[400];
       pid_t pid;
 
-      fprintf(stderr, "Kaboom! Got signal %d. Attempting traceback.\n", sig);
+      fprintf(stderr, "Kaboom! %s got signal %d. Attempting traceback.\n", 
+             my_name, sig);
       if (strlen(exepath) + 12 > (int)sizeof(btpath)) {
          strcpy(btpath, "btraceback");
       } else {
diff --git a/bacula/src/lib/tree.c b/bacula/src/lib/tree.c
new file mode 100755 (executable)
index 0000000..05ff49a
--- /dev/null
@@ -0,0 +1,388 @@
+/*
+ * Directory tree build/traverse routines
+ * 
+ *    Kern Sibbald, June MMII
+ *
+*/
+/*
+   Copyright (C) 2002 Kern Sibbald and John Walker
+
+   This program is free software; you can redistribute it and/or
+   modify it under the terms of the GNU General Public License as
+   published by the Free Software Foundation; either version 2 of
+   the License, or (at your option) any later version.
+
+   This program is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+   General Public License for more details.
+
+   You should have received a copy of the GNU General Public
+   License along with this program; if not, write to the Free
+   Software Foundation, Inc., 59 Temple Place - Suite 330, Boston,
+   MA 02111-1307, USA.
+
+ */
+
+
+#include "bacula.h"
+#include "findlib/find.h"
+#include "findlib/system.h"
+            
+#ifndef MAXPATHLEN
+#define MAXPATHLEN 1000
+#endif
+
+TREE_NODE *new_tree_node(int type)
+{
+   TREE_NODE *node;
+   int size;
+
+   if (type == TN_ROOT) {
+      size = sizeof(TREE_ROOT);
+   } else {
+      size = sizeof(TREE_NODE);
+   }
+   node = (TREE_NODE *)malloc(size);
+   memset(node, 0, size);
+   node->type = type;
+   return node;
+}
+
+TREE_NODE *insert_tree_node(char *path, TREE_NODE *node, TREE_ROOT *root, TREE_NODE *parent)
+{
+   char *p, *fname;
+
+   Dmsg1(100, "insert_tree_node: %s\n", path);
+   p = strrchr(path, '/');
+   if (!p) {
+      Dmsg1(000, "No / found: %s\n", path);
+      exit(1);
+   }
+   *p = 0;
+   fname = p + 1;
+   if (!parent) {
+      parent = make_tree_path(path, root);
+   }
+   *p = '/';
+   append_tree_node(fname, node, root, parent);
+   Dmsg1(100, "insert_tree_node: parent=%s\n", parent->fname);
+   return parent;
+}
+
+TREE_NODE *make_tree_path(char *path, TREE_ROOT *root)
+{
+   TREE_NODE *parent, *sibling;
+   char *fname, *p;
+
+   Dmsg1(100, "make_tree_path: %s\n", path);
+   if (!*path) {
+      Dmsg0(100, "make_tree_path: parent=*root*\n");
+      return (TREE_NODE *)root;
+   }
+   p = strrchr(path, '/');
+   if (!p) {
+      Dmsg1(000, "No / found: %s\n", path);
+      exit(1);
+   }
+   *p = 0;
+   fname = p + 1;
+   /* Find parent */
+   parent = make_tree_path(path, root);
+   *p = '/';
+   /* Is it already a sibling? */
+   for (sibling=parent->sibling; sibling; sibling=sibling->sibling) {
+      if (strcmp(sibling->fname, fname) == 0) {
+         Dmsg1(100, "make_tree_path: found parent=%s\n", parent->fname);
+        return parent;
+      }
+   }
+   /* Must add */
+   sibling = new_tree_node(TN_NEWDIR);
+   append_tree_node(fname, sibling, root, parent);
+   parent = sibling;
+   Dmsg1(100, "make_tree_path: add parent=%s\n", parent->fname);
+   return parent;
+}  
+
+/*
+ *  Append sibling to parent's child chain
+ */
+void append_tree_node(char *fname, TREE_NODE *node, TREE_ROOT *root, TREE_NODE *parent)
+{
+   TREE_NODE *child;
+
+   Dmsg1(100, "append_tree_node: %s\n", fname);
+   node->fname = bstrdup(fname);
+   node->parent = parent;
+   if (!parent->child) {
+      parent->child = node;
+      goto item_link;
+   }
+   for (child=parent->child; child->sibling; child=child->sibling)
+      { }
+   child->sibling = node;
+
+item_link:
+   if (!root->first) {
+      root->first = node;
+      root->last = node;
+   } else {
+      root->last->next = node;
+      root->last = node;
+   }
+   return;
+}
+
+TREE_NODE *first_tree_node(TREE_ROOT *root)
+{
+   return root->first;
+}
+
+TREE_NODE *next_tree_node(TREE_NODE *node)
+{
+   return node->next;
+}
+
+
+void print_tree(char *path, TREE_NODE *tree)
+{
+   char buf[MAXPATHLEN];
+   char *termchr;
+
+   if (!tree) {
+      return;
+   }
+   switch (tree->type) {
+   case TN_DIR:
+   case TN_NEWDIR:  
+      termchr = "/";
+      break;
+   case TN_ROOT:
+   case TN_FILE:
+   default:
+      termchr = "";
+      break;
+   }
+   Dmsg3(-1, "%s/%s%s\n", path, tree->fname, termchr);
+   switch (tree->type) {
+   case TN_FILE:
+      break;
+   case TN_DIR:
+      sprintf(buf, "%s/%s", path, tree->fname);
+      print_tree(buf, tree->child);
+      break;
+   case TN_ROOT:
+      print_tree(path, tree->child);
+      break;
+   case TN_NEWDIR:  
+      sprintf(buf, "%s/%s", path, tree->fname);
+      print_tree(buf, tree->child);
+      break;
+   default:
+      Dmsg1(000, "Unknown node type %d\n", tree->type);
+   }
+   print_tree(path, tree->sibling);
+   return;
+}
+
+void free_tree(TREE_NODE *node)
+{
+   if (!node) {
+      return;
+   }
+   switch (node->type) {
+   case TN_FILE:
+      break;
+   case TN_DIR:
+   case TN_ROOT:
+   case TN_NEWDIR:  
+      free_tree(node->child);
+      break;
+   default:
+      Dmsg1(000, "Unknown node type %d\n", node->type);
+      break;
+   }
+   free_tree(node->sibling);
+   free(node->fname);
+   free(node);
+   return;
+}
+
+int tree_getpath(TREE_NODE *node, char *buf, int buf_size)
+{
+   if (!node) {
+      buf[0] = 0;
+      return 1;
+   }
+   tree_getpath(node->parent, buf, buf_size);
+   strcat(buf, node->fname);
+   if (node->type != TN_FILE) {
+      strcat(buf, "/");
+   }
+   return 1;
+}
+
+/* 
+ * Change to specified directory
+ */
+TREE_NODE *tree_cwd(char *path, TREE_ROOT *root, TREE_NODE *node)
+{
+   if (strcmp(path, ".") == 0) {
+      return node;
+   }
+   if (strcmp(path, "..") == 0) {
+      if (node->parent) {
+        return node->parent;
+      } else {
+        return node;
+      }
+   }
+   if (path[0] == '/') {
+      Dmsg0(100, "Doing absolute lookup.\n");
+      return tree_relcwd(path+1, root, (TREE_NODE *)root);
+   }
+   Dmsg0(100, "Doing relative lookup.\n");
+   return tree_relcwd(path, root, node);
+}
+
+
+TREE_NODE *tree_relcwd(char *path, TREE_ROOT *root, TREE_NODE *node)
+{
+   char *p;
+   int len;
+   TREE_NODE *cd;
+
+   if (*path == 0) {
+      return node;
+   }
+   p = strchr(path, '/');
+   if (p) {
+      len = p - path;
+   }
+   for (cd=node->child; cd; cd=cd->sibling) {
+      if (strncmp(cd->fname, path, len) == 0) {
+         Dmsg1(100, "tree_relcwd: found cd=%s\n", cd->fname);
+        break;
+      }
+   }
+   if (!cd || cd->type == TN_FILE) {
+      Dmsg1(100, "tree_relcwd: failed %s is a file.\n", cd->fname);
+      return NULL;
+   }
+   if (!p) {
+      Dmsg0(100, "tree_relcwd: no more to lookup. found.\n");
+      return cd;
+   }
+   Dmsg2(100, "recurse tree_relcwd with path=%s, cd=%s\n", p+1, cd->fname);
+   return tree_relcwd(p+1, root, cd);
+}
+
+
+
+#ifdef BUILD_TEST_PROGRAM
+
+void FillDirectoryTree(char *path, TREE_ROOT *root, TREE_NODE *parent);
+
+static uint32_t FileIndex = 0;
+/*
+ * Simple test program for tree routines
+ */
+int main(int argc, char *argv[])
+{
+    TREE_ROOT *root;
+    TREE_NODE *node;
+    char buf[MAXPATHLEN];
+
+    root = (TREE_ROOT *)new_tree_node(TN_ROOT);
+    root->fname = bstrdup("");
+
+    FillDirectoryTree("/home/kern/bacula/k", root, NULL);
+
+    for (node = first_tree_node(root); node; node=next_tree_node(node)) {
+       tree_getpath(node, buf, sizeof(buf));
+       Dmsg2(100, "%d: %s\n", node->FileIndex, buf);
+    }
+
+    node = (TREE_NODE *)root;
+    Dmsg0(000, "doing cd /home/kern/bacula/k/techlogs\n");
+    node = tree_cwd("/home/kern/bacula/k/techlogs", root, node);
+    if (node) {
+       tree_getpath(node, buf, sizeof(buf));
+       Dmsg2(100, "findex=%d: cwd=%s\n", node->FileIndex, buf);
+    }
+
+    Dmsg0(000, "doing cd /home/kern/bacula/k/src/testprogs\n");
+    node = tree_cwd("/home/kern/bacula/k/src/testprogs", root, node);
+    if (node) {
+       tree_getpath(node, buf, sizeof(buf));
+       Dmsg2(100, "findex=%d: cwd=%s\n", node->FileIndex, buf);
+    } else {
+       Dmsg0(100, "testprogs not found.\n");
+    }
+
+    free_tree((TREE_NODE *)root);
+
+    return 0;
+}
+
+void FillDirectoryTree(char *path, TREE_ROOT *root, TREE_NODE *parent)
+{
+   TREE_NODE *newparent = NULL;
+   TREE_NODE *node;
+   struct stat statbuf;
+   DIR *dp;
+   struct dirent *dir;
+   char pathbuf[MAXPATHLEN];
+   char file[MAXPATHLEN];
+   int type;
+   int i;
+   
+   Dmsg1(100, "FillDirectoryTree: %s\n", path);
+   dp = opendir(path);
+   if (!dp) {
+      return;
+   }
+   while ((dir = readdir(dp))) {
+      if (strcmp(dir->d_name, ".") == 0 || strcmp(dir->d_name, "..") == 0) {
+        continue;
+      }
+      strcpy(file, dir->d_name);
+      snprintf(pathbuf, MAXPATHLEN-1, "%s/%s", path, file);
+      if (lstat(pathbuf, &statbuf) < 0) {
+         printf("lstat() failed. ERR=%s\n", strerror(errno));
+        continue;
+      }
+//      printf("got file=%s, pathbuf=%s\n", file, pathbuf);
+      type = TN_FILE;
+      if (S_ISLNK(statbuf.st_mode))
+        type =  TN_FILE;  /* link */
+      else if (S_ISREG(statbuf.st_mode))
+        type = TN_FILE;
+      else if (S_ISDIR(statbuf.st_mode)) {
+        type = TN_DIR;
+      } else if (S_ISCHR(statbuf.st_mode))
+        type = TN_FILE; /* char dev */
+      else if (S_ISBLK(statbuf.st_mode))
+        type = TN_FILE; /* block dev */
+      else if (S_ISFIFO(statbuf.st_mode))
+        type = TN_FILE; /* fifo */
+      else if (S_ISSOCK(statbuf.st_mode))
+        type = TN_FILE; /* sock */
+      else {
+        type = TN_FILE;
+         printf("Unknown file type: 0x%x\n", statbuf.st_mode);
+      }
+
+      Dmsg2(100, "Doing: %d %s\n", type, pathbuf);
+      node = new_tree_node(type);
+      node->FileIndex = ++FileIndex;
+      parent = insert_tree_node(pathbuf, node, root, parent);
+      if (S_ISDIR(statbuf.st_mode) && !S_ISLNK(statbuf.st_mode)) {
+         Dmsg2(100, "calling fill. pathbuf=%s, file=%s\n", pathbuf, file);
+        FillDirectoryTree(pathbuf, root, node);
+      }
+   }
+   closedir(dp);
+}
+#endif
diff --git a/bacula/src/lib/tree.h b/bacula/src/lib/tree.h
new file mode 100644 (file)
index 0000000..cbc80c1
--- /dev/null
@@ -0,0 +1,70 @@
+/*
+ * Directory tree build/traverse routines
+ * 
+ *    Kern Sibbald, June MMII
+ *
+*/
+/*
+   Copyright (C) 2002 Kern Sibbald and John Walker
+
+   This program is free software; you can redistribute it and/or
+   modify it under the terms of the GNU General Public License as
+   published by the Free Software Foundation; either version 2 of
+   the License, or (at your option) any later version.
+
+   This program is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+   General Public License for more details.
+
+   You should have received a copy of the GNU General Public
+   License along with this program; if not, write to the Free
+   Software Foundation, Inc., 59 Temple Place - Suite 330, Boston,
+   MA 02111-1307, USA.
+
+ */
+
+struct s_tree_node {
+   char *fname;                      /* file name */
+   uint32_t FileIndex;               /* file index */
+   int type;                         /* node type */
+   struct s_tree_node *parent;
+   struct s_tree_node *sibling;
+   struct s_tree_node *child;
+   struct s_tree_node *next;         /* next hash of FileIndex */
+};
+typedef struct s_tree_node TREE_NODE;
+
+struct s_tree_root {
+   char *fname;                      /* file name */
+   uint32_t FileIndex;               /* file index */
+   int type;                         /* node type */
+   struct s_tree_node *parent;
+   struct s_tree_node *sibling;
+   struct s_tree_node *child;
+   struct s_tree_node *next;         /* next hash of FileIndex */
+
+   /* The above ^^^ must be identical to a TREE_NODE structure */
+   struct s_tree_node *first;        /* first entry in the tree */
+   struct s_tree_node *last;         /* last entry in tree */
+};
+typedef struct s_tree_root TREE_ROOT;
+
+/* type values */
+#define TN_ROOT    1                 /* root node */
+#define TN_NEWDIR  2                 /* created directory to fill path */
+#define TN_DIR    3                  /* directory entry */
+#define TN_FILE    4                 /* file entry */
+
+TREE_NODE *new_tree_node(int type);
+TREE_NODE *insert_tree_node(char *path, TREE_NODE *node, TREE_ROOT *root, TREE_NODE *parent);
+TREE_NODE *make_tree_path(char *path, TREE_ROOT *root);
+TREE_NODE *first_tree_node(TREE_ROOT *root);
+TREE_NODE *next_tree_node(TREE_NODE *node);
+TREE_NODE *tree_cwd(char *path, TREE_ROOT *root, TREE_NODE *node);
+TREE_NODE *tree_relcwd(char *path, TREE_ROOT *root, TREE_NODE *node);
+void append_tree_node(char *fname, TREE_NODE *node, TREE_ROOT *root, TREE_NODE *parent);
+void print_tree(char *path, TREE_NODE *root);   
+void free_tree(TREE_NODE *node);
+int tree_getpath(TREE_NODE *node, char *buf, int buf_size);
+
index 6e08841214f47a1907ea3c164f2d9b6a7850f5b0..be8ef84d379dfa79851415b062f8ab3f433ab1cf 100644 (file)
@@ -53,6 +53,12 @@ typedef struct s_bsr_sessid {
    int found;
 } BSR_SESSID;
 
+typedef struct s_bsr_sesstime {
+   struct s_bsr_sesstime *next;
+   uint32_t sesstime;
+   int found;
+} BSR_SESSTIME;
+
 typedef struct s_bsr_volfile {
    struct s_bsr_volfile *next;
    uint32_t sfile;                    /* start file */
@@ -60,13 +66,6 @@ typedef struct s_bsr_volfile {
    int found;
 } BSR_VOLFILE;
 
-
-typedef struct s_bsr_sesstime {
-   struct s_bsr_sesstime *next;
-   uint32_t sesstime;
-   int found;
-} BSR_SESSTIME;
-
 typedef struct s_bsr_findex {
    struct s_bsr_findex *next;
    int32_t findex;                    /* start file index */
@@ -102,15 +101,15 @@ typedef struct s_bsr {
    struct s_bsr *next;                /* pointer to next one */
    int           done;                /* set when everything found */
    char         *VolumeName;
-   BSR_CLIENT   *client;
-   BSR_JOB      *job;
-   BSR_SESSID   *sessid;
+   BSR_VOLFILE  *volfile;
    BSR_SESSTIME *sesstime;
-   BSR_FINDEX   *FileIndex;
+   BSR_SESSID   *sessid;
    BSR_JOBID    *JobId;
+   BSR_JOB      *job;
+   BSR_CLIENT   *client;
+   BSR_FINDEX   *FileIndex;
    BSR_JOBTYPE  *JobType;
    BSR_JOBLEVEL *JobLevel;
-   BSR_VOLFILE  *volfile;
    FF_PKT *ff;                        /* include/exclude */
 } BSR;
 
index 2038f5ef4564eab578961572b4a7b7f53bb50458..3eb5387ca7a4c0a348f124c5ce17d53d65ddfbd9 100755 (executable)
 /* Forward references */
 static int match_sesstime(BSR_SESSTIME *sesstime, DEV_RECORD *rec);
 static int match_sessid(BSR_SESSID *sessid, DEV_RECORD *rec);
-static int match_client(BSR_CLIENT *client, SESSION_LABEL *sesrec);
-static int match_job(BSR_JOB *job, SESSION_LABEL *sesrec);
-static int match_job_type(BSR_JOBTYPE *job_type, SESSION_LABEL *sesrec);
-static int match_job_level(BSR_JOBLEVEL *job_level, SESSION_LABEL *sesrec);
-static int match_jobid(BSR_JOBID *jobid, SESSION_LABEL *sesrec);
-static int match_file_index(BSR_FINDEX *findex, DEV_RECORD *rec);
-static int match_one_bsr(BSR *bsr, DEV_RECORD *rec, VOLUME_LABEL *volrec, SESSION_LABEL *sesrec);
+static int match_client(BSR_CLIENT *client, SESSION_LABEL *sessrec);
+static int match_job(BSR_JOB *job, SESSION_LABEL *sessrec);
+static int match_job_type(BSR_JOBTYPE *job_type, SESSION_LABEL *sessrec);
+static int match_job_level(BSR_JOBLEVEL *job_level, SESSION_LABEL *sessrec);
+static int match_jobid(BSR_JOBID *jobid, SESSION_LABEL *sessrec);
+static int match_findex(BSR_FINDEX *findex, DEV_RECORD *rec);
+static int match_volfile(BSR_VOLFILE *volfile, DEV_RECORD *rec);
+static int match_one_bsr(BSR *bsr, DEV_RECORD *rec, VOLUME_LABEL *volrec, SESSION_LABEL *sessrec);
 
 /*********************************************************************
  *
  *     Match Bootstrap records
  *
  */
-int match_bsr(BSR *bsr, DEV_RECORD *rec, VOLUME_LABEL *volrec, SESSION_LABEL *sesrec)
+int match_bsr(BSR *bsr, DEV_RECORD *rec, VOLUME_LABEL *volrec, SESSION_LABEL *sessrec)
 {
    if (!bsr) {
       return 0;
    }
-   if (match_one_bsr(bsr, rec, volrec, sesrec)) {
+   if (match_one_bsr(bsr, rec, volrec, sessrec)) {
       return 1;
    }
-   return match_bsr(bsr->next, rec, volrec, sesrec);
+   return match_bsr(bsr->next, rec, volrec, sessrec);
 }
 
-static int match_one_bsr(BSR *bsr, DEV_RECORD *rec, VOLUME_LABEL *volrec, SESSION_LABEL *sesrec)
+static int match_one_bsr(BSR *bsr, DEV_RECORD *rec, VOLUME_LABEL *volrec, SESSION_LABEL *sessrec)
 {
    if (strcmp(bsr->VolumeName, volrec->VolName) != 0) {
       return 0;
    }
-   if (!match_client(bsr->client, sesrec)) {
+   if (!match_volfile(bsr->volfile, rec)) {
+      return 0;
+   }
+   if (!match_sesstime(bsr->sesstime, rec)) {
       return 0;
    }
    if (!match_sessid(bsr->sessid, rec)) {
       return 0;
    }
-   if (!match_sesstime(bsr->sesstime, rec)) {
+   if (!match_jobid(bsr->JobId, sessrec)) {
       return 0;
    }
-   if (!match_job(bsr->job, sesrec)) {
+   if (!match_job(bsr->job, sessrec)) {
       return 0;
    }
-   if (!match_file_index(bsr->FileIndex, rec)) {
+   if (!match_client(bsr->client, sessrec)) {
       return 0;
    }
-   if (!match_job_type(bsr->JobType, sesrec)) {
+   if (!match_findex(bsr->FileIndex, rec)) {
       return 0;
    }
-   if (!match_job_level(bsr->JobLevel, sesrec)) {
+   if (!match_job_type(bsr->JobType, sessrec)) {
       return 0;
    }
-   if (!match_jobid(bsr->JobId, sesrec)) {
+   if (!match_job_level(bsr->JobLevel, sessrec)) {
       return 0;
    }
    return 1;
 }
 
-static int match_client(BSR_CLIENT *client, SESSION_LABEL *sesrec)
+static int match_client(BSR_CLIENT *client, SESSION_LABEL *sessrec)
 {
    if (!client) {
       return 1;                      /* no specification matches all */
    }
-   if (strcmp(client->ClientName, sesrec->ClientName) == 0) {
+   if (strcmp(client->ClientName, sessrec->ClientName) == 0) {
       return 1;
    }
    if (client->next) {
-      return match_client(client->next, sesrec);
+      return match_client(client->next, sessrec);
    }
    return 0;
 }
 
-static int match_job(BSR_JOB *job, SESSION_LABEL *sesrec)
+static int match_job(BSR_JOB *job, SESSION_LABEL *sessrec)
 {
    if (!job) {
       return 1;                      /* no specification matches all */
    }
-   if (strcmp(job->Job, sesrec->Job) == 0) {
+   if (strcmp(job->Job, sessrec->Job) == 0) {
       job->found++;
       return 1;
    }
    if (job->next) {
-      return match_job(job->next, sesrec);
+      return match_job(job->next, sessrec);
    }
    return 0;
 }
 
 
-static int match_job_type(BSR_JOBTYPE *job_type, SESSION_LABEL *sesrec)
+static int match_job_type(BSR_JOBTYPE *job_type, SESSION_LABEL *sessrec)
 {
    if (!job_type) {
       return 1;                      /* no specification matches all */
    }
-   if (job_type->JobType == sesrec->JobType) {
+   if (job_type->JobType == sessrec->JobType) {
       return 1;
    }
    if (job_type->next) {
-      return match_job_type(job_type->next, sesrec);
+      return match_job_type(job_type->next, sessrec);
    }
    return 0;
 }
 
-static int match_job_level(BSR_JOBLEVEL *job_level, SESSION_LABEL *sesrec)
+static int match_job_level(BSR_JOBLEVEL *job_level, SESSION_LABEL *sessrec)
 {
    if (!job_level) {
       return 1;                      /* no specification matches all */
    }
-   if (job_level->JobLevel == sesrec->JobLevel) {
+   if (job_level->JobLevel == sessrec->JobLevel) {
       return 1;
    }
    if (job_level->next) {
-      return match_job_level(job_level->next, sesrec);
+      return match_job_level(job_level->next, sessrec);
    }
    return 0;
 }
 
-static int match_jobid(BSR_JOBID *jobid, SESSION_LABEL *sesrec)
+static int match_jobid(BSR_JOBID *jobid, SESSION_LABEL *sessrec)
 {
    if (!jobid) {
       return 1;                      /* no specification matches all */
    }
-   if (jobid->JobId == sesrec->JobId) {
+   if (jobid->JobId >= sessrec->JobId && jobid->JobId2 <= sessrec->JobId) {
       jobid->found++;
       return 1;
    }
    if (jobid->next) {
-      return match_jobid(jobid->next, sesrec);
+      return match_jobid(jobid->next, sessrec);
+   }
+   return 0;
+}
+
+
+static int match_volfile(BSR_VOLFILE *volfile, DEV_RECORD *rec)
+{
+   if (!volfile) {
+      return 1;                      /* no specification matches all */
+   }
+   if (volfile->sfile >= rec->File && volfile->efile <= rec->File) {
+      volfile->found++;
+      return 1;
+   }
+   if (volfile->next) {
+      return match_volfile(volfile->next, rec);
    }
    return 0;
 }
 
 
-static int match_file_index(BSR_FINDEX *findex, DEV_RECORD *rec)
+static int match_findex(BSR_FINDEX *findex, DEV_RECORD *rec)
 {
    if (!findex) {
       return 1;                      /* no specification matches all */
@@ -174,7 +194,7 @@ static int match_file_index(BSR_FINDEX *findex, DEV_RECORD *rec)
       return 1;
    }
    if (findex->next) {
-      return match_file_index(findex->next, rec);
+      return match_findex(findex->next, rec);
    }
    return 0;
 }
index 0a32e9cdc825c5adf9fa01408a06d3c3c59390ab..91ee185c11212564eb33e9598a20469b232c1da9 100755 (executable)
@@ -21,7 +21,6 @@
 
    You should have received a copy of the GNU General Public
    License along with this program; if not, write to the Free
-   Software Foundation, Inc., 59 Temple Place - Suite 330, Boston,
    MA 02111-1307, USA.
 
  */
@@ -38,7 +37,7 @@ static BSR *store_job(LEX *lc, BSR *bsr);
 static BSR *store_jobid(LEX *lc, BSR *bsr);
 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_findex(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);
@@ -55,7 +54,7 @@ struct kw_items items[] = {
    {"client", store_client},
    {"job", store_job},
    {"jobid", store_jobid},
-   {"fileindex", store_file_index},
+   {"fileindex", store_findex},
    {"jobtype", store_jobtype},
    {"joblevel", store_joblevel},
    {"volsessionid", store_sessid},
@@ -88,17 +87,14 @@ BSR *parse_bsr(char *cf)
 
    Dmsg0(200, "Enter parse_bsf()\n");
    lc = lex_open_file(lc, cf);
-   while ((token=lex_get_token(lc)) != T_EOF) {
+   while ((token=lex_get_token(lc, T_ALL)) != T_EOF) {
       Dmsg1(150, "parse got token=%s\n", lex_tok_to_str(token));
       if (token == T_EOL) {
         continue;
       }
-      if (token != T_IDENTIFIER) {
-         scan_err1(lc, "Expected a keyword identifier, got: %s", lc->str);
-      }
       for (i=0; items[i].name; i++) {
         if (strcasecmp(items[i].name, lc->str) == 0) {
-           token = lex_get_token(lc);
+           token = lex_get_token(lc, T_ALL);
             Dmsg1 (150, "in T_IDENT got token=%s\n", lex_tok_to_str(token));
            if (token != T_EQUALS) {
                scan_err1(lc, "expected an equals, got: %s", lc->str);
@@ -125,19 +121,12 @@ static BSR *store_vol(LEX *lc, BSR *bsr)
 {
    int token;
     
-   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 {
-      if (bsr->VolumeName) {
-        bsr->next = new_bsr();
-        bsr = bsr->next;
-      }
-      bsr->VolumeName = bstrdup(lc->str);
+   token = lex_get_token(lc, T_NAME);
+   if (bsr->VolumeName) {
+      bsr->next = new_bsr();
+      bsr = bsr->next;
    }
+   bsr->VolumeName = bstrdup(lc->str);
    scan_to_eol(lc);
    return bsr;
 }
@@ -148,8 +137,7 @@ static BSR *store_client(LEX *lc, BSR *bsr)
    BSR_CLIENT *client;
     
    for (;;) {
-      lc->expect = T_NAME;
-      token = lex_get_token(lc);
+      token = lex_get_token(lc, T_NAME);
       client = (BSR_CLIENT *)malloc(sizeof(BSR_CLIENT));
       memset(client, 0, sizeof(BSR_CLIENT));
       client->ClientName = bstrdup(lc->str);
@@ -158,22 +146,15 @@ static BSR *store_client(LEX *lc, BSR *bsr)
         bsr->client = client;
       } else {
         BSR_CLIENT *bc = bsr->client;
-        for ( ;; ) {
-           if (bc->next) {
-              bc = bc->next;
-           } else {
-              bc->next = client;
-              break;
-           }
-        }
+        for ( ;bc->next; bc=bc->next)  
+           { }
+        bc->next = client;
       }
-      lc->expect = 0;
-      token = lex_get_token(lc);
+      token = lex_get_token(lc, T_ALL);
       if (token != T_COMMA) {
         break;
       }
    }
-// scan_to_eol(lc);
    return bsr;
 }
 
@@ -182,33 +163,36 @@ static BSR *store_job(LEX *lc, BSR *bsr)
    int token;
    BSR_JOB *job;
     
-   lc->expect = T_NAME;
-   token = lex_get_token(lc);
-   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;
+   for (;;) {
+      token = lex_get_token(lc, T_NAME);
+      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;
+      }
+      token = lex_get_token(lc, T_ALL);
+      if (token != T_COMMA) {
+        break;
+      }
    }
-   scan_to_eol(lc);
    return bsr;
 }
 
-static BSR *store_file_index(LEX *lc, BSR *bsr)
+static BSR *store_findex(LEX *lc, BSR *bsr)
 {
    int token;
    BSR_FINDEX *findex;
 
    for (;;) {
-      lc->expect = T_PINT32_RANGE;
-      token = lex_get_token(lc);
+      token = lex_get_token(lc, T_PINT32_RANGE);
       findex = (BSR_FINDEX *)malloc(sizeof(BSR_FINDEX));
       memset(findex, 0, sizeof(BSR_FINDEX));
       findex->findex = lc->pint32_val;
@@ -220,16 +204,14 @@ static BSR *store_file_index(LEX *lc, BSR *bsr)
         /* Add to end of chain */
         BSR_FINDEX *bs = bsr->FileIndex;
         for ( ;bs->next; bs=bs->next)
-          {  }
+           {  }
         bs->next = findex;
       }
-      lc->expect = 0;
-      token = lex_get_token(lc);
+      token = lex_get_token(lc, T_ALL);
       if (token != T_COMMA) {
         break;
       }
    }
-// scan_to_eol(lc);
    return bsr;
 }
 
@@ -240,8 +222,7 @@ static BSR *store_jobid(LEX *lc, BSR *bsr)
    BSR_JOBID *jobid;
 
    for (;;) {
-      lc->expect = T_PINT32_RANGE;
-      token = lex_get_token(lc);
+      token = lex_get_token(lc, T_PINT32_RANGE);
       jobid = (BSR_JOBID *)malloc(sizeof(BSR_JOBID));
       memset(jobid, 0, sizeof(BSR_JOBID));
       jobid->JobId = lc->pint32_val;
@@ -253,16 +234,14 @@ static BSR *store_jobid(LEX *lc, BSR *bsr)
         /* Add to end of chain */
         BSR_JOBID *bs = bsr->JobId;
         for ( ;bs->next; bs=bs->next)
-          {  }
+           {  }
         bs->next = jobid;
       }
-      lc->expect = 0;
-      token = lex_get_token(lc);
+      token = lex_get_token(lc, T_ALL);
       if (token != T_COMMA) {
         break;
       }
    }
-// scan_to_eol(lc);
    return bsr;
 }
 
@@ -293,8 +272,7 @@ static BSR *store_volfile(LEX *lc, BSR *bsr)
    BSR_VOLFILE *volfile;
 
    for (;;) {
-      lc->expect = T_PINT32_RANGE;
-      token = lex_get_token(lc);
+      token = lex_get_token(lc, T_PINT32_RANGE);
       volfile = (BSR_VOLFILE *)malloc(sizeof(BSR_VOLFILE));
       memset(volfile, 0, sizeof(BSR_VOLFILE));
       volfile->sfile = lc->pint32_val;
@@ -306,16 +284,14 @@ static BSR *store_volfile(LEX *lc, BSR *bsr)
         /* 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);
+      token = lex_get_token(lc, T_ALL);
       if (token != T_COMMA) {
         break;
       }
    }
-// scan_to_eol(lc);
    return bsr;
 }
 
@@ -327,8 +303,7 @@ static BSR *store_sessid(LEX *lc, BSR *bsr)
    BSR_SESSID *sid;
 
    for (;;) {
-      lc->expect = T_PINT32_RANGE;
-      token = lex_get_token(lc);
+      token = lex_get_token(lc, T_PINT32_RANGE);
       sid = (BSR_SESSID *)malloc(sizeof(BSR_SESSID));
       memset(sid, 0, sizeof(BSR_SESSID));
       sid->sessid = lc->pint32_val;
@@ -340,16 +315,14 @@ static BSR *store_sessid(LEX *lc, BSR *bsr)
         /* Add to end of chain */
         BSR_SESSID *bs = bsr->sessid;
         for ( ;bs->next; bs=bs->next)
-          {  }
+           {  }
         bs->next = sid;
       }
-      lc->expect = 0;
-      token = lex_get_token(lc);
+      token = lex_get_token(lc, T_ALL);
       if (token != T_COMMA) {
         break;
       }
    }
-// scan_to_eol(lc);
    return bsr;
 }
 
@@ -358,22 +331,26 @@ static BSR *store_sesstime(LEX *lc, BSR *bsr)
    int token;
    BSR_SESSTIME *stime;
 
-   lc->expect = T_PINT32;
-   token = lex_get_token(lc);
-   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 {
-      /* Add to end of chain */
-      BSR_SESSTIME *bs = bsr->sesstime;
-      for ( ;bs->next; bs=bs->next)
-        { }
-      bs->next = stime;
+   for (;;) {
+      token = lex_get_token(lc, T_PINT32);
+      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 {
+        /* Add to end of chain */
+        BSR_SESSTIME *bs = bsr->sesstime;
+        for ( ;bs->next; bs=bs->next)
+           { }
+        bs->next = stime;
+      }
+      token = lex_get_token(lc, T_ALL);
+      if (token != T_COMMA) {
+        break;
+      }
    }
-   scan_to_eol(lc);
    return bsr;
 }
 
@@ -391,79 +368,71 @@ static BSR *store_exclude(LEX *lc, BSR *bsr)
 
 void dump_volfile(BSR_VOLFILE *volfile)
 {
-   if (!volfile) {
-      return;
+   if (volfile) {
+      Dmsg2(-1, "VolFile     : %u-%u\n", volfile->sfile, volfile->efile);
+      dump_volfile(volfile->next);
    }
-   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);
+   if (FileIndex) {
+      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);
    }
-   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);
+   if (jobid) {
+      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);
    }
-   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);
+   if (sessid) {
+      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);
    }
-   dump_sessid(sessid->next);
 }
 
 
 void dump_client(BSR_CLIENT *client)
 {
-   if (!client) {
-      return;
+   if (client) {
+      Dmsg1(-1, "Client      : %s\n", client->ClientName);
+      dump_client(client->next);
    }
-   Dmsg1(-1, "Client      : %s\n", client->ClientName);
-   dump_client(client->next);
 }
 
 void dump_job(BSR_JOB *job)
 {
-   if (!job) {
-      return;
+   if (job) {
+      Dmsg1(-1, "Job          : %s\n", job->Job);
+      dump_job(job->next);
    }
-   Dmsg1(-1, "Job          : %s\n", job->Job);
-   dump_job(job->next);
 }
 
 void dump_sesstime(BSR_SESSTIME *sesstime)
 {
-   if (!sesstime) {
-      return;
+   if (sesstime) {
+      Dmsg1(-1, "SessTime    : %u\n", sesstime->sesstime);
+      dump_sesstime(sesstime->next);
    }
-   Dmsg1(-1, "SessTime    : %u\n", sesstime->sesstime);
-   dump_sesstime(sesstime->next);
 }
 
 
@@ -503,11 +472,10 @@ void dump_bsr(BSR *bsr)
 
 static void free_bsr_item(BSR *bsr)
 {
-   if (!bsr) {
-      return;
+   if (bsr) {
+      free_bsr_item(bsr->next);
+      free(bsr);
    }
-   free_bsr_item(bsr->next);
-   free(bsr);
 }
 
 void free_bsr(BSR *bsr)
@@ -519,6 +487,11 @@ void free_bsr(BSR *bsr)
    free_bsr_item((BSR *)bsr->sessid);
    free_bsr_item((BSR *)bsr->sesstime);
    free_bsr_item((BSR *)bsr->volfile);
+   free_bsr_item((BSR *)bsr->JobId);
+   free_bsr_item((BSR *)bsr->job);
+   free_bsr_item((BSR *)bsr->FileIndex);
+   free_bsr_item((BSR *)bsr->JobType);
+   free_bsr_item((BSR *)bsr->JobLevel);
    if (bsr->VolumeName) {
       free(bsr->VolumeName);
    }
index 5ed343aff5bc08c264908ad3e318fabd24ea3c4d..d7dc3eb4537efe18e6514172bc17c5df67060412 100644 (file)
@@ -136,6 +136,8 @@ int read_record(DEVICE *dev, DEV_BLOCK *block, DEV_RECORD *record)
    Dmsg4(90, "read_record FI=%s SessId=%d Strm=%s len=%d\n",
              FI_to_ascii(record->FileIndex), record->VolSessionId, 
              stream_to_ascii(record->Stream), record->data_len);
+   record->File = dev->file;
+   record->Block = dev->block_num;
    return 1;
 }
 
index 2d88056fa22e42fbdfbf5afcc7f532c42fd214d7..4e8919b3b7c92585c8c9000af5ad13103c6f3cfe 100644 (file)
@@ -63,8 +63,11 @@ typedef struct s_record_hdr {
  */
 typedef struct s_dev_rec {
    int      sync;                     /* synchronous */
-   uint32_t File;                     /* File number, returned if sync set */
-   uint32_t Block;                    /* Block number, returned if sync set */
+   /* File and Block are always returned on reading records, but
+    *  only returned on writing if sync is set (obviously).
+    */
+   uint32_t File;                     /* File number */
+   uint32_t Block;                    /* Block number */
    uint32_t VolSessionId;             /* sequential id within this session */
    uint32_t VolSessionTime;           /* session start time */
    int32_t  FileIndex;                /* sequential file number */
index 073aee4e8172284366a406f4902700d33690b8f6..f0e78b6b84e356d786c5a6b4311471bf2dee11a3 100644 (file)
@@ -1,8 +1,8 @@
 /* */
 #define VERSION "1.22"
 #define VSTRING "1"
-#define DATE    "19 June 2002"
-#define LSMDATE "19Jun02"
+#define DATE    "20 June 2002"
+#define LSMDATE "20Jun02"
 
 /* Debug flags */
 #define DEBUG 1