#!/usr/bin/perl -- -*- C -*-1# Perl Routines to Manipulate CGI input2# [email protected]3#4# Copyright 1994 Steven E. Brenner5# Unpublished work.6# Permission granted to use and modify this library so long as the7# copyright above is maintained, modifications are documented, and8# credit is given for any use of the library.9#10# Thanks are due to many people for reporting bugs and suggestions11# especially Meng Weng Wong, Maki Watanabe, Bo Frese Rasmussen,12# Andrew Dalke, Mark-Jason Dominus and Dave Dittrich.13# For more information, see:14# http://www.bio.cam.ac.uk/web/form.html15# http://www.seas.upenn.edu/~mengwong/forms/16# Minimalist http form and script (http://www.bio.cam.ac.uk/web/minimal.cgi):17#18# require "cgi-lib.pl";19# if (&ReadParse(*input)) {20# print &PrintHeader, &PrintVariables(%input);21# } else {22# print &PrintHeader,'<form><input type="submit">Data: <input name="myfield">';23#}24# ReadParse25# Reads in GET or POST data, converts it to unescaped text, and puts26# one key=value in each member of the list "@in"27# Also creates key/value pairs in %in, using '\0' to separate multiple28# selections29# Returns TRUE if there was input, FALSE if there was no input30# UNDEF may be used in the future to indicate some failure.31# Now that cgi scripts can be put in the normal file space, it is useful32# to combine both the form and the script in one place. If no parameters33# are given (i.e., ReadParse returns FALSE), then a form could be output.34# If a variable-glob parameter (e.g., *cgi_input) is passed to ReadParse,35# information is stored there, rather than in $in, @in, and %in.36#3738sub ReadParse {39local (*in) = @_ if @_;40local ($i, $key, $val);41# Read in text42if (&MethGet) {43$in = $ENV{'QUERY_STRING'};44} elsif ($ENV{'REQUEST_METHOD'} eq "POST") {45read(STDIN,$in,$ENV{'CONTENT_LENGTH'});46}47@in = split(/&/,$in);48foreach $i (0 .. $#in) {49# Convert plus's to spaces50$in[$i] =~ s/\+/ /g;51# Split into key and value.52($key, $val) = split(/=/,$in[$i],2); # splits on the first =.53# Convert %XX from hex numbers to alphanumeric54$key =~ s/%(..)/pack("c",hex($1))/ge;55$key =~ tr/[^A-Za-z0-9\-\_\$\+\=\~\.\,]//; # allow only safe chars56$val =~ s/%(..)/pack("c",hex($1))/ge;57$val =~ tr/[^A-Za-z0-9\-\_\$\+\=\~\.\,]//; # allow only safe chars58# Associate key and value59$in{$key} .= "\0" if (defined($in{$key})); # \0 is the multiple separator60$in{$key} .= $val;61}62return length($in);63}64# PrintHeader65# Returns the magic line which tells WWW that we're an HTML document66sub PrintHeader {67return "Content-type: text/html\n\n";68}69# MethGet70# Return true if this cgi call was using the GET request, false otherwise71sub MethGet {72return ($ENV{'REQUEST_METHOD'} eq "GET");73}74# MyURL75# Returns a URL to the script76sub MyURL {77return '//' . $ENV{'SERVER_NAME'} . $ENV{'SCRIPT_NAME'};78}79# CgiError80# Prints out an error message which containes appropriate headers,81# markup, etcetera.82# Parameters:83# If no parameters, gives a generic error message84# Otherwise, the first parameter will be the title and the rest will85# be given as different paragraphs of the body86sub CgiError {87local (@msg) = @_;88local ($i,$name);89if (!@msg) {90$name = &MyURL;91@msg = ("Error: script $name encountered fatal error");92};93print &PrintHeader;94print "<html><head><title>$msg[0]</title></head>\n";95print "<body><h1>$msg[0]</h1>\n";96foreach $i (1 .. $#msg) {97print "<p>$msg[$i]</p>\n";98}99print "</body></html>\n";100}101# PrintVariables102# Nicely formats variables in an associative array passed as a parameter103# And returns the HTML string.104sub PrintVariables {105local (%in) = @_;106local ($old, $out, $output);107#$old = $*; $* =1;108$output .= "<DL COMPACT>";109foreach $key (sort keys(%in)) {110foreach (split("\0", $in{$key})) {111($out = $_) =~ s/\n/<BR>/gm;112$output .= "<DT><B>$key</B><DD><I>$out</I><BR>";113}114}115$output .= "</DL>";116#$* = $old;117return $output;118}1191;120121122