в продолжение темы.
нужно открывать второй дескриптор на запись.
( если я парвильно перевел "qmail-queue reads a mail message from descriptor 0. It then reads envelope information from descriptor 1.")
единственный рабочий пример, который я нашел сликшом сложен:
(qmail-queue-scaner.pl line 1231)
sub qmail_requeue {
my($sender,$env_recips,$msg)=@_;
my ($temp,$findate);
&debug("q_r: fork off child into $qmailqueue...");
#($recips=$env_recips) =~ s/^T//;
#$recips =~ s/\0T/\,/g;
#$recips =~ /^(.*)\0+$/;
#$recips = $1;
#$recips =~ s/\0+$//g;
# Create a pipe through which to send the envelope addresses.
pipe (EOUT, EIN) or &error_condition("Unable to create a pipe. - $!");
select(EOUT);$|=1;
select(EIN);$|=1;
# Fork qmail-queue. The qmail-queue child will then open fd 0 as
# $message and fd 1 as the reading end of the envelope pipe and exec
# qmail-queue. The parent will read in the addresses and pass them
# through the pipe and then check the exit status.
$elapsed_time = tv_interval ($start_time, [gettimeofday]);
local $SIG{PIPE} = 'IGNORE';
my $pid = fork;
if (not defined $pid) {
&error_condition ("Unable to fork. (#4.3.0) - $!");
} elsif ($pid == 0) {
# In child. Mutilate our file handles.
close EIN;
open(STDIN,"<$msg")|| &error_condition ("Unable to reopen fd 0. (#4.3.0) - $!");
open (STDOUT, "<&EOUT") || &error_condition ("Unable to reopen fd 1. (#4.3.0) - $!");
select(STDIN);$|=1;
&debug("q_r: xstatus=$xstatus");
open (QMQ, "|$qmailqueue")|| &error_condition ("Unable to open pipe to $qmailqueue [$xstatus] (#4.3.0) - $!");
($sec,$min,$hour,$mday,$mon,$year) = gmtime(time);
$elapsed_time = tv_interval ($start_time, [gettimeofday]);
$findate = POSIX::strftime( "%d %b ",$sec,$min,$hour,$mday,$mon,$year);
$findate .= sprintf "d d:d:d -0000", $year+1900, $hour, $min, $sec;
print QMQ "Received: from $returnpath by $hostname by uid $uid with qmail-scanner-$VERSION \n";
print QMQ " ($SCANINFO Clear:$tag_score. \n";
print QMQ " Processed in $elapsed_time secs); $findate\n";
print QMQ "X-Spam-Status: $sa_comment\n" if ($sa_comment ne "");
print QMQ "X-Spam-Level: $sa_level\n" if ($sa_comment ne "" && $sa_level ne "");
if ( $descriptive_hdrs ) {
print QMQ "${V_HEADER}-Mail-From: $returnpath via $hostname\n";
print QMQ "${V_HEADER}-Rcpt-To: $recips\n" if ($descriptive_hdrs eq "2");
print QMQ "$V_HEADER: $VERSION (Clear:$tag_score. Processed in $elapsed_time secs)\n";
}
my $still_headers=1;
my $seen_env=0;
while (<STDIN>) {
if ($still_headers) {
#if (!$seen_env && /^X\-Envelope\-From:/) {
#$seen_env=1;
#just skip the next line (X-Envelope-To:)
#<STDIN>;
#next;
#}
#remove any X-Spam-Status/Level IFF we've set a SA value ourselves
if (($sa_comment ne "" && /^X-Spam-Status:/i) || ($sa_level ne "" && /^X-Spam-Level:/i) ) {
#Hmm, better get rid of any other continuation headers to this!
while (<STDIN>) {
$still_headers=0 if (/^(\r|\r\n|\n)$/);
if ($still_headers && /^\s/i) {
next;
} else {
$still_headers=1;
last;
}
}
}
if ($sa_comment =~ /^yes/i && $spamc_subject ne "" && !/^Subject: \Q$spamc_subject\E/i && /^(Subject):(\s?)([^\n]+)\n/i ) {
$altered_subject="$1: $spamc_subject $3";
if ($altered_subject !~ /^: \Q$spamc_subject\E/) {
&debug("altering subject line to $altered_subject");
print QMQ "$altered_subject\n";
next;
}
}
$still_headers=0 if (/^(\r|\r\n|\n)$/);
#Insert Subject: line if e-mail dosn't contain one but must be tagged
print QMQ "Subject: $spamc_subject\n" if ((!$still_headers) && ($sa_comment =~ /^yes/i) && (!$altered_subject) && $spamc_subject ne "" );
}
print QMQ;
}
close(QMQ); #||&error_condition("Unable to close pipe to $qmailqueue (#4.3.0) - $!");
$xstatus = ( $? >> 8 );
if ( $xstatus > 10 && $xstatus < 41 ) {
&error_condition("mail server permanently rejected message. (#5.3.0) - $!",$xstatus);
} elsif ($xstatus > 0) {
&error_condition("Unable to open pipe to $qmailqueue [$xstatus] (#4.3.0) - $!",$xstatus);
}
#This child is finished - exit
exit;
} else {
# In parent.
close EOUT;
# Feed the envelope addresses to qmail-queue.
print EIN "$sender\0$env_recips";
close EIN || &error_condition ("Write error to envelope pipe. (#4.3.0) - $!");
}
# We should now have queued the message. Let's find out the exit status
# of qmail-queue.
waitpid ($pid, 0);
$xstatus =($? >> 8);
if ( $xstatus > 10 && $xstatus < 41 ) {
&error_condition("mail server permanently rejected message. (#5.3.0) - $!",$xstatus);
} elsif ($xstatus > 0) {
&error_condition("Unable to close pipe to $qmailqueue [$xstatus] (#4.3.0) - $!",$xstatus);
}
}