#!/usr/bin/perl -wT
use CGI qw(:standard);
use CGI::Carp qw(warningsToBrowser fatalsToBrowser);
use Fcntl qw(:flock :seek);
use strict;

my $passfile = 'secure/.htpasswd';
print header;
print start_html("Registration Results");

my $username = param('username');
my $password = param('password');

# First, do some data validation.

# be sure the username is alphanumeric - no spaces or funny characters
# also, require it to be at least 3 chars long
if ($username !~ /^\w{3,}$/) {
    &dienice("Please use an alphanumeric username at least 3 letters long, with no spaces.");   

# be sure the password isn't blank or shorter than 6 chars
if (length($password) < 6) {
    &dienice("Please enter a password at least 6 characters

# now encrypt the password
my $encpass = &encrypt($password);

# open the password file for read-write
open(PASSF,"+<$passfile") or &dienice("Can't open password file.");
flock(PASSF, LOCK_EX);          # lock the file (exclusively)
seek(PASSF, 0, SEEK_SET);       # rewind to beginning
my @passf = <PASSF>;            # read entire file

# the structure of the htpasswd file is:
# username:passwd
# username:passwd
# ...etc., with each user's record on a separate line.
# here we're going to loop through and make sure the new username
# doesn't already exist in the htpasswd file.
foreach my $i (@passf) {
    my ($user,$pass) = split(/:/,$i);
    if ($user eq $username) {
       &dienice("The username `$username' is already in use. Please choose another.");

# everything seems clear now, so append the info to the password file.
seek(PASSF, 0, SEEK_END);       # go to EOF
print PASSF "$username:$encpass\n";

print qq(<p>
You're now registered!  Your username is <b>$username</b>, and your 
password is <b>$password</b>.  Login <a href="secure/">here</a>.</p>\n);

print end_html;

sub encrypt {
    my($plain) = @_;
    my @salt = ('a'..'z', 'A'..'Z', '0'..'9', '.', '/');
    return crypt($plain, $salt[int(rand(@salt))] . $salt[int(rand(@salt))] );

sub dienice {
    my($msg) = @_;
    print "<h2>Error</h2>\n";
    print $msg;