|
|
1.1 root 1: #ifndef lint
2: static char sccsid[] = "@(#)cmds.c 4.8 (Berkeley) 7/27/83";
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) {
40: printf("cannot open printer description file\n");
41: continue;
42: } else if (status == 0) {
43: printf("unknown printer %s\n", printer);
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) {
73: if ((fd = open(line, O_WRONLY|O_CREAT, 0760)) < 0)
74: printf("\tcannot create lock file\n");
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: }
92: if (!getline(fp) || flock(fileno(fp), LOCK_SH|LOCK_NB) == 0) {
93: (void) fclose(fp); /* unlocks as well */
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) {
133: printf("cannot open printer description file\n");
134: continue;
135: } else if (status == 0) {
136: printf("unknown printer %s\n", printer);
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) {
203: printf("cannot open printer description file\n");
204: continue;
205: } else if (status == 0) {
206: printf("unknown printer %s\n", printer);
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)
230: printf("\tcannot enable queuing\n");
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) {
265: printf("cannot open printer description file\n");
266: continue;
267: } else if (status == 0) {
268: printf("unknown printer %s\n", printer);
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) {
296: if ((fd = open(line, O_WRONLY|O_CREAT, 0670)) < 0)
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) {
346: printf("cannot open printer description file\n");
347: continue;
348: } else if (status == 0) {
349: printf("unknown printer %s\n", printer);
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) {
386: printf("cannot open printer description file\n");
387: continue;
388: } else if (status == 0) {
389: printf("unknown printer %s\n", printer);
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;
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: }
417: if (!startdaemon(printer))
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) {
448: printf("cannot open printer description file\n");
449: continue;
450: } else if (status == 0) {
451: printf("unknown printer %s\n", printer);
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);
502: fd = open(line, O_RDONLY);
503: if (fd < 0 || flock(fd, LOCK_SH|LOCK_NB) == 0) {
504: (void) close(fd); /* unlocks as well */
505: printf("\tno daemon present\n");
506: return;
507: }
508: (void) close(fd);
509: putchar('\t');
510: (void) sprintf(line, "%s/%s", SD, ST);
511: fd = open(line, O_RDONLY);
512: if (fd >= 0) {
513: (void) flock(fd, LOCK_SH);
514: while ((i = read(fd, line, sizeof(line))) > 0)
515: (void) fwrite(line, 1, i, stdout);
516: (void) close(fd); /* unlocks as well */
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) {
550: printf("cannot open printer description file\n");
551: continue;
552: } else if (status == 0) {
553: printf("unknown printer %s\n", printer);
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) {
582: if ((fd = open(line, O_WRONLY|O_CREAT, 0760)) < 0)
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: }
591:
592: /*
593: * Put the specified jobs at the top of printer queue.
594: */
595: topq(argc, argv)
596: char *argv[];
597: {
598: register int status, nitems, n;
599: struct stat stbuf;
600: register char *cfname;
601: struct queue **queue;
602: int changed = 0;
603:
604: if (argc == 1) {
605: printf("Usage: topq printer [jobnum ...] [user ...]\n");
606: return;
607: }
608:
609: --argc;
610: printer = *++argv;
611: status = pgetent(line, printer);
612: if (status < 0) {
613: printf("cannot open printer description file\n");
614: return;
615: } else if (status == 0) {
616: printf("%s: unknown printer\n", printer);
617: return;
618: }
619: bp = pbuf;
620: if ((SD = pgetstr("sd", &bp)) == NULL)
621: SD = DEFSPOOL;
622: if ((LO = pgetstr("lo", &bp)) == NULL)
623: LO = DEFLOCK;
624: printf("%s:\n", printer);
625:
626: if (chdir(SD) < 0) {
627: printf("\tcannot chdir to %s\n", SD);
628: return;
629: }
630: nitems = getq(&queue);
631: while (--argc) {
632: if ((n = inqueue(*++argv, queue, nitems)) < 0) {
633: printf("\tjob %s is not in the queue\n", *argv);
634: continue;
635: }
636: /*
637: * Reposition the job by changing the modification time of
638: * the control file.
639: */
640: if (touch(queue[n]->q_name)) {
641: free(queue[n]);
642: queue[n] = NULL;
643: changed++;
644: }
645: }
646: /*
647: * Put the remaining jobs at the end of the queue.
648: */
649: for (n = 0; n < nitems; n++) {
650: if (queue[n] == NULL)
651: continue;
652: cfname = queue[n]->q_name;
653: if (changed)
654: touch(cfname);
655: free(cfname);
656: }
657: free(queue);
658: printf("\tqueue order %s\n", changed ? "changed" : "unchanged");
659: /*
660: * Turn on the public execute bit of the lock file to
661: * get lpd to rebuild the queue after the current job.
662: */
663: if (changed && stat(LO, &stbuf) >= 0)
664: (void) chmod(LO, (stbuf.st_mode & 0777) | 01);
665: }
666:
667: /*
668: * Change the modification time of the file.
669: * Returns boolean if successful.
670: */
671: touch(cfname)
672: char *cfname;
673: {
674: register int fd;
675:
676: fd = open(cfname, O_RDWR);
677: if (fd < 0) {
678: printf("\tcannot open %s\n", cfname);
679: return(0);
680: }
681: (void) read(fd, line, 1);
682: (void) lseek(fd, 0L, 0); /* set pointer back to top of file */
683: (void) write(fd, line, 1);
684: (void) close(fd);
685: sleep(1); /* so times will be different */
686: return(1);
687: }
688:
689: /*
690: * Checks if specified job name is in the printer's queue.
691: * Returns: negative (-1) if argument name is not in the queue.
692: * 0 to n: array index of pointer to argument name.
693: */
694: inqueue(job, queue, nitems)
695: char *job;
696: struct queue *queue[];
697: int nitems;
698: {
699: register struct queue *q;
700: register int n, jobnum;
701: register char *cp;
702: FILE *fp;
703:
704: jobnum = -1;
705: if (isdigit(*job)) {
706: jobnum = 0;
707: do
708: jobnum = jobnum * 10 + (*job++ - '0');
709: while (isdigit(*job));
710: }
711:
712: while (--nitems >= 0) {
713: if ((q = queue[nitems]) == NULL)
714: continue;
715: /* this needs to be fixed since the same number can be used
716: by different machines (i.e. jobnum & machine) */
717: if (jobnum >= 0) {
718: n = 0;
719: for (cp = q->q_name+3; isdigit(*cp); )
720: n = n * 10 + (*cp++ - '0');
721: if (jobnum == n)
722: return(nitems);
723: continue;
724: }
725: /*
726: * Read cf file for owner's name
727: */
728: if ((fp = fopen(q->q_name, "r")) == NULL)
729: continue;
730: while (getline(fp) > 0) {
731: if (line[0] == 'P' && !strcmp(job, line+1)) {
732: (void) fclose(fp);
733: return(nitems);
734: }
735: }
736: (void) fclose(fp);
737: }
738: return(-1);
739: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.