From 4c0c28283cc9671f4a6ef01f4060fcbb418b9fd6 Mon Sep 17 00:00:00 2001 From: sgerwk Date: Sat, 28 Oct 2017 11:08:43 +0200 Subject: [PATCH] print all jobs executed in interval --- man/cronnext.1 | 12 ++++--- src/cronnext.c | 95 +++++++++++++++++++++++++++++--------------------- 2 files changed, 63 insertions(+), 44 deletions(-) diff --git a/man/cronnext.1 b/man/cronnext.1 index d3887b8..4233c42 100644 --- a/man/cronnext.1 +++ b/man/cronnext.1 @@ -7,7 +7,7 @@ cronnext \- time of next job cron will execute [\fB-i \fIusers\fR] [\fB-e \fIusers\fR] [\fB-s\fR] [\fB-a\fR] [\fB-t \fItime\fR] [\fB-q \fItime\fR] -[\fB-l\fR] [\fB-v\fR] [\fB-h\fR] [\fB-V\fR] +[\fB-l\fR] [\fB-c\fR] [\fB-f\fR] [\fB-h\fR] [\fB-V\fR] [file]... .SH DESCRIPTION Determine the time cron will execute the next job. Without arguments, it @@ -54,10 +54,12 @@ Epoch. Print the whole entries of the jobs that are the next to be executed by cron. The default is to only print their next time of execution. .TP -.B \-v -Scanning of the crontab is done in verbose mode. Each user and job the next -execution time is printed both as number of seconds since the Epoch and in -the standard format. +.B \-c +Print every entry in every crontab with the next time it is executed. +.TP +.B \-f +Print all jobs that are executed in the given interval. Requires option +\fB-q\fR. .TP .B \-h Print usage output and exit. diff --git a/src/cronnext.c b/src/cronnext.c index 19447f4..eebe410 100644 --- a/src/cronnext.c +++ b/src/cronnext.c @@ -32,9 +32,11 @@ #include "funcs.h" #include "cron-paths.h" -/* what to print: entries, crontabs, both */ -#define ENTRIES 0x01 -#define CRONTABS 0x02 +/* flags to crontab search */ +#define ENTRIES 0x01 // print entries +#define CRONTABS 0x02 // print crontabs +#define SYSTEM 0x04 // include system crontab +#define ALLJOBS 0x08 // print all jobs in interval #ifdef WITH_INOTIFY void set_cron_watched(int fd) { @@ -214,17 +216,18 @@ int matchuser(char *user, char *list) { */ time_t cronnext(cron_db database, time_t start, time_t end, - char *include, char *exclude, int system, - int verbose) { + char *include, char *exclude, int flags) { time_t closest, next; user *u; entry *e; char *indent = ""; - if (verbose & CRONTABS) { + if (flags & CRONTABS) { printf("crontabs:\n"); indent = " "; } + else if (flags & ALLJOBS) + printf("jobs:\n"); /* find next sheduled time */ closest = -1; @@ -233,21 +236,25 @@ time_t cronnext(cron_db database, continue; if (exclude && matchuser(u->name, exclude)) continue; - if (!system && u->system) + if (!(flags & SYSTEM) && u->system) continue; - if (verbose & CRONTABS) + if (flags & CRONTABS) printcrontab(u); - for (e = u->crontab; e; e = e->next) { - next = nextmatch(e, start, end); - if (next < 0) - continue; - if ((closest < 0) || (next < closest)) - closest = next; - if (verbose & ENTRIES) - printentry(indent, e, next); - } + for (e = u->crontab; e; e = e->next) + for (next = nextmatch(e, start, end); + next <= end; + next = nextmatch(e, next + 60, end)) { + if (next < 0) + break; + if (closest < 0 || next < closest) + closest = next; + if (flags & ENTRIES) + printentry(indent, e, next); + if (! (flags & ALLJOBS)) + break; + } } return closest; @@ -299,7 +306,8 @@ void usage() { fprintf(stderr, " -t time start from this time (seconds since epoch)\n"); fprintf(stderr, " -q time end check at this time (seconds since epoch)\n"); fprintf(stderr, " -l print next jobs to be executed\n"); - fprintf(stderr, " -v verbose mode\n"); + fprintf(stderr, " -c print next execution of each job\n"); + fprintf(stderr, " -f print all jobs executed in the given interval\n"); fprintf(stderr, " -h this help\n"); fprintf(stderr, " -V print version and exit\n"); } @@ -310,21 +318,20 @@ void usage() { int main(int argn, char *argv[]) { int opt; char *include, *exclude; - int system, verbose, endtime, printjobs; + int flags; time_t start, end, next; + int endtime, printjobs; + cron_db db; + int installed = 0; include = NULL; exclude = NULL; - system = 1; + flags = SYSTEM; endtime = 0; printjobs = 0; start = time(NULL); - int installed = 0; - verbose = 0; - - cron_db db; - while (-1 != (opt = getopt(argn, argv, "i:e:ast:vhV"))) { + while (-1 != (opt = getopt(argn, argv, "i:e:ast:q:lcfhV"))) { switch (opt) { case 'i': include = optarg; @@ -336,7 +343,7 @@ int main(int argn, char *argv[]) { installed = 1; break; case 's': - system = 0; + flags &= ~SYSTEM; break; case 't': start = atoi(optarg); @@ -348,8 +355,11 @@ int main(int argn, char *argv[]) { case 'l': printjobs = 1; break; - case 'v': - verbose = ENTRIES | CRONTABS; + case 'c': + flags |= ENTRIES | CRONTABS; + break; + case 'f': + flags |= ALLJOBS | ENTRIES; break; case 'h': usage(); @@ -365,6 +375,12 @@ int main(int argn, char *argv[]) { } } + if (flags & ALLJOBS && !endtime) { + fprintf(stderr, "no ending time specified: -f requires -q\n"); + usage(); + exit(EXIT_FAILURE); + } + /* maximum match interval is 8 years: * crontab has '* * 29 2 *' and we are on 1 March 2096: * next matching time will be 29 February 2104 */ @@ -372,7 +388,7 @@ int main(int argn, char *argv[]) { end = start + 8 * 12 * 31 * 24 * 60 * 60; /* debug cron */ - if (verbose) { + if (flags & CRONTABS) { printf("spool: %s\n", SPOOL_DIR); set_debug_flags(""); } @@ -382,19 +398,20 @@ int main(int argn, char *argv[]) { /* load database */ db = database(installed || argv[optind] == NULL, argv + optind); - /* print time of next scheduled command */ - next = cronnext(db, start, end, include, exclude, system, verbose); - if (next == -1) { - if (verbose) - printf("no job scheduled\n"); + /* find time of next scheduled command */ + next = cronnext(db, start, end, include, exclude, flags); + + /* print time */ + if (next == -1) return EXIT_FAILURE; - } - else if (verbose || printjobs) { + else + printf("next: %ld\n", (long) next); + + /* print next jobs */ + if (printjobs) { printf("nextjobs:\n"); - cronnext(db, next, next, include, exclude, system, ENTRIES); + cronnext(db, next, next, include, exclude, (flags & SYSTEM) | ENTRIES); } - else - printf("%ld\n", (long) next); return EXIT_SUCCESS; } -- 2.40.0