source: trunk/athena/bin/lpr/cmds.c @ 6932

Revision 6932, 26.2 KB checked in by probe, 31 years ago (diff)
Reduced the #ifdef's by globally changing names (req'd by Solaris port)
Line 
1/*
2 *      $Source: /afs/dev.mit.edu/source/repository/athena/bin/lpr/cmds.c,v $
3 *      $Author: probe $
4 *      $Locker:  $
5 *      $Header: /afs/dev.mit.edu/source/repository/athena/bin/lpr/cmds.c,v 1.8 1993-10-09 18:13:48 probe Exp $
6 */
7
8#ifndef lint
9static char *rcsid_cmds_c = "$Header: /afs/dev.mit.edu/source/repository/athena/bin/lpr/cmds.c,v 1.8 1993-10-09 18:13:48 probe Exp $";
10#endif lint
11
12/*
13 * Copyright (c) 1983 Regents of the University of California.
14 * All rights reserved.  The Berkeley software License Agreement
15 * specifies the terms and conditions for redistribution.
16 */
17
18#ifndef lint
19static char sccsid[] = "@(#)cmds.c      5.2 (Berkeley) 3/30/86";
20#endif not lint
21
22/*
23 * lpc -- line printer control program -- commands:
24 */
25
26#include "lp.h"
27#include <sys/time.h>
28
29/* Currently "lpc" runs only off information in /etc/printcap.
30 * If you want it to query Hesiod, #define HESIOD_LPC here.
31 */
32
33/*
34 * kill an existing daemon and disable printing.
35 */
36abort(argc, argv)
37        char *argv[];
38{
39        register int c, status;
40        register char *cp1, *cp2;
41        char prbuf[100];
42
43        if (argc == 1) {
44                printf("Usage: abort {all | printer ...}\n");
45                return;
46        }
47        if (argc == 2 && !strcmp(argv[1], "all")) {
48                printer = prbuf;
49                while (getprent(line) > 0) {
50                        cp1 = prbuf;
51                        cp2 = line;
52                        while ((c = *cp2++) && c != '|' && c != ':')
53                                *cp1++ = c;
54                        *cp1 = '\0';
55                        abortpr(1);
56                }
57                return;
58        }
59        while (--argc) {
60                printer = *++argv;
61#ifdef HESIOD_LPC
62                if ((status = pgetent(line, printer)) <= 0) {
63                        if(pralias(alibuf, printer))
64                                printer = alibuf;
65                        if ((status = hpgetent(line, printer)) < 1) {
66                                printf("unknown printer %s\n", printer);
67                                continue;
68                        }
69                }
70#else
71                if ((status = pgetent(line, printer)) < 0) {
72                        printf("cannot open printer description file\n");
73                        continue;
74                } else if (status == 0) {
75                        printf("unknown printer %s\n", printer);
76                        continue;
77                }
78#endif HESIOD_LPC
79                abortpr(1);
80        }
81}
82
83abortpr(dis)
84{
85        register FILE *fp;
86        struct stat stbuf;
87        int pid, fd;
88
89        bp = pbuf;
90        if ((SD = pgetstr("sd", &bp)) == NULL)
91                SD = DEFSPOOL;
92        if ((LO = pgetstr("lo", &bp)) == NULL)
93                LO = DEFLOCK;
94        (void) sprintf(line, "%s/%s", SD, LO);
95        printf("%s:\n", printer);
96
97        /*
98         * Turn on the owner execute bit of the lock file to disable printing.
99         */
100        if (dis) {
101                if (stat(line, &stbuf) >= 0) {
102                        if (chmod(line, (stbuf.st_mode & 0777) | 0100) < 0)
103                                printf("\tcannot disable printing\n");
104                        else
105                                printf("\tprinting disabled\n");
106                } else if (errno == ENOENT) {
107                        if ((fd = open(line, O_WRONLY|O_CREAT, 0760)) < 0)
108                                printf("\tcannot create lock file\n");
109                        else {
110                                (void) close(fd);
111                                printf("\tprinting disabled\n");
112                                printf("\tno daemon to abort\n");
113                        }
114                        return;
115                } else {
116                        printf("\tcannot stat lock file\n");
117                        return;
118                }
119        }
120        /*
121         * Kill the current daemon to stop printing now.
122         */
123        if ((fp = fopen(line, "r")) == NULL) {
124                printf("\tcannot open lock file\n");
125                return;
126        }
127        if (!getline(fp) || flock(fileno(fp), LOCK_SH|LOCK_NB) == 0) {
128                (void) fclose(fp);      /* unlocks as well */
129                printf("\tno daemon to abort\n");
130                return;
131        }
132        (void) fclose(fp);
133        if (kill(pid = atoi(line), SIGTERM) < 0)
134                printf("\tWarning: daemon (pid %d) not killed\n", pid);
135        else
136                printf("\tdaemon (pid %d) killed\n", pid);
137}
138
139/*
140 * Remove all spool files and temporaries from the spooling area.
141 */
142clean(argc, argv)
143        char *argv[];
144{
145        register int c, status;
146        register char *cp1, *cp2;
147        char prbuf[100];
148
149        if (argc == 1) {
150                printf("Usage: clean {all | printer ...}\n");
151                return;
152        }
153        if (argc == 2 && !strcmp(argv[1], "all")) {
154                printer = prbuf;
155                while (getprent(line) > 0) {
156                        cp1 = prbuf;
157                        cp2 = line;
158                        while ((c = *cp2++) && c != '|' && c != ':')
159                                *cp1++ = c;
160                        *cp1 = '\0';
161                        cleanpr();
162                }
163                return;
164        }
165        while (--argc) {
166                printer = *++argv;
167#ifdef HESIOD_LPC
168                if ((status = pgetent(line, printer)) <= 0) {
169                        if(pralias(alibuf, printer))
170                                printer = alibuf;
171                        if ((status = hpgetent(line, printer)) < 1) {
172                                printf("unknown printer %s\n", printer);
173                                continue;
174                        }
175                }
176#else
177                if ((status = pgetent(line, printer)) < 0) {
178                        printf("cannot open printer description file\n");
179                        continue;
180                } else if (status == 0) {
181                        printf("unknown printer %s\n", printer);
182                        continue;
183                }
184#endif HESIOD_LPC
185                cleanpr();
186        }
187}
188
189
190
191static
192cselect(d)
193#ifdef POSIX
194struct dirent *d;
195#else
196struct direct *d;
197#endif
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 */
210sortq(d1, d2)
211#ifdef POSIX
212struct dirent **d1, **d2;
213#else
214struct direct **d1, **d2;
215#endif
216{
217        int c1, c2;
218
219        if (c1 = strcmp((*d1)->d_name + 3, (*d2)->d_name + 3))
220                return(c1);
221        c1 = (*d1)->d_name[0];
222        c2 = (*d2)->d_name[0];
223        if (c1 == c2)
224                return((*d1)->d_name[2] - (*d2)->d_name[2]);
225        if (c1 == 'c')
226                return(-1);
227        if (c1 == 'd' || c2 == 'c')
228                return(1);
229        return(-1);
230}
231
232/*
233 * Remove incomplete jobs from spooling area.
234 */
235cleanpr()
236{
237        register int i, n;
238        register char *cp, *cp1, *lp;
239#ifdef POSIX
240        struct dirent **queue;
241#else
242        struct direct **queue;
243#endif
244        int nitems;
245
246        bp = pbuf;
247        if ((SD = pgetstr("sd", &bp)) == NULL)
248                SD = DEFSPOOL;
249        printf("%s:\n", printer);
250
251        for (lp = line, cp = SD; *lp++ = *cp++; )
252                ;
253        lp[-1] = '/';
254
255        nitems = scandir(SD, &queue, cselect, sortq);
256        if (nitems < 0) {
257                printf("\tcannot examine spool directory\n");
258                return;
259        }
260        if (nitems == 0)
261                return;
262        i = 0;
263        do {
264                cp = queue[i]->d_name;
265                if (*cp == 'c') {
266                        n = 0;
267                        while (i + 1 < nitems) {
268                                cp1 = queue[i + 1]->d_name;
269                                if (*cp1 != 'd' || strcmp(cp + 3, cp1 + 3))
270                                        break;
271                                i++;
272                                n++;
273                        }
274                        if (n == 0) {
275                                strcpy(lp, cp);
276                                unlinkf(line);
277                        }
278                } else {
279                        /*
280                         * Must be a df with no cf (otherwise, it would have
281                         * been skipped above) or a tf file (which can always
282                         * be removed).
283                         */
284                        strcpy(lp, cp);
285                        unlinkf(line);
286                }
287        } while (++i < nitems);
288}
289 
290unlinkf(name)
291        char    *name;
292{
293        if (UNLINK(name) < 0)
294                printf("\tcannot remove %s\n", name);
295        else
296                printf("\tremoved %s\n", name);
297}
298
299/*
300 * Enable queuing to the printer (allow lpr's).
301 */
302enable(argc, argv)
303        char *argv[];
304{
305        register int c, status;
306        register char *cp1, *cp2;
307        char prbuf[100];
308
309        if (argc == 1) {
310                printf("Usage: enable {all | printer ...}\n");
311                return;
312        }
313        if (argc == 2 && !strcmp(argv[1], "all")) {
314                printer = prbuf;
315                while (getprent(line) > 0) {
316                        cp1 = prbuf;
317                        cp2 = line;
318                        while ((c = *cp2++) && c != '|' && c != ':')
319                                *cp1++ = c;
320                        *cp1 = '\0';
321                        enablepr();
322                }
323                return;
324        }
325        while (--argc) {
326                printer = *++argv;
327#ifdef HESIOD_LPC
328                if ((status = pgetent(line, printer)) <= 0) {
329                        if(pralias(alibuf, printer))
330                                printer = alibuf;
331                        if ((status = hpgetent(line, printer)) < 1) {
332                                printf("unknown printer %s\n", printer);
333                                continue;
334                        }
335                }
336#else
337                if ((status = pgetent(line, printer)) < 0) {
338                        printf("cannot open printer description file\n");
339                        continue;
340                } else if (status == 0) {
341                        printf("unknown printer %s\n", printer);
342                        continue;
343                }
344#endif HESIOD_LPC
345                enablepr();
346        }
347}
348
349enablepr()
350{
351        struct stat stbuf;
352
353        bp = pbuf;
354        if ((SD = pgetstr("sd", &bp)) == NULL)
355                SD = DEFSPOOL;
356        if ((LO = pgetstr("lo", &bp)) == NULL)
357                LO = DEFLOCK;
358        (void) sprintf(line, "%s/%s", SD, LO);
359        printf("%s:\n", printer);
360
361        /*
362         * Turn off the group execute bit of the lock file to enable queuing.
363         */
364        if (stat(line, &stbuf) >= 0) {
365                if (chmod(line, stbuf.st_mode & 0767) < 0)
366                        printf("\tcannot enable queuing\n");
367                else
368                        printf("\tqueuing enabled\n");
369        }
370}
371
372/*
373 * Disable queuing.
374 */
375disable(argc, argv)
376        char *argv[];
377{
378        register int c, status;
379        register char *cp1, *cp2;
380        char prbuf[100];
381
382        if (argc == 1) {
383                printf("Usage: disable {all | printer ...}\n");
384                return;
385        }
386        if (argc == 2 && !strcmp(argv[1], "all")) {
387                printer = prbuf;
388                while (getprent(line) > 0) {
389                        cp1 = prbuf;
390                        cp2 = line;
391                        while ((c = *cp2++) && c != '|' && c != ':')
392                                *cp1++ = c;
393                        *cp1 = '\0';
394                        disablepr();
395                }
396                return;
397        }
398        while (--argc) {
399                printer = *++argv;
400#ifdef HESIOD_LPC
401                if ((status = pgetent(line, printer)) <= 0) {
402                        if(pralias(alibuf, printer))
403                                printer = alibuf;
404                        if ((status = hpgetent(line, printer)) < 1) {
405                                printf("unknown printer %s\n", printer);
406                                continue;
407                        }
408                }
409#else
410                if ((status = pgetent(line, printer)) < 0) {
411                        printf("cannot open printer description file\n");
412                        continue;
413                } else if (status == 0) {
414                        printf("unknown printer %s\n", printer);
415                        continue;
416                }
417#endif HESIOD_LPC
418                disablepr();
419        }
420}
421
422disablepr()
423{
424        register int fd;
425        struct stat stbuf;
426
427        bp = pbuf;
428        if ((SD = pgetstr("sd", &bp)) == NULL)
429                SD = DEFSPOOL;
430        if ((LO = pgetstr("lo", &bp)) == NULL)
431                LO = DEFLOCK;
432        (void) sprintf(line, "%s/%s", SD, LO);
433        printf("%s:\n", printer);
434        /*
435         * Turn on the group execute bit of the lock file to disable queuing.
436         */
437        if (stat(line, &stbuf) >= 0) {
438                if (chmod(line, (stbuf.st_mode & 0777) | 010) < 0)
439                        printf("\tcannot disable queuing\n");
440                else
441                        printf("\tqueuing disabled\n");
442        } else if (errno == ENOENT) {
443                if ((fd = open(line, O_WRONLY|O_CREAT, 0670)) < 0)
444                        printf("\tcannot create lock file\n");
445                else {
446                        (void) close(fd);
447                        printf("\tqueuing disabled\n");
448                }
449                return;
450        } else
451                printf("\tcannot stat lock file\n");
452}
453
454/*
455 * Disable queuing and printing and put a message into the status file
456 * (reason for being down).
457 */
458down(argc, argv)
459        char *argv[];
460{
461        register int c, status;
462        register char *cp1, *cp2;
463        char prbuf[100];
464
465        if (argc == 1) {
466                printf("Usage: down {all | printer} [message ...]\n");
467                return;
468        }
469        if (!strcmp(argv[1], "all")) {
470                printer = prbuf;
471                while (getprent(line) > 0) {
472                        cp1 = prbuf;
473                        cp2 = line;
474                        while ((c = *cp2++) && c != '|' && c != ':')
475                                *cp1++ = c;
476                        *cp1 = '\0';
477                        putmsg(argc - 2, argv + 2);
478                }
479                return;
480        }
481        printer = argv[1];
482#ifdef HESIOD_LPC
483        if ((status = pgetent(line, printer)) <= 0) {
484                if(pralias(alibuf, printer))
485                                printer = alibuf;
486                if ((status = hpgetent(line, printer)) < 1) {
487                        printf("unknown printer %s\n", printer);
488                        return;
489                }
490        }
491#else
492        if ((status = pgetent(line, printer)) < 0) {
493                printf("cannot open printer description file\n");
494                return;
495        } else if (status == 0) {
496                printf("unknown printer %s\n", printer);
497                return;
498        }
499#endif HESIOD_LPC
500        putmsg(argc - 2, argv + 2);
501}
502
503putmsg(argc, argv)
504        char **argv;
505{
506        register int fd;
507        register char *cp1, *cp2;
508        char buf[1024];
509        struct stat stbuf;
510
511        bp = pbuf;
512        if ((SD = pgetstr("sd", &bp)) == NULL)
513                SD = DEFSPOOL;
514        if ((LO = pgetstr("lo", &bp)) == NULL)
515                LO = DEFLOCK;
516        if ((ST = pgetstr("st", &bp)) == NULL)
517                ST = DEFSTAT;
518        printf("%s:\n", printer);
519        /*
520         * Turn on the group execute bit of the lock file to disable queuing and
521         * turn on the owner execute bit of the lock file to disable printing.
522         */
523        (void) sprintf(line, "%s/%s", SD, LO);
524        if (stat(line, &stbuf) >= 0) {
525                if (chmod(line, (stbuf.st_mode & 0777) | 0110) < 0)
526                        printf("\tcannot disable queuing\n");
527                else
528                        printf("\tprinter and queuing disabled\n");
529        } else if (errno == ENOENT) {
530                if ((fd = open(line, O_WRONLY|O_CREAT, 0770)) < 0)
531                        printf("\tcannot create lock file\n");
532                else {
533                        (void) close(fd);
534                        printf("\tprinter and queuing disabled\n");
535                }
536                return;
537        } else
538                printf("\tcannot stat lock file\n");
539        /*
540         * Write the message into the status file.
541         */
542        (void) sprintf(line, "%s/%s", SD, ST);
543        fd = open(line, O_WRONLY|O_CREAT, 0664);
544        if (fd < 0 || flock(fd, LOCK_EX) < 0) {
545                printf("\tcannot create status file\n");
546                return;
547        }
548        (void) ftruncate(fd, 0);
549        if (argc <= 0) {
550                (void) write(fd, "\n", 1);
551                (void) close(fd);
552                return;
553        }
554        cp1 = buf;
555        while (--argc >= 0) {
556                cp2 = *argv++;
557                while (*cp1++ = *cp2++)
558                        ;
559                cp1[-1] = ' ';
560        }
561        cp1[-1] = '\n';
562        *cp1 = '\0';
563        (void) write(fd, buf, strlen(buf));
564        (void) close(fd);
565}
566
567/*
568 * Exit lpc
569 */
570quit(argc, argv)
571        char *argv[];
572{
573        exit(0);
574}
575
576/*
577 * Kill and restart the daemon.
578 */
579restart(argc, argv)
580        char *argv[];
581{
582        register int c, status;
583        register char *cp1, *cp2;
584        struct hostent *hp;
585        char prbuf[100];
586
587        if (argc == 1) {
588                printf("Usage: restart {all | printer ...}\n");
589                return;
590        }
591        gethostname(host, sizeof(host));
592        if (hp = gethostbyname(host)) strcpy(host, hp->h_name);
593
594        if (argc == 2 && !strcmp(argv[1], "all")) {
595                printer = prbuf;
596                while (getprent(line) > 0) {
597                        cp1 = prbuf;
598                        cp2 = line;
599                        while ((c = *cp2++) && c != '|' && c != ':')
600                                *cp1++ = c;
601                        *cp1 = '\0';
602                        abortpr(0);
603                        startpr(0);
604                }
605                return;
606        }
607        while (--argc) {
608                printer = *++argv;
609#ifdef HESIOD_LPC
610                if ((status = pgetent(line, printer)) <= 0) {
611                        if(pralias(alibuf, printer))
612                                printer = alibuf;
613                        if ((status = hpgetent(line, printer)) < 1) {
614                                printf("unknown printer %s\n", printer);
615                                continue;
616                        }
617                }
618#else
619                if ((status = pgetent(line, printer)) < 0) {
620                        printf("cannot open printer description file\n");
621                        continue;
622                } else if (status == 0) {
623                        printf("unknown printer %s\n", printer);
624                        continue;
625                }
626#endif HESIOD_LPC
627                abortpr(0);
628                startpr(0);
629        }
630}
631
632/*
633 * Enable printing on the specified printer and startup the daemon.
634 */
635start(argc, argv)
636        char *argv[];
637{
638        register int c, status;
639        register char *cp1, *cp2;
640        char prbuf[100];
641        struct hostent *hp;
642
643        if (argc == 1) {
644                printf("Usage: start {all | printer ...}\n");
645                return;
646        }
647        gethostname(host, sizeof(host));
648        if (hp = gethostbyname(host)) strcpy (host, hp -> h_name);
649
650        if (argc == 2 && !strcmp(argv[1], "all")) {
651                printer = prbuf;
652                while (getprent(line) > 0) {
653                        cp1 = prbuf;
654                        cp2 = line;
655                        while ((c = *cp2++) && c != '|' && c != ':')
656                                *cp1++ = c;
657                        *cp1 = '\0';
658                        startpr(1);
659                }
660                return;
661        }
662        while (--argc) {
663                printer = *++argv;
664#ifdef HESIOD_LPC
665                if ((status = pgetent(line, printer)) <= 0) {
666                        if(pralias(alibuf, printer))
667                                printer = alibuf;
668                        if ((status = hpgetent(line, printer)) < 1) {
669                                printf("unknown printer %s\n", printer);
670                                continue;
671                        }
672                }
673#else
674                if ((status = pgetent(line, printer)) < 0) {
675                        printf("cannot open printer description file\n");
676                        continue;
677                } else if (status == 0) {
678                        printf("unknown printer %s\n", printer);
679                        continue;
680                }
681#endif HESIOD_LPC
682                startpr(1);
683        }
684}
685
686startpr(enable)
687{
688        struct stat stbuf;
689
690        bp = pbuf;
691        if ((SD = pgetstr("sd", &bp)) == NULL)
692                SD = DEFSPOOL;
693        if ((LO = pgetstr("lo", &bp)) == NULL)
694                LO = DEFLOCK;
695        (void) sprintf(line, "%s/%s", SD, LO);
696        printf("%s:\n", printer);
697
698        /*
699         * Turn off the owner execute bit of the lock file to enable printing.
700         */
701        if (enable && stat(line, &stbuf) >= 0) {
702                if (chmod(line, stbuf.st_mode & (enable==2 ? 0666 : 0677)) < 0)
703                        printf("\tcannot enable printing\n");
704                else
705                        printf("\tprinting enabled\n");
706        }
707        if (!startdaemon(printer))
708                printf("\tcouldn't start daemon\n");
709        else
710                printf("\tdaemon started\n");
711}
712
713/*
714 * Print the status of each queue listed or all the queues.
715 */
716status(argc, argv)
717        char *argv[];
718{
719        register int c, status;
720        register char *cp1, *cp2;
721        char prbuf[100];
722
723        if (argc == 1) {
724                printer = prbuf;
725                while (getprent(line) > 0) {
726                        cp1 = prbuf;
727                        cp2 = line;
728                        while ((c = *cp2++) && c != '|' && c != ':')
729                                *cp1++ = c;
730                        *cp1 = '\0';
731                        prstat();
732                }
733                return;
734        }
735        while (--argc) {
736                printer = *++argv;
737#ifdef HESIOD_LPC
738                if ((status = pgetent(line, printer)) <= 0) {
739                        if(pralias(alibuf, printer))
740                                printer = alibuf;
741                        if ((status = hpgetent(line, printer)) < 1) {
742                                printf("unknown printer %s\n", printer);
743                                continue;
744                        }
745                }
746#else
747                if ((status = pgetent(line, printer)) < 0) {
748                        printf("cannot open printer description file\n");
749                        continue;
750                } else if (status == 0) {
751                        printf("unknown printer %s\n", printer);
752                        continue;
753                }
754#endif HESIOD_LPC
755                prstat();
756        }
757}
758
759/*
760 * Print the status of the printer queue.
761 */
762prstat()
763{
764        struct stat stbuf;
765        register int fd, i;
766#ifdef POSIX
767        register struct dirent *dp;
768#else
769        register struct direct *dp;
770#endif
771        DIR *dirp;
772
773        bp = pbuf;
774        if ((SD = pgetstr("sd", &bp)) == NULL)
775                SD = DEFSPOOL;
776        if ((LO = pgetstr("lo", &bp)) == NULL)
777                LO = DEFLOCK;
778        if ((ST = pgetstr("st", &bp)) == NULL)
779                ST = DEFSTAT;
780        printf("%s:\n", printer);
781        (void) sprintf(line, "%s/%s", SD, LO);
782        if (stat(line, &stbuf) >= 0) {
783                printf("\tqueuing is %s\n",
784                        (stbuf.st_mode & 010) ? "disabled" : "enabled");
785                printf("\tprinting is %s\n",
786                        (stbuf.st_mode & 0100) ? "disabled" : "enabled");
787        } else {
788                printf("\tqueuing is enabled\n");
789                printf("\tprinting is enabled\n");
790        }
791        if ((dirp = opendir(SD)) == NULL) {
792                printf("\tcannot examine spool directory\n");
793                return;
794        }
795        i = 0;
796        while ((dp = readdir(dirp)) != NULL) {
797                if (*dp->d_name == 'c' && dp->d_name[1] == 'f')
798                        i++;
799        }
800        closedir(dirp);
801        if (i == 0)
802                printf("\tno entries\n");
803        else if (i == 1)
804                printf("\t1 entry in spool area\n");
805        else
806                printf("\t%d entries in spool area\n", i);
807        fd = open(line, O_RDONLY);
808        if (fd < 0 || flock(fd, LOCK_SH|LOCK_NB) == 0) {
809                (void) close(fd);       /* unlocks as well */
810                printf("\tno daemon present\n");
811                return;
812        }
813        (void) close(fd);
814        putchar('\t');
815        (void) sprintf(line, "%s/%s", SD, ST);
816        fd = open(line, O_RDONLY);
817        if (fd >= 0) {
818                (void) flock(fd, LOCK_SH);
819                while ((i = read(fd, line, sizeof(line))) > 0)
820                        (void) fwrite(line, 1, i, stdout);
821                (void) close(fd);       /* unlocks as well */
822        }
823        putchar('\n');
824}
825
826/*
827 * Stop the specified daemon after completing the current job and disable
828 * printing.
829 */
830stop(argc, argv)
831        char *argv[];
832{
833        register int c, status;
834        register char *cp1, *cp2;
835        char prbuf[100];
836
837        if (argc == 1) {
838                printf("Usage: stop {all | printer ...}\n");
839                return;
840        }
841        if (argc == 2 && !strcmp(argv[1], "all")) {
842                printer = prbuf;
843                while (getprent(line) > 0) {
844                        cp1 = prbuf;
845                        cp2 = line;
846                        while ((c = *cp2++) && c != '|' && c != ':')
847                                *cp1++ = c;
848                        *cp1 = '\0';
849                        stoppr();
850                }
851                return;
852        }
853        while (--argc) {
854                printer = *++argv;
855#ifdef HESIOD_LPC
856                if ((status = pgetent(line, printer)) <= 0) {
857                        if(pralias(alibuf, printer))
858                                printer = alibuf;
859                        if ((status = hpgetent(line, printer)) < 1) {
860                                printf("unknown printer %s\n", printer);
861                                continue;
862                        }
863                }
864#else
865                if ((status = pgetent(line, printer)) < 0) {
866                        printf("cannot open printer description file\n");
867                        continue;
868                } else if (status == 0) {
869                        printf("unknown printer %s\n", printer);
870                        continue;
871                }
872#endif HESIOD_LPC
873                stoppr();
874        }
875}
876
877stoppr()
878{
879        register int fd;
880        struct stat stbuf;
881
882        bp = pbuf;
883        if ((SD = pgetstr("sd", &bp)) == NULL)
884                SD = DEFSPOOL;
885        if ((LO = pgetstr("lo", &bp)) == NULL)
886                LO = DEFLOCK;
887        (void) sprintf(line, "%s/%s", SD, LO);
888        printf("%s:\n", printer);
889
890        /*
891         * Turn on the owner execute bit of the lock file to disable printing.
892         */
893        if (stat(line, &stbuf) >= 0) {
894                if (chmod(line, (stbuf.st_mode & 0777) | 0100) < 0)
895                        printf("\tcannot disable printing\n");
896                else
897                        printf("\tprinting disabled\n");
898        } else if (errno == ENOENT) {
899                if ((fd = open(line, O_WRONLY|O_CREAT, 0760)) < 0)
900                        printf("\tcannot create lock file\n");
901                else {
902                        (void) close(fd);
903                        printf("\tprinting disabled\n");
904                }
905        } else
906                printf("\tcannot stat lock file\n");
907}
908
909struct  queue_ **queue;
910int     nitems;
911time_t  mtime;
912
913/*
914 * Put the specified jobs at the top of printer queue.
915 */
916topq(argc, argv)
917        char *argv[];
918{
919        register int i;
920        struct stat stbuf;
921        int status, changed;
922
923        if (argc < 3) {
924                printf("Usage: topq printer [jobnum ...] [user ...]\n");
925                return;
926        }
927
928        --argc;
929        printer = *++argv;
930#ifdef HESIOD_LPC
931        if ((status = pgetent(line, printer)) <= 0) {
932                if(pralias(alibuf, printer))
933                        printer = alibuf;
934                if ((status = hpgetent(line, printer)) < 1) {
935                        printf("unknown printer %s\n", printer);
936                        return;
937                }
938        }
939#else
940        if ((status = pgetent(line, printer)) < 0) {
941                printf("cannot open printer description file\n");
942                return;
943        } else if (status == 0) {
944                printf("unknown printer %s\n", printer);
945                return;
946        }
947#endif HESIOD_LPC
948        bp = pbuf;
949        if ((SD = pgetstr("sd", &bp)) == NULL)
950                SD = DEFSPOOL;
951        if ((LO = pgetstr("lo", &bp)) == NULL)
952                LO = DEFLOCK;
953        printf("%s:\n", printer);
954
955        if (chdir(SD) < 0) {
956                printf("\tcannot chdir to %s\n", SD);
957                return;
958        }
959        nitems = getq_(&queue);
960        if (nitems == 0)
961                return;
962        changed = 0;
963        mtime = queue[0]->q_time;
964        for (i = argc; --i; ) {
965                if (doarg(argv[i]) == 0) {
966                        printf("\tjob %s is not in the queue\n", argv[i]);
967                        continue;
968                } else
969                        changed++;
970        }
971        for (i = 0; i < nitems; i++)
972                free(queue[i]);
973        free(queue);
974        if (!changed) {
975                printf("\tqueue order unchanged\n");
976                return;
977        }
978        /*
979         * Turn on the public execute bit of the lock file to
980         * get lpd to rebuild the queue after the current job.
981         */
982        if (changed && stat(LO, &stbuf) >= 0)
983                (void) chmod(LO, (stbuf.st_mode & 0777) | 01);
984}
985
986/*
987 * Reposition the job by changing the modification time of
988 * the control file.
989 */
990touch(q)
991        struct queue_ *q;
992{
993        struct timeval tvp[2];
994
995        tvp[0].tv_sec = tvp[1].tv_sec = --mtime;
996        tvp[0].tv_usec = tvp[1].tv_usec = 0;
997        return(utimes(q->q_name, tvp));
998}
999
1000/*
1001 * Checks if specified job name is in the printer's queue.
1002 * Returns:  negative (-1) if argument name is not in the queue.
1003 */
1004doarg(job)
1005        char *job;
1006{
1007        register struct queue_ **qq;
1008        register int jobnum, n;
1009        register char *cp, *machine;
1010        char *jobtmp;
1011        int cnt = 0;
1012        FILE *fp;
1013
1014        /*
1015         * Look for a job item consisting of system name, colon, number
1016         * (example: ucbarpa:114) 
1017         */
1018        if ((cp = index(job, ':')) != NULL) {
1019                machine = job;
1020                *cp++ = '\0';
1021                job = cp;
1022        } else
1023                machine = NULL;
1024
1025        /*
1026         * Check for job specified by number (example: 112 or 235ucbarpa).
1027         */
1028        jobtmp = job;
1029        if (isdigit(*job)) {
1030                jobnum = 0;
1031                do
1032                        jobnum = jobnum * 10 + (*job++ - '0');
1033                while (isdigit(*job) && job != jobtmp+3);
1034                if (*job == '@')
1035                        job++;
1036                for (qq = queue + nitems; --qq >= queue; ) {
1037                        n = 0;
1038                        for (cp = (*qq)->q_name+3; isdigit(*cp) &&
1039                             cp != (*qq)->q_name+6; )
1040                                n = n * 10 + (*cp++ - '0');
1041                        if (jobnum != n)
1042                                continue;
1043                        if (*job && strcmp(job, cp) != 0)
1044                                continue;
1045                        if (machine != NULL && strcmp(machine, cp) != 0)
1046                                continue;
1047                        if (touch(*qq) == 0) {
1048                                printf("\tmoved %s\n", (*qq)->q_name);
1049                                cnt++;
1050                        }
1051                }
1052                return(cnt);
1053        }
1054        /*
1055         * Process item consisting of owner's name (example: henry).
1056         */
1057        for (qq = queue + nitems; --qq >= queue; ) {
1058                if ((fp = fopen((*qq)->q_name, "r")) == NULL)
1059                        continue;
1060                while (getline(fp) > 0)
1061                        if (line[0] == 'P')
1062                                break;
1063                (void) fclose(fp);
1064                if (line[0] != 'P' || strcmp(job, line+1) != 0)
1065                        continue;
1066                if (touch(*qq) == 0) {
1067                        printf("\tmoved %s\n", (*qq)->q_name);
1068                        cnt++;
1069                }
1070        }
1071        return(cnt);
1072}
1073
1074/*
1075 * Enable everything and start printer (undo `down').
1076 */
1077up(argc, argv)
1078        char *argv[];
1079{
1080        register int c, status;
1081        register char *cp1, *cp2;
1082        char prbuf[100];
1083
1084        if (argc == 1) {
1085                printf("Usage: up {all | printer ...}\n");
1086                return;
1087        }
1088        if (argc == 2 && !strcmp(argv[1], "all")) {
1089                printer = prbuf;
1090                while (getprent(line) > 0) {
1091                        cp1 = prbuf;
1092                        cp2 = line;
1093                        while ((c = *cp2++) && c != '|' && c != ':')
1094                                *cp1++ = c;
1095                        *cp1 = '\0';
1096                        startpr(2);
1097                }
1098                return;
1099        }
1100        while (--argc) {
1101                printer = *++argv;
1102#ifdef HESIOD_LPC
1103                if ((status = pgetent(line, printer)) <= 0) {
1104                        if(pralias(alibuf, printer))
1105                                printer = alibuf;
1106                        if ((status = hpgetent(line, printer)) < 1) {
1107                                printf("unknown printer %s\n", printer);
1108                                continue;
1109                        }
1110                }
1111#else
1112                if ((status = pgetent(line, printer)) < 0) {
1113                        printf("cannot open printer description file\n");
1114                        continue;
1115                } else if (status == 0) {
1116                        printf("unknown printer %s\n", printer);
1117                        continue;
1118                }
1119#endif HESIOD_LPC
1120                startpr(2);
1121        }
1122}
1123
1124
1125/*
1126 * examine queue using /usr/ucb/lpq
1127 */
1128lookat(argc, argv)
1129        char *argv[];
1130{
1131        register int c, status;
1132        register char *cp1, *cp2;
1133        char prbuf[100];
1134
1135        if (argc == 1) {
1136                printf("Usage: lookat {all | printer ...}\n");
1137                return;
1138        }
1139        if (argc == 2 && !strcmp(argv[1], "all")) {
1140                printer = prbuf;
1141                while (getprent(line) > 0) {
1142                        cp1 = prbuf;    /* hack, get printer name */
1143                        cp2 = line;
1144                        while ((c = *cp2++) && c != '|' && c != ':')
1145                                *cp1++ = c;
1146                        *cp1 = '\0';
1147                        lookatpr();
1148                }
1149                return;
1150        }
1151        while (--argc) {
1152                printer = *++argv;
1153#ifdef HESIOD_LPC
1154                if ((status = pgetent(line, printer)) <= 0) {
1155                        if(pralias(alibuf, printer))
1156                                printer = alibuf;
1157                        if ((status = hpgetent(line, printer)) < 1) {
1158                                printf("unknown printer %s\n", printer);
1159                                continue;
1160                        }
1161                }
1162#else
1163                if ((status = pgetent(line, printer)) < 0) {
1164                        printf("cannot open printer description file\n");
1165                        continue;
1166                } else if (status == 0) {
1167                        printf("unknown printer %s\n", printer);
1168                        continue;
1169                }
1170#endif HESIOD_LPC
1171                lookatpr();
1172        }
1173}
1174
1175lookatpr ()
1176{
1177        char cmdbuf[255];
1178        char *command = "/usr/ucb/lpq";
1179
1180#ifdef DEBUG
1181        command = "./lpq";
1182#endif
1183
1184        (void) sprintf (cmdbuf, "-P%s", printer);
1185
1186#ifdef DEBUG
1187        printf ("WARNING:  Using program %s to examine print queue %s\n",
1188                command, printer);
1189#endif
1190
1191        printf ("%s:\n", printer);
1192        switch(fork())
1193          {
1194          case 0: /* Child */
1195            execl(command, "lpq", cmdbuf, 0);
1196            perror("Can't exec /usr/ucb/lpq");
1197            exit(1);
1198            /*NOTREACHED*/
1199          case -1:
1200            perror("fork");
1201          default:
1202            wait(0);
1203          }
1204        printf ("\n");
1205        return;
1206}
1207
1208/*
1209 * Remove all spool files and temporaries from the spooling area.  What
1210 * clean used to do.
1211 */
1212flushq_(argc, argv)
1213        char *argv[];
1214{
1215        register int c, status;
1216        register char *cp1, *cp2;
1217        char prbuf[100];
1218
1219        if (argc == 1) {
1220                printf("Usage: flush {all | printer ...}\n");
1221                return;
1222        }
1223        if (argc == 2 && !strcmp(argv[1], "all")) {
1224                printer = prbuf;
1225                while (getprent(line) > 0) {
1226                        cp1 = prbuf;
1227                        cp2 = line;
1228                        while ((c = *cp2++) && c != '|' && c != ':')
1229                                *cp1++ = c;
1230                        *cp1 = '\0';
1231                        flushpr();
1232                }
1233                return;
1234        }
1235        while (--argc) {
1236                printer = *++argv;
1237#ifdef HESIOD_LPC
1238                if ((status = pgetent(line, printer)) <= 0) {
1239                        if(pralias(alibuf, printer))
1240                                printer = alibuf;
1241                        if ((status = hpgetent(line, printer)) < 1) {
1242                                printf("unknown printer %s\n", printer);
1243                                continue;
1244                        }
1245                }
1246#else
1247                if ((status = pgetent(line, printer)) < 0) {
1248                        printf("cannot open printer description file\n");
1249                        continue;
1250                } else if (status == 0) {
1251                        printf("unknown printer %s\n", printer);
1252                        continue;
1253                }
1254#endif HESIOD_LPC
1255                flushpr();
1256        }
1257}
1258
1259/*
1260 * flush the queue (cleanpr from old version of lpc)
1261 */
1262
1263flushpr()
1264{
1265        register int c;
1266        register DIR *dirp;
1267#ifdef POSIX
1268        register struct dirent *dp;
1269#else
1270        register struct direct *dp;
1271#endif
1272        char *cp, *cp1;
1273
1274        bp = pbuf;
1275        if ((SD = pgetstr("sd", &bp)) == NULL)
1276                SD = DEFSPOOL;
1277        for (cp = line, cp1 = SD; *cp++ = *cp1++; );
1278        cp[-1] = '/';
1279        printf("%s:\n", printer);
1280
1281        if ((dirp = opendir(SD)) == NULL) {
1282                printf("\tcannot examine spool directory\n");
1283                return;
1284        }
1285        while ((dp = readdir(dirp)) != NULL) {
1286                c = dp->d_name[0];
1287                if ((c == 'c' || c == 't' || c == 'd') && dp->d_name[1]=='f') {
1288                        strcpy(cp, dp->d_name);
1289                        if (UNLINK(line) < 0)
1290                                printf("\tcannot remove %s\n", line);
1291                        else
1292                                printf("\tremoved %s\n", line);
1293                }
1294        }
1295        closedir(dirp);
1296  }
Note: See TracBrowser for help on using the repository browser.