Commit | Line | Data |
---|---|---|
5df74a28 | 1 | #ifndef lint |
adec4d9e | 2 | static char sccsid[] = "@(#)cmds.c 4.4 (Berkeley) %G%"; |
5df74a28 RC |
3 | #endif |
4 | ||
5 | /* | |
6 | * lpc -- line printer control program | |
7 | */ | |
8 | ||
9 | #include "lp.h" | |
10 | ||
11 | /* | |
12 | * kill an existing daemon and disable printing. | |
13 | */ | |
14 | abort(argc, argv) | |
15 | char *argv[]; | |
16 | { | |
17 | register int c, status; | |
18 | register char *cp1, *cp2; | |
19 | char prbuf[100]; | |
20 | ||
21 | if (argc == 1) { | |
22 | printf("Usage: abort {all | printer ...}\n"); | |
23 | return; | |
24 | } | |
25 | if (argc == 2 && !strcmp(argv[1], "all")) { | |
26 | printer = prbuf; | |
27 | while (getprent(line) > 0) { | |
28 | cp1 = prbuf; | |
29 | cp2 = line; | |
30 | while ((c = *cp2++) && c != '|' && c != ':') | |
31 | *cp1++ = c; | |
32 | *cp1 = '\0'; | |
33 | abortpr(); | |
34 | } | |
35 | return; | |
36 | } | |
37 | while (--argc) { | |
38 | printer = *++argv; | |
39 | if ((status = pgetent(line, printer)) < 0) { | |
7b22a8ae | 40 | printf("cannot open printer description file\n"); |
5df74a28 RC |
41 | continue; |
42 | } else if (status == 0) { | |
7b22a8ae | 43 | printf("unknown printer %s\n", printer); |
5df74a28 RC |
44 | continue; |
45 | } | |
46 | abortpr(); | |
47 | } | |
48 | } | |
49 | ||
50 | abortpr() | |
51 | { | |
52 | register FILE *fp; | |
53 | struct stat stbuf; | |
54 | int pid, fd; | |
55 | ||
56 | bp = pbuf; | |
57 | if ((SD = pgetstr("sd", &bp)) == NULL) | |
58 | SD = DEFSPOOL; | |
59 | if ((LO = pgetstr("lo", &bp)) == NULL) | |
60 | LO = DEFLOCK; | |
61 | (void) sprintf(line, "%s/%s", SD, LO); | |
62 | printf("%s:\n", printer); | |
63 | ||
64 | /* | |
65 | * Turn on the owner execute bit of the lock file to disable printing. | |
66 | */ | |
67 | if (stat(line, &stbuf) >= 0) { | |
68 | if (chmod(line, (stbuf.st_mode & 0777) | 0100) < 0) | |
69 | printf("\tcannot disable printing\n"); | |
70 | else | |
71 | printf("\tprinting disabled\n"); | |
72 | } else if (errno == ENOENT) { | |
adec4d9e | 73 | if ((fd = open(line, O_WRONLY|O_CREAT, 0760)) < 0) |
7b22a8ae | 74 | printf("\tcannot create lock file\n"); |
5df74a28 RC |
75 | else { |
76 | (void) close(fd); | |
77 | printf("\tprinting disabled\n"); | |
78 | printf("\tno daemon to abort\n"); | |
79 | } | |
80 | return; | |
81 | } else { | |
82 | printf("\tcannot stat lock file\n"); | |
83 | return; | |
84 | } | |
85 | /* | |
86 | * Kill the current daemon to stop printing now. | |
87 | */ | |
88 | if ((fp = fopen(line, "r")) == NULL) { | |
89 | printf("\tcannot open lock file\n"); | |
90 | return; | |
91 | } | |
adec4d9e | 92 | if (!getline(fp) || flock(fileno(fp), LOCK_SH|LOCK_NB) == 0) { |
5df74a28 RC |
93 | (void) fclose(fp); |
94 | printf("\tno daemon to abort\n"); | |
95 | return; | |
96 | } | |
97 | (void) fclose(fp); | |
98 | if (kill(pid = atoi(line), SIGINT) < 0) | |
99 | printf("\tWarning: daemon (pid %d) not killed\n", pid); | |
100 | else | |
101 | printf("\tdaemon (pid %d) killed\n", pid); | |
102 | } | |
103 | ||
104 | /* | |
105 | * Remove all spool files and temporaries from the spooling area. | |
106 | */ | |
107 | clean(argc, argv) | |
108 | char *argv[]; | |
109 | { | |
110 | register int c, status; | |
111 | register char *cp1, *cp2; | |
112 | char prbuf[100]; | |
113 | ||
114 | if (argc == 1) { | |
115 | printf("Usage: clean {all | printer ...}\n"); | |
116 | return; | |
117 | } | |
118 | if (argc == 2 && !strcmp(argv[1], "all")) { | |
119 | printer = prbuf; | |
120 | while (getprent(line) > 0) { | |
121 | cp1 = prbuf; | |
122 | cp2 = line; | |
123 | while ((c = *cp2++) && c != '|' && c != ':') | |
124 | *cp1++ = c; | |
125 | *cp1 = '\0'; | |
126 | cleanpr(); | |
127 | } | |
128 | return; | |
129 | } | |
130 | while (--argc) { | |
131 | printer = *++argv; | |
132 | if ((status = pgetent(line, printer)) < 0) { | |
7b22a8ae | 133 | printf("cannot open printer description file\n"); |
5df74a28 RC |
134 | continue; |
135 | } else if (status == 0) { | |
7b22a8ae | 136 | printf("unknown printer %s\n", printer); |
5df74a28 RC |
137 | continue; |
138 | } | |
139 | cleanpr(); | |
140 | } | |
141 | } | |
142 | ||
143 | cleanpr() | |
144 | { | |
145 | register int c; | |
146 | register DIR *dirp; | |
147 | register struct direct *dp; | |
148 | char *cp, *cp1; | |
149 | ||
150 | bp = pbuf; | |
151 | if ((SD = pgetstr("sd", &bp)) == NULL) | |
152 | SD = DEFSPOOL; | |
153 | for (cp = line, cp1 = SD; *cp++ = *cp1++; ); | |
154 | cp[-1] = '/'; | |
155 | printf("%s:\n", printer); | |
156 | ||
157 | if ((dirp = opendir(SD)) == NULL) { | |
158 | printf("\tcannot examine spool directory\n"); | |
159 | return; | |
160 | } | |
161 | while ((dp = readdir(dirp)) != NULL) { | |
162 | c = dp->d_name[0]; | |
163 | if ((c == 'c' || c == 't' || c == 'd') && dp->d_name[1]=='f') { | |
164 | strcpy(cp, dp->d_name); | |
165 | if (unlink(line) < 0) | |
166 | printf("\tcannot remove %s\n", line); | |
167 | else | |
168 | printf("\tremoved %s\n", line); | |
169 | } | |
170 | } | |
171 | closedir(dirp); | |
172 | } | |
173 | ||
174 | /* | |
175 | * Enable queuing to the printer (allow lpr's). | |
176 | */ | |
177 | enable(argc, argv) | |
178 | char *argv[]; | |
179 | { | |
180 | register int c, status; | |
181 | register char *cp1, *cp2; | |
182 | char prbuf[100]; | |
183 | ||
184 | if (argc == 1) { | |
185 | printf("Usage: enable {all | printer ...}\n"); | |
186 | return; | |
187 | } | |
188 | if (argc == 2 && !strcmp(argv[1], "all")) { | |
189 | printer = prbuf; | |
190 | while (getprent(line) > 0) { | |
191 | cp1 = prbuf; | |
192 | cp2 = line; | |
193 | while ((c = *cp2++) && c != '|' && c != ':') | |
194 | *cp1++ = c; | |
195 | *cp1 = '\0'; | |
196 | enablepr(); | |
197 | } | |
198 | return; | |
199 | } | |
200 | while (--argc) { | |
201 | printer = *++argv; | |
202 | if ((status = pgetent(line, printer)) < 0) { | |
7b22a8ae | 203 | printf("cannot open printer description file\n"); |
5df74a28 RC |
204 | continue; |
205 | } else if (status == 0) { | |
7b22a8ae | 206 | printf("unknown printer %s\n", printer); |
5df74a28 RC |
207 | continue; |
208 | } | |
209 | enablepr(); | |
210 | } | |
211 | } | |
212 | ||
213 | enablepr() | |
214 | { | |
215 | struct stat stbuf; | |
216 | ||
217 | bp = pbuf; | |
218 | if ((SD = pgetstr("sd", &bp)) == NULL) | |
219 | SD = DEFSPOOL; | |
220 | if ((LO = pgetstr("lo", &bp)) == NULL) | |
221 | LO = DEFLOCK; | |
222 | (void) sprintf(line, "%s/%s", SD, LO); | |
223 | printf("%s:\n", printer); | |
224 | ||
225 | /* | |
226 | * Turn off the group execute bit of the lock file to enable queuing. | |
227 | */ | |
228 | if (stat(line, &stbuf) >= 0) { | |
229 | if (chmod(line, stbuf.st_mode & 0767) < 0) | |
7b22a8ae | 230 | printf("\tcannot enable queuing\n"); |
5df74a28 RC |
231 | else |
232 | printf("\tqueuing enabled\n"); | |
233 | } | |
234 | } | |
235 | ||
236 | /* | |
237 | * Disable queuing. | |
238 | */ | |
239 | disable(argc, argv) | |
240 | char *argv[]; | |
241 | { | |
242 | register int c, status; | |
243 | register char *cp1, *cp2; | |
244 | char prbuf[100]; | |
245 | ||
246 | if (argc == 1) { | |
247 | printf("Usage: disable {all | printer ...}\n"); | |
248 | return; | |
249 | } | |
250 | if (argc == 2 && !strcmp(argv[1], "all")) { | |
251 | printer = prbuf; | |
252 | while (getprent(line) > 0) { | |
253 | cp1 = prbuf; | |
254 | cp2 = line; | |
255 | while ((c = *cp2++) && c != '|' && c != ':') | |
256 | *cp1++ = c; | |
257 | *cp1 = '\0'; | |
258 | disablepr(); | |
259 | } | |
260 | return; | |
261 | } | |
262 | while (--argc) { | |
263 | printer = *++argv; | |
264 | if ((status = pgetent(line, printer)) < 0) { | |
7b22a8ae | 265 | printf("cannot open printer description file\n"); |
5df74a28 RC |
266 | continue; |
267 | } else if (status == 0) { | |
7b22a8ae | 268 | printf("unknown printer %s\n", printer); |
5df74a28 RC |
269 | continue; |
270 | } | |
271 | disablepr(); | |
272 | } | |
273 | } | |
274 | ||
275 | disablepr() | |
276 | { | |
277 | register int fd; | |
278 | struct stat stbuf; | |
279 | ||
280 | bp = pbuf; | |
281 | if ((SD = pgetstr("sd", &bp)) == NULL) | |
282 | SD = DEFSPOOL; | |
283 | if ((LO = pgetstr("lo", &bp)) == NULL) | |
284 | LO = DEFLOCK; | |
285 | (void) sprintf(line, "%s/%s", SD, LO); | |
286 | printf("%s:\n", printer); | |
287 | /* | |
288 | * Turn on the group execute bit of the lock file to disable queuing. | |
289 | */ | |
290 | if (stat(line, &stbuf) >= 0) { | |
291 | if (chmod(line, (stbuf.st_mode & 0777) | 010) < 0) | |
292 | printf("\tcannot disable queuing\n"); | |
293 | else | |
294 | printf("\tqueuing disabled\n"); | |
295 | } else if (errno == ENOENT) { | |
adec4d9e | 296 | if ((fd = open(line, O_WRONLY|O_CREAT, 0670)) < 0) |
5df74a28 RC |
297 | printf("\tcannot create lock file\n"); |
298 | else { | |
299 | (void) close(fd); | |
300 | printf("\tqueuing disabled\n"); | |
301 | } | |
302 | return; | |
303 | } else | |
304 | printf("\tcannot stat lock file\n"); | |
305 | } | |
306 | ||
307 | /* | |
308 | * Exit lpc | |
309 | */ | |
310 | quit(argc, argv) | |
311 | char *argv[]; | |
312 | { | |
313 | exit(0); | |
314 | } | |
315 | ||
316 | /* | |
317 | * Startup the daemon. | |
318 | */ | |
319 | restart(argc, argv) | |
320 | char *argv[]; | |
321 | { | |
322 | register int c, status; | |
323 | register char *cp1, *cp2; | |
324 | char prbuf[100]; | |
325 | ||
326 | if (argc == 1) { | |
327 | printf("Usage: restart {all | printer ...}\n"); | |
328 | return; | |
329 | } | |
330 | gethostname(host, sizeof(host)); | |
331 | if (argc == 2 && !strcmp(argv[1], "all")) { | |
332 | printer = prbuf; | |
333 | while (getprent(line) > 0) { | |
334 | cp1 = prbuf; | |
335 | cp2 = line; | |
336 | while ((c = *cp2++) && c != '|' && c != ':') | |
337 | *cp1++ = c; | |
338 | *cp1 = '\0'; | |
339 | startpr(0); | |
340 | } | |
341 | return; | |
342 | } | |
343 | while (--argc) { | |
344 | printer = *++argv; | |
345 | if ((status = pgetent(line, printer)) < 0) { | |
7b22a8ae | 346 | printf("cannot open printer description file\n"); |
5df74a28 RC |
347 | continue; |
348 | } else if (status == 0) { | |
7b22a8ae | 349 | printf("unknown printer %s\n", printer); |
5df74a28 RC |
350 | continue; |
351 | } | |
352 | startpr(0); | |
353 | } | |
354 | } | |
355 | ||
356 | /* | |
357 | * Enable printing on the specified printer and startup the daemon. | |
358 | */ | |
359 | start(argc, argv) | |
360 | char *argv[]; | |
361 | { | |
362 | register int c, status; | |
363 | register char *cp1, *cp2; | |
364 | char prbuf[100]; | |
365 | ||
366 | if (argc == 1) { | |
367 | printf("Usage: start {all | printer ...}\n"); | |
368 | return; | |
369 | } | |
370 | gethostname(host, sizeof(host)); | |
371 | if (argc == 2 && !strcmp(argv[1], "all")) { | |
372 | printer = prbuf; | |
373 | while (getprent(line) > 0) { | |
374 | cp1 = prbuf; | |
375 | cp2 = line; | |
376 | while ((c = *cp2++) && c != '|' && c != ':') | |
377 | *cp1++ = c; | |
378 | *cp1 = '\0'; | |
379 | startpr(1); | |
380 | } | |
381 | return; | |
382 | } | |
383 | while (--argc) { | |
384 | printer = *++argv; | |
385 | if ((status = pgetent(line, printer)) < 0) { | |
7b22a8ae | 386 | printf("cannot open printer description file\n"); |
5df74a28 RC |
387 | continue; |
388 | } else if (status == 0) { | |
7b22a8ae | 389 | printf("unknown printer %s\n", printer); |
5df74a28 RC |
390 | continue; |
391 | } | |
392 | startpr(1); | |
393 | } | |
394 | } | |
395 | ||
396 | startpr(enable) | |
397 | { | |
398 | struct stat stbuf; | |
399 | ||
400 | bp = pbuf; | |
401 | if ((SD = pgetstr("sd", &bp)) == NULL) | |
402 | SD = DEFSPOOL; | |
403 | if ((LO = pgetstr("lo", &bp)) == NULL) | |
404 | LO = DEFLOCK; | |
5df74a28 RC |
405 | (void) sprintf(line, "%s/%s", SD, LO); |
406 | printf("%s:\n", printer); | |
407 | ||
408 | /* | |
409 | * Turn off the owner execute bit of the lock file to enable printing. | |
410 | */ | |
411 | if (enable && stat(line, &stbuf) >= 0) { | |
412 | if (chmod(line, stbuf.st_mode & 0677) < 0) | |
413 | printf("\tcannot enable printing\n"); | |
414 | else | |
415 | printf("\tprinting enabled\n"); | |
416 | } | |
54266d1f | 417 | if (!startdaemon(host)) |
5df74a28 RC |
418 | printf("\tcouldn't start daemon\n"); |
419 | else | |
420 | printf("\tdaemon started\n"); | |
421 | } | |
422 | ||
423 | /* | |
424 | * Print the status of each queue listed or all the queues. | |
425 | */ | |
426 | status(argc, argv) | |
427 | char *argv[]; | |
428 | { | |
429 | register int c, status; | |
430 | register char *cp1, *cp2; | |
431 | char prbuf[100]; | |
432 | ||
433 | if (argc == 1) { | |
434 | printer = prbuf; | |
435 | while (getprent(line) > 0) { | |
436 | cp1 = prbuf; | |
437 | cp2 = line; | |
438 | while ((c = *cp2++) && c != '|' && c != ':') | |
439 | *cp1++ = c; | |
440 | *cp1 = '\0'; | |
441 | prstat(); | |
442 | } | |
443 | return; | |
444 | } | |
445 | while (--argc) { | |
446 | printer = *++argv; | |
447 | if ((status = pgetent(line, printer)) < 0) { | |
7b22a8ae | 448 | printf("cannot open printer description file\n"); |
5df74a28 RC |
449 | continue; |
450 | } else if (status == 0) { | |
7b22a8ae | 451 | printf("unknown printer %s\n", printer); |
5df74a28 RC |
452 | continue; |
453 | } | |
454 | prstat(); | |
455 | } | |
456 | } | |
457 | ||
458 | /* | |
459 | * Print the status of the printer queue. | |
460 | */ | |
461 | prstat() | |
462 | { | |
463 | struct stat stbuf; | |
464 | register int fd, i; | |
465 | register struct direct *dp; | |
466 | DIR *dirp; | |
467 | ||
468 | bp = pbuf; | |
469 | if ((SD = pgetstr("sd", &bp)) == NULL) | |
470 | SD = DEFSPOOL; | |
471 | if ((LO = pgetstr("lo", &bp)) == NULL) | |
472 | LO = DEFLOCK; | |
473 | if ((ST = pgetstr("st", &bp)) == NULL) | |
474 | ST = DEFSTAT; | |
475 | printf("%s:\n", printer); | |
476 | (void) sprintf(line, "%s/%s", SD, LO); | |
477 | if (stat(line, &stbuf) >= 0) { | |
478 | printf("\tqueuing is %s\n", | |
479 | (stbuf.st_mode & 010) ? "disabled" : "enabled"); | |
480 | printf("\tprinting is %s\n", | |
481 | (stbuf.st_mode & 0100) ? "disabled" : "enabled"); | |
482 | } else { | |
483 | printf("\tqueuing is enabled\n"); | |
484 | printf("\tprinting is enabled\n"); | |
485 | } | |
486 | if ((dirp = opendir(SD)) == NULL) { | |
487 | printf("\tcannot examine spool directory\n"); | |
488 | return; | |
489 | } | |
490 | i = 0; | |
491 | while ((dp = readdir(dirp)) != NULL) { | |
492 | if (*dp->d_name == 'c' && dp->d_name[1] == 'f') | |
493 | i++; | |
494 | } | |
495 | closedir(dirp); | |
496 | if (i == 0) | |
497 | printf("\tno entries\n"); | |
498 | else if (i == 1) | |
499 | printf("\t1 entry in spool area\n"); | |
500 | else | |
501 | printf("\t%d entries in spool area\n", i); | |
adec4d9e SL |
502 | fd = open(line, O_RDONLY); |
503 | if (fd < 0 || flock(fd, LOCK_SH|LOCK_NB) == 0) { | |
5df74a28 RC |
504 | (void) close(fd); |
505 | printf("\tno daemon present\n"); | |
506 | return; | |
507 | } | |
508 | (void) close(fd); | |
509 | putchar('\t'); | |
510 | (void) sprintf(line, "%s/%s", SD, ST); | |
adec4d9e SL |
511 | fd = open(line, O_RDONLY); |
512 | if (fd >= 0) { | |
513 | (void) flock(fd, LOCK_SH); | |
5df74a28 RC |
514 | while ((i = read(fd, line, sizeof(line))) > 0) |
515 | (void) fwrite(line, 1, i, stdout); | |
516 | (void) close(fd); | |
517 | } | |
518 | } | |
519 | ||
520 | /* | |
521 | * Stop the specified daemon after completing the current job and disable | |
522 | * printing. | |
523 | */ | |
524 | stop(argc, argv) | |
525 | char *argv[]; | |
526 | { | |
527 | register int c, status; | |
528 | register char *cp1, *cp2; | |
529 | char prbuf[100]; | |
530 | ||
531 | if (argc == 1) { | |
532 | printf("Usage: stop {all | printer ...}\n"); | |
533 | return; | |
534 | } | |
535 | if (argc == 2 && !strcmp(argv[1], "all")) { | |
536 | printer = prbuf; | |
537 | while (getprent(line) > 0) { | |
538 | cp1 = prbuf; | |
539 | cp2 = line; | |
540 | while ((c = *cp2++) && c != '|' && c != ':') | |
541 | *cp1++ = c; | |
542 | *cp1 = '\0'; | |
543 | stoppr(); | |
544 | } | |
545 | return; | |
546 | } | |
547 | while (--argc) { | |
548 | printer = *++argv; | |
549 | if ((status = pgetent(line, printer)) < 0) { | |
7b22a8ae | 550 | printf("cannot open printer description file\n"); |
5df74a28 RC |
551 | continue; |
552 | } else if (status == 0) { | |
7b22a8ae | 553 | printf("unknown printer %s\n", printer); |
5df74a28 RC |
554 | continue; |
555 | } | |
556 | stoppr(); | |
557 | } | |
558 | } | |
559 | ||
560 | stoppr() | |
561 | { | |
562 | register int fd; | |
563 | struct stat stbuf; | |
564 | ||
565 | bp = pbuf; | |
566 | if ((SD = pgetstr("sd", &bp)) == NULL) | |
567 | SD = DEFSPOOL; | |
568 | if ((LO = pgetstr("lo", &bp)) == NULL) | |
569 | LO = DEFLOCK; | |
570 | (void) sprintf(line, "%s/%s", SD, LO); | |
571 | printf("%s:\n", printer); | |
572 | ||
573 | /* | |
574 | * Turn on the owner execute bit of the lock file to disable printing. | |
575 | */ | |
576 | if (stat(line, &stbuf) >= 0) { | |
577 | if (chmod(line, (stbuf.st_mode & 0777) | 0100) < 0) | |
578 | printf("\tcannot disable printing\n"); | |
579 | else | |
580 | printf("\tprinting disabled\n"); | |
581 | } else if (errno == ENOENT) { | |
adec4d9e | 582 | if ((fd = open(line, O_WRONLY|O_CREAT, 0760)) < 0) |
5df74a28 RC |
583 | printf("\tcannot create lock file\n"); |
584 | else { | |
585 | (void) close(fd); | |
586 | printf("\tprinting disabled\n"); | |
587 | } | |
588 | } else | |
589 | printf("\tcannot stat lock file\n"); | |
590 | } |