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