* directives, which are part of the Schedule Resource
*
* Kern Sibbald, May MM
+ *
+ * Version $Id$
*/
/*
Copyright (C) 2000, 2001, 2002 Kern Sibbald and John Walker
s_weekly,
s_monthly,
s_hourly,
+ s_wpos, /* 1st, 2nd, ...*/
};
struct s_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);
}
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
*
*/
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" */
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 (strcasecmp(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.
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;
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;
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;
}
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) {
}
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);
pm = 1;
} else {
scan_err0(lc, _("Bad time specification."));
+ /* NOT REACHED */
}
} else {
pm = 0;
}
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;
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 */
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) {
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;
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;
}
}
* 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;