#!/usr/bin/perl ############################################################################# # # File: cyberpals_college.pl # # History: # Ver Date Who Comments # ----------------------------------------------------------------------- # 2.0 29-Feb-96 Falke Bruinsma (falke@innersource.com) # Added the ability to EDIT ads using # passwords for protection # 1.1 02-Feb-96 Craig Bloom Minor revisions to HTML output. # # 1.0 30-Jan-96 Mike Reading Changed database structure to colon and # new-line delimited flat file. # Added search and preview capabilities. # Added "poor man's database locking". # # 0.2 09-Dec-95 Paul Coddington Initial Release # # require 'cgi-lib.pl'; ############################################################################# # # CONFIGURABLE PARAMATERS # ############################################################################# # # The fully qualified path to the database file. # NOTE: The this file and the directory in which it is located # MUST be readable/writeable by the httpd deamon. # $DB_FILE="cyberpals.db"; $SECRET="4Pals"; $SCRIPT = "cyberpals_college.pl"; ############################################################################# # # MAIN FUNCTION # ############################################################################# # # Initialize the random number generator # srand; # # Parse arguments passed by http server # &ReadParse(*input); # # Figure out what we're supposed to do and do it # $preview_button = $input{"preview_button"}; $post_button = $input{"post_button"}; $search_button = $input{"search_button"}; $search2_button = $input{"search2_button"}; $edit_button = $input{"edit_button"}; $add_button = $input{"add_button"}; $passwd_button = $input{"passwd_button"}; $delete_button = $input{"delete_button"}; if ($preview_button) { &Preview_Personal(); } elsif ($post_button) { &Post_Personal(); } elsif ($search_button) { &Display_Search_Page(); } elsif ($search2_button) { &Search_Database(); } elsif ($edit_button) { &Edit_Personal(0); } elsif ($add_button) { &Edit_Personal(1); } elsif ($passwd_button) { &Ask_For_Passwd(); } elsif ($delete_button) { &Delete_Personal(); } else { &Display_Info(); } ############################################################################# # # SUBROUTINES # ############################################################################# sub Pack_Record { # # INPUTS: A list of field values # OUTPUTS: A single string containing the fields joined by colons # and "special" characters replaced by their Hex equivalents # local(@fields) = @_; local($field); # # Convert all percent signs to %25, all colons to %3A and all new-lines to %0A # foreach $field (@fields) { $field =~ s/%/%25/g; $field =~ s/:/%3A/g; $field =~ s/\n/%0A/g; } # # Return the fields joined by colons # join(":",@fields); } sub Unpack_Record { # # INPUT: A single string containing the fields joined by colons and # "special" characters encoded with their hex equivalents # OUTPUTS: A list of unencoded field values # local($record) = @_; local($field,@fields); # take off the last \n chop($record); # # Split the records into individual fields using : as a delimeter # @fields = split(/:/,$record); # # Convert all %3A's to colons, all %0A's to new-lines, and all %25's to percents. # foreach $field (@fields) { $field =~ s/%3A/:/g; $field =~ s/%0A/\n/g; $field =~ s/%25/%/g; } # # Return the "unpacked" list # @fields; } sub Delete_Personal { local($class,$name,$age,$sex,$town,$state,$country,$email,$homepage,$entry,$postdate, $passwd); local($tmpclass,$tmpname,$tmpage,$tmpsex,$tmptown,$tmpstate,$tmpcountry,$tmpemail, $tmphomepage, $tmpentry,$tmppostdate,$tmppasswd); local($record); local($tmprecord); $postdate = $input{'postdate'}; open(DB,"$DB_FILE"); open(DBTMP, ">$DB_FILE.tmp"); while ($tmprecord = ) { ($tmpclass,$tmpname,$tmpage,$tmpsex,$tmptown,$tmpstate,$tmpcountry,$tmpemail,$tmphomepage,$tmpentry,$tmppostdate,$tmppasswd) = &Unpack_Record($tmprecord); if ($postdate ne $tmppostdate) { print DBTMP $tmprecord; } } close(DB); close(DBTMP); system("cp $DB_FILE.tmp $DB_FILE"); print &PrintHeader; print " Personal ad has been removed Your personal ad has been successfully removed

Click here to continue "; } sub Post_Personal { # PURPOSE: Prepend a new "packed" record to the database # INPUTS: Data supplied by the assoc array %input # OUTPUTS: An HTML Document displaying some feedback along with a printout # of how the personal will look. local($class,$name,$age,$sex,$town,$state,$country,$email,$homepage,$entry,$postdate,$passwd); local($tmpclass,$tmpname,$tmpage,$tmpsex,$tmptown,$tmpstate,$tmpcountry,$tmpemail,$tmphomepage,$tmpentry,$tmppostdate,$tmppasswd); local($record); # Pull out the variables we're interested in $class = $input{'class'}; $name = $input{'name'}; $age = $input{'age'}; $sex = $input{'sex'}; $town = $input{'town'}; $state = $input{'state'}; $country = $input{'country'}; $email = $input{'email'}; $homepage = $input{'homepage'}; $entry = $input{'entry'}; $passwd = $input{'the_passwd'}; $oldpostdate = $input{'postdate'}; if (not $input{'postdate'}) { $add = 1; } # Get the date from the system clock $postdate = `date`; chop($postdate); # Prepend a record to the database file by: # 1. "Locking" the database file # 2. Writing the new record to a temporary file # 3. Appending the existing database to the temp file # 4. Copying the temp file back to the database file # 5. "Unlocking" the database file $record = &Pack_Record($class,$name,$age,$sex,$town,$state,$country,$email,$homepage,$entry,$postdate,$passwd); # Loop until we can get a sucessful "lock" on the database while (!&Lock_Database) { # Sleep a random amount of time between 0 and 1 seconds select(undef,undef,undef,rand); } # Prepend the record open (DBTMP,">$DB_FILE.tmp") || die "Unable to open $DB_FILE.tmp\n"; print DBTMP "$record\n"; close DBTMP; if ($add) { system("cat $DB_FILE >> $DB_FILE.tmp"); } else { open(DB,"$DB_FILE"); open(DBTMP, ">>$DB_FILE.tmp"); while ($tmprecord = ) { ($tmpclass,$tmpname,$tmpage,$tmpsex,$tmptown,$tmpstate,$tmpcountry,$tmpemail,$tmphomepage,$tmpentry,$tmppostdate,$tmppasswd) = &Unpack_Record($tmprecord); if ($oldpostdate ne $tmppostdate) { print DBTMP $tmprecord; } } close(DB); close(DBTMP); } system("cp $DB_FILE.tmp $DB_FILE"); # Unlock the database &Unlock_Database; # Display a message telling the user that the post was sucessful print &PrintHeader; print " Sucessful Post

Your Cyberpals Personal Ad was sucessfully added to the database!


"; &Display_Record($record); print "






Perform a

|The Center|Your Comments And Ours|About The Student Center| "; return 1; } sub Edit_Personal { local local($add) = @_; local($class,$name,$age,$sex,$town,$state,$country,$email,$homepage,$entry,$postdate,$passwd); local($tmpclass,$tmpname,$tmpage,$tmpsex,$tmptown,$tmpstate,$tmpcountry,$tmpemail,$tmphomepage,$tmpentry,$tmppostdate,$tmppasswd); $class = $input{'class'}; $name = $input{'name'}; $age = $input{'age'}; $sex = $input{'sex'}; $town = $input{'town'}; $state = $input{'state'}; $country = $input{'country'}; $email = $input{'email'}; $homepage = $input{'homepage'}; $entry = $input{'entry'}; $passwd = $input{'the_passwd'}; $postdate= $input{'postdate'}; print &PrintHeader; print ""; if ($add) { print"College Cyberpals Add Form"; } else { print "College Cyberpals Edit Form"; } print ""; if ($add) { print "

College Cyberpals Add Form

"; } else { print "

College Cyberpals Edit Form

"; open(DB, "$DB_FILE"); while ($record = ) { ($tmpclass,$tmpname,$tmpage,$tmpsex,$tmptown,$tmpstate,$tmpcountry,$tmpemail,$tmphomepage,$tmpentry,$tmppostdate,$tmppasswd) = &Unpack_Record($record); if ($postdate eq $tmppostdate) { if (($passwd ne $tmppasswd || $tmppasswd eq "") && $passwd ne $SECRET) { print "You entered the wrong password! "; die; } } } close DB; } print "
"; if (not $add) { print ""; } print "
Full Name (or Nickname):
Sex: "; if ($sex eq "M") { print " Male"; } else { print " Male"; } if ($sex eq "F") { print " Female"; } else { print " Female"; } print "
Age:
City/Town:
State (use 2-letter code if USA):
Country:
E-mail address:
Enter the URL of your homepage (if you have one).
Please include the \"http://\":
Password for your personal ad: (this allows you to edit your ad later)
Enter your personal ad:

"; if ($add) { print ""; } else { print ""; print ""; } print "


|The Center|Your Comments And Ours|About The Student Center| "; } sub Preview_Personal { # PURPOSE: Show the user what the Personal will look like and allow him # her to Submit the Personal to the database # INPUTS: Data supplied by the assoc array %in # OUTPUTS: An HTML Document displaying a preview of how the personal # along with a form with embeded data allowing the user to Submit # the personal. local($class,$name,$age,$sex,$town,$state,$country,$email,$homepage,$entry,$postdate,$passwd); local($record); # Pull out the variables we're interested in $class = $input{'class'}; $name = $input{'name'}; $age = $input{'age'}; $sex = $input{'sex'}; $town = $input{'town'}; $state = $input{'state'}; $country = $input{'country'}; $email = $input{'email'}; $homepage = $input{'homepage'}; $entry = $input{'entry'}; $passwd = $input{'the_passwd'}; # Get the date from the system clock $postdate = $input{'postdate'}; $oldpostdate = $input{'postdate'}; if (not $input{'postdate'}) { $add = 1; } $postdate = `date`; chop($postdate); # Print out a Preview of the Personal print &PrintHeader; print " Cyberpals personal Ad Preview

Cyberpals Personal Ad Preview


"; $record = &Pack_Record($class,$name,$age,$sex,$town,$state,$country,$email,$homepage,$entry,$postdate,$passwd); &Display_Record($record); # Embed the posted data into the output and provide a Submit button # to allow the user to Post the data. print "


Press to add your Cyberpals Personal to the database or use your browser's \"Back\" button to go back and edit your posting.



|The Center|Your Comments And Ours|About The Student Center|

"; } sub Display_Record { # PURPOSE: Display a Personal # INPUTS: A "packed" record # OUTPUTS: An HTML Document displaying the personal local($record) = @_; local($class,$name,$age,$sex,$town,$state,$country,$email,$homepage,$entry,$postdate,$passwd); ($class,$name,$age,$sex,$town,$state,$country,$email,$homepage,$entry,$postdate,$passwd) = &Unpack_Record($record); print " Last updated: $postdate
From "; if ($homepage eq "") { print "$name "; } else { print "$name "; } if ($email eq "") { print "($email) "; } else { print "($email) "; } print " Sex: $sex Age: $age $town, $state, $country
$entry
"; } sub Display_HiddenRecord { # PURPOSE: Display Hidden info for a Personal # INPUTS: A "packed" record # OUTPUTS: An HTML Document displaying the hidden personal local($record) = @_; local($class,$name,$age,$sex,$town,$state,$country,$email,$homepage,$entry,$postdate,$passwd); ($class,$name,$age,$sex,$town,$state,$country,$email,$homepage,$entry,$postdate,$passwd) = &Unpack_Record($record); print " "; if ($_[1]) { print ""; } } sub Display_Search_Page { print &PrintHeader; print " Cyberpals Search Form

Cyberpals Search Form

Fill in as many fields as you wish and press the SEARCH button to start your search. All searches are case-insensitive. Wildcard characters (ie *,%,#,$ etc.) are not required.

To view all listings, just hit the search button!


Name:
Sex: Male or Female Male Female
Age Range: To
Town:
State (use 2-letter code if USA):
Country:
Keyword(s)
(Separate Keywords with spaces):
Search Type: Only Return Records Matching ALL Keywords
Return Records Matching ANY of the Keywords
Limit the number of
personals displayed to:


|The Center|Your Comments And Ours|About The Student Center| "; } sub Search_Database { # PURPOSE: Scan through the database and pick out the records that match # the search criteria. Display a maximum of $search_match_max # matching records staring with match number $search_match_start. # INPUTS: Search data supplied by the assoc array %in # OUTPUTS: An HTML document displaying the matches along with a form (with) # embedded search criteria) that allows the user to continue the # search if more matching records exist. local($class,$name,$age,$sex,$town,$state,$country,$email,$homepage,$entry,$postdate,$passwd); local($search_class,$search_name,$search_age,$search_sex,$search_town,$search_state,$search_country,$search_entry); local($record,$match_count); # # Pull out the variables we're interested in # $search_class = $input{'search_class'}; $search_name = $input{'search_name'}; $search_age_min = $input{'search_age_min'}; $search_age_max = $input{'search_age_max'}; $search_sex = $input{'search_sex'}; $search_town = $input{'search_town'}; $search_state = $input{'search_state'}; $search_country = $input{'search_country'}; $search_entry = $input{'search_entry'}; $search_boolean = $input{'search_boolean'}; $search_match_start = $input{'search_match_start'}; $search_match_max = $input{'search_match_max'}; $search_match_start = 1 if ($search_match_start eq ""); $search_match_max = 10 if ($search_match_max eq ""); print "Content-type: text/html\n\n"; print "

Cyberpals Search Results

"; open(DB,"$DB_FILE"); $match_count = 0; # # Loop through the records comparing each field to the search criteria. # Immediately drop out of the loop if any of the fields do not pass the # search criteria. # while ($record = ) { ($class,$name,$age,$sex,$town,$state,$country,$email,$homepage,$entry,$postdate,$passwd) = &Unpack_Record($record); next if ( !($class =~ /$search_class/i) && ($search_class ne "")); next if ( !($name =~ /$search_name/i) && ($search_name ne "")); next if ( ($age < $search_age_min ) && ($search_age_min ne "")); next if ( ($age > $search_age_max ) && ($search_age_max ne "")); next if ( !($sex =~ /$search_sex/i) && ($search_sex ne "")); next if ( !($town =~ /$search_town/i) && ($search_town ne "")); next if ( !($state =~ /$search_state/i) && ($search_state ne "")); next if ( !($country =~ /$search_country/i) && ($search_country ne "")); if (($search_boolean eq "OR") && ($search_entry ne "")) { # # Boolean OR case - ANY key must match # $match_found = 0 ; @keywords = split(/\s/,$search_entry); foreach $keyword (@keywords) { $match_found = 1 if ($entry =~ /$keyword/i); } next if !$match_found; } else { # # Boolean AND case -- all keywords MUST match # $found_mismatch = 0; @keywords = split(/\s/,$search_entry); foreach $keyword (@keywords) { $found_mismatch = 1 if !($entry =~ /$keyword/i); } next if $found_mismatch; } # # If we made it this far then we must have a match # ++$match_count; # # Display the record if it falls within the proper range # if ( ($match_count >= $search_match_start) && ($match_count < ($search_match_start + $search_match_max))) { &Display_Record($record); print ""; &Display_HiddenRecord($record, 0); print ""; print "


"; } # # Separate records with a New-line # print "

"; } close(DB); # # Figure out if there are more records to be displayed # if (($search_match_start + $search_match_max - 1) >= $match_count) { # # We must have displayed all of them. # print "

Found $match_count Matching Personals.

"; if ($match_count==0) { # # If no matches found then say so # print "0 matches are displayed."; } else { print "Matches $search_match_start - $match_count are displayed."; } } else { # # There must be more # $max_match_displayed = $search_match_start + $search_match_max - 1; print "

Found $match_count Matching Personals.

"; if ($match_count==0) { # # If no matches found then say so # print "0 matches are displayed."; } else { print " Matches $search_match_start - $max_match_displayed are displayed.

Press to see more matching Personals.

"; } # # Embed the data from the previous search and increment $search_match_start # to allow the next search to display the next set of matching records # print "
"; } # # Print a closing footer # print "

|The Center|Your Comments And Ours|About The Student Center| "; } ######################################################################### # Database Locking functions ######################################################################### sub Lock_Database { # # PURPOSE: Attempt to "lock" the database by creating a lock file. # INPUTS: # OUTPUTS: A boolean telling if the lock was sucessful # if (-e "$DB_FILE.lock") { # DB is already locked 0; } else { system "touch","$DB_FILE.lock"; 1; } } sub Unlock_Database { # # PURPOSE: Attempt to "unlock" the database by deleting the lock file. # INPUTS: # OUTPUTS: A boolean telling if the unlock was sucessful # unlink("$DB_FILE.lock"); } sub Display_Info { print &PrintHeader; print " College Cyberpals

College Cyberpals

The Best Way to Meet College Students With Similar Interests


Add your own Cyberpals personal to the database


Search for other Cyberpals with common interests


|The Center|Your Comments And Ours|About The Student Center| "; } sub Ask_For_Passwd { local($class,$name,$age,$sex,$town,$state,$country,$email,$homepage,$entry,$postdate,$passwd); local($record); # Pull out the variables we're interested in $class = $input{'class'}; $name = $input{'name'}; $age = $input{'age'}; $sex = $input{'sex'}; $town = $input{'town'}; $state = $input{'state'}; $country = $input{'country'}; $email = $input{'email'}; $homepage = $input{'homepage'}; $entry = $input{'entry'}; $postdate = $input{'postdate'}; $record = &Pack_Record($class,$name,$age,$sex,$town,$state,$country,$email,$homepage,$entry,$postdate,$passwd); print &PrintHeader; print " Verification

"; &Display_HiddenRecord($record); print " Please enter the password to edit this personal ad:

"; } Verify_Passwd { local($record) = @_; 1; }