#!/srvtools/http/bin/perl -w
##!/usr/local/bin/perl -w

#############################################################################
#  
#  The LivingPage(TM) software is copyrighted by Community School Networks
#  and the Northeast Parallel Architectures Center at Syracuse University.   
#
#  For more information, see http://www.infomall.org/CSNet/LivingPage/
#  
#  Name: Add URL Item Object  
#  
#  File: AddURL.pl
#
#  Author: Paul Coddington
#
#  Version: 0.2  
#
#  Date: 17-Jan-96 
#
#  Input: CGI input ('QUERY_STRING') 
#          QUERY_STRING: $filename      (the file to be updated)
#                        $listname      (the list to be updated)
#                        $url           (the URL to be added)
#                        $title         (the title of the document)
#                        $description   (a description of the document)
#                        $name          (name of the submitter)
#                        $email         (email of the submitter)
#                        $institution   (institution of the submitter)
#                        @lpvar         (for TEMPLATE option) 
#
#  Output: Add an HTML entry to list $listname in document $filename.
#  The default is to add a hyperlink to a document (specified by a
#  URL and title) annotated by some description of the document, and 
#  an HTML comment specifying the name of the person submitting the
#  entry along with the date.
#
#  The listname, the format of the list, and where the new entry should be
#  positioned in the list, are all described by the LIVINGPAGE tag, which
#  indicates which part of the document is writable. 
#
#  It is also possible using the TEMPLATE option to add an arbitrary
#  format entry, in which case the variables in the array @lpvar
#  could be anything. 
#
#  TO BE ADDED:
#      File locking
#      URL checking
#      Template
#      Security (do we need it to sends a magic cookie or something
#                so people can't mock up the http request?)
#
#   History:
#
#    Ver   Date       Comments
#    -----------------------------------------------------------------------
#    0.2   17-Jan-96  Implemented most of the parameters -- different types 
#                     of list, contributor information, filename specified 
#                     in the form, etc. Added preview.
#    0.1   16-Aug-95  Initial very basic implementation with everything
#                     hard-wired (no parameters)
#
#############################################################################


#####################################
#  
# MAIN FUNCTION
#  
#####################################

require "../cgiconf.pl";  # Contains the server variables
require "npac-lib";
require "ConfirmAddition.pl";     # Confirm the update

$docroot = "$ENV{'INFOMALL_DOCROOT_RW'}";
$docurl = "$ENV{'INFOMALL_URL_RO'}";
$lphome = "$docroot/lp";

%in = ();
&ParseArg(*in);		# Parse arguments passed by http server

# DEBUG
# &PrintHeader;
# print STDOUT "DEBUG ON \n";

&EditPage;            # Do the edit
&ConfirmAddition($filename,$listname,$pagetitle);     # Confirm the update


#############################################################################
#  
#   SUBROUTINES
#
#############################################################################


#####################################
# Edit the Page
#####################################
sub EditPage {          
   
  $date = `date`;
  chop($date);

  # Sort out the variables passed from the form 
  $filename = $in{'filename'};
  $listname = $in{'listname'};
  $url = $in{'url'};
  $title = $in{'title'};
  $description = $in{'description'};
  $name = $in{'name'};
  $email = $in{'email'};
  $pagetitle = $in{'pagetitle'};

  # Split out the directory and the filename from $filename
  @tmp = split(/\//, $filename);  # split on directory delimeter, i.e. /
  $file = pop(@tmp);  # Remove the last element of tmp, i.e the filename
  $glue = "/";
  $directory = join($glue, @tmp);  # join to create directory name

  # Construct the filename for the template for the LivingPage file
  $template = $filename;
  $template =~ s^\.html^\.template^;   # Replace the file extension

  # Open the template file

  # Construct the filename for the data file for the list, which is 
  # $directory/$listname.data, with underbars replacing spaces in $listname
  # (replace other Unix chars that can't be in filenames, like ! and &)
  $listfile = $listname;
  $listfile =~ s^ ^_^;
  $datafile = "$directory/$listfile.data";

  # Open the data file for the list, and append the new entry
  if (-e $datafile) {
     system("cp $datafile $datafile.bak");
  } 
  open(DATAFILE, ">> $datafile") ||
       print "Content-type\: text/html\n\n\n Cannot open $datafile\: $!";
  print DATAFILE "$url\005$title\005$description\005$name\005$email\005$date\n";  
  close(DATAFILE);

# DEBUG
# print STDOUT "<BR> filename = $filename \n";
# print STDOUT "<BR> listname = $listname \n";
# print STDOUT "<BR> url = $url \n";
# print STDOUT "<BR> title = $title \n";
# print STDOUT "<BR> description = $description \n";
# print STDOUT "<BR> name = $name \n";
# print STDOUT "<BR> email = $email \n";
##
# print STDOUT "<BR> file = $file \n";
# print STDOUT "<BR> directory = $directory \n";
# print STDOUT "<BR> template = $template \n";
# print STDOUT "<BR> datafile = $datafile \n";
# return 0;
  
  # Check that the filename is correct 
  # (and we have permission to open it?)
  if (!open(LIVINGPAGE, $filename) ) {
	&PrintHeader;
 	print "cannot open $filename";
 	return 0;
  }
  close(LIVINGPAGE);

#
# Do an "in place" edit on the LivingPage, i.e. copy $filename
# to $filename~ and create a new $filename with the addition appended
#
  $^I = "~"; 
  @ARGV = ($filename);
  $living = 0;
  $continue = 0;
  $found = 0;
  $para = 0;

# DEBUG
# print STDOUT "<BR> Opening $filename \n";

  while (<>) {

# DEBUG
# print STDOUT "Next: $_";

    if (/<LIVINGPAGE/i) {   # Find the <LIVINGPAGE> tag (ignore case)

# DEBUG
# print STDOUT "<BR> Found the LIVINGPAGE tag \n";

      if (/>/) {           # Found the end of the <LIVINGPAGE> tag 
        &ParseTag;           # Get information from the tag parameters
        if ("\U$thislistname" eq "\U$listname") {  # Check it's the right list
          $living = 1;
          $found = 1;

# DEBUG
# print STDOUT "<BR> Found the right list = $listname \n";

        }
        else {
          $living = 0;

# DEBUG
# print STDOUT "<BR> Not the right list = $listname \n";

        }
      }
      else {
        $continue = 1;
        $tag = $_;  # Store this line 
      }
      print;
      next;
    }
    if ($continue) {   # Read another line to get all the LIVINGPAGE tag info
      $tag .= $_;  # Append the new line 
      if (/>/) {   # Found the end of the <LIVINGPAGE> tag 
        $_ = $tag;  
        &ParseTag;           # Get information from the tag parameters
        $continue = 0;
        $living = 1;
      }
      print;
      next;
    }    
    if ($living) {  # This is the list we want to update
       if ( ((/<UL>/i) || (/<OL>/i) || (/<DL>/i)) && ($position eq "TOP")) {  
          # Add the new site
          print;
          &AddSite;           
          $living = 0;
          next;
       }
       if ( ((/<\/UL>/i) || (/<\/OL>/i) || (/<\/DL>/i)) && ($position eq "BOTTOM")) {  
          # Add the new site
          &AddSite;           
          $living = 0;
          print;
          next;
       }
       if (/<\/LIVINGPAGE>/i) {  # No list yet, so need to start one
          if ($list eq "UL") { 
            print "<UL>\n";
            &AddSite;           
            print "</UL>\n";
          } 
          if ($list eq "OL") { 
            print "<OL>\n";
            &AddSite;           
            print "</OL>\n";
            print;
          } 
          if ($list eq "DL") { 
            print "<DL>\n";
            &AddSite;           
            print "</DL>\n";
          } 
          if ($list eq "IMG") { 
            &AddSite;           
          } 
          if ($list eq "TEMPLATE") { 
            &AddSite;           
          } 
          print;
          $living = 0;
          next;
       }
       if (/<P>/i) {  # Put paragraph markers between the list elements
         $para = 1;
         print;
       }
       # else 
       print;
    }
    else {  # Just regurgitate the line
         print;
    }
  }
}




#########################################
# Parse the LIVINGPAGE tag information 
#########################################
sub ParseTag {    
     
  if (/NAME=/i) {   # Find the list NAME (ignore case)
    &WordAfter("NAME=");
    $thislistname = $nextword;

# DEBUG
# print STDOUT "<BR> ParseTag: listname = $thislistname \n";

  }
     
  if (/LIST=/i) {   # Find the LIST type (ignore case)

    # Find the list type
    &WordAfter("LIST=");
    $list = $nextword;

# DEBUG
# print STDOUT "<BR> ParseTag: list = $list\n";

    if ($list eq "IMG") {     # Use image for bullet  
      if (/SRC=/i) {   # Find the SRC tag (ignore case)
        &WordAfter("SRC=");
        $imgfile = $nextword;
      }
      else {
        $error = "SRC file not specified for IMG tag.";
      }
      if (-e $imgfile) {   # Find the image file
        $src = 0;
      }
      else {
        $src = 1;
        $error = "Cannot find SRC file $imgfile for IMG tag.";
      }
    }
    if ($list eq "TEMPLATE") {   
      if (/SRC=/i) {   # Find the SRC tag (ignore case)
        &WordAfter("SRC=");
        $template = $nextword;
      }
      else {
        $error = "SRC file not specified for TEMPLATE tag.";
      }
      if (-e $template) {   # Find the template file
        $src = 0;
      }
      else {
        $src = 1;
        $error = "Cannot find SRC file $template for TEMPLATE tag.";
      }
    }
  }
  else {
    $error = "LIST type not specified.";
  }
     
  if (/POSITION=/i) {   # Find the POSITION (ignore case)
    &WordAfter("POSITION=");
    $position = $nextword;

# DEBUG
# print STDOUT "<BR> ParseTag: position = $position\n";

  }
  else {
    # Put it at the end
    $position = "BOTTOM";
  }

}


#########################################
# Find the word after the given expression
#########################################
sub WordAfter {
  $prevstring = $_[0];
  # Find everything after $prevstring (ignore case)
  ($junk,$wordstring) = split(/$prevstring/i);  

  if ($wordstring =~ /^"/) {  # The first non-whitespace character is a quote

    # Grab what's inside the quotes
    # Remove the first quotation mark
    $wordstring =~ s/"//;   

    # and then split out everything before the next quotation mark
    ($word,$junk) = split(/"/, $wordstring);  
  }
  else { 

    # Grab the next word
    ($word,$junk) = split(/\s+/,$wordstring);  # Split out the first word
    $word =~ s/"//g;                           # Remove any unwanted quotes
  }

  if ($prevstring ne "NAME=") { 
    $word = "\U$word";           # Convert to upper case
  }

  $word =~ s/>//;
  $nextword = $word;

}    


#########################################
# Add the information for the new site
#########################################
sub AddSite {    

# DEBUG
# print STDOUT "<BR> AddSite: list = $list\n";


   if ( ($list eq "UL") || ($list eq "OL") ) {
     print "\n";
     print "<!-- Added by $name ($email) on $date -->\n";
     if ($para) {
       print "<P>\n";
     }
     print "<LI>\n";
     print "<A HREF=\"$url\">$title</A> \n";
     print "$description \n";
   }
   if ($list eq "DL") {
     print "\n";
     print "<!-- Added by $name ($email) on $date -->\n";
     if ($para) {
       print "<P>\n";
     }
     print "<DT>\n";
     print "<A HREF=\"$url\">$title</A> \n";
     print "<DD>\n";
     print "$description \n";
   }
}


#########################################
# Add the information using a TEMPLATE 
#########################################
# sub UseTemplate {    
# }


### DEBUG

sub Debug {
    local($debug_string) = @_;
    print "Content-type\: text/html\n\n";
    print "$debug_string \n";
}



##########################################################################
# Standard CGI interface stuff
#########################################


sub PrintHeader {                      # Print out the Header for HTML
  print "Content-type: text/html\n\n";
  print "\n";
}


sub ParseArg {                        # reads the passed arguments
    local ($i, $loc, $key, $val);
    local (*in) = @_;

    if ($ENV{'REQUEST_METHOD'} eq "GET") {                      # Read in text
       $in = $ENV{'QUERY_STRING'};
    } elsif ($ENV{'REQUEST_METHOD'} eq "POST") {
      for ($i = 0; $i < $ENV{'CONTENT_LENGTH'}; $i++) {
        $in .=getc;
      }
    }

    @in = split(/&/,$in);

    foreach $i (0 .. $#in) {
      $in[$i] =~ s/\+/ /g;                          # Convert plus's to spaces
      $in[$i] =~ s/%(..)/pack("c",hex($1))/ge;
                                # Convert %XX from hex numbers to alphanumeric
      $loc = index($in[$i], "=");                  # Split onto key and value.
      $key = substr($in[$i],0,$loc);
      $val = substr($in[$i],$loc+1);
      $in{$key} .= '\0' if (defined($in{$key})); # \0 is the multiple separator
      $in{$key} .= $val;
   }
}
1;


