#!/usr/local/bin/perl5 ############################################################################## # WWWBoard Version 2.0 ALPHA 2 # # Copyright 1996 Matt Wright mattw@worldwidemart.com # # Created 10/21/95 Last Modified 11/25/95 # # Scripts Archive at: http://www.worldwidemart.com/scripts/ # # # # Modified by Schaft for Best Internet users 4/97 # # # ############################################################################## ############################################################################## # Define Variables - See Write-up below for the reasons for these settings # ############################################################################## # # NOTE: In the "new_file" subroutine, a command is included # to set the new files to 664 # $basedir = "."; # The changes in the program make these $baseurl = "."; # entries just "." so it will work for # either www.you.com/wwwboard or the long form # shellxx.ba.best.com/~you/wwwboard $cgi_url = "wwwboard.cgi"; #make sure this is "chmod 750" $mesgdir = "messages"; # make sure this is "chmod 730" $datafile = "data.txt"; # don't forget to "chmod 760 " $mesgfile = "wwwboard.sht"; # don't forget to "chmod 760" $faqfile = "faq.html"; $ext = "htm"; $title = "Qwxyz Forum"; # You can change this to "My WWWBoard" # or some such to personalize it ########################################################### # Configure Options # ########################################################### $show_faq = 0; # 1 - YES; # 0 = NO $allow_html = 0; # 1 = YES, HTML will show # 0 = NO, HTML will be deleted $quote_text = 0; # 1 = YES, and editable # 0 = NO, old text not in entry box $subject_line = 0; # 0 = Quote Subject Editable; # 1 = Quote Subject UnEditable; # 2 = Don't Quote Subject, Editable. $use_time = 1; # 1 = YES; 0 = NO ####################### # N E W ####################### # mail stuff - if you want to be notified of entries # # This will cause a mail message to be sent to you whenever # an entry is made in the WWWBoard message area. # # By default, no mail will be sent # $mail_me = 0; # 0 = don't mail, 1 = mail $yourname = ""; # put your login name here # For mail, the entries would look like: # $mail_me = 1; # $yourname = "your_login_name"; # # Where "your_login_name" is the name you use to log into Best # Example - For me it would look like: # # $mail_me = 1; # $yourname = "schaft"; # # #################################################################### # # Rational For Changes # ##################################################################### # The following changes were made specifically for Best Internet users # who have the capability to run CGI from their own area. # # The CGI area is a sub-directory of the directory "ftp" and is # called "public_html". The server runs as user "nobody" in the # group "mosaic", and its base directory is the user's "public_html" # when it is invoked. # # The server will not allow files to be created in a directory that is # running a script, so the normal placement of these files, and the # permissions, are: # # ftp --------- 755 <--directory # my_stuff ---- 755 <--anonymous FTP directory # etcstuff ---- 755 <--another anonymous FTP directory # # public_html - 710 <-- CGI directory # index.html - 740 <-- default page # script.cgi - 750 <-- a script # counterpg1 - 760 <-- a file that is appended to # mypic1.gif - 740 <-- a picture # # wwwboard ------ 710 <-- directory for this set of programs # wwwboard.cgi - 750 <-- executable # wwwadmin.cgi - 750 <-- executable # data.txt ----- 760 <-- modified for attachment counts # passwd.txt --- 760 <-- modifiable admin password storage # wwwboard.html -760 <-- modified display page # faq.html ------740 <-- FAQ page, displayed only # # messages ------730 <-- Directory for new messages, writable # 1.html ------664 <-- new file, owned by "nobody" so set # world readable so it can be deleted # without running "wwwadmin.cgi" # ################################################################# # MORE CHANGES, ETC. ################################################################## # Jan 97 Changes # # There are a bunch more changes - doing a "chmod" in the # NEWFILE routine, and changing the follow-up CGI address in the NEWFILE # to "../wwwboard.cgi" since it executes in the "messages" directory # # I also changed the $basedir to just a "." in a couple of places # because it shows better that the page is off of the main page. # # I lined up the boxes with a "
...
" set of tags in # both the HTML and this routine. Also made them 65 characters # (there was an inconsistency between the HTML and this script) # and put in the "wrap physical" tag for browsers that support it. # # I put a
between each new topic to separate the topics and # their follow-ups from each other. # # I put in code to add the month to the counter file (normally # "data.txt") so I could separate each month's new entries out. # Follow-ups to a prior month's entry will go in the normal chain. # # As the result of a suggestion, I put the posting stuff at the top # of the page, followed by the posts, followed by a link back to the # form. Apparently folks don't tend to post if the form is at the # bottom and there are a lot of entries. # # I didn't like the fact that new posts appeared at the top, so I # made them follow in the order posted. They used to look like: # # posting 3 # re: posting 3 (followup 2) # re: posting 3 (followup 1) # posting 2 # re: posting 2 (followup 1) # posting 1 # #now they look like: # posting 1 # posting 2 # re: posting 2 (followup 1) # posting 3 # re: posting 3 (followup 1) # re: posting 3 (followup 2) # # If there is a URL but no title, I made the URL the title. # # I made the background color white - #ffffff - for all of the # pages. Drab grey was depressing... :) I made the date and time # easier (to me) to read. This broke the admin script searching # on postings to delete by date. I may correct that script in # the future. # # I added in the preview posting subroutine (3/97) # # There was an error in the error routine for a bad subject - if # modification of the subject is not allowed, there was no way to # correct the error. I deleted the check. There was an error in the # way that the error routines handled a blank message if there was # another error. I put in a check for a "body" and moved an extraneous # return inside of the check. # # I changed the error routines so that for missing fields, all # the missing ones will be shown at once. # # There were a few other nits for stuff that I thought needed the # logic changed around, like the updating to the message number file. ########################################################################### # # Get date stuff - made it a subroutine &date_stuff; # Get Form Information &parse_form; # Put items into nice variables &get_variables; # If there are errors, we will never get to the next line # Get and update the Data Number (and the month) &get_number; # Open the new file and write information to it. &new_file; # Open the Main WWWBoard File to add link &main_page; # Now Add Thread to Individual Pages &thread_pages if ($num_followups >= 1); # Return the user HTML &return_html; # Check to see if mail should be sent &mail_note if ($mail_me && $yourname); # $mailme=1, $yourname not blank # # All done, exit exit; # # ########################### # # S U B R O U T I N E S # ############################ # Date Stuff sub date_stuff{ @DoW = ('Sunday','Monday','Tuesday','Wednesday', 'Thursday','Friday','Saturday'); @MoY = ('January','February','March','April','May','June', 'July','August','September','October','November', 'December'); ($sec, $min, $hour, $mday, $mon, $year, $wday, $yday, $isdst) = localtime (time); # check for PST or PDT $tizo = ($isdst == 1) # 1 = PDT, 0 = PST ? "PDT" : "PST"; # set min. and seconds to print "01", etc. $sec = "0$sec" if ($sec < 10); $min = "0$min" if ($min < 10); # Check for AM or PM $AMPM = ($hour < 12) ? "AM" : "PM"; # set up an array for hours to map "0" to 12, "13" to 1, etc. @HR2 = (12,1,2,3,4,5,6,7,8,9,10,11, # AM 12,1,2,3,4,5,6,7,8,9,10,11); # PM $hour = $HR2[$hour]; # index into array with the hour value (00 to 23) # add the century to the year - good to 2034, unless Unix changes... :) $year += ($year < 90) ? 2000 : 1900; $daweek = $DoW[$wday]; # Monday, Tuesday, etc. $month = $MoY[$mon]; # January, February, etc. $dayth = $mday . &ordinalize($mday); # day of the month - 1st, etc. if ($use_time == 1) { $date = "$hour\:$min\:$sec $AMPM $tizo $month $dayth, $year"; } else { $date = "$month $dayth, $year"; } chop($date) if ($date =~ /\n$/); $long_date ="$daweek $month $dayth, $year at $hour\:$min\:$sec $AMPM $tizo"; return (1); # done } ################################ # Get Data Number and Month Subroutine # # File not locked because of minimal time in it # sub get_number { $change_month = 0; open(NUMBER,"$basedir/$datafile"); $numdate = ; close(NUMBER); ($num,$holdate) = split(/:/,$numdate); # split out number and month chop $holdate; # get rid of \n $num++; # increment number $num = "1" if ($num == 99999); # reset if 99,999 $change_month = 1 if ($month ne $holdate); # new month check, set flag open(NUM,">$basedir/$datafile") || die $!; print NUM "$num:$month\n"; # write out nbr and month close(NUM); } ####################### # Parse Form Subroutine sub parse_form { # Get the input read(STDIN, $buffer, $ENV{'CONTENT_LENGTH'}); # Split the name-value pairs @pairs = split(/&/, $buffer); foreach $pair (@pairs) { ($name, $value) = split(/=/, $pair); # Un-Webify plus signs and %-encoding $value =~ tr/+/ /; $value =~ s/%([a-fA-F0-9][a-fA-F0-9])/pack("C", hex($1))/eg; $value =~ s///g; # if($FORM{'action'} ne "post") # { if ($allow_html != 1) { $value =~ s/<([^>]|\n)*>//g;} else { unless ($name eq 'body') { $value =~ s/<([^>]|\n)*>//g;} } # } $FORM{$name} = $value; } } ############### # Get Variables sub get_variables { $error_indic = 0; $followup = "0"; if ($FORM{'followup'}) { $followup = "1"; @followup_num = split(/,/,$FORM{'followup'}); $num_followups = @followups = @followup_num; $last_message = pop(@followups); $origdate = "$FORM{'origdate'}"; $origname = "$FORM{'origname'}"; $origsubject = "$FORM{'origsubject'}"; } $name = "$FORM{'name'}"; $name =~ s/"//g; $name =~ s///g; $name =~ s/\&//g; $error_indic = 1 if (!$name); # NO NAME $subject = "$FORM{'subject'}"; $subject =~ s/\&/\&\;/g; $subject =~ s/"/\&qout\;/g; $error_indic = 1 if (!$subject); # NO SUBJECT # # change - it checked for URL and title, make it check # for URL, and make title = URL if it is missing # Also, must start with "http://" if ($FORM{'url'} =~ /^http\:\/\/.*\..*/i ) { $message_url = "$FORM{'url'}"; if ($FORM{'url_title'}) { # is there a title? $message_url_title = "$FORM{'url_title'}"; # yes } else { $message_url_title = " $FORM{'url'}"; # no title } } # Check for entry, but bad format. Error. if ($FORM{'url'} && $FORM{'url'} !~ /^http:\/\/.*\..*/i) {$error_indic = 1;} # Check for entry, but bad format. Error. if ($FORM{'img'} && $FORM{'img'} !~ /^http:\/\/.*\..*/i) {$error_indic = 1;} else{$message_img = "$FORM{'img'}";} if ($FORM{'body'}) { $body = "$FORM{'body'}"; $body =~ s/\cM//g; $body =~ s/&/\&/g; # ampersand $body =~ s/<//g; # by changing "<" and ">" $body =~ s/"/\"/g; # and quote $body =~ s/\n\n/

/g; # change two returns into

$body =~ s/\n/
/g; # change one return into
} else {$error_indic = 1;} # NO MESSAGE if ($quote_text == 1){ $hidden_body = "$body"; $hidden_body =~ s/>/>/g; $hidden_body =~ s/$basedir/$mesgdir/$num\.$ext") || die $!; #### CHANGE to set file permissions to "664" and lock access ##### flock(NEWFILE,2); # lock the file $Filenew = "$basedir/$mesgdir/$num\.$ext"; chmod 0664, $Filenew; ### #################### print NEWFILE "\n"; print NEWFILE "\n"; print NEWFILE "$subject\n"; print NEWFILE "\n"; print NEWFILE "\n"; print NEWFILE "\n"; print NEWFILE "

\n"; print NEWFILE "

$subject

\n"; print NEWFILE "
\n"; print NEWFILE "
\n"; if ($show_faq) { print NEWFILE "
[ Follow Ups ] [ Post Followup ] [ Go To $title ] [ FAQ ]
\n"; } else { print NEWFILE "
[ Follow Ups ] [ Post Followup ] [ Go To $title ]
\n"; } print NEWFILE "

\n"; print NEWFILE "Posted by "; if ($email) { print NEWFILE "$name on $long_date:

\n"; } else { print NEWFILE "$name on $long_date:

\n"; } if ($followup == 1) { print NEWFILE "In Reply to: $origsubject posted by "; if ($origemail) { print NEWFILE "$origname on $origdate:

\n"; } else { print NEWFILE "$origname on $origdate:

\n"; } } if ($message_img) { print NEWFILE "

\n"; } print NEWFILE "$body\n"; print NEWFILE "
\n"; if ($message_url) { print NEWFILE "

\n"; } print NEWFILE "

\n"; print NEWFILE "Follow Ups:
\n"; print NEWFILE "

\n"; print NEWFILE "

\n"; print NEWFILE "Post a Followup

\n"; #### --- The next line does a post to "../wwwboard.cgi" to # back up out of the messages directory print NEWFILE "

\n"; print NEWFILE "\n"; print NEWFILE "\n"; if ($email) { print NEWFILE "\n"; } print NEWFILE "\n"; print NEWFILE "\n"; print NEWFILE "Name:
\n"; print NEWFILE "E-Mail:

\n"; if ($subject_line == 1) { if ($subject_line =~ /^Re:/) { print NEWFILE "\n"; print NEWFILE "Subject: $subject

\n"; } else { print NEWFILE "\n"; print NEWFILE "Subject: Re: $subject

\n"; } } elsif ($subject_line == 2) { print NEWFILE "Subject:

\n"; } else { if ($subject =~ /^Re:/) { print NEWFILE "Subject:

\n"; } else { print NEWFILE "Subject:

\n"; } } print NEWFILE "Comments:
\n"; print NEWFILE "\n"; print NEWFILE "

\n";
   print NEWFILE " Optional Link URL: 
\n"; print NEWFILE " Link Title:
\n"; print NEWFILE "Optional Image URL:

\n"; print NEWFILE " \n"; print NEWFILE "

[You may have to hit the \"Reload\" button to see your post]"; print NEWFILE "


\n"; if ($show_faq) { print NEWFILE "
[ Follow Ups ] [ Post Followup ] [ Go To $title ] [ FAQ ]
\n"; } else { print NEWFILE "
[ Follow Ups ] [ Post Followup ] [ Go To $title ]
\n"; } print NEWFILE "\n"; flock(NEWFILE,8); # unlock file close(NEWFILE); return (1); } # ############################### # Main WWWBoard Page Subroutine ############################## sub main_page { open(MAIN,"$basedir/$mesgfile") || die $!; @main =
; close(MAIN); open(MAIN,">$basedir/$mesgfile") || die $!; flock(MAIN,2); # lock access if ($followup == 0) { foreach $main_line (@main) { if($change_month){ # If the month has changed... if($main_line =~ /Read Month Messages Links/) { # line for top for new month print MAIN "Read $month New Messages
\n"; } } if ($main_line =~ //) { if($change_month){ # if the month has changed... print MAIN "
\n
\n
"; # set it off and name it print MAIN "

"; print MAIN "
Messages Posted in $month
"; print MAIN "

\n"; print MAIN "
\n"; } print MAIN "
\n"; print MAIN "
  • $subject - $name $date\n"; print MAIN "(0)\n"; print MAIN "
      \n"; print MAIN "
    \n"; print MAIN "\n"; }else { print MAIN "$main_line"; } } } else { foreach $main_line (@main) { $work = 0; if ($main_line =~ /<\/ul>/) { print MAIN "
  • $subject - $name $date\n"; print MAIN "(0)\n"; print MAIN "
      \n"; print MAIN "
    \n"; print MAIN "\n"; } elsif ($main_line =~ /\((.*)\)/) { $response_num = $1; $num_responses = $2; $num_responses++; foreach $followup_num (@followup_num) { if ($followup_num == $response_num) { print MAIN "($num_responses)\n"; $work = 1; } } if ($work != 1) { print MAIN "$main_line"; } } else { print MAIN "$main_line"; } } } flock(MAIN,8); # unlock the file close(MAIN); return (1); } ############################################ # Add Followup Threading to Individual Pages ########################################### sub thread_pages { foreach $followup_num (@followup_num) { open(FOLLOWUP,"$basedir/$mesgdir/$followup_num\.$ext"); @followup_lines = ; close(FOLLOWUP); open(FOLLOWUP,">$basedir/$mesgdir/$followup_num\.$ext"); flock(FOLLOWUP,2); # lock access foreach $followup_line (@followup_lines) { $work = 0; if ($followup_line =~ /<\/ul>/) { print FOLLOWUP "
  • $subject - $name $date\n"; print FOLLOWUP "(0)\n"; print FOLLOWUP "
      \n"; print FOLLOWUP "
    \n"; print FOLLOWUP "\n"; } elsif ($followup_line =~ /\((.*)\)/) { $response_num = $1; $num_responses = $2; $num_responses++; foreach $followup_num (@followup_num) { if ($followup_num == $response_num) { print FOLLOWUP "($num_responses)\n"; $work = 1; } } if ($work != 1) { print FOLLOWUP "$followup_line"; } } else { print FOLLOWUP "$followup_line"; } } flock(FOLLOWUP,8); # unlock the file close(FOLLOWUP); } return (1); } # ######################### # Return HTML ######################### # sub return_html { print "Content-type: text/html\n\n"; print "Message Added: $subject\n"; print "\n"; # "bgcolor" set to white - ffffff print "

    Message Added: $subject

    \n"; print "The following information was added to the message board:


    \n"; print "Name: $name
    \n"; print "E-Mail: $email
    \n" if ($email); print "Subject: $subject
    \n"; print "Body of Message:

    \n"; print "$body

    \n"; if ($message_url) { print "Link: $message_url_title
    \n"; } if ($message_img) { print "Image:
    \n"; } print "Added on Date: $date

    \n"; print "


    \n"; print "
    [ Go to Your Message ] [ Go To $title ]
    \n"; print "\n"; return (1); } ######################### # # E R R O R ! ! ! # # We are here because the user made an error - $error_indic = 1 or # we're passing in a value for a non-blank but invalid field # (applies to e-mail) # ######################## sub error { $error = $_[0]; print "Content-type: text/html\n\n"; print "$title Errors In Form\n"; print "\n"; print ""; print "

    WHOOPS!!!

    "; print "- You forgot to fill in the 'Name' field in your posting.
    " if (!($FORM{'name'}) ); print "- You forgot to fill in the 'Subject' field in your posting.
    " if (!($FORM{'subject'}) ); print "- You forgot to fill in the 'Message' field in your posting.
    " if (!($FORM{'body'}) ); # the following catches the optional field errors print "- Your e-mail address is not valid.
    It must be in the form of name\@domain.type, for example:
    \"joe\@myprovider.com\".
    " if ( $FORM{'email'} && ($FORM{'email'} !~ /.+\@.+\..+/) ); print "- Your URL is bad. It must start with \"http\:\/\/\" and be correctly formatted
    " if ($FORM{'url'} && $FORM{'url'} !~ /^http:\/\/.*\..*/i); print "- Your Image Link is bad. It must start with \"http\:\/\/\" and be correctly formatted
    " if ($FORM{'img'} && $FORM{'img'} !~ /^http:\/\/.*\..*/i); print "

    Please correct the errors below and re-submit, or go back and start again.

    The necessary fields are: Name, Subject and Message.


    \n"; print "\n"; if ($followup == 1) { print "\n"; print "\n"; print "\n"; print "\n"; print "\n"; } print "

    ";
       print "   Name: 
    \n"; print " E-Mail:

    \n"; print "Subject:

    \n"; print "Message:
    \n"; print "

    \n"; print " Optional Link URL:
    \n"; print " Link Title:
    \n"; print "Optional Image URL:

    \n"; print " \n"; print "

  • \n"; print "

    \n"; if ($show_faq) { print "
    [ Follow Ups ] [ Post Followup ] [ $title ] [ FAQ ]
    \n"; } else { print "
    [ Follow Ups ] [ Post Followup ] [ $title ]
    \n"; } print "\n"; exit; } ############################ # # Mail_note subroutine to mail notification of entry # ############################## # # sub mail_note { # $mailprog = "/usr/lib/sendmail -t"; $mailprog = "/usr/sbin/sendmail -t"; $maildone = ".\n"; open (MAIL, "| $mailprog") || die; print MAIL "From: $yourname\@best.com\n"; print MAIL "To: $yourname\@best.com\n"; print MAIL "Subject: WWWBoard entry by $FORM{'name'}\n"; print MAIL "\n"; print MAIL "An Entry has been made to the WWWBoard\n\n"; print MAIL " Topic: $FORM{'subject'}\n\n"; print MAIL " Actually from: host $ENV{'REMOTE_HOST'} ($ENV{'REMOTE_ADDR'})\n"; print MAIL $maildone; close (MAIL); return(1); } ############################## # # Ordinalize routine for day # put "th", "rd" etc. on numbers ############################## sub ordinalize { local($count) = @_; local($last, $last2); $last2 = $count % 100; $last = $count % 10; if ($last2 < 10 || $last2 > 13) { return "st" if $last == 1; # 1st, 21st, 31st... return "nd" if $last == 2; # 2nd, 22nd. 32nd... return "rd" if $last == 3; # 3rd, 23rd, 33rd... } return "th"; # Catch 11th, 12th, 13th, 4th, 24th, etc. etc. } # END OF SCRIPT ADD-ON ################################# That's about it folks ########