# FormData.pl - Perl library file containing getFormData, a
# CGI subroutine for parsing & decoding any submitted form
# Usage: $original_query_string = &getFormData( *name_for_assoc_array );

sub   getFormData  {
  local(*FormData) = @_ if @_; # Make *FormData an alias for the argument
  local($QueryInfo, $request_method, $name_value, $name, $value);

  # Get the query string, depending on the request method: if GET,
  # extract it from the environment; if POST, read it from standard input:
  $request_method = $ENV{'REQUEST_METHOD'};
  if ($request_method eq 'GET') {
    $QueryInfo = $ENV{'QUERY_STRING'};
  } elsif ($request_method eq 'POST') {
    read (STDIN, $QueryInfo, $ENV{'CONTENT_LENGTH'});
  } else {
    print "Content-type: text/html\n\n";
    print "<TITLE>Error parsing form</TITLE>\n";
    print "<H2>Error parsing form</H2>\n";
    print "Request method must be GET or POST, not ``$request_method''\n";
    die("$0: Bad request method: [$request_method]\n");
  }

  # Split $QueryInfo into name=value pairs and convert each pair:
  foreach $name_value (split('&', $QueryInfo)) {

    # Translate any plus signs in the pair-strings into spaces:
    $name_value  =~ tr/+/ /;
    $name_value =~ tr/~!/ ~!/;

    # Split the name=value pair into a separate name and value:
    ($name, $value) = split ('=', $name_value);

    # Translate escaped hex numbers back into 8-bit characters:
    $name  =~ s/%(..)/pack("C", hex($1))/eg;
    $value =~ s/%(..)/pack("C", hex($1))/eg; # it's ok if a value is null

    # Now convert the names and values into named, assigned variables;
    # i.e., use each name as a key in an associative array and associate
    # it with all the values originally paired with that name, separating
    # multiple values for the same name with the null character:

    if (defined($FormData{$name})) {  # If %FormData{$name} already has a
      $FormData{$name} .= "\0$value"; # value, append '\0' as a separator
    } else {                          # before appending the new value.
      $FormData{$name}  =    $value;  # Otherwise, just assign the new
    }                                 # value to %FormData{$name} as is.
  }
  $QueryInfo; # Return the original query string or posted message body.
}

1; # Library files must end with the satement "1;" 
   # to satisfy the require operator.