
#!/usr/bin/perl
#
# htpasswd by Nem W Schlecht
#
#  Modified 1/7/96 by Mark Solomon to include checking for current
#       users - the original just appended each successive new password for
#       the same person as a new line, not deleting the old.
#
#       I took this script and made it much longer physically by making it
#       modular so that 1) I could understand it 2) It could be easily
#       followable, and 3) It could be later modified by anyone else :)  I
#       understand that the spirit of perl is to keep things short, but I'm
#       still learning, and this seems to work well.  Any comments, I take
#       constructive criticism well.
#
#

&GetArgs;               # Get Command line args or die
&LoadPwFile;            # Load current passwordfile
                        # (I'll add file locking later)
print &Prompt;          # Prompt for password
chop($pass=<>);         # Get new password
&MakeNewPassword;       # Encrypt the newly entered password with "salt".
$list{$name} = $cpw;    # Load new crypt pw into passwordfile array
&WriteNewFile;          # Write the amended array as the passwordfile

####################################################################
####                                                            ####
####            Start of subs                                   ####
####                                                            ####
####################################################################

sub GetArgs {
        $file=shift(@ARGV);
        $name=shift(@ARGV);
        if ( (!$file) | (!$name) ) {
                die "Usage: $0 htpasswdfile username\n";
        }
}
sub MakeNewPassword {
        srand($$|time);                                 # random seed
        @saltchars=(a..z,A..Z,0..9,'.','/');            # valid salt chars
        $salt=$saltchars[int(rand($#saltchars+1))];     # first random salt cha

        $salt.=$saltchars[int(rand($#saltchars+1))];    # second random salt ch

        $cpw = crypt($pass,$salt);
}
sub LoadPwFile {
        open(HP, "$file") || open(HP, ">$file");
        while (<HP>) {
                chop;
                ($tname,$tpw) = split(':',$_);
                $list{$tname} = $tpw;
        }
}
sub Prompt {
        local($text);
        if ($list{$name}) {
                $text = "Changing password for $name\nEnter new password:";
        }
        else {
                $text = "Enter password for $name:";
        }
        return($text);
}
sub WriteNewFile {
        open(HTPASSWD, ">$file");
                foreach $key (sort keys(%list)) {
                        print HTPASSWD "$key:$list{$key}\n";  # print it
                }
        close(HTPASSWD);
}

