]> git.sur5r.net Git - bacula/bacula/commitdiff
Implement new Finclude/Fexclude -- drop FileOptions
authorKern Sibbald <kern@sibbald.com>
Mon, 3 Mar 2003 11:52:10 +0000 (11:52 +0000)
committerKern Sibbald <kern@sibbald.com>
Mon, 3 Mar 2003 11:52:10 +0000 (11:52 +0000)
git-svn-id: https://bacula.svn.sourceforge.net/svnroot/bacula/trunk@364 91ce42f0-d328-0410-95d8-f526ca767f89

bacula/src/dird/Makefile.in
bacula/src/dird/dird_conf.c
bacula/src/dird/dird_conf.h
bacula/src/dird/fd_cmds.c
bacula/src/dird/inc_conf.c [new file with mode: 0644]
bacula/src/lib/parse_conf.c
bacula/src/lib/parse_conf.h
bacula/src/version.h

index 976592130dc4f0706a17605d4097f83e86a52a2e..69d15a2172208cb45ae0d20da1898130709e7996 100644 (file)
@@ -25,7 +25,7 @@ dummy:
 SVRSRCS = dird.c authenticate.c autoprune.c \
          backup.c \
          catreq.c dird_conf.c \
-         fd_cmds.c getmsg.c job.c \
+         fd_cmds.c getmsg.c inc_conf.c job.c \
          mountreq.c msgchan.c newvol.c \
          recycle.c restore.c run_conf.c \
          scheduler.c sql_cmds.c \
@@ -38,7 +38,7 @@ SVRSRCS = dird.c authenticate.c autoprune.c \
 SVROBJS = dird.o authenticate.o autoprune.o \
          backup.o \
          catreq.o dird_conf.o \
-         fd_cmds.o getmsg.o job.o \
+         fd_cmds.o getmsg.o inc_conf.o job.o \
          mountreq.o msgchan.o newvol.o \
          recycle.o restore.o run_conf.o \
          scheduler.o sql_cmds.o \
index 088b9e23073ecbf75a78b317012d7bbe402c842f..844c7b48319eef8432e1e5389d015c162f97c670 100644 (file)
@@ -54,18 +54,17 @@ pthread_mutex_t res_mutex =  PTHREAD_MUTEX_INITIALIZER;
 
 /* Imported subroutines */
 extern void store_run(LEX *lc, struct res_items *item, int index, int pass);
+extern void store_finc(LEX *lc, struct res_items *item, int index, int pass);
+extern void store_inc(LEX *lc, struct res_items *item, int index, int pass);
 
 
 /* Forward referenced subroutines */
 
-static void store_inc(LEX *lc, struct res_items *item, int index, int pass);
-static void store_match(LEX *lc, struct res_items *item, int index, int pass);
 static void store_backup(LEX *lc, struct res_items *item, int index, int pass);
 static void store_restore(LEX *lc, struct res_items *item, int index, int pass);
 static void store_jobtype(LEX *lc, struct res_items *item, int index, int pass);
 static void store_level(LEX *lc, struct res_items *item, int index, int pass);
 static void store_replace(LEX *lc, struct res_items *item, int index, int pass);
-static void store_opts(LEX *lc, struct res_items *item, int index, int pass);
 
 
 /* We build the current resource here as we are
@@ -201,7 +200,9 @@ static struct res_items fs_items[] = {
    {"name",        store_name, ITEM(res_fs.hdr.name), 0, ITEM_REQUIRED, 0},
    {"description", store_str,  ITEM(res_fs.hdr.desc), 0, 0, 0},
    {"include",     store_inc,  NULL,                  0, 0, 0},
+   {"finclude",    store_finc, NULL,                  0, ITEM_NO_EQUALS, 0},
    {"exclude",     store_inc,  NULL,                  1, 0, 0},
+   {"fexclude",    store_finc, NULL,                  1, ITEM_NO_EQUALS, 0},
    {NULL,         NULL,       NULL,                  0, 0, 0} 
 };
 
@@ -266,27 +267,6 @@ static struct res_items counter_items[] = {
 };
 
 
-/* 
- * FileOptions Resource
- *   name            handler     value                        code flags default_value
- */
-static struct res_items fo_items[] = {
-   {"name",            store_name,    ITEM(res_fopts.hdr.name),    0, ITEM_REQUIRED, 0},
-   {"description",     store_str,     ITEM(res_fopts.hdr.desc),    0, 0, 0},
-   {"compression",     store_opts,    ITEM(res_fopts.opts),        0, 0, 0},
-   {"signature",       store_opts,    ITEM(res_fopts.opts),        0, 0, 0},
-   {"verify",          store_opts,    ITEM(res_fopts.opts),        0, 0, 0},
-   {"onefs",           store_opts,    ITEM(res_fopts.opts),        0, 0, 0},
-   {"recurse",         store_opts,    ITEM(res_fopts.opts),        0, 0, 0},
-   {"sparse",          store_opts,    ITEM(res_fopts.opts),        0, 0, 0},
-   {"readfifo",        store_opts,    ITEM(res_fopts.opts),        0, 0, 0},
-   {"replace",         store_replace, ITEM(res_fopts.replace),     0, 0, 0},
-   {"match",           store_match,   ITEM(res_fopts.match),       0, 0, 0},
-   {NULL, NULL, NULL, 0, 0, 0} 
-};
-
-
-
 /* Message resource */
 extern struct res_items msgs_items[];
 
@@ -308,7 +288,6 @@ struct s_res resources[] = {
    {"pool",          pool_items,  R_POOL,      NULL},
    {"messages",      msgs_items,  R_MSGS,      NULL},
    {"counter",       counter_items, R_COUNTER, NULL},
-   {"fileoptions",   fo_items,    R_FILEOPTIONS, NULL},
    {NULL,           NULL,        0,           NULL}
 };
 
@@ -370,77 +349,6 @@ struct s_kw ReplaceOptions[] = {
    {NULL,              0}
 };
 
-
-
-/* Define FileSet KeyWord values */
-
-#define INC_KW_NONE        0
-#define INC_KW_COMPRESSION  1
-#define INC_KW_SIGNATURE    2
-#define INC_KW_ENCRYPTION   3
-#define INC_KW_VERIFY      4
-#define INC_KW_ONEFS       5
-#define INC_KW_RECURSE     6
-#define INC_KW_SPARSE      7
-#define INC_KW_REPLACE     8         /* restore options */
-#define INC_KW_READFIFO     9        /* Causes fifo data to be read */
-#define INC_KW_FILEOPTIONS 10        /* file options */
-
-/* Include keywords -- these are keywords that can appear
- *    in the options lists of an include ( Include = compression= ...)
- */
-static struct s_kw FS_option_kw[] = {
-   {"compression", INC_KW_COMPRESSION},
-   {"signature",   INC_KW_SIGNATURE},
-   {"encryption",  INC_KW_ENCRYPTION},
-   {"verify",      INC_KW_VERIFY},
-   {"onefs",       INC_KW_ONEFS},
-   {"recurse",     INC_KW_RECURSE},
-   {"sparse",      INC_KW_SPARSE},
-   {"replace",     INC_KW_REPLACE},
-   {"readfifo",    INC_KW_READFIFO},
-   {"fileoptions", INC_KW_FILEOPTIONS},
-   {NULL,         0}
-};
-
-/* Options for FileSet keywords */
-
-struct s_fs_opt {
-   char *name;
-   int keyword;
-   char *option;
-};
-
-/* Options permitted for each keyword and resulting value */
-static struct s_fs_opt FS_options[] = {
-   {"md5",      INC_KW_SIGNATURE,    "M"},
-   {"sha1",     INC_KW_SIGNATURE,    "S"},
-   {"gzip",     INC_KW_COMPRESSION,  "Z6"},
-   {"gzip1",    INC_KW_COMPRESSION,  "Z1"},
-   {"gzip2",    INC_KW_COMPRESSION,  "Z2"},
-   {"gzip3",    INC_KW_COMPRESSION,  "Z3"},
-   {"gzip4",    INC_KW_COMPRESSION,  "Z4"},
-   {"gzip5",    INC_KW_COMPRESSION,  "Z5"},
-   {"gzip6",    INC_KW_COMPRESSION,  "Z6"},
-   {"gzip7",    INC_KW_COMPRESSION,  "Z7"},
-   {"gzip8",    INC_KW_COMPRESSION,  "Z8"},
-   {"gzip9",    INC_KW_COMPRESSION,  "Z9"},
-   {"blowfish", INC_KW_ENCRYPTION,    "B"},   /* ***FIXME*** not implemented */
-   {"3des",     INC_KW_ENCRYPTION,    "3"},   /* ***FIXME*** not implemented */
-   {"yes",      INC_KW_ONEFS,         "0"},
-   {"no",       INC_KW_ONEFS,         "f"},
-   {"yes",      INC_KW_RECURSE,       "0"},
-   {"no",       INC_KW_RECURSE,       "h"},
-   {"yes",      INC_KW_SPARSE,        "s"},
-   {"no",       INC_KW_SPARSE,        "0"},
-   {"always",   INC_KW_REPLACE,       "a"},
-   {"ifnewer",  INC_KW_REPLACE,       "w"},
-   {"never",    INC_KW_REPLACE,       "n"},
-   {"yes",      INC_KW_READFIFO,      "r"},
-   {"no",       INC_KW_READFIFO,      "0"},
-   {NULL,      0,                   0}
-};
-
 char *level_to_str(int level)
 {
    int i;
@@ -457,8 +365,6 @@ char *level_to_str(int level)
    return str;
 }
 
-
-
 /* Dump contents of resource */
 void dump_resource(int type, RES *reshdr, void sendit(void *sock, char *fmt, ...), void *sock)
 {
@@ -671,14 +577,6 @@ next_run:
         if (res->res_msgs.operator_cmd) 
             sendit(sock, "      opcmd=%s\n", res->res_msgs.operator_cmd);
         break;
-      case R_FILEOPTIONS:
-         sendit(sock, "FileOptions: name=%s\n", res->res_msgs.hdr.name);
-         sendit(sock, "      opts=%s replace=%c\n", res->res_fopts.opts,
-               res->res_fopts.replace);
-        for (int i=0; i < res->res_fopts.num_match; i++) {
-            sendit(sock, "      match=%s\n", res->res_fopts.match[i]);
-        }
-        break;
       default:
          sendit(sock, "Unknown resource type %d in dump_resource.\n", type);
         break;
@@ -786,6 +684,12 @@ void free_resource(int type)
               if (incexe->name_list) {
                  free(incexe->name_list);
               }
+              for (int i=0; i<incexe->num_match; i++) {
+                 free(incexe->match_list[i]);
+              }
+              if (incexe->match_list) {
+                 free(incexe->match_list);
+              }
               free(incexe);
            }
            free(res->res_fs.include_items);
@@ -800,6 +704,12 @@ void free_resource(int type)
               if (incexe->name_list) {
                  free(incexe->name_list);
               }
+              for (int i=0; i<incexe->num_match; i++) {
+                 free(incexe->match_list[i]);
+              }
+              if (incexe->match_list) {
+                 free(incexe->match_list);
+              }
               free(incexe);
            }
            free(res->res_fs.exclude_items);
@@ -850,14 +760,6 @@ void free_resource(int type)
         free_msgs_res((MSGS *)res);  /* free message resource */
         res = NULL;
         break;
-      case R_FILEOPTIONS:
-        if (res->res_fopts.num_match) {
-           for (int i=0; i < res->res_fopts.num_match; i++) {
-              free(res->res_fopts.match[i]);
-           }
-           free((char *)res->res_fopts.match);   
-        }
-        break;
       case R_GROUP:
         break;
       default:
@@ -912,26 +814,10 @@ void save_resource(int type, struct res_items *items, int pass)
         /* Resources not containing a resource */
         case R_CATALOG:
         case R_STORAGE:
-        case R_FILEOPTIONS:
         case R_GROUP:
         case R_POOL:
         case R_MSGS:
-           break;
-
-        /* Special case for FileSet, all allocations are done
-         * only in pass 2, so here we must copy the whole structure.
-         * This is done so that we can have forward references to
-         *   FileOptions resources within the fileset
-         */
         case R_FILESET:
-           RES res_save;
-           if ((res = (URES *)GetResWithName(R_FILESET, res_all.res_dir.hdr.name)) == NULL) {
-               Emsg1(M_ERROR_TERM, 0, "Cannot find FileSet resource %s\n", res_all.res_dir.hdr.name);
-           }
-           memcpy(&res_save, &res_all, sizeof(RES));
-           memcpy(&res_all, res, sizeof(RES));
-           memcpy(res, &res_all, sizeof(FILESET));
-           memcpy(&res_all, &res_save, sizeof(RES));
            break;
 
         /* Resources containing another resource */
@@ -1040,9 +926,6 @@ void save_resource(int type, struct res_items *items, int pass)
       case R_COUNTER:
         size = sizeof(COUNTER);
         break;
-      case R_FILEOPTIONS:
-        size = sizeof(FILEOPTIONS);
-        break;
       default:
          printf("Unknown resource type %d in save_resrouce.\n", type);
         error = 1;
@@ -1334,234 +1217,3 @@ static void store_restore(LEX *lc, struct res_items *item, int index, int pass)
    lc->options = options;            /* reset original options */
    set_bit(index, res_all.hdr.item_present);
 }
-
-
-
-/* 
- * Scan for Include options (keyword=option) is converted into one or
- *  two characters. Verifyopts=xxxx is Vxxxx:
- */
-static void scan_include_options(LEX *lc, int keyword, char *opts, int optlen)
-{
-   int token, i;
-   char option[3];
-
-   option[0] = 0;                    /* default option = none */
-   option[2] = 0;                    /* terminate options */
-   token = lex_get_token(lc, T_NAME);            /* expect at least one option */       
-   if (keyword == INC_KW_VERIFY) { /* special case */
-      /* ***FIXME**** ensure these are in permitted set */
-      bstrncat(opts, "V", optlen);         /* indicate Verify */
-      bstrncat(opts, lc->str, optlen);
-      bstrncat(opts, ":", optlen);         /* terminate it */
-
-   /* Standard keyword -- these are now deprecated and should be specified
-    *  in the FileOptions resource
-    */
-   } else {
-      for (i=0; FS_options[i].name; i++) {
-        if (strcasecmp(lc->str, FS_options[i].name) == 0 && FS_options[i].keyword == keyword) {
-           /* NOTE! maximum 2 letters here or increase option[3] */
-           option[0] = FS_options[i].option[0];
-           option[1] = FS_options[i].option[1];
-           i = 0;
-           break;
-        }
-      }
-      if (i != 0) {
-         scan_err1(lc, "Expected a FileSet option keyword, got:%s:", lc->str);
-      } else { /* add option */
-        bstrncat(opts, option, optlen);
-         Dmsg3(200, "Catopts=%s option=%s optlen=%d\n", opts, option,optlen);
-      }
-   }
-
-   /* If option terminated by comma, eat it */
-   if (lc->ch == ',') {
-      token = lex_get_token(lc, T_ALL);      /* yes, eat comma */
-   }
-}
-
-/* Store FileSet Include/Exclude info */
-static void store_inc(LEX *lc, struct res_items *item, int index, int pass)
-{
-   int token, i;
-   int options = lc->options;
-   int keyword;
-   char inc_opts[100];
-   int inc_opts_len;
-   RES *res = NULL;
-
-   lc->options |= LOPT_NO_IDENT;      /* make spaces significant */
-
-   /* Get include options */
-   inc_opts[0] = 0;
-   while ((token=lex_get_token(lc, T_ALL)) != T_BOB) {
-      keyword = INC_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 == INC_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_ALL)) != T_EQUALS) {
-         scan_err1(lc, _("expected an = following keyword, got: %s"), lc->str);
-      }
-      if (keyword == INC_KW_FILEOPTIONS) {
-        token = lex_get_token(lc, T_NAME);
-        if (pass == 2) {
-           res = GetResWithName(R_FILEOPTIONS, lc->str);
-           if (res == NULL) {
-               scan_err1(lc, _("Could not find specified FileOptions Resource: %s"), lc->str);
-           }
-        }
-      } else {
-        scan_include_options(lc, keyword, inc_opts, sizeof(inc_opts));
-      }
-      if (token == T_BOB) {
-        break;
-      }
-   }
-   if (!inc_opts[0]) {
-      strcat(inc_opts, "0");          /* set no options */
-   }
-   inc_opts_len = strlen(inc_opts);
-
-   if (pass == 2) {
-      INCEXE *incexe;
-      if (!res_all.res_fs.have_MD5) {
-        MD5Init(&res_all.res_fs.md5c);
-        res_all.res_fs.have_MD5 = TRUE;
-      }
-      /* Create incexe structure */
-      Dmsg0(200, "Create INCEXE structure\n");
-      incexe = (INCEXE *)malloc(sizeof(INCEXE));
-      memset(incexe, 0, sizeof(INCEXE));
-      bstrncpy(incexe->opts, inc_opts, sizeof(incexe->opts));
-      incexe->fileopts = (struct s_res_fopts *)res;
-      Dmsg1(200, "incexe opts=%s\n", incexe->opts);
-      if (item->code == 0) { /* include */
-        if (res_all.res_fs.num_includes == 0) {
-           res_all.res_fs.include_items = (INCEXE **)malloc(sizeof(INCEXE *));
-         } else {
-           res_all.res_fs.include_items = (INCEXE **)realloc(res_all.res_fs.include_items,
-                          sizeof(INCEXE *) * res_all.res_fs.num_includes + 1);
-         }
-         res_all.res_fs.include_items[res_all.res_fs.num_includes++] = incexe;
-          Dmsg1(200, "num_includes=%d\n", res_all.res_fs.num_includes);
-      } else {   /* exclude */
-        if (res_all.res_fs.num_excludes == 0) {
-           res_all.res_fs.exclude_items = (INCEXE **)malloc(sizeof(INCEXE *));
-         } else {
-           res_all.res_fs.exclude_items = (INCEXE **)realloc(res_all.res_fs.exclude_items,
-                          sizeof(INCEXE *) * res_all.res_fs.num_excludes + 1);
-         }
-         res_all.res_fs.exclude_items[res_all.res_fs.num_excludes++] = incexe;
-          Dmsg1(200, "num_excludes=%d\n", res_all.res_fs.num_excludes);
-     }
-
-      /* Pickup include/exclude names. They are stored in INCEXE
-       *  structures which contains the options and the name.
-       */
-      while ((token = lex_get_token(lc, T_ALL)) != T_EOB) {
-        switch (token) {
-           case T_COMMA:
-           case T_EOL:
-              continue;
-
-           case T_IDENTIFIER:
-           case T_UNQUOTED_STRING:
-           case T_QUOTED_STRING:
-              if (res_all.res_fs.have_MD5) {
-                 MD5Update(&res_all.res_fs.md5c, (unsigned char *)lc->str, lc->str_len);
-              }
-              if (incexe->num_names == incexe->max_names) {
-                 incexe->max_names += 10;
-                 if (incexe->name_list == NULL) {
-                    incexe->name_list = (char **)malloc(sizeof(char *) * incexe->max_names);
-                 } else {
-                    incexe->name_list = (char **)realloc(incexe->name_list,
-                          sizeof(char *) * incexe->max_names);
-                 }
-              }
-              incexe->name_list[incexe->num_names++] = bstrdup(lc->str);
-               Dmsg1(200, "Add to name_list %s\n", incexe->name_list[incexe->num_names -1]);
-              break;
-           default:
-               scan_err1(lc, "Expected a filename, got: %s", lc->str);
-        }                                 
-      }
-      /* Note, MD5Final is done in backup.c */
-   } else { /* pass 1 */
-      while (lex_get_token(lc, T_ALL) != T_EOB) 
-        {}
-   }
-   scan_to_eol(lc);
-   lc->options = options;
-   set_bit(index, res_all.hdr.item_present);
-}
-
-/* Store FileOptions Match info */
-static void store_match(LEX *lc, struct res_items *item, int index, int pass)
-{
-   int token;
-   char *match;
-
-   if (pass == 1) {
-      /* Pickup Match string
-       */
-      token = lex_get_token(lc, T_ALL);           
-      switch (token) {
-        case T_IDENTIFIER:
-        case T_UNQUOTED_STRING:
-        case T_QUOTED_STRING:
-           match = (char *)malloc(lc->str_len + 1);
-           strcpy(match, lc->str);
-           res_all.res_fopts.num_match++;
-           if (res_all.res_fopts.match == NULL) {
-              res_all.res_fopts.match = (char **)malloc(sizeof(char *) * res_all.res_fopts.num_match);
-           } else {
-              res_all.res_fopts.match = (char **)realloc(res_all.res_fopts.match,
-                 sizeof(char *) * res_all.res_fopts.num_match);
-           }
-           res_all.res_fopts.match[res_all.res_fopts.num_match-1] = match;
-           break;
-        default:
-            scan_err1(lc, "Expected a filename, got: %s", lc->str);
-      }                                
-   } else { /* pass 2 */
-      lex_get_token(lc, T_ALL);         
-   }
-   scan_to_eol(lc);
-   set_bit(index, res_all.hdr.item_present);
-}
-
-static void store_opts(LEX *lc, struct res_items *item, int index, int pass)
-{
-   int i;
-   int keyword;
-   char inc_opts[100];
-
-   inc_opts[0] = 0;
-   keyword = INC_KW_NONE;
-   for (i=0; FS_option_kw[i].name; i++) {
-      if (strcasecmp(item->name, FS_option_kw[i].name) == 0) {
-        keyword = FS_option_kw[i].token;
-        break;
-      }
-   }
-   if (keyword == INC_KW_NONE) {
-      scan_err1(lc, "Expected a FileSet keyword, got: %s", lc->str);
-   }
-   Dmsg2(200, "keyword=%d %s\n", keyword, FS_option_kw[keyword].name);
-   scan_include_options(lc, keyword, inc_opts, sizeof(inc_opts));
-
-   bstrncat((char *)item->value, inc_opts, MAX_FO_OPTS);
-
-   scan_to_eol(lc);
-   set_bit(index, res_all.hdr.item_present);
-}
index 9a188506af6767985f4635899312952be39f1db1..63126b50e0d8cb6aa3f8556d18430796f95b254c 100644 (file)
@@ -43,9 +43,8 @@
 #define R_POOL                        1009
 #define R_MSGS                        1010
 #define R_COUNTER                     1011
-#define R_FILEOPTIONS                 1012
 
-#define R_LAST                        R_FILEOPTIONS
+#define R_LAST                        R_COUNTER
 
 /*
  * Some resource attributes
@@ -181,27 +180,16 @@ struct s_res_job {
 };
 typedef struct s_res_job JOB;
 
-/*
- * File Options Resource (options for Includes)
- */
 #define MAX_FO_OPTS 30
-struct s_res_fopts {
-   RES  hdr;
-
-   char opts[MAX_FO_OPTS];            /* Options string */
-   int  replace;                      /* How (overwrite, ...) */
-   char **match;                      /* match strings */
-   int num_match;                     /* number of match strings */
-}; 
-typedef struct s_res_fopts FILEOPTIONS;
 
 /* This is either an include item or an exclude item */
 struct s_incexc_item {
    char opts[MAX_FO_OPTS];            /* options string */
-   struct s_res_fopts *fileopts;      /* File Options resource */
+   char **match_list;                 /* match strings */
+   int num_match;                     /* number of match strings */
    char **name_list;                  /* filename list */
+   int max_names;                     /* malloc'ed size of name list */
    int num_names;                     /* number of names in the list */
-   int max_names;                     /* malloc'ed size of list */
 };
 typedef struct s_incexc_item INCEXE;
 
@@ -212,6 +200,7 @@ typedef struct s_incexc_item INCEXE;
 struct s_res_fs {
    RES   hdr;
 
+   int finclude;                      /* Set if finclude/fexclude used */
    INCEXE **include_items;            /* array of incexe structures */
    int num_includes;                  /* number in array */
    INCEXE **exclude_items;
@@ -297,7 +286,6 @@ union u_res {
    struct s_res_pool    res_pool;
    struct s_res_msgs    res_msgs;
    struct s_res_counter res_counter;
-   struct s_res_fopts   res_fopts;
    RES hdr;
 };
 
index 3f79864aaa516b598e1827654a5a0faeb0e228de..111cd7c69da9a57df151e833868864ba23f21f3e 100644 (file)
@@ -143,11 +143,7 @@ int send_include_list(JCR *jcr)
               goto bail_out;
            }
            /* Copy File options */
-           if (ie->fileopts) {
-              strcpy(buf, ie->fileopts->opts);
-           } else {
-              strcpy(buf, ie->opts);
-           }
+           strcpy(buf, ie->opts);
             strcat(buf, " ");
            optlen = strlen(buf);
            while (fgets(buf+optlen, sizeof(buf)-optlen, bpipe->rfd)) {
@@ -171,11 +167,7 @@ int send_include_list(JCR *jcr)
               goto bail_out;
            }
            /* Copy File options */
-           if (ie->fileopts) {
-              strcpy(buf, ie->fileopts->opts);
-           } else {
-              strcpy(buf, ie->opts);
-           }
+           strcpy(buf, ie->opts);
             strcat(buf, " ");
            optlen = strlen(buf);
            while (fgets(buf+optlen, sizeof(buf)-optlen, ffd)) {
@@ -188,12 +180,7 @@ int send_include_list(JCR *jcr)
            fclose(ffd);
            break;
         default:
-           if (ie->fileopts) {
-              pm_strcpy(&fd->msg, ie->fileopts->opts);
-               Dmsg1(200, "Fileopts=%s\n", fd->msg);
-           } else {
-              pm_strcpy(&fd->msg, ie->opts);
-           }
+           pm_strcpy(&fd->msg, ie->opts);
             pm_strcat(&fd->msg, " ");
            pm_strcat(&fd->msg, ie->name_list[j]);
             Dmsg1(200, "Include name=%s\n", fd->msg);
diff --git a/bacula/src/dird/inc_conf.c b/bacula/src/dird/inc_conf.c
new file mode 100644 (file)
index 0000000..da1d12f
--- /dev/null
@@ -0,0 +1,474 @@
+/*
+ *   Configuration file parser for Include, Exclude, Finclude
+ *    and FExclude records.
+ *
+ *     Kern Sibbald, March MMIII
+ *
+ *     Version $Id$
+ */
+/*
+   Copyright (C) 2000-2003 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 "dird.h"
+
+/* Forward referenced subroutines */
+
+void store_inc(LEX *lc, struct res_items *item, int index, int pass);
+void store_finc(LEX *lc, struct res_items *item, int index, int pass);
+
+static void store_match(LEX *lc, struct res_items *item, int index, int pass);
+static void store_opts(LEX *lc, struct res_items *item, int index, int pass);
+static void store_fname(LEX *lc, struct res_items *item, int index, int pass);
+
+
+/* We build the current resource here as we are
+ * scanning the resource configuration definition,
+ * then move it to allocated memory when the resource
+ * scan is complete.
+ */
+extern URES res_all;
+extern int  res_all_size;
+
+/* We build the current Finclude Fexclude item here */
+static INCEXE res_incexe;
+
+/* 
+ * FInclude/FExclude items
+ *   name            handler     value                        code flags default_value
+ */
+static struct res_items finc_items[] = {
+   {"compression",     store_opts,    NULL,     0, 0, 0},
+   {"signature",       store_opts,    NULL,     0, 0, 0},
+   {"verify",          store_opts,    NULL,     0, 0, 0},
+   {"onefs",           store_opts,    NULL,     0, 0, 0},
+   {"recurse",         store_opts,    NULL,     0, 0, 0},
+   {"sparse",          store_opts,    NULL,     0, 0, 0},
+   {"readfifo",        store_opts,    NULL,     0, 0, 0},
+   {"replace",         store_opts,    NULL,     0, 0, 0},
+   {"match",           store_match,   NULL,     0, 0, 0},
+   {"file",            store_fname,   NULL,     0, 0, 0},
+
+   {NULL, NULL, NULL, 0, 0, 0} 
+};
+
+/* Define FileSet KeyWord values */
+
+#define INC_KW_NONE        0
+#define INC_KW_COMPRESSION  1
+#define INC_KW_SIGNATURE    2
+#define INC_KW_ENCRYPTION   3
+#define INC_KW_VERIFY      4
+#define INC_KW_ONEFS       5
+#define INC_KW_RECURSE     6
+#define INC_KW_SPARSE      7
+#define INC_KW_REPLACE     8         /* restore options */
+#define INC_KW_READFIFO     9        /* Causes fifo data to be read */
+
+/* Include keywords -- these are keywords that can appear
+ *    in the options lists of an include ( Include = compression= ...)
+ */
+static struct s_kw FS_option_kw[] = {
+   {"compression", INC_KW_COMPRESSION},
+   {"signature",   INC_KW_SIGNATURE},
+   {"encryption",  INC_KW_ENCRYPTION},
+   {"verify",      INC_KW_VERIFY},
+   {"onefs",       INC_KW_ONEFS},
+   {"recurse",     INC_KW_RECURSE},
+   {"sparse",      INC_KW_SPARSE},
+   {"replace",     INC_KW_REPLACE},
+   {"readfifo",    INC_KW_READFIFO},
+   {NULL,         0}
+};
+
+/* Options for FileSet keywords */
+
+struct s_fs_opt {
+   char *name;
+   int keyword;
+   char *option;
+};
+
+/*
+ * Options permitted for each keyword and resulting value.     
+ * The output goes into opts, which are then transmitted to
+ * the FD for application as options to the following list of
+ * included files.
+ */
+static struct s_fs_opt FS_options[] = {
+   {"md5",      INC_KW_SIGNATURE,    "M"},
+   {"sha1",     INC_KW_SIGNATURE,    "S"},
+   {"gzip",     INC_KW_COMPRESSION,  "Z6"},
+   {"gzip1",    INC_KW_COMPRESSION,  "Z1"},
+   {"gzip2",    INC_KW_COMPRESSION,  "Z2"},
+   {"gzip3",    INC_KW_COMPRESSION,  "Z3"},
+   {"gzip4",    INC_KW_COMPRESSION,  "Z4"},
+   {"gzip5",    INC_KW_COMPRESSION,  "Z5"},
+   {"gzip6",    INC_KW_COMPRESSION,  "Z6"},
+   {"gzip7",    INC_KW_COMPRESSION,  "Z7"},
+   {"gzip8",    INC_KW_COMPRESSION,  "Z8"},
+   {"gzip9",    INC_KW_COMPRESSION,  "Z9"},
+   {"blowfish", INC_KW_ENCRYPTION,    "B"},   /* ***FIXME*** not implemented */
+   {"3des",     INC_KW_ENCRYPTION,    "3"},   /* ***FIXME*** not implemented */
+   {"yes",      INC_KW_ONEFS,         "0"},
+   {"no",       INC_KW_ONEFS,         "f"},
+   {"yes",      INC_KW_RECURSE,       "0"},
+   {"no",       INC_KW_RECURSE,       "h"},
+   {"yes",      INC_KW_SPARSE,        "s"},
+   {"no",       INC_KW_SPARSE,        "0"},
+   {"always",   INC_KW_REPLACE,       "a"},
+   {"ifnewer",  INC_KW_REPLACE,       "w"},
+   {"never",    INC_KW_REPLACE,       "n"},
+   {"yes",      INC_KW_READFIFO,      "r"},
+   {"no",       INC_KW_READFIFO,      "0"},
+   {NULL,      0,                   0}
+};
+
+
+
+/* 
+ * Scan for Include options (keyword=option) is converted into one or
+ *  two characters. Verifyopts=xxxx is Vxxxx:
+ */
+static void scan_include_options(LEX *lc, int keyword, char *opts, int optlen)
+{
+   int token, i;
+   char option[3];
+
+   option[0] = 0;                    /* default option = none */
+   option[2] = 0;                    /* terminate options */
+   token = lex_get_token(lc, T_NAME);            /* expect at least one option */       
+   if (keyword == INC_KW_VERIFY) { /* special case */
+      /* ***FIXME**** ensure these are in permitted set */
+      bstrncat(opts, "V", optlen);         /* indicate Verify */
+      bstrncat(opts, lc->str, optlen);
+      bstrncat(opts, ":", optlen);         /* terminate it */
+
+   /*
+    * Standard keyword options for Include/Exclude 
+    */
+   } else {
+      for (i=0; FS_options[i].name; i++) {
+        if (strcasecmp(lc->str, FS_options[i].name) == 0 && FS_options[i].keyword == keyword) {
+           /* NOTE! maximum 2 letters here or increase option[3] */
+           option[0] = FS_options[i].option[0];
+           option[1] = FS_options[i].option[1];
+           i = 0;
+           break;
+        }
+      }
+      if (i != 0) {
+         scan_err1(lc, "Expected a FileSet option keyword, got:%s:", lc->str);
+      } else { /* add option */
+        bstrncat(opts, option, optlen);
+         Dmsg3(200, "Catopts=%s option=%s optlen=%d\n", opts, option,optlen);
+      }
+   }
+
+   /* If option terminated by comma, eat it */
+   if (lc->ch == ',') {
+      token = lex_get_token(lc, T_ALL);      /* yes, eat comma */
+   }
+}
+
+/* Store FileSet Include/Exclude info */
+void store_inc(LEX *lc, struct res_items *item, int index, int pass)
+{
+   int token, i;
+   int options = lc->options;
+   int keyword;
+   char inc_opts[100];
+   int inc_opts_len;
+
+   lc->options |= LOPT_NO_IDENT;      /* make spaces significant */
+
+   /* Get include options */
+   inc_opts[0] = 0;
+   while ((token=lex_get_token(lc, T_ALL)) != T_BOB) {
+      keyword = INC_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 == INC_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_ALL)) != T_EQUALS) {
+         scan_err1(lc, _("expected an = following keyword, got: %s"), lc->str);
+      } else {
+        scan_include_options(lc, keyword, inc_opts, sizeof(inc_opts));
+      }
+      if (token == T_BOB) {
+        break;
+      }
+   }
+   if (!inc_opts[0]) {
+      strcat(inc_opts, "0");          /* set no options */
+   }
+   inc_opts_len = strlen(inc_opts);
+
+   if (pass == 1) {
+      INCEXE *incexe;
+      if (!res_all.res_fs.have_MD5) {
+        MD5Init(&res_all.res_fs.md5c);
+        res_all.res_fs.have_MD5 = TRUE;
+      }
+      /* Create incexe structure */
+      Dmsg0(200, "Create INCEXE structure\n");
+      incexe = (INCEXE *)malloc(sizeof(INCEXE));
+      memset(incexe, 0, sizeof(INCEXE));
+      bstrncpy(incexe->opts, inc_opts, sizeof(incexe->opts));
+      Dmsg1(200, "incexe opts=%s\n", incexe->opts);
+      if (item->code == 0) { /* include */
+        if (res_all.res_fs.num_includes == 0) {
+           res_all.res_fs.include_items = (INCEXE **)malloc(sizeof(INCEXE *));
+         } else {
+           res_all.res_fs.include_items = (INCEXE **)realloc(res_all.res_fs.include_items,
+                          sizeof(INCEXE *) * res_all.res_fs.num_includes + 1);
+         }
+         res_all.res_fs.include_items[res_all.res_fs.num_includes++] = incexe;
+          Dmsg1(200, "num_includes=%d\n", res_all.res_fs.num_includes);
+      } else {   /* exclude */
+        if (res_all.res_fs.num_excludes == 0) {
+           res_all.res_fs.exclude_items = (INCEXE **)malloc(sizeof(INCEXE *));
+         } else {
+           res_all.res_fs.exclude_items = (INCEXE **)realloc(res_all.res_fs.exclude_items,
+                          sizeof(INCEXE *) * res_all.res_fs.num_excludes + 1);
+         }
+         res_all.res_fs.exclude_items[res_all.res_fs.num_excludes++] = incexe;
+          Dmsg1(200, "num_excludes=%d\n", res_all.res_fs.num_excludes);
+      }
+
+      /* Pickup include/exclude names. They are stored in INCEXE
+       *  structures which contains the options and the name.
+       */
+      while ((token = lex_get_token(lc, T_ALL)) != T_EOB) {
+        switch (token) {
+           case T_COMMA:
+           case T_EOL:
+              continue;
+
+           case T_IDENTIFIER:
+           case T_UNQUOTED_STRING:
+           case T_QUOTED_STRING:
+              if (res_all.res_fs.have_MD5) {
+                 MD5Update(&res_all.res_fs.md5c, (unsigned char *)lc->str, lc->str_len);
+              }
+              if (incexe->num_names == incexe->max_names) {
+                 incexe->max_names += 10;
+                 if (incexe->name_list == NULL) {
+                    incexe->name_list = (char **)malloc(sizeof(char *) * incexe->max_names);
+                 } else {
+                    incexe->name_list = (char **)realloc(incexe->name_list,
+                          sizeof(char *) * incexe->max_names);
+                 }
+              }
+              incexe->name_list[incexe->num_names++] = bstrdup(lc->str);
+               Dmsg1(200, "Add to name_list %s\n", incexe->name_list[incexe->num_names -1]);
+              break;
+           default:
+               scan_err1(lc, "Expected a filename, got: %s", lc->str);
+        }                                 
+      }
+      /* Note, MD5Final is done in backup.c */
+   } else { /* pass 1 */
+      while (lex_get_token(lc, T_ALL) != T_EOB) 
+        {}
+   }
+   scan_to_eol(lc);
+   lc->options = options;
+   set_bit(index, res_all.hdr.item_present);
+}
+
+
+/*
+ * Store FileSet FInclude/FExclude info   
+ *  Note, when this routine is called, we are inside a FileSet
+ *  resource.  We treat the Finclude/Fexeclude like a sort of
+ *  mini-resource within the FileSet resource.
+ */
+void store_finc(LEX *lc, struct res_items *item, int index, int pass)
+{
+   int token, i;
+   INCEXE *incexe;
+
+   res_all.res_fs.finclude = TRUE;
+   token = lex_get_token(lc, T_ALL);           
+   if (token != T_BOB) {
+      scan_err1(lc, _("Expecting a beginning brace, got: %s\n"), lc->str);
+   }
+   memset(&res_incexe, 0, sizeof(INCEXE));
+   while ((token = lex_get_token(lc, T_ALL)) != T_EOF) {
+      if (token == T_EOL) {
+        continue;
+      }
+      if (token == T_EOB) {
+        break;
+      }
+      if (token != T_IDENTIFIER) {
+         scan_err1(lc, _("Expecting keyword, got: %s\n"), lc->str);
+      }
+      for (i=0; finc_items[i].name; i++) {
+        if (strcasecmp(finc_items[i].name, lc->str) == 0) {
+           token = lex_get_token(lc, T_ALL);
+           if (token != T_EQUALS) {
+               scan_err1(lc, "expected an equals, got: %s", lc->str);
+           }
+           /* Call item handler */
+           finc_items[i].handler(lc, &finc_items[i], i, pass);
+           i = -1;
+           break;
+        }
+      }
+      if (i >=0) {
+         scan_err1(lc, "Keyword %s not permitted in this resource", lc->str);
+      }
+   }
+   if (pass == 1) {
+      incexe = (INCEXE *)malloc(sizeof(INCEXE));
+      memcpy(incexe, &res_incexe, sizeof(INCEXE));
+      Dmsg1(200, "incexe opts=%s\n", incexe->opts);
+      if (item->code == 0) { /* include */
+        if (res_all.res_fs.num_includes == 0) {
+           res_all.res_fs.include_items = (INCEXE **)malloc(sizeof(INCEXE *));
+        } else {
+           res_all.res_fs.include_items = (INCEXE **)realloc(res_all.res_fs.include_items,
+                          sizeof(INCEXE *) * res_all.res_fs.num_includes + 1);
+        }
+        res_all.res_fs.include_items[res_all.res_fs.num_includes++] = incexe;
+         Dmsg1(200, "num_includes=%d\n", res_all.res_fs.num_includes);
+      } else {   /* exclude */
+        if (res_all.res_fs.num_excludes == 0) {
+           res_all.res_fs.exclude_items = (INCEXE **)malloc(sizeof(INCEXE *));
+        } else {
+           res_all.res_fs.exclude_items = (INCEXE **)realloc(res_all.res_fs.exclude_items,
+                          sizeof(INCEXE *) * res_all.res_fs.num_excludes + 1);
+        }
+        res_all.res_fs.exclude_items[res_all.res_fs.num_excludes++] = incexe;
+         Dmsg1(200, "num_excludes=%d\n", res_all.res_fs.num_excludes);
+      }
+   }
+   scan_to_eol(lc);
+   set_bit(index, res_all.hdr.item_present);
+}
+
+
+/* Store Match info */
+static void store_match(LEX *lc, struct res_items *item, int index, int pass)
+{
+   int token;
+   char *match;
+
+   if (pass == 1) {
+      /* Pickup Match string
+       */
+      token = lex_get_token(lc, T_ALL);           
+      switch (token) {
+        case T_IDENTIFIER:
+        case T_UNQUOTED_STRING:
+        case T_QUOTED_STRING:
+           match = (char *)malloc(lc->str_len + 1);
+           strcpy(match, lc->str);
+           res_incexe.num_match++;
+           if (res_incexe.match_list == NULL) {
+              res_incexe.match_list = (char **)malloc(sizeof(char *) * res_incexe.num_match);
+           } else {
+              res_incexe.match_list = (char **)realloc(res_incexe.match_list,
+                 sizeof(char *) * res_incexe.num_match);
+           }
+           res_incexe.match_list[res_incexe.num_match-1] = match;
+           break;
+        default:
+            scan_err1(lc, "Expected a filename, got: %s", lc->str);
+      }                                
+   } else { /* pass 2 */
+      lex_get_token(lc, T_ALL);         
+   }
+   scan_to_eol(lc);
+}
+
+
+/* Store Filename info */
+static void store_fname(LEX *lc, struct res_items *item, int index, int pass)
+{
+   int token;
+   INCEXE *incexe;
+
+   if (pass == 1) {
+      /* Pickup Filename string
+       */
+      token = lex_get_token(lc, T_ALL);           
+      switch (token) {
+        case T_IDENTIFIER:
+        case T_UNQUOTED_STRING:
+        case T_QUOTED_STRING:
+           if (res_all.res_fs.have_MD5) {
+              MD5Update(&res_all.res_fs.md5c, (unsigned char *)lc->str, lc->str_len);
+           }
+           incexe = &res_incexe;
+           if (incexe->num_names == incexe->max_names) {
+              incexe->max_names += 10;
+              if (incexe->name_list == NULL) {
+                 incexe->name_list = (char **)malloc(sizeof(char *) * incexe->max_names);
+              } else {
+                 incexe->name_list = (char **)realloc(incexe->name_list,
+                       sizeof(char *) * incexe->max_names);
+              }
+           }
+           incexe->name_list[incexe->num_names++] = bstrdup(lc->str);
+            Dmsg1(200, "Add to name_list %s\n", incexe->name_list[incexe->num_names -1]);
+           break;
+        default:
+            scan_err1(lc, "Expected a filename, got: %s", lc->str);
+      }                                
+   } else { /* pass 2 */
+      lex_get_token(lc, T_ALL);         
+   }
+   scan_to_eol(lc);
+}
+
+
+static void store_opts(LEX *lc, struct res_items *item, int index, int pass)
+{
+   int i;
+   int keyword;
+   char inc_opts[100];
+
+   inc_opts[0] = 0;
+   keyword = INC_KW_NONE;
+   for (i=0; FS_option_kw[i].name; i++) {
+      if (strcasecmp(item->name, FS_option_kw[i].name) == 0) {
+        keyword = FS_option_kw[i].token;
+        break;
+      }
+   }
+   if (keyword == INC_KW_NONE) {
+      scan_err1(lc, "Expected a FileSet keyword, got: %s", lc->str);
+   }
+   Dmsg2(200, "keyword=%d %s\n", keyword, FS_option_kw[keyword].name);
+   scan_include_options(lc, keyword, inc_opts, sizeof(inc_opts));
+
+   bstrncat(res_incexe.opts, inc_opts, MAX_FO_OPTS);
+
+   scan_to_eol(lc);
+}
index 500cb8a54be883676893b942072ac0a4387de321..3e2f77f4eb67906cfec328141ea196aada9e36d3 100755 (executable)
@@ -658,11 +658,15 @@ parse_config(char *cf)
                     }
                     for (i=0; items[i].name; i++) {
                        if (strcasecmp(items[i].name, lc->str) == 0) {
-                          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);
-                             /* NOT REACHED */
+                          /* If the ITEM_NO_EQUALS flag is set we do NOT              
+                           *   scan for = after the keyword  */
+                          if (!(items[i].flags & ITEM_NO_EQUALS)) {
+                             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);
+                                /* NOT REACHED */
+                             }
                           }
                            Dmsg1(150, "calling handler for %s\n", items[i].name);
                           /* Call item handler */
index a666970af828b405cd737062266336bc8849608c..9f2f47ff3e8f5dc7a802aec30970081f11683d02 100644 (file)
@@ -74,8 +74,9 @@ struct s_res {
 
 #define MAX_RES_NAME_LENGTH MAX_NAME_LENGTH-1       /* maximum resource name length */
 
-#define ITEM_REQUIRED 0x1             /* item required */
-#define ITEM_DEFAULT  0x2             /* default supplied */
+#define ITEM_REQUIRED    0x1          /* item required */
+#define ITEM_DEFAULT     0x2          /* default supplied */
+#define ITEM_NO_EQUALS   0x4          /* Don't scan = after name */
 
 /* Message Resource */
 struct s_res_msgs {
index a4e4594974067f8b8671a3794d92422aea5181c3..3424f68a661bfc027ae28a20052b0118033a9d5f 100644 (file)
@@ -1,8 +1,8 @@
 /* */
 #define VERSION "1.30"
 #define VSTRING "1"
-#define BDATE   "02 March 2003"
-#define LSMDATE "02Mar03"
+#define BDATE   "03 March 2003"
+#define LSMDATE "03Mar03"
 
 /* Debug flags */
 #define DEBUG 1