#!/usr/bin/perl -Tw -I/home/weasel/projects/pmix/libmix-perl

use strict;
use Mix;
use Mail::Internet;
use Getopt::Long;

$ENV{'PATH'} = '/bin:/usr/bin';
delete @ENV{'IFS', 'CDPATH', 'ENV', 'BASH_ENV'};


sub usage($) {
	my ($err) = @_;

	my $fh;
	if ($err) {
		$fh = *STDERR;
	} else {
		$fh = *STDOUT;
	};
	print $fh "Usage: $0 [OPTIONS] [MAIL [MAIL, ...]]\n";
	print $fh "\t-l, --chain=mix1,mix2,mix3,...  specify a remailer chain\n";
	print $fh "\t-c, --copies=num                send num copies to increase reliability\n";
	print $fh "\t-s, --send                      send mails using Mail::Mailer\n";
	print $fh "\t-S, --smtpsend                  send mails using Net::SMTP\n";
	print $fh "\t-h, --help                      print this help\n";
	print $fh "\t-p, --post                      input is a usenet news posting\n";
	print $fh "\t-d, --dummy                     generate a dummy message\n";
	print $fh "\t-T, --type2list                 print the type2.list\n";
	exit ($err);
};


my %PARAMS;
Getopt::Long::config('bundling');
GetOptions(
	'l|chain=s'   => \$PARAMS{'chain'},
	'c|copies=i'  => \$PARAMS{'copies'},
	's|send'      => \$PARAMS{'send'},
	'S|smtpsend'  => \$PARAMS{'smtpsend'},
	'h|help'      => \$PARAMS{'help'},
	'm|mail'      => \$PARAMS{'ignore'},
	'p|post'      => \$PARAMS{'post'},
	'd|dummy'     => \$PARAMS{'dummy'},
	'T|type2list' => \$PARAMS{'printtype2list'}
) or usage(1);

usage(0) if ($PARAMS{'help'});

my $keyring = new Mix::Keyring( Filename => 'pubring.mix' );
my $mix = new Mix( Keyring => $keyring );

if ($PARAMS{'printtype2list'}) {
	print $mix->{'Keyring'}->get_type2list();
	exit(0);
};

my $type = 'mail';
$type = 'post' if ($PARAMS{'post'});
$type = 'dummy' if ($PARAMS{'dummy'});

my $copies = 1;
$copies = $PARAMS{'copies'} if (defined $PARAMS{'copies'});


my @mails;

if ($type eq 'mail' || $type eq 'post') {
	my @files = @ARGV;
	push @ARGV, "-" unless (scalar @ARGV);

	for my $file (@ARGV) {
		open (FH, $file) or die "Cannot open file '$file': $!\n";
		my $message = new Mail::Internet *FH;
		close (FH);

		my @chain = $message->head()->get('chain');
		$message->head()->delete('chain');

		@chain = ($PARAMS{'chain'}) if (defined $PARAMS{'chain'});
		@chain = split /(?:\s|,)+/, join ', ', map {chomp; $_ } @chain;

		push @mails, $mix->mix(
			message =>$message->as_string(),
			chain => \@chain,
			type => $type,
			copies => $copies
		);
	};
} else {
	my @chain;
	@chain = split /(?:\s|,)+/, $PARAMS{'chain'} if (defined $PARAMS{'chain'});

	push @mails, $mix->mix(
		chain => \@chain,
		type => $type,
		copies => $copies
	);
};

for my $mail (@mails) {
	if ($PARAMS{'send'}) {
		$mail->send();
	} elsif ($PARAMS{'smtpsend'}) {
		$mail->smtpsend();
	} else {
		print $mail->as_string(),"\n";
	};
};

=pod

=head1 NAME

mixc - send mixmaster v2 messages

=head1 SYNOPSIS

mixc [OPTIONS] [FILE [FILE ...]]

=back

=head1 DESCRIPTION

Mixmaster is an anonymous remailer network and protocol. It protects
against traffic analysis and allows users to send mails and post usenet
articles in an anonymous way.

B<mixc> is a client for this network. It constructs mix messages from a
mail or article which can then be sent to the first remailer.

By default the messages to be sent are printed on STDOUT. Using the B<-s>
option you can instruct B<mixc> to send them directly using SMTP.

=head1 OPTIONS

=over

=item B<-h, --help>

Prints a short help message and exists successfully.

=item B<-l, --chain>=I<chain>

send the message through the remailers given in I<chain>. I<chain> is a comma
seperated list of remailer names from your public mixring.

A chain may also be given by the pseudo header C<Chain: mix1, mix2, ...> in the
message itself. The C<Chain: > header is removed from the message before mixing
it.

The chain passed on the command line takes precedence over one in the mesage.

=item B<-c, --copies>=I<numcopies>

Send the message I<numcopies> times to increase reliability. They all end at
the same last hop which then filter duplicates, so the message is only
delivered once to the final recipient(s). If random remailers are used in the
chain, it is randomly chosed for each of the copies.

=item B<-s, --send>

Sends the message using C<Mail::Mailer> (uses local methods).

=item B<-S, --smtpsend>

Sends the message using C<Net::SMTP> (tries to send through smtp servers).

=item B<-T, --type2list>

Prints the type2.list.

=item B<-m>

Ignored.

=back

If no files are given on the command line, the mixclients reads the message from STDIN.

=head1 AUTHOR

Peter Palfrader E<lt>peter@palfrader.orgE<gt>

=head1 BUGS

Please report them to the author.

=head1 SEE ALSO

=over

=item Mixmaster Protocol, Version 2 <draft-moeller-v2-01.txt>

=item mix(1)

=item news:alt.privacy.anon-server

=item Mix

=item Mix::Keyring
        
=item Mutt E-Mail Client Manual

=item Mail::Mailer

=item Net::SMTP
	
=back

=cut
