.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
.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,...
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
/*
* 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) {
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");
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;
case 'e':
exclude = optarg;
break;
+ case 'a':
+ installed = 1;
+ break;
case 's':
system = 0;
break;
/* "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");