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