package Socalsail::Register; # a module to contain routines for accessing and manipulating the # various membership-related files on the Socalsail site. use strict; BEGIN { use Exporter; use Fcntl ':flock'; use vars qw(@ISA @EXPORT @EXPORT_OK $VERSION $queue_file $queue_file_semaphore $member_file $member_file_semaphore $htgroup_file $htgroup_semaphore $htpasswd_file); $VERSION = '0.01'; $queue_file = '/w1/s/socalsail/maint/data/pending_memberships.txt'; $queue_file_semaphore = $queue_file . '.sem'; $member_file = '/w1/s/socalsail/maint/data/members.txt'; $member_file_semaphore = $member_file . '.sem'; $htgroup_file = '/w1/s/socalsail/maint/data/.htgroup'; $htgroup_semaphore = $htgroup_file . '.sem'; $htpasswd_file = '/w1/s/socalsail/maint/data/.htpasswd'; @ISA = ('Exporter'); @EXPORT = qw(); @EXPORT_OK = qw(read_register_queue write_register_queue read_members write_members read_htgroup write_htgroup); } sub read_register_queue { # invoked with no arguments, read all the membership # applications on the disk file, and return a HoH of # the following form: # # my %HoH = ( username => { # verify => $verify, # password => $password, # real_name => $real_name, # phone => $phone, # email => $email, # }, # username => { # (etc.) # # note that this routine counts on the caller to implement # any file locking required. also, note that the routine # counts on the $queue_file to be structured with one record # per line, structured as follows: # # username\tverify\tpassword\treal_name\tphone\temail\n my %HoH = (); # note: okay to fail on open, if file doesn't exist yet if (open IN, $queue_file) { while () { chomp; my($username, $verify, $password, $real_name, $phone, $email) = split /\t/, $_; $HoH{$username} = { verify => $verify, password => $password, real_name => $real_name, phone => $phone, email => $email, }; } close IN; # close the data file } %HoH; # return the data structure } sub write_register_queue { # invoked with an argument of a %HoH data structure (see # read_register_queue), write that data out to the $queue_file # with one record per line, and each record's fields separated # from each other by tabs. Note that locking # must be taken care of by the caller. my %HoH = @_; open OUT, "> $queue_file" or die "couldn't open $queue_file for writing: $!"; while (my($username, $href) = each %HoH) { my @record = (); foreach my $field ($username, $href->{verify}, $href->{password}, $href->{real_name}, $href->{phone}, $href->{email}) { # squash consec. whitespace into a single space char $field =~ s{\s+}{ }g; push @record, $field; } print OUT join("\t", @record), "\n"; } close OUT; } sub read_members { # invoked with no arguments, read all the member # records on the disk file, and return a HoH of # the following form: # # my %HoH = ( username => { # password => $password, # real_name => $real_name, # phone => $phone, # email => $email, # }, # username => { # (etc.) # # note that this routine counts on the caller to implement # any file locking required. also, note that the routine # counts on the $member_file to be structured with one record # per line, structured as follows: # # username\tpassword\treal_name\tphone\temail\n my %HoH = (); # note: okay to fail on open, since file may not exist yet if (open IN, $member_file) { while () { chomp; my($username, $password, $real_name, $phone, $email) = split /\t/, $_; $HoH{$username} = { password => $password, real_name => $real_name, phone => $phone, email => $email, }; } close IN; # close the data file } %HoH; # return the data structure } sub write_members { # invoked with an argument of a %HoH data structure (see # read_members), write that data out to the $member_file # with one record per line, and each record's fields separated # from each other by tabs. Note that locking # must be taken care of by the caller. my %HoH = @_; open OUT, "> $member_file" or die "couldn't open $member_file for writing: $!"; while (my($username, $href) = each %HoH) { my @record = (); foreach my $field ($username, $href->{password}, $href->{real_name}, $href->{phone}, $href->{email}) { # squash consec. whitespace into a single space char $field =~ s{\s+}{ }g; push @record, $field; } print OUT join("\t", @record), "\n"; } close OUT; } sub read_htgroup { # read the htgroup file for Socalsail members. # return a HoH of the following form: # # primary key: groupname. secondary key: membername. # value: 1. my %HoH = (); # okay to fail on open, since file may not exist yet if (open IN, $htgroup_file) { while () { if (/^(\S+): (.+)/) { my $group = $1; my $rest = $2; my @members = split /\s+/, $rest; foreach my $member (@members) { $HoH{$group}{$member} = 1; } } } close IN; # close data file } %HoH; # return data structure } sub write_htgroup { # invoked with a HoH: primary key: groupname # secondary key: membername # value: 1 # # writes the data out to $htgroup_file. my %HoH = @_; open OUT, "> $htgroup_file" or die "couldn't open $htgroup_file for writing: $!"; while (my($group, $hashref) = each %HoH) { print OUT "$group: ", join(' ', keys %{$hashref}), "\n"; } close OUT; } 1;