sbase

suckless unix tools
git clone git://git.suckless.org/sbase
Log | Files | Refs | README | LICENSE

commit 5f6a3dad770e6e57218c3b82f96a8ed9b7a5a23d
parent 11c53a1739e17c6fe5fb233e187e35d9600e6c60
Author: Roberto E. Vargas Caballero <k0ga@shike2.com>
Date:   Thu, 19 Dec 2024 12:53:24 +0100

cron: Revert to version before 6c8dc15

The changes introduced after 6c8dc15 had some problems and it
was really hard to follow the chain of changes, and for that
reason I took the conservative decision of reverting to the
original code.

Diffstat:
Mcron.c | 250+++++++++++++++++++++++++++++++++++++++----------------------------------------
1 file changed, 123 insertions(+), 127 deletions(-)

diff --git a/cron.c b/cron.c @@ -17,13 +17,19 @@ #include "queue.h" #include "util.h" -struct range { - long low, high, repeat; - TAILQ_ENTRY(range) entry; +struct field { + enum { + ERROR, + WILDCARD, + NUMBER, + RANGE, + REPEAT, + LIST + } type; + long *val; + int len; }; -TAILQ_HEAD(field, range); - struct ctabentry { struct field min; struct field hour; @@ -196,148 +202,141 @@ matchentry(struct ctabentry *cte, struct tm *tm) { .f = &cte->wday, .tm = tm->tm_wday, .len = 7 }, }; size_t i; - int found, t; - long low; - struct range *r; + int j; for (i = 0; i < LEN(matchtbl); i++) { - found = 0; - t = matchtbl[i].tm; - TAILQ_FOREACH(r, matchtbl[i].f, entry) { - if (r->low <= t && r->high >= t && t % r->repeat == 0) { - found = 1; - break; + switch (matchtbl[i].f->type) { + case WILDCARD: + continue; + case NUMBER: + if (matchtbl[i].f->val[0] == matchtbl[i].tm) + continue; + break; + case RANGE: + if (matchtbl[i].f->val[0] <= matchtbl[i].tm) + if (matchtbl[i].f->val[1] >= matchtbl[i].tm) + continue; + break; + case REPEAT: + if (matchtbl[i].tm > 0) { + if (matchtbl[i].tm % matchtbl[i].f->val[0] == 0) + continue; + } else { + if (matchtbl[i].len % matchtbl[i].f->val[0] == 0) + continue; } - } - if (!found) break; + case LIST: + for (j = 0; j < matchtbl[i].f->len; j++) + if (matchtbl[i].f->val[j] == matchtbl[i].tm) + break; + if (j < matchtbl[i].f->len) + continue; + break; + default: + break; + } + break; } if (i != LEN(matchtbl)) return 0; - return 1; } - static int -parserange(char *str, long low, long high, struct range *r) +parsefield(const char *field, long low, long high, struct field *f) { - /* range = number | - * [number] "~" [number] ["/" number] | - * number "-" number ["/" number] - */ - char *range, *repeat, *strlow, *strhigh; - char *e; - int random; - - random = 0; - - range = strsep(&str, "/"); - repeat = strsep(&str, "/"); - if (!range || !*range) - return -1; + int i; + char *e1, *e2; + const char *p; + + p = field; + while (isdigit(*p)) + p++; + + f->type = ERROR; + + switch (*p) { + case '*': + if (strcmp(field, "*") == 0) { + f->val = NULL; + f->len = 0; + f->type = WILDCARD; + } else if (strncmp(field, "*/", 2) == 0) { + f->val = emalloc(sizeof(*f->val)); + f->len = 1; - switch (*range) { - case '~': - random = 1; - case '*': /* fallthru */ - if (range[1] != '\0') - return -1; - r->low = low; - r->high = high; + errno = 0; + f->val[0] = strtol(field + 2, &e1, 10); + if (e1[0] != '\0' || errno != 0 || f->val[0] == 0) + break; + + f->type = REPEAT; + } break; - ARGNUM: - strlow = strsep(&range, "-"); - strhigh = strsep(&range, "-"); - if (!*strlow) /* i.e. - */ - return -1; + case '\0': + f->val = emalloc(sizeof(*f->val)); + f->len = 1; errno = 0; - r->low = strtol(strlow, &e, 10); - if ((*e && *e != '~') || errno != 0) - return -1; - if (strhigh) { - if (!*strhigh || range != NULL) /* i.e. N- or N-M-... */ - return -1; - errno = 0; - r->high = strtol(strhigh, &e, 10); - if (*e || errno != 0) - return -1; - } else { - e = strsep(&strlow, "~"); - if (!strlow) /* i.e. N */ - r->high = r->low; - strhigh = strsep(&strlow, "-"); - if (strhigh) { - if (!*strhigh || strlow != NULL) /* i.e. N~ or N~M~... */ - return -1; - random = 1; - - errno = 0; - r->high = strtol(strhigh, &e, 10); - if (*e || errno != 0) - return -1; - } - } + f->val[0] = strtol(field, &e1, 10); + if (e1[0] != '\0' || errno != 0) + break; + + f->type = NUMBER; break; - } + case '-': + f->val = emalloc(2 * sizeof(*f->val)); + f->len = 2; - if (repeat) { - if (!*repeat || str != NULL) - return -1; errno = 0; - r->repeat = strtol(repeat, &e, 10); - if (*e || errno != 0 || r->repeat == 0) - return -1; - } else { - r->repeat = 1; - } + f->val[0] = strtol(field, &e1, 10); + if (e1[0] != '-' || errno != 0) + break; - if (random) { - /* random replaces low in matchentry() */ - r->repeat = r->low; /* so that it doesn't repeat */ - r->low = random_uniform(r->high - r->low+1) + r->low; - } + errno = 0; + f->val[1] = strtol(e1 + 1, &e2, 10); + if (e2[0] != '\0' || errno != 0) + break; - if (r->low < low || r->low > high || r->high < low || r->high > high || r->repeat < low || r->repeat > high) { - return -1; - } + f->type = RANGE; + break; + case ',': + for (i = 1; isdigit(*p) || *p == ','; p++) + if (*p == ',') + i++; + f->val = emalloc(i * sizeof(*f->val)); + f->len = i; - return 0; -} + errno = 0; + f->val[0] = strtol(field, &e1, 10); + if (f->val[0] < low || f->val[0] > high) + break; -static int -parsefield(char *field, long low, long high, struct field *f) -{ - char *elem; - struct range *r; - - int first = 1; - while ((elem = strsep(&field, ",")) != NULL) { - if (*elem == '\0') - return -1; - first = 0; - - r = emalloc(sizeof(*r)); - if (parserange(elem, low, high, r)) - return -1; - TAILQ_INSERT_TAIL(f, r, entry); - } + for (i = 1; *e1 == ',' && errno == 0; i++) { + errno = 0; + f->val[i] = strtol(e1 + 1, &e2, 10); + e1 = e2; + } + if (e1[0] != '\0' || errno != 0) + break; - if (first) + f->type = LIST; + break; + default: return -1; + } - return 0; -} + for (i = 0; i < f->len; i++) + if (f->val[i] < low || f->val[i] > high) + f->type = ERROR; -static void -freefield(struct field *f) -{ - struct range *r; - while ((r = TAILQ_FIRST(f))) { - TAILQ_REMOVE(f, r, entry); - free(r); + if (f->type == ERROR) { + free(f->val); + return -1; } + + return 0; } static void @@ -347,15 +346,15 @@ freecte(struct ctabentry *cte, int nfields) case 6: free(cte->cmd); case 5: - freefield(&cte->wday); + free(cte->wday.val); case 4: - freefield(&cte->mon); + free(cte->mon.val); case 3: - freefield(&cte->mday); + free(cte->mday.val); case 2: - freefield(&cte->hour); + free(cte->hour.val); case 1: - freefield(&cte->min); + free(cte->min.val); } free(cte); } @@ -413,7 +412,6 @@ loadentries(void) flim[4].f = &cte->wday; for (x = 0; x < LEN(flim); x++) { - TAILQ_INIT(flim[x].f); do col = strsep(&p, "\t\n "); while (col && col[0] == '\0'); @@ -527,8 +525,6 @@ main(int argc, char *argv[]) sigaction(SIGHUP, &sa, NULL); sigaction(SIGTERM, &sa, NULL); - random_seed(); - loadentries(); while (1) {