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