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

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