
#!/usr/bin/perl
#
# formdata.pl
#
# script for parsing form data and saving to local file and emailing
# specialized for ncsa cgi account.
#
# Based on code from Mike Haberman <mikeh@ncsa.uiuc.edu>
#  and Beth Azzi <bethazzi@ncsa.uiuc.edu>
#
# William H. Hsu <bhsu@ncsa.uiuc.edu>
#  Copyright 1999 University of Illinois
#  Last revision: March 10, 1999
#
# Jesse Reichler <reichler@uiuc.edu>
#  Additional modifications and documentation 3/10/99
#


# This is a simple perl script that gets called when a person pushes submit on
#  a form.  It first reads the form data <key,value> pairs, and puts them into
#  a perl hash.  Then it calls a subroutine to save the form data to a local
#  file on the cgi server, then it calls a subroutine to mail the form data to
#  some email account.
# File and email data are appended to include submission time.





# SYSTEM SPEIFIC VALUES
 
# These will need to be changed on different machines, and for different apps.

# the sendmail binary.
$sendmail = "/usr/lib/sendmail";

# base directory and filename for local form data file (note: if filename is to
#  be based on form field, this should be done below).
$localfiledir="/tmp/";
$filename = $localfiledir . "bndev.formdata.txt";

# file permissions to chmod the form data file to (if 0 chmod will not be run)
# this needs to be set in a way that allows cgi server to write file
#   (640 = owner readwrite, group read, other noaccess)
#   (650 = owner readwrite, group readwrite, other noaccess)
$filechmod = 0640;

# hardcoded title of the form, to be displayed to user after submission
$formtitle="ANNCBT/IWGGEC JOINT WORKSHOP REGISTRATION FORM";
$htmlheader="Your form has been parsed as follows:<BR>\n";
$htmlfooter="Thank you.<BR>\n";

# email addresses to mail form data (note @ signs should be escaped-out via \)
#  multiple addresses can be separated by spaces
$email="hpguo\@ksu.edu";







# MAIN PROGRAM

# Initialize globals (data hash, current_time, etc.)
&Initialize();

# Create "fake" form data entries for current time, etc.
&FakeData();

# Store form data in hash
&ReadData();

# To show the submitter what he/she submitted:
&PrintData();


# Now we want to save the data to a local file.  What is the name of the local
#   file the data should be APPENDED to?

# If we want the file which we save to, to be based on a form field, we do it here.
#$filename = $localfiledir . $data{"registrant-name"} . "txt";

# Print form data to local file
&FileData($filename);


# Email the data to someone
&EmailData($email);












# SUBROUTINES


sub Initialize()
{
    # Initialize globals (hash, current_time, etc.)

    # clear hash table used to store form data
    $Data = {};

    # get pretty version of current time
    $curtime=time();
    ($csec,$cmin,$chour,$cmday,$cmon,$cyear,$cwday,$t,$t) = localtime($curtime);
    $cthisday=(sun,mon,tue,wed,thu,fri,sat)[$cwday];
    $cthismon=(jan,feb,mar,apr,may,jun,jul,aug,sept,oct,nov,dec)[$cmon];

    # Clear the file error flag, used to indicate in email if a file error has occured
    $fileerror=0;
}


sub FakeData
{
    # Create fake form fields which contain the current pretty time and form name
    $Data{"ReceivedDate"}="$chour:$cmin $cthisday $cmon/$cyear";
    $Data{"FormTitle"}=$formtitle;

    # Might be nice to add fields for other environment stuff like machine name, etc.
}



sub ReadData
{
    my($Buffer,@Pairs,$Key,$Value,$Pair);
    
    #
    # parse form data and store into hash so it can be accessed by name
    # e.g $value = $Data{"registrant-name"};
    #

    # first see if we're called by a GET or a POST, and get our data properly.
    # "GET"s pass data to us via arguments.
    # "POST"s pass data to us via an environment variable.
    
    if ($ENV{'REQUEST_METHOD'} eq "POST")
    {
	read(STDIN, $Buffer, $ENV{'CONTENT_LENGTH'});
	@Pairs = split(/&/, $Buffer);
    }
    else
    {
	@Pairs = split(/&/, $ENV{'QUERY_STRING'});
    }
    
    # now that we have the data, let's undo any urlencoding
    
    foreach $Pair (@Pairs)
    {
	($Key, $Value) = split(/=/, $Pair);
	$Value =~ tr/+/ /;
	$Key =~ tr/+/ /;
	$Value =~ s/%([a-fA-F0-9][a-fA-F0-9])/pack("C", hex($1))/eg;
	if ($Data{$Key} eq "")
	{
	    # set the value
	    $Data{$Key} = $Value;
	}
	else
	{
	    # append the value
	    $Data{$Key} .= "," . $Value;
	}
    }
}



sub PrintData
{
    # this procedure used to debug the parsing of data, and to confirm to the user what they submitted
    print "Content-type: text/html\n\n";
    print "<HTML><HEAD>\n";
    print "<TITLE>" . $formtitle . "</TITLE>\n";
    print "<H1>" . $formtitle . "</H1><BR>\n";
    print "</HEAD>\n";
    print "<BODY bgcolor=#ffffff>\n";

    print $htmlheader;

    print "<HR>";
    foreach $key (keys (%Data))
    {
	print $key . " = " . $Data{$key} . "<BR>\n";
    }
    print "<HR>";

    print $htmlfooter;
    print "</BODY>\n"
}



sub FileData
{
    # APPEND the data to the filename passed
    local ($filename)=@_;
    local $spacers;
    
    # open the file in append mode
    if ( !open(fpData, ">>" . $filename))
    {
	&error("Could not open local data file to save form data.");
	$fileerror=1;
	return;
    }

    if ($filechmod != 0)
    {
	# set permissions of file
	chmod($filechmod,$filename);
    }
    
    foreach $key (keys (%Data))
    {
	print fpData "$key=";
	$spacers=30-length($key);
	if ($spacers<1)
	{
	    $spacers=1;
	}
	printf fpData "%" . $spacers."s"," ";
	print fpData $Data{$key};
	print fpData "\n";
    }

    print fpData "-----------------------------------------------------------------------------\n";

    # close the file
    close(fpData);
}




sub EmailData
{
    # Email the form data to the address passed
    local ($emailtarget)=@_;

    if ($emailtarget eq "")
    {
	# they don't really want to send email
	return;
    }

    # Open pipe to the mail program
    # Warning: even if the sendmail program is not found, an error will NOT occur here!
    if (!open(MAIL,"| $sendmail $emailtarget") )
    {
	&error("Could not fork mail program in order to email a copy of form data to administrator.");
	exit(-1);
    }

    # spacer at start of mail
    print MAIL "\n\n";

    # if there was an error writing the local file, mention this
    if ($fileerror)
    {
	print MAIL "NOTE: there was an error saving this form data to the local file.\n";
	print "(a copy of the form data was emailed to the administrator).<BR>\n";
    }

    print MAIL "-----------------------------------------------------------------------------\n";
    foreach $key (keys (%Data))
    {
	print MAIL "$key=";
	$spacers=30-length($key);
	if ($spacers<1)
	{
	    $spacers=1;
	}
	printf MAIL "%" . $spacers."s"," ";
	print MAIL $Data{$key};
	print MAIL "\n";
    }

    print MAIL "-----------------------------------------------------------------------------\n";
    print MAIL "\n";

    # Close the mail pipe and it's on it's way
    close (MAIL);
}




# simple error routine to print html error
sub error
{
    ($message) = @_;
    print("<b>ERROR:<b>", $message, "<p>Contact the author of the previous page for assistance.<BR>\n");
}



