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

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