Annotation of 43BSD/old/vpr/vpac.c, revision 1.1.1.1

1.1       root        1: static char sccsid[] = "@(#)vpac.c     1.2     (Berkeley)      8/8/82";
                      2: 
                      3: #include <stdio.h>
                      4: 
                      5: /*
                      6:  * Do Versatec and Varian accounting summary.
                      7:  * Currently, usage is
                      8:  *     vpac [-srW] [user] ...
                      9:  * to print the usage information for the named people.
                     10:  */
                     11: 
                     12: int    errs;
                     13: 
                     14: #define VAACCT         "/usr/adm/vaacct"
                     15: #define VASUM          "/usr/adm/va_sum"
                     16: #define VPACCT         "/usr/adm/vpacct"
                     17: #define VPSUM          "/usr/adm/vp_sum"
                     18: char   *acctfile;
                     19: char   *sumfile;
                     20: 
                     21: #define        VAPRICE 0.02                    /* Dollars per page */
                     22: #define        VPPRICE 0.08                    /* Dollars per foot of paper */
                     23: float price;
                     24: 
                     25: /*
                     26:  * Grossness follows:
                     27:  *  Names to be accumulated are hashed into the following
                     28:  *  table.
                     29:  */
                     30: 
                     31: #define        HSHSIZE 97                      /* Number of hash buckets */
                     32: 
                     33: struct hent {
                     34:        struct  hent *h_link;           /* Forward hash link */
                     35:        char    h_name[9];              /* Name of this user */
                     36:        float   h_feetpages;            /* Feet or pages of paper */
                     37:        int     h_count;                /* Number of runs */
                     38: };
                     39: 
                     40: struct hent    *hashtab[HSHSIZE];      /* Hash table proper */
                     41: struct hent    *enter();
                     42: struct hent    *lookup();
                     43: 
                     44: #define        NIL     ((struct hent *) 0)     /* The big zero */
                     45: 
                     46: int    allflag;                        /* Get stats on everybody */
                     47: int    sort;                           /* Sort by cost */
                     48: int    summarize;                      /* Compress accounting file */
                     49: int    reverse;                        /* Reverse sort order */
                     50: int    wide;                           /* wide paper (Versatec) accounting. */
                     51: 
                     52: int    hcount;                         /* Count of hash entries */
                     53: 
                     54: main(argc, argv)
                     55:        char **argv;
                     56: {
                     57:        register FILE *acct;
                     58:        register char *cp;
                     59:        register int gotcha = 0;
                     60: 
                     61:        acctfile = VAACCT;
                     62:        sumfile = VASUM;
                     63:        price = VAPRICE;
                     64:        if (argc >= 2)
                     65:                while (--argc) {
                     66:                        cp = *++argv;
                     67:                        if (*cp++ == '-') {
                     68:                                while (*cp) switch(*cp++) {
                     69:                                case 's':
                     70:                                        /*
                     71:                                         * Summarize and compress
                     72:                                         * accounting file.
                     73:                                         */
                     74:                                        summarize++;
                     75:                                        break;
                     76: 
                     77:                                case 't':
                     78:                                        /*
                     79:                                         * Sort by feet of typesetter film.
                     80:                                         */
                     81:                                        sort++;
                     82:                                        break;
                     83: 
                     84:                                case 'r':
                     85:                                        /*
                     86:                                         * Reverse sorting order.
                     87:                                         */
                     88:                                        reverse++;
                     89:                                        break;
                     90: 
                     91:                                case 'W':
                     92:                                        /*
                     93:                                         * Versatec, not Varian accounting.
                     94:                                         */
                     95:                                        wide++;
                     96:                                        acctfile = VPACCT;
                     97:                                        sumfile = VPSUM;
                     98:                                        price = VPPRICE;
                     99:                                        break;
                    100:                                default:
                    101:                                        fprintf(stderr, "%s?\n", *argv);
                    102:                                        exit(1);
                    103:                                }
                    104:                                continue;
                    105:                        }
                    106:                        ignore(enter(--cp));
                    107:                        gotcha++;
                    108:                }
                    109:        allflag = gotcha == 0;
                    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:        float t, atof();
                    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 && !allflag)
                    160:                        continue;
                    161:                if (hp == NIL)
                    162:                        hp = enter(cp);
                    163:                hp->h_feetpages += t;
                    164:                if (ic)
                    165:                        hp->h_count += ic;
                    166:                else
                    167:                        hp->h_count++;
                    168:        }
                    169: }
                    170: 
                    171: /*
                    172:  * Sort the hashed entries by name or footage
                    173:  * and print it all out.
                    174:  */
                    175: 
                    176: dumpit()
                    177: {
                    178:        struct hent **base;
                    179:        register struct hent *hp, **ap;
                    180:        register int hno, c, runs;
                    181:        float feet;
                    182:        int qucmp();
                    183: 
                    184:        hp = hashtab[0];
                    185:        hno = 1;
                    186:        base = (struct hent **) calloc(sizeof hp, hcount+4);
                    187:        for (ap = base, c = hcount; c--; ap++) {
                    188:                while (hp == NIL)
                    189:                        hp = hashtab[hno++];
                    190:                *ap = hp;
                    191:                hp = hp->h_link;
                    192:        }
                    193:        qsort(base, hcount, sizeof hp, qucmp);
                    194:        printf(wide ? " Login    feet   runs    price\n"
                    195:                    : " Login   pages   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("%-8s %7.2f %4d   $%6.2f\n", hp->h_name, hp->h_feetpages,
                    203:                    hp->h_count, hp->h_feetpages * price);
                    204:        }
                    205:        if (allflag) {
                    206:                printf("\n");
                    207:                printf("%-8s %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 passed name into the hash table
                    253:  * and returns the pointer allocated.
                    254:  */
                    255: 
                    256: struct hent *
                    257: enter(name)
                    258:        char name[];
                    259: {
                    260:        register struct hent *hp;
                    261:        register int h;
                    262: 
                    263:        if ((hp = lookup(name)) != NIL)
                    264:                return(hp);
                    265:        h = hash(name);
                    266:        hcount++;
                    267:        hp = (struct hent *) calloc(sizeof *hp, 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:        if (h < 0)
                    309:                h = -h;
                    310:        if (h < 0)
                    311:                h = 0;
                    312:        return(h % HSHSIZE);
                    313: }
                    314: 
                    315: /*
                    316:  * Other stuff
                    317:  */
                    318: 
                    319: any(ch, str)
                    320:        char str[];
                    321: {
                    322:        register int c = ch;
                    323:        register char *cp = str;
                    324: 
                    325:        while (*cp)
                    326:                if (*cp++ == c)
                    327:                        return(1);
                    328:        return(0);
                    329: }
                    330: 
                    331: /*
                    332:  * Throw away a hash pointer.
                    333:  */
                    334: 
                    335: ignore(p)
                    336:        struct hent *p;
                    337: {;}
                    338: 
                    339: /*
                    340:  * The qsort comparison routine.
                    341:  * The comparison is ascii collating order
                    342:  * or by feet of typesetter film, according to sort.
                    343:  */
                    344: 
                    345: qucmp(left, right)
                    346:        struct hent **left, **right;
                    347: {
                    348:        register struct hent *h1, *h2;
                    349:        register int r;
                    350: 
                    351:        h1 = *left;
                    352:        h2 = *right;
                    353:        if (sort)
                    354:                r = h1->h_feetpages < h2->h_feetpages ? -1 : h1->h_feetpages > h2->h_feetpages;
                    355:        else
                    356:                r = strcmp(h1->h_name, h2->h_name);
                    357:        return(reverse ? -r : r);
                    358: }

unix.superglobalmegacorp.com

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