source: trunk/third/lprng/doc/LPRng-HOWTO-15.html @ 14517

Revision 14517, 19.8 KB checked in by mwhitson, 25 years ago (diff)
This commit was generated by cvs2svn to compensate for changes in r14516, which included commits to RCS files with non-trunk default branches.
Line 
1<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 3.2 Final//EN">
2<HTML>
3<HEAD>
4 <META NAME="GENERATOR" CONTENT="SGML-Tools 1.0.9">
5 <TITLE> LPRng-HOWTO: Accounting</TITLE>
6 <LINK HREF="LPRng-HOWTO-16.html" REL=next>
7 <LINK HREF="LPRng-HOWTO-14.html" REL=previous>
8 <LINK HREF="LPRng-HOWTO.html#toc15" REL=contents>
9</HEAD>
10<BODY>
11<A HREF="LPRng-HOWTO-16.html">Next</A>
12<A HREF="LPRng-HOWTO-14.html">Previous</A>
13<A HREF="LPRng-HOWTO.html#toc15">Contents</A>
14<HR>
15<H2><A NAME="accountingref"></A> <A NAME="s15">15. Accounting</A></H2>
16
17<P>The LPRng method for doing accounting is based on experiences in a
18Academic environment,  where avoiding printing accounting procedures
19has long been practiced.  While the LPRng procedures are not bombproof,
20they do provide a wide range of facilities,  with various degrees
21of trust built into them.
22<H2><A NAME="ss15.1">15.1 Printer Accounting Reality Check</A>
23</H2>
24
25<P>The following was written
26by Patrick Powell
27<CODE>&lt;papowell@astart.com></CODE>
28in response to the expressions of frustration
29that are periodically vented in the
30<CODE>
31<A HREF="LPRng-HOWTO-1.html#maillist">lprng@lprng.org</A></CODE>
32mailing list.
33While this addresses the use of a particular set of printer filters,
34i.e. - the
35<A HREF="LPRng-HOWTO-13.html#ifhp">ifhp</A>
36set,
37the comments are appropriate to other issues.
38<P>In Academic institutions, avoiding printing accounting has been
39regarded as a challenge,  an ongoing game of fat cat and poor starving
40mouse, between the Administration and the downtrodden, poor, over charged
41student.  The following is a lighthearted ramble down the dark lane of
42printing accounting.
43<P>We will disregard the fact that if most students put as much effort
44into their studies as in finding ways to avoid accounting procedures
45then they would be Rhodes Scholar material,  but I digress...
46<P>The accounting procedures put into the LPRng and the hpif filters may
47appear to be extraordinarily complex,  but believe me, they are not.
48Firstly, we make the assumption that the printer has some sort of
49non-volatile page counter mechanism that is reliable and impervious to
50power on/off cycles.  Without this mechanism the enterprising student
51ummm... user will simply turn off the printer.  Software that prescans
52jobs for line counts and pages is notoriously unreliable,  given even
53the most modest efforts of users to hide these procedures.   The cost
54of running a PostScript simulator simply to do accounting has its
55flaws; without ensuring that the simulator has all of the interesting
56security loopholes closed, such as opening files, etc.,  it can become
57a trap door to hell for the system administrator.
58<P>Secondly,  we must make the assumption that the student... uhhh...
59user will not be able to tinker with the page counter mechanism, i.e.-
60they will not be able to roll back the odometer on the printer, FOR THE
61DURATION OF A SINGLE JOB.  I will digress and point out that a student
62actually did this for a challenge;  it only took him a couple of weeks
63of study and a fully equipped microcontroller lab, and two (2) laser
64printers which he ruined in the experiment.  HP was not amused when we
65sent them back under warranty,  claiming that this our 'normal lab usage.'
66<P>Lastly,  you should not mind a small amount of pilferage, or a few
67pages here and there being charged to the wrong account.
68<P><B>How Does It Work?</B>
69<P>The <CODE>ifhp</CODE> filter records the page
70counter value at the start and end of each part of a print job. Each
71record has the form:
72<BLOCKQUOTE><CODE>
73<PRE>
74start -ppagecounter -Ff -kjob -uuser -hhost -R...
75end  -ppages -qpagecounter -Ff -kjob -uuser -hhost -R...
76</PRE>
77</CODE></BLOCKQUOTE>
78<P>When we use the OF filter and/or banners,  we will see the
79individual jobs bracketed by the OF filter records:
80<BLOCKQUOTE><CODE>
81<PRE>
82start -p100 -Fo -kcfA100taco -uuser -hhost -R... 
83start -p101 -Ff -kcfA100taco -uuser -hhost -R... 
84end  -p1 -q102 -Ff -kcfA100taco -uuser -hhost -R... 
85start -p102 -Ff -kcfA100taco -uuser -hhost -R...
86end  -p3 -q105 -Ff -kcfA100taco -uuser -hhost -R... 
87end  -p5 -q105 -Fo -kcfA100taco -uuser -hhost -R...
88</PRE>
89</CODE></BLOCKQUOTE>
90<P>It should be clear from the above that all we need to do is to add up
91the values for the -Fo (OF) filter lines and we are done.
92<P>Unfortunately,  this is too simplistic.  If for some reason the job is
93killed or terminates due to error conditions,  the OF filter may not
94get to finish its work.  Thus,  we may see the following:
95<BLOCKQUOTE><CODE>
96<PRE>
97start -p100 -Fo -kcfA100taco -uuser -hhost -R... 
98start -p101 -Ff -kcfA100taco -uuser -hhost -R... 
99start -p110 -Fo -kcfA101taco -uuser -hhost -R...
100</PRE>
101</CODE></BLOCKQUOTE>
102<P>This is a clear indication that the user's job has been terminated.  In
103this case we need to use the differences between pagecounters of the start
104records to do accounting.
105<P>There is a caveat to all of this;  that is the problem of the last dead
106job in the list.  If the last line in the accounting file is:
107<BLOCKQUOTE><CODE>
108<PRE>
109start -p110 -Fo -kcfA101taco -uuser -hhost -R...
110</PRE>
111</CODE></BLOCKQUOTE>
112
113is the last job finished or did it abort?
114<P><B>Who Used Up 2000 Pages of Paper Today?</B>
115<P>Now we move on to the problem of real time accounting.  Due to limited
116budgets, etc., many institutions would like to strictly enforce limits
117on paper use by students. As jobs are printed their accounts should be
118docked for the amount of paper use.  One way to do this is to have an
119external accounting procedure update a shared database.  The <CODE>ifhp</CODE> filter
120has provision for a shell script to be called at the end of print job;
121this is done by both the OF and IF filter.  Thus, we can blithely
122assume that there is a central database carefully getting updates
123from the LPRng software, probably from dozens of different printers,
124and updating the accounting information.
125<P>The first question to be asked is simple:  is this worth it?
126Perhaps doing accounting as a batch job once an hour/four times
127a day/once a day is cheaper than building an running such a database.
128If it costs $5K/year for the database software, you might just consider
129ignoring the 10,000 pages that get lost in the shuffle and use
130a simple set of awk/sed/perl scripts to update a database once
131an hour.
132<P><B>BAD JOBS - Who Do We Bill?</B>
133<P>We inevitably run into an interesting question:
134what happens if a job does not complete correctly?
135<P>If you use the completion of the OF filter as a success status, I have
136to point out that many students... ummm... users soon find ways to send
137jobs to the printer that will cause it to lock up after their output
138has been printed. These jobs require power cycling of the printer and
139restarting the filter; a bit extreme, perhaps, but it has happened.
140<P>I suggest that you simply adopt a 'bill to last user of record'
141attitude,  using the pagecount information as follows:
142<BLOCKQUOTE><CODE>
143<PRE>
144start OF -- starting point for THIS job
145start IF --  nice information, but not useful
146start IF --
147end   OF -- ending point for this job - can record information
148start OF --
149if no end OF for previous job,  then treat as end OF and
150  update accounting.
151</PRE>
152</CODE></BLOCKQUOTE>
153<P>Now somebody is sure to complain that they got charged for a bunch of
154pages that they did not use.  This is inevitable;  always carry a
155can of oil for the squeaky wheels.  I might make the observation that
156once is accident, twice is coincidence, but three times is malice;
157be wary of the constant complainer and check out not only him or her but
158also their co-workers.
159<P><B>How Do We Update the Database?</B>
160<P>I suggest that database update be done as follows:
161<P>You maintain a 'last page reported' counter for each printer in the
162database.  When a successful job reports in,  check to see that<BR>
163pagecount + joblength ==  newpagecount;
164<P>If this is not the case,  then you have had a some unsuccessful jobs.
165In this case I strongly recommend that you have a means to request the
166accounting reporting program to go back through the accounting file and
167find the last report for the page counter value and try to backtrack
168through the accounting files.  The accounting file is one of the first
169things to be attacked by students... Ummm...  users.  It should NOT be
170kept on an NFS exported or mounted file system.  It should be
171carefully pruned and copied, perhaps on an hourly basis.
172<P>Now some administrators have fallen in love with network based printers;
173do not believe ANYTHING that comes over a network connection without
174some form of authentication;  PGP has some very nice Public Key
175mechanisms for handling this.  This is a major weakness in using a
176database for keeping track of accounting - a weak authentication
177mechanism may lead to denial of service attacks by students flooding
178the database with bogus print usage reports;  suddenly NOBODY can print
179and the administrator is driven to turning off accounting.
180<P>Good luck.  I am never surprised when I encounter yet another wrinkle in
181this area.
182<P>Patrick ("You call me a Bean Counter?  Guido,  break this kid's fingers<BR>
183&nbsp; &nbsp; &nbsp; &nbsp; with an adding machine!") Powell
184<H2><A NAME="ss15.2">15.2 How HP Printers Implement Page Counters</A>
185</H2>
186
187<P>The following is from
188<A HREF="http://www.hp.com/cposupport/printers/support_doc/bpl02119.html">http://www.hp.com/cposupport/printers/support_doc/bpl02119.html</A><P><B>HP LaserJet Printer Family - Page Count</B>
189<P>Description Of The Page Count Feature On HP LaserJet 4 Family
190Printers
191<P>All HP LaserJet 4/5/6 family printers have a page count feature
192built into the firmware. However, this feature works differently
193depending on which HP LaserJet printer is being used. The following
194is a description of how the page count feature works for each
195printer within the HP LaserJet 4/5/6 printer families.
196<BLOCKQUOTE><CODE>
197<PRE>
198HP LaserJet 4/4M printers
199HP LaserJet 4 Plus/4M Plus printers
200HP LaserJet 4P/4MP printers
201HP LaserJet 4Si/4Si MX printers
202HP LaserJet 4ML printers
203HP LaserJet 5P/5MP printers
204HP LaserJet 6P/6MP printers
205</PRE>
206</CODE></BLOCKQUOTE>
207<P>All of the above printers use the same method for keeping track of
208the number of copies. There are really two different page count
209values: Primary and Secondary values. Every time a page is printed,
210whether it is an internal job (such as a self-test) or a standard
211print job, the Secondary page count increases by one. This value
212is stored in standard RAM. Once the Secondary page count value
213reaches 10, the Primary page count will increase by 10. The Primary
214page count value is stored in a type of memory called NVRAM
215(Non-Volatile RAM). This is important, since NVRAM is not cleared
216when the printer is powered off. Standard RAM, on the other hand,
217is cleared when the printer is turned off or reset. Thus, the
218Primary page count only increases in increments of 10.
219<P>Example
220<P>You have a brand new HP LaserJet 6P printer and you print a self-test
221page. When you look on the test page for the Page Count value, you
222will see that it says 1. Next, you decide to print a two page letter
223and, after that, another self-test. The page count value now says
2244. Internally, the printers Secondary page count (stored in RAM)
225has the value of 4 while the Primary page count (stored in NVRAM)
226still has the value of 0. Now, you turn the printer off, then back
227on, and print another self-test. The page count value again says
2281 since the previous value of 4, stored in RAM, was cleared when
229the printer was powered off. Finally, print a ten page document
230and then turn the printer off. Upon turning the printer back on
231and printing out another self test, you see that the page count
232value is 11.  Internally, the Secondary page count value is back
233at 1 while the Primary page count value (stored in NVRAM) is 10.
234Added together, you end up with the resulting value seen on the
235self-test page.
236<P>HP LaserJet 4L/5L/6L Printers
237<P>The reason that the page count method for the HP LaserJet 4L/5L/6L
238printers differ from that of the other printers is that the HP
239LaserJet 4L/5L/6L printers do not have any NVRAM available. Thus,
240no way exists for the printer to retain a page count value once
241the printer is powered off. The HP LaserJet 4L/5L/6L printers have
242only a single page count value that increases in increments of one
243until the printer is powered off. At that point, the page count
244value is reset and begins from 0 once again.
245<P>
246<H2><A NAME="accountingserver"></A> <A NAME="ss15.3">15.3 Accounting Printcap Options</A>
247</H2>
248
249<P>The accounting facilities are controlled and enabled by the following
250entries in the printcap file.  The default value is indicated.
251<P>
252<CENTER><TABLE BORDER><TR><TD>
253<BR>
254Tag</TD><TD>Default Value</TD><TD>Purpose</TD></TR><TR><TD>
255af</TD><TD>NULL</TD><TD>accounting file name</TD></TR><TR><TD>
256as</TD><TD>"jobstart $H $n $P $k $b $t"</TD><TD>accounting info for job start</TD></TR><TR><TD>
257ae</TD><TD>"jobend $H $n $P $k $b $t"</TD><TD>accounting info for job end</TD></TR><TR><TD>
258accounting_server</TD><TD>NULL</TD></TR><TR><TD>
259achk</TD><TD>FALSE</TD></TR><TR><TD>
260la</TD><TD>TRUE</TD><TD>do accounting for 'local' printer</TD></TR><TR><TD>
261ar</TD><TD>FALSE</TD><TD>do accounting for 'remote' transfers</TD></TR><TR><TD>
262
263</TD></TR></TABLE></CENTER>
264<P>
265<H2><A NAME="ss15.4">15.4 Accounting File</A>
266</H2>
267
268<P>The most common method of accounting is to record the start and end
269times of a job and its size to the accounting file. A typical entry
270for the printcap defaults are shown below.
271<BLOCKQUOTE><CODE>
272<PRE>
273jobstart '-Htaco.astart.com' '-nroot' '-Pps' '-kcfA938taco.astart.com' \
274'-b1093' '-tNov  5 19:39:59'
275start '-p12942' '-kcfA938taco.astart.com' '-nroot' '-htaco.astart.com' '-Pps' \
276'-c0' '-Fo' '-tSun Nov  5 19:39:25 1995'
277start '-p12944' '-kcfA938taco.astart.com' '-nroot' '-htaco.astart.com' '-Pps' \
278'-c0' '-Ff' '-tSun Nov  5 19:39:27 1995'
279end '-p12944' '-kcfA938taco.astart.com' '-nroot' '-htaco.astart.com' '-Pps' \
280'-b3' '-c0' '-Ff' '-tSun Nov  5 19:39:58 1995'
281end '-p12942' '-kcfA938taco.astart.com' '-nroot' '-htaco.astart.com' '-Pps' \
282'-b2' '-c0' '-Fo' '-tSun Nov  5 19:39:59 1995'
283jobend '-Htaco.astart.com' '-nroot' '-Pps' '-kcfA938taco.astart.com' \
284'-b1093' '-tNov  5 19:39:59'
285</PRE>
286</CODE></BLOCKQUOTE>
287<P>The <CODE>jobstart</CODE> and <CODE>jobend</CODE> lines are added by the LPD server,  as
288specified by the <CODE>as</CODE> and <CODE>ae</CODE> printcap options;
289the -b (byte count) indicates the numbers of bytes in the job.
290<P>The <CODE>start</CODE> and <CODE>end</CODE>
291lines are produced by the filters;
292the of filter has an -Fo, and the if filter a -Ff entry.
293The filters in the LPRng distribution produce the
294indicated output format by default.
295The -p value is the current value of a page counter device (if any),
296and the -b value indicates the total number of pages used.
297<P>It should be clear that a simple AWK or Perl script will be able to
298process an accounting file and update accounting information for
299accounting purposes;  the usual problems with truncation, time stamps,
300etc., are left as an exercise for the system administrator.
301However,
302for those who are exercise challenged,
303the LPRng distribution
304<CODE>.../LPRng/UTILS/accounting.pl</CODE>
305file is a template that can be used to process the accounting information.
306The printcap for using this file should resemble:
307<BLOCKQUOTE><CODE>
308<PRE>
309pr:
310  :as=|/.../accounting.pl START
311  :ae=|/.../accounting.pl END
312  :if=/.../ifhp
313  :of=/.../ofhp
314  # set this to the printing device
315  :lp=prdevice
316  :sd=/.../%P
317</PRE>
318</CODE></BLOCKQUOTE>
319<P>Note that the accounting file must exist and will not be created by the
320<CODE>lpd</CODE> server.
321The accounting file should be periodically truncated.
322<H2><A NAME="ss15.5">15.5 Accounting Using an Accounting Server</A>
323</H2>
324
325<P>To accommodate even more aggressive and centralized accounting,
326a method to make a connection to a print server and send information
327to the server has been provided as well.
328If <CODE>achk</CODE> option is set,
329it is assumed that the <CODE>af</CODE> entry specifies a connection to
330server on a remote host.
331The <CODE>lpd</CODE> server will send the <CODE>as</CODE> string to the server,
332and then wait for a single line of text from the remote server.
333If the first word on the return line is
334<CODE>accept</CODE> or <CODE>hold</CODE>,
335the job will be either accepted for printing or held.
336Any other value will cause the job to be deleted.
337<P>At the end of the job the <CODE>ae</CODE> string will be sent to the server.
338No response is expected.  Example:
339<P>
340<BLOCKQUOTE><CODE>
341<PRE>
342:af=accounting.site.com%2300,tcp
343:achk
344:as=starting
345:ae=ending
346</PRE>
347</CODE></BLOCKQUOTE>
348<P>The port that the connection originates from will be in the range
349set by the configuration or printcap
350<CODE>
351<A HREF="LPRng-HOWTO-18.html#originateport">originate_port</A></CODE>
352option.
353<H2><A NAME="ss15.6">15.6 Using Filters For Accounting</A>
354</H2>
355
356<P>Some sites have expressed interest in using a central accounting
357mechanism to check that users have permissions.  This can be done by
358using the an alternative form of the as (accounting start) and ae
359(accounting end) printcap tags.  If the as and ae are filter
360specifications,  then a filter is invoked.  If the as (accounting
361start) filter returns a non-zero exit status,  then its value
362is used to handle the job as indicated by
363the
364<A HREF="LPRng-HOWTO-12.html#termination">Abnormal Termination</A>
365codes for filters.
366At the end of the job the :ae: filter will be invoked in a similar manner,
367but its exit status is ignored.
368<P>When using an accounting filter,
369the STDIN  is attached (read/write) to the accounting file or remote host
370specified by the <CODE>af</CODE> printcap option,
371STDOUT to the output device,
372and STDERR to the status file.
373The filter program would be invoked with the default filter options.
374<P>For example, here is a sample entry to check and update accounting
375<BLOCKQUOTE><CODE>
376<PRE>
377printer
378:as=|/usr/local/libexec/filters/accounting.pl start
379:ae=|/usr/local/libexec/filters/accounting.pl end
380</PRE>
381</CODE></BLOCKQUOTE>
382<H2><A NAME="ss15.7">15.7 Accounting Utility accounting.pl</A>
383</H2>
384
385<P>In order to provide a framework for doing using the outlined accounting
386methods,  the LPRng distribution
387<CODE>UTILS</CODE> directory has a <CODE>accounting.pl</CODE> script.
388This script does the following.
389<OL>
390<LI>It is assumed that the accounting filter is invoked with the
391following printcap entry.
392The start and end is used by the filter to determine at which point in
393the accounting process it is invoked.
394<BLOCKQUOTE><CODE>
395<PRE>
396printer
397:as=|/usr/local/libexec/filters/accounting.pl start
398:ae=|/usr/local/libexec/filters/accounting.pl end
399</PRE>
400</CODE></BLOCKQUOTE>
401</LI>
402<LI>It maintains the accounting file as a set of entries in the following format:
403<BLOCKQUOTE><CODE>
404<PRE>
405START [job identification]
406start -pnn ...
407...
408end -pnn+pagecount ...
409END -ppagecount [job identification]
410</PRE>
411</CODE></BLOCKQUOTE>
412</LI>
413<LI>Each time the filter is invoked with the <CODE>start</CODE>
414tags,
415it will add a <CODE>START</CODE> record to the end of the accounting file.</LI>
416<LI>When it is invoked with the <CODE>end</CODE> option,
417it will update the accounting file and add an <CODE>END</CODE> entry.</LI>
418<LI>It will handle aborted jobs by looking for jobs with have a <CODE>START</CODE>
419entry and a following <CODE>start</CODE> line and assuming that they
420progressed to the point of starting print operations,
421i.e. - the printer page counter was accessed and reported.
422It will then look for the next <CODE>START</CODE> entry with a
423following <CODE>start</CODE> line,
424and assume that the pages between the two points were used by the
425aborted job.</LI>
426</OL>
427<P>Administrators can use this script as a starting point for more advanced
428accounting.
429For example,
430rather than just recording the information,
431at the job start the script can query either a local database
432or a remote server to see if the user has permissions to access the printer.
433At the end of the job or when an <CODE>END</CODE> line is written to the
434accounting file,
435the local database or remote accounting server can be updated.
436<HR>
437<A HREF="LPRng-HOWTO-16.html">Next</A>
438<A HREF="LPRng-HOWTO-14.html">Previous</A>
439<A HREF="LPRng-HOWTO.html#toc15">Contents</A>
440</BODY>
441</HTML>
Note: See TracBrowser for help on using the repository browser.