Annotation of 42BSD/usr.lib/lpr/pac.c, revision 1.1.1.1

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

unix.superglobalmegacorp.com

This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.