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. 14dea673e9SRodney W. Grimes * 3. All advertising materials mentioning features or use of this software 15dea673e9SRodney W. Grimes * must display the following acknowledgement: 16dea673e9SRodney W. Grimes * This product includes software developed by the University of 17dea673e9SRodney W. Grimes * California, Berkeley and its contributors. 18dea673e9SRodney W. Grimes * 4. Neither the name of the University nor the names of its contributors 19dea673e9SRodney W. Grimes * may be used to endorse or promote products derived from this software 20dea673e9SRodney W. Grimes * without specific prior written permission. 21dea673e9SRodney W. Grimes * 22dea673e9SRodney W. Grimes * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND 23dea673e9SRodney W. Grimes * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 24dea673e9SRodney W. Grimes * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 25dea673e9SRodney W. Grimes * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE 26dea673e9SRodney W. Grimes * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 27dea673e9SRodney W. Grimes * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 28dea673e9SRodney W. Grimes * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 29dea673e9SRodney W. Grimes * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 30dea673e9SRodney W. Grimes * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 31dea673e9SRodney W. Grimes * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 32dea673e9SRodney W. Grimes * SUCH DAMAGE. 33dea673e9SRodney W. Grimes */ 34dea673e9SRodney W. Grimes 35dea673e9SRodney W. Grimes #ifndef lint 36dea673e9SRodney W. Grimes static char copyright[] = 37dea673e9SRodney W. Grimes "@(#) Copyright (c) 1983, 1993\n\ 38dea673e9SRodney W. Grimes The Regents of the University of California. All rights reserved.\n"; 39dea673e9SRodney W. Grimes #endif /* not lint */ 40dea673e9SRodney W. Grimes 41dea673e9SRodney W. Grimes #ifndef lint 42dea673e9SRodney W. Grimes static char sccsid[] = "@(#)pac.c 8.1 (Berkeley) 6/6/93"; 43dea673e9SRodney W. Grimes #endif /* not lint */ 44dea673e9SRodney W. Grimes 45dea673e9SRodney W. Grimes /* 46dea673e9SRodney W. Grimes * Do Printer accounting summary. 47dea673e9SRodney W. Grimes * Currently, usage is 48dea673e9SRodney W. Grimes * pac [-Pprinter] [-pprice] [-s] [-r] [-c] [-m] [user ...] 49dea673e9SRodney W. Grimes * to print the usage information for the named people. 50dea673e9SRodney W. Grimes */ 51dea673e9SRodney W. Grimes 52dea673e9SRodney W. Grimes #include <sys/param.h> 53dea673e9SRodney W. Grimes 54dea673e9SRodney W. Grimes #include <dirent.h> 55dea673e9SRodney W. Grimes #include <stdlib.h> 56dea673e9SRodney W. Grimes #include <stdio.h> 57dea673e9SRodney W. Grimes #include <string.h> 58dea673e9SRodney W. Grimes #include "lp.h" 59dea673e9SRodney W. Grimes #include "lp.local.h" 60dea673e9SRodney W. Grimes 61dea673e9SRodney W. Grimes static char *acctfile; /* accounting file (input data) */ 62dea673e9SRodney W. Grimes static int allflag = 1; /* Get stats on everybody */ 63dea673e9SRodney W. Grimes static int errs; 64dea673e9SRodney W. Grimes static int hcount; /* Count of hash entries */ 65dea673e9SRodney W. Grimes static int mflag = 0; /* disregard machine names */ 66dea673e9SRodney W. Grimes static int pflag = 0; /* 1 if -p on cmd line */ 67dea673e9SRodney W. Grimes static float price = 0.02; /* cost per page (or what ever) */ 68dea673e9SRodney W. Grimes static long price100; /* per-page cost in 100th of a cent */ 69dea673e9SRodney W. Grimes static int reverse; /* Reverse sort order */ 70dea673e9SRodney W. Grimes static int sort; /* Sort by cost */ 71dea673e9SRodney W. Grimes static char *sumfile; /* summary file */ 72dea673e9SRodney W. Grimes static int summarize; /* Compress accounting file */ 73dea673e9SRodney W. Grimes 74dea673e9SRodney W. Grimes /* 75dea673e9SRodney W. Grimes * Grossness follows: 76dea673e9SRodney W. Grimes * Names to be accumulated are hashed into the following 77dea673e9SRodney W. Grimes * table. 78dea673e9SRodney W. Grimes */ 79dea673e9SRodney W. Grimes 80dea673e9SRodney W. Grimes #define HSHSIZE 97 /* Number of hash buckets */ 81dea673e9SRodney W. Grimes 82dea673e9SRodney W. Grimes struct hent { 83dea673e9SRodney W. Grimes struct hent *h_link; /* Forward hash link */ 84dea673e9SRodney W. Grimes char *h_name; /* Name of this user */ 85dea673e9SRodney W. Grimes float h_feetpages; /* Feet or pages of paper */ 86dea673e9SRodney W. Grimes int h_count; /* Number of runs */ 87dea673e9SRodney W. Grimes }; 88dea673e9SRodney W. Grimes 89dea673e9SRodney W. Grimes static struct hent *hashtab[HSHSIZE]; /* Hash table proper */ 90dea673e9SRodney W. Grimes 91dea673e9SRodney W. Grimes static void account __P((FILE *)); 92dea673e9SRodney W. Grimes static int any __P((int, char [])); 93dea673e9SRodney W. Grimes static int chkprinter __P((char *)); 94dea673e9SRodney W. Grimes static void dumpit __P((void)); 95dea673e9SRodney W. Grimes static int hash __P((char [])); 96dea673e9SRodney W. Grimes static struct hent *enter __P((char [])); 97dea673e9SRodney W. Grimes static struct hent *lookup __P((char [])); 98dea673e9SRodney W. Grimes static int qucmp __P((const void *, const void *)); 99dea673e9SRodney W. Grimes static void rewrite __P((void)); 100dea673e9SRodney W. Grimes 101dea673e9SRodney W. Grimes void 102dea673e9SRodney W. Grimes main(argc, argv) 103dea673e9SRodney W. Grimes int argc; 104dea673e9SRodney W. Grimes char **argv; 105dea673e9SRodney W. Grimes { 106dea673e9SRodney W. Grimes register FILE *acct; 107dea673e9SRodney W. Grimes register char *cp; 108dea673e9SRodney W. Grimes 109dea673e9SRodney W. Grimes while (--argc) { 110dea673e9SRodney W. Grimes cp = *++argv; 111dea673e9SRodney W. Grimes if (*cp++ == '-') { 112dea673e9SRodney W. Grimes switch(*cp++) { 113dea673e9SRodney W. Grimes case 'P': 114dea673e9SRodney W. Grimes /* 115dea673e9SRodney W. Grimes * Printer name. 116dea673e9SRodney W. Grimes */ 117dea673e9SRodney W. Grimes printer = cp; 118dea673e9SRodney W. Grimes continue; 119dea673e9SRodney W. Grimes 120dea673e9SRodney W. Grimes case 'p': 121dea673e9SRodney W. Grimes /* 122dea673e9SRodney W. Grimes * get the price. 123dea673e9SRodney W. Grimes */ 124dea673e9SRodney W. Grimes price = atof(cp); 125dea673e9SRodney W. Grimes pflag = 1; 126dea673e9SRodney W. Grimes continue; 127dea673e9SRodney W. Grimes 128dea673e9SRodney W. Grimes case 's': 129dea673e9SRodney W. Grimes /* 130dea673e9SRodney W. Grimes * Summarize and compress accounting file. 131dea673e9SRodney W. Grimes */ 132dea673e9SRodney W. Grimes summarize++; 133dea673e9SRodney W. Grimes continue; 134dea673e9SRodney W. Grimes 135dea673e9SRodney W. Grimes case 'c': 136dea673e9SRodney W. Grimes /* 137dea673e9SRodney W. Grimes * Sort by cost. 138dea673e9SRodney W. Grimes */ 139dea673e9SRodney W. Grimes sort++; 140dea673e9SRodney W. Grimes continue; 141dea673e9SRodney W. Grimes 142dea673e9SRodney W. Grimes case 'm': 143dea673e9SRodney W. Grimes /* 144dea673e9SRodney W. Grimes * disregard machine names for each user 145dea673e9SRodney W. Grimes */ 146dea673e9SRodney W. Grimes mflag = 1; 147dea673e9SRodney W. Grimes continue; 148dea673e9SRodney W. Grimes 149dea673e9SRodney W. Grimes case 'r': 150dea673e9SRodney W. Grimes /* 151dea673e9SRodney W. Grimes * Reverse sorting order. 152dea673e9SRodney W. Grimes */ 153dea673e9SRodney W. Grimes reverse++; 154dea673e9SRodney W. Grimes continue; 155dea673e9SRodney W. Grimes 156dea673e9SRodney W. Grimes default: 157dea673e9SRodney W. Grimes fprintf(stderr, 158dea673e9SRodney W. Grimes "usage: pac [-Pprinter] [-pprice] [-s] [-c] [-r] [-m] [user ...]\n"); 159dea673e9SRodney W. Grimes exit(1); 160dea673e9SRodney W. Grimes } 161dea673e9SRodney W. Grimes } 162dea673e9SRodney W. Grimes (void) enter(--cp); 163dea673e9SRodney W. Grimes allflag = 0; 164dea673e9SRodney W. Grimes } 165dea673e9SRodney W. Grimes if (printer == NULL && (printer = getenv("PRINTER")) == NULL) 166dea673e9SRodney W. Grimes printer = DEFLP; 167dea673e9SRodney W. Grimes if (!chkprinter(printer)) { 168dea673e9SRodney W. Grimes printf("pac: unknown printer %s\n", printer); 169dea673e9SRodney W. Grimes exit(2); 170dea673e9SRodney W. Grimes } 171dea673e9SRodney W. Grimes 172dea673e9SRodney W. Grimes if ((acct = fopen(acctfile, "r")) == NULL) { 173dea673e9SRodney W. Grimes perror(acctfile); 174dea673e9SRodney W. Grimes exit(1); 175dea673e9SRodney W. Grimes } 176dea673e9SRodney W. Grimes account(acct); 177dea673e9SRodney W. Grimes fclose(acct); 178dea673e9SRodney W. Grimes if ((acct = fopen(sumfile, "r")) != NULL) { 179dea673e9SRodney W. Grimes account(acct); 180dea673e9SRodney W. Grimes fclose(acct); 181dea673e9SRodney W. Grimes } 182dea673e9SRodney W. Grimes if (summarize) 183dea673e9SRodney W. Grimes rewrite(); 184dea673e9SRodney W. Grimes else 185dea673e9SRodney W. Grimes dumpit(); 186dea673e9SRodney W. Grimes exit(errs); 187dea673e9SRodney W. Grimes } 188dea673e9SRodney W. Grimes 189dea673e9SRodney W. Grimes /* 190dea673e9SRodney W. Grimes * Read the entire accounting file, accumulating statistics 191dea673e9SRodney W. Grimes * for the users that we have in the hash table. If allflag 192dea673e9SRodney W. Grimes * is set, then just gather the facts on everyone. 193dea673e9SRodney W. Grimes * Note that we must accomodate both the active and summary file 194dea673e9SRodney W. Grimes * formats here. 195dea673e9SRodney W. Grimes * Host names are ignored if the -m flag is present. 196dea673e9SRodney W. Grimes */ 197dea673e9SRodney W. Grimes static void 198dea673e9SRodney W. Grimes account(acct) 199dea673e9SRodney W. Grimes register FILE *acct; 200dea673e9SRodney W. Grimes { 201dea673e9SRodney W. Grimes char linebuf[BUFSIZ]; 202dea673e9SRodney W. Grimes double t; 203dea673e9SRodney W. Grimes register char *cp, *cp2; 204dea673e9SRodney W. Grimes register struct hent *hp; 205dea673e9SRodney W. Grimes register int ic; 206dea673e9SRodney W. Grimes 207dea673e9SRodney W. Grimes while (fgets(linebuf, BUFSIZ, acct) != NULL) { 208dea673e9SRodney W. Grimes cp = linebuf; 209dea673e9SRodney W. Grimes while (any(*cp, " t\t")) 210dea673e9SRodney W. Grimes cp++; 211dea673e9SRodney W. Grimes t = atof(cp); 212dea673e9SRodney W. Grimes while (any(*cp, ".0123456789")) 213dea673e9SRodney W. Grimes cp++; 214dea673e9SRodney W. Grimes while (any(*cp, " \t")) 215dea673e9SRodney W. Grimes cp++; 216dea673e9SRodney W. Grimes for (cp2 = cp; !any(*cp2, " \t\n"); cp2++) 217dea673e9SRodney W. Grimes ; 218dea673e9SRodney W. Grimes ic = atoi(cp2); 219dea673e9SRodney W. Grimes *cp2 = '\0'; 220dea673e9SRodney W. Grimes if (mflag && index(cp, ':')) 221dea673e9SRodney W. Grimes cp = index(cp, ':') + 1; 222dea673e9SRodney W. Grimes hp = lookup(cp); 223dea673e9SRodney W. Grimes if (hp == NULL) { 224dea673e9SRodney W. Grimes if (!allflag) 225dea673e9SRodney W. Grimes continue; 226dea673e9SRodney W. Grimes hp = enter(cp); 227dea673e9SRodney W. Grimes } 228dea673e9SRodney W. Grimes hp->h_feetpages += t; 229dea673e9SRodney W. Grimes if (ic) 230dea673e9SRodney W. Grimes hp->h_count += ic; 231dea673e9SRodney W. Grimes else 232dea673e9SRodney W. Grimes hp->h_count++; 233dea673e9SRodney W. Grimes } 234dea673e9SRodney W. Grimes } 235dea673e9SRodney W. Grimes 236dea673e9SRodney W. Grimes /* 237dea673e9SRodney W. Grimes * Sort the hashed entries by name or footage 238dea673e9SRodney W. Grimes * and print it all out. 239dea673e9SRodney W. Grimes */ 240dea673e9SRodney W. Grimes static void 241dea673e9SRodney W. Grimes dumpit() 242dea673e9SRodney W. Grimes { 243dea673e9SRodney W. Grimes struct hent **base; 244dea673e9SRodney W. Grimes register struct hent *hp, **ap; 245dea673e9SRodney W. Grimes register int hno, c, runs; 246dea673e9SRodney W. Grimes float feet; 247dea673e9SRodney W. Grimes 248dea673e9SRodney W. Grimes hp = hashtab[0]; 249dea673e9SRodney W. Grimes hno = 1; 250dea673e9SRodney W. Grimes base = (struct hent **) calloc(sizeof hp, hcount); 251dea673e9SRodney W. Grimes for (ap = base, c = hcount; c--; ap++) { 252dea673e9SRodney W. Grimes while (hp == NULL) 253dea673e9SRodney W. Grimes hp = hashtab[hno++]; 254dea673e9SRodney W. Grimes *ap = hp; 255dea673e9SRodney W. Grimes hp = hp->h_link; 256dea673e9SRodney W. Grimes } 257dea673e9SRodney W. Grimes qsort(base, hcount, sizeof hp, qucmp); 258dea673e9SRodney W. Grimes printf(" Login pages/feet runs price\n"); 259dea673e9SRodney W. Grimes feet = 0.0; 260dea673e9SRodney W. Grimes runs = 0; 261dea673e9SRodney W. Grimes for (ap = base, c = hcount; c--; ap++) { 262dea673e9SRodney W. Grimes hp = *ap; 263dea673e9SRodney W. Grimes runs += hp->h_count; 264dea673e9SRodney W. Grimes feet += hp->h_feetpages; 265dea673e9SRodney W. Grimes printf("%-24s %7.2f %4d $%6.2f\n", hp->h_name, 266dea673e9SRodney W. Grimes hp->h_feetpages, hp->h_count, hp->h_feetpages * price); 267dea673e9SRodney W. Grimes } 268dea673e9SRodney W. Grimes if (allflag) { 269dea673e9SRodney W. Grimes printf("\n"); 270dea673e9SRodney W. Grimes printf("%-24s %7.2f %4d $%6.2f\n", "total", feet, 271dea673e9SRodney W. Grimes runs, feet * price); 272dea673e9SRodney W. Grimes } 273dea673e9SRodney W. Grimes } 274dea673e9SRodney W. Grimes 275dea673e9SRodney W. Grimes /* 276dea673e9SRodney W. Grimes * Rewrite the summary file with the summary information we have accumulated. 277dea673e9SRodney W. Grimes */ 278dea673e9SRodney W. Grimes static void 279dea673e9SRodney W. Grimes rewrite() 280dea673e9SRodney W. Grimes { 281dea673e9SRodney W. Grimes register struct hent *hp; 282dea673e9SRodney W. Grimes register int i; 283dea673e9SRodney W. Grimes register FILE *acctf; 284dea673e9SRodney W. Grimes 285dea673e9SRodney W. Grimes if ((acctf = fopen(sumfile, "w")) == NULL) { 286dea673e9SRodney W. Grimes perror(sumfile); 287dea673e9SRodney W. Grimes errs++; 288dea673e9SRodney W. Grimes return; 289dea673e9SRodney W. Grimes } 290dea673e9SRodney W. Grimes for (i = 0; i < HSHSIZE; i++) { 291dea673e9SRodney W. Grimes hp = hashtab[i]; 292dea673e9SRodney W. Grimes while (hp != NULL) { 293dea673e9SRodney W. Grimes fprintf(acctf, "%7.2f\t%s\t%d\n", hp->h_feetpages, 294dea673e9SRodney W. Grimes hp->h_name, hp->h_count); 295dea673e9SRodney W. Grimes hp = hp->h_link; 296dea673e9SRodney W. Grimes } 297dea673e9SRodney W. Grimes } 298dea673e9SRodney W. Grimes fflush(acctf); 299dea673e9SRodney W. Grimes if (ferror(acctf)) { 300dea673e9SRodney W. Grimes perror(sumfile); 301dea673e9SRodney W. Grimes errs++; 302dea673e9SRodney W. Grimes } 303dea673e9SRodney W. Grimes fclose(acctf); 304dea673e9SRodney W. Grimes if ((acctf = fopen(acctfile, "w")) == NULL) 305dea673e9SRodney W. Grimes perror(acctfile); 306dea673e9SRodney W. Grimes else 307dea673e9SRodney W. Grimes fclose(acctf); 308dea673e9SRodney W. Grimes } 309dea673e9SRodney W. Grimes 310dea673e9SRodney W. Grimes /* 311dea673e9SRodney W. Grimes * Hashing routines. 312dea673e9SRodney W. Grimes */ 313dea673e9SRodney W. Grimes 314dea673e9SRodney W. Grimes /* 315dea673e9SRodney W. Grimes * Enter the name into the hash table and return the pointer allocated. 316dea673e9SRodney W. Grimes */ 317dea673e9SRodney W. Grimes 318dea673e9SRodney W. Grimes static struct hent * 319dea673e9SRodney W. Grimes enter(name) 320dea673e9SRodney W. Grimes char name[]; 321dea673e9SRodney W. Grimes { 322dea673e9SRodney W. Grimes register struct hent *hp; 323dea673e9SRodney W. Grimes register int h; 324dea673e9SRodney W. Grimes 325dea673e9SRodney W. Grimes if ((hp = lookup(name)) != NULL) 326dea673e9SRodney W. Grimes return(hp); 327dea673e9SRodney W. Grimes h = hash(name); 328dea673e9SRodney W. Grimes hcount++; 329dea673e9SRodney W. Grimes hp = (struct hent *) calloc(sizeof *hp, 1); 330dea673e9SRodney W. Grimes hp->h_name = (char *) calloc(sizeof(char), strlen(name)+1); 331dea673e9SRodney W. Grimes strcpy(hp->h_name, name); 332dea673e9SRodney W. Grimes hp->h_feetpages = 0.0; 333dea673e9SRodney W. Grimes hp->h_count = 0; 334dea673e9SRodney W. Grimes hp->h_link = hashtab[h]; 335dea673e9SRodney W. Grimes hashtab[h] = hp; 336dea673e9SRodney W. Grimes return(hp); 337dea673e9SRodney W. Grimes } 338dea673e9SRodney W. Grimes 339dea673e9SRodney W. Grimes /* 340dea673e9SRodney W. Grimes * Lookup a name in the hash table and return a pointer 341dea673e9SRodney W. Grimes * to it. 342dea673e9SRodney W. Grimes */ 343dea673e9SRodney W. Grimes 344dea673e9SRodney W. Grimes static struct hent * 345dea673e9SRodney W. Grimes lookup(name) 346dea673e9SRodney W. Grimes char name[]; 347dea673e9SRodney W. Grimes { 348dea673e9SRodney W. Grimes register int h; 349dea673e9SRodney W. Grimes register struct hent *hp; 350dea673e9SRodney W. Grimes 351dea673e9SRodney W. Grimes h = hash(name); 352dea673e9SRodney W. Grimes for (hp = hashtab[h]; hp != NULL; hp = hp->h_link) 353dea673e9SRodney W. Grimes if (strcmp(hp->h_name, name) == 0) 354dea673e9SRodney W. Grimes return(hp); 355dea673e9SRodney W. Grimes return(NULL); 356dea673e9SRodney W. Grimes } 357dea673e9SRodney W. Grimes 358dea673e9SRodney W. Grimes /* 359dea673e9SRodney W. Grimes * Hash the passed name and return the index in 360dea673e9SRodney W. Grimes * the hash table to begin the search. 361dea673e9SRodney W. Grimes */ 362dea673e9SRodney W. Grimes static int 363dea673e9SRodney W. Grimes hash(name) 364dea673e9SRodney W. Grimes char name[]; 365dea673e9SRodney W. Grimes { 366dea673e9SRodney W. Grimes register int h; 367dea673e9SRodney W. Grimes register char *cp; 368dea673e9SRodney W. Grimes 369dea673e9SRodney W. Grimes for (cp = name, h = 0; *cp; h = (h << 2) + *cp++) 370dea673e9SRodney W. Grimes ; 371dea673e9SRodney W. Grimes return((h & 0x7fffffff) % HSHSIZE); 372dea673e9SRodney W. Grimes } 373dea673e9SRodney W. Grimes 374dea673e9SRodney W. Grimes /* 375dea673e9SRodney W. Grimes * Other stuff 376dea673e9SRodney W. Grimes */ 377dea673e9SRodney W. Grimes static int 378dea673e9SRodney W. Grimes any(ch, str) 379dea673e9SRodney W. Grimes int ch; 380dea673e9SRodney W. Grimes char str[]; 381dea673e9SRodney W. Grimes { 382dea673e9SRodney W. Grimes register int c = ch; 383dea673e9SRodney W. Grimes register char *cp = str; 384dea673e9SRodney W. Grimes 385dea673e9SRodney W. Grimes while (*cp) 386dea673e9SRodney W. Grimes if (*cp++ == c) 387dea673e9SRodney W. Grimes return(1); 388dea673e9SRodney W. Grimes return(0); 389dea673e9SRodney W. Grimes } 390dea673e9SRodney W. Grimes 391dea673e9SRodney W. Grimes /* 392dea673e9SRodney W. Grimes * The qsort comparison routine. 393dea673e9SRodney W. Grimes * The comparison is ascii collating order 394dea673e9SRodney W. Grimes * or by feet of typesetter film, according to sort. 395dea673e9SRodney W. Grimes */ 396dea673e9SRodney W. Grimes static int 397dea673e9SRodney W. Grimes qucmp(a, b) 398dea673e9SRodney W. Grimes const void *a, *b; 399dea673e9SRodney W. Grimes { 400dea673e9SRodney W. Grimes register struct hent *h1, *h2; 401dea673e9SRodney W. Grimes register int r; 402dea673e9SRodney W. Grimes 403dea673e9SRodney W. Grimes h1 = *(struct hent **)a; 404dea673e9SRodney W. Grimes h2 = *(struct hent **)b; 405dea673e9SRodney W. Grimes if (sort) 406dea673e9SRodney W. Grimes r = h1->h_feetpages < h2->h_feetpages ? 407dea673e9SRodney W. Grimes -1 : h1->h_feetpages > h2->h_feetpages; 408dea673e9SRodney W. Grimes else 409dea673e9SRodney W. Grimes r = strcmp(h1->h_name, h2->h_name); 410dea673e9SRodney W. Grimes return(reverse ? -r : r); 411dea673e9SRodney W. Grimes } 412dea673e9SRodney W. Grimes 413dea673e9SRodney W. Grimes /* 414dea673e9SRodney W. Grimes * Perform lookup for printer name or abbreviation -- 415dea673e9SRodney W. Grimes */ 416dea673e9SRodney W. Grimes static int 417dea673e9SRodney W. Grimes chkprinter(s) 418dea673e9SRodney W. Grimes register char *s; 419dea673e9SRodney W. Grimes { 420dea673e9SRodney W. Grimes int stat; 421dea673e9SRodney W. Grimes 422dea673e9SRodney W. Grimes if ((stat = cgetent(&bp, printcapdb, s)) == -2) { 423dea673e9SRodney W. Grimes printf("pac: can't open printer description file\n"); 424dea673e9SRodney W. Grimes exit(3); 425dea673e9SRodney W. Grimes } else if (stat == -1) 426dea673e9SRodney W. Grimes return(0); 427dea673e9SRodney W. Grimes else if (stat == -3) 428dea673e9SRodney W. Grimes fatal("potential reference loop detected in printcap file"); 429dea673e9SRodney W. Grimes 430dea673e9SRodney W. Grimes if (cgetstr(bp, "af", &acctfile) == -1) { 431dea673e9SRodney W. Grimes printf("accounting not enabled for printer %s\n", printer); 432dea673e9SRodney W. Grimes exit(2); 433dea673e9SRodney W. Grimes } 434dea673e9SRodney W. Grimes if (!pflag && (cgetnum(bp, "pc", &price100) == 0)) 435dea673e9SRodney W. Grimes price = price100/10000.0; 436dea673e9SRodney W. Grimes sumfile = (char *) calloc(sizeof(char), strlen(acctfile)+5); 437dea673e9SRodney W. Grimes if (sumfile == NULL) { 438dea673e9SRodney W. Grimes perror("pac"); 439dea673e9SRodney W. Grimes exit(1); 440dea673e9SRodney W. Grimes } 441dea673e9SRodney W. Grimes strcpy(sumfile, acctfile); 442dea673e9SRodney W. Grimes strcat(sumfile, "_sum"); 443dea673e9SRodney W. Grimes return(1); 444dea673e9SRodney W. Grimes } 445