* Copyright (c) 1983 Regents of the University of California.
* Redistribution and use in source and binary forms are permitted
* provided that this notice is preserved and that due credit is given
* to the University of California at Berkeley. The name of the University
* may not be used to endorse or promote products derived from this
* software without specific prior written permission. This software
* is provided ``as is'' without express or implied warranty.
"@(#) Copyright (c) 1983 Regents of the University of California.\n\
static char sccsid
[] = "@(#)pac.c 5.3 (Berkeley) %G%";
* Do Printer accounting summary.
* pac [-Pprinter] [-pprice] [-s] [-r] [-c] [-m] [user ...]
* to print the usage information for the named people.
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 mflag
= 0; /* disregard machine names */
int pflag
= 0; /* 1 if -p on cmd line */
int price100
; /* per-page cost in 100th of a cent */
* Names to be accumulated are hashed into the following
#define HSHSIZE 97 /* Number of hash buckets */
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 */
#define NIL ((struct hent *) 0) /* The big zero */
* Summarize and compress accounting file.
* disregard machine names for each user
"usage: pac [-Pprinter] [-pprice] [-s] [-c] [-r] [-m] [user ...]\n");
if (printer
== NULL
&& (printer
= getenv("PRINTER")) == NULL
)
if (!chkprinter(printer
)) {
printf("pac: unknown printer %s\n", printer
);
if ((acct
= fopen(acctfile
, "r")) == NULL
) {
if ((acct
= fopen(sumfile
, "r")) != NULL
) {
* 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
* Host names are ignored if the -m flag is present.
register struct hent
*hp
;
while (fgets(linebuf
, BUFSIZ
, acct
) != NULL
) {
while (any(*cp
, ".0123456789"))
for (cp2
= cp
; !any(*cp2
, " \t\n"); cp2
++)
if (mflag
&& index(cp
, ':'))
* Sort the hashed entries by name or footage
register struct hent
*hp
, **ap
;
register int hno
, c
, runs
;
base
= (struct hent
**) calloc(sizeof hp
, hcount
);
for (ap
= base
, c
= hcount
; c
--; ap
++) {
qsort(base
, hcount
, sizeof hp
, qucmp
);
printf(" Login pages/feet runs price\n");
for (ap
= base
, c
= hcount
; c
--; ap
++) {
printf("%-24s %7.2f %4d $%6.2f\n", hp
->h_name
,
hp
->h_feetpages
, hp
->h_count
, hp
->h_feetpages
* price
);
printf("%-24s %7.2f %4d $%6.2f\n", "total", feet
,
* Rewrite the summary file with the summary information we have accumulated.
register struct hent
*hp
;
if ((acctf
= fopen(sumfile
, "w")) == NULL
) {
for (i
= 0; i
< HSHSIZE
; i
++) {
fprintf(acctf
, "%7.2f\t%s\t%d\n", hp
->h_feetpages
,
hp
->h_name
, hp
->h_count
);
if ((acctf
= fopen(acctfile
, "w")) == NULL
)
* Enter the name into the hash table and return the pointer allocated.
register struct hent
*hp
;
if ((hp
= lookup(name
)) != NIL
)
hp
= (struct hent
*) calloc(sizeof *hp
, 1);
hp
->h_name
= (char *) calloc(sizeof(char), strlen(name
)+1);
strcpy(hp
->h_name
, name
);
* Lookup a name in the hash table and return a pointer
register struct hent
*hp
;
for (hp
= hashtab
[h
]; hp
!= NIL
; hp
= hp
->h_link
)
if (strcmp(hp
->h_name
, name
) == 0)
* Hash the passed name and return the index in
* the hash table to begin the search.
for (cp
= name
, h
= 0; *cp
; h
= (h
<< 2) + *cp
++)
return((h
& 0x7fffffff) % HSHSIZE
);
* The qsort comparison routine.
* The comparison is ascii collating order
* or by feet of typesetter film, according to sort.
struct hent
**left
, **right
;
register struct hent
*h1
, *h2
;
r
= h1
->h_feetpages
< h2
->h_feetpages
? -1 : h1
->h_feetpages
>
r
= strcmp(h1
->h_name
, h2
->h_name
);
return(reverse
? -r
: r
);
* Perform lookup for printer name or abbreviation --
static char buf
[BUFSIZ
/2];
if ((stat
= pgetent(b
, s
)) < 0) {
printf("pac: can't open printer description file\n");
if ((acctfile
= pgetstr("af", &bp
)) == NULL
) {
printf("accounting not enabled for printer %s\n", printer
);
if (!pflag
&& (price100
= pgetnum("pc")) > 0)
price
= price100
/10000.0;
sumfile
= (char *) calloc(sizeof(char), strlen(acctfile
)+5);
strcpy(sumfile
, acctfile
);