На старые принтера HP
Некоторые принтера (и печатающие сетевые "черные ящики") поддерживают только никуда не годные маленькие непротокольные соединения включая чистые TCP соединения. Примечательными в этой категории являются ранние модели карт JetDirect (включая некоторые карты JetDirectEx). В основном для печати на принтер вы должны открыть соединение TCP на принтер на указанный порт (обычно 9100 или 9100, 9101 и 9102 для трех-портовых принтеров) и запихнуть свое задание печати в принтер. LPRng имеет встроенную поддержку для выдачи заданий печати на произвольные порты TCP, но при использовании BSD lpd это не так легко. Это может быть выполнено на Perl:
Интерфейс PDQ использующий netcat должен выглядеть примерно так:
interface tcp-port-0.1 {
help "Это один из первых интерфейсов поддерживаемых стандартными сетевыми принтерами и серверами печати. Устройство просто ожидает TCP-соединения на определенном порту, и посылает данные с любого соединения на принтер.\nЭтот интерфейс требует наличия программы netcat (\"nc\")."
required_args "REMOTE_HOST"
argument { var = "REMOTE_HOST" desc = "Удаленная машина" help = "Имя или IP-адрес сервера печати." }
argument { var = "REMOTE_PORT" def_value = "9100" desc = "Удаленный порт" help = "Это номер порта TCP сервера печати, на который должно посылаться задание. Большинство карт JetDirect, и их вариантов принимают задания на порту 9100 (или 9101 для порта номер 2, и т.п.)." }
requires "nc"
# nc заканчивает работу после 45 секунд отсутствия сетевой активности: # он не завершает работу после приема EOF как мы того желаем. send_exec { cat $OUTPUT | nc -w 45 $REMOTE_HOST $REMOTE_PORT }
}
В случае отсутствия этой программы, она может быть реализована другими способами, например на языке Perl, используя нижеприведенную программу. Или для большей производительности используйте программу netcat ("nc"), которая выполняет то же самое. Большинство дистрибутивов должны иметь эту программу в своем составе.
#!/usr/bin/perl # Спасибо Dan McLaughlin за написание оригинальной версии этого скрипта # (А также Jim W. Jones за помощь мне при внесении исправлений ;)
$fileName = @ARGV[0];
open(IN,"$fileName") die "Can't open file $fileName";
$dpi300 = "\x1B*t300R"; $dosCr = "\x1B&k3G"; $ends = "\x0A";
$port = 9100 unless $port; $them = "bach.sr.hp.com" unless $them;
$AF_INET = 2; $SOCK_STREAM = 1; $SIG{'INT'} = 'dokill'; $sockaddr = 'S n a4 x8';
chop($hostname = `hostname`); ($name,$aliases,$proto) = getprotobyname('tcp'); ($name,$aliases,$port) = getservbyname($port,'tcp') unless $port =~ /^\d+$/;; ($name,$aliases,$type,$len,$thisaddr) = gethostbyname($hostname); ($name,$aliases,$type,$len,$thataddr) = gethostbyname($them); $this = pack($sockaddr, $AF_INET, 0, $thisaddr); $that = pack($sockaddr, $AF_INET, $port, $thataddr);
if (socket(S, $AF_INET, $SOCK_STREAM, $proto)) { # print "socket ok\n"; } else { die $!; } # Задать адрес сокету. if (bind(S, $this)) { # print "bind ok\n"; } else { die $!; }
# Вызвать сервер.
if (connect(S,$that)) { # print "connect ok\n"; } else { die $!; }
# Установить буферизацию для сокета.
select(S); $| = 1; select(STDOUT);
# print S "@PJL ECHO Hi $hostname! $ends"; # print S "@PJL OPMSG DISPLAY=\"Job $whoami\" $ends"; # print S $dpi300;
# Избежать блокировки при fork.
if($child = fork) { print S $dosCr; print S $TimesNewR;
while (<IN>) { print S; } sleep 3; do dokill(); } else { while(<S>) { print; } }
sub dokill { kill 9,$child if $child; }