#!/usr/bin/perl
########################
#
# guestbook cgi application demo for web perl class
#
# The assignment was to do this both with and without CGI.pm;
# this is the "use CGI" version; see http://stin.cshl.org/WWW/software/CGI/
#
# The point is three fold : 
#   (a) to see how to use CGI.pm
#   (b) to get more practice writing a perl/cgi, including file I/O
#   (c) to see how form input/output is handled.
#
# To use this thing, just point your browser at it and follow the directions.
#
# Note that the web server must be able to read/write 
# the guestbook file in this directory; 
# with the setuid scripts running in the /home/user/html/cgi/ directories,
# that means everything (including the directory) should be set 
# to "chmod 755".  Remember that incorrect permissions are the cause
# of 4 out of 5 web script problems.  Your mileage may vary.
# 
# As it exists, here, this script is not particularly secure.
# Can you see how to do any upleasant stuff with it?
#
# And there are some behaviors which aren't really the best - 
# in particular, once a user has given a username, they can't change it...
#
# Jim Mahoney
# v0.1 Sep 27 2004
########################
use strict;
use warnings;
use CGI qw(:standard);
use CGI::Carp qw(fatalsToBrowser);

my $title         = "Jim's Guestbook";
my $filename      = "./guestbook_data.txt";
my $cookiename    = "jims_guestbook_cookie";
my $new_entry     = param('data');
my $username      = cookie($cookiename) || param('username');
my $cookie        = cookie( -name  => $cookiename, 
                            -value => $username );
my $error_message = '';

if ($new_entry and not $username){
  $error_message = q{<font color="darkred"> } . 
                   q{Please enter your name as well as a message.</font>};
}

output_to_file($new_entry, $username, $filename) if ($new_entry and $username);
my $all_entries = read_from_file($filename);

print header( -cookie => $cookie );
print 
  start_html( -title => $title ),
  "<h1>$title</h1>",
  start_form(),
  $error_message,
  html_page($all_entries, $username),
  end_form(),
  end_html();
  
# == subroutines =====================================================

# Input: guestbook entries text
# Output: a string with the HTML body of the guestbook page. 
#  (Don't put the starting html or form stuff; we're using CGI.pm for that.)
sub html_page {
  my ($guestbook_entries, $username) = @_;
  my $html;
  if ($username){
    $html .= qq{ <b>Hi $username</b>, welcome back.<br />
      Would you like to leave another note?<p />
    };
  }
  else {
    $html .= qq{<p />
      Enter your name and some text in the provided fields below.<br />
      Then just click the button...<p />
      Your name: <input name="username" type="text" value=""><p />
    };
  }
  $html .= qq{
    <table><tr>
    <td valign="top">Your words of wisdom : </td>
    <td><textarea name="data" rows="8" 
         cols="40">\n  So type something already... </textarea></td>
    </tr></table>
    <input type="submit" value="Click here." />
    <hr noshade size=1>
  };
  $html .= $guestbook_entries if $guestbook_entries;
  $html .= qq{
    <div align="right">
      Questions?  Send some mail to Jim Mahoney
      (<a href="mailto:mahoney\@marlboro.edu">mahoney\@marlboro.ddu</a>).<br />
      <small><a href="with_CGIpm.cgi_html">view source</a></small>
     
    </div>
  };
  return $html;
}

# Inputs:    
#   text      to append to the guestbook, 
#   username  of who's doing it, 
#   filename  where it'll be stored.
# Sideffect: 
#   appends an entry to the given file,
#   with a username, date, and a bit of formatting.
# Output:
#   none
sub output_to_file {
  my ($text, $username, $filename) = @_;
  open DATA, ">> $filename" 
    or die "Oops - couldn't open '$filename' for writing";
  print DATA qq{<table><tr><td><font color="darkgreen"> $username on }
             . scalar(localtime()) . " writes </font></td></tr><tr><td>\n"
             . "<pre>$text</pre>\n"
             . "</td></tr></table>\n"
             . "<hr noshade size=1>";
  close DATA;
}

# Input:  filename
# Output: all text from the file as a single string
sub read_from_file {
  my ($filename) = @_;
  return '' unless -e $filename;
  open DATA, "< $filename"
    or die "oops - couldn't open '$filename' for reading";
  my @lines = <DATA>;
  close DATA;
  return join('', @lines);
}
