in reply to Apache::Htpasswd syntax questions

Using CGI.pm lets us drop the somewhat-broken parseform() altogether, making the entire program much shorter. Doing that also lets us have somewhat nicer error checking. The warnings you mention earlier have to do with form values not being present. Here's a potential fix:
#!/usr/bin/perl -w use strict; use CGI; use Apache::Htpasswd; my $htpasswd = "/etc/htsec/motion.ht"; my $method = Apache::Htpasswd->new($htpasswd); my $q = CGI->new(); my %fields; for my $field (qw( username newpw oldpw )) { $fields{$field} = $q->param($field); unless (defined($fields{$field})) { showform(); exit(); } } $method->htpasswd(@fields{ qw(username newpw oldpw) }); # print a success message sub showform { my $q = shift; print $q->header(); print <<HTML; <html> <head><title>Password Administration</title></head> <body bgcolor="#FFFFFF"> <form method = "post" action = "https://www.lunarmedia.net/motion/chpa +ss.cgi"> Username:&nbsp;<input type="text" length="30" name="username"><br> Password:&nbsp;<input type="password" length="30" name="oldpw"><br> New Password:&nbsp;<input type="password" length="30" name="newpw"><br +> <input type="submit" value="Go!"><br> </body> </html> HTML }
This allows us to verify that each field contains a defined value, aborting if necessary.

Using CGI to generate the HTML would also give you the benefit of sticky form fields, where the contents of the field display on subsequent invocations.

Update: Fixed two typos. The code ought to work now. Then a third, as c pointed out.