- case s_none:
- continue;
- case s_mday: /* day of month */
- if (!have_mday) {
- clear_bits(0, 30, lrun.mday);
- clear_bits(0, 6, lrun.wday);
- have_mday = TRUE;
- }
- set_bit(code, lrun.mday);
- break;
- case s_month: /* month of year */
- if (!have_month) {
- clear_bits(0, 11, lrun.month);
- have_month = TRUE;
- }
- set_bit(code, lrun.month);
- break;
- case s_wday: /* week day */
- if (!have_wday) {
- clear_bits(0, 6, lrun.wday);
- clear_bits(0, 30, lrun.mday);
- have_wday = TRUE;
- }
- set_bit(code, lrun.wday);
- break;
- case s_time: /* time */
- if (!have_at) {
- scan_err0(lc, _("Time must be preceded by keyword AT."));
- }
- if (!have_hour) {
- clear_bit(0, lrun.hour);
- have_hour = TRUE;
- }
- p = strchr(lc->str, ':');
- if (!p) {
- scan_err0(lc, _("Time logic error.\n"));
- }
- *p++ = 0; /* separate two halves */
- code = atoi(lc->str);
- len = strlen(p);
- if (len > 2 && p[len-1] == 'm') {
- if (p[len-2] == 'a') {
- pm = 0;
- } else if (p[len-2] == 'p') {
- pm = 1;
- } else {
- scan_err0(lc, _("Bad time specification."));
- }
- } else {
- pm = 0;
- }
- code2 = atoi(p);
- if (pm) {
- code += 12;
- }
- if (code < 0 || code > 23 || code2 < 0 || code2 > 59) {
- scan_err0(lc, _("Bad time specification."));
- }
- set_bit(code, lrun.hour);
- lrun.minute = code2;
- break;
- case s_at:
- have_at = TRUE;
- break;
- case s_range:
- p = strchr(lc->str, '-');
- if (!p) {
- scan_err0(lc, _("Range logic error.\n"));
- }
- *p++ = 0; /* separate two halves */
-
- /* Check for day range */
- if (is_num(lc->str) && is_num(p)) {
- code = atoi(lc->str) - 1;
- code2 = atoi(p) - 1;
- if (code < 0 || code > 30 || code2 < 0 || code2 > 30) {
- scan_err0(lc, _("Bad day range specification."));
- }
- if (!have_mday) {
- clear_bits(0, 30, lrun.mday);
- clear_bits(0, 6, lrun.wday);
- have_mday = TRUE;
- }
- if (code < code2) {
- set_bits(code, code2, lrun.mday);
- } else {
- set_bits(code, 30, lrun.mday);
- set_bits(0, code2, lrun.mday);
- }
- break;
- }
-
- /* lookup first half of keyword range (week days or months) */
- lcase(lc->str);
- for (i=0; keyw[i].name; i++) {
- if (strcmp(lc->str, keyw[i].name) == 0) {
- state = keyw[i].state;
- code = keyw[i].code;
- i = 0;
- break;
- }
- }
- if (i != 0 || (state != s_month && state != s_wday)) {
- scan_err0(lc, _("Invalid month or week day range"));
- }
-
- /* Lookup end of range */
- lcase(p);
- for (i=0; keyw[i].name; i++) {
- if (strcmp(p, keyw[i].name) == 0) {
- state2 = keyw[i].state;
- code2 = keyw[i].code;
- i = 0;
- break;
- }
- }
- if (i != 0 || state != state2 ||
- (state2 != s_month && state2 != s_wday) || code == code2) {
- scan_err0(lc, _("Invalid month or weekday range"));
- }
- if (state == s_wday) {
- if (!have_wday) {
- clear_bits(0, 6, lrun.wday);
- clear_bits(0, 30, lrun.mday);
- have_wday = TRUE;
- }
- if (code < code2) {
- set_bits(code, code2, lrun.wday);
- } else {
- set_bits(code, 6, lrun.wday);
- set_bits(0, code2, lrun.wday);
- }
- } else {
- /* must be s_month */
- if (!have_month) {
- clear_bits(0, 30, lrun.month);
- have_month = TRUE;
- }
- if (code < code2) {
- set_bits(code, code2, lrun.month);
- } else {
- /* this is a bit odd, but we accept it anyway */
- set_bits(code, 30, lrun.month);
- set_bits(0, code2, lrun.month);
- }
- }
- break;
- case s_hourly:
- clear_defaults();
- set_bits(0, 23, lrun.hour);
- set_bits(0, 30, lrun.mday);
- set_bits(0, 11, lrun.month);
- break;
- case s_weekly:
- clear_defaults();
- set_bit(0, lrun.wday);
- set_bits(0, 11, lrun.month);
- break;
- case s_daily:
- clear_defaults();
- set_bits(0, 30, lrun.mday);
- set_bits(0, 11, lrun.month);
- break;
- case s_monthly:
- clear_defaults();
- set_bit(0, lrun.mday);
- set_bits(0, 11, lrun.month);
- break;
- default:
- scan_err0(lc, _("Unexpected run state\n"));
- break;
+ case s_none:
+ continue;
+ case s_mday: /* day of month */
+ if (!have_mday) {
+ clear_bits(0, 30, lrun.mday);
+ have_mday = true;
+ }
+ set_bit(code, lrun.mday);
+ break;
+ case s_month: /* month of year */
+ if (!have_month) {
+ clear_bits(0, 11, lrun.month);
+ have_month = true;
+ }
+ set_bit(code, lrun.month);
+ break;
+ case s_wday: /* week day */
+ if (!have_wday) {
+ clear_bits(0, 6, lrun.wday);
+ have_wday = true;
+ }
+ set_bit(code, lrun.wday);
+ break;
+ case s_wom: /* Week of month 1st, ... */
+ if (!have_wom) {
+ clear_bits(0, 4, lrun.wom);
+ have_wom = true;
+ }
+ set_bit(code, lrun.wom);
+ break;
+ case s_woy:
+ if (!have_woy) {
+ clear_bits(0, 53, lrun.woy);
+ have_woy = true;
+ }
+ set_bit(code, lrun.woy);
+ break;
+ case s_time: /* time */
+ if (!have_at) {
+ scan_err0(lc, _("Time must be preceded by keyword AT."));
+ /* NOT REACHED */
+ }
+ if (!have_hour) {
+ clear_bits(0, 23, lrun.hour);
+ }
+// Dmsg1(000, "s_time=%s\n", lc->str);
+ p = strchr(lc->str, ':');
+ if (!p) {
+ scan_err0(lc, _("Time logic error.\n"));
+ /* NOT REACHED */
+ }
+ *p++ = 0; /* separate two halves */
+ code = atoi(lc->str); /* pick up hour */
+ code2 = atoi(p); /* pick up minutes */
+ len = strlen(p);
+ if (len >= 2) {
+ p += 2;
+ }
+ if (strcasecmp(p, "pm") == 0) {
+ pm = true;
+ } else if (strcasecmp(p, "am") == 0) {
+ am = true;
+ } else if (len != 2) {
+ scan_err0(lc, _("Bad time specification."));
+ /* NOT REACHED */
+ }
+ /*
+ * Note, according to NIST, 12am and 12pm are ambiguous and
+ * can be defined to anything. However, 12:01am is the same
+ * as 00:01 and 12:01pm is the same as 12:01, so we define
+ * 12am as 00:00 and 12pm as 12:00.
+ */
+ if (pm) {
+ /* Convert to 24 hour time */
+ if (code != 12) {
+ code += 12;
+ }
+ /* am */
+ } else if (am && code == 12) {
+ code -= 12;
+ }
+ if (code < 0 || code > 23 || code2 < 0 || code2 > 59) {
+ scan_err0(lc, _("Bad time specification."));
+ /* NOT REACHED */
+ }
+// Dmsg2(000, "hour=%d min=%d\n", code, code2);
+ set_bit(code, lrun.hour);
+ lrun.minute = code2;
+ have_hour = true;
+ break;
+ case s_at:
+ have_at = true;
+ break;
+ case s_range:
+ p = strchr(lc->str, '-');
+ if (!p) {
+ scan_err0(lc, _("Range logic error.\n"));
+ }
+ *p++ = 0; /* separate two halves */
+
+ /* Check for day range */
+ if (is_an_integer(lc->str) && is_an_integer(p)) {
+ code = atoi(lc->str) - 1;
+ code2 = atoi(p) - 1;
+ if (code < 0 || code > 30 || code2 < 0 || code2 > 30) {
+ scan_err0(lc, _("Bad day range specification."));
+ }
+ if (!have_mday) {
+ clear_bits(0, 30, lrun.mday);
+ have_mday = true;
+ }
+ if (code < code2) {
+ set_bits(code, code2, lrun.mday);
+ } else {
+ set_bits(code, 30, lrun.mday);
+ set_bits(0, code2, lrun.mday);
+ }
+ break;
+ }
+ /* Check for week of year range */
+ if (strlen(lc->str) == 3 && strlen(p) == 3 &&
+ (lc->str[0] == 'w' || lc->str[0] == 'W') &&
+ (p[0] == 'w' || p[0] == 'W') &&
+ is_an_integer(lc->str+1) && is_an_integer(p+1)) {
+ code = atoi(lc->str+1);
+ code2 = atoi(p+1);
+ if (code < 0 || code > 53 || code2 < 0 || code2 > 53) {
+ scan_err0(lc, _("Week number out of range (0-53)"));
+ }
+ if (!have_woy) {
+ clear_bits(0, 53, lrun.woy);
+ have_woy = true;
+ }
+ if (code < code2) {
+ set_bits(code, code2, lrun.woy);
+ } else {
+ set_bits(code, 53, lrun.woy);
+ set_bits(0, code2, lrun.woy);
+ }
+ break;
+ }
+ /* lookup first half of keyword range (week days or months) */
+ lcase(lc->str);
+ for (i=0; keyw[i].name; i++) {
+ if (strcmp(lc->str, keyw[i].name) == 0) {
+ state = keyw[i].state;
+ code = keyw[i].code;
+ i = 0;
+ break;
+ }
+ }
+ if (i != 0 || (state != s_month && state != s_wday && state != s_wom)) {
+ scan_err0(lc, _("Invalid month, week or position day range"));
+ /* NOT REACHED */
+ }
+
+ /* Lookup end of range */
+ lcase(p);
+ for (i=0; keyw[i].name; i++) {
+ if (strcmp(p, keyw[i].name) == 0) {
+ state2 = keyw[i].state;
+ code2 = keyw[i].code;
+ i = 0;
+ break;
+ }
+ }
+ 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) {
+ clear_bits(0, 6, lrun.wday);
+ have_wday = true;
+ }
+ if (code < code2) {
+ set_bits(code, code2, lrun.wday);
+ } else {
+ set_bits(code, 6, lrun.wday);
+ set_bits(0, code2, lrun.wday);
+ }
+ } else if (state == s_month) {
+ if (!have_month) {
+ clear_bits(0, 11, lrun.month);
+ have_month = true;
+ }
+ if (code < code2) {
+ set_bits(code, code2, lrun.month);
+ } else {
+ /* this is a bit odd, but we accept it anyway */
+ set_bits(code, 11, lrun.month);
+ set_bits(0, code2, lrun.month);
+ }
+ } else {
+ /* Must be position */
+ if (!have_wom) {
+ clear_bits(0, 4, lrun.wom);
+ have_wom = true;
+ }
+ if (code < code2) {
+ set_bits(code, code2, lrun.wom);
+ } else {
+ set_bits(code, 4, lrun.wom);
+ set_bits(0, code2, lrun.wom);
+ }
+ }
+ break;
+ case s_hourly:
+ have_hour = true;
+ set_bits(0, 23, lrun.hour);
+ break;
+ case s_weekly:
+ have_mday = have_wom = have_woy = true;
+ set_bits(0, 30, lrun.mday);
+ set_bits(0, 4, lrun.wom);
+ set_bits(0, 53, lrun.woy);
+ break;
+ case s_daily:
+ have_mday = true;
+ set_bits(0, 6, lrun.wday);
+ break;
+ case s_monthly:
+ have_month = true;
+ set_bits(0, 11, lrun.month);
+ break;
+ default:
+ scan_err0(lc, _("Unexpected run state\n"));
+ /* NOT REACHED */
+ break;