|
|
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[] = "@(#)cmds.c 5.7 (Berkeley) 6/1/90";
22: #endif /* not lint */
23:
24: /*
25: * lpc -- line printer control program -- commands:
26: */
27:
28: #include "lp.h"
29: #include <sys/time.h>
30: #include "pathnames.h"
31:
32: /*
33: * kill an existing daemon and disable printing.
34: */
35: abort(argc, argv)
36: char *argv[];
37: {
38: register int c, status;
39: register char *cp1, *cp2;
40: char prbuf[100];
41:
42: if (argc == 1) {
43: printf("Usage: abort {all | printer ...}\n");
44: return;
45: }
46: if (argc == 2 && !strcmp(argv[1], "all")) {
47: printer = prbuf;
48: while (getprent(line) > 0) {
49: cp1 = prbuf;
50: cp2 = line;
51: while ((c = *cp2++) && c != '|' && c != ':')
52: *cp1++ = c;
53: *cp1 = '\0';
54: abortpr(1);
55: }
56: return;
57: }
58: while (--argc) {
59: printer = *++argv;
60: if ((status = pgetent(line, printer)) < 0) {
61: printf("cannot open printer description file\n");
62: continue;
63: } else if (status == 0) {
64: printf("unknown printer %s\n", printer);
65: continue;
66: }
67: abortpr(1);
68: }
69: }
70:
71: abortpr(dis)
72: {
73: register FILE *fp;
74: struct stat stbuf;
75: int pid, fd;
76:
77: bp = pbuf;
78: if ((SD = pgetstr("sd", &bp)) == NULL)
79: SD = _PATH_DEFSPOOL;
80: if ((LO = pgetstr("lo", &bp)) == NULL)
81: LO = DEFLOCK;
82: (void) sprintf(line, "%s/%s", SD, LO);
83: printf("%s:\n", printer);
84:
85: /*
86: * Turn on the owner execute bit of the lock file to disable printing.
87: */
88: if (dis) {
89: if (stat(line, &stbuf) >= 0) {
90: if (chmod(line, (stbuf.st_mode & 0777) | 0100) < 0)
91: printf("\tcannot disable printing\n");
92: else {
93: upstat("printing disabled\n");
94: printf("\tprinting disabled\n");
95: }
96: } else if (errno == ENOENT) {
97: if ((fd = open(line, O_WRONLY|O_CREAT, 0760)) < 0)
98: printf("\tcannot create lock file\n");
99: else {
100: (void) close(fd);
101: upstat("printing disabled\n");
102: printf("\tprinting disabled\n");
103: printf("\tno daemon to abort\n");
104: }
105: return;
106: } else {
107: printf("\tcannot stat lock file\n");
108: return;
109: }
110: }
111: /*
112: * Kill the current daemon to stop printing now.
113: */
114: if ((fp = fopen(line, "r")) == NULL) {
115: printf("\tcannot open lock file\n");
116: return;
117: }
118: if (!getline(fp) || flock(fileno(fp), LOCK_SH|LOCK_NB) == 0) {
119: (void) fclose(fp); /* unlocks as well */
120: printf("\tno daemon to abort\n");
121: return;
122: }
123: (void) fclose(fp);
124: if (kill(pid = atoi(line), SIGTERM) < 0)
125: printf("\tWarning: daemon (pid %d) not killed\n", pid);
126: else
127: printf("\tdaemon (pid %d) killed\n", pid);
128: }
129:
130: /*
131: * Write a message into the status file.
132: */
133: upstat(msg)
134: char *msg;
135: {
136: register int fd;
137: char statfile[BUFSIZ];
138:
139: bp = pbuf;
140: if ((ST = pgetstr("st", &bp)) == NULL)
141: ST = DEFSTAT;
142: (void) sprintf(statfile, "%s/%s", SD, ST);
143: umask(0);
144: fd = open(statfile, O_WRONLY|O_CREAT, 0664);
145: if (fd < 0 || flock(fd, LOCK_EX) < 0) {
146: printf("\tcannot create status file\n");
147: return;
148: }
149: (void) ftruncate(fd, 0);
150: if (msg == (char *)NULL)
151: (void) write(fd, "\n", 1);
152: else
153: (void) write(fd, msg, strlen(msg));
154: (void) close(fd);
155: }
156:
157: /*
158: * Remove all spool files and temporaries from the spooling area.
159: */
160: clean(argc, argv)
161: char *argv[];
162: {
163: register int c, status;
164: register char *cp1, *cp2;
165: char prbuf[100];
166:
167: if (argc == 1) {
168: printf("Usage: clean {all | printer ...}\n");
169: return;
170: }
171: if (argc == 2 && !strcmp(argv[1], "all")) {
172: printer = prbuf;
173: while (getprent(line) > 0) {
174: cp1 = prbuf;
175: cp2 = line;
176: while ((c = *cp2++) && c != '|' && c != ':')
177: *cp1++ = c;
178: *cp1 = '\0';
179: cleanpr();
180: }
181: return;
182: }
183: while (--argc) {
184: printer = *++argv;
185: if ((status = pgetent(line, printer)) < 0) {
186: printf("cannot open printer description file\n");
187: continue;
188: } else if (status == 0) {
189: printf("unknown printer %s\n", printer);
190: continue;
191: }
192: cleanpr();
193: }
194: }
195:
196: select(d)
197: struct direct *d;
198: {
199: int c = d->d_name[0];
200:
201: if ((c == 't' || c == 'c' || c == 'd') && d->d_name[1] == 'f')
202: return(1);
203: return(0);
204: }
205:
206: /*
207: * Comparison routine for scandir. Sort by job number and machine, then
208: * by `cf', `tf', or `df', then by the sequence letter A-Z, a-z.
209: */
210: sortq(d1, d2)
211: struct direct **d1, **d2;
212: {
213: int c1, c2;
214:
215: if (c1 = strcmp((*d1)->d_name + 3, (*d2)->d_name + 3))
216: return(c1);
217: c1 = (*d1)->d_name[0];
218: c2 = (*d2)->d_name[0];
219: if (c1 == c2)
220: return((*d1)->d_name[2] - (*d2)->d_name[2]);
221: if (c1 == 'c')
222: return(-1);
223: if (c1 == 'd' || c2 == 'c')
224: return(1);
225: return(-1);
226: }
227:
228: /*
229: * Remove incomplete jobs from spooling area.
230: */
231: cleanpr()
232: {
233: register int i, n;
234: register char *cp, *cp1, *lp;
235: struct direct **queue;
236: int nitems;
237:
238: bp = pbuf;
239: if ((SD = pgetstr("sd", &bp)) == NULL)
240: SD = _PATH_DEFSPOOL;
241: printf("%s:\n", printer);
242:
243: for (lp = line, cp = SD; *lp++ = *cp++; )
244: ;
245: lp[-1] = '/';
246:
247: nitems = scandir(SD, &queue, select, sortq);
248: if (nitems < 0) {
249: printf("\tcannot examine spool directory\n");
250: return;
251: }
252: if (nitems == 0)
253: return;
254: i = 0;
255: do {
256: cp = queue[i]->d_name;
257: if (*cp == 'c') {
258: n = 0;
259: while (i + 1 < nitems) {
260: cp1 = queue[i + 1]->d_name;
261: if (*cp1 != 'd' || strcmp(cp + 3, cp1 + 3))
262: break;
263: i++;
264: n++;
265: }
266: if (n == 0) {
267: strcpy(lp, cp);
268: unlinkf(line);
269: }
270: } else {
271: /*
272: * Must be a df with no cf (otherwise, it would have
273: * been skipped above) or a tf file (which can always
274: * be removed).
275: */
276: strcpy(lp, cp);
277: unlinkf(line);
278: }
279: } while (++i < nitems);
280: }
281:
282: unlinkf(name)
283: char *name;
284: {
285: if (unlink(name) < 0)
286: printf("\tcannot remove %s\n", name);
287: else
288: printf("\tremoved %s\n", name);
289: }
290:
291: /*
292: * Enable queuing to the printer (allow lpr's).
293: */
294: enable(argc, argv)
295: char *argv[];
296: {
297: register int c, status;
298: register char *cp1, *cp2;
299: char prbuf[100];
300:
301: if (argc == 1) {
302: printf("Usage: enable {all | printer ...}\n");
303: return;
304: }
305: if (argc == 2 && !strcmp(argv[1], "all")) {
306: printer = prbuf;
307: while (getprent(line) > 0) {
308: cp1 = prbuf;
309: cp2 = line;
310: while ((c = *cp2++) && c != '|' && c != ':')
311: *cp1++ = c;
312: *cp1 = '\0';
313: enablepr();
314: }
315: return;
316: }
317: while (--argc) {
318: printer = *++argv;
319: if ((status = pgetent(line, printer)) < 0) {
320: printf("cannot open printer description file\n");
321: continue;
322: } else if (status == 0) {
323: printf("unknown printer %s\n", printer);
324: continue;
325: }
326: enablepr();
327: }
328: }
329:
330: enablepr()
331: {
332: struct stat stbuf;
333:
334: bp = pbuf;
335: if ((SD = pgetstr("sd", &bp)) == NULL)
336: SD = _PATH_DEFSPOOL;
337: if ((LO = pgetstr("lo", &bp)) == NULL)
338: LO = DEFLOCK;
339: (void) sprintf(line, "%s/%s", SD, LO);
340: printf("%s:\n", printer);
341:
342: /*
343: * Turn off the group execute bit of the lock file to enable queuing.
344: */
345: if (stat(line, &stbuf) >= 0) {
346: if (chmod(line, stbuf.st_mode & 0767) < 0)
347: printf("\tcannot enable queuing\n");
348: else
349: printf("\tqueuing enabled\n");
350: }
351: }
352:
353: /*
354: * Disable queuing.
355: */
356: disable(argc, argv)
357: char *argv[];
358: {
359: register int c, status;
360: register char *cp1, *cp2;
361: char prbuf[100];
362:
363: if (argc == 1) {
364: printf("Usage: disable {all | printer ...}\n");
365: return;
366: }
367: if (argc == 2 && !strcmp(argv[1], "all")) {
368: printer = prbuf;
369: while (getprent(line) > 0) {
370: cp1 = prbuf;
371: cp2 = line;
372: while ((c = *cp2++) && c != '|' && c != ':')
373: *cp1++ = c;
374: *cp1 = '\0';
375: disablepr();
376: }
377: return;
378: }
379: while (--argc) {
380: printer = *++argv;
381: if ((status = pgetent(line, printer)) < 0) {
382: printf("cannot open printer description file\n");
383: continue;
384: } else if (status == 0) {
385: printf("unknown printer %s\n", printer);
386: continue;
387: }
388: disablepr();
389: }
390: }
391:
392: disablepr()
393: {
394: register int fd;
395: struct stat stbuf;
396:
397: bp = pbuf;
398: if ((SD = pgetstr("sd", &bp)) == NULL)
399: SD = _PATH_DEFSPOOL;
400: if ((LO = pgetstr("lo", &bp)) == NULL)
401: LO = DEFLOCK;
402: (void) sprintf(line, "%s/%s", SD, LO);
403: printf("%s:\n", printer);
404: /*
405: * Turn on the group execute bit of the lock file to disable queuing.
406: */
407: if (stat(line, &stbuf) >= 0) {
408: if (chmod(line, (stbuf.st_mode & 0777) | 010) < 0)
409: printf("\tcannot disable queuing\n");
410: else
411: printf("\tqueuing disabled\n");
412: } else if (errno == ENOENT) {
413: if ((fd = open(line, O_WRONLY|O_CREAT, 0670)) < 0)
414: printf("\tcannot create lock file\n");
415: else {
416: (void) close(fd);
417: printf("\tqueuing disabled\n");
418: }
419: return;
420: } else
421: printf("\tcannot stat lock file\n");
422: }
423:
424: /*
425: * Disable queuing and printing and put a message into the status file
426: * (reason for being down).
427: */
428: down(argc, argv)
429: char *argv[];
430: {
431: register int c, status;
432: register char *cp1, *cp2;
433: char prbuf[100];
434:
435: if (argc == 1) {
436: printf("Usage: down {all | printer} [message ...]\n");
437: return;
438: }
439: if (!strcmp(argv[1], "all")) {
440: printer = prbuf;
441: while (getprent(line) > 0) {
442: cp1 = prbuf;
443: cp2 = line;
444: while ((c = *cp2++) && c != '|' && c != ':')
445: *cp1++ = c;
446: *cp1 = '\0';
447: putmsg(argc - 2, argv + 2);
448: }
449: return;
450: }
451: printer = argv[1];
452: if ((status = pgetent(line, printer)) < 0) {
453: printf("cannot open printer description file\n");
454: return;
455: } else if (status == 0) {
456: printf("unknown printer %s\n", printer);
457: return;
458: }
459: putmsg(argc - 2, argv + 2);
460: }
461:
462: putmsg(argc, argv)
463: char **argv;
464: {
465: register int fd;
466: register char *cp1, *cp2;
467: char buf[1024];
468: struct stat stbuf;
469:
470: bp = pbuf;
471: if ((SD = pgetstr("sd", &bp)) == NULL)
472: SD = _PATH_DEFSPOOL;
473: if ((LO = pgetstr("lo", &bp)) == NULL)
474: LO = DEFLOCK;
475: if ((ST = pgetstr("st", &bp)) == NULL)
476: ST = DEFSTAT;
477: printf("%s:\n", printer);
478: /*
479: * Turn on the group execute bit of the lock file to disable queuing and
480: * turn on the owner execute bit of the lock file to disable printing.
481: */
482: (void) sprintf(line, "%s/%s", SD, LO);
483: if (stat(line, &stbuf) >= 0) {
484: if (chmod(line, (stbuf.st_mode & 0777) | 0110) < 0)
485: printf("\tcannot disable queuing\n");
486: else
487: printf("\tprinter and queuing disabled\n");
488: } else if (errno == ENOENT) {
489: if ((fd = open(line, O_WRONLY|O_CREAT, 0770)) < 0)
490: printf("\tcannot create lock file\n");
491: else {
492: (void) close(fd);
493: printf("\tprinter and queuing disabled\n");
494: }
495: return;
496: } else
497: printf("\tcannot stat lock file\n");
498: /*
499: * Write the message into the status file.
500: */
501: (void) sprintf(line, "%s/%s", SD, ST);
502: fd = open(line, O_WRONLY|O_CREAT, 0664);
503: if (fd < 0 || flock(fd, LOCK_EX) < 0) {
504: printf("\tcannot create status file\n");
505: return;
506: }
507: (void) ftruncate(fd, 0);
508: if (argc <= 0) {
509: (void) write(fd, "\n", 1);
510: (void) close(fd);
511: return;
512: }
513: cp1 = buf;
514: while (--argc >= 0) {
515: cp2 = *argv++;
516: while (*cp1++ = *cp2++)
517: ;
518: cp1[-1] = ' ';
519: }
520: cp1[-1] = '\n';
521: *cp1 = '\0';
522: (void) write(fd, buf, strlen(buf));
523: (void) close(fd);
524: }
525:
526: /*
527: * Exit lpc
528: */
529: quit(argc, argv)
530: char *argv[];
531: {
532: exit(0);
533: }
534:
535: /*
536: * Kill and restart the daemon.
537: */
538: restart(argc, argv)
539: char *argv[];
540: {
541: register int c, status;
542: register char *cp1, *cp2;
543: char prbuf[100];
544:
545: if (argc == 1) {
546: printf("Usage: restart {all | printer ...}\n");
547: return;
548: }
549: if (argc == 2 && !strcmp(argv[1], "all")) {
550: printer = prbuf;
551: while (getprent(line) > 0) {
552: cp1 = prbuf;
553: cp2 = line;
554: while ((c = *cp2++) && c != '|' && c != ':')
555: *cp1++ = c;
556: *cp1 = '\0';
557: abortpr(0);
558: startpr(0);
559: }
560: return;
561: }
562: while (--argc) {
563: printer = *++argv;
564: if ((status = pgetent(line, printer)) < 0) {
565: printf("cannot open printer description file\n");
566: continue;
567: } else if (status == 0) {
568: printf("unknown printer %s\n", printer);
569: continue;
570: }
571: abortpr(0);
572: startpr(0);
573: }
574: }
575:
576: /*
577: * Enable printing on the specified printer and startup the daemon.
578: */
579: start(argc, argv)
580: char *argv[];
581: {
582: register int c, status;
583: register char *cp1, *cp2;
584: char prbuf[100];
585:
586: if (argc == 1) {
587: printf("Usage: start {all | printer ...}\n");
588: return;
589: }
590: if (argc == 2 && !strcmp(argv[1], "all")) {
591: printer = prbuf;
592: while (getprent(line) > 0) {
593: cp1 = prbuf;
594: cp2 = line;
595: while ((c = *cp2++) && c != '|' && c != ':')
596: *cp1++ = c;
597: *cp1 = '\0';
598: startpr(1);
599: }
600: return;
601: }
602: while (--argc) {
603: printer = *++argv;
604: if ((status = pgetent(line, printer)) < 0) {
605: printf("cannot open printer description file\n");
606: continue;
607: } else if (status == 0) {
608: printf("unknown printer %s\n", printer);
609: continue;
610: }
611: startpr(1);
612: }
613: }
614:
615: startpr(enable)
616: {
617: struct stat stbuf;
618:
619: bp = pbuf;
620: if ((SD = pgetstr("sd", &bp)) == NULL)
621: SD = _PATH_DEFSPOOL;
622: if ((LO = pgetstr("lo", &bp)) == NULL)
623: LO = DEFLOCK;
624: (void) sprintf(line, "%s/%s", SD, LO);
625: printf("%s:\n", printer);
626:
627: /*
628: * Turn off the owner execute bit of the lock file to enable printing.
629: */
630: if (enable && stat(line, &stbuf) >= 0) {
631: if (chmod(line, stbuf.st_mode & (enable==2 ? 0666 : 0677)) < 0)
632: printf("\tcannot enable printing\n");
633: else
634: printf("\tprinting enabled\n");
635: }
636: if (!startdaemon(printer))
637: printf("\tcouldn't start daemon\n");
638: else
639: printf("\tdaemon started\n");
640: }
641:
642: /*
643: * Print the status of each queue listed or all the queues.
644: */
645: status(argc, argv)
646: char *argv[];
647: {
648: register int c, status;
649: register char *cp1, *cp2;
650: char prbuf[100];
651:
652: if (argc == 1) {
653: printer = prbuf;
654: while (getprent(line) > 0) {
655: cp1 = prbuf;
656: cp2 = line;
657: while ((c = *cp2++) && c != '|' && c != ':')
658: *cp1++ = c;
659: *cp1 = '\0';
660: prstat();
661: }
662: return;
663: }
664: while (--argc) {
665: printer = *++argv;
666: if ((status = pgetent(line, printer)) < 0) {
667: printf("cannot open printer description file\n");
668: continue;
669: } else if (status == 0) {
670: printf("unknown printer %s\n", printer);
671: continue;
672: }
673: prstat();
674: }
675: }
676:
677: /*
678: * Print the status of the printer queue.
679: */
680: prstat()
681: {
682: struct stat stbuf;
683: register int fd, i;
684: register struct direct *dp;
685: DIR *dirp;
686:
687: bp = pbuf;
688: if ((SD = pgetstr("sd", &bp)) == NULL)
689: SD = _PATH_DEFSPOOL;
690: if ((LO = pgetstr("lo", &bp)) == NULL)
691: LO = DEFLOCK;
692: if ((ST = pgetstr("st", &bp)) == NULL)
693: ST = DEFSTAT;
694: printf("%s:\n", printer);
695: (void) sprintf(line, "%s/%s", SD, LO);
696: if (stat(line, &stbuf) >= 0) {
697: printf("\tqueuing is %s\n",
698: (stbuf.st_mode & 010) ? "disabled" : "enabled");
699: printf("\tprinting is %s\n",
700: (stbuf.st_mode & 0100) ? "disabled" : "enabled");
701: } else {
702: printf("\tqueuing is enabled\n");
703: printf("\tprinting is enabled\n");
704: }
705: if ((dirp = opendir(SD)) == NULL) {
706: printf("\tcannot examine spool directory\n");
707: return;
708: }
709: i = 0;
710: while ((dp = readdir(dirp)) != NULL) {
711: if (*dp->d_name == 'c' && dp->d_name[1] == 'f')
712: i++;
713: }
714: closedir(dirp);
715: if (i == 0)
716: printf("\tno entries\n");
717: else if (i == 1)
718: printf("\t1 entry in spool area\n");
719: else
720: printf("\t%d entries in spool area\n", i);
721: fd = open(line, O_RDONLY);
722: if (fd < 0 || flock(fd, LOCK_SH|LOCK_NB) == 0) {
723: (void) close(fd); /* unlocks as well */
724: printf("\tno daemon present\n");
725: return;
726: }
727: (void) close(fd);
728: putchar('\t');
729: (void) sprintf(line, "%s/%s", SD, ST);
730: fd = open(line, O_RDONLY);
731: if (fd >= 0) {
732: (void) flock(fd, LOCK_SH);
733: while ((i = read(fd, line, sizeof(line))) > 0)
734: (void) fwrite(line, 1, i, stdout);
735: (void) close(fd); /* unlocks as well */
736: }
737: }
738:
739: /*
740: * Stop the specified daemon after completing the current job and disable
741: * printing.
742: */
743: stop(argc, argv)
744: char *argv[];
745: {
746: register int c, status;
747: register char *cp1, *cp2;
748: char prbuf[100];
749:
750: if (argc == 1) {
751: printf("Usage: stop {all | printer ...}\n");
752: return;
753: }
754: if (argc == 2 && !strcmp(argv[1], "all")) {
755: printer = prbuf;
756: while (getprent(line) > 0) {
757: cp1 = prbuf;
758: cp2 = line;
759: while ((c = *cp2++) && c != '|' && c != ':')
760: *cp1++ = c;
761: *cp1 = '\0';
762: stoppr();
763: }
764: return;
765: }
766: while (--argc) {
767: printer = *++argv;
768: if ((status = pgetent(line, printer)) < 0) {
769: printf("cannot open printer description file\n");
770: continue;
771: } else if (status == 0) {
772: printf("unknown printer %s\n", printer);
773: continue;
774: }
775: stoppr();
776: }
777: }
778:
779: stoppr()
780: {
781: register int fd;
782: struct stat stbuf;
783:
784: bp = pbuf;
785: if ((SD = pgetstr("sd", &bp)) == NULL)
786: SD = _PATH_DEFSPOOL;
787: if ((LO = pgetstr("lo", &bp)) == NULL)
788: LO = DEFLOCK;
789: (void) sprintf(line, "%s/%s", SD, LO);
790: printf("%s:\n", printer);
791:
792: /*
793: * Turn on the owner execute bit of the lock file to disable printing.
794: */
795: if (stat(line, &stbuf) >= 0) {
796: if (chmod(line, (stbuf.st_mode & 0777) | 0100) < 0)
797: printf("\tcannot disable printing\n");
798: else {
799: upstat("printing disabled\n");
800: printf("\tprinting disabled\n");
801: }
802: } else if (errno == ENOENT) {
803: if ((fd = open(line, O_WRONLY|O_CREAT, 0760)) < 0)
804: printf("\tcannot create lock file\n");
805: else {
806: (void) close(fd);
807: upstat("printing disabled\n");
808: printf("\tprinting disabled\n");
809: }
810: } else
811: printf("\tcannot stat lock file\n");
812: }
813:
814: struct queue **queue;
815: int nitems;
816: time_t mtime;
817:
818: /*
819: * Put the specified jobs at the top of printer queue.
820: */
821: topq(argc, argv)
822: char *argv[];
823: {
824: register int n, i;
825: struct stat stbuf;
826: register char *cfname;
827: int status, changed;
828:
829: if (argc < 3) {
830: printf("Usage: topq printer [jobnum ...] [user ...]\n");
831: return;
832: }
833:
834: --argc;
835: printer = *++argv;
836: status = pgetent(line, printer);
837: if (status < 0) {
838: printf("cannot open printer description file\n");
839: return;
840: } else if (status == 0) {
841: printf("%s: unknown printer\n", printer);
842: return;
843: }
844: bp = pbuf;
845: if ((SD = pgetstr("sd", &bp)) == NULL)
846: SD = _PATH_DEFSPOOL;
847: if ((LO = pgetstr("lo", &bp)) == NULL)
848: LO = DEFLOCK;
849: printf("%s:\n", printer);
850:
851: if (chdir(SD) < 0) {
852: printf("\tcannot chdir to %s\n", SD);
853: return;
854: }
855: nitems = getq(&queue);
856: if (nitems == 0)
857: return;
858: changed = 0;
859: mtime = queue[0]->q_time;
860: for (i = argc; --i; ) {
861: if (doarg(argv[i]) == 0) {
862: printf("\tjob %s is not in the queue\n", argv[i]);
863: continue;
864: } else
865: changed++;
866: }
867: for (i = 0; i < nitems; i++)
868: free(queue[i]);
869: free(queue);
870: if (!changed) {
871: printf("\tqueue order unchanged\n");
872: return;
873: }
874: /*
875: * Turn on the public execute bit of the lock file to
876: * get lpd to rebuild the queue after the current job.
877: */
878: if (changed && stat(LO, &stbuf) >= 0)
879: (void) chmod(LO, (stbuf.st_mode & 0777) | 01);
880: }
881:
882: /*
883: * Reposition the job by changing the modification time of
884: * the control file.
885: */
886: touch(q)
887: struct queue *q;
888: {
889: struct timeval tvp[2];
890:
891: tvp[0].tv_sec = tvp[1].tv_sec = --mtime;
892: tvp[0].tv_usec = tvp[1].tv_usec = 0;
893: return(utimes(q->q_name, tvp));
894: }
895:
896: /*
897: * Checks if specified job name is in the printer's queue.
898: * Returns: negative (-1) if argument name is not in the queue.
899: */
900: doarg(job)
901: char *job;
902: {
903: register struct queue **qq;
904: register int jobnum, n;
905: register char *cp, *machine;
906: int cnt = 0;
907: FILE *fp;
908:
909: /*
910: * Look for a job item consisting of system name, colon, number
911: * (example: ucbarpa:114)
912: */
913: if ((cp = index(job, ':')) != NULL) {
914: machine = job;
915: *cp++ = '\0';
916: job = cp;
917: } else
918: machine = NULL;
919:
920: /*
921: * Check for job specified by number (example: 112 or 235ucbarpa).
922: */
923: if (isdigit(*job)) {
924: jobnum = 0;
925: do
926: jobnum = jobnum * 10 + (*job++ - '0');
927: while (isdigit(*job));
928: for (qq = queue + nitems; --qq >= queue; ) {
929: n = 0;
930: for (cp = (*qq)->q_name+3; isdigit(*cp); )
931: n = n * 10 + (*cp++ - '0');
932: if (jobnum != n)
933: continue;
934: if (*job && strcmp(job, cp) != 0)
935: continue;
936: if (machine != NULL && strcmp(machine, cp) != 0)
937: continue;
938: if (touch(*qq) == 0) {
939: printf("\tmoved %s\n", (*qq)->q_name);
940: cnt++;
941: }
942: }
943: return(cnt);
944: }
945: /*
946: * Process item consisting of owner's name (example: henry).
947: */
948: for (qq = queue + nitems; --qq >= queue; ) {
949: if ((fp = fopen((*qq)->q_name, "r")) == NULL)
950: continue;
951: while (getline(fp) > 0)
952: if (line[0] == 'P')
953: break;
954: (void) fclose(fp);
955: if (line[0] != 'P' || strcmp(job, line+1) != 0)
956: continue;
957: if (touch(*qq) == 0) {
958: printf("\tmoved %s\n", (*qq)->q_name);
959: cnt++;
960: }
961: }
962: return(cnt);
963: }
964:
965: /*
966: * Enable everything and start printer (undo `down').
967: */
968: up(argc, argv)
969: char *argv[];
970: {
971: register int c, status;
972: register char *cp1, *cp2;
973: char prbuf[100];
974:
975: if (argc == 1) {
976: printf("Usage: up {all | printer ...}\n");
977: return;
978: }
979: if (argc == 2 && !strcmp(argv[1], "all")) {
980: printer = prbuf;
981: while (getprent(line) > 0) {
982: cp1 = prbuf;
983: cp2 = line;
984: while ((c = *cp2++) && c != '|' && c != ':')
985: *cp1++ = c;
986: *cp1 = '\0';
987: startpr(2);
988: }
989: return;
990: }
991: while (--argc) {
992: printer = *++argv;
993: if ((status = pgetent(line, printer)) < 0) {
994: printf("cannot open printer description file\n");
995: continue;
996: } else if (status == 0) {
997: printf("unknown printer %s\n", printer);
998: continue;
999: }
1000: startpr(2);
1001: }
1002: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.