Our "at -l" currently acts like the historic BSD atq which takes a
list of users instead of a list of jobs.  The following diff accepts
either a user or a job number for "at -l".  The "at -l user" syntax
is still accepted but no longer documented.  This is similar to how
we handle differences in "at -r" vs. atrm.

 - todd

Index: usr.bin/at/at.1
===================================================================
RCS file: /cvs/src/usr.bin/at/at.1,v
retrieving revision 1.52
diff -u -p -u -r1.52 at.1
--- usr.bin/at/at.1     16 Sep 2014 15:56:36 -0000      1.52
+++ usr.bin/at/at.1     15 Nov 2015 23:25:17 -0000
@@ -35,7 +35,7 @@
 .Nm at
 .Op Fl bm
 .Op Fl f Ar file
-.Op Fl l Op Ar user ...
+.Op Fl l Op Ar job ...
 .Op Fl q Ar queue
 .Fl t Ar time_arg | timespec
 .Nm at
@@ -85,12 +85,11 @@ Prints the jobs listed on the command li
 Reads the job from
 .Ar file
 rather than standard input.
-.It Fl l Op Ar user ...
+.It Fl l Op Ar job ...
 Displays the queue of jobs which are currently awaiting execution.
 If a
-.Ar user
-argument is specified, only jobs belonging to that user will
-be displayed.
+.Ar job
+argument is specified, only the specified jobs will be displayed.
 Unless the user is the superuser, only the user's own jobs will be
 displayed.
 .It Fl m
@@ -336,10 +335,7 @@ and
 .Nm batch
 utilities are compliant with the
 .St -p1003.1-2008
-specification,
-except behaviour for the
-.Fl l
-flag differs.
+specification.
 .Pp
 The
 .Nm
Index: usr.bin/at/at.c
===================================================================
RCS file: /cvs/src/usr.bin/at/at.c,v
retrieving revision 1.76
diff -u -p -u -r1.76 at.c
--- usr.bin/at/at.c     13 Nov 2015 21:35:34 -0000      1.76
+++ usr.bin/at/at.c     15 Nov 2015 23:31:04 -0000
@@ -444,28 +444,41 @@ list_jobs(int argc, char **argv, int cou
        struct atjob **atjobs, **newatjobs, *job;
        struct stat stbuf;
        time_t runtimer;
+       char **jobs;
        uid_t *uids;
        char queue, *ep;
        DIR *spool;
+       int job_matches, jobs_len, uids_len;
        int dfd, i, shortformat;
        size_t numjobs, maxjobs;
 
        syslog(LOG_INFO, "(%s) LIST (%s)", user_name,
            user_uid ? user_name : "ALL");
 
+       /* Convert argv into a list of jobs and uids. */
+       jobs = NULL;
+       uids = NULL;
+       jobs_len = uids_len = 0;
+
        if (argc) {
-               if ((uids = calloc(sizeof(uid_t), argc)) == NULL)
+               if ((jobs = reallocarray(NULL, argc, sizeof(char *))) == NULL ||
+                   (uids = reallocarray(NULL, argc, sizeof(uid_t))) == NULL)
                        fatal(NULL);
 
                for (i = 0; i < argc; i++) {
-                       if ((pw = getpwnam(argv[i])) == NULL)
+                       if (strtot(argv[i], &ep, &runtimer) == 0 &&
+                           *ep == '.' && isalpha((unsigned char)*(ep + 1)) &&
+                           *(ep + 2) == '\0')
+                               jobs[jobs_len++] = argv[i];
+                       else if ((pw = getpwnam(argv[i])) != NULL) {
+                               if (pw->pw_uid != user_uid && user_uid != 0)
+                                       fatalx("only the superuser may "
+                                           "display other users' jobs");
+                               uids[uids_len++] = pw->pw_uid;
+                       } else
                                fatalx("unknown user %s", argv[i]);
-                       if (pw->pw_uid != user_uid && user_uid != 0)
-                               fatalx("only the superuser may display other 
users' jobs");
-                       uids[i] = pw->pw_uid;
                }
-       } else
-               uids = NULL;
+       }
 
        shortformat = strcmp(__progname, "at") == 0;
 
@@ -483,7 +496,7 @@ list_jobs(int argc, char **argv, int cou
         */
        numjobs = 0;
        maxjobs = stbuf.st_nlink + 4;
-       atjobs = calloc(maxjobs, sizeof(struct atjob *));
+       atjobs = reallocarray(NULL, maxjobs, sizeof(struct atjob *));
        if (atjobs == NULL)
                fatal(NULL);
 
@@ -511,15 +524,26 @@ list_jobs(int argc, char **argv, int cou
                if (atqueue && (queue != atqueue))
                        continue;
 
-               /* Check against specified user(s). */
-               if (argc) {
-                       for (i = 0; i < argc; i++) {
-                               if (uids[0] == stbuf.st_uid)
+               /* Check against specified jobs and/or user(s). */
+               job_matches = (argc == 0) ? 1 : 0;
+               if (!job_matches) {
+                       for (i = 0; i < jobs_len; i++) {
+                               if (strcmp(dirent->d_name, jobs[i]) == 0) {
+                                       job_matches = 1;
+                                       break;
+                               }
+                       }
+               }
+               if (!job_matches) {
+                       for (i = 0; i < uids_len; i++) {
+                               if (uids[i] == stbuf.st_uid) {
+                                       job_matches = 1;
                                        break;
+                               }
                        }
-                       if (i == argc)
-                               continue;       /* user doesn't match */
                }
+               if (!job_matches)
+                       continue;
 
                if (count_only) {
                        numjobs++;
@@ -597,7 +621,6 @@ process_jobs(int argc, char **argv, int 
        time_t runtimer;
        uid_t *uids;
        char **jobs, *ep;
-       long l;
        FILE *fp;
        DIR *spool;
        int job_matches, jobs_len, uids_len;
@@ -612,14 +635,14 @@ process_jobs(int argc, char **argv, int 
        uids = NULL;
        jobs_len = uids_len = 0;
        if (argc > 0) {
-               if ((jobs = calloc(sizeof(char *), argc)) == NULL ||
-                   (uids = calloc(sizeof(uid_t), argc)) == NULL)
+               if ((jobs = reallocarray(NULL, argc, sizeof(char *))) == NULL ||
+                   (uids = reallocarray(NULL, argc, sizeof(uid_t))) == NULL)
                        fatal(NULL);
 
                for (i = 0; i < argc; i++) {
-                       l = strtol(argv[i], &ep, 10);
-                       if (*ep == '.' && isalpha((unsigned char)*(ep + 1)) &&
-                           *(ep + 2) == '\0' && l > 0 && l < INT_MAX)
+                       if (strtot(argv[i], &ep, &runtimer) == 0 &&
+                           *ep == '.' && isalpha((unsigned char)*(ep + 1)) &&
+                           *(ep + 2) == '\0')
                                jobs[jobs_len++] = argv[i];
                        else if ((pw = getpwnam(argv[i])) != NULL) {
                                if (user_uid != pw->pw_uid && user_uid != 0) {
@@ -817,7 +840,7 @@ usage(void)
        case AT:
        case CAT:
                (void)fprintf(stderr,
-                   "usage: at [-bm] [-f file] [-l [user ...]] [-q queue] "
+                   "usage: at [-bm] [-f file] [-l [job ...]] [-q queue] "
                    "-t time_arg | timespec\n"
                    "       at -c | -r job ...\n");
                break;

Reply via email to