?? pac.c
字號:
#ifndef lintstatic char *sccsid = "@(#)pac.c 4.1 ULTRIX 7/2/90";#endif/************************************************************************ * * * Copyright (c) 1988 by * * Digital Equipment Corporation, Maynard, MA * * All rights reserved. * * * * This software is furnished under a license and may be used and * * copied only in accordance with the terms of such license and * * with the inclusion of the above copyright notice. This * * software or any other copies thereof may not be provided or * * otherwise made available to any other person. No title to and * * ownership of the software is hereby transferred. * * * * This software is derived from software received from the * * University of California, Berkeley, and from Bell * * Laboratories. Use, duplication, or disclosure is subject to * * restrictions under license agreements with University of * * California and with AT&T. * * * * The information in this software is subject to change without * * notice and should not be construed as a commitment by Digital * * Equipment Corporation. * * * * Digital assumes no responsibility for the use or reliability * * of its software on equipment which is not supplied by Digital. * * * ************************************************************************//* * pac.c -- Do Printer accounting summary. * Currently, usage is * pac [-Pprinter] [-pprice] [-s] [-r] [-c] [user ...] * to print the usage information for the named people. *//* SCCS history beginning * *************************************************************** * -- Revision History -- * *************************************************************** * * 1.1 01/11/83 -- sccs * date and time created 83/11/01 20:58:26 by sccs * * *************************************************************** * * 1.2 19/07/88 -- thoms * Added copyright notice and modification history * * SCCS history end */#include <stdio.h>#include "lp.local.h"char *printer; /* printer name */char *acctfile; /* accounting file (input data) */char *sumfile; /* summary file */float price = 0.02; /* cost per page (or what ever) */int allflag = 1; /* Get stats on everybody */int sort; /* Sort by cost */int summarize; /* Compress accounting file */int reverse; /* Reverse sort order */int hcount; /* Count of hash entries */int errs;/* * Grossness follows: * Names to be accumulated are hashed into the following * table. */#define HSHSIZE 97 /* Number of hash buckets */struct hent { struct hent *h_link; /* Forward hash link */ char *h_name; /* Name of this user */ float h_feetpages; /* Feet or pages of paper */ int h_count; /* Number of runs */};struct hent *hashtab[HSHSIZE]; /* Hash table proper */struct hent *enter();struct hent *lookup();#define NIL ((struct hent *) 0) /* The big zero */double atof();char *getenv();char *pgetstr();main(argc, argv) char **argv;{ register FILE *acct; register char *cp; while (--argc) { cp = *++argv; if (*cp++ == '-') { switch(*cp++) { case 'P': /* * Printer name. */ printer = cp; continue; case 'p': /* * get the price. */ price = atof(cp); continue; case 's': /* * Summarize and compress accounting file. */ summarize++; continue; case 'c': /* * Sort by cost. */ sort++; continue; case 'r': /* * Reverse sorting order. */ reverse++; continue; default:fprintf(stderr, "usage: pac [-Pprinter] [-pprice] [-s] [-c] [-r] [user ...]\n"); exit(1); } } (void) enter(--cp); allflag = 0; } if (printer == NULL && (printer = getenv("PRINTER")) == NULL) printer = DEFLP; if (!chkprinter(printer)) { printf("pac: unknown printer %s\n", printer); exit(2); } if ((acct = fopen(acctfile, "r")) == NULL) { perror(acctfile); exit(1); } account(acct); fclose(acct); if ((acct = fopen(sumfile, "r")) != NULL) { account(acct); fclose(acct); } if (summarize) rewrite(); else dumpit(); exit(errs);}/* * Read the entire accounting file, accumulating statistics * for the users that we have in the hash table. If allflag * is set, then just gather the facts on everyone. * Note that we must accomodate both the active and summary file * formats here. */account(acct) register FILE *acct;{ char linebuf[BUFSIZ]; double t; register char *cp, *cp2; register struct hent *hp; register int ic; while (fgets(linebuf, BUFSIZ, acct) != NULL) { cp = linebuf; while (any(*cp, " t\t")) cp++; t = atof(cp); while (any(*cp, ".0123456789")) cp++; while (any(*cp, " \t")) cp++; for (cp2 = cp; !any(*cp2, " \t\n"); cp2++) ; ic = atoi(cp2); *cp2 = '\0'; hp = lookup(cp); if (hp == NIL) { if (!allflag) continue; hp = enter(cp); } hp->h_feetpages += t; if (ic) hp->h_count += ic; else hp->h_count++; }}/* * Sort the hashed entries by name or footage * and print it all out. */dumpit(){ struct hent **base; register struct hent *hp, **ap; register int hno, c, runs; float feet; int qucmp(); hp = hashtab[0]; hno = 1; base = (struct hent **) calloc(sizeof hp, hcount); for (ap = base, c = hcount; c--; ap++) { while (hp == NIL) hp = hashtab[hno++]; *ap = hp; hp = hp->h_link; } qsort(base, hcount, sizeof hp, qucmp); printf(" Login pages/feet runs price\n"); feet = 0.0; runs = 0; for (ap = base, c = hcount; c--; ap++) { hp = *ap; runs += hp->h_count; feet += hp->h_feetpages; printf("%-24s %7.2f %4d $%6.2f\n", hp->h_name, hp->h_feetpages, hp->h_count, hp->h_feetpages * price); } if (allflag) { printf("\n"); printf("%-24s %7.2f %4d $%6.2f\n", "total", feet, runs, feet * price); }}/* * Rewrite the summary file with the summary information we have accumulated. */rewrite(){ register struct hent *hp; register int i; register FILE *acctf; if ((acctf = fopen(sumfile, "w")) == NULL) { perror(sumfile); errs++; return; } for (i = 0; i < HSHSIZE; i++) { hp = hashtab[i]; while (hp != NULL) { fprintf(acctf, "%7.2f\t%s\t%d\n", hp->h_feetpages, hp->h_name, hp->h_count); hp = hp->h_link; } } fflush(acctf); if (ferror(acctf)) { perror(sumfile); errs++; } fclose(acctf); if ((acctf = fopen(acctfile, "w")) == NULL) perror(acctfile); else fclose(acctf);}/* * Hashing routines. *//* * Enter the name into the hash table and return the pointer allocated. */struct hent *enter(name) char name[];{ register struct hent *hp; register int h; if ((hp = lookup(name)) != NIL) return(hp); h = hash(name); hcount++; hp = (struct hent *) calloc(sizeof *hp, 1); hp->h_name = (char *) calloc(sizeof(char), strlen(name)+1); strcpy(hp->h_name, name); hp->h_feetpages = 0.0; hp->h_count = 0; hp->h_link = hashtab[h]; hashtab[h] = hp; return(hp);}/* * Lookup a name in the hash table and return a pointer * to it. */struct hent *lookup(name) char name[];{ register int h; register struct hent *hp; h = hash(name); for (hp = hashtab[h]; hp != NIL; hp = hp->h_link) if (strcmp(hp->h_name, name) == 0) return(hp); return(NIL);}/* * Hash the passed name and return the index in * the hash table to begin the search. */hash(name) char name[];{ register int h; register char *cp; for (cp = name, h = 0; *cp; h = (h << 2) + *cp++) ; return((h & 0x7fffffff) % HSHSIZE);}/* * Other stuff */any(ch, str) char str[];{ register int c = ch; register char *cp = str; while (*cp) if (*cp++ == c) return(1); return(0);}/* * The qsort comparison routine. * The comparison is ascii collating order * or by feet of typesetter film, according to sort. */qucmp(left, right) struct hent **left, **right;{ register struct hent *h1, *h2; register int r; h1 = *left; h2 = *right; if (sort) r = h1->h_feetpages < h2->h_feetpages ? -1 : h1->h_feetpages > h2->h_feetpages; else r = strcmp(h1->h_name, h2->h_name); return(reverse ? -r : r);}/* * Perform lookup for printer name or abbreviation -- */chkprinter(s) register char *s;{ static char buf[BUFSIZ/2]; char b[BUFSIZ]; int stat; char *bp = buf; if ((stat = pgetent(b, s)) < 0) { printf("pac: can't open printer description file\n"); exit(3); } else if (stat == 0) return(0); if ((acctfile = pgetstr("af", &bp)) == NULL) { printf("accounting not enabled for printer %s\n", printer); exit(2); } sumfile = (char *) calloc(sizeof(char), strlen(acctfile)+5); if (sumfile == NULL) { perror("pac"); exit(1); } strcpy(sumfile, acctfile); strcat(sumfile, "_sum"); return(1);}
?? 快捷鍵說明
復制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號
Ctrl + =
減小字號
Ctrl + -