#!/usr/local/bin/perl
# Customize these variables.
# If you change APOPFILEBASE, change the same variable in apopcall.c too.
# See http://www.gentei.org/~yuuji/software/imapext/

$HOME=$ENV{"HOME"};

$DEFAULTMAILDIR = "Maildir";	# Must be same as ../src/osdep/unix/Makefile

$APOPFILEBASE = ".apop";	# "$HOME/$APOPFILEBASE" is the password file
# $APOPFILEBASE = "$DEFAULTMAILDIR/apop";
# $APOPFILEBASE = "Mail/apop";

$ENCODER = "cat";
# $ENCODER = "gzip";
# $ENCODER = "uuencode $$|gzip";

$DECODER = "cat";
# $DECODER = "gzip -dc";
# $DECODER = "gzip -dc | uudecode";

$DOTQMAIL = ".qmail";		# qmail
# $DOTQMAIL = ".forward";	# Postfix

$XADDR_DELIM = "-";		# qmail
# $XADDR_DELIM = "+";		# Postfix

$HERE = ".";			# qmail
# $HERE = "~";			# Postfix

$EXT = "";
$force = 0;
$base = 0;

$APOPFILE = "$HOME/$APOPFILEBASE";

sub handler {
	system "stty echo";
	print STDERR "Abort:\n";
	exit 1;
}

$SIG{'INT'} = $SIG{'KILL'} = $SIG{'QUIT'} = $SIG{'HUP'} = 'handler';

while ($_=$ARGV[0], /^-.+/ && shift) {
    if (/^-e/) {
	$APOPFILE .= $XADDR_DELIM . ($EXT=shift);
    } elsif (/^-b/) {
	$base++;
    } elsif (/^-c/) {
	$create++;
    } elsif (/^-s/) {
	$stream++;
	# and exit;
    } elsif (/^-h/) {
	&usage; # and exit
    }
}

sub checkmaildir {
    local($dotqmail) = ("$HOME/$DOTQMAIL");
    local($maildir) = ($DEFAULTMAILDIR);	  # default
    $dotqmail .= "$XADDR_DELIM$EXT" if $EXT;
    $maildir .= "-$EXT" if $EXT;
    unless (-f "$dotqmail") {
	if ($create) {
	    if (open(DQMAIL, "> $dotqmail")) {
		print DQMAIL "$HERE/$maildir/\n";
		print "File [$dotqmail] created\n";
		close(DQMAIL);
	    }
	} else {
	    print "$dotqmail file does not exist.\n";	# should go to stdout
	    print "Your should create $maildir first!\n";
	    print "(-c option automatically makes it)\n";
	    exit 1;
	}
    }
    if (-s $dotqmail) {
	$maildir='';
	if (open(DQMAIL, "< $dotqmail")) {
	    while (<DQMAIL>) {
		s/[\r\n \t]*$//g;
		next if /#/;
		next unless m,\./.*/,;
		chop;			  # strip trailing "/"
		$maildir = $_;
		last;
	    }
	    close(DQMAIL);
	    $maildir = $DEFAULTMAILDIR if $maildir eq '';
	    unless (-d "$HOME/$maildir"
		    && -d "$HOME/$maildir/new"
		    && -d "$HOME/$maildir/cur"
		    && -d "$HOME/$maildir/tmp") {
		if ($create) {
		    mkdir "$HOME/$maildir", 0700;
		    mkdir "$HOME/$maildir/new", 0700;
		    mkdir "$HOME/$maildir/cur", 0700;
		    mkdir "$HOME/$maildir/tmp", 0700;
		    print "Maildir [$maildir/] created\n";
		} else {
		    print "Maildir($maildir) does not exist\n";
		    print "Your should do maildirmake $maildir first!\n";
		    print "(-c option automatically makes it)\n";
		    exit 1;
		}
	    }
	}
    }
}

sub usage {
    local($mydir, $myname) = ($0 =~ m,(.*)/(.*),);
    print<<_EOU_;
$myname	Change Mail password for imap-4.7+qmailapop
Usage:	$myname [options]
Options are...
	-e EXT		Set target email address to "user-EXT"
	-c		If no .qmail file and Maildir, create them

_EOU_
    exit 0;
}

if ($stream) {
    &stream;
    exit; # not reached
}
$OK=0;
until ($OK) {
    system "stty -echo";
    print STDERR "Enter APOP Password: ";
    $new1 = <>;
    print STDERR "\n";
    if (length($new1) == 1) {
	print STDERR "Canceled\n";
	exit 1;
    } elsif (length($new1) < 9) {
	print STDERR "Password is too short!  Please use more than 8 chars.\n";
	next;
    }
    print STDERR "Again APOP Password: ";
    $new2 = <>;
    if ($new1 eq $new2) {
	$OK=1;
    } else {
	print STDERR "\nPassword mismatch! Try again.\n";
    }
}
#OK
&checkmaildir;
system "stty echo";
open(NP, "| $ENCODER > $APOPFILE") || die "Cannot write on $APOPFILE\n";
print NP "$new1";
close(NP);
chmod 0600, $APOPFILE;
print STDERR "\nUpdated APOP password successfully.\n";

sub stream {				  # Must match with old password
    local($PASS, $old, $new1, $new2, $master) = (0);
    local($masterfile) = ($APOPFILE);
    $masterfile = "$HOME/$APOPFILEBASE" if $base;
    exit 1 if ($> == 0);
    while (<>) {
	chop;
	if (/^PASS (.*)$/i) {
	    $old = $1;
	} elsif (/^NEW (.*)/i) {
	    $new1 = $1;
	} elsif (/^NEW2 (.*)/i) {
	    $new2 = $1;
	}
	last if ("$new1" ne "" && "$new2" ne "");
    }
    if (-s $APOPFILE || ($base && -f $masterfile)) { # Already exist
	if (open(OLD, "$DECODER $masterfile |")) {
	    ($master = <OLD>) =~ s/[\n\r]$//g;
	    close(OLD);
	} else {
	    print "Old password file corrupted.\n";
	    print "Please ask to administrator.\n";
	    exit 1;
	}
	if ($master ne $old) {
	    print "Illegal password\nBye\n";
	    exit 1;
	}
    } 
    if ($new1 ne $new2) {
	print "Password(new) mismatch\nBye\n";
	exit 1;
    }
    # OK, now begin to create!
    &checkmaildir;
    if (open(P, "| $ENCODER > $APOPFILE")) {
	# open success
	print P "$new1\n";
	close(P);
	chmod 0600, $APOPFILE;
	if (-s $APOPFILE) {
	    print "Success!\n";
	    exit 0;
	}
    } else {
	print "Cannot output to $APOPFILE\nBye\n";
	exit 1;
    }
    exit 0;
}
