Cover V04, I02
Article
Listing 1
Listing 2
Listing 3
Listing 4
Sidebar 1
Table 1

mar95.tar


Listing 2: mypac, printer accounting using BSD pacstyle records

#!/opt/bin/perl
#
# Example 2 (mypac)
#
# Printer accounting using BSD pac style records.
#
# Looks in /etc/printcap :af: entries for location
# of accounting files. Displays summaries for all
# printers for which accounting files are found.
#
# -s command line option generates PRINTER_sum
# files a la pac and empties the base accounting
# files.
#
# -z command line option generates PRINTER.yymmdd
# summary file in the same directory as the printer
# accounting file and empties the accounting and
# summary files.
#-----------------------------------------------------
# John Lees, Systems Analyst, Lab Manager
# Pattern Recognition and Image Processing Laboratory
# Department of Computer Science, A714 Wells Hall,
# East Lansing, Michigan 48824-1027  USA
# lees@cps.msu.edu, http://web.cps.msu.edu/prip
#  M i c h i g a n   S t a t e   U n i v e r s i t y
#-----------------------------------------------------
# Copyright 1994 by the Board of Trustees of Michigan
# State University and made available according to the
# provisions of the Free Software Foundation's GNU
# General Public License. The GPL is available by
# anonymous ftp from prep.ai.mit.edu in the file
# /pub/gnu/COPYING-2.0, or from ftp.cps.msu.edu in
# the file /pub/prip/lees/sysadmin/GPL.
#-----------------------------------------------------
require 'getopts.pl';
Getopts('sz');

#----------
# Scan /etc/printcap and find all the printers that have
# accounting files.
#----------
#open(PRINTCAP, './printcap') || # for debugging
open(PRINTCAP, '/etc/printcap') ||
die "There is no /etc/printcap on this system!\n";
while (<PRINTCAP>) {
/^[^:#\s]/ && do {
($lp = $_) =~ s/^\s*([^:|]*).*\s/$1/;
};
/:af=/ && do {
($af = $_) =~ s/^.*:af=([^:]*):.*\s/$1/;
$lp{$lp} = $af;
};
}
close PRINTCAP;

#----------
# Generate accounting summary.
# If the -s flag is specified, write a
#    PRINTER_sum file.
# If the -z flag is specified, write a
#    PRINTER.yymmdd file.
#----------
print "Printer Accounting As Of ", `date`;
printf "%16s %6s %6s %6s\n",
"Printer", "Pages", "Jobs",
"Users";$page_all = 0; $jobs_all = 0; %user_all = ();

# The format of the accounting file is:
#  %7.2f   pages (or feet if plotter)
#  space
#  %s:%s   hostname:username
# There is one entry for each job.

# The format of the summary file is:
#  %7.2f   total pages/feet for this user
#  tab
#  %s:%s   hostname:username
#  tab
#  %d      total jobs for this user
# There is one entry for each host:user.

# Local assumptions:
# We have no plotters, so I ignore the fractional
#   part of the page/feet.
# I don't care about the hostname in the accounting
#   records, so I generate the summary files with
#   one entry per user.

# For each printer.
while (($lp, $af) = each %lp) {
$page = 0; $jobs = 0; %user = ();

# The base accounting file.
open (AF, $af) && do {
while (<AF>) {
/^\s*([0-9]*)\.00\s*([^:]*):(\S*).*$/;
$p = $1; $h = $2; $u = $3;
$page += $p;
$jobs++;
# Build summary record for this user.
if ($_ = $user{$u}) {
/^\s*([0-9]*).*\t([0-9]*)$/;
$pp = $1; $jj = $2;
}
else {
# First entry.
$pp = 0; $jj = 0;
}
$pp += $p;
$jj++;
$user{$u} =
sprintf "%7.2f\t%s:%s\t%d", $pp, $h, $u, $jj;
}
};
close AF;

# The summary accounting file.
$sf = $af . '_sum';
open (SF, $sf) && do {
while (<SF>) {
/^\s*([0-9]*)\.00\s*([^:]*):(\S*)\s*([0-9]*).*$/;
$p = $1; $h = $2; $u = $3; $j = $4;
$page += $p;
$jobs += $j;
# Build summary record for this user.
if ($_ = $user{$u}) {
/^\s*([0-9]*).*\t([0-9]*)$/;
$pp = $1; $jj = $2;
}
else {
# First entry.
$pp = 0; $jj = 0;
}
$pp += $p;
$jj += $j;
$user{$u} =
sprintf "%7.2f\t%s:%s\t%d", $pp, $h, $u, $jj;
}
};
close SF;

# Print accounting summary for this printer.
printf "%16s %6d %6d %6d\n",
$lp, $page, $jobs, 0+keys(%user);

# Write a new PRINTER_sum file and empty the
# base accounting file.
($opt_s) && do {
truncate($af, 0);
truncate($sf, 0);
if (open(SF, ">>$sf")) {
foreach $key (keys(%user)) {
print SF $user{$key}, "\n";
}
}
else {
print STDERR
"*** Could not open summary file $sf\n";
}
};
close SF;

# Write a PRINTER.yymmdd file and empty the
# base and summary files.
($opt_z) && do {
truncate($af, 0);
truncate($sf, 0);
chop($date = `date +'%y%m%d'`);
$ymd = $af . '.' . $date;
if (open(YMD, ">$ymd")) {
foreach $key (keys(%user)) {
print YMD $user{$key}, "\n";
}
}
else {
print STDERR
"*** Could not open yymmdd file $ymd\n";
}
};
close YMD;

# Accumulate totals.
$page_all += $page;
$jobs_all += $jobs;
foreach $key (keys(%user)) {
$user_all{$key} += 1;
}
} # while printers

# Print totals.
printf "%-16s %6d %6d %6d\n",
"Totals:", $page_all, $jobs_all, 0+keys(%user_all);

#----------
# Done.
#----------
exit 0;