# 2.11BSD#431 - /usr/src/usr.sbin/lpr/pac.c

##### Functions

    account           X
    any               X
    chkprinter        X
    dumpit            X
    enter             X
    hash              X
    lookup            X
    main              X
    qucmp             X
    rewrite           X

##### Variables

    acctfile          X
    allflag           X
    copyright         X
    errs              X
    hashtab           X
    hcount            X
    mflag             X
    pflag             X
    price             X
    price100          X
    printer           X
    reverse           X
    sort              X
    sumfile           X
    summarize         X

##### Macros

    HSHSIZE           X
    NIL               X

##### struct's

    hent              X

       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
       8: char copyright[] =
       9: "@(#) Copyright (c) 1983 Regents of the University of California.\n\
      10:  All rights reserved.\n";
      11: #endif not lint
      12:
      13: #ifndef lint
      14: static char sccsid[] = "@(#)pac.c	5.2 (Berkeley) 10/30/85";
      15: #endif not lint
      16:
      17: /*
      18:  * Do Printer accounting summary.
      19:  * Currently, usage is
      20:  *	pac [-Pprinter] [-pprice] [-s] [-r] [-c] [-m] [user ...]
      21:  * to print the usage information for the named people.
      22:  */
      23:
      24: #include <stdio.h>
      25: #include "lp.local.h"
      26:
      27: char    *printer;           /* printer name */
      28: char    *acctfile;          /* accounting file (input data) */
      29: char    *sumfile;           /* summary file */
      30: float   price = 0.02;           /* cost per page (or what ever) */
      31: int allflag = 1;            /* Get stats on everybody */
      32: int sort;               /* Sort by cost */
      33: int summarize;          /* Compress accounting file */
      34: int reverse;            /* Reverse sort order */
      35: int hcount;             /* Count of hash entries */
      36: int errs;
      37: int mflag = 0;          /* disregard machine names */
      38: int pflag = 0;          /* 1 if -p on cmd line */
      39: int price100;           /* per-page cost in 100th of a cent */
      40: char    *index();
      41: int pgetnum();
      42:
      43: /*
      44:  * Grossness follows:
      45:  *  Names to be accumulated are hashed into the following
      46:  *  table.
      47:  */
      48:
      49: #define HSHSIZE 97          /* Number of hash buckets */
      50:
      51: struct hent {
      52:     struct  hent *h_link;       /* Forward hash link */
      53:     char    *h_name;        /* Name of this user */
      54:     float   h_feetpages;        /* Feet or pages of paper */
      55:     int h_count;        /* Number of runs */
      56: };
      57:
      58: struct  hent    *hashtab[HSHSIZE];  /* Hash table proper */
      59: struct  hent    *enter();
      60: struct  hent    *lookup();
      61:
      62: #define NIL ((struct hent *) 0) /* The big zero */
      63:
      64: double  atof();
      65: char    *getenv();
      66: char    *pgetstr();
      67:
      68: main(argc, argv)
      69:     char **argv;
      70: {
      71:     register FILE *acct;
      72:     register char *cp;
      73:
      74:     while (--argc) {
      75:         cp = *++argv;
      76:         if (*cp++ == '-') {
      77:             switch(*cp++) {
      78:             case 'P':
      79:                 /*
      80: 				 * Printer name.
      81: 				 */
      82:                 printer = cp;
      83:                 continue;
      84:
      85:             case 'p':
      86:                 /*
      87: 				 * get the price.
      88: 				 */
      89:                 price = atof(cp);
      90:                 pflag = 1;
      91:                 continue;
      92:
      93:             case 's':
      94:                 /*
      95: 				 * Summarize and compress accounting file.
      96: 				 */
      97:                 summarize++;
      98:                 continue;
      99:
     100:             case 'c':
     101:                 /*
     102: 				 * Sort by cost.
     103: 				 */
     104:                 sort++;
     105:                 continue;
     106:
     107:             case 'm':
     108:                 /*
     109: 				 * disregard machine names for each user
     110: 				 */
     111:                 mflag = 1;
     112:                 continue;
     113:
     114:             case 'r':
     115:                 /*
     116: 				 * Reverse sorting order.
     117: 				 */
     118:                 reverse++;
     119:                 continue;
     120:
     121:             default:
     122: fprintf(stderr,
     123:     "usage: pac [-Pprinter] [-pprice] [-s] [-c] [-r] [-m] [user ...]\n");
     124:                 exit(1);
     125:             }
     126:         }
     127:         (void) enter(--cp);
     128:         allflag = 0;
     129:     }
     130:     if (printer == NULL && (printer = getenv("PRINTER")) == NULL)
     131:         printer = DEFLP;
     132:     if (!chkprinter(printer)) {
     133:         printf("pac: unknown printer %s\n", printer);
     134:         exit(2);
     135:     }
     136:
     137:     if ((acct = fopen(acctfile, "r")) == NULL) {
     138:         perror(acctfile);
     139:         exit(1);
     140:     }
     141:     account(acct);
     142:     fclose(acct);
     143:     if ((acct = fopen(sumfile, "r")) != NULL) {
     144:         account(acct);
     145:         fclose(acct);
     146:     }
     147:     if (summarize)
     148:         rewrite();
     149:     else
     150:         dumpit();
     151:     exit(errs);
     152: }
     153:
     154: /*
     155:  * Read the entire accounting file, accumulating statistics
     156:  * for the users that we have in the hash table.  If allflag
     157:  * is set, then just gather the facts on everyone.
     158:  * Note that we must accomodate both the active and summary file
     159:  * formats here.
     160:  * Host names are ignored if the -m flag is present.
     161:  */
     162:
     163: account(acct)
     164:     register FILE *acct;
     165: {
     166:     char linebuf[BUFSIZ];
     167:     double t;
     168:     register char *cp, *cp2;
     169:     register struct hent *hp;
     170:     register int ic;
     171:
     172:     while (fgets(linebuf, BUFSIZ, acct) != NULL) {
     173:         cp = linebuf;
     174:         while (any(*cp, " t\t"))
     175:             cp++;
     176:         t = atof(cp);
     177:         while (any(*cp, ".0123456789"))
     178:             cp++;
     179:         while (any(*cp, " \t"))
     180:             cp++;
     181:         for (cp2 = cp; !any(*cp2, " \t\n"); cp2++)
     182:             ;
     183:         ic = atoi(cp2);
     184:         *cp2 = '\0';
     185:         if (mflag && index(cp, ':'))
     186:             cp = index(cp, ':') + 1;
     187:         hp = lookup(cp);
     188:         if (hp == NIL) {
     189:             if (!allflag)
     190:                 continue;
     191:             hp = enter(cp);
     192:         }
     193:         hp->h_feetpages += t;
     194:         if (ic)
     195:             hp->h_count += ic;
     196:         else
     197:             hp->h_count++;
     198:     }
     199: }
     200:
     201: /*
     202:  * Sort the hashed entries by name or footage
     203:  * and print it all out.
     204:  */
     205:
     206: dumpit()
     207: {
     208:     struct hent **base;
     209:     register struct hent *hp, **ap;
     210:     register int hno, c, runs;
     211:     float feet;
     212:     int qucmp();
     213:
     214:     hp = hashtab[0];
     215:     hno = 1;
     216:     base = (struct hent **) calloc(sizeof hp, hcount);
     217:     for (ap = base, c = hcount; c--; ap++) {
     218:         while (hp == NIL)
     219:             hp = hashtab[hno++];
     220:         *ap = hp;
     221:         hp = hp->h_link;
     222:     }
     223:     qsort(base, hcount, sizeof hp, qucmp);
     224:     printf("  Login               pages/feet   runs    price\n");
     225:     feet = 0.0;
     226:     runs = 0;
     227:     for (ap = base, c = hcount; c--; ap++) {
     228:         hp = *ap;
     229:         runs += hp->h_count;
     230:         feet += hp->h_feetpages;
     231:         printf("%-24s %7.2f %4d   $%6.2f\n", hp->h_name,
     232:             hp->h_feetpages, hp->h_count, hp->h_feetpages * price);
     233:     }
     234:     if (allflag) {
     235:         printf("\n");
     236:         printf("%-24s %7.2f %4d   $%6.2f\n", "total", feet,
     237:             runs, feet * price);
     238:     }
     239: }
     240:
     241: /*
     242:  * Rewrite the summary file with the summary information we have accumulated.
     243:  */
     244:
     245: rewrite()
     246: {
     247:     register struct hent *hp;
     248:     register int i;
     249:     register FILE *acctf;
     250:
     251:     if ((acctf = fopen(sumfile, "w")) == NULL) {
     252:         perror(sumfile);
     253:         errs++;
     254:         return;
     255:     }
     256:     for (i = 0; i < HSHSIZE; i++) {
     257:         hp = hashtab[i];
     258:         while (hp != NULL) {
     259:             fprintf(acctf, "%7.2f\t%s\t%d\n", hp->h_feetpages,
     260:                 hp->h_name, hp->h_count);
     261:             hp = hp->h_link;
     262:         }
     263:     }
     264:     fflush(acctf);
     265:     if (ferror(acctf)) {
     266:         perror(sumfile);
     267:         errs++;
     268:     }
     269:     fclose(acctf);
     270:     if ((acctf = fopen(acctfile, "w")) == NULL)
     271:         perror(acctfile);
     272:     else
     273:         fclose(acctf);
     274: }
     275:
     276: /*
     277:  * Hashing routines.
     278:  */
     279:
     280: /*
     281:  * Enter the name into the hash table and return the pointer allocated.
     282:  */
     283:
     284: struct hent *
     285: enter(name)
     286:     char name[];
     287: {
     288:     register struct hent *hp;
     289:     register int h;
     290:
     291:     if ((hp = lookup(name)) != NIL)
     292:         return(hp);
     293:     h = hash(name);
     294:     hcount++;
     295:     hp = (struct hent *) calloc(sizeof *hp, 1);
     296:     hp->h_name = (char *) calloc(sizeof(char), strlen(name)+1);
     297:     strcpy(hp->h_name, name);
     298:     hp->h_feetpages = 0.0;
     299:     hp->h_count = 0;
     300:     hp->h_link = hashtab[h];
     301:     hashtab[h] = hp;
     302:     return(hp);
     303: }
     304:
     305: /*
     306:  * Lookup a name in the hash table and return a pointer
     307:  * to it.
     308:  */
     309:
     310: struct hent *
     311: lookup(name)
     312:     char name[];
     313: {
     314:     register int h;
     315:     register struct hent *hp;
     316:
     317:     h = hash(name);
     318:     for (hp = hashtab[h]; hp != NIL; hp = hp->h_link)
     319:         if (strcmp(hp->h_name, name) == 0)
     320:             return(hp);
     321:     return(NIL);
     322: }
     323:
     324: /*
     325:  * Hash the passed name and return the index in
     326:  * the hash table to begin the search.
     327:  */
     328:
     329: hash(name)
     330:     char name[];
     331: {
     332:     register int h;
     333:     register char *cp;
     334:
     335:     for (cp = name, h = 0; *cp; h = (h << 2) + *cp++)
     336:         ;
     337:     return((h & 0x7fffffff) % HSHSIZE);
     338: }
     339:
     340: /*
     341:  * Other stuff
     342:  */
     343:
     344: any(ch, str)
     345:     char str[];
     346: {
     347:     register int c = ch;
     348:     register char *cp = str;
     349:
     350:     while (*cp)
     351:         if (*cp++ == c)
     352:             return(1);
     353:     return(0);
     354: }
     355:
     356: /*
     357:  * The qsort comparison routine.
     358:  * The comparison is ascii collating order
     359:  * or by feet of typesetter film, according to sort.
     360:  */
     361:
     362: qucmp(left, right)
     363:     struct hent **left, **right;
     364: {
     365:     register struct hent *h1, *h2;
     366:     register int r;
     367:
     368:     h1 = *left;
     369:     h2 = *right;
     370:     if (sort)
     371:         r = h1->h_feetpages < h2->h_feetpages ? -1 : h1->h_feetpages >
     372: h2->h_feetpages;
     373:     else
     374:         r = strcmp(h1->h_name, h2->h_name);
     375:     return(reverse ? -r : r);
     376: }
     377:
     378: /*
     379:  * Perform lookup for printer name or abbreviation --
     380:  */
     381: chkprinter(s)
     382:     register char *s;
     383: {
     384:     static char buf[BUFSIZ/2];
     385:     char b[BUFSIZ];
     386:     int stat;
     387:     char *bp = buf;
     388:
     389:     if ((stat = pgetent(b, s)) < 0) {
     390:         printf("pac: can't open printer description file\n");
     391:         exit(3);
     392:     } else if (stat == 0)
     393:         return(0);
     394:     if ((acctfile = pgetstr("af", &bp)) == NULL) {
     395:         printf("accounting not enabled for printer %s\n", printer);
     396:         exit(2);
     397:     }
     398:     if (!pflag && (price100 = pgetnum("pc")) > 0)
     399:         price = price100/10000.0;
     400:     sumfile = (char *) calloc(sizeof(char), strlen(acctfile)+5);
     401:     if (sumfile == NULL) {
     402:         perror("pac");
     403:         exit(1);
     404:     }
     405:     strcpy(sumfile, acctfile);
     406:     strcat(sumfile, "_sum");
     407:     return(1);
     408: }

#### Defined functions

account defined in line 163; used 2 times

- in line 141-144(2)

any defined in line 344; used 4 times

- in line 174-181(4)

chkprinter defined in line 381; used 1 times

- in line 132

dumpit defined in line 206; used 1 times

- in line 150

enter defined in line 284; used 3 times

- in line 59, 127, 191

hash defined in line 329; used 2 times

- in line 293, 317

lookup defined in line 310; used 3 times

- in line 60, 187, 291

main defined in line 68; never used
qucmp defined in line 362; used 2 times

- in line 212, 223

rewrite defined in line 245; used 1 times

- in line 148

#### Defined variables

acctfile defined in line 28; used 7 times

- in line 137-138(2), 270-271(2), 394, 400-405(2)

allflag defined in line 31; used 3 times

- in line 128, 189, 234

copyright defined in line 8; never used
errs defined in line 36; used 3 times

- in line 151, 253, 267

hashtab defined in line 58; used 6 times

- in line 214-219(2), 257, 300-301(2), 318

hcount defined in line 35; used 5 times

- in line 216-217(2), 223-227(2), 294

mflag defined in line 37; used 2 times

- in line 111, 185

pflag defined in line 38; used 2 times

- in line 90, 398

price defined in line 30; used 4 times

- in line 89, 232-237(2), 399

price100 defined in line 39; used 2 times

- in line 398-399(2)

printer defined in line 27; used 7 times

- in line 82, 130-133(5), 395

reverse defined in line 34; used 2 times

- in line 118, 375

sccsid defined in line 14; never used
sort defined in line 32; used 2 times

- in line 104, 370

sumfile defined in line 29; used 8 times

- in line 143, 251-252(2), 266, 400-406(4)

summarize defined in line 33; used 2 times

- in line 97, 147

#### Defined struct's

hent defined in line 51; used 32 times

- in line 52(2), 58-60(6), 169(2), 208-209(4), 216(2), 247(2), 284-288(4), 295(2), 310-315(4), 363-365(4)

#### Defined macros

HSHSIZE defined in line 49; used 3 times

- in line 58, 256, 337

NIL defined in line 62; used 5 times

- in line 188, 218, 291, 318-321(2)

Last modified: 1987-02-18 Generated: 2016-12-26 | Generated by src2html V0.67 page hit count: 1474 |