rlpr(1)

rlpr(1) β€” the UNIX Reference Manual, but make it make sense πŸ’–

okay bestie, pull up a chair πŸͺ‘ because this is rlpr, aka remote off-line print, and she is lowkey the glow-up the printing world needed.


✨ NAME ✨

rlpr β€” remote off-line print πŸ–¨οΈ


🌸 SYNOPSIS 🌸

rlpr [-Hprinthost] [-Pprinter] [-Xproxyhost] [-#copies] [-Cclass]
[-Jjob] [-Ttitle] [-Uuser] [-i[indent]] [-wwidth]
[-1234cdfghlmnopqrstvNV] [--debug] [--port=port] [--hostname=hostname]
[--send-data-first] [--timeout=seconds] [--tmpdir=dir] [--verbose]
[--windows] [file ...]

πŸ¦‹ DESCRIPTION πŸ¦‹

so rlpr uses TCP/IP to yeet print jobs straight to lpd servers literally anywhere on a network. and the way that lpr makes you pre-register every remote printer on your local system (traditionally through /etc/printcap)? yeah no, rlpr said not me being that extra. she doesn't need that at all, which makes her way more flexible and needs like, basically zero administration. slay. πŸ’…

you can use rlpr anywhere you'd use a traditional lpr, and she's backwards compatible with traditional BSD lpr. if rlpr gets invoked as lpr, she preserves all known lpr semantics, periodt. πŸ‘‘

you can install and use rlpr in two different ways (and fr fr, the same guidelines apply for rlpq(1) and rlprm(1)):

  1. Ideally, if the rlpr client can be installed setuid root, then rlpr can interact directly with other lpd's on the network. peek the EXAMPLES below for the tea. ✨
  2. If rlpr cannot be installed setuid root (say, because you're not the administrator on the machine you need to print from 😭), then rlpr can be used alongside an rlprd proxy agent. check out CONFIGURING A PROXY and EXAMPLES below for the details.

πŸ’œ MOTIVATION πŸ’œ

traditional Berkeley lpr has one major drawback: the mortal user (a regular human, not root, tragic) cannot lpr to a printer that isn't explicitly listed in the /etc/printcap file.

and this is especially annoying when there's a central UNIX server that a bunch of users (on their own desktop computers) connect to for their daily work. if those users want to print files from the central server to their personal machines (assuming they even have a local lpd), they literally can't do it unless the central server's /etc/printcap gets edited to contain the host and printer of every single user on the network. and that, bestie, scales horribly. πŸ’€


πŸŽ€ OPTIONS πŸŽ€

Environment/Setup

  • --debug β€” print gobs and gobs of debugging information. like, an unhinged amount. πŸ›
  • -N, --no-bind β€” don't try to bind to a privileged port before connecting to lpd. please please please see CONFIGURING A PROXY below for the info on when to use this one, it matters. 🫢
  • --port=number β€” pick an alternate port (instead of 7290) to connect to, if you're using rlprd. usually not needed ngl.
  • -H, --printhost=host β€” select the host to print to (used with -P).

instead of using -H, you can just specify the hostname directly by including it with the printer name using the printer@hostname syntax. iykyk. ✨

  • -P, --printer=printername, --queue=printername β€” select the printer to print to (used with -H).
  • -X, --proxyhost=proxyhost β€” select the proxy host to use, if you need one.
  • --timeout=seconds β€” set the inactivity timer. if the connection hangs for more than seconds seconds, then rlpr will give up. use the special value -1 to wait forever (main character patience πŸ’…). default timeout is 3 seconds.
  • --tmpdir=tmpdir β€” use tmpdir for temporary files (by default, /tmp is used).
  • -V, --version β€” print version and exit. short and sweet.
NOTE: instead of specifying the printer, printhost, or proxy variables on the commandline, you can set up defaults through either environment variables or rlprrc configuration files. for info on personal or system-wide rlprrc files, see rlprrc(5). πŸ“š

Behavior

  • -#, --copies=copies β€” print copies copies of each document. use sparingly bestie, printers aren't copiers. πŸ™ˆ
  • -m, --mail β€” send mail upon completion. πŸ“¬
  • -q, --quiet, --silent β€” quiet mode, stay quiet (except for fatal errors). the introvert setting.
  • -r, --remove β€” remove file after printing. poof, gone. 🧚
  • -s β€” Ignored (provided for compatibility). she's just there for the vibes.
  • --send-data-first β€” send the "data" transaction before the "control" transaction. this should never be required when rlpr is used alongside a RFC 1179 conformant lpd. however, buggy implementations exist which require these semantics, so use only when necessary. ⚠️
  • --verbose β€” verbose mode. on by default unless rlpr is invoked as lpr.
  • --windows β€” "Windows" mode, for printing multiple files to a windows-based lpd. πŸͺŸ

Document Content

  • -1 β€” print data using troff(1) R (times roman) font.
  • -2 β€” print data using troff(1) I (times italic) font.
  • -3 β€” print data using troff(1) B (times bold) font.
  • -4 β€” print data using troff(1) S (special) font.
  • -c β€” assume data has been produced by cifplot(1).
  • -d β€” assume data has been produced by tex(1).
  • -f β€” filter data assuming the start of each line has a fortran carriage control character.
  • -g β€” assume data has been produced by the BSD plot library.
  • -l β€” treat control characters as regular characters.
  • -n β€” assume data has been produced by ditroff.
  • -o β€” assume data is postscript.
  • -p β€” print data using pr(1).
  • -t β€” assume data has been produced by troff(1).
  • -v β€” assume the data contains a raster image.

Document Format

  • -i, --indent=[cols] β€” indent output by cols columns (8 by default).
  • -h, --no-burst β€” do not print burst (banner) page. no banner, no drama. 🚫
  • -w, --width=width β€” use width for page width when using pr(1).
  • -C, --class=class β€” use class for the class name on the burst page instead of the local system name.
  • -J, --job=jobname β€” use jobname for the job name on the burst page instead of the first filename in the job.
  • -T, --title=title β€” use title for the title when using pr(1) instead of the current filename.
  • -U, --user=username β€” use username for the user name on the burst page instead of the actual username. (anonymity era πŸ₯Έ)
  • --hostname=hostname β€” use hostname for the hostname on the burst page instead of the local system name.

OS-Specific Extensions

see OS-SPECIFIC EXTENSIONS below for the deets on these options.

  • --ext=os --extension=os β€” interpret the arguments passed to --extargs as if on operating system os. currently, os must be either hpux or none.
  • --extargs="args" β€” change behavior according to OS-specific arguments listed in args.

🌈 CONFIGURING A PROXY 🌈

okay so, in situations where the rlpr client can't be installed setuid root, rlpr often cannot directly talk to an lpd, because most lpd's require that requests come from privileged ports. unfortunately, rlpr cannot "come from a privileged port" without having superuser status. and the privileged port requirement? that's part of RFC 1179. can't argue with the RFC, bestie. 😭

that said, some lpd's β€” most notably some of the ones which have shipped with Windows NT, Solaris, and NCRunix β€” do not require requests to come from a privileged port. so before you go through all the work of configuring a proxy, you should make sure one is actually required for your situation. you can check by just trying to run rlpr: if it's successful in spooling the job, you do not need to install rlpr setuid root. in that case you should pass the -N (or the more verbose --no-bind) to rlpr in the future to suppress rlpr's warning messages. πŸ’…

if your situation doesn't require a privileged port, do not use one. you can explicitly request a regular port, even when rlpr has been installed setuid root, by using the --no-bind option. this is a good idea because there are only 11 privileged ports that the RFC allows. practical implication? it limits your print requests to about 11 per every 3 minutes, which is often unacceptable. not the vibe. 🚫

the rest of this section assumes that rlpr cannot be installed setuid root in your situation, and that a remote lpd requires rlpr to connect to it from a privileged port. it requires that you or someone you know has root access to another machine on the network, so that you can use a proxy β€” known as rlprd β€” to get around the problem. πŸ•΅οΈ

rlprd works by taking lpd requests on a non-privileged port, mapping them to a privileged port, and sending them out to the real lpd. the proxy and the lpd do not need to be on the same machine. iconic. ✨

in the scenario provided in the motivation, if each user had root access on his own machine, it would be optimal for the user to start rlprd up on his own machine, in which case the proxy and the printhost are the same machine. the user would additionally have to make sure his own machine was listed in his local /etc/hosts.lpd so that his lpd would accept connections from his rlprd. 🫢

however, if the machine the user wants to print to isn't running unix (but is running an lpd) (i.e. Windows, WinNT, etc) β€” then that user can configure his lpd to accept connections from an rlprd running somewhere on the network, and use that rlprd as a proxy for rlpr. πŸ’«

for more on this mess, see rlprd(8).


⭐ EXAMPLES ⭐

WITHOUT A PROXY (rlpr is setuid root)

sun% rlpr --printer=hp4l@foo.bar.org foo.c

prints foo.c to the printer hp4l on the host foo.bar.org (assuming foo.bar.org has been configured to accept print requests from host sun in its /etc/hosts.lpd).

sun% who | rlpr --printer=hp4l@foo.bar.org

prints the output of who(1) to the printer hp4l on the host foo.bar.org.

WITH A PROXY (rlpr is a normal program)

sun% rlpr -Xfoo.bar.org --printer=hp4l@foo.bar.org foo.c

prints foo.c to the printer hp4l on the host foo.bar.org using foo.bar.org as a proxyhost. under this configuration, foo.bar.org needs to be configured to accept print requests from the proxy (itself) and not from sun. in situations where the proxy and the printhost are not the same machine, this can lead to some security holes due to the original lameness of berkeley lpd's host-based security. ⚠️

NOTE: if a proxyhost isn't specified anywhere, rlpr assumes one isn't necessary.

πŸ’€ OS-SPECIFIC EXTENSIONS πŸ’€

some vendors have added features to their BSD-based lpr products, which are upwardly compatible with lpr but incompatible with one another. to support these extensions, rlpr allows the user to indicate what operating system to emulate and provide a string of OS-specific options β€” either through commandline arguments or environment variables. πŸŽ›οΈ

note that for correct operation, these extensions should only be used when interoperating with an lpd provided by the vendor for the indicated operating system.


🌈 ENVIRONMENT VARIABLES 🌈

okay bestie, here's the tea on the env vars rlpr is literally obsessed with 🫢

  • RLPR_EXTENSION β€” tells it which operating system to interpret the OS-specific arguments relative to. like, "hey, read these args the way this OS would" πŸ’…
  • RLPR_EXTARGS β€” this is where the OS-specific arguments actually live ✨
  • RLPR_PRINTHOST β€” the default host you wanna print to, no cap πŸŽ€
  • PRINTER or LPDEST β€” sets a default printer (printqueue) to use. PRINTER gets consulted first, and then LPDEST. order matters, queen πŸ‘‘
not me also pointing out: you can set the host to print to by making printer be printer@hostname πŸ‘€ this can be more convenient than setting RLPR_PRINTHOST, but heads up β€” it will confuse the traditional BSD print commands 😭 so like, pick your battles.
  • RLPR_PROXYHOST β€” specifies a proxy host to use, if necessary πŸ¦‹
  • RLPR_CONFDIR β€” if it's set, it's the directory holding the system-wide rlprrc file. by default, /etc is used 🌸
  • TMPDIR β€” if it's set, it's used for temporary files. by default, /tmp is used πŸ“

πŸ“ FILES πŸ“

the little roster of files in this girl's life:

  • ~/.rlprrc β€” personal printer/host database πŸ’–
  • $TMPDIR/cf* β€” temporary control files on local machine
  • $TMPDIR/df* β€” temporary data file for jobs from stdin
  • /var/spool/*/cf* β€” temporary control files on printhost
  • /var/spool/*/df* β€” temporary data files on printhost
  • /etc/hosts.lpd β€” host-based security on printhost πŸ”’
  • /etc/passwd β€” personal identification
  • /etc/rlprrc β€” system-wide printer/host database (by default)

πŸ‘€ SEE ALSO πŸ‘€

go read these next, iykyk:


πŸ‘‘ AUTHOR πŸ‘‘

meem <meem@gnu.org> β€” the icon, the legend, the moment πŸ’œ


πŸ’€ BUGS / LIMITATIONS πŸ’€

some evil applications have lpr hardcoded into them πŸ™ˆ that's it. that's the limitation. not me crying about it.


and that's the whole page bestie!! this was rlpr 2.04, dated 2000/12/30, living in rlpr(1) β€” iconic behavior honestly, ate and left no crumbs πŸ’…βœ¨πŸŽ€