--- /usr/bin/swaks	2004-04-04 21:49:30.000000000 -0500
+++ swaks	2005-06-06 15:11:19.000000000 -0500
@@ -6,6 +6,8 @@
 use Sys::Hostname;
 use Getopt::Long;
 use Time::Local;
+use IPC::Open2;
+use IO::Handle;
 
 my($p_name)   = $0 =~ m|/?([^/]+)$|;
 my $p_version = "20040404.1";
@@ -67,7 +69,8 @@
   'hs|hide-send'    => \$O{hide_send},     # Don't show sending lines
   'stl|show-time-lapse:s' => \$O{show_time_lapse}, # print lapse for send/recv
   'ndf|no-data-fixup' => \$O{no_data_fixup}, # don't touch the data
-  'dump'            => \$O{dump_args}      # build options and dump
+  'dump'            => \$O{dump_args},     # build options and dump
+  'pipe:s'          => \$O{pipe}           # Work with pipes, not sockets
 ) || exit(1);
 
 load_modules({
@@ -110,7 +113,8 @@
 
 sendmail($opts->{from}, $opts->{to}, $opts->{helo}, $opts->{data},
          $opts->{server}, $opts->{port}, $opts->{a_user}, $opts->{a_pass},
-         $opts->{a_type}, $opts->{lint}, $opts->{timeout});
+         $opts->{a_type}, $opts->{lint}, $opts->{timeout}, $opts->{conn_type},
+	 $opts->{pipe});
 
 exit(0);
 
@@ -126,13 +130,23 @@
   my $a_type  = shift;	# what kind of auth (this must be set to to attempt)
   my $lint    = shift;	# what local interface to use
   my $timeout = shift;	# timeout for all transactions
+  my $type    = shift;  # type of connection to use
+  my $pipe    = shift;  # command to pipe to
   my $ehlo    = {};	# If server is esmtp, save advertised features here
   $|          = 1;
+  my $s;
 
-  print_transaction(11, "Trying $host:$port...");
-  my $s       = IO::Socket::INET->new( PeerAddr  => $host, PeerPort => $port,
-		                       Proto     => 'tcp', Timeout  => $timeout,
-                                       LocalAddr => $lint);
+  if ($type eq 'socket') {
+      print_transaction(11, "Trying $host:$port...");
+      my $s_tmp   = IO::Socket::INET->new( PeerAddr => $host, PeerPort => $port,
+					   Proto     => 'tcp', Timeout  => $timeout,
+					   LocalAddr => $lint);
+      $s = {rd => $s_tmp, wr => $s_tmp};
+  } else {
+    my ($server_rd,$server_wr) = (IO::Handle->new,IO::Handle->new);
+    open2($server_rd, $server_wr, $pipe);
+    $s = {rd => $server_rd, wr => $server_wr};
+  }
 
   if ($@) {
     print_transaction(12,"Error connecting $lint to $host:$port:\n\t$@");
@@ -593,7 +607,7 @@
 }
 
 sub do_smtp_gen {
-  my $s = shift; # socket
+  my $s = shift; # socket pair
   my $m = shift; # string to send
   my $e = shift; # String we're expecting to get back
   my $t = shift; # timeout
@@ -636,7 +650,7 @@
 }
 
 sub transact {
-  my $s    = shift;       # This is my IO::Socket object
+  my $s    = shift;       # This is my socket pair object
   my $send = shift;       # This is the string to send
   my $buff = shift;       # we will store and manipulate the return value here.
   my $alrm = shift || 0; # change timeout here so we can have it wait forever
@@ -650,7 +664,7 @@
       if ($G::tls_active) {
         my $res = Net::SSLeay::write($G::tls_ssl, "$send\r\n");
       } else {
-        print $s $send, "\r\n";
+        $s->{wr}->print($send, "\r\n");
       }
     }
     alarm($alrm);
@@ -662,7 +676,7 @@
         $buff = Net::SSLeay::read($G::tls_ssl);
       } else {
         do {
-          $buff .= <$s>;
+          $buff .= $s->{rd}->getline;
         } while ($buff !~ /^\d\d\d /m);
       }
       $buff =~ s/\r//msg;
@@ -977,10 +991,19 @@
     }
   }
 
-  # SMTP port
-  $n{port} = $o->{mail_port} || interact("Port: ", '^\d+$')
-      if (defined($o->{mail_port}));
-  $n{port} ||= $fconf->{PORT} || ($G::tls_on_connect ? 465 : 25);
+  # Use a pipe instead of a socket?
+  if ($o->{pipe}) {
+      delete $n{server};
+      $n{pipe} = $o->{pipe};
+      $n{conn_type} = 'pipe';
+  } else {
+      # SMTP port
+      $n{port} = $o->{mail_port} || interact("Port: ", '^\d+$')
+	  if (defined($o->{mail_port}));
+      $n{port} ||= $fconf->{PORT} || ($G::tls_on_connect ? 465 : 25);
+      $n{conn_type} = 'socket';
+  }
+
 
   # Handle AUTH options
   $G::auth_optional = 1 if (defined($o->{auth_optional}));
