diff options
| author | Ivan Kohler <ivan@freeside.biz> | 2012-06-01 17:15:27 -0700 |
|---|---|---|
| committer | Ivan Kohler <ivan@freeside.biz> | 2012-06-01 17:15:27 -0700 |
| commit | cbb4c260c40779ba84c794dd68147c54f3de2f52 (patch) | |
| tree | 2be7909d11386d157240b48ac4ce5ff878adfa1f /rt/lib/RT/Interface/Email.pm | |
| parent | d4617c6565d5fc6bafe14d11c19646b0674ae73d (diff) | |
RT 3.8.13
Diffstat (limited to 'rt/lib/RT/Interface/Email.pm')
| -rwxr-xr-x | rt/lib/RT/Interface/Email.pm | 36 |
1 files changed, 25 insertions, 11 deletions
diff --git a/rt/lib/RT/Interface/Email.pm b/rt/lib/RT/Interface/Email.pm index 9216887cd..37b1545d5 100755 --- a/rt/lib/RT/Interface/Email.pm +++ b/rt/lib/RT/Interface/Email.pm @@ -57,6 +57,7 @@ use RT::EmailParser; use File::Temp; use UNIVERSAL::require; use Mail::Mailer (); +use Text::ParseWords qw/shellwords/; BEGIN { use base 'Exporter'; @@ -404,7 +405,7 @@ sub SendEmail { if ( $mail_command eq 'sendmailpipe' ) { my $path = RT->Config->Get('SendmailPath'); - my $args = RT->Config->Get('SendmailArguments'); + my @args = shellwords(RT->Config->Get('SendmailArguments')); # SetOutgoingMailFrom if ( RT->Config->Get('SetOutgoingMailFrom') ) { @@ -423,12 +424,13 @@ sub SendEmail { $OutgoingMailAddress ||= RT->Config->Get('OverrideOutgoingMailFrom')->{'Default'}; - $args .= " -f $OutgoingMailAddress" + push @args, "-f", $OutgoingMailAddress if $OutgoingMailAddress; } # Set Bounce Arguments - $args .= ' '. RT->Config->Get('SendmailBounceArguments') if $args{'Bounce'}; + push @args, shellwords(RT->Config->Get('SendmailBounceArguments')) + if $args{'Bounce'}; # VERP if ( $TransactionObj and @@ -438,32 +440,44 @@ sub SendEmail { my $from = $TransactionObj->CreatorObj->EmailAddress; $from =~ s/@/=/g; $from =~ s/\s//g; - $args .= " -f $prefix$from\@$domain"; + push @args, "-f", "$prefix$from\@$domain"; } eval { # don't ignore CHLD signal to get proper exit code local $SIG{'CHLD'} = 'DEFAULT'; - open( my $mail, '|-', "$path $args >/dev/null" ) - or die "couldn't execute program: $!"; - # if something wrong with $mail->print we will get PIPE signal, handle it local $SIG{'PIPE'} = sub { die "program unexpectedly closed pipe" }; + + # Make it look to open2 like STDIN is on FD 0, like it + # should be; this is necessary because under mod_perl with + # the perl-script handler, it's not. This causes our + # child's "STDIN" (FD 10-ish) to be set to the pipe we want, + # but FD 0 (which the exec'd sendmail assumes is STDIN) is + # still open to /dev/null; this ends disasterously. + local *STDIN = IO::Handle->new_from_fd( 0, "r" ); + + require IPC::Open2; + my ($mail, $stdout); + my $pid = IPC::Open2::open2( $stdout, $mail, $path, @args ) + or die "couldn't execute program: $!"; + $args{'Entity'}->print($mail); + close $mail or die "close pipe failed: $!"; - unless ( close $mail ) { - die "close pipe failed: $!" if $!; # system error + waitpid($pid, 0); + if ($?) { # sendmail exit statuses mostly errors with data not software # TODO: status parsing: core dump, exit on signal or EX_* - my $msg = "$msgid: `$path $args` exitted with code ". ($?>>8); + my $msg = "$msgid: `$path @args` exited with code ". ($?>>8); $msg = ", interrupted by signal ". ($?&127) if $?&127; $RT::Logger->error( $msg ); die $msg; } }; if ( $@ ) { - $RT::Logger->crit( "$msgid: Could not send mail with command `$path $args`: " . $@ ); + $RT::Logger->crit( "$msgid: Could not send mail with command `$path @args`: " . $@ ); if ( $TicketObj ) { _RecordSendEmailFailure( $TicketObj ); } |
