Every now and then people post a "question" about printing to this
mailng list which exposes their confusion. I am putting this email
together so that anybody capable of searching through the mailing list
can at least have terminology straight before asking for help.
Information presented here is in the public domain and I make no claims
of posting anything new.


Table of Contents:

1. Print spooling overview: LPD, LPRng, CUPS
2. Common network printing protocols: LPD, IPP, JetDirect
3. Printer driver. 
4. Input filters
5. ASCII and page description language PostScript(PS)
6. PostScript Printer Description (PPD) files 
7. Printer recommendations
8. Code contribution


1. What is a print spooling? Why is needed?

A print spooler is a program/daemon that accepts print jobs from a
program or network. It typically consist of two programs: a print
spooler daemon that sends jobs to a printer and a command to submit
print jobs to the spooler daemon. In general spooler is not needed on
an operating system that allows a single user to perform only one task
at a time as long as that single user doesn't try to send multiple
documents to the printer at the same time.

However, UNIX has been designed multitasking, multiuser computer
operating systems. Imagine that my wife and I send two documents to a
printer at the same time. Her documents gets there first and gets
printed. My document losses the race and my job is rejected because the
device is busy. I wait a few minutes and I sent my document again but
this time my daughter outrace me and her document get printed and not
mine. Now imagine the organization with hundreds of users and only a few
printers. This is exactly why we need a spooler program/daemon which
will listen for the incoming printing requests, stores them in a spool
queue, and then sends them to a printer when it becomes available.

The original Berkeley spooling system is The Line Printer Daemon
protocol/Line Printer Remote protocol (or LPD) and it is available on
any default OpenBSD installation. LPD is super simple and writing a lpd
daemon should not be a too difficult for an undergraduate CS student.
For those of us who are old enough to remember legendary Richard Stevens

https://www.oreilly.com/library/view/advanced-programming-in/9780321638014/ch21.html

As the computer technology and printing proliferated among common folks
like me some system admins felt the need to develop more complex
queueing policies. People start hitting limitations of LPD and
eventually Dr. Patrick Powell felt compel to rewrite a new spooler
program/daemon which will be more capable of complex printing policies
and easier to incorporate drivers and input filters (please see below)
so the UNIX world got

LPRng

http://web.mit.edu/ops/services/print/Attic/src/doc/LPRng-HOWTO.html#toc2

as the project grew and never became truly financially viable eventually
was replaced with newer and super complex spooling system called CUPS

https://www.cups.org/documentation.html

Now the true CUPS claim to fame is the support for the new Internet
printing protocol (IPP).


2. What are network printing protocols?

>From its inception UNIX was designed to a distributed computing
environment. A bunch of developers will use dumb terminals to connect to
the same computer and do some work. At the same time it became possible
for printers to be first class citizens on the LAN. LPD is not just a
spooling system it is also a network protocol spoken by the daemon
itself but also spoken by any decent quality printer. The major
limitation of LPD that is primarily single direction protocol.

As printer became more sophisticated and more like a computers than
microcontroller boards it became obvious that one could ask the printer
about the level of the toner or the state of key mechanical components
(drum comes to mind). Thus we got IPP. Actually, we got more than that.
Most so called workgroup printers come with a built in CUPS server. 

That is not it. Manufacturer came up with many different network
protocols. I will mention the one I use JetDirect. From wikipedia page:
AppSocket, also known as Port 9100, RAW, JetDirect, or Windows TCPmon is
a protocol that was developed by Tektronix. It is considered as 'the
simplest, fastest, and generally the most reliable network protocol used
for printers


3. What are the printer drivers? Do I need them.

In "old good times" all printers were capable of printing raw ASCII
code. You don't need any drivers to print raw ASCII text on most
business grade printers. As printers became more sophisticated users
wanted to print more complicated things like pictures as oppose to ASCII
art. One of earliest examples of page description language was stack
language developed by Adobe called PostScript (to be discussed more
later in this document). A high quality (expensive in old times)
printers came with built in interpreters for PostScript language. You
don't need a driver to print on such printers. 

Then various manufacturers came with the reduced set of instructions
like Printer Command Langauge (PCL). You do need a driver to print to
such printer. The good news is that many such drivers are freely
available in

https://www.ghostscript.com/

but the story doesn't end there. Printer manufacturers came up with a
novel business concept for mass market. They decided to give crappy
printers essentially for free, offload all the work to OS/consumers'
computers and make a kill by selling ink. You DO need proprietary
drivers to print on such devices and they are not useful if you are
trying to print from your OpenBSD desktop unless you are planning to
smack your co-worker with such a device during a friendly office brawl.
High quality open source drivers beside vulnerable GhostScript are part
of packages like

http://gimp-print.sourceforge.net/

or 

https://developers.hp.com/hp-linux-imaging-and-printing

or even for crappy Samsung printers which need firmware

http://splix.ap2c.org/

All these drivers are already ported to OpenBSD and maintained single
handedly for over 10-15 years by Anthony Jacotot.



4. What are the Input filters? Do I need them?

No you don't need them. As long as you buy a decent quality printer
which some with the built in PostScript interpreter and you never send
anything to that printer except the PostScript file you are golden. For
the rest of us which are less perfect various input filters come to the
rescue. The most primitive input filter is just a shell script or Perl
script which parses your file and decides on the type of the file. Than
it calls an auxiliary program which converts the file to the PostScript
language. Finally if the printer doesn't speak complete PostScript but
some kind reduced version like PCL it calls the driver to convert the
PostScript stream into the language spoken by printer (PCL is very
common) before sending it to the printer. This is the simplest possible
example of such a filter is shamelessly stollen from NetBSD
documentation

#!/bin/sh
# Treat LF as CR+LF
printf "\033&k2G" || exit 2
# Print the postscript file
/usr/pkg/bin/gs -dSAFER -dBATCH -dQUIET -dNOPAUSE -q -sDEVICE=cdj550 \
-sOutputFile=- -sPAPERSIZE=a4 - && exit 0
exit 2



If you don't know what is your printer capable of maybe you should learn
a bit of SNMP protocol.

  snmpwalk -c public 10.0.1.19 .1.3.6.1.4.1.2699.1.2

where 10.0.1.19 is the IPv4 of your network printer. 
This is one of my favorite printing posts and Greg Woods really knows
what he is talking about

https://marc.info/?l=netbsd-users&m=159389498001287&w=2

I wormly recommend searching mailing lists archives for his posts.

I would like to finish this section mentioning a few well known input
filters which are not exactly one liners.

http://ports.su/print/apsfilter

or much newer which I use

https://wiki.linuxfoundation.org/openprinting/database/foomatic

Be careful with the last one foomatic people disabled the support for
LPD a few years ago. That is why whe have to have a work around. Make
sure you read pkg-readme which comes with cups-filters (yes they even
renamed they stupid filter after the CUPS). 


5. ASCII and page description language PostScript(PS)

By this section we already mentioned that all decent quality printers
should be able to print ASCII code without any drivers. As of page
description language PostScript(PS) I would just say that is a true
stack based programming language (I think it is inspired by my favorite
programming language Forth). 


https://www.adobe.com/jp/print/postscript/pdfs/PLRM.pdf

In "old good times" while growing up behind the Iron curtain I as many
other people learnt to hack PostScript files by hand to make them
printable to the crappy printers (we could not effort to buy good once
from the West). 

It is also an excellent tool for teaching geometry 

http://www.math.ubc.ca/~cass/courses/m308-7b/ch1.pdf

but these days I only teach my own daughters. A "common trick" in old
times would be a getting a PostScript module from a junk yard

https://www.ebay.com/p/1625921313

and putting it in the cheap printer, instantaneous converting it to
the decent quality printer.



6. What the hack are PostScript Printer Description (PPD) files?

Those are not drivers? They are simple see below text files describing 
capabilities of your printer to the Input filter. 

*%================================================
*%      Copyright(C) 2005 Brother Industries, Ltd.
*%      "Brother HL-5250DN BR-Script3"
*%================================================

*%==== General Information Keywords ========================
*FormatVersion: "4.3"
*FileVersion: "1.03"
*LanguageEncoding: ISOLatin1
*LanguageVersion: English
*Manufacturer: "Brother"
*PCFileName: "BR5250_2.PPD"
*Product: "(Brother HL-5250DN series)"
*PSVersion: "(3010.106) 5"
*ShortNickName: "Brother HL-5250DN BR-Script3"
*ModelName: "Brother HL-5250DN BR-Script3"
*NickName: "Brother HL-5250DN BR-Script3"
*1284DeviceID: "MFG:Brother;MDL:HL-5250DN
series;CMD:PJL,PCL,PCLXL,POSTSCRIPT;"

*%==== Basic Device Capabilities =============
*LanguageLevel: "3"
*TTRasterizer: Type42
*ColorDevice: False
*DefaultColorSpace: Gray
*FileSystem: True
*?FileSystem:"
save 
        /devname (%disk0%) def 
        /ret false def 
        0 1 7{ 
                devname exch 48 add 5 exch put 
                devname devstatus { 
                        0 ne {/ret true def}if 
                        pop pop pop pop pop pop pop 
                }if 
        }for 
        ret {(True)}{(False)} ifelse = flush 
restore 
" 
*End

*Throughput: "28"
*FreeVM: "6050000"

*%==== Emulations and Protocols ==========
*Protocols: PJL TBCP

*SuggestedJobTimeout: "0"
*SuggestedWaitTimeout: "300"
*PrintPSErrors: True


7. Could you give me some recommendation for a printer?

Sure. I like Brother monochromatic laser printers like this one.

https://www.amazon.com/Brother-HL-5250DN-Network-Printer-Duplex/dp/B000BQ535K

They speak PostScript or at least PCL6. They come with a built in CUPS
server (you will need to use CUPS on your OpenBSD desktop if you want to
print that way) but they also support DirectJet Protocol

oko# cat /etc/printcap
# Remote printer must use jetdirect since foomatic-rip doesn't speak LPD
rp|HL-5250DN:\
        :lp=9100@192.168.3.15:\
        :if=/etc/foomatic-rip/script_brother.sh:\
        :sh:sd=/var/spool/output/brother:\
        :lf=/var/log/lpd-errs:

oko# cat /etc/foomatic-rip/script_brother.sh
#!/bin/sh

/usr/local/bin/a2ps -BRq --columns=1 -o - | \
        /usr/local/bin/foomatic-rip -P HL-5250DN --ppd \
/etc/foomatic-rip/direct/brother-hl-5250dn-postscript-brother.ppd


If you want to print Duplex don't forget to embed 


%!
<</Duplex true>>setpagedevice

at the beginning of a PostScript file you are trying to print

Or for example using a2ps filter from Xpdf. 

predrag@oko$ head .xpdfrc
# Set the default PostScript file or command.
psFile                 "|a2ps -Prp -1 -s2"
psPaperSize            letter

# launch URLs in Firefox
urlCommand     "firefox-esr '%s'"

# launch movie annotations in mplayer
movieCommand "/usr/local/bin/mplayer %s"


In "old good times" HP priters were the Gold standard. HP LaserJet 4
lasted me for 15 years and was still usable but getting a bit slow for
my work flow. 



8. Code contribution?

You read this post and you feel like you could contribute to UNIX
printing. Why not hack on the LPD itself. At some point Eric Faurot was
working on the new lpd server for OpenBSD

https://undeadly.org/cgi?action=article;sid=20180509184829


Why don't go step further and implement IPP protocol inside LPD? Who
need CUPS?



Most Kind Regards,
Predrag Punosevac

Reply via email to