summaryrefslogtreecommitdiff
path: root/usr.bin/at/at.c
diff options
context:
space:
mode:
authorTodd C. Miller <millert@cvs.openbsd.org>2015-11-16 16:43:07 +0000
committerTodd C. Miller <millert@cvs.openbsd.org>2015-11-16 16:43:07 +0000
commitf3b52ab4fdac1de692d6541eced0ba69f0449777 (patch)
treea60a6ff18ab157971abf15c166681cc714332bc8 /usr.bin/at/at.c
parenteb7365b86928eaf51db717fd510590c688436513 (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/at.c')
-rw-r--r--usr.bin/at/at.c67
1 files changed, 45 insertions, 22 deletions
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;