From: Marco Migliori Date: Thu, 2 Nov 2017 15:30:05 +0000 (+0100) Subject: cronnext can read additional crontabs from files X-Git-Tag: cronie-1.5.2~12 X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=1b7318c9c2d8350559e0c3320cf6226fcf57e2fd;p=cronie cronnext can read additional crontabs from files --- diff --git a/man/cronnext.1 b/man/cronnext.1 index 4a120f8..621b882 100644 --- a/man/cronnext.1 +++ b/man/cronnext.1 @@ -4,8 +4,11 @@ cronnext \- time of next job cron will execute .SH SYNOPSIS .TP 9 .B cronnext -[\fB-i \fIusers\fR] [\fB-e \fIusers\fR] [\fB-s\fR] [\fB-t \fItime\fR] +[\fB-i \fIusers\fR] [\fB-e \fIusers\fR] [\fB-s\fR] +[\fB-a\fR] +[\fB-t \fItime\fR] [\fB-v\fR] [\fB-h\fR] [\fB-V\fR] +[file]... .SH DESCRIPTION Determine the time cron will execute the next job. Without arguments, it prints that time considering all crontabs, in number of seconds since the @@ -13,6 +16,10 @@ Epoch. This number can be converted into other formats using .BR date (1), like .B date --date @43243254 + +The file arguments are optional. If provided, +.I cronnext +uses them as crontabs instead of the ones installed in the system. .SH OPTIONS .TP .BI "\-i " user,user,user,... @@ -24,12 +31,16 @@ for the system crontab. Do not consider the crontabs of the specified users. .TP .B \-s -Do not consider the system crontab, usually +Do not consider the system crontab, usually the .I /etc/crontab file. The system crontab usually contains the hourly, daily, weekly and montly crontabs, which might be better dealt with .BR anacron (8). .TP +.BI \-a +Use the crontabs installed in the system in addition to the ones passed as +file arguments. This is implicit if no file is passed. +.TP .BI "\-t " time Determine the next job from this time, instead of now. The time is expressed in number of seconds since the Epoch, as obtained for example by diff --git a/src/cronnext.c b/src/cronnext.c index 8a52e87..e5d743c 100644 --- a/src/cronnext.c +++ b/src/cronnext.c @@ -207,17 +207,14 @@ int matchuser(char *user, char *list) { /* * find next sheduled job */ -time_t cronnext(time_t start, +time_t cronnext(cron_db database, + time_t start, char *include, char *exclude, int system, int verbose) { time_t closest, next; - static cron_db database = {NULL, NULL, (time_t) 0}; user *u; entry *e; - /* load crontabs */ - load_database(&database); - /* find next sheduled time */ closest = -1; for (u = database.head; u; u = u->next) { @@ -245,15 +242,49 @@ time_t cronnext(time_t start, return closest; } +/* + * load installed crontabs and/or crontab files + */ +cron_db database(int installed, char **additional) { + cron_db db = {NULL, NULL, (time_t) 0}; + struct passwd pw; + int fd; + user *u; + + if (installed) + load_database(&db); + + for ( ; *additional != NULL; additional++) { + fd = open(*additional, O_RDONLY); + if (fd == -1) { + perror(*additional); + continue; + } + memset(&pw, 0, sizeof(pw)); + pw.pw_name = *additional; + pw.pw_passwd = ""; + pw.pw_dir = "."; + u = load_user(fd, &pw, *additional, *additional, *additional); + if (u == NULL) { + printf("cannot load crontab %s\n", *additional); + continue; + } + link_user(&db, u); + } + + return db; +} + void usage() { fprintf(stderr, "Find the time of the next scheduled cron job.\n"); fprintf(stderr, "Usage:\n"); - fprintf(stderr, " cronnext [options]\n"); + fprintf(stderr, " cronnext [options] [file ...]\n"); fprintf(stderr, "\n"); fprintf(stderr, "Options:\n"); fprintf(stderr, " -i users include only the crontab of these users\n"); fprintf(stderr, " -e users exclude the crontab of these users\n"); fprintf(stderr, " -s do not include the system crontab\n"); + fprintf(stderr, " -a examine installed crontabs even if files are given\n"); fprintf(stderr, " -t time start from this time (seconds since epoch)\n"); fprintf(stderr, " -v verbose mode\n"); fprintf(stderr, " -h this help\n"); @@ -273,9 +304,12 @@ int main(int argn, char *argv[]) { exclude = NULL; system = 1; start = time(NULL); + int installed = 0; verbose = 0; - while (-1 != (opt = getopt(argn, argv, "i:e:st:vhV"))) { + cron_db db; + + while (-1 != (opt = getopt(argn, argv, "i:e:ast:vhV"))) { switch (opt) { case 'i': include = optarg; @@ -283,6 +317,9 @@ int main(int argn, char *argv[]) { case 'e': exclude = optarg; break; + case 'a': + installed = 1; + break; case 's': system = 0; break; @@ -314,8 +351,11 @@ int main(int argn, char *argv[]) { /* "load,pars" for debugging loading and parsing, "" for nothing see globals.h for symbolic names and macros.h for meaning */ + /* load database */ + db = database(installed || argv[optind] == NULL, argv + optind); + /* print time of next scheduled command */ - next = cronnext(start, include, exclude, system, verbose); + next = cronnext(db, start, include, exclude, system, verbose); if (next == -1) { if (verbose) printf("no job scheduled\n");