file reorg, pathnames.h, paths.h
[unix-history] / usr / src / usr.sbin / lpr / common_source / rmjob.c
CommitLineData
d0aeaf5a
DF
1/*
2 * Copyright (c) 1983 Regents of the University of California.
9d85c861
KB
3 * All rights reserved.
4 *
5 * Redistribution and use in source and binary forms are permitted
a399f6c8
KB
6 * provided that the above copyright notice and this paragraph are
7 * duplicated in all such forms and that any documentation,
8 * advertising materials, and other materials related to such
9 * distribution and use acknowledge that the software was developed
10 * by the University of California, Berkeley. The name of the
11 * University may not be used to endorse or promote products derived
12 * from this software without specific prior written permission.
13 * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR
14 * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
15 * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE.
d0aeaf5a
DF
16 */
17
5f84f8f0 18#ifndef lint
7abf8d65 19static char sccsid[] = "@(#)rmjob.c 5.5 (Berkeley) %G%";
9d85c861 20#endif /* not lint */
5f84f8f0 21
ccbfa562
RC
22/*
23 * rmjob - remove the specified jobs from the queue.
24 */
25
26#include "lp.h"
7abf8d65 27#include "pathnames.h"
ccbfa562
RC
28
29/*
30 * Stuff for handling lprm specifications
31 */
32extern char *user[]; /* users to process */
33extern int users; /* # of users in user array */
34extern int requ[]; /* job number of spool entries */
35extern int requests; /* # of spool requests */
54266d1f 36extern char *person; /* name of person doing lprm */
ccbfa562 37
3d3c9f9f
RC
38char root[] = "root";
39int all = 0; /* eliminate all files (root only) */
40int cur_daemon; /* daemon's pid */
41char current[40]; /* active control file name */
ccbfa562
RC
42
43int iscf();
44
45rmjob()
46{
47 register int i, nitems;
48 int assasinated = 0;
49 struct direct **files;
50
ccbfa562
RC
51 if ((i = pgetent(line, printer)) < 0)
52 fatal("cannot open printer description file");
53 else if (i == 0)
54 fatal("unknown printer");
55 if ((SD = pgetstr("sd", &bp)) == NULL)
7abf8d65 56 SD = _PATH_DEFSPOOL;
ccbfa562
RC
57 if ((LO = pgetstr("lo", &bp)) == NULL)
58 LO = DEFLOCK;
59 if ((LP = pgetstr("lp", &bp)) == NULL)
7abf8d65 60 LP = _PATH_DEFDEVLP;
ccbfa562 61 if ((RP = pgetstr("rp", &bp)) == NULL)
4d4caa50 62 RP = DEFLP;
a87bde97 63 RM = pgetstr("rm", &bp);
7bc71354
TF
64 /*
65 * Figure out whether the local machine is the same as the remote
66 * machine entry (if it exists). If not, then ignore the local
67 * queue information.
68 */
69 if (RM != (char *) NULL) {
70 char name[256];
71 struct hostent *hp;
72
73 /* get the standard network name of the local host */
74 gethostname(name, sizeof(name));
75 name[sizeof(name)-1] = '\0';
76 hp = gethostbyname(name);
77 if (hp == (struct hostent *) NULL) {
78 printf("unable to get network name for local machine %s",
79 name);
80 goto localcheck_done;
81 } else strcpy(name, hp->h_name);
82
83 /* get the standard network name of RM */
84 hp = gethostbyname(RM);
85 if (hp == (struct hostent *) NULL) {
86 printf("unable to get hostname for remote machine %s", RM);
87 goto localcheck_done;
88 }
89
90 /* if printer is not on local machine, ignore LP */
91 if (strcmp(name, hp->h_name) != 0) *LP = '\0';
92 }
93localcheck_done:
ccbfa562
RC
94
95 /*
96 * If the format was `lprm -' and the user isn't the super-user,
97 * then fake things to look like he said `lprm user'.
98 */
99 if (users < 0) {
100 if (getuid() == 0)
101 all = 1; /* all files in local queue */
102 else {
103 user[0] = person;
104 users = 1;
105 }
106 }
107 if (!strcmp(person, "-all")) {
108 if (from == host)
109 fatal("The login name \"-all\" is reserved");
110 all = 1; /* all those from 'from' */
111 person = root;
112 }
113
114 if (chdir(SD) < 0)
115 fatal("cannot chdir to spool directory");
116 if ((nitems = scandir(".", &files, iscf, NULL)) < 0)
117 fatal("cannot access spool directory");
118
119 if (nitems) {
120 /*
121 * Check for an active printer daemon (in which case we
122 * kill it if it is reading our file) then remove stuff
123 * (after which we have to restart the daemon).
124 */
125 if (lockchk(LO) && chk(current)) {
126 assasinated = kill(cur_daemon, SIGINT) == 0;
127 if (!assasinated)
128 fatal("cannot kill printer daemon");
129 }
130 /*
131 * process the files
132 */
133 for (i = 0; i < nitems; i++)
134 process(files[i]->d_name);
135 }
136 chkremote();
137 /*
138 * Restart the printer daemon if it was killed
139 */
775e8534 140 if (assasinated && !startdaemon(printer))
ccbfa562
RC
141 fatal("cannot restart printer daemon\n");
142 exit(0);
143}
144
145/*
146 * Process a lock file: collect the pid of the active
147 * daemon and the file name of the active spool entry.
148 * Return boolean indicating existence of a lock file.
149 */
150lockchk(s)
151 char *s;
152{
153 register FILE *fp;
154 register int i, n;
155
156 if ((fp = fopen(s, "r")) == NULL)
157 if (errno == EACCES)
158 fatal("can't access lock file");
159 else
160 return(0);
8fed920b 161 if (!getline(fp)) {
ccbfa562
RC
162 (void) fclose(fp);
163 return(0); /* no daemon present */
164 }
165 cur_daemon = atoi(line);
8fed920b
RC
166 if (kill(cur_daemon, 0) < 0) {
167 (void) fclose(fp);
168 return(0); /* no daemon present */
169 }
ccbfa562 170 for (i = 1; (n = fread(current, sizeof(char), sizeof(current), fp)) <= 0; i++) {
a87bde97 171 if (i > 5) {
ccbfa562
RC
172 n = 1;
173 break;
174 }
175 sleep(i);
176 }
177 current[n-1] = '\0';
178 (void) fclose(fp);
179 return(1);
180}
181
182/*
183 * Process a control file.
184 */
185process(file)
186 char *file;
187{
188 FILE *cfp;
189
190 if (!chk(file))
191 return;
192 if ((cfp = fopen(file, "r")) == NULL)
193 fatal("cannot open %s", file);
3d3c9f9f 194 while (getline(cfp)) {
ccbfa562
RC
195 switch (line[0]) {
196 case 'U': /* unlink associated files */
197 if (from != host)
198 printf("%s: ", host);
199 printf(unlink(line+1) ? "cannot dequeue %s\n" :
200 "%s dequeued\n", line+1);
201 }
202 }
203 (void) fclose(cfp);
204 if (from != host)
205 printf("%s: ", host);
206 printf(unlink(file) ? "cannot dequeue %s\n" : "%s dequeued\n", file);
207}
208
209/*
210 * Do the dirty work in checking
211 */
212chk(file)
213 char *file;
214{
215 register int *r, n;
216 register char **u, *cp;
217 FILE *cfp;
218
139505f2
RC
219 /*
220 * Check for valid cf file name (mostly checking current).
221 */
222 if (strlen(file) < 7 || file[0] != 'c' || file[1] != 'f')
223 return(0);
224
ccbfa562
RC
225 if (all && (from == host || !strcmp(from, file+6)))
226 return(1);
227
228 /*
229 * get the owner's name from the control file.
230 */
231 if ((cfp = fopen(file, "r")) == NULL)
232 return(0);
233 while (getline(cfp)) {
234 if (line[0] == 'P')
235 break;
236 }
237 (void) fclose(cfp);
238 if (line[0] != 'P')
239 return(0);
240
241 if (users == 0 && requests == 0)
242 return(!strcmp(file, current) && isowner(line+1, file));
243 /*
244 * Check the request list
245 */
246 for (n = 0, cp = file+3; isdigit(*cp); )
247 n = n * 10 + (*cp++ - '0');
248 for (r = requ; r < &requ[requests]; r++)
249 if (*r == n && isowner(line+1, file))
250 return(1);
251 /*
252 * Check to see if it's in the user list
253 */
254 for (u = user; u < &user[users]; u++)
255 if (!strcmp(*u, line+1) && isowner(line+1, file))
256 return(1);
257 return(0);
258}
259
260/*
261 * If root is removing a file on the local machine, allow it.
4d4caa50
RC
262 * If root is removing a file from a remote machine, only allow
263 * files sent from the remote machine to be removed.
ccbfa562
RC
264 * Normal users can only remove the file from where it was sent.
265 */
266isowner(owner, file)
267 char *owner, *file;
268{
4d4caa50
RC
269 if (!strcmp(person, root) && (from == host || !strcmp(from, file+6)))
270 return(1);
271 if (!strcmp(person, owner) && !strcmp(from, file+6))
272 return(1);
273 if (from != host)
274 printf("%s: ", host);
275 printf("%s: Permission denied\n", file);
276 return(0);
ccbfa562
RC
277}
278
279/*
280 * Check to see if we are sending files to a remote machine. If we are,
281 * then try removing files on the remote machine.
282 */
283chkremote()
284{
285 register char *cp;
286 register int i, rem;
287 char buf[BUFSIZ];
288
289 if (*LP || RM == NULL)
290 return; /* not sending to a remote machine */
291
4d4caa50
RC
292 /*
293 * Flush stdout so the user can see what has been deleted
294 * while we wait (possibly) for the connection.
295 */
296 fflush(stdout);
297
ccbfa562
RC
298 sprintf(buf, "\5%s %s", RP, all ? "-all" : person);
299 cp = buf;
300 for (i = 0; i < users; i++) {
301 cp += strlen(cp);
302 *cp++ = ' ';
303 strcpy(cp, user[i]);
304 }
305 for (i = 0; i < requests; i++) {
306 cp += strlen(cp);
307 (void) sprintf(cp, " %d", requ[i]);
308 }
309 strcat(cp, "\n");
a87bde97 310 rem = getport(RM);
ccbfa562
RC
311 if (rem < 0) {
312 if (from != host)
313 printf("%s: ", host);
314 printf("connection to %s is down\n", RM);
315 } else {
316 i = strlen(buf);
317 if (write(rem, buf, i) != i)
318 fatal("Lost connection");
319 while ((i = read(rem, buf, sizeof(buf))) > 0)
320 (void) fwrite(buf, 1, i, stdout);
321 (void) close(rem);
322 }
323}
324
325/*
326 * Return 1 if the filename begins with 'cf'
327 */
328iscf(d)
329 struct direct *d;
330{
331 return(d->d_name[0] == 'c' && d->d_name[1] == 'f');
332}