Date: Wed, 7 Mar 2001 13:53:58 +1000 (EST) From: <andrew@ugh.net.au> To: <questions@freebsd.org> Subject: Printing loops Message-ID: <Pine.BSF.4.32.0103071230230.34937-100000@starbug.ugh.net.au>
next in thread | raw e-mail | index | archive | help
Hi,
I've just got printing going on an HP LaserJet 4050N and I thought I'd
send this to the archives to make it quicker for others trying the same
thing.
The LaserJet runs its own lpd server. It seems there are 2 virtual
printers controlled by the lpd server...RAW which accepts postscript jobs
and text which accepts text jobs.
I set up 2 printers in my printcap file...blah-ps and blah-text.
I set up a perl script as the if filter for blah-ps that checks the first
two chars of the print job and if they aren't %! runs lpr -Pblah-text and
writes the data to that process. If they are %! it just copies its input
to stdout.
I found what might be a bug in lpd at this point. If a filter produces no
output (because it sent all the data to lpr -Pblah-text) lpd tries to
reprint the job even if the filter exited with the exit value 0. I have
worked around that by guarenteeing output.
I attach below my printcap entries and the perl script.
Thanks,
Andrew
--
lp|blah|blah-ps|HP LaserJet 4050N (Blah):\
:sh:\
:if=/usr/local/libexec/hpfilter:\
:sd=/var/spool/lpd/blah-ps:\
:lp=:\
:mx#0:\
:rp=RAW:\
:rm=blah.domain.au:
text|blah-text|HP LaserJet 4050N (Blah):\
:sh:\
:sd=/var/spool/lpd/blah-text:\
:lp=:\
:mx#0:\
:rp=text:\
:rm=blah.domain.au:
#!/usr/bin/perl -w
# $Id$
# Exit values:
#
# 0 - Printed fine
# 1 - Try to reprint
# 2 - Fatal error - give up
$block_size = 2048; # bytes to read/write at a time
$lpr = '/usr/bin/lpr'; # path to lpr
$text_print = 'blah-text'; # name of text printer
# Catch SIGPIPE (in case lpr -P fails for text files)
$SIG{'SIGPIPE'} = \&sigpipe;
# Use syslog to report problems
use Sys::Syslog qw(:DEFAULT setlogsock);
# open log
setlogsock('unix');
openlog('hpfilter', 'pid', LOG_LPR);
syslog(LOG_DEBUG, 'starting up');
# Get the first 2 bytes
if (! defined(read(STDIN, $buff, 2))) {
syslog(LOG_ERR, 'first read failed: %m');
exit(1); # might work next time
}
if ($buff ne '%!') {
syslog(LOG_DEBUG, 'non ps file, swapping modes');
# Not a PS job so send to text printer. To keep lpd happy we have to
# produce some output however so we'll send the following PS job.
print('%!PS');
$text_job = 1; # remember we are printing text
if (! open(STDOUT, "|$lpr -P$text_print")) {
syslog(LOG_ERR, 'fork failed: %m');
exit(1); # might work next time
}
} else {
# PS file
$text_job = 0;
}
# print first 2 chars
print($buff); # of course it wont fail...
# print everything else
while (defined($rv = read(STDIN, $buff, $block_size)) and ($rv > 0)) {
print $buff or do {
syslog(LOG_ERR, 'print failed: %m');
exit(1); # might work next time
};
}
if ($text_job) {
# If we duped STDOUT we should close it and collect the return value
if (! close(STDOUT)) {
if ($! == 0) {
# lpr exited with non 0 status
syslog(LOG_ERR, 'lpr exited with code ' . ($? >> 8));
exit(2); # probably the text printer doesn't exist
} else {
# close failed (something is very wrong)
syslog(LOG_ERR, 'close failed: %m');
exit(1); # might work next time
}
}
}
syslog(LOG_DEBUG, 'shutting down');
# we have finished logging now
closelog();
# everything worked
exit(0);
# signal handler for SIGPIPE (something went wrong writing to lpr for a text
# job)
sub sigpipe {
syslog(LOG_ERR, 'received SIGPIPE'); # is this safe?
exit(2); # or this for that matter
}
To Unsubscribe: send mail to majordomo@FreeBSD.org
with "unsubscribe freebsd-questions" in the body of the message
Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?Pine.BSF.4.32.0103071230230.34937-100000>
