]> granicus.if.org Git - cronie/commitdiff
cronnext can read additional crontabs from files
authorMarco Migliori <sgerwk@aol.com>
Thu, 2 Nov 2017 15:30:05 +0000 (16:30 +0100)
committerTomáš Mráz <t8m@users.noreply.github.com>
Fri, 3 Nov 2017 13:01:31 +0000 (14:01 +0100)
man/cronnext.1
src/cronnext.c

index 4a120f8a6b62f883b23d2ae2f61ee44c3cfd6878..621b8824a37c8a8746391463e38e40698e570013 100644 (file)
@@ -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
index 8a52e8770a150796c7df812354809c85b1e49855..e5d743cc2407d12319e63055a009d208d74e2ae8 100644 (file)
@@ -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");