#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) {
*/
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;
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;
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");
}
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;
installed = 1;
break;
case 's':
- system = 0;
+ flags &= ~SYSTEM;
break;
case 't':
start = atoi(optarg);
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();
}
}
+ 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 */
end = start + 8 * 12 * 31 * 24 * 60 * 60;
/* debug cron */
- if (verbose) {
+ if (flags & CRONTABS) {
printf("spool: %s\n", SPOOL_DIR);
set_debug_flags("");
}
/* 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;
}