source: trunk/athena/bin/lpr/displayq.c @ 7903

Revision 7903, 11.3 KB checked in by miki, 29 years ago (diff)
flock requires read-write on some systems printf should use %ld not %D (AIX)
Line 
1/*
2 * Copyright (c) 1983 Regents of the University of California.
3 * All rights reserved.  The Berkeley software License Agreement
4 * specifies the terms and conditions for redistribution.
5 */
6
7#ifndef lint
8static char sccsid[] = "@(#)displayq.c  5.1 (Berkeley) 6/6/85";
9#endif not lint
10
11/*
12 * Routines to display the state of the queue.
13 */
14
15#include "lp.h"
16#if defined(POSIX) && !defined(ultrix)
17#include "posix.h"   /* for flock() */
18#endif
19#define JOBCOL  40              /* column for job # in -l format */
20#define OWNCOL  7               /* start of Owner column in normal */
21#define SIZCOL  62              /* start of Size column in normal */
22
23/*
24 * Stuff for handling job specifications
25 */
26extern char     *user[];        /* users to process */
27extern int      users;          /* # of users in user array */
28extern int      requ[];         /* job number of spool entries */
29extern int      requests;       /* # of spool requests */
30
31int     lflag;          /* long output option */
32char    current[40];    /* current file being printed */
33int     garbage;        /* # of garbage cf files */
34int     rank;           /* order to be printed (-1=none, 0=active) */
35long    totsize;        /* total print job size in bytes */
36int     first;          /* first file in ``files'' column? */
37int     col;            /* column on screen */
38int     sendtorem;      /* are we sending to a remote? */
39char    file[132];      /* print file name */
40
41char    *head0 = "Rank   Owner      Job  Files";
42char    *head1 = "Total Size\n";
43char    restart_succeed[] =
44        "%s daemon %d does not exist; restarting a new one....";
45char    restart_fail[] =
46        "%s daemon %d does not exist; could not start a new daemon!";
47
48/*
49 * Display the current state of the queue. Format = 1 if long format.
50 */
51displayq(format)
52        int format;
53{
54        register struct queue_ *q;
55        register int i, nitems, fd;
56        struct queue_ **queue;
57        struct stat statb;
58        int rem_fils;
59        char *tmpptr;
60        FILE *fp;
61#ifdef KERBEROS
62        short KA;
63#endif
64#if defined(PQUOTA) && defined(KERBEROS)
65        int pagecost;
66#endif
67        lflag = format;
68        totsize = 0;
69        rank = -1;
70        rem_fils = 0;
71
72#ifdef HESIOD
73        if ((i = pgetent(line, printer)) <= 0) {
74                if (pralias(alibuf, printer))
75                        printer = alibuf;
76                if ((i = hpgetent(line, printer)) < 1)
77                        fatal("unknown printer");
78        }
79#else
80        if ((i = pgetent(line, printer)) < 0) {
81                fatal("cannot open printer description file");
82        } else if (i == 0)
83                fatal("unknown printer");
84#endif HESIOD
85        if ((LP = pgetstr("lp", &bp)) == NULL)
86                LP = DEFDEVLP;
87        if ((RP = pgetstr("rp", &bp)) == NULL)
88                RP = DEFLP;
89        if ((SD = pgetstr("sd", &bp)) == NULL)
90                SD = DEFSPOOL;
91        if ((LO = pgetstr("lo", &bp)) == NULL)
92                LO = DEFLOCK;
93        if ((ST = pgetstr("st", &bp)) == NULL)
94                ST = DEFSTAT;
95        RM = pgetstr("rm", &bp);
96#ifdef KERBEROS
97        KA = pgetnum("ka");
98#endif
99#ifdef PQUOTA
100        RQ = pgetstr("rq", &bp);
101#endif PQUOTA
102#if defined(PQUOTA) && defined(KERBEROS)
103        pagecost = pgetnum("pc");
104#endif
105        /*
106         * Figure out whether the local machine is the same as the remote
107         * machine entry (if it exists).  If not, then ignore the local
108         * queue information.
109         */
110
111         if (RM != (char *) NULL) {
112
113                char name[255];
114                struct hostent *hp;
115
116                        /* get the name of the local host */
117                gethostname (name, sizeof(name) - 1);
118                name[sizeof(name)-1] = '\0';
119                        /* get the network standard name of the local host */
120                hp = gethostbyname (name);
121                if (hp == (struct hostent *) NULL) {
122                    printf ("unable to get hostname for local machine %s\n",
123                                name);
124                }
125                else {
126                  strcpy (name, hp->h_name);
127                  /* get the network standard name of RM */
128                  hp = gethostbyname (RM);
129                  if (hp == (struct hostent *) NULL) {
130                    printf ("unable to get hostname for remote machine %s\n",
131                            RM);
132                  }
133                  /* if printer is not on local machine, ignore LP */
134                  else if (strcasecmp (name, hp->h_name) != 0)
135                      LP = "";
136                }
137        }
138
139        /*
140         * If there is no local printer, then print the queue on
141         * the remote machine and then what's in the queue here.
142         * Note that a file in transit may not show up in either queue.
143         */
144        if (*LP == '\0') {
145                register char *cp;
146
147                sendtorem++;
148                (void) sprintf(line, "%c%s", format + '\3', RP);
149                cp = line;
150                for (i = 0; i < requests; i++) {
151                        cp += strlen(cp);
152                        (void) sprintf(cp, " %d", requ[i]);
153                }
154                for (i = 0; i < users; i++) {
155                        cp += strlen(cp);
156                        *cp++ = ' ';
157                        strcpy(cp, user[i]);
158                }
159                strcat(line, "\n");
160                fd = getport(RM);
161                if (fd < 0) {
162                        if (from != host)
163                                printf("%s: ", host);
164                        printf("unable to connect to %s (for %s)\n", RM, RP);
165                } else {
166                        printf("%s...  ", RM); fflush(stdout);
167                        i = strlen(line);
168                        if (write(fd, line, i) != i)
169                                fatal("Lost connection");
170                        rem_fils = -1;
171                        while ((i = read(fd, line, sizeof(line))) > 0) {
172                                (void) fwrite(line, 1, i, stdout);
173                                for (tmpptr = line;
174                                     tmpptr = strchr(tmpptr,'\n'); ) {
175                                        rem_fils++;
176                                        tmpptr++;
177                                }
178                        }
179                        (void) close(fd);
180                }
181        }
182        /*
183         * Allow lpq -l info about printing
184         */
185        else if (lflag) {
186#ifdef KERBEROS
187            if(KA > 0) {
188                printf("\nKerberos authenticated");
189#ifndef PQUOTA
190                putchar('\n');
191#endif PQUOTA   
192            }   
193#endif KERBEROS
194
195#ifdef PQUOTA
196            if((RQ != (char *) NULL)) {
197                printf("\nQuota server: %s\n", RQ);
198            }
199#ifdef KERBEROS
200            else putchar('\n');
201#endif KERBEROS
202#if defined(PQUOTA) && defined(KERBEROS)
203            if (pagecost > 0) printf("Page cost: %d cents\n", pagecost);
204#endif
205#endif
206        }
207        /*
208         * Find all the control files in the spooling directory
209         */
210        if (chdir(SD) < 0) {
211                char msgbuf[255];
212
213                if (RM) return(rem_fils);
214                sprintf(msgbuf,
215                        "Cannot chdir to spooling directory %s for %s",
216                        SD, printer);
217                fatal(msgbuf);
218                }
219        if ((nitems = getq_(&queue)) < 0) {
220                char msgbuf[255];
221                sprintf(
222                        msgbuf,
223                        "Cannot examine spooling area %s for %s",
224                        SD, printer);
225                fatal (msgbuf);
226                }
227        if (stat(LO, &statb) >= 0) {
228                if ((statb.st_mode & 0110) && sendtorem)
229                        printf("\n");
230                if (statb.st_mode & 0100) {
231                        if (sendtorem)
232                                printf("%s: ", host);
233                        printf("Warning: %s is down: ", printer);
234                        fd = open(ST, O_RDWR);
235                        if (fd >= 0) {
236                                char tmp[1024];
237                                (void) flock(fd, LOCK_SH);
238                                while ((i = read(fd, line, sizeof(line))) > 0){
239                                     strcpy(tmp, printer);
240                                     if (strncmp(line, strcat(tmp," is ready and printing"), 24) != 0)
241                                        (void) fwrite(line, 1, i, stdout);
242                                     else
243                                        putchar('\n');
244                                 }
245                                (void) close(fd);       /* unlocks as well */
246                        } else
247                                putchar('\n');
248                }
249                if (statb.st_mode & 010) {
250                        if (sendtorem)
251                                printf("%s: ", host);
252                        printf("Warning: %s queue is turned off\n", printer);
253                }
254        }
255        if (nitems == 0) {
256                if (!sendtorem)
257                        printf("no entries in %s\n", printer);
258                return(rem_fils);
259        }
260        fp = fopen(LO, "r");
261        if (fp == NULL) {
262                char msgbuf[255];
263                sprintf(msgbuf, "Unable to lock file %s/%s for %s",
264                        SD, LO, printer);
265                warn(msgbuf);
266                }
267        else {
268                register char *cp;
269
270                /* get daemon pid */
271                cp = current;
272                while ((*cp = getc(fp)) != EOF && *cp != '\n')
273                        cp++;
274                *cp = '\0';
275                i = atoi(current);
276                if (i <= 0 || kill(i, 0) < 0) {
277                        char    msg[256];
278
279                        if (startdaemon(printer))
280                                sprintf(msg, restart_succeed, printer, i);
281                        else
282                                sprintf(msg, restart_fail, printer, i);
283                        warn(msg);
284                }
285                else {
286                        /* read current file name */
287                        cp = current;
288                        while ((*cp = getc(fp)) != EOF && *cp != '\n')
289                                cp++;
290                        *cp = '\0';
291                        /*
292                         * Print the status file.
293                         */
294                        if (sendtorem)
295                                printf("\n%s: ", host);
296                        fd = open(ST, O_RDWR);
297                        if (fd >= 0) {
298                                (void) flock(fd, LOCK_SH);
299                                while ((i = read(fd, line, sizeof(line))) > 0)
300                                        (void) fwrite(line, 1, i, stdout);
301                                (void) close(fd);       /* unlocks as well */
302                        } else
303                                putchar('\n');
304                }
305                (void) fclose(fp);
306        }
307        /*
308         * Now, examine the control files and print out the jobs to
309         * be done for each user.
310         */
311        if (!lflag)
312                header();
313
314        for (i = 0; i < nitems; i++) {
315                q = queue[i];
316                inform(q->q_name);
317                free(q);
318        }
319        free(queue);
320        return(nitems-garbage+rem_fils);
321}
322
323/*
324 * Print a warning message if there is no daemon present.
325 */
326warn(msgbuf)
327     char *msgbuf;
328{
329        if (sendtorem)
330                printf("\n%s: ", host);
331        printf("Warning: no daemon present\n[%s]\n", msgbuf);
332        current[0] = '\0';
333}
334
335/*
336 * Print the header for the short listing format
337 */
338header()
339{
340        printf(head0);
341        col = strlen(head0)+1;
342        blankfill(SIZCOL);
343        printf(head1);
344}
345
346inform(cf)
347        char *cf;
348{
349        register int j;
350        FILE *cfp;
351        char jobnum[4];
352
353        /*
354         * There's a chance the control file has gone away
355         * in the meantime; if this is the case just keep going
356         */
357        if ((cfp = fopen(cf, "r")) == NULL)
358                return;
359
360        if (rank < 0)
361                rank = 0;
362        if (sendtorem || garbage || strcmp(cf, current))
363                rank++;
364        j = 0;
365        strncpy(jobnum,cf+3,3);
366        jobnum[3] = '\0';
367        while (getline(cfp)) {
368                switch (line[0]) {
369                case 'P': /* Was this file specified in the user's list? */
370                        if (!inlist(line+1, cf)) {
371                                fclose(cfp);
372                                return;
373                        }
374                        if (lflag) {
375                                printf("\n%s: ", line+1);
376                                col = strlen(line+1) + 2;
377                                prank(rank);
378                                blankfill(JOBCOL);
379                                printf(" [job %s@%s]\n", jobnum, cf+6);
380                        } else {
381                                col = 0;
382                                prank(rank);
383                                blankfill(OWNCOL);
384                                printf("%-10s %-3d  ", line+1, atoi(jobnum));
385                                col += 16;
386                                first = 1;
387                        }
388                        continue;
389                default: /* some format specifer and file name? */
390                        if (line[0] < 'a' || line[0] > 'z')
391                                continue;
392                        if (j == 0 || strcmp(file, line+1) != 0)
393                                strcpy(file, line+1);
394                        j++;
395                        continue;
396                case 'N':
397                        show(line+1, file, j);
398                        file[0] = '\0';
399                        j = 0;
400                }
401        }
402        fclose(cfp);
403        if (!lflag) {
404                blankfill(SIZCOL);
405                printf("%ld bytes\n", totsize);
406                totsize = 0;
407        }
408}
409
410inlist(name, file)
411        char *name, *file;
412{
413        register int *r, n;
414        register char **u, *cp;
415
416        if (users == 0 && requests == 0)
417                return(1);
418        /*
419         * Check to see if it's in the user list
420         */
421        for (u = user; u < &user[users]; u++)
422                if (!strcmp(*u, name))
423                        return(1);
424        /*
425         * Check the request list
426         */
427        for (n = 0, cp = file+3; isdigit(*cp); )
428                n = n * 10 + (*cp++ - '0');
429        for (r = requ; r < &requ[requests]; r++)
430                if (*r == n && !strcmp(cp, from))
431                        return(1);
432        return(0);
433}
434
435show(nfile, file, copies)
436        register char *nfile, *file;
437{
438        if (strcmp(nfile, " ") == 0)
439                nfile = "(standard input)";
440        if (lflag)
441                ldump(nfile, file, copies);
442        else
443                dump(nfile, file, copies);
444}
445
446/*
447 * Fill the line with blanks to the specified column
448 */
449blankfill(n)
450        register int n;
451{
452        while (col++ < n)
453                putchar(' ');
454}
455
456/*
457 * Give the abbreviated dump of the file names
458 */
459dump(nfile, file, copies)
460        char *nfile, *file;
461{
462        register short n, fill;
463        struct stat lbuf;
464
465        /*
466         * Print as many files as will fit
467         *  (leaving room for the total size)
468         */
469         fill = first ? 0 : 2;  /* fill space for ``, '' */
470         if (((n = strlen(nfile)) + col + fill) >= SIZCOL-4) {
471                if (col < SIZCOL) {
472                        printf(" ..."), col += 4;
473                        blankfill(SIZCOL);
474                }
475        } else {
476                if (first)
477                        first = 0;
478                else
479                        printf(", ");
480                printf("%s", nfile);
481                col += n+fill;
482        }
483        if (*file && !stat(file, &lbuf))
484                totsize += copies * lbuf.st_size;
485}
486
487/*
488 * Print the long info about the file
489 */
490ldump(nfile, file, copies)
491        char *nfile, *file;
492{
493        struct stat lbuf;
494
495        putchar('\t');
496        if (copies > 1)
497                printf("%d copies of %-19s%s", copies, nfile,
498                       copies<10?" ":"");
499        else
500                printf("%-32s", nfile);
501        if (*file && !stat(file, &lbuf))
502                printf(" %ld bytes", lbuf.st_size);
503        else
504                printf(" ??? bytes");
505        putchar('\n');
506}
507
508/*
509 * Print the job's rank in the queue,
510 *   update col for screen management
511 */
512prank(n)
513{
514        char line[100];
515        static char *r[] = {
516                "th", "st", "nd", "rd", "th", "th", "th", "th", "th", "th"
517        };
518
519        if (n == 0) {
520                printf("active");
521                col += 6;
522                return;
523        }
524        if ((n/10) == 1)
525                (void) sprintf(line, "%dth", n);
526        else
527                (void) sprintf(line, "%d%s", n, r[n%10]);
528        col += strlen(line);
529        printf("%s", line);
530}
Note: See TracBrowser for help on using the repository browser.