A RFC 1179 não é tão difícil de escrever para um cliente, com a maior parte do trabalho sendo verificação de erro e obtendo os formatos de entrada certos.
#!/usr/bin/perl
# Lobs PostScript at a LPD printer (see RFC 1179). Poorly. Use at own risk,
use strict;
use warnings;
use IO::Socket::INET;
use Sys::Hostname qw(hostname);
my $printer_addr = shift or die "Usage: $0 host [file.ps|-]\n";
my $file = shift;
my $queue = "queue"; # may not be needed?
my $client_host = substr hostname(), 0, 31;
my $user = substr $ENV{USER}, 0, 31;
my $jobnum = sprintf "%03d", rand 1000;
my $sock = IO::Socket::INET->new(
# if server mandates this, client will need to be run as root,
# or Linux capabilities delved into
# LocalPort => 721, # RFC 1179 sec 3.1
PeerAddr => $printer_addr,
PeerPort => 515,
Proto => 'tcp',
ReuseAddr => 1,
) or die "$0: could not connect to $printer_addr: $@\n";
# o - Postscript
# f - ASCII
# l - ASCII, leaving control chars
my $control_file = <<"END_CONTROL_FILE";
H$client_host
P$user
odfA$jobnum$client_host
UdfA$jobnum$client_host
END_CONTROL_FILE
my $control_file_size = length $control_file;
my ($data_file_size, $fh);
if (defined $file and $file ne '-') {
open $fh, '<', $file or die "$0: could not open '$file': $!\n";
$data_file_size = -s $file;
} else {
$fh = \*STDIN;
$data_file_size = 0;
}
sendcmd(sprintf "%c%s\n", 0x02, $queue);
sendcmd(sprintf "%c%u %s\n", 0x02, $control_file_size, "cfA$jobnum$client_host");
$control_file .= "#!/usr/bin/perl
# Lobs PostScript at a LPD printer (see RFC 1179). Poorly. Use at own risk,
use strict;
use warnings;
use IO::Socket::INET;
use Sys::Hostname qw(hostname);
my $printer_addr = shift or die "Usage: $0 host [file.ps|-]\n";
my $file = shift;
my $queue = "queue"; # may not be needed?
my $client_host = substr hostname(), 0, 31;
my $user = substr $ENV{USER}, 0, 31;
my $jobnum = sprintf "%03d", rand 1000;
my $sock = IO::Socket::INET->new(
# if server mandates this, client will need to be run as root,
# or Linux capabilities delved into
# LocalPort => 721, # RFC 1179 sec 3.1
PeerAddr => $printer_addr,
PeerPort => 515,
Proto => 'tcp',
ReuseAddr => 1,
) or die "$0: could not connect to $printer_addr: $@\n";
# o - Postscript
# f - ASCII
# l - ASCII, leaving control chars
my $control_file = <<"END_CONTROL_FILE";
H$client_host
P$user
odfA$jobnum$client_host
UdfA$jobnum$client_host
END_CONTROL_FILE
my $control_file_size = length $control_file;
my ($data_file_size, $fh);
if (defined $file and $file ne '-') {
open $fh, '<', $file or die "$0: could not open '$file': $!\n";
$data_file_size = -s $file;
} else {
$fh = \*STDIN;
$data_file_size = 0;
}
sendcmd(sprintf "%c%s\n", 0x02, $queue);
sendcmd(sprintf "%c%u %s\n", 0x02, $control_file_size, "cfA$jobnum$client_host");
$control_file .= "%pre%"; # must pad message
sendcmd($control_file);
sendcmd(sprintf "%c%u %s\n", 0x03, $data_file_size, "dfA$jobnum$client_host");
binmode $fh;
my $buf;
while (1) {
my $buflen = sysread $fh, $buf, 4096;
die "sysread() failed: $!\n" if !defined $buflen;
last if $buflen == 0; # EOF
syswrite $sock, $buf, $buflen;
}
syswrite $sock, 0x00, 1 if $data_file_size == 0;
# meh, blocks program when input from STDIN
#my $resp;
#sysread $sock, $resp, 1;
#
#syswrite $sock, 0x00, 1;
sub sendcmd {
my $cmd = shift;
my $response;
syswrite $sock, $cmd, length $cmd;
sysread $sock, $response, 1;
chomp $cmd;
die "$0: unexpected lack of response to '$cmd'\n"
if !defined $response;
die sprintf "$0: not-zero response to '$cmd': %vx\n", $response
if $response ne "%pre%";
}
"; # must pad message
sendcmd($control_file);
sendcmd(sprintf "%c%u %s\n", 0x03, $data_file_size, "dfA$jobnum$client_host");
binmode $fh;
my $buf;
while (1) {
my $buflen = sysread $fh, $buf, 4096;
die "sysread() failed: $!\n" if !defined $buflen;
last if $buflen == 0; # EOF
syswrite $sock, $buf, $buflen;
}
syswrite $sock, 0x00, 1 if $data_file_size == 0;
# meh, blocks program when input from STDIN
#my $resp;
#sysread $sock, $resp, 1;
#
#syswrite $sock, 0x00, 1;
sub sendcmd {
my $cmd = shift;
my $response;
syswrite $sock, $cmd, length $cmd;
sysread $sock, $response, 1;
chomp $cmd;
die "$0: unexpected lack of response to '$cmd'\n"
if !defined $response;
die sprintf "$0: not-zero response to '$cmd': %vx\n", $response
if $response ne "%pre%";
}