Хабр Курсы для всех
РЕКЛАМА
Практикум, Хекслет, SkyPro, авторские курсы — собрали всех и попросили скидки. Осталось выбрать!
Если кому-то интересно будет, а с чисткой кода из статьи возиться не хочется, то вот он:
#! /usr/bin/perl
use strict;
if (!defined($ENV{'CONTENT_TYPE'}) || $ENV{'CONTENT_TYPE'} ne "application/ipp") {
print "Content-Type: text/html\n\n";
print ":-)";
exit;
}
# $d - входные данные в виде строки
# $l - длина строки входных данных
# $i - текущая позиция разбора данных
# %a - разобранные атрибуты
my ($d, $l, $i, %a) = ("", 0, 0);
binmode STDIN;
$l += read(STDIN, $d, 4096, $l) while (!eof(STDIN));
parseRequest(\$d, \$l, \$i, \%a);
my $o = ""
. substr($d, 0, 2) # version
. chr(0x00) . chr(0x00) # status
. substr($d, 4, 4) # request
. chr(0x01) # attributes
. stringAttribute(0x47, "attributes-charset", "utf-8")
. stringAttribute(0x48, "attributes-natural-language", "en-us")
. chr(0x04) # attributes
. stringAttribute(0x42, "printer-name", "PDF")
. chr(0x03) # end
. chr(0x0a)
;
print "Content-Type: text/html\n";
print "Content-Length: " . length($o) . "\n";
print "\n";
print $o;
if (defined($a{'-status'}) && $a{'-status'} == 0x02 && $i < $l) {
my @t = localtime;
my $output = sprintf("../pdf/%04d%02d%02d-%02d%02d%02d.pdf", $t[5] + 1900, $t[4], $t[3], $t[2], $t[1], $t[0]);
if (open(P, "|-", "gs", "-q", "-dBATCH", "-dNOPAUSE", "-dSAFER", "-sDEVICE=pdfwrite", "-sOutputFile=$output", "-")) {
binmode P;
print P substr($d, $i);
close P;
}
}
sub parseRequest {
my ($d, $l, $i, $a) = @_;
return if $$i >= $$l - 2;
$$a{'-version'} = (ord(substr($$d, $$i, 1)) << 8) + ord(substr($$d, $$i + 1, 1)); $$i += 2;
return if $$i >= $$l - 2;
$$a{'-status'} = (ord(substr($$d, $$i, 1)) << 8) + ord(substr($$d, $$i + 1, 1)); $$i += 2;
return if $$i >= $$l - 4;
$$a{'-request'} = parseInt(substr($$d, $$i, 4)); $$i += 4;
return if $$i >= $$l - 1;
my $what = ord(substr($$d, $$i, 1)); $$i ++;
return parseAttributes($d, $l, $i, $a) if ($what == 0x01);
}
sub parseAttributes {
my ($d, $l, $i, $a) = @_;
while ($$i < $$l) {
my $what = ord(substr($$d, $$i, 1)); $$i ++;
return if ($what == 0x03);
return parseAttributes($d, $l, $i, $a) if ($what == 0x02);
return parseAttributes($d, $l, $i, $a) if ($what == 0x04);
return if $$i >= $$l - 2;
my $key_len = (ord(substr($$d, $$i, 1)) << 8) + ord(substr($$d, $$i + 1, 1)); $$i += 2;
return if $$i >= $$l - $key_len;
my $key = substr($$d, $$i, $key_len); $$i += $key_len;
return if $$i >= $$l - 2;
my $val_len = (ord(substr($$d, $$i, 1)) << 8) + ord(substr($$d, $$i + 1, 1)); $$i += 2;
return if $$i >= $$l - $val_len;
my $val = substr($$d, $$i, $val_len); $$i += $val_len;
$$a{$key} = $val;
}
}
sub parseInt {
my $v = shift;
my $l = length($v);
my $r = 0;
for (my $i = $l; $i > 0; $i --) {
$r += ( (1 << (($i - 1) * 8)) * ord(substr($v, $l - $i, 1)) );
}
$r -= 4294967296 if ($r >= 2147483648);
return $r;
}
sub stringLength {
my $s = shift;
my $l = length($s);
my $i1 = $l & 0xFF;
$l = ($l - $i1) >> 8;
my $i2 = $l & 0xFF;
return chr($i2) . chr($i1);
}
sub stringAttribute {
my ($type, $key, $val) = @_;
return chr($type) . stringLength($key) . $key . stringLength($val) . $val;
}
Свой Web-PDF принтер за 10 минут