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