]> git.sur5r.net Git - bacula/bacula/blobdiff - bacula/src/dird/run_conf.c
Fix newvol.c
[bacula/bacula] / bacula / src / dird / run_conf.c
index c58a713f5da19c12b23760bd14def279595b4e71..032ce1037f326de0da1d171161b91c11093508ab 100644 (file)
@@ -4,6 +4,8 @@
  *   directives, which are part of the Schedule Resource
  *
  *     Kern Sibbald, May MM
+ *
+ *     Version $Id$
  */
 /*
    Copyright (C) 2000, 2001, 2002 Kern Sibbald and John Walker
@@ -45,6 +47,7 @@ enum e_state {
    s_weekly,
    s_monthly,
    s_hourly,
+   s_wpos,                           /* 1st, 2nd, ...*/
 };  
 
 struct s_keyw {
@@ -101,30 +104,44 @@ static struct s_keyw keyw[] = {
   {N_("weekly"),     s_weekly,  0},
   {N_("monthly"),    s_monthly, 0},
   {N_("hourly"),     s_hourly,  0},
+
+  {N_("1st"),        s_wpos,    0},
+  {N_("2nd"),        s_wpos,    1},
+  {N_("3rd"),        s_wpos,    2},
+  {N_("4th"),        s_wpos,    3},
+  {N_("5th"),        s_wpos,    4},
+
+  {N_("first"),      s_wpos,    0},
+  {N_("second"),     s_wpos,    1},
+  {N_("third"),      s_wpos,    2},
+  {N_("fourth"),     s_wpos,    3},
+  {N_("fifth"),      s_wpos,    4},
   {NULL,        s_none,    0}
 };
 
-static int have_hour, have_mday, have_wday, have_month;
+static int have_hour, have_mday, have_wday, have_month, have_wpos;
 static int have_at;
 static RUN lrun;
 
 static void clear_defaults()
 {
-   have_hour = have_mday = have_wday = have_month = TRUE;
+   have_hour = have_mday = have_wday = have_month = have_wpos = TRUE;
    clear_bit(0,lrun.hour);
    clear_bits(0, 30, lrun.mday);
    clear_bits(0, 6, lrun.wday);
    clear_bits(0, 11, lrun.month);
+   clear_bits(0, 4, lrun.wpos);
 }
 
 static void set_defaults()
 {
-   have_hour = have_mday = have_wday = have_month = FALSE;
+   have_hour = have_mday = have_wday = have_month = have_wpos = FALSE;
    have_at = FALSE;
    set_bit(0,lrun.hour);
    set_bits(0, 30, lrun.mday);
    set_bits(0, 6, lrun.wday);
    set_bits(0, 11, lrun.month);
+   set_bits(0, 4, lrun.wpos);
 }
 
 
@@ -141,13 +158,21 @@ static int is_num(char *num)
    return TRUE;
 }
 
+/* Keywords (RHS) permitted in Run records */
+static struct s_kw RunFields[] = {
+   {"pool",     'P'},
+   {"level",    'L'},
+   {"storage",  'S'},
+   {"messages", 'M'},
+   {NULL,       0}
+};
 
 /* 
  * Store Schedule Run information   
  * 
  * Parse Run statement:
  *
- *  Run <full|incremental|...> [on] 2 january at 23:45
+ *  Run <keyword=value ...> [on] 2 january at 23:45
  *
  *   Default Run time is daily at 0:0
  *  
@@ -157,11 +182,13 @@ static int is_num(char *num)
  */
 void store_run(LEX *lc, struct res_items *item, int index, int pass)
 {
-   int token, state, state2, i, code, code2;
+   int i, j, found;
+   int token, state, state2 = 0, code = 0, code2 = 0;
    int options = lc->options;
    RUN **run = (RUN **)(item->value);  
    RUN *trun;
    char *p;
+   RES *res;
 
 
    lc->options |= LOPT_NO_IDENT;      /* want only "strings" */
@@ -170,23 +197,86 @@ void store_run(LEX *lc, struct res_items *item, int index, int pass)
    memset(&lrun, 0, sizeof(RUN));
 
    /* scan for Job level "full", "incremental", ... */
-   token = lex_get_token(lc);
-   if (token != T_STRING) {
-      scan_err1(lc, _("Expected a Job level identifier, got: %s"), lc->str);
-   } else {
-      lcase(lc->str);
-      for (i=0; joblevels[i].level_name; i++) {
-        if (strcmp(lc->str, joblevels[i].level_name) == 0) {
-           lrun.level = joblevels[i].level;
-           lrun.job_class = joblevels[i].job_class;
-           i = 0;
+   for (found=TRUE; found; ) {
+      found = FALSE;
+      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_ALL) != T_EQUALS) {
+               scan_err1(lc, "Expected an equals, got: %s", lc->str);
+              /* NOT REACHED */ 
+           }
+           token = lex_get_token(lc, T_NAME);
+           switch (RunFields[i].token) {
+            case 'L':                 /* level */
+              for (j=0; joblevels[j].level_name; j++) {
+                 if (strcasecmp(lc->str, joblevels[j].level_name) == 0) {
+                    lrun.level = joblevels[j].level;
+                    lrun.job_type = joblevels[j].job_type;
+                    j = 0;
+                    break;
+                 }
+              }
+              if (j != 0) {
+                  scan_err1(lc, _("Job level field: %s not found in run record"), lc->str);
+                 /* NOT REACHED */
+              }
+              break;
+            case 'P':                 /* Pool */
+              if (pass == 2) {
+                 res = GetResWithName(R_POOL, lc->str);
+                 if (res == NULL) {
+                     scan_err1(lc, "Could not find specified Pool Resource: %s",
+                               lc->str);
+                    /* NOT REACHED */
+                 }
+                 lrun.pool = (POOL *)res;
+              }
+              break;
+            case 'S':                 /* storage */
+              if (pass == 2) {
+                 res = GetResWithName(R_STORAGE, lc->str);
+                 if (res == NULL) {
+                     scan_err1(lc, "Could not find specified Storage Resource: %s",
+                               lc->str);
+                    /* NOT REACHED */
+                 }
+                 lrun.storage = (STORE *)res;
+              }
+              break;
+            case 'M':                 /* messages */
+              if (pass == 2) {
+                 res = GetResWithName(R_MSGS, lc->str);
+                 if (res == NULL) {
+                     scan_err1(lc, "Could not find specified Messages Resource: %s",
+                               lc->str);
+                    /* NOT REACHED */
+                 }
+                 lrun.msgs = (MSGS *)res;
+              }
+              break;
+           default:
+               scan_err1(lc, "Expected a keyword name, got: %s", lc->str);
+              /* NOT REACHED */
+              break;
+           } /* end switch */     
+        } /* end if strcasecmp */
+      } /* end for RunFields */
+
+      /* At this point, it is not a keyword. Check for old syle
+       * Job Levels without keyword. This form is depreciated!!!
+       */
+      for (j=0; joblevels[j].level_name; j++) {
+        if (strcasecmp(lc->str, joblevels[j].level_name) == 0) {
+           lrun.level = joblevels[j].level;
+           lrun.job_type = joblevels[j].job_type;
+           found = TRUE;
            break;
         }
       }
-      if (i != 0) {
-         scan_err1(lc, _("Job level field: %s not found in run record"), lc->str);
-      }
-   }
+   } /* end for found */
+
 
    /*
     * Scan schedule times.
@@ -195,8 +285,8 @@ void store_run(LEX *lc, struct res_items *item, int index, int pass)
    state = s_none;
    set_defaults();
 
-   while ((token = lex_get_token(lc)) != T_EOL) {
-      int len, pm;
+   for ( ; token != T_EOL; (token = lex_get_token(lc, T_ALL))) {
+      int len, pm = 0;
       switch (token) {
         case T_NUMBER:
            state = s_mday;
@@ -205,7 +295,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;
@@ -215,9 +306,8 @@ void store_run(LEX *lc, struct res_items *item, int index, int pass)
               break;
            }
            /* everything else must be a keyword */
-           lcase(lc->str);
            for (i=0; keyw[i].name; i++) {
-              if (strcmp(lc->str, keyw[i].name) == 0) {
+              if (strcasecmp(lc->str, keyw[i].name) == 0) {
                  state = keyw[i].state;
                  code   = keyw[i].code;
                  i = 0;
@@ -226,12 +316,14 @@ void store_run(LEX *lc, struct res_items *item, int index, int pass)
            }
            if (i != 0) {
                scan_err1(lc, _("Job type field: %s in run record not found"), lc->str);
+              /* NOT REACHED */
            }
            break;
         case T_COMMA:
            continue;
         default:
-            scan_err1(lc, _("Unexpected token: %s"), lc->str);
+            scan_err2(lc, _("Unexpected token: %d:%s"), token, lc->str);
+           /* NOT REACHED */
            break;
       }
       switch (state) {
@@ -260,17 +352,25 @@ void store_run(LEX *lc, struct res_items *item, int index, int pass)
            }
            set_bit(code, lrun.wday);
            break;
+        case s_wpos:                 /* Week position 1st, ... */
+           if (!have_wpos) {
+              clear_bits(0, 4, lrun.wpos);
+              have_wpos = TRUE;
+           }
+           set_bit(code, lrun.wpos);
+           break;
         case s_time:                 /* time */
            if (!have_at) {
                scan_err0(lc, _("Time must be preceded by keyword AT."));
+              /* NOT REACHED */
            }
            if (!have_hour) {
               clear_bit(0, lrun.hour);
-              have_hour = TRUE;
            }
             p = strchr(lc->str, ':');
            if (!p)  {
                scan_err0(lc, _("Time logic error.\n"));
+              /* NOT REACHED */
            }
            *p++ = 0;                 /* separate two halves */
            code = atoi(lc->str);
@@ -282,6 +382,7 @@ void store_run(LEX *lc, struct res_items *item, int index, int pass)
                  pm = 1;
               } else {
                   scan_err0(lc, _("Bad time specification."));
+                 /* NOT REACHED */
               }
            } else {
               pm = 0;
@@ -292,9 +393,11 @@ void store_run(LEX *lc, struct res_items *item, int index, int pass)
            }
            if (code < 0 || code > 23 || code2 < 0 || code2 > 59) {
                scan_err0(lc, _("Bad time specification."));
+              /* NOT REACHED */
            }
            set_bit(code, lrun.hour);
            lrun.minute = code2;
+           have_hour = TRUE;
            break;
         case s_at:
            have_at = TRUE;
@@ -337,8 +440,9 @@ void store_run(LEX *lc, struct res_items *item, int index, int pass)
                  break;
               }
            }
-           if (i != 0 || (state != s_month && state != s_wday)) {
-               scan_err0(lc, _("Invalid month or week day range"));
+           if (i != 0 || (state != s_month && state != s_wday && state != s_wpos)) {
+               scan_err0(lc, _("Invalid month, week or position day range"));
+              /* NOT REACHED */
            }
 
            /* Lookup end of range */
@@ -351,9 +455,9 @@ void store_run(LEX *lc, struct res_items *item, int index, int pass)
                  break;
               }
            }
-           if (i != 0 || state != state2 || 
-              (state2 != s_month && state2 != s_wday) || code == code2) {
-               scan_err0(lc, _("Invalid month or weekday range"));
+           if (i != 0 || state != state2 || code == code2) {
+               scan_err0(lc, _("Invalid month, weekday or position range"));
+              /* NOT REACHED */
            }
            if (state == s_wday) {
               if (!have_wday) {
@@ -367,8 +471,7 @@ void store_run(LEX *lc, struct res_items *item, int index, int pass)
                  set_bits(code, 6, lrun.wday);
                  set_bits(0, code2, lrun.wday);
               }
-           } else {
-              /* must be s_month */
+           } else if (state == s_month) {
               if (!have_month) {
                  clear_bits(0, 30, lrun.month);
                  have_month = TRUE;
@@ -380,31 +483,47 @@ void store_run(LEX *lc, struct res_items *item, int index, int pass)
                  set_bits(code, 30, lrun.month);
                  set_bits(0, code2, lrun.month);
               }
-           }
+           } else {
+              /* Must be position */
+              if (!have_wpos) {
+                 clear_bits(0, 4, lrun.wpos);
+                 have_wpos = TRUE;
+              }
+              if (code < code2) {
+                 set_bits(code, code2, lrun.wpos);
+              } else {
+                 set_bits(code, 4, lrun.wpos);
+                 set_bits(0, code2, lrun.wpos);
+              }
+           }                      
            break;
         case s_hourly:
            clear_defaults();
            set_bits(0, 23, lrun.hour);
            set_bits(0, 30, lrun.mday);
            set_bits(0, 11, lrun.month);
+           set_bits(0, 4, lrun.wpos);
            break;
         case s_weekly:
            clear_defaults();
            set_bit(0, lrun.wday);
            set_bits(0, 11, lrun.month);
+           set_bits(0, 4, lrun.wpos);
            break;
         case s_daily:
            clear_defaults();
            set_bits(0, 30, lrun.mday);
            set_bits(0, 11, lrun.month);
+           set_bits(0, 4,  lrun.wpos);
            break;
         case s_monthly:
            clear_defaults();
-           set_bit(0, lrun.mday);
            set_bits(0, 11, lrun.month);
+           set_bits(0, 4,  lrun.wpos);
            break;
         default:
             scan_err0(lc, _("Unexpected run state\n"));
+           /* NOT REACHED */
            break;
       }
    }
@@ -413,8 +532,8 @@ void store_run(LEX *lc, struct res_items *item, int index, int pass)
     * and link it into the list of run records 
     * in the schedule resource.
     */
-   if (pass == 1) {
-      trun = (RUN *) malloc(sizeof(RUN));
+   if (pass == 2) {
+      trun = (RUN *)malloc(sizeof(RUN));
       memcpy(trun, &lrun, sizeof(RUN));
       if (*run) {
         trun->next = *run;