1#!/usr/local/plan9/bin/rc
2# This program enqueues the file to be printed and starts the daemon, when necessary.
3# Make changes to /sys/src/cmd/lp/lp.rc.  Changes made directly to /rc/bin/lp will be lost.
4
5# rfork en	# so that environment and name space are not polluted
6#
7# put 'fn sigexit { rm /tmp/lpcrap; exit interrupted }' into processes that create /tmp/lpcrap.
8
9ifs='
10'		# set ifs in case it is munged in user's environment
11
12LPLIB=$PLAN9/lp		# lp scripts directories and configuration file are here
13LPBIN=$PLAN9/bin/lpbin		# lp specific binaries are here
14LPSPOOL=$LPLIB/queue		# lp queues
15LPLOGDIR=$LPLIB/log		# lp logs
16
17# $LPLIB/bin/lpscratch || exit $status
18LPTMP=/var/tmp
19
20path=($PLAN9/bin /usr/local/bin /usr/bin /bin $LPLIB/bin $LPBIN)
21
22USAGE='usage:	lp [-d printer] [-p process] [options] [files]
23		lp [-d printer] -q
24		lp [-d printer] -k jobnos
25
26		options include:
27		-H		no header
28		-L		landscape mode
29		-c<n>		make <n> copies
30		-f<font.size>	specify font and size
31		-i<src>		take media from <src> input bin
32		-l<n>		print <n> lines per logical page
33		-m<n>		magnify <n> times
34		-n<n>		print <n> logical pages per physical page
35		-o<i-j,k>	print only pages i-j and k
36		-r		reverse pages
37		-x<n>		x page offset in inches
38		-y<n>		y page offset in inches'
39
40umask 000	# this doesn't work in plan 9
41THIS_HOST=$sysname
42if(~ $#THIS_HOST 0)
43	THIS_HOST=`{hostname | sed 's/\..*//'}
44if(~ $#THIS_HOST 0)
45	THIS_HOST=gnot
46
47# Helpers for scripts
48
49# Run a program from a /sys/lib/lp subdirectory.
50fn lpsub {
51	_LPSUB=$1
52	shift
53	_LPCMD=$1
54	shift
55	@{path=($LPLIB/$_LPSUB $path); $LPLIB/$_LPSUB/$_LPCMD $*}
56}
57
58# Run a command with standard input from file $1.
59# If $1 is '', use the current standard input.
60fn lpinput {
61	_LPFILE=$1
62	shift
63	if(~ $_LPFILE '') $*
64	if not $* < $_LPFILE
65}
66
67LPMACHID=$THIS_HOST
68THIS_USERID=$user
69LPUSERID=$THIS_USERID
70LPLOC=''
71
72# Set default printer to be output device
73if (~ $#LPDEST 0 && test -f $LPLIB/default)
74	LPDEST=`{cat $LPLIB/default}
75
76# Parse option parameters
77
78XOFF=''
79YOFF=''
80POINT=''
81FONT=''
82LINES=''
83LAND=''
84COPIES=''
85MAG=''
86NPAG=''
87OLIST=''
88IBIN=''
89REVERSE=''
90NOHEAD=''
91TRAY=''
92# remove FLAGS from environment
93FLAGD=();FLAGH=();FLAGL=();FLAGM=();FLAGQ=();FLAGc=();FLAGd=();FLAGf=()
94FLAGi=();FLAGk=();FLAGl=();FLAGm=();FLAGn=();FLAGo=();FLAGp=();FLAGq=()
95FLAGr=();FLAGt=();FLAGu=();FLAGx=();FLAGy=()
96# Process options
97eval `{getflags DHLM:1QRc:1d:1f:1i:1kl:1m:1n:1o:1p:1qrt:1u:1x:1y:1 $*}
98if (! ~ $status '') exit $status
99if (! ~ $#FLAGD 0) { DEBUG=1; flag x + }; if not { DEBUG=''; flag x - }
100if (! ~ $#FLAGH 0) NOHEAD=1; if not NOHEAD=''
101if (! ~ $#FLAGL 0) LAND=1; if not LAND=''
102# originating machine id (for information only)
103if (! ~ $#FLAGM 0 && ~ $LPUSERID daemon) LPMACHID=$FLAGM
104if (! ~ $#FLAGQ 0) QONLY=1; if not QONLY=''
105if (! ~ $#FLAGR 0) RESET=1; if not RESET=''
106if (! ~ $#FLAGc 0) COPIES=$FLAGc; if not COPIES=1
107if (! ~ $#FLAGd 0) {
108	switch ($FLAGd) {
109	case '?'; exec awk 'BEGIN{printf "device       location  host                 class\n"}
110			/^[^#]/	{printf "%-12s %-9s %-20s %s\n", $1, $2, $3, $6 }' $LPLIB/devices
111	case *; LPDEST=$FLAGd
112	}
113}
114if (! ~ $#FLAGf 0) eval `{echo $FLAGf | sed -e 's/([^.]*)\.([0-9.]*)/FONT=\1;POINT=\2;/'}
115if (! ~ $#FLAGi 0) IBIN=$FLAGi
116if (! ~ $#FLAGk 0) KILLFLAG=1; if not KILLFLAG=0
117if (! ~ $#FLAGl 0) LINES=$FLAGl
118if (! ~ $#FLAGm 0) MAG=$FLAGm
119if (! ~ $#FLAGn 0) NPAG=$FLAGn
120if (! ~ $#FLAGo 0) OLIST=-o$FLAGo
121if (! ~ $#FLAGp 0) {
122	switch (FLAGp) {
123	case '?';exec ls $LPLIB/process
124	case *;	LPPROC=$FLAGp
125	}
126}
127if (! ~ $#FLAGq 0) LPQ=1; if not LPQ=0
128if (! ~ $#FLAGr 0) {
129	switch ($REVERSE) {
130	case '';REVERSE=1
131	case 1;	REVERSE=''
132	}
133}
134if (! ~ $#FLAGt 0) TRAY=$FLAGt
135# originating user id
136if (! ~ $#FLAGu 0) LPUSERID=$FLAGu
137if (! ~ $#FLAGx 0) XOFF=$FLAGx
138if (! ~ $#FLAGy 0) YOFF=$FLAGy
139
140if (~ $#LPDEST 0) {
141	echo 'Set environment variable LPDEST or use the
142''-d printer'' option to set the destination.' >[1=2]
143	exit 'LPDEST not set'
144}
145if (~ $LPDEST */*) {	# handles MHCC destinations like mh/lino
146	LPLOC=`{echo $LPDEST|sed 's/^(.*)\/(.*)/\1/'}
147	LPDEST=`{echo $LPDEST|sed 's/^(.*)\/(.*)/\2/'}
148}
149
150# Fetch device info from devices file.
151
152LPDLINE=`{grep '^'$LPDEST'[ 	]' $LPLIB/devices}
153if (! ~ $status '') {
154	echo 'device '$LPDEST' is not in '$LPLIB'/devices' >[1=2]
155	exit 'LPDEST is bad'
156}
157LOC=$LPDLINE(2)
158DEST_HOST=$LPDLINE(3)
159OUTDEV=$LPDLINE(4)
160SPEED=$LPDLINE(5)
161LPCLASS=$LPDLINE(6)
162if (~ $#LPPROC 0) LPPROC=$LPDLINE(7)
163SPOOLER=$LPDLINE(8)
164STAT=$LPDLINE(9)
165KILL=$LPDLINE(10)
166DAEMON=$LPDLINE(11)
167SCHED=$LPDLINE(12)
168
169# On to the actual command-line processing.
170
171# lp -k
172if (~ $KILLFLAG 1)
173	switch ($KILL) {
174	case -
175		echo kill option not available on $LPDEST >[1=2]
176		exit 'kill n/a'
177	case *
178		lpsub kill $KILL $*
179		exit $status
180	}
181
182# lp -q
183if (~ $LPQ 1)
184	switch ($STAT) {
185	case -
186		echo queue status option not available on $LPDEST >[1=2]
187		exit 'stat option not available'
188	case *
189		lpsub stat $STAT $* </dev/null
190		exit $status
191	}
192
193# lp
194DATE=`{date}
195LPLOG=$LPLOGDIR/$LPDEST
196if (! test -e $LPLOG) {
197	>$LPLOG
198	chmod +rwa $LPLOG >[2]/dev/null
199}
200
201if (~ $RESET '') {	# lp file
202	switch ($SPOOLER) {
203	case -;	echo spooler does not exist for $LPDEST >[1=2]
204		exit 'no spooler'
205	case *;	path=($LPLIB/spooler $path)
206		if (~ $#* 0) $SPOOLER
207		if not $SPOOLER $*
208	}
209}
210
211if not {	# lp -R
212	echo restarting daemon for printer $LPDEST >[1=2]
213	echo `{date} restarting daemon >>$LPLOG
214	UNLOCK $LPSPOOL/$LPDEST
215	sleep 5
216}
217
218# run daemon
219if (~ $QONLY '') {	# not lp -Q
220	if (! ~ $DAEMON -) {
221		lpsub daemon $DAEMON $* >>$LPLOG >[2=1] &
222	}
223}
224exit ''
225