=head1 NAME

smtp-forward

=head1 DESCRIPTION

This plugin forwards the mail via SMTP to a specified server, rather than
delivering the email locally.

=head1 CONFIG

It takes one required parameter, the IP address or hostname to forward to. 

  queue/smtp-forward 10.2.2.2

Optionally you can also add a port:

  queue/smtp-forward 10.2.2.2 9025

=cut

use Net::SMTP;

sub register {
  my ($self, $qp, @args) = @_;

  if (@args > 0) {
    if ($args[0] =~ /^([\.\w_-]+)$/) {
      $self->{_smtp_server} = $1;
    }
    else {
      die "Bad data in smtp server: $args[0]";
    }
    $self->{_smtp_port} = 25;
    if (@args > 1 and $args[1] =~ /^(\d+)$/) {
      $self->{_smtp_port} = $1;
    }
    $self->log(LOGWARN, "WARNING: Ignoring additional arguments.") if (@args > 2);
  } else {
    die("No SMTP server specified in smtp-forward config");
  }

}

sub hook_queue {
  my ($self, $transaction) = @_;

  $self->log(LOGINFO, "forwarding to $self->{_smtp_server}:$self->{_smtp_port}");
  my $smtp = Net::SMTP->new(
                            $self->{_smtp_server},
                            Port => $self->{_smtp_port},
                            Timeout => 60,
                            Hello => $self->qp->config("me"),
                           ) || die $!;
  $smtp->mail( $transaction->sender->address || "" );
  my $rc = $smtp->code;
  my $message = $smtp->message;
  chomp($message);

  if ($rc =~ m/^4\d{2}$/ ) {
	return(DENYSOFT, "Unable to queue message ($message)");
  } elsif ($rc =~ m/^5\d{2}$/ ) {
	return(DENY, "Unable to queue message ($message)");
  }

  for ($transaction->recipients) {
    $smtp->to($_->address);
	$rc = $smtp->code;
	$message = $smtp->message;
	chomp($message);

		if ($rc =~ m/^4\d{2}$/ ) {
			return(DENYSOFT, "Unable to queue message ($message)");
		} elsif ($rc =~ m/^5\d{2}$/ ) {
			return(DENY, "Unable to queue message ($message)");
		}
  }

  $smtp->data();
  $rc = $smtp->code;
  $message = $smtp->message;
  chomp($message);

  if ($rc =~ m/^4\d{2}$/ ) {
        return(DENYSOFT, "Unable to queue message ($message)");
  } elsif ($rc =~ m/^5\d{2}$/ ) {
        return(DENY, "Unable to queue message ($message)");
  }

  $smtp->datasend($transaction->header->as_string);
  $rc = $smtp->code;
  $message = $smtp->message;
  chomp($message);
  
  if ($rc =~ m/^4\d{2}$/ ) {
        return(DENYSOFT, "Unable to queue message ($message)");
  } elsif ($rc =~ m/^5\d{2}$/ ) {
        return(DENY, "Unable to queue message ($message)");
  }

  $transaction->body_resetpos;
  
  while (my $line = $transaction->body_getline) {
    $smtp->datasend($line);

    $rc = $smtp->code;
    $message = $smtp->message;
    chomp($message);

    if ($rc =~ m/^4\d{2}$/ ) {
        return(DENYSOFT, "Unable to queue message ($message)");
    } elsif ($rc =~ m/^5\d{2}$/ ) {
        return(DENY, "Unable to queue message ($message)");
    }
  }
  
  $smtp->dataend();
  $rc = $smtp->code;
  my @messages = $smtp->message;
  my $queue_message = $messages[$#messages];

  if ($rc =~ m/^4\d{2}$/ ) {
        return(DENYSOFT, "Unable to queue message ($queue_message)");
  } elsif ($rc =~ m/^5\d{2}$/ ) {
        return(DENY, "Unable to queue message ($queue_message)");
  }

  $smtp->quit();
  $rc = $smtp->code;
  $message = $smtp->message;
  chomp($message);

  if ($rc =~ m/^4\d{2}$/ ) {
        return(DENYSOFT, "Unable to queue message ($message)");
  } elsif ($rc =~ m/^5\d{2}$/ ) {
        return(DENY, "Unable to queue message ($message)");
  }

  $self->log(LOGINFO, "finished queueing");
  return (OK, "Queued! ($queue_message)");
}
