summaryrefslogtreecommitdiffstats
path: root/usr.sbin/lpr/pac
diff options
context:
space:
mode:
authorrgrimes <rgrimes@FreeBSD.org>1994-05-26 05:23:31 +0000
committerrgrimes <rgrimes@FreeBSD.org>1994-05-26 05:23:31 +0000
commit862fdf11a2ede45dec0da01ed575525d79468981 (patch)
tree7a1c88ccb8006476bd4b4a548a6ad48fbfc33a01 /usr.sbin/lpr/pac
parent8e1a19ddde0df113b0b26b0ea621afd61dbaf91f (diff)
downloadFreeBSD-src-862fdf11a2ede45dec0da01ed575525d79468981.zip
FreeBSD-src-862fdf11a2ede45dec0da01ed575525d79468981.tar.gz
BSD 4.4 Lite usr.sbin Sources
Diffstat (limited to 'usr.sbin/lpr/pac')
-rw-r--r--usr.sbin/lpr/pac/Makefile10
-rw-r--r--usr.sbin/lpr/pac/pac.8106
-rw-r--r--usr.sbin/lpr/pac/pac.c444
3 files changed, 560 insertions, 0 deletions
diff --git a/usr.sbin/lpr/pac/Makefile b/usr.sbin/lpr/pac/Makefile
new file mode 100644
index 0000000..70cea89
--- /dev/null
+++ b/usr.sbin/lpr/pac/Makefile
@@ -0,0 +1,10 @@
+# @(#)Makefile 8.1 (Berkeley) 6/6/93
+
+PROG= pac
+CFLAGS+=-I${.CURDIR}/../common_source
+MAN8= pac.0
+SRCS= pac.c common.c
+.PATH: ${.CURDIR}/../common_source
+
+.include "../../Makefile.inc"
+.include <bsd.prog.mk>
diff --git a/usr.sbin/lpr/pac/pac.8 b/usr.sbin/lpr/pac/pac.8
new file mode 100644
index 0000000..6e7ffc0
--- /dev/null
+++ b/usr.sbin/lpr/pac/pac.8
@@ -0,0 +1,106 @@
+.\" Copyright (c) 1983, 1991, 1993
+.\" The Regents of the University of California. All rights reserved.
+.\"
+.\" Redistribution and use in source and binary forms, with or without
+.\" modification, are permitted provided that the following conditions
+.\" are met:
+.\" 1. Redistributions of source code must retain the above copyright
+.\" notice, this list of conditions and the following disclaimer.
+.\" 2. Redistributions in binary form must reproduce the above copyright
+.\" notice, this list of conditions and the following disclaimer in the
+.\" documentation and/or other materials provided with the distribution.
+.\" 3. All advertising materials mentioning features or use of this software
+.\" must display the following acknowledgement:
+.\" This product includes software developed by the University of
+.\" California, Berkeley and its contributors.
+.\" 4. Neither the name of the University nor the names of its contributors
+.\" may be used to endorse or promote products derived from this software
+.\" without specific prior written permission.
+.\"
+.\" THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+.\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+.\" ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+.\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+.\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+.\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+.\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+.\" SUCH DAMAGE.
+.\"
+.\" @(#)pac.8 8.1 (Berkeley) 6/6/93
+.\"
+.Dd June 6, 1993
+.Dt PAC 8
+.Os BSD 4.2
+.Sh NAME
+.Nm pac
+.Nd printer/plotter accounting information
+.Sh SYNOPSIS
+.Nm pac
+.Op Fl P Ns Ar printer
+.Op Fl c
+.Op Fl m
+.Op Fl p Ns Ar price
+.Op Fl s
+.Op Fl r
+.Op Ar name ...
+.Sh DESCRIPTION
+.Nm Pac
+reads the printer/plotter accounting files, accumulating the number
+of pages (the usual case) or feet (for raster devices)
+of paper consumed by each user, and printing out
+how much each user consumed in pages or feet and dollars.
+.Pp
+Options and operands available:
+.Bl -tag -width PPprinter
+.It Fl P Ns Ar printer
+Accounting is done for the named printer.
+Normally, accounting is done for the default printer (site dependent) or
+the value of the environment variable
+.Ev PRINTER
+is used.
+.It Fl c
+flag causes the output to be sorted by cost; usually the
+output is sorted alphabetically by name.
+.It Fl m
+flag causes the host name to be ignored in the accounting file. This
+allows for a user on multiple machines to have all of his printing
+charges grouped together.
+.It Fl p Ns Ar price
+The value
+.Ar price
+is used for the cost in dollars instead of the default value of 0.02
+or the price specified in
+.Pa /etc/printcap .
+.It Fl r
+Reverse the sorting order.
+.It Fl s
+Accounting information is summarized on the
+summary accounting file; this summarization is necessary since on a
+busy system, the accounting file can grow by several lines per day.
+.It Ar names
+Statistics are only printed for user(s)
+.Ar name ;
+usually, statistics are printed for every user who has used any paper.
+.El
+.Sh FILES
+.Bl -tag -width /var/account/?_sum -compact
+.It Pa /var/account/?acct
+raw accounting files
+.It Pa /var/account/?_sum
+summary accounting files
+.It Pa /etc/printcap
+printer capability data base
+.El
+.Sh SEE ALSO
+.Xr printcap 5
+.Sh BUGS
+The relationship between the computed price and reality is
+as yet unknown.
+.Sh HISTORY
+The
+.Nm
+command appeared in
+.Bx 4.0 .
diff --git a/usr.sbin/lpr/pac/pac.c b/usr.sbin/lpr/pac/pac.c
new file mode 100644
index 0000000..af0c8cc
--- /dev/null
+++ b/usr.sbin/lpr/pac/pac.c
@@ -0,0 +1,444 @@
+/*
+ * Copyright (c) 1983, 1993
+ * The Regents of the University of California. All rights reserved.
+ *
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by the University of
+ * California, Berkeley and its contributors.
+ * 4. Neither the name of the University nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#ifndef lint
+static char copyright[] =
+"@(#) Copyright (c) 1983, 1993\n\
+ The Regents of the University of California. All rights reserved.\n";
+#endif /* not lint */
+
+#ifndef lint
+static char sccsid[] = "@(#)pac.c 8.1 (Berkeley) 6/6/93";
+#endif /* not lint */
+
+/*
+ * Do Printer accounting summary.
+ * Currently, usage is
+ * pac [-Pprinter] [-pprice] [-s] [-r] [-c] [-m] [user ...]
+ * to print the usage information for the named people.
+ */
+
+#include <sys/param.h>
+
+#include <dirent.h>
+#include <stdlib.h>
+#include <stdio.h>
+#include <string.h>
+#include "lp.h"
+#include "lp.local.h"
+
+static char *acctfile; /* accounting file (input data) */
+static int allflag = 1; /* Get stats on everybody */
+static int errs;
+static int hcount; /* Count of hash entries */
+static int mflag = 0; /* disregard machine names */
+static int pflag = 0; /* 1 if -p on cmd line */
+static float price = 0.02; /* cost per page (or what ever) */
+static long price100; /* per-page cost in 100th of a cent */
+static int reverse; /* Reverse sort order */
+static int sort; /* Sort by cost */
+static char *sumfile; /* summary file */
+static int summarize; /* Compress accounting file */
+
+/*
+ * 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 */
+};
+
+static struct hent *hashtab[HSHSIZE]; /* Hash table proper */
+
+static void account __P((FILE *));
+static int any __P((int, char []));
+static int chkprinter __P((char *));
+static void dumpit __P((void));
+static int hash __P((char []));
+static struct hent *enter __P((char []));
+static struct hent *lookup __P((char []));
+static int qucmp __P((const void *, const void *));
+static void rewrite __P((void));
+
+void
+main(argc, argv)
+ int argc;
+ 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);
+ pflag = 1;
+ continue;
+
+ case 's':
+ /*
+ * Summarize and compress accounting file.
+ */
+ summarize++;
+ continue;
+
+ case 'c':
+ /*
+ * Sort by cost.
+ */
+ sort++;
+ continue;
+
+ case 'm':
+ /*
+ * disregard machine names for each user
+ */
+ mflag = 1;
+ continue;
+
+ case 'r':
+ /*
+ * Reverse sorting order.
+ */
+ reverse++;
+ continue;
+
+ default:
+fprintf(stderr,
+ "usage: pac [-Pprinter] [-pprice] [-s] [-c] [-r] [-m] [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.
+ * Host names are ignored if the -m flag is present.
+ */
+static void
+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';
+ if (mflag && index(cp, ':'))
+ cp = index(cp, ':') + 1;
+ hp = lookup(cp);
+ if (hp == NULL) {
+ 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.
+ */
+static void
+dumpit()
+{
+ struct hent **base;
+ register struct hent *hp, **ap;
+ register int hno, c, runs;
+ float feet;
+
+ hp = hashtab[0];
+ hno = 1;
+ base = (struct hent **) calloc(sizeof hp, hcount);
+ for (ap = base, c = hcount; c--; ap++) {
+ while (hp == NULL)
+ 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.
+ */
+static void
+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.
+ */
+
+static struct hent *
+enter(name)
+ char name[];
+{
+ register struct hent *hp;
+ register int h;
+
+ if ((hp = lookup(name)) != NULL)
+ 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.
+ */
+
+static struct hent *
+lookup(name)
+ char name[];
+{
+ register int h;
+ register struct hent *hp;
+
+ h = hash(name);
+ for (hp = hashtab[h]; hp != NULL; hp = hp->h_link)
+ if (strcmp(hp->h_name, name) == 0)
+ return(hp);
+ return(NULL);
+}
+
+/*
+ * Hash the passed name and return the index in
+ * the hash table to begin the search.
+ */
+static int
+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
+ */
+static int
+any(ch, str)
+ int ch;
+ 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.
+ */
+static int
+qucmp(a, b)
+ const void *a, *b;
+{
+ register struct hent *h1, *h2;
+ register int r;
+
+ h1 = *(struct hent **)a;
+ h2 = *(struct hent **)b;
+ 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 --
+ */
+static int
+chkprinter(s)
+ register char *s;
+{
+ int stat;
+
+ if ((stat = cgetent(&bp, printcapdb, s)) == -2) {
+ printf("pac: can't open printer description file\n");
+ exit(3);
+ } else if (stat == -1)
+ return(0);
+ else if (stat == -3)
+ fatal("potential reference loop detected in printcap file");
+
+ if (cgetstr(bp, "af", &acctfile) == -1) {
+ printf("accounting not enabled for printer %s\n", printer);
+ exit(2);
+ }
+ if (!pflag && (cgetnum(bp, "pc", &price100) == 0))
+ price = price100/10000.0;
+ sumfile = (char *) calloc(sizeof(char), strlen(acctfile)+5);
+ if (sumfile == NULL) {
+ perror("pac");
+ exit(1);
+ }
+ strcpy(sumfile, acctfile);
+ strcat(sumfile, "_sum");
+ return(1);
+}
OpenPOWER on IntegriCloud