#!/DOCUMENT_ROOT/OCEAN_PLANET/SUPPORT_PROGRAMS/perl # Get the document root from the path to perl. ($dr) = $^X =~ m@^(.*)/OCEAN_PLANET/@; require "$dr/OCEAN_PLANET/SUPPORT_PROGRAMS/cgi-lib.pl"; # The home page $hp = '/OCEAN_PLANET/HTML/ocean_planet_overview.html'; # Some directory names $md = "/OCEAN_PLANET/BB_MESSAGES"; # message directory $hd = '/OCEAN_PLANET/HTML'; # html directory $id = '/OCEAN_PLANET/ICONS'; # icon directory # Some images $wi = ""; $bi = ""; $ui = ""; $di = ""; $ii = ""; $li = ""; $gi = "http://oceancolor.gsfc.nasa.gov/staff/gene/"; $hi = ""; $hl = "$hi"; # Message categories @types = ( join($;,'con','Comments or Suggestions for Ocean Conservation'), join($;,'gen','General comments about the exhibition'), join($;,'que','Questions About the Exhibit') ); # These strings serve as the name portions of the NAME=VALUE pairs # that are sent to the http server. $nm_p = 'page'; # Which type of BB page to display (post,list,message,etc) $nm_g = 'grp'; # Page number indicating group of BB messages to be displayed $nm_t = 'type'; # Category of BB message; serves as initial part of filename $nm_o = 'order';# 'N' or 'O' to indicate if newest or oldest messages come 1st $nm_k = 'keys'; # Key words to be used in selecting BB messages $nm_a = 'andor';# 'A' or 'O' to indicate how keywords should control a search $nm_c = 'case'; # 'S' or 'I'; keyword matching is case-sensitive or -insensitiv $nm_m = 'msg'; # BB message filename (type_yyyydddhhmmss) $nm_n = 'name'; # Message writer's name $nm_e = 'eml'; # Message writer's e-mail address $nm_s = 'subj'; # Subject of the message to be posted to the BB $nm_x = 'text'; # Body of the message to be posted to the BB # Number of message links per page $lpp = 16; # Some arrays to make readable dates. @mon = ('Jan','Feb','Mar','Apr','May','Jun','Jul','Aug','Sep','Oct','Nov','Dec'); @wday = ('Sun','Mon','Tue','Wed','Thu','Fri','Sat'); @dpm = (31,0,31,30,31,30,31,31,30,31,30,31); # days per month # Get the name of this script. $sn = (reverse split(/\//,$ENV{'SCRIPT_NAME'}))[0]; # Last bulletin board script update $lu = int(-M "$dr/OCEAN_PLANET/SCRIPTS/$sn"); $lu == 1 && ($lu = "$lu day ago") || ($lu = "$lu days ago"); # Let the client browser know that HTML is coming. print <<"--"; Content-type: text/html -- # Change directory to the one containing the bulletin board messages. chdir "$dr$md" || die "Could not change directory to $dr$md, stopped"; # Interpret data from client browser. &ReadParse; # Take action indicated by data from client. { $_ = $in{$nm_p}; /^M/ && ( &bb_msg, last ); # Display a message /^L/ && ( &bb_lst, last ); # Display a listing of messages /^P/ && ( &bb_pst, last ); # Post a message /^W/ && ( &bb_wrt, last ); # Write and acknowledge a message posting /^F/ && ( &bb_fnd, last ); # Find messages of interest $in{$nm_p} = 'F'; $in{$nm_o} = 'N'; $in{$nm_g} = 0; $in = "$nm_p=$in{$nm_p}&$nm_o=$in{$nm_o}&$nm_g=$in{$nm_g}"; redo; } ################################################################################ ################################################################################ sub bb_msg{ open(FILE,$in{$nm_m}) || die "Could not open file, $dr$md/$in{$nm_m}, stopped"; undef $/; $text = ; $/ = "\n"; # Separate the header from the body in the display. $text =~ s/\n\n/\n

\n/; # Put each element of the header on iy=ts own line. $text =~ s/\nDate:/
\nDate:/; $text =~ s/\nFrom:/
\nFrom:/; $text =~ s/\nSubject:/
\nSubject:/; # Replace blank lines with paragraph breaks. $text =~ s/\n\s*\n/\n

\n/g; # Place paragraph breaks before indented lines. $text =~ s/\n\s+/\n

\n/g; # Get the list of key words if the user specified any. @keys = split(' ',$in{$nm_k}); foreach (@keys){ # Make keywords bold and mark them so the page will be scrolled to the # first ocurrance when the message is displayed. if($in{$nm_c} eq 'I'){ $text =~ s/\b(${_}s?)\b/$1<\/B><\/A>/gi; # Case insensitive } else{ $text =~ s/\b(${_}s?)\b/$1<\/B><\/A>/g; # Case sensitive } } &head('Ocean Planet: bulletin board message'); print <<"--"; $text


Read some more messages.

-- &tail; } ################################################################################ sub bb_lst{ # Get a list of message files. opendir(DIR,"$dr$md") || die "Could not open the bulletin board message directory, $dr$md, stopped"; if(defined($in{$nm_t})){ # If the user specified some types... # Make types look like regular-expression alternatives. ($t = $in{$nm_t}) =~ s/\\0/|/g; # Get the files whose names begin with the specified alternatives. @files = grep(/^($t)_\d{13}$/, readdir(DIR)); } else{ # If the user did not specify any types then get all the message files. @files = grep(/.+_\d{13}$/, readdir(DIR)); } closedir DIR; # Get the list of key words if the user specified any. @keys = split(' ',$in{$nm_k}); # Search for files containing the keywords. if(@keys){ $in{$nm_c} eq 'I' && ($case = 'i'); # Set case insensitivity if requested. # The following code snippet is adapted from: # Programming perl by Larry Wall & Randal L. Schwartz, page 190. # They say it screams. $search = 'while(<>){ study;'; # Build the search. foreach $key (@keys){ # Minimal allowance for keyword plurals $search .= "++\$seen{\$ARGV} if /\\b${key}s?\\b/$case;\n"; } $search .= "}"; @ARGV = @files; undef $/; # Slurp files in one piece. eval $search; # Execute the search. $/ = "\n"; # Reset slurping to 1 line at a time. if($in{$nm_a} eq 'A'){ # Special handling to AND keywords. foreach $file (keys %seen){ delete($seen{$file}) unless $seen{$file} == scalar(@keys); } } @files = keys %seen; } # Print the initial HTML. &head('Ocean Planet: list of bulletin board messages'); unless(@files){ print <<" --"; No messages were found which satisfied all of the constraints of your search. -- &tail; return; } # Put the messages in the specified order. sub by_time { ($t1) = $a =~ /(\d{13})$/; ($t2) = $b =~ /(\d{13})$/; if($in{$nm_o} eq 'O'){ $t1 <=> $t2; } else { $t2 <=> $t1; } } @files = sort by_time @files; $nf=@files; # number of files $ng = int(($nf - 1)/$lpp) + 1; # number of groups $bgn = $in{$nm_g} * $lpp; # first message listed on this page $bgn < $nf || ($bgn = 0); $end = $bgn + $lpp - 1; # last message listed on this page $end < $nf || ($end = $nf - 1); # Let the user reverse the order of the listings. if($in{$nm_o} eq 'O'){ ($qu = $in) =~ s/$nm_o=./$nm_o=N/; $reverse = <<" --"; Entries are listed from the oldest to newest.
Change to list the newest entries first. -- } else{ ($qu = $in) =~ s/$nm_o=./$nm_o=O/; $reverse = <<" --"; Entries are listed from most recent to oldest.
Change to list the oldest entries first. -- } # Assemble the markup for the page-up and page-down buttons. $g = $in{$nm_g} - 1; if($g < 0){ $upstr = $ui; } else{ ($upstr = $in) =~ s/$nm_g=\d+/$nm_g=$g/; $upstr = "$ui"; } $g = $in{$nm_g} + 1; if($g >= $ng){ $downstr = $di; } else{ ($downstr = $in) =~ s/$nm_g=\d+/$nm_g=$g/; $downstr = "$di"; } # Let the user know how many messages are available. if($nf == 1){ print "Only 1 message satisfied all of the constraints of your search.


\n"; $msgcont = 'message contains'; } else{ print "$nf messages satisfied all of the constraints of your search.
\n"; $msgcont = 'messages contain'; } # Indicate what the keywords were if any were specified. if(@keys){ $in{$nm_a} eq 'A' && ($" = "
and ") || ($" = " or "); print "The following $msgcont
@keys.
"; } # First accumulate dates, subjects, links, etc. foreach (@files[$bgn .. $end]){ ($c,$d,$t) = &interp_name($_); open(FILE,$_) || die "Could not open file, $dr$md/$_, stopped"; while($line = ){ (($s) = $line =~ /^Subject: (.*)$/) && last; } $s || ($s = 'Untitled'); ($sl = length($s)) > $msl && ($msl = $sl); # Remember the longest subject. push(@subjects,$s); push(@dates,$d); push(@cats,$c); } # Then print them out in tabular form. $spaces = ' ' x ($msl - length('Subject')); $sub = "Subject$spaces"; print <<"--";
Date       $sub  Category
--
foreach (@types){
  push(@title,split(/$;/));
}
%title = @title;
foreach (@files[$bgn .. $end]){
  $spaces = ' ' x ($msl - length($subjects[$i]));
  $keys = join('+',@keys);
  $qu = "$nm_p=M&$nm_m=$_&$nm_k=$keys&$nm_c=$in{$nm_c}";
  print "$dates[$i]  $subjects[$i]$spaces  ";
  print "$title{$cats[$i]}\n";
  $i++;
}

print <<"--";

Below is a list of all of the available pages of bulletin board listings given the constraints you have specified. You may either use the page-up and page-down buttons or go directly to a page by clicking on the encompassing dates. The encompassing dates for the page you are currently viewing are presented without a hypertext link.
$upstr                 $downstr

--

# Print the links to other groups.
$rows = int($ng/2) + 1;
for($g = 0, $h = $rows; $g < $rows; $g++, $h++){
  push(@g,$g);
  $h < $ng && push(@g,$h);
}
foreach $g (@g){
  print "$bi";
  $b = $g * $lpp;
  $e = $b + $lpp - 1;
  $e < $nf || ($e = $nf - 1);
  ($qu = $in) =~ s/$nm_g=\d+/$nm_g=$g/;
  print "" unless $b == $bgn;
  print((&interp_name($files[$b]))[1]);
  print " »»» ";
  print((&interp_name($files[$e]))[1]);
  print "" unless $b == $bgn;
  ($lf = !$lf) && print("  ") || print("\n");		# Two-column output
}

print "\n\n$reverse\n";
print "
\n"; &tail; } ################################################################################ sub bb_pst{ &head('Ocean Planet: posting to the bulletin board'); print <<"--";

Post a Message to the Bulletin Board

Your browser must be able to support FORMS to use all the functions on this page.

Enter your NAME:

Please give us your e-mail address:

Please enter the SUBJECT of your message:

Click on a button to indicate the CATEGORY of the Bulletin Board you wish to post to:

-- foreach (@types){ ($prefix,$title) = split(/$;/); $prefix eq 'gen' && ($checked = ' CHECKED') || undef $checked; print <<" --"; $title
-- } print <<"--";

Please enter your message in the space below:

To submit your comments, press this button: .

To clear the form, press this button: .

-- &tail; } ################################################################################ sub bb_fnd{ # Get a list of message files. opendir(DIR,"$dr$md") || die "Could not open the bulletin board message directory, $dr$md, stopped"; @files = grep(/.+_\d{13}$/, readdir(DIR)); closedir DIR; &head('Ocean Planet: bulletin board categories and search form'); print <<"--";

Messages that other Ocean Planet visitors have left behind


Below are listed the three general categories of messages that visitors to Ocean Planet Online have left behind. You can look at all messages in a category by clicking on its name. To look at all messages from all categories, click on the Search button.
-- foreach (@types){ ($prefix,$title) = split(/$;/); # Count the number of messages of this type. @f = grep(/^($prefix)_\d{13}$/, @files); $n = scalar(@f); $n == 1 && ($m = 'message') || ($m = 'messages'); if($n){ $m = "$m,"; # Determine the date of the most recent message. ($d,$t) = (&interp_name((reverse(sort(@f)))[0]))[1,2]; $mr = " most recent on $d at $t"; } else{ $mr = ''; } # Print out the link to this type. print <<" --";
$title
($n $m$mr) -- } print <<"--";
You can also search for messages that contain a specific word or topic. Enter the word or words of your choice, select the category of messages that you wish to search by depressing the button to the left of the name of the category above and Search. If you do not select a specific category, you will search through all the messages. Your search can use more than one keyword and you can choose to find messages that must contain all the keywords you have entered (and) or any of them (or).

Keywords [ AND OR ] [ Case insensitive Case sensitive ]:

-- &tail; } ################################################################################ sub bb_wrt{ # Get the current time. local($s,$m,$h,$d,$m,$y,$w,$j,$isdst) = gmtime(time); # Make a date string. local($ds) = sprintf("$wday[$w], %2d $mon[$m] %02d %02d:%02d:%02d UT",$d,$y,$h,$m,$s); # Adjust the year to a 4-digit value. $y += 1900; # Make the day-of-the-year start counting with one instead of zero. $j++; # Make a filename for the message. local($fn) = sprintf("$dr$md/$in{$nm_t}_$y%03d%02d%02d%02d",$j,$h,$m,$s); # Open/create the new file. open(FILE,">$fn") || die "Could not create file, $fn, stopped"; # Write out the message header. print FILE "Date: $ds\nFrom: $in{$nm_n} ($in{$nm_e})\nSubject: $in{$nm_s}\n\n"; # Write out the message body. print FILE "$in{$nm_x}\n"; # Close the file. close FILE; # Acknowledge receipt of the message &head('Ocean Planet: bulletin board posting acknowledgement'); print <<"--";

Thank you for your input.

Read what others have written or see your own message.

-- &tail; } ################################################################################ sub head{ local($title) = @_; print <<"--"; $title $wi


-- } ################################################################################ sub tail{ print <<"--";

$ii Ocean Planet Exhibition Floorplan

$li

$hl

Gene Carl Feldman (gene@seawifs.gsfc.nasa.gov) &
Judith Gradwohl (Curator/Ocean Planet)
Bulletin board script last updated $lu. -- } ################################################################################ sub interp_name{ # This subroutine uses the global arrays, @dpm and @mon. local($c,$y,$d,$h,$m,$s) = $_[0] =~ /^(.*)_(\d{4})(\d{3})(\d{2})(\d{2})(\d{2})$/; &isleap($y) ? ($dpm[1] = 29) : ($dpm[1] = 28); for($mn=0;$d>$dpm[$mn];$d -= $dpm[$mn++]){ ; } $mn <= 11 || die "Weird date format, $_[0], stopped"; $y -= 1900; $d = sprintf("%2d",$d); ($c,"$d-$mon[$mn]-$y","$h:$m:$s UTC"); # Return the category, date, and tine. } ################################################################################ sub isleap{ local($y) = @_; !($y%4) && $y%100 || !($y%400); } ################################################################################