7812 Remove gender specific language
[unleashed.git] / usr / src / cmd / cron / atrm.c
blob46e58fcf0f5214c1b68e6437d0bb9b3d2131f217
1 /*
2 * Copyright 2009 Sun Microsystems, Inc. All rights reserved.
3 * Use is subject to license terms.
4 * Copyright (c) 2016 by Delphix. All rights reserved.
5 */
7 /* Copyright (c) 1984, 1986, 1987, 1988, 1989 AT&T */
8 /* All Rights Reserved */
12 * Copyright (c) 1983 Regents of the University of California.
13 * All rights reserved. The Berkeley software License Agreement
14 * specifies the terms and conditions for redistribution.
18 * synopsis: atrm [-f] [-i] [-a] [[job #] [user] ...]
21 * Remove "at" jobs.
24 #include <stdio.h>
25 #include <pwd.h>
26 #include <ctype.h>
27 #include <sys/types.h>
28 #include <dirent.h>
29 #include <sys/file.h>
30 #include <sys/stat.h>
31 #include <errno.h>
32 #include <unistd.h>
33 #include <locale.h>
34 #include <strings.h>
35 #include <stdlib.h>
36 #include <libintl.h>
37 #include "cron.h"
38 #include "getresponse.h"
40 extern time_t num();
41 extern char *errmsg();
42 extern void audit_at_delete(char *, char *, int);
44 #define SUPERUSER 0 /* is user super-user? */
45 #define CANTCD "can't change directory to the at directory"
46 #define NOREADDIR "can't read the at directory"
48 uid_t user; /* person requesting removal */
49 int fflag = 0; /* suppress announcements? */
50 int iflag = 0; /* run interactively? */
52 char login[UNAMESIZE];
53 char login_authchk[UNAMESIZE]; /* used for authorization checks */
55 #define INVALIDUSER "you are not a valid user (no entry in /etc/passwd)"
56 #define NOTALLOWED "you are not authorized to use at. Sorry."
57 #define NAMETOOLONG "login name too long"
59 static void usage(void);
60 static void atabortperror(char *msg);
61 static void atabort(char *msg);
62 static void atperror(char *msg);
63 static void atperror2(char *msg, char *name);
64 static void aterror(char *msg);
65 static void powner(char *file);
67 int getjoblist(struct dirent ***, struct stat ***, int (*)());
68 int removentry(char *, struct stat *, uid_t);
70 int
71 main(int argc, char **argv)
73 int i; /* for loop index */
74 int numjobs; /* # of jobs in spooling area */
75 int allflag = 0; /* remove all jobs belonging to user? */
76 int jobexists; /* does a requested job exist? */
77 char *pp;
78 struct dirent **namelist; /* names of jobs in spooling area */
79 struct stat **statlist;
80 struct passwd *pwd;
83 * If job number, user name, or "-" is not specified, just print
84 * usage info and exit.
86 (void) setlocale(LC_ALL, "");
87 (void) textdomain(TEXT_DOMAIN);
88 if (argc < 2)
89 usage();
91 --argc; ++argv;
93 pp = getuser((user = getuid()));
94 if (pp == NULL)
95 atabort(INVALIDUSER);
96 if (strlcpy(login, pp, sizeof (login)) >= sizeof (login))
97 atabort(NAMETOOLONG);
98 if (strlcpy(login_authchk, pp, sizeof (login_authchk))
99 >= sizeof (NAMETOOLONG))
100 atabort(INVALIDUSER);
101 if (!allowed(login, ATALLOW, ATDENY))
102 atabort(NOTALLOWED);
105 * Process command line flags.
106 * Special case the "-" option so that others may be grouped.
108 while (argc > 0 && **argv == '-') {
109 *(*argv)++;
110 while (**argv) {
111 switch (*(*argv)++) {
113 case 'a': ++allflag;
114 break;
116 case 'f': ++fflag;
117 break;
119 case 'i': ++iflag;
120 break;
122 default: usage();
125 ++argv; --argc;
129 * If all jobs are to be removed and extra command line arguments
130 * are given, print usage info and exit.
132 if (allflag && argc)
133 usage();
136 * If only certain jobs are to be removed and no job #'s or user
137 * names are specified, print usage info and exit.
139 if (!allflag && !argc)
140 usage();
143 * If interactive removal and quiet removal are requested, override
144 * quiet removal and run interactively.
146 if (iflag && fflag)
147 fflag = 0;
151 * Move to spooling directory and get a list of the files in the
152 * spooling area.
154 numjobs = getjoblist(&namelist, &statlist, strcmp);
156 * If all jobs belonging to the user are to be removed, compare
157 * the user's id to the owner of the file. If they match, remove
158 * the file. If the user is the super-user, don't bother comparing
159 * the id's. After all files are removed, exit (status 0).
161 if (allflag) {
162 for (i = 0; i < numjobs; ++i) {
163 if (cron_admin(login_authchk) ||
164 user == statlist[i]->st_uid)
165 (void) removentry(namelist[i]->d_name,
166 statlist[i], user);
168 exit(0);
172 * If only certain jobs are to be removed, interpret each command
173 * line argument. A check is done to see if it is a user's name or
174 * a job number (inode #). If it's a user's name, compare the argument
175 * to the files owner. If it's a job number, compare the argument to
176 * the file name. In either case, if a match occurs, try to
177 * remove the file.
180 while (argc--) {
181 jobexists = 0;
182 for (i = 0; i < numjobs; ++i) {
184 /* if the inode number is 0, this entry was removed */
185 if (statlist[i]->st_ino == 0)
186 continue;
189 * if argv is a username, compare their uid to
190 * the uid of the owner of the file......
192 if (pwd = getpwnam(*argv)) {
193 if (statlist[i]->st_uid != pwd->pw_uid)
194 continue;
196 * otherwise, we assume that the argv is a job # and
197 * thus compare argv to the file name.
199 } else {
200 if (strcmp(namelist[i]->d_name, *argv))
201 continue;
203 ++jobexists;
205 * if the entry is ultimately removed, don't
206 * try to remove it again later.
208 if (removentry(namelist[i]->d_name, statlist[i],
209 user)) {
210 statlist[i]->st_ino = 0;
215 * If a requested argument doesn't exist, print a message.
217 if (!jobexists && !fflag) {
218 fprintf(stderr, "atrm: %s: no such job number\n",
219 *argv);
221 ++argv;
223 return (0);
227 * Print usage info and exit.
229 static void
230 usage(void)
232 fprintf(stderr, "usage: atrm [-f] [-i] [-a] [[job #] [user] ...]\n");
233 exit(1);
238 * Remove an entry from the queue. The access of the file is checked for
239 * write permission (since all jobs are mode 644). If access is granted,
240 * unlink the file. If the fflag (suppress announcements) is not set,
241 * print the job number that we are removing and the result of the access
242 * check (either "permission denied" or "removed"). If we are running
243 * interactively (iflag), prompt the user before we unlink the file. If
244 * the super-user is removing jobs, inform them who owns each file before
245 * it is removed. Return TRUE if file removed, else FALSE.
248 removentry(char *filename, struct stat *statptr, uid_t user)
250 struct passwd *pwd;
251 char *pp;
252 int r;
254 if (init_yes() < 0) {
255 (void) fprintf(stderr, gettext(ERR_MSG_INIT_YES),
256 strerror(errno));
257 exit(1);
260 if (!fflag)
261 printf("%s: ", filename);
263 if (user != statptr->st_uid && !cron_admin(login_authchk)) {
265 if (!fflag) {
266 printf("permission denied\n");
268 return (0);
270 } else {
271 if (iflag) {
272 if (cron_admin(login_authchk)) {
273 printf("\t(owned by ");
274 powner(filename);
275 printf(") ");
277 printf(gettext("remove it? "));
278 if (yes() == 0)
279 return (0);
282 if (cron_admin(login_authchk)) {
283 pp = getuser((uid_t)statptr->st_uid);
284 if (pp == NULL)
285 atabort(INVALIDUSER);
286 if (strlcpy(login, pp, sizeof (login)) >=
287 sizeof (login))
288 atabort(NAMETOOLONG);
290 cron_sendmsg(DELETE, login, filename, AT);
291 if ((r = unlink(filename)) < 0) {
292 if (!fflag) {
293 fputs("could not remove\n", stdout);
294 (void) fprintf(stderr, "atrm: %s: %s\n",
295 filename, errmsg(errno));
297 audit_at_delete(filename, NULL, r);
298 return (0);
300 audit_at_delete(filename, NULL, r);
301 if (!fflag && !iflag)
302 printf("removed\n");
303 return (1);
308 * Print the owner of the job. This is the owner of the spoolfile.
309 * If we run into trouble getting the name, we'll just print "???".
311 static void
312 powner(char *file)
314 struct stat statb;
315 char *getname();
317 if (stat(file, &statb) < 0) {
318 printf("%s", "???");
319 (void) fprintf(stderr, "atrm: Couldn't stat spoolfile %s: %s\n",
320 file, errmsg(errno));
321 return;
324 printf("%s", getname(statb.st_uid));
329 getjoblist(struct dirent ***namelistp, struct stat ***statlistp,
330 int (*sortfunc)())
332 int numjobs;
333 struct dirent **namelist;
334 int i;
335 struct stat *statptr; /* pointer to file stat structure */
336 struct stat **statlist;
337 extern int filewanted(); /* should a file be listed in queue? */
338 if (chdir(ATDIR) < 0)
339 atabortperror(CANTCD);
342 * Get a list of the files in the spooling area.
344 if ((numjobs = scandir(".", namelistp, filewanted, sortfunc)) < 0)
345 atabortperror(NOREADDIR);
347 if ((statlist =
348 (struct stat **)malloc(numjobs * sizeof (struct stat ***)))
349 == NULL)
350 atabort("Out of memory");
352 namelist = *namelistp;
355 * Build an array of pointers to the file stats for all jobs in
356 * the spooling area.
358 for (i = 0; i < numjobs; ++i) {
359 statptr = (struct stat *)malloc(sizeof (struct stat));
360 if (statptr == NULL)
361 atabort("Out of memory");
362 if (stat(namelist[i]->d_name, statptr) < 0) {
363 atperror2("Can't stat", namelist[i]->d_name);
364 continue;
366 statlist[i] = statptr;
369 *statlistp = statlist;
370 return (numjobs);
374 * Get the full login name of a person using their user id.
376 char *
377 getname(uid_t uid)
379 struct passwd *pwdinfo; /* password info structure */
382 if ((pwdinfo = getpwuid(uid)) == 0)
383 return ("???");
384 return (pwdinfo->pw_name);
387 static void
388 aterror(char *msg)
390 fprintf(stderr, "atrm: %s\n", msg);
393 static void
394 atperror(char *msg)
396 fprintf(stderr, "atrm: %s: %s\n", msg, errmsg(errno));
399 static void
400 atperror2(char *msg, char *name)
402 fprintf(stderr, "atrm: %s %s: %s\n", msg, name, errmsg(errno));
405 static void
406 atabort(char *msg)
408 aterror(msg);
409 exit(1);
412 static void
413 atabortperror(char *msg)
415 atperror(msg);
416 exit(1);