The Survey Script

The survey script will accept input from an HTML Form and format it into rows of data suitable for loading into various analysis programs. One of the easiset ways to get the data is merely pull the datafile up in your web browser then cut&paste from it to your software window. I have used this successfully with SAS, Lotus, and Excel.

The following files are good example files:

Here are the sections in this particular page
  1. Calling the Script
  2. Output Files
  3. Formatting the Data
  4. Security
  5. Sending Messages to Users

Calling the Script

The script is called from the FORM html field and you can pass in the name of a data file on the command line. Be sure to have already created both the default.data and the passed in name.data files and done the correct chmod on them so anyone can write data to those files.

For example, the sample form is called as

<FORM METHOD="POST" ACTION="/cgi-bin/mmoxcey/survey.pl?survey.data">
which means it is accessing the survey.pl file in the /cgi-bin/mmoxcey directory on the current server and is passing in the data file to write to: survey.data

Output Files

The script has this source code
########
# main #
########
if (defined($ARGV[0])) {
  $datafile=$ARGV[0];
  }
else {
  $datafile = "default.data"; 
  }
open (DATAFILE, ">> $datafile") || &error('open_file');

which means it looks for a datafile name on the cammand line and if there isn't one, then it opens default.data in the directory where the script resides. You can of course open other files to write data to. For example, in the equine_survey script, I wrote analyzable data to one file (passed in ont he command line) and wrote the comments to a different file using this source code:
$commentfile = "/home/htdocs/equine_survey/comments.data"; 

open (COMMFILE, ">> $commentfile") || &error('open_comm_file');


and then, based on the name of the data, I would write the specific comment fields (50, 60 or 70) to that file
# print data structure 
  foreach $ky (sort(keys %Datarray)) 
  {
    if ($ky eq '50' || $ky eq '60' || $ky eq '70') 
    {
       if ( $Datarray{$ky} ne '') 
       {
           print (COMMFILE "$ky=$Datarray{$ky}$sepchar");
       }
    }
    else 
    {
       print (DATAFILE "$Datarray{$ky}$sepchar");
    }
  }

Formatting the Data

The script orders your data based on field names so I "name" them numbers so they sort correctly such as 01, 02, 03 etc. This is done in the html form using the NAME parameter. Here are the first two questions and I NAMEd the fields 01 and 02:

1. Enter the number of equine you currently own: <INPUT TYPE="text" NAME="01" VALUE="0" SIZE=4> <p> <!-- Number 02 --> 2. Enter your zip code: <INPUT TYPE="text" NAME="02" VALUE="00000" SIZE=10> 


The script uses a SEPCHAR variable as the SEParating CHARacter: the stuff uses to separate between different fields. You can use anything except an underscore because the script translates the $sepchar into an underscore. Here is how SEPCAHR is defined:


$sepchar=" "; # a space is best for import into SAS

and here, under the sub program "parse_data" is where it is translated into underscores (inside a foreach loop so it gets everything):
  $Datarray{$key} =~  s/$sepchar/_/g;   #strip sepchar

If you want a different character, change it there.

Output

The output is printed as NAME=VALUE NAME=VALUE with a line return at the end of each record. If you want to change the equal character, or drop the NAME, then it is done in the parse_data sub routine:
print (DATAFILE "$ky=$Datarray{$ky}$sepchar");

The first $ky is the NAME field. The second one is used to pull the value out of the associative array so don't modify it. "$Datarray{$ky}" is the entire name of the actual data field. The $sepchar is the separator and explained elsewhere on this page.

Security

There are several options for making a survey more secure.
  1. Don't let people write a script to automatically submit data to the form.. The "referers" array keeps track of legal addresses the script can be called from:
    @referers = ('www.aphis.usda.gov','151.121.3.135','file:///C|/_/WRK/survey/es1.html','file:///H|/MMOXCEY/survey/es1.html');
  2. Strip meta-characters from inputs that may allow people to exit to the operating system and run commands. I have generic code in the parse_data sub program inside the foreach loop.
  3.   $key =~ s/%(..)/pack("c",hex($1))/ge;
      $val =~ s/%(..)/pack("c",hex($1))/ge;

  4. Check the address and time each row is submitted so you can get rid of people hitting Submit time after time. Here is how that info (rec'd from environment vars) is written:
  5.   print (DATAFILE "IP: $ENV{'REMOTE_ADDR'} $sepchar");
      print (DATAFILE "Secs: $^T$sepchar");
      print (DATAFILE "Date:");
      print (DATAFILE &ctime(time));

Sending Messages to Users

After a user submmits the data or if there is an error, then you should send them a page informing them of success or failure. The survey script does that under various sub programs. To change these, you merely put in the HTML page between the print << and the label that you assigend after it. For example, the following source code labels the end of printing as EOM2 (end of message 2) and everything until the line all by itself with EOM2 on it is sent direct to the user's web browser. The only hting I had to do extra was "escape" the at sign (2) with a backslash character so it would interpret the mailto url correctly.
print <<EOM2;
Contact Mike Moxcey at <a href="mailto:mmoxcey\@aphis.usda.gov">
mmoxcey\@aphis.usda.gov</a>
or 970-490-7980
EOM2

Mike Moxcey Feb 1997