#!/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"};
$APOPFILEBASE = ".apop"; # "$HOME/$APOPFILEBASE" is the password file
# $APOPFILEBASE = "maildir/apop";
# $APOPFILEBASE = "Mail/apop";
# $ENCODER = "cat";
$ENCODER = "gzip";
# $ENCODER = "uuencode $$|gzip";
# $DECODER = "cat";
$DECODER = "gzip -dc";
# $DECODER = "gzip -dc | uudecode";
$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 .= "-" . ($EXT=shift);
} elsif (/^-b/) {
$base++;
} elsif (/^-c/) {
$create++;
} elsif (/^-s/) {
$stream++;
# and exit;
} elsif (/^-f/) {
$force++;
} elsif (/^-h/) {
&usage; # and exit
}
}
sub checkmaildir {
local($dotqmail) = ("$HOME/.qmail");
local($maildir) = ("maildir"); # default
$dotqmail .= "-$EXT" if $EXT;
$maildir .= "-$EXT" if $EXT;
unless (-f "$dotqmail") {
if ($create) {
if (open(DQMAIL, "> $dotqmail")) {
print DQMAIL "./$maildir/\n";
print "File [$dotqmail] created\n";
close(DQMAIL);
}
} else {
print "$dotqmail file does not exist.\n"; # shoud go to stdout
print "Your shoud 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);
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 shoud 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
$force || &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!
$force || &checkmaildir;
if (open(P, "| $ENCODER > $APOPFILE")) {
# open success
print P "$new1";
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;
}