Provided by: printbill_4.1.2-1.1_i386
printbill - fair printing billing and accounting system.
printbill is a print filter, print-billing daemon, and associated
administrative utilities which allow for accurate user-pays printing on
Linux (and possibly other Unix/Unixish systems) based on toner
consumption and page count. printbill(1) is the print filter, which
parses command-line options given to it by lprng (with some extra ones
specified in the as=... line in /etc/printcap). This does nothing but
check and send the command-line options to printbilld, via a Unix-
domain socket, which can then do one of several things depending on the
--type argument given to printbill(1).
In all cases, a copy is made of a print job when it arrives at the
front of the queue. In the case of --type accounting and --type
lazybill, the server immediately returns JSUCC or JREMOVE (as
appropriate - lazybill returns JREMOVE if the user has a quota less
than or equal to zero) to the printbill(1) filter, then calculates the
cost / page count / toner consumption afterwards. If --type is "bill",
printbilld only allows the job to be printed after the billing process
is complete and it is known whether or not the user can afford to
print. When this occurs, the user is debited the cost of the print job
and the job is printed via a secondary (non-user-accessable) print
queue (the primary queue should use /dev/null as the printer device).
This avoids the head-of-line problem, where user A prints 100 MB PS
file, user B has to wait an hour to print a 3-page LaTeX document, by
allowing jobs to be billed concurrently. The secondary print queue uses
printbill_printer(1) as the print filter (achk=true is still required)
- this only accepts jobs from the username under which printbilld and
lprng are running.
Your choice of --type bill or --type lazybill depends on how long your
users are prepared to wait for printing to start, and whether you allow
people to go into debt (maybe insist on a substantial refundable
deposit prior to printing!).
You can also specify --type quote, which just calculates the cost and
e-mails/sends a winpopup message to the user who send the print job.
See printbill(1) for details.
The actual billing process involves taking each postscript file, if
necessary pre-processing with the optional anything-to-postscript
converter, then processing it with GhostScript to standardise its
format (as Windows drivers use several different techniques for
specifying multiple copies). Next, it calculates the total number of
copies of each page which are to be printed, and extracts a modified
postscript file which contains just one copy of each page. This is then
processed once again with Ghostscript, to produce a set of PNG images
(one for each page) which are processed using percentblack(1) ,
percentcolour(1) or percent_cmy(1) programs (depending on the type of
printer, which may either be a default printer or one explicitly
described in printbillrc (5)). If billing is to be performed, the price
of the total number of copies of all pages is calculated (paper costs
plus toner/ink), and deducted from the users quota. Paper and
ink/toner consumption is logged on a per-user and per-printer basis. If
--type is "bill" and the user cannot afford the cost, or if the job was
rejected for some other reason, the user is e-mailed with a brief yet
vaguely informative message.
The configuration file printbillrc(5) includes a parameter limiting the
maximum number of concurrent billing processes. If desired, this may be
limited to one or two concurrent processes - two will be sufficient to
deal with the head-of-line problems for small systems, although more
shouldn’t cause a problem. The pool of available processes is shared
amongst all printqueues, so even if multiple printers are managed
through a single server, the total number of processes remains limited.
If all process slots are filled, pending jobs from different queues
have an equal likelyhood of getting access to the next available
The current version of printbill supports multiple printers, with per-
printer charge rates. Databases storing information about pages printed
(global, per printer and per user), toner/ink (black and colour)
consumption (per printer), quota levels per user, money paid in (global
and per user), money actually spent (global and per user) are
maintained by printbill and the related utilities.
printbilld(1) optionally writes detailed statistical information to a
stats file unique to each printer. Each line of this stats file
consists of the following information related to each file processed
(not the cumulative total of all the files in a job):
Time in seconds since the Epoch, as returned by time(2), when we
started to process this job;
User-space time spent by the printfilter in processing the job
(typically very small);
Operating system time spent by the printfilter in processing the
job (typically even smaller than user time);
child user time
User-space time spent by child processes (ghostscript and
percentcolour/black/cmy) - typically the bulk of processing
child system time
Operating system time spent by child processes (ghostscript and
Size of the current file in bytes;
Number of pages in this file;
cyan Total percentage coverage of cyan ink/toner - zero for mono
Total percentage coverage of magenta ink/toner - zero for mono
yellow Total percentage coverage of yellow ink/toner - zero for mono
black Total percentage coverage of black ink/toner - zero for CMY
printbill requires GhostScript (any version which can generate PNG
images) and libpng2. The latter is a requirement of
percentblack/percentcolour/percent_cmy, without which this program is
essentially useless. It is strongly recommended that you install an
anything-to-PostScript converter to allow things like plain text to be
printed (e.g. from text editors!)
Please see the accompanying README file for detailed installation
instructions. Chances are if you’re reading this it’s correctly
installed. Note that the program and the accompanying utilities are
written in Perl and so may be customised by the user very easily.
printbill and the accompanying utilities were written by Daniel
Franklin (firstname.lastname@example.org). The web interface was written by Phil
You can always grab the latest and greatest version from
This is fairly complex, and is now documented on its own manual
page (see printbillrc(5)).
Printer-specific overrides to printbillrc (see printbillrc(5) -
these files use exactly the same format).
This contains the message mailed to anybody who has a print job
rejected. The default message just informs the user why their
job may have been rejected, and suggests some possible remedies.
Current user quotas.
Global page count, money paid and money spent are stored here.
Printer databases - contain toner/ink usage and total pages
To do pre-printing billing, you need to have printcap entries
which look similar to this:
lp|Laser printer (scheduler queue - print to this)
:as=|/usr/sbin/printbill --type bill --printbill_secondary real
real|Laser printer (real queue - you can’t print to this)
:if=.... (if you need an input filter, e.g. PS -> PCL)
If you want --type "lazybill", "account" or "quote", you don’t
specify a --printbill_secondary (or define the ’real’ queue) -
for the "quote" type you should use lp=/dev/null.
You may add an additional print-filter, in case you don’t have a
PostScript printer. Obviously, if the scripts are located
somewhere else, adjust your printcap and config files
printbill(1) printbilld(1) printbill_configure(8),
printbill_grapher(1), percentblack(1), percentcolour(1),
percent_cmy(1), pqcheck(1), printquote(1), printbill_printer(1),
printbillrc(5), printcap(5), init_from_passwd(8), pqm(8).