1*032624d5Sbasabi /* 2*032624d5Sbasabi * Copyright 2005 Sun Microsystems, Inc. All rights reserved. 3*032624d5Sbasabi * Use is subject to license terms. 4*032624d5Sbasabi */ 5*032624d5Sbasabi 67c478bd9Sstevel@tonic-gate /* Copyright (c) 1984, 1986, 1987, 1988, 1989 AT&T */ 77c478bd9Sstevel@tonic-gate /* All Rights Reserved */ 87c478bd9Sstevel@tonic-gate 97c478bd9Sstevel@tonic-gate 107c478bd9Sstevel@tonic-gate /* 117c478bd9Sstevel@tonic-gate * Copyright (c) 1983 Regents of the University of California. 127c478bd9Sstevel@tonic-gate * All rights reserved. The Berkeley software License Agreement 137c478bd9Sstevel@tonic-gate * specifies the terms and conditions for redistribution. 147c478bd9Sstevel@tonic-gate */ 157c478bd9Sstevel@tonic-gate 16*032624d5Sbasabi #pragma ident "%Z%%M% %I% %E% SMI" 177c478bd9Sstevel@tonic-gate 187c478bd9Sstevel@tonic-gate /* 197c478bd9Sstevel@tonic-gate * synopsis: atrm [-f] [-i] [-a] [[job #] [user] ...] 207c478bd9Sstevel@tonic-gate * 217c478bd9Sstevel@tonic-gate * 227c478bd9Sstevel@tonic-gate * Remove "at" jobs. 237c478bd9Sstevel@tonic-gate */ 247c478bd9Sstevel@tonic-gate 257c478bd9Sstevel@tonic-gate #include <stdio.h> 267c478bd9Sstevel@tonic-gate #include <pwd.h> 277c478bd9Sstevel@tonic-gate #include <ctype.h> 287c478bd9Sstevel@tonic-gate #include <sys/types.h> 297c478bd9Sstevel@tonic-gate #include <dirent.h> 307c478bd9Sstevel@tonic-gate #include <sys/file.h> 317c478bd9Sstevel@tonic-gate #include <sys/stat.h> 327c478bd9Sstevel@tonic-gate #include <errno.h> 337c478bd9Sstevel@tonic-gate #include <unistd.h> 347c478bd9Sstevel@tonic-gate #include <locale.h> 35*032624d5Sbasabi #include <strings.h> 367c478bd9Sstevel@tonic-gate #include "cron.h" 377c478bd9Sstevel@tonic-gate 387c478bd9Sstevel@tonic-gate extern time_t num(); 397c478bd9Sstevel@tonic-gate extern char *errmsg(); 407c478bd9Sstevel@tonic-gate 417c478bd9Sstevel@tonic-gate extern void audit_at_delete(char *, char *, int); 427c478bd9Sstevel@tonic-gate 437c478bd9Sstevel@tonic-gate #define SUPERUSER 0 /* is user super-user? */ 447c478bd9Sstevel@tonic-gate #define CANTCD "can't change directory to the at directory" 457c478bd9Sstevel@tonic-gate #define NOREADDIR "can't read the at directory" 467c478bd9Sstevel@tonic-gate 477c478bd9Sstevel@tonic-gate uid_t user; /* person requesting removal */ 487c478bd9Sstevel@tonic-gate int fflag = 0; /* suppress announcements? */ 497c478bd9Sstevel@tonic-gate int iflag = 0; /* run interactively? */ 507c478bd9Sstevel@tonic-gate 517c478bd9Sstevel@tonic-gate char login[UNAMESIZE]; 527c478bd9Sstevel@tonic-gate char login_authchk[UNAMESIZE]; /* used for authorization checks */ 537c478bd9Sstevel@tonic-gate 547c478bd9Sstevel@tonic-gate #define INVALIDUSER "you are not a valid user (no entry in /etc/passwd)" 557c478bd9Sstevel@tonic-gate #define NOTALLOWED "you are not authorized to use at. Sorry." 567c478bd9Sstevel@tonic-gate #define NAMETOOLONG "login name too long" 577c478bd9Sstevel@tonic-gate 58*032624d5Sbasabi static void usage(void); 59*032624d5Sbasabi static void atabortperror(char *msg); 60*032624d5Sbasabi static void atabort(char *msg); 61*032624d5Sbasabi static void atperror(char *msg); 62*032624d5Sbasabi static void atperror2(char *msg, char *name); 63*032624d5Sbasabi static void aterror(char *msg); 64*032624d5Sbasabi static void powner(char *file); 657c478bd9Sstevel@tonic-gate 66*032624d5Sbasabi int 67*032624d5Sbasabi main(int argc, char **argv) 687c478bd9Sstevel@tonic-gate { 697c478bd9Sstevel@tonic-gate int i; /* for loop index */ 707c478bd9Sstevel@tonic-gate int numjobs; /* # of jobs in spooling area */ 717c478bd9Sstevel@tonic-gate int allflag = 0; /* remove all jobs belonging to user? */ 727c478bd9Sstevel@tonic-gate int jobexists; /* does a requested job exist? */ 737c478bd9Sstevel@tonic-gate char *pp; 747c478bd9Sstevel@tonic-gate char *getuser(); 757c478bd9Sstevel@tonic-gate struct dirent **namelist; /* names of jobs in spooling area */ 767c478bd9Sstevel@tonic-gate struct stat **statlist; 777c478bd9Sstevel@tonic-gate struct passwd *pwd; 787c478bd9Sstevel@tonic-gate 797c478bd9Sstevel@tonic-gate /* 807c478bd9Sstevel@tonic-gate * If job number, user name, or "-" is not specified, just print 817c478bd9Sstevel@tonic-gate * usage info and exit. 827c478bd9Sstevel@tonic-gate */ 837c478bd9Sstevel@tonic-gate (void) setlocale(LC_ALL, ""); 847c478bd9Sstevel@tonic-gate if (argc < 2) 857c478bd9Sstevel@tonic-gate usage(); 867c478bd9Sstevel@tonic-gate 877c478bd9Sstevel@tonic-gate --argc; ++argv; 887c478bd9Sstevel@tonic-gate 897c478bd9Sstevel@tonic-gate pp = getuser((user = getuid())); 907c478bd9Sstevel@tonic-gate if (pp == NULL) 917c478bd9Sstevel@tonic-gate atabort(INVALIDUSER); 927c478bd9Sstevel@tonic-gate if (strlcpy(login, pp, sizeof (login)) >= sizeof (login)) 937c478bd9Sstevel@tonic-gate atabort(NAMETOOLONG); 947c478bd9Sstevel@tonic-gate if (strlcpy(login_authchk, pp, sizeof (login_authchk)) 957c478bd9Sstevel@tonic-gate >= sizeof (NAMETOOLONG)) 967c478bd9Sstevel@tonic-gate atabort(INVALIDUSER); 977c478bd9Sstevel@tonic-gate if (!allowed(login, ATALLOW, ATDENY)) 987c478bd9Sstevel@tonic-gate atabort(NOTALLOWED); 997c478bd9Sstevel@tonic-gate 1007c478bd9Sstevel@tonic-gate /* 1017c478bd9Sstevel@tonic-gate * Process command line flags. 1027c478bd9Sstevel@tonic-gate * Special case the "-" option so that others may be grouped. 1037c478bd9Sstevel@tonic-gate */ 1047c478bd9Sstevel@tonic-gate while (argc > 0 && **argv == '-') { 1057c478bd9Sstevel@tonic-gate *(*argv)++; 106*032624d5Sbasabi while (**argv) { 107*032624d5Sbasabi switch (*(*argv)++) { 1087c478bd9Sstevel@tonic-gate 1097c478bd9Sstevel@tonic-gate case 'a': ++allflag; 1107c478bd9Sstevel@tonic-gate break; 1117c478bd9Sstevel@tonic-gate 1127c478bd9Sstevel@tonic-gate case 'f': ++fflag; 1137c478bd9Sstevel@tonic-gate break; 1147c478bd9Sstevel@tonic-gate 1157c478bd9Sstevel@tonic-gate case 'i': ++iflag; 1167c478bd9Sstevel@tonic-gate break; 1177c478bd9Sstevel@tonic-gate 1187c478bd9Sstevel@tonic-gate default: usage(); 1197c478bd9Sstevel@tonic-gate } 120*032624d5Sbasabi } 1217c478bd9Sstevel@tonic-gate ++argv; --argc; 1227c478bd9Sstevel@tonic-gate } 1237c478bd9Sstevel@tonic-gate 1247c478bd9Sstevel@tonic-gate /* 1257c478bd9Sstevel@tonic-gate * If all jobs are to be removed and extra command line arguments 1267c478bd9Sstevel@tonic-gate * are given, print usage info and exit. 1277c478bd9Sstevel@tonic-gate */ 1287c478bd9Sstevel@tonic-gate if (allflag && argc) 1297c478bd9Sstevel@tonic-gate usage(); 1307c478bd9Sstevel@tonic-gate 1317c478bd9Sstevel@tonic-gate /* 1327c478bd9Sstevel@tonic-gate * If only certain jobs are to be removed and no job #'s or user 1337c478bd9Sstevel@tonic-gate * names are specified, print usage info and exit. 1347c478bd9Sstevel@tonic-gate */ 1357c478bd9Sstevel@tonic-gate if (!allflag && !argc) 1367c478bd9Sstevel@tonic-gate usage(); 1377c478bd9Sstevel@tonic-gate 1387c478bd9Sstevel@tonic-gate /* 1397c478bd9Sstevel@tonic-gate * If interactive removal and quiet removal are requested, override 1407c478bd9Sstevel@tonic-gate * quiet removal and run interactively. 1417c478bd9Sstevel@tonic-gate */ 1427c478bd9Sstevel@tonic-gate if (iflag && fflag) 1437c478bd9Sstevel@tonic-gate fflag = 0; 1447c478bd9Sstevel@tonic-gate 1457c478bd9Sstevel@tonic-gate 1467c478bd9Sstevel@tonic-gate /* 1477c478bd9Sstevel@tonic-gate * Move to spooling directory and get a list of the files in the 1487c478bd9Sstevel@tonic-gate * spooling area. 1497c478bd9Sstevel@tonic-gate */ 1507c478bd9Sstevel@tonic-gate numjobs = getjoblist(&namelist, &statlist, strcmp); 1517c478bd9Sstevel@tonic-gate /* 1527c478bd9Sstevel@tonic-gate * If all jobs belonging to the user are to be removed, compare 1537c478bd9Sstevel@tonic-gate * the user's id to the owner of the file. If they match, remove 1547c478bd9Sstevel@tonic-gate * the file. If the user is the super-user, don't bother comparing 1557c478bd9Sstevel@tonic-gate * the id's. After all files are removed, exit (status 0). 1567c478bd9Sstevel@tonic-gate */ 1577c478bd9Sstevel@tonic-gate if (allflag) { 1587c478bd9Sstevel@tonic-gate for (i = 0; i < numjobs; ++i) { 1597c478bd9Sstevel@tonic-gate if (chkauthattr(CRONADMIN_AUTH, login_authchk) || 1607c478bd9Sstevel@tonic-gate user == statlist[i]->st_uid) 1617c478bd9Sstevel@tonic-gate (void) removentry(namelist[i]->d_name, 1627c478bd9Sstevel@tonic-gate statlist[i], user); 1637c478bd9Sstevel@tonic-gate } 1647c478bd9Sstevel@tonic-gate exit(0); 1657c478bd9Sstevel@tonic-gate } 1667c478bd9Sstevel@tonic-gate 1677c478bd9Sstevel@tonic-gate /* 1687c478bd9Sstevel@tonic-gate * If only certain jobs are to be removed, interpret each command 1697c478bd9Sstevel@tonic-gate * line argument. A check is done to see if it is a user's name or 1707c478bd9Sstevel@tonic-gate * a job number (inode #). If it's a user's name, compare the argument 1717c478bd9Sstevel@tonic-gate * to the files owner. If it's a job number, compare the argument to 1727c478bd9Sstevel@tonic-gate * the file name. In either case, if a match occurs, try to 1737c478bd9Sstevel@tonic-gate * remove the file. 1747c478bd9Sstevel@tonic-gate */ 1757c478bd9Sstevel@tonic-gate 1767c478bd9Sstevel@tonic-gate while (argc--) { 1777c478bd9Sstevel@tonic-gate jobexists = 0; 1787c478bd9Sstevel@tonic-gate for (i = 0; i < numjobs; ++i) { 1797c478bd9Sstevel@tonic-gate 1807c478bd9Sstevel@tonic-gate /* if the inode number is 0, this entry was removed */ 1817c478bd9Sstevel@tonic-gate if (statlist[i]->st_ino == 0) 1827c478bd9Sstevel@tonic-gate continue; 1837c478bd9Sstevel@tonic-gate 1847c478bd9Sstevel@tonic-gate /* 1857c478bd9Sstevel@tonic-gate * if argv is a username, compare his/her uid to 1867c478bd9Sstevel@tonic-gate * the uid of the owner of the file...... 1877c478bd9Sstevel@tonic-gate */ 1887c478bd9Sstevel@tonic-gate if (pwd = getpwnam(*argv)) { 1897c478bd9Sstevel@tonic-gate if (statlist[i]->st_uid != pwd->pw_uid) 1907c478bd9Sstevel@tonic-gate continue; 1917c478bd9Sstevel@tonic-gate /* 1927c478bd9Sstevel@tonic-gate * otherwise, we assume that the argv is a job # and 1937c478bd9Sstevel@tonic-gate * thus compare argv to the file name. 1947c478bd9Sstevel@tonic-gate */ 1957c478bd9Sstevel@tonic-gate } else { 1967c478bd9Sstevel@tonic-gate if (strcmp(namelist[i]->d_name, *argv)) 1977c478bd9Sstevel@tonic-gate continue; 1987c478bd9Sstevel@tonic-gate } 1997c478bd9Sstevel@tonic-gate ++jobexists; 2007c478bd9Sstevel@tonic-gate /* 2017c478bd9Sstevel@tonic-gate * if the entry is ultimately removed, don't 2027c478bd9Sstevel@tonic-gate * try to remove it again later. 2037c478bd9Sstevel@tonic-gate */ 204*032624d5Sbasabi if (removentry(namelist[i]->d_name, statlist[i], 205*032624d5Sbasabi user)) { 2067c478bd9Sstevel@tonic-gate statlist[i]->st_ino = 0; 2077c478bd9Sstevel@tonic-gate } 2087c478bd9Sstevel@tonic-gate } 2097c478bd9Sstevel@tonic-gate 2107c478bd9Sstevel@tonic-gate /* 2117c478bd9Sstevel@tonic-gate * If a requested argument doesn't exist, print a message. 2127c478bd9Sstevel@tonic-gate */ 2137c478bd9Sstevel@tonic-gate if (!jobexists && !fflag) { 214*032624d5Sbasabi fprintf(stderr, "atrm: %s: no such job number\n", 215*032624d5Sbasabi *argv); 2167c478bd9Sstevel@tonic-gate } 2177c478bd9Sstevel@tonic-gate ++argv; 2187c478bd9Sstevel@tonic-gate } 219*032624d5Sbasabi return (0); 2207c478bd9Sstevel@tonic-gate } 2217c478bd9Sstevel@tonic-gate 2227c478bd9Sstevel@tonic-gate /* 2237c478bd9Sstevel@tonic-gate * Print usage info and exit. 2247c478bd9Sstevel@tonic-gate */ 225*032624d5Sbasabi static void 226*032624d5Sbasabi usage(void) 2277c478bd9Sstevel@tonic-gate { 2287c478bd9Sstevel@tonic-gate fprintf(stderr, "usage: atrm [-f] [-i] [-a] [[job #] [user] ...]\n"); 2297c478bd9Sstevel@tonic-gate exit(1); 2307c478bd9Sstevel@tonic-gate } 2317c478bd9Sstevel@tonic-gate 2327c478bd9Sstevel@tonic-gate 2337c478bd9Sstevel@tonic-gate /* 2347c478bd9Sstevel@tonic-gate * Remove an entry from the queue. The access of the file is checked for 2357c478bd9Sstevel@tonic-gate * write permission (since all jobs are mode 644). If access is granted, 2367c478bd9Sstevel@tonic-gate * unlink the file. If the fflag (suppress announcements) is not set, 2377c478bd9Sstevel@tonic-gate * print the job number that we are removing and the result of the access 2387c478bd9Sstevel@tonic-gate * check (either "permission denied" or "removed"). If we are running 2397c478bd9Sstevel@tonic-gate * interactively (iflag), prompt the user before we unlink the file. If 2407c478bd9Sstevel@tonic-gate * the super-user is removing jobs, inform him/her who owns each file before 2417c478bd9Sstevel@tonic-gate * it is removed. Return TRUE if file removed, else FALSE. 2427c478bd9Sstevel@tonic-gate */ 2437c478bd9Sstevel@tonic-gate int 244*032624d5Sbasabi removentry(char *filename, struct stat *statptr, uid_t user) 2457c478bd9Sstevel@tonic-gate { 2467c478bd9Sstevel@tonic-gate struct passwd *pwd; 2477c478bd9Sstevel@tonic-gate char *pp; 2487c478bd9Sstevel@tonic-gate char *getuser(); 2497c478bd9Sstevel@tonic-gate int r; 2507c478bd9Sstevel@tonic-gate 2517c478bd9Sstevel@tonic-gate if (!fflag) 2527c478bd9Sstevel@tonic-gate printf("%s: ", filename); 2537c478bd9Sstevel@tonic-gate 2547c478bd9Sstevel@tonic-gate if (user != statptr->st_uid && 2557c478bd9Sstevel@tonic-gate !chkauthattr(CRONADMIN_AUTH, login_authchk)) { 2567c478bd9Sstevel@tonic-gate 2577c478bd9Sstevel@tonic-gate if (!fflag) { 2587c478bd9Sstevel@tonic-gate printf("permission denied\n"); 2597c478bd9Sstevel@tonic-gate } 2607c478bd9Sstevel@tonic-gate return (0); 2617c478bd9Sstevel@tonic-gate 2627c478bd9Sstevel@tonic-gate } else { 2637c478bd9Sstevel@tonic-gate if (iflag) { 2647c478bd9Sstevel@tonic-gate if (chkauthattr(CRONADMIN_AUTH, login_authchk)) { 2657c478bd9Sstevel@tonic-gate printf("\t(owned by "); 2667c478bd9Sstevel@tonic-gate powner(filename); 2677c478bd9Sstevel@tonic-gate printf(") "); 2687c478bd9Sstevel@tonic-gate } 2697c478bd9Sstevel@tonic-gate printf("remove it? "); 2707c478bd9Sstevel@tonic-gate if (!yes()) 2717c478bd9Sstevel@tonic-gate return (0); 2727c478bd9Sstevel@tonic-gate } 2737c478bd9Sstevel@tonic-gate 2747c478bd9Sstevel@tonic-gate if (chkauthattr(CRONADMIN_AUTH, login_authchk)) { 2757c478bd9Sstevel@tonic-gate pp = getuser((uid_t)statptr->st_uid); 2767c478bd9Sstevel@tonic-gate if (pp == NULL) 2777c478bd9Sstevel@tonic-gate atabort(INVALIDUSER); 2787c478bd9Sstevel@tonic-gate if (strlcpy(login, pp, sizeof (login)) >= 2797c478bd9Sstevel@tonic-gate sizeof (login)) 2807c478bd9Sstevel@tonic-gate atabort(NAMETOOLONG); 2817c478bd9Sstevel@tonic-gate } 2827c478bd9Sstevel@tonic-gate cron_sendmsg(DELETE, login, filename, AT); 2837c478bd9Sstevel@tonic-gate if ((r = unlink(filename)) < 0) { 2847c478bd9Sstevel@tonic-gate if (!fflag) { 2857c478bd9Sstevel@tonic-gate fputs("could not remove\n", stdout); 2867c478bd9Sstevel@tonic-gate (void) fprintf(stderr, "atrm: %s: %s\n", 2877c478bd9Sstevel@tonic-gate filename, errmsg(errno)); 2887c478bd9Sstevel@tonic-gate } 2897c478bd9Sstevel@tonic-gate audit_at_delete(filename, NULL, r); 2907c478bd9Sstevel@tonic-gate return (0); 2917c478bd9Sstevel@tonic-gate } 2927c478bd9Sstevel@tonic-gate audit_at_delete(filename, NULL, r); 2937c478bd9Sstevel@tonic-gate if (!fflag && !iflag) 2947c478bd9Sstevel@tonic-gate printf("removed\n"); 2957c478bd9Sstevel@tonic-gate return (1); 2967c478bd9Sstevel@tonic-gate } 2977c478bd9Sstevel@tonic-gate } 2987c478bd9Sstevel@tonic-gate 2997c478bd9Sstevel@tonic-gate /* 3007c478bd9Sstevel@tonic-gate * Print the owner of the job. This is the owner of the spoolfile. 3017c478bd9Sstevel@tonic-gate * If we run into trouble getting the name, we'll just print "???". 3027c478bd9Sstevel@tonic-gate */ 303*032624d5Sbasabi static void 304*032624d5Sbasabi powner(char *file) 3057c478bd9Sstevel@tonic-gate { 3067c478bd9Sstevel@tonic-gate struct stat statb; 3077c478bd9Sstevel@tonic-gate char *getname(); 3087c478bd9Sstevel@tonic-gate 3097c478bd9Sstevel@tonic-gate if (stat(file, &statb) < 0) { 3107c478bd9Sstevel@tonic-gate printf("%s", "???"); 3117c478bd9Sstevel@tonic-gate (void) fprintf(stderr, "atrm: Couldn't stat spoolfile %s: %s\n", 3127c478bd9Sstevel@tonic-gate file, errmsg(errno)); 313*032624d5Sbasabi return; 3147c478bd9Sstevel@tonic-gate } 3157c478bd9Sstevel@tonic-gate 3167c478bd9Sstevel@tonic-gate printf("%s", getname(statb.st_uid)); 3177c478bd9Sstevel@tonic-gate } 3187c478bd9Sstevel@tonic-gate 3197c478bd9Sstevel@tonic-gate 3207c478bd9Sstevel@tonic-gate int 321*032624d5Sbasabi getjoblist(struct dirent ***namelistp, struct stat ***statlistp, 322*032624d5Sbasabi int (*sortfunc)()) 3237c478bd9Sstevel@tonic-gate { 324*032624d5Sbasabi int numjobs; 325*032624d5Sbasabi struct dirent **namelist; 326*032624d5Sbasabi int i; 327*032624d5Sbasabi struct stat *statptr; /* pointer to file stat structure */ 328*032624d5Sbasabi struct stat **statlist; 3297c478bd9Sstevel@tonic-gate extern int alphasort(); /* sort jobs by date of execution */ 3307c478bd9Sstevel@tonic-gate extern int filewanted(); /* should a file be listed in queue? */ 3317c478bd9Sstevel@tonic-gate 3327c478bd9Sstevel@tonic-gate if (chdir(ATDIR) < 0) 3337c478bd9Sstevel@tonic-gate atabortperror(CANTCD); 3347c478bd9Sstevel@tonic-gate 3357c478bd9Sstevel@tonic-gate /* 3367c478bd9Sstevel@tonic-gate * Get a list of the files in the spooling area. 3377c478bd9Sstevel@tonic-gate */ 3387c478bd9Sstevel@tonic-gate if ((numjobs = ascandir(".", namelistp, filewanted, sortfunc)) < 0) 3397c478bd9Sstevel@tonic-gate atabortperror(NOREADDIR); 3407c478bd9Sstevel@tonic-gate 341*032624d5Sbasabi if ((statlist = 342*032624d5Sbasabi (struct stat **)malloc(numjobs * sizeof (struct stat ***))) 343*032624d5Sbasabi == NULL) 3447c478bd9Sstevel@tonic-gate atabort("Out of memory"); 3457c478bd9Sstevel@tonic-gate 3467c478bd9Sstevel@tonic-gate namelist = *namelistp; 3477c478bd9Sstevel@tonic-gate 3487c478bd9Sstevel@tonic-gate /* 3497c478bd9Sstevel@tonic-gate * Build an array of pointers to the file stats for all jobs in 3507c478bd9Sstevel@tonic-gate * the spooling area. 3517c478bd9Sstevel@tonic-gate */ 3527c478bd9Sstevel@tonic-gate for (i = 0; i < numjobs; ++i) { 3537c478bd9Sstevel@tonic-gate statptr = (struct stat *)malloc(sizeof (struct stat)); 3547c478bd9Sstevel@tonic-gate if (statptr == NULL) 3557c478bd9Sstevel@tonic-gate atabort("Out of memory"); 3567c478bd9Sstevel@tonic-gate if (stat(namelist[i]->d_name, statptr) < 0) { 357*032624d5Sbasabi atperror2("Can't stat", namelist[i]->d_name); 3587c478bd9Sstevel@tonic-gate continue; 3597c478bd9Sstevel@tonic-gate } 3607c478bd9Sstevel@tonic-gate statlist[i] = statptr; 3617c478bd9Sstevel@tonic-gate } 3627c478bd9Sstevel@tonic-gate 3637c478bd9Sstevel@tonic-gate *statlistp = statlist; 3647c478bd9Sstevel@tonic-gate return (numjobs); 3657c478bd9Sstevel@tonic-gate } 3667c478bd9Sstevel@tonic-gate 3677c478bd9Sstevel@tonic-gate 3687c478bd9Sstevel@tonic-gate /* 3697c478bd9Sstevel@tonic-gate * Get answer to interactive prompts, eating all characters beyond the first 3707c478bd9Sstevel@tonic-gate * one. If a 'y' is typed, return 1. 3717c478bd9Sstevel@tonic-gate */ 372*032624d5Sbasabi int 373*032624d5Sbasabi yes(void) 3747c478bd9Sstevel@tonic-gate { 375*032624d5Sbasabi int ch; /* dummy variable */ 376*032624d5Sbasabi int ch1; /* dummy variable */ 3777c478bd9Sstevel@tonic-gate 3787c478bd9Sstevel@tonic-gate ch = ch1 = getchar(); 3797c478bd9Sstevel@tonic-gate while (ch1 != '\n' && ch1 != EOF) 3807c478bd9Sstevel@tonic-gate ch1 = getchar(); 3817c478bd9Sstevel@tonic-gate if (isupper(ch)) 3827c478bd9Sstevel@tonic-gate ch = tolower(ch); 3837c478bd9Sstevel@tonic-gate return (ch == 'y'); 3847c478bd9Sstevel@tonic-gate } 3857c478bd9Sstevel@tonic-gate 3867c478bd9Sstevel@tonic-gate 3877c478bd9Sstevel@tonic-gate /* 3887c478bd9Sstevel@tonic-gate * Get the full login name of a person using his/her user id. 3897c478bd9Sstevel@tonic-gate */ 3907c478bd9Sstevel@tonic-gate char * 391*032624d5Sbasabi getname(uid_t uid) 3927c478bd9Sstevel@tonic-gate { 393*032624d5Sbasabi struct passwd *pwdinfo; /* password info structure */ 3947c478bd9Sstevel@tonic-gate 3957c478bd9Sstevel@tonic-gate 3967c478bd9Sstevel@tonic-gate if ((pwdinfo = getpwuid(uid)) == 0) 3977c478bd9Sstevel@tonic-gate return ("???"); 3987c478bd9Sstevel@tonic-gate return (pwdinfo->pw_name); 3997c478bd9Sstevel@tonic-gate } 4007c478bd9Sstevel@tonic-gate 401*032624d5Sbasabi static void 402*032624d5Sbasabi aterror(char *msg) 4037c478bd9Sstevel@tonic-gate { 4047c478bd9Sstevel@tonic-gate fprintf(stderr, "atrm: %s\n", msg); 4057c478bd9Sstevel@tonic-gate } 4067c478bd9Sstevel@tonic-gate 407*032624d5Sbasabi static void 408*032624d5Sbasabi atperror(char *msg) 4097c478bd9Sstevel@tonic-gate { 4107c478bd9Sstevel@tonic-gate fprintf(stderr, "atrm: %s: %s\n", msg, errmsg(errno)); 4117c478bd9Sstevel@tonic-gate } 4127c478bd9Sstevel@tonic-gate 413*032624d5Sbasabi static void 414*032624d5Sbasabi atperror2(char *msg, char *name) 415*032624d5Sbasabi { 416*032624d5Sbasabi fprintf(stderr, "atrm: %s %s: %s\n", msg, name, errmsg(errno)); 417*032624d5Sbasabi } 418*032624d5Sbasabi 419*032624d5Sbasabi static void 420*032624d5Sbasabi atabort(char *msg) 4217c478bd9Sstevel@tonic-gate { 4227c478bd9Sstevel@tonic-gate aterror(msg); 4237c478bd9Sstevel@tonic-gate exit(1); 4247c478bd9Sstevel@tonic-gate } 4257c478bd9Sstevel@tonic-gate 426*032624d5Sbasabi static void 427*032624d5Sbasabi atabortperror(char *msg) 4287c478bd9Sstevel@tonic-gate { 4297c478bd9Sstevel@tonic-gate atperror(msg); 4307c478bd9Sstevel@tonic-gate exit(1); 4317c478bd9Sstevel@tonic-gate } 432