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