#!/usr/bin/perl ############################################################################# # # File: cyberpals_high.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_high.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"High School Cyberpals Add Form"; } else { print "High School Cyberpals Edit Form"; } print ""; if ($add) { print "

High School Cyberpals Add Form

"; } else { print "

High School 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 " High School Cyberpals

High School Cyberpals

The Best Way to Meet High School 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; }