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