Netprint perl script from Handbook doesn't work

Jonathan McKeown jonathan+freebsd-questions at hst.org.za
Thu Sep 25 07:37:00 UTC 2008


On Wednesday 24 September 2008 17:12:36 Dan Nelson wrote:
> In the last episode (Sep 24), Andy Kosela said:
> > The netprint perl script provided in the Handbook (9.4.3.2) is not
> > working.. or am I missing something:
> >
> > plotinus:~> cat new.txt | lp.sh
> > Can't contact 10.10.21.12: Address family not supported by protocol
> > family at /usr/local/libexec/netprint line 21.
>
> Can you telnet to that ip address ("telnet 10.10.21.12 9100", or
> whatever port you're using)?
>
> > plotinus:> cat /usr/local/libexec/netprint
> > #!/usr/bin/perl
> > #
> > #  netprint - Text filter for printer attached to network
> > #  Installed in /usr/local/libexec/netprint
> > #
> > $#ARGV eq 1 || die "Usage: $0 <printer-hostname> <port-number>";
> >
> > $printer_host = $ARGV[0];
> > $printer_port = $ARGV[1];
> >
> > require 'sys/socket.ph';
> >
> > ($ignore, $ignore, $protocol) = getprotobyname('tcp');
> > ($ignore, $ignore, $ignore, $ignore, $address)
> >    = gethostbyname($printer_host);
> >
> > $sockaddr = pack('S n a4 x8', &AF_INET, $printer_port, $address);
> >
> > socket(PRINTER, &PF_INET, &SOCK_STREAM, $protocol)
> >
> >    || die "Can't create TCP/IP stream socket: $!";
> >
> > connect(PRINTER, $sockaddr) || die "Can't contact $printer_host: $!";
> > while (<STDIN>) { print PRINTER; }
> > exit 0;
>
> Wow.  That's a really complicated way to say
>
>   #! /bin/sh
>   nc $1 $2

It's also ugly (and very old-fashioned) Perl. Starting at (and replacing) the 
require 'sys/socket.ph' line (which is Perl 4, I think), it should look more 
like this (with appropriate error-checking added):

use Socket;
my $proto = getprotobyname('tcp');
socket(my $socket, PF_INET, SOCK_STREAM, $proto);
my $sock_in = sockaddr_in($printer_port, inet_aton($printer_host));
connect($socket, $sock_in);

Although this rewrite removes the need, if you want in general to ignore some 
of the return values of a function returning a list, the usual way is to 
assign to undef:

(undef, undef, undef, undef, $address) = gethostbyname($printer_host);

Although when you're throwing away that many, it makes more sense to index the 
returned list in the same way you would index an array:

$address = (gethostbyname($printer_host))[4] # returns 5th element

I really should submit a doc patch for this (incorporating Dan's sterling 
suggestion of nc $1 $2).

Jonathan


More information about the freebsd-questions mailing list