diff options
author | Todd C. Miller <millert@cvs.openbsd.org> | 2015-11-16 16:43:07 +0000 |
---|---|---|
committer | Todd C. Miller <millert@cvs.openbsd.org> | 2015-11-16 16:43:07 +0000 |
commit | f3b52ab4fdac1de692d6541eced0ba69f0449777 (patch) | |
tree | a60a6ff18ab157971abf15c166681cc714332bc8 /usr.bin/at | |
parent | eb7365b86928eaf51db717fd510590c688436513 (diff) |
Make "at -l" comply with POSIX. Our "at -l" currently acts like
the historic BSD atq which takes a list of users instead of a list
of jobs. We now accept 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.
OK deraadt@ jmc@
Diffstat (limited to 'usr.bin/at')
-rw-r--r-- | usr.bin/at/at.1 | 18 | ||||
-rw-r--r-- | usr.bin/at/at.c | 67 |
2 files changed, 52 insertions, 33 deletions
diff --git a/usr.bin/at/at.1 b/usr.bin/at/at.1 index 0ca314abda9..5aa55a279d3 100644 --- a/usr.bin/at/at.1 +++ b/usr.bin/at/at.1 @@ -1,4 +1,4 @@ -.\" $OpenBSD: at.1,v 1.52 2014/09/16 15:56:36 jmc Exp $ +.\" $OpenBSD: at.1,v 1.53 2015/11/16 16:43:06 millert Exp $ .\" .\" Copyright (C) 1993, 1994 Thomas Koenig .\" Copyright (C) 1993 David Parsons @@ -24,7 +24,7 @@ .\" (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF .\" THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. .\" -.Dd $Mdocdate: September 16 2014 $ +.Dd $Mdocdate: November 16 2015 $ .Dt AT 1 .Os .Sh NAME @@ -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 line to standard output. 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 diff --git a/usr.bin/at/at.c b/usr.bin/at/at.c index 8b9798896e8..407d5df18cf 100644 --- a/usr.bin/at/at.c +++ b/usr.bin/at/at.c @@ -1,4 +1,4 @@ -/* $OpenBSD: at.c,v 1.76 2015/11/13 21:35:34 millert Exp $ */ +/* $OpenBSD: at.c,v 1.77 2015/11/16 16:43:06 millert Exp $ */ /* * at.c : Put file into atrun queue @@ -444,28 +444,41 @@ list_jobs(int argc, char **argv, int count_only, int csort) 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 count_only, int csort) */ 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 count_only, int csort) 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 what) 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 what) 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; |