#!/usr/bin/perl -w
#
# Migrates a single user's .procmailrc, .vacation.msg, and .forward to 
# .sieve
#

if ($#ARGV < 0) {
	print "Usage: $0 username\n";
	print "  Migrates username's .procmailrc, .vacation.msg, and .forward to .sieve\n";
	exit(-1);
}

my $username = $ARGV[0];


# Verify that user exists on system
if (! defined(getpwnam($username))) {
	print "ERROR: username '$username' not found\n";
	exit(-1);
}


# Get for later
my ($uid, $gid, $homedir) = (getpwnam($username))[2,3,7];


# Sieve hash for holding info
my %sievehash = (
		'forward' => "",
		'sa' => 0,
		'outofoffice' => "",
		'filters' => [ ]
		);


# Build .sieve file from .forward, .procmailrc, and .vacation.msg
$hasfw = 0;
$haspm = 0;
$hassa = 0;
$hasbitbucket = 0;
$hasvacation = 0;

if (-l "$homedir/.forward") {
	# Soft link, don't handle
}
elsif (-f "$homedir/.forward") {
	open(IN, "$homedir/.forward");
	$fw = <IN>;
	close(IN);
	chomp $fw;
	if ($fw =~ /^\s*[^\@\s]+\@[^\s]+\s*$/) {
		$hasfw = 1;
		# Strip trailing CR
		$fw =~ s/\r//g;
	}
	if ($fw =~ /^\/dev\/null$/) {
		$hasfw = 1;
		$hasbitbucket = 1;
	}
	if ($fw =~ /^\\$username, "\|.*vacation $username"/) {
		$hasvacation = 1;
	}

	if ($hasfw == 0 and $hasvacation == 0) {
		print "Couldn't parse .forward file for $username\n";
	}
}

if (-l "$homedir/.procmailrc") {
	# Soft link, don't handle
}
elsif (-f "$homedir/.procmailrc") {
	if (open(IN, "$homedir/.procmailrc")) {
		while(<IN>) {
			chomp;
			next unless (/^\* /);
			if (/^\* \^From:\.\*(.*)/) {
				$addr = $1;
				$dest = <IN>;
				chomp $dest;
				push @addrs, "$addr:$dest";
				$haspm = 1;
			}
			if (/^\* \^X-Spam-Status:.*/) {
				$haspm = 1;
				$hassa = 1;
			}
		}
		close(IN);
	}
}

# Generate an appropriate .sieve file
# skip the procmail stuff if they have a .forward
if ($hasfw == 1) {
	open(SIEVE, "> $homedir/.sieve");
	if ($hasbitbucket == 0) {
		print "Forward file email address: $fw\n";
		print SIEVE "redirect \"$fw\";\n";
	}
	else {
		print "Forwarding to /dev/null\n";
		print SIEVE "discard;\n";
	}

	close(SIEVE);

	# Set perms and ownership
	chown($uid, $gid, "$homedir/.sieve");
	chmod(0644, "$homedir/.sieve");

	# Done, stop, exit
	exit();
}

if ($haspm == 1 or $hasvacation == 1) {
	open(SIEVE, "> $homedir/.sieve");
#	open(SIEVE, "> /private/tools/logs/sieve.$username");
	print SIEVE "# Generated by ONID migration script\n";
	print SIEVE "# Modifying this file by hand will make it unreadable by the ONID web tools\n";
	if ($hasvacation == 1) {
		print SIEVE "require [ \"fileinto\", \"vacation\" ];\n\n";
	}
	else {
		print SIEVE "require [ \"fileinto\" ];\n\n";
	}

	# Put Spam Assassin first
	if ($hassa == 1) {
		print "Spam Assassin Enabled\n";
		print SIEVE "# Spam Assassin\n";
		print SIEVE "if header :contains \"X-Spam-Flag\" \"YES\" { fileinto \"INBOX.junk-mail\"; }\n\n";
	}

	# Then outofoffice
	if ($hasvacation == 1 and -f "$homedir/.vacation.msg") {
		print "Vacation found\n";
		open(IN, "$homedir/.vacation.msg");
		while(<IN>) {
			next if (/^From: /);
			next if (/^Subject: /);
			$outofofficemsg .= $_;
		}
		close(IN);
		print SIEVE "# Out of Office\n";
		print SIEVE "vacation :days 7 :subject \"Out of office\" \"\n";
		print SIEVE $outofofficemsg;
		print SIEVE "\n\";\n\n";
	}

	# Then mail filters
	foreach $tmp (@addrs) {
		print "Mail filter found: $tmp\n";
		($addr,$dest) = split(/:/,$tmp);
		if ($dest eq "/dev/null") {
			$dest = "discard;";
		}
		else {
			$dest = "fileinto \"INBOX." . $dest . "\";";
		}
		print SIEVE "if header :contains \"From\" \"$addr\" { $dest }\n\n";
	}

	# Close and set perms and ownership
	close(SIEVE);
	chown($uid, $gid, "$homedir/.sieve");
	chmod(0644, "$homedir/.sieve");
}

