1*8a16b7a1SPedro F. Giffuni /*- 2*8a16b7a1SPedro F. Giffuni * SPDX-License-Identifier: BSD-3-Clause 3*8a16b7a1SPedro F. Giffuni * 4dea673e9SRodney W. Grimes * Copyright (c) 1983, 1993 5dea673e9SRodney W. Grimes * The Regents of the University of California. All rights reserved. 6dea673e9SRodney W. Grimes * 7dea673e9SRodney W. Grimes * 8dea673e9SRodney W. Grimes * Redistribution and use in source and binary forms, with or without 9dea673e9SRodney W. Grimes * modification, are permitted provided that the following conditions 10dea673e9SRodney W. Grimes * are met: 11dea673e9SRodney W. Grimes * 1. Redistributions of source code must retain the above copyright 12dea673e9SRodney W. Grimes * notice, this list of conditions and the following disclaimer. 13dea673e9SRodney W. Grimes * 2. Redistributions in binary form must reproduce the above copyright 14dea673e9SRodney W. Grimes * notice, this list of conditions and the following disclaimer in the 15dea673e9SRodney W. Grimes * documentation and/or other materials provided with the distribution. 16fbbd9655SWarner Losh * 3. Neither the name of the University nor the names of its contributors 17dea673e9SRodney W. Grimes * may be used to endorse or promote products derived from this software 18dea673e9SRodney W. Grimes * without specific prior written permission. 19dea673e9SRodney W. Grimes * 20dea673e9SRodney W. Grimes * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND 21dea673e9SRodney W. Grimes * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 22dea673e9SRodney W. Grimes * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 23dea673e9SRodney W. Grimes * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE 24dea673e9SRodney W. Grimes * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 25dea673e9SRodney W. Grimes * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 26dea673e9SRodney W. Grimes * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 27dea673e9SRodney W. Grimes * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 28dea673e9SRodney W. Grimes * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 29dea673e9SRodney W. Grimes * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 30dea673e9SRodney W. Grimes * SUCH DAMAGE. 31dea673e9SRodney W. Grimes */ 32dea673e9SRodney W. Grimes 33dea673e9SRodney W. Grimes #ifndef lint 349b3fe531SPhilippe Charnier static const char copyright[] = 35dea673e9SRodney W. Grimes "@(#) Copyright (c) 1983, 1993\n\ 36dea673e9SRodney W. Grimes The Regents of the University of California. All rights reserved.\n"; 37dea673e9SRodney W. Grimes #endif /* not lint */ 38dea673e9SRodney W. Grimes 399b3fe531SPhilippe Charnier #if 0 408e36ed92SGarance A Drosehn #ifndef lint 41dea673e9SRodney W. Grimes static char sccsid[] = "@(#)pac.c 8.1 (Berkeley) 6/6/93"; 42dea673e9SRodney W. Grimes #endif /* not lint */ 438e36ed92SGarance A Drosehn #endif 448e36ed92SGarance A Drosehn 458e36ed92SGarance A Drosehn #include "lp.cdefs.h" /* A cross-platform version of <sys/cdefs.h> */ 468e36ed92SGarance A Drosehn __FBSDID("$FreeBSD$"); 47dea673e9SRodney W. Grimes 48dea673e9SRodney W. Grimes /* 49dea673e9SRodney W. Grimes * Do Printer accounting summary. 50dea673e9SRodney W. Grimes * Currently, usage is 51dea673e9SRodney W. Grimes * pac [-Pprinter] [-pprice] [-s] [-r] [-c] [-m] [user ...] 52dea673e9SRodney W. Grimes * to print the usage information for the named people. 53dea673e9SRodney W. Grimes */ 54dea673e9SRodney W. Grimes 55dea673e9SRodney W. Grimes #include <sys/param.h> 56dea673e9SRodney W. Grimes 57dea673e9SRodney W. Grimes #include <dirent.h> 5890cf373dSGarrett Wollman #include <err.h> 59dea673e9SRodney W. Grimes #include <stdlib.h> 60dea673e9SRodney W. Grimes #include <stdio.h> 61dea673e9SRodney W. Grimes #include <string.h> 6290cf373dSGarrett Wollman #include <unistd.h> 63dea673e9SRodney W. Grimes #include "lp.h" 64dea673e9SRodney W. Grimes #include "lp.local.h" 65dea673e9SRodney W. Grimes 66dea673e9SRodney W. Grimes static char *acctfile; /* accounting file (input data) */ 67dea673e9SRodney W. Grimes static int allflag = 1; /* Get stats on everybody */ 68dea673e9SRodney W. Grimes static int errs; 69961d3645SGarance A Drosehn static size_t hcount; /* Count of hash entries */ 70dea673e9SRodney W. Grimes static int mflag = 0; /* disregard machine names */ 71dea673e9SRodney W. Grimes static int pflag = 0; /* 1 if -p on cmd line */ 72dea673e9SRodney W. Grimes static float price = 0.02; /* cost per page (or what ever) */ 73dea673e9SRodney W. Grimes static int reverse; /* Reverse sort order */ 74dea673e9SRodney W. Grimes static int sort; /* Sort by cost */ 75dea673e9SRodney W. Grimes static char *sumfile; /* summary file */ 76dea673e9SRodney W. Grimes static int summarize; /* Compress accounting file */ 77dea673e9SRodney W. Grimes 78360d4ad5SWarner Losh uid_t uid, euid; 79360d4ad5SWarner Losh 80dea673e9SRodney W. Grimes /* 81dea673e9SRodney W. Grimes * Grossness follows: 82dea673e9SRodney W. Grimes * Names to be accumulated are hashed into the following 83dea673e9SRodney W. Grimes * table. 84dea673e9SRodney W. Grimes */ 85dea673e9SRodney W. Grimes 86dea673e9SRodney W. Grimes #define HSHSIZE 97 /* Number of hash buckets */ 87dea673e9SRodney W. Grimes 88dea673e9SRodney W. Grimes struct hent { 89dea673e9SRodney W. Grimes struct hent *h_link; /* Forward hash link */ 90dea673e9SRodney W. Grimes char *h_name; /* Name of this user */ 91dea673e9SRodney W. Grimes float h_feetpages; /* Feet or pages of paper */ 92dea673e9SRodney W. Grimes int h_count; /* Number of runs */ 93dea673e9SRodney W. Grimes }; 94dea673e9SRodney W. Grimes 95dea673e9SRodney W. Grimes static struct hent *hashtab[HSHSIZE]; /* Hash table proper */ 96dea673e9SRodney W. Grimes 97ba7a1ad7SGarance A Drosehn int main(int argc, char **_argv); 98961d3645SGarance A Drosehn static void account(FILE *_acctf); 99ba7a1ad7SGarance A Drosehn static int any(int _ch, const char _str[]); 100ba7a1ad7SGarance A Drosehn static int chkprinter(const char *_ptrname); 101ba7a1ad7SGarance A Drosehn static void dumpit(void); 102ba7a1ad7SGarance A Drosehn static int hash(const char _name[]); 103ba7a1ad7SGarance A Drosehn static struct hent *enter(const char _name[]); 104ba7a1ad7SGarance A Drosehn static struct hent *lookup(const char _name[]); 105ba7a1ad7SGarance A Drosehn static int qucmp(const void *_a, const void *_b); 106ba7a1ad7SGarance A Drosehn static void rewrite(void); 107ba7a1ad7SGarance A Drosehn static void usage(void); 108dea673e9SRodney W. Grimes 109bc407914SWarner Losh int 110ba7a1ad7SGarance A Drosehn main(int argc, char **argv) 111dea673e9SRodney W. Grimes { 112961d3645SGarance A Drosehn FILE *acctf; 113ba7a1ad7SGarance A Drosehn const char *cp, *printer; 114dea673e9SRodney W. Grimes 1154a1a0dbeSGarrett Wollman printer = NULL; 116360d4ad5SWarner Losh euid = geteuid(); /* these aren't used in pac(1) */ 117360d4ad5SWarner Losh uid = getuid(); 118dea673e9SRodney W. Grimes while (--argc) { 119dea673e9SRodney W. Grimes cp = *++argv; 120dea673e9SRodney W. Grimes if (*cp++ == '-') { 121dea673e9SRodney W. Grimes switch(*cp++) { 122dea673e9SRodney W. Grimes case 'P': 123dea673e9SRodney W. Grimes /* 124dea673e9SRodney W. Grimes * Printer name. 125dea673e9SRodney W. Grimes */ 126dea673e9SRodney W. Grimes printer = cp; 127dea673e9SRodney W. Grimes continue; 128dea673e9SRodney W. Grimes 129dea673e9SRodney W. Grimes case 'p': 130dea673e9SRodney W. Grimes /* 131dea673e9SRodney W. Grimes * get the price. 132dea673e9SRodney W. Grimes */ 133dea673e9SRodney W. Grimes price = atof(cp); 134dea673e9SRodney W. Grimes pflag = 1; 135dea673e9SRodney W. Grimes continue; 136dea673e9SRodney W. Grimes 137dea673e9SRodney W. Grimes case 's': 138dea673e9SRodney W. Grimes /* 139dea673e9SRodney W. Grimes * Summarize and compress accounting file. 140dea673e9SRodney W. Grimes */ 141dea673e9SRodney W. Grimes summarize++; 142dea673e9SRodney W. Grimes continue; 143dea673e9SRodney W. Grimes 144dea673e9SRodney W. Grimes case 'c': 145dea673e9SRodney W. Grimes /* 146dea673e9SRodney W. Grimes * Sort by cost. 147dea673e9SRodney W. Grimes */ 148dea673e9SRodney W. Grimes sort++; 149dea673e9SRodney W. Grimes continue; 150dea673e9SRodney W. Grimes 151dea673e9SRodney W. Grimes case 'm': 152dea673e9SRodney W. Grimes /* 153dea673e9SRodney W. Grimes * disregard machine names for each user 154dea673e9SRodney W. Grimes */ 155dea673e9SRodney W. Grimes mflag = 1; 156dea673e9SRodney W. Grimes continue; 157dea673e9SRodney W. Grimes 158dea673e9SRodney W. Grimes case 'r': 159dea673e9SRodney W. Grimes /* 160dea673e9SRodney W. Grimes * Reverse sorting order. 161dea673e9SRodney W. Grimes */ 162dea673e9SRodney W. Grimes reverse++; 163dea673e9SRodney W. Grimes continue; 164dea673e9SRodney W. Grimes 165dea673e9SRodney W. Grimes default: 1669b3fe531SPhilippe Charnier usage(); 167dea673e9SRodney W. Grimes } 168dea673e9SRodney W. Grimes } 169dea673e9SRodney W. Grimes (void) enter(--cp); 170dea673e9SRodney W. Grimes allflag = 0; 171dea673e9SRodney W. Grimes } 172dea673e9SRodney W. Grimes if (printer == NULL && (printer = getenv("PRINTER")) == NULL) 173dea673e9SRodney W. Grimes printer = DEFLP; 174dea673e9SRodney W. Grimes if (!chkprinter(printer)) { 175dea673e9SRodney W. Grimes printf("pac: unknown printer %s\n", printer); 176dea673e9SRodney W. Grimes exit(2); 177dea673e9SRodney W. Grimes } 178dea673e9SRodney W. Grimes 179961d3645SGarance A Drosehn if ((acctf = fopen(acctfile, "r")) == NULL) { 180dea673e9SRodney W. Grimes perror(acctfile); 181dea673e9SRodney W. Grimes exit(1); 182dea673e9SRodney W. Grimes } 183961d3645SGarance A Drosehn account(acctf); 184961d3645SGarance A Drosehn fclose(acctf); 185961d3645SGarance A Drosehn if ((acctf = fopen(sumfile, "r")) != NULL) { 186961d3645SGarance A Drosehn account(acctf); 187961d3645SGarance A Drosehn fclose(acctf); 188dea673e9SRodney W. Grimes } 189dea673e9SRodney W. Grimes if (summarize) 190dea673e9SRodney W. Grimes rewrite(); 191dea673e9SRodney W. Grimes else 192dea673e9SRodney W. Grimes dumpit(); 193dea673e9SRodney W. Grimes exit(errs); 194dea673e9SRodney W. Grimes } 195dea673e9SRodney W. Grimes 1969b3fe531SPhilippe Charnier static void 197ba7a1ad7SGarance A Drosehn usage(void) 1989b3fe531SPhilippe Charnier { 1999b3fe531SPhilippe Charnier fprintf(stderr, 2009b3fe531SPhilippe Charnier "usage: pac [-Pprinter] [-pprice] [-s] [-c] [-r] [-m] [user ...]\n"); 2019b3fe531SPhilippe Charnier exit(1); 2029b3fe531SPhilippe Charnier } 2039b3fe531SPhilippe Charnier 204dea673e9SRodney W. Grimes /* 205dea673e9SRodney W. Grimes * Read the entire accounting file, accumulating statistics 206dea673e9SRodney W. Grimes * for the users that we have in the hash table. If allflag 207dea673e9SRodney W. Grimes * is set, then just gather the facts on everyone. 2083df5ecacSUlrich Spörlein * Note that we must accommodate both the active and summary file 209dea673e9SRodney W. Grimes * formats here. 210dea673e9SRodney W. Grimes * Host names are ignored if the -m flag is present. 211dea673e9SRodney W. Grimes */ 212dea673e9SRodney W. Grimes static void 213961d3645SGarance A Drosehn account(FILE *acctf) 214dea673e9SRodney W. Grimes { 215dea673e9SRodney W. Grimes char linebuf[BUFSIZ]; 216dea673e9SRodney W. Grimes double t; 217dea673e9SRodney W. Grimes register char *cp, *cp2; 218dea673e9SRodney W. Grimes register struct hent *hp; 219dea673e9SRodney W. Grimes register int ic; 220dea673e9SRodney W. Grimes 221961d3645SGarance A Drosehn while (fgets(linebuf, BUFSIZ, acctf) != NULL) { 222dea673e9SRodney W. Grimes cp = linebuf; 2236689ae4bSPeter Wemm while (any(*cp, " \t")) 224dea673e9SRodney W. Grimes cp++; 225dea673e9SRodney W. Grimes t = atof(cp); 226dea673e9SRodney W. Grimes while (any(*cp, ".0123456789")) 227dea673e9SRodney W. Grimes cp++; 228dea673e9SRodney W. Grimes while (any(*cp, " \t")) 229dea673e9SRodney W. Grimes cp++; 230dea673e9SRodney W. Grimes for (cp2 = cp; !any(*cp2, " \t\n"); cp2++) 231dea673e9SRodney W. Grimes ; 232dea673e9SRodney W. Grimes ic = atoi(cp2); 233dea673e9SRodney W. Grimes *cp2 = '\0'; 234f8eb25daSWarner Losh if (mflag && strchr(cp, ':')) 235f8eb25daSWarner Losh cp = strchr(cp, ':') + 1; 236dea673e9SRodney W. Grimes hp = lookup(cp); 237dea673e9SRodney W. Grimes if (hp == NULL) { 238dea673e9SRodney W. Grimes if (!allflag) 239dea673e9SRodney W. Grimes continue; 240dea673e9SRodney W. Grimes hp = enter(cp); 241dea673e9SRodney W. Grimes } 242dea673e9SRodney W. Grimes hp->h_feetpages += t; 243dea673e9SRodney W. Grimes if (ic) 244dea673e9SRodney W. Grimes hp->h_count += ic; 245dea673e9SRodney W. Grimes else 246dea673e9SRodney W. Grimes hp->h_count++; 247dea673e9SRodney W. Grimes } 248dea673e9SRodney W. Grimes } 249dea673e9SRodney W. Grimes 250dea673e9SRodney W. Grimes /* 251dea673e9SRodney W. Grimes * Sort the hashed entries by name or footage 252dea673e9SRodney W. Grimes * and print it all out. 253dea673e9SRodney W. Grimes */ 254dea673e9SRodney W. Grimes static void 255ba7a1ad7SGarance A Drosehn dumpit(void) 256dea673e9SRodney W. Grimes { 257dea673e9SRodney W. Grimes struct hent **base; 258dea673e9SRodney W. Grimes register struct hent *hp, **ap; 259961d3645SGarance A Drosehn register int hno, runs; 260961d3645SGarance A Drosehn size_t c; 261dea673e9SRodney W. Grimes float feet; 262dea673e9SRodney W. Grimes 263dea673e9SRodney W. Grimes hp = hashtab[0]; 264dea673e9SRodney W. Grimes hno = 1; 265dea673e9SRodney W. Grimes base = (struct hent **) calloc(sizeof hp, hcount); 266dea673e9SRodney W. Grimes for (ap = base, c = hcount; c--; ap++) { 267dea673e9SRodney W. Grimes while (hp == NULL) 268dea673e9SRodney W. Grimes hp = hashtab[hno++]; 269dea673e9SRodney W. Grimes *ap = hp; 270dea673e9SRodney W. Grimes hp = hp->h_link; 271dea673e9SRodney W. Grimes } 272dea673e9SRodney W. Grimes qsort(base, hcount, sizeof hp, qucmp); 273dea673e9SRodney W. Grimes printf(" Login pages/feet runs price\n"); 274dea673e9SRodney W. Grimes feet = 0.0; 275dea673e9SRodney W. Grimes runs = 0; 276dea673e9SRodney W. Grimes for (ap = base, c = hcount; c--; ap++) { 277dea673e9SRodney W. Grimes hp = *ap; 278dea673e9SRodney W. Grimes runs += hp->h_count; 279dea673e9SRodney W. Grimes feet += hp->h_feetpages; 280dea673e9SRodney W. Grimes printf("%-24s %7.2f %4d $%6.2f\n", hp->h_name, 281dea673e9SRodney W. Grimes hp->h_feetpages, hp->h_count, hp->h_feetpages * price); 282dea673e9SRodney W. Grimes } 283dea673e9SRodney W. Grimes if (allflag) { 284dea673e9SRodney W. Grimes printf("\n"); 285dea673e9SRodney W. Grimes printf("%-24s %7.2f %4d $%6.2f\n", "total", feet, 286dea673e9SRodney W. Grimes runs, feet * price); 287dea673e9SRodney W. Grimes } 288dea673e9SRodney W. Grimes } 289dea673e9SRodney W. Grimes 290dea673e9SRodney W. Grimes /* 291dea673e9SRodney W. Grimes * Rewrite the summary file with the summary information we have accumulated. 292dea673e9SRodney W. Grimes */ 293dea673e9SRodney W. Grimes static void 294ba7a1ad7SGarance A Drosehn rewrite(void) 295dea673e9SRodney W. Grimes { 296dea673e9SRodney W. Grimes register struct hent *hp; 297dea673e9SRodney W. Grimes register int i; 298961d3645SGarance A Drosehn FILE *acctf; 299dea673e9SRodney W. Grimes 300dea673e9SRodney W. Grimes if ((acctf = fopen(sumfile, "w")) == NULL) { 3019b3fe531SPhilippe Charnier warn("%s", sumfile); 302dea673e9SRodney W. Grimes errs++; 303dea673e9SRodney W. Grimes return; 304dea673e9SRodney W. Grimes } 305dea673e9SRodney W. Grimes for (i = 0; i < HSHSIZE; i++) { 306dea673e9SRodney W. Grimes hp = hashtab[i]; 307dea673e9SRodney W. Grimes while (hp != NULL) { 308dea673e9SRodney W. Grimes fprintf(acctf, "%7.2f\t%s\t%d\n", hp->h_feetpages, 309dea673e9SRodney W. Grimes hp->h_name, hp->h_count); 310dea673e9SRodney W. Grimes hp = hp->h_link; 311dea673e9SRodney W. Grimes } 312dea673e9SRodney W. Grimes } 313dea673e9SRodney W. Grimes fflush(acctf); 314dea673e9SRodney W. Grimes if (ferror(acctf)) { 3159b3fe531SPhilippe Charnier warn("%s", sumfile); 316dea673e9SRodney W. Grimes errs++; 317dea673e9SRodney W. Grimes } 318dea673e9SRodney W. Grimes fclose(acctf); 319dea673e9SRodney W. Grimes if ((acctf = fopen(acctfile, "w")) == NULL) 3209b3fe531SPhilippe Charnier warn("%s", acctfile); 321dea673e9SRodney W. Grimes else 322dea673e9SRodney W. Grimes fclose(acctf); 323dea673e9SRodney W. Grimes } 324dea673e9SRodney W. Grimes 325dea673e9SRodney W. Grimes /* 326dea673e9SRodney W. Grimes * Hashing routines. 327dea673e9SRodney W. Grimes */ 328dea673e9SRodney W. Grimes 329dea673e9SRodney W. Grimes /* 330dea673e9SRodney W. Grimes * Enter the name into the hash table and return the pointer allocated. 331dea673e9SRodney W. Grimes */ 332dea673e9SRodney W. Grimes 333dea673e9SRodney W. Grimes static struct hent * 334ba7a1ad7SGarance A Drosehn enter(const char name[]) 335dea673e9SRodney W. Grimes { 336dea673e9SRodney W. Grimes register struct hent *hp; 337dea673e9SRodney W. Grimes register int h; 338dea673e9SRodney W. Grimes 339dea673e9SRodney W. Grimes if ((hp = lookup(name)) != NULL) 340dea673e9SRodney W. Grimes return(hp); 341dea673e9SRodney W. Grimes h = hash(name); 342dea673e9SRodney W. Grimes hcount++; 343961d3645SGarance A Drosehn hp = (struct hent *) calloc(sizeof *hp, (size_t)1); 344dea673e9SRodney W. Grimes hp->h_name = (char *) calloc(sizeof(char), strlen(name)+1); 345dea673e9SRodney W. Grimes strcpy(hp->h_name, name); 346dea673e9SRodney W. Grimes hp->h_feetpages = 0.0; 347dea673e9SRodney W. Grimes hp->h_count = 0; 348dea673e9SRodney W. Grimes hp->h_link = hashtab[h]; 349dea673e9SRodney W. Grimes hashtab[h] = hp; 350dea673e9SRodney W. Grimes return(hp); 351dea673e9SRodney W. Grimes } 352dea673e9SRodney W. Grimes 353dea673e9SRodney W. Grimes /* 354dea673e9SRodney W. Grimes * Lookup a name in the hash table and return a pointer 355dea673e9SRodney W. Grimes * to it. 356dea673e9SRodney W. Grimes */ 357dea673e9SRodney W. Grimes 358dea673e9SRodney W. Grimes static struct hent * 359ba7a1ad7SGarance A Drosehn lookup(const char name[]) 360dea673e9SRodney W. Grimes { 361dea673e9SRodney W. Grimes register int h; 362dea673e9SRodney W. Grimes register struct hent *hp; 363dea673e9SRodney W. Grimes 364dea673e9SRodney W. Grimes h = hash(name); 365dea673e9SRodney W. Grimes for (hp = hashtab[h]; hp != NULL; hp = hp->h_link) 366dea673e9SRodney W. Grimes if (strcmp(hp->h_name, name) == 0) 367dea673e9SRodney W. Grimes return(hp); 368dea673e9SRodney W. Grimes return(NULL); 369dea673e9SRodney W. Grimes } 370dea673e9SRodney W. Grimes 371dea673e9SRodney W. Grimes /* 372dea673e9SRodney W. Grimes * Hash the passed name and return the index in 373dea673e9SRodney W. Grimes * the hash table to begin the search. 374dea673e9SRodney W. Grimes */ 375dea673e9SRodney W. Grimes static int 376ba7a1ad7SGarance A Drosehn hash(const char name[]) 377dea673e9SRodney W. Grimes { 378dea673e9SRodney W. Grimes register int h; 379ba7a1ad7SGarance A Drosehn register const char *cp; 380dea673e9SRodney W. Grimes 381dea673e9SRodney W. Grimes for (cp = name, h = 0; *cp; h = (h << 2) + *cp++) 382dea673e9SRodney W. Grimes ; 383dea673e9SRodney W. Grimes return((h & 0x7fffffff) % HSHSIZE); 384dea673e9SRodney W. Grimes } 385dea673e9SRodney W. Grimes 386dea673e9SRodney W. Grimes /* 387dea673e9SRodney W. Grimes * Other stuff 388dea673e9SRodney W. Grimes */ 389dea673e9SRodney W. Grimes static int 390ba7a1ad7SGarance A Drosehn any(int ch, const char str[]) 391dea673e9SRodney W. Grimes { 392dea673e9SRodney W. Grimes register int c = ch; 393ba7a1ad7SGarance A Drosehn register const char *cp = str; 394dea673e9SRodney W. Grimes 395dea673e9SRodney W. Grimes while (*cp) 396dea673e9SRodney W. Grimes if (*cp++ == c) 397dea673e9SRodney W. Grimes return(1); 398dea673e9SRodney W. Grimes return(0); 399dea673e9SRodney W. Grimes } 400dea673e9SRodney W. Grimes 401dea673e9SRodney W. Grimes /* 402dea673e9SRodney W. Grimes * The qsort comparison routine. 403dea673e9SRodney W. Grimes * The comparison is ascii collating order 404dea673e9SRodney W. Grimes * or by feet of typesetter film, according to sort. 405dea673e9SRodney W. Grimes */ 406dea673e9SRodney W. Grimes static int 407ba7a1ad7SGarance A Drosehn qucmp(const void *a, const void *b) 408dea673e9SRodney W. Grimes { 409ba7a1ad7SGarance A Drosehn register const struct hent *h1, *h2; 410dea673e9SRodney W. Grimes register int r; 411dea673e9SRodney W. Grimes 412f0baf665SGarance A Drosehn h1 = *(const struct hent * const *)a; 413f0baf665SGarance A Drosehn h2 = *(const struct hent * const *)b; 414dea673e9SRodney W. Grimes if (sort) 415dea673e9SRodney W. Grimes r = h1->h_feetpages < h2->h_feetpages ? 416dea673e9SRodney W. Grimes -1 : h1->h_feetpages > h2->h_feetpages; 417dea673e9SRodney W. Grimes else 418dea673e9SRodney W. Grimes r = strcmp(h1->h_name, h2->h_name); 419dea673e9SRodney W. Grimes return(reverse ? -r : r); 420dea673e9SRodney W. Grimes } 421dea673e9SRodney W. Grimes 422dea673e9SRodney W. Grimes /* 423dea673e9SRodney W. Grimes * Perform lookup for printer name or abbreviation -- 424dea673e9SRodney W. Grimes */ 425dea673e9SRodney W. Grimes static int 426ba7a1ad7SGarance A Drosehn chkprinter(const char *ptrname) 427dea673e9SRodney W. Grimes { 428dea673e9SRodney W. Grimes int stat; 4294a1a0dbeSGarrett Wollman struct printer myprinter, *pp = &myprinter; 430dea673e9SRodney W. Grimes 4314a1a0dbeSGarrett Wollman init_printer(&myprinter); 432ba7a1ad7SGarance A Drosehn stat = getprintcap(ptrname, pp); 4334a1a0dbeSGarrett Wollman switch(stat) { 4344a1a0dbeSGarrett Wollman case PCAPERR_OSERR: 4354a1a0dbeSGarrett Wollman printf("pac: getprintcap: %s\n", pcaperr(stat)); 436dea673e9SRodney W. Grimes exit(3); 4374a1a0dbeSGarrett Wollman case PCAPERR_NOTFOUND: 4384a1a0dbeSGarrett Wollman return 0; 4394a1a0dbeSGarrett Wollman case PCAPERR_TCLOOP: 4404a1a0dbeSGarrett Wollman fatal(pp, "%s", pcaperr(stat)); 441dea673e9SRodney W. Grimes } 44267ba6825SDavid Malone if ((acctfile = pp->acct_file) == NULL) 443ba7a1ad7SGarance A Drosehn errx(3, "accounting not enabled for printer %s", ptrname); 4444a1a0dbeSGarrett Wollman if (!pflag && pp->price100) 4454a1a0dbeSGarrett Wollman price = pp->price100/10000.0; 446dea673e9SRodney W. Grimes sumfile = (char *) calloc(sizeof(char), strlen(acctfile)+5); 4479b3fe531SPhilippe Charnier if (sumfile == NULL) 4489b3fe531SPhilippe Charnier errx(1, "calloc failed"); 449dea673e9SRodney W. Grimes strcpy(sumfile, acctfile); 450dea673e9SRodney W. Grimes strcat(sumfile, "_sum"); 451dea673e9SRodney W. Grimes return(1); 452dea673e9SRodney W. Grimes } 453