Processing Form Data in Shell CGI Scripts[转]

简介: Processing Form Data in Shell CGI Scripts This page presents a little /bin/sh shell script that will help you processing form data in a CGI shell script, without needing C or perl. You receive

Processing Form Data in Shell CGI Scripts

This page presents a little /bin/sh shell script that will help you processing form data in a CGI shell script, without needing C or perl. You receive the form values straight into your shell environment, where you can then access them just like other shell variables. About no special requirements are needed, it just uses the standard Unix utilities ddtestgrepcutdc and echo. The latter must be able to print arbitrary octal codes.
Note: Writing this script was interesting, but the program is also kind of a joke. I wanted to prove that it is indeed possible to pick apart CGI data with a shell script, and I succeeded. Yet the script has some deficiencies.

Don't get me wrong. Programming CGI shell scripts isn't a bad idea in general, it indeed works quite well for small jobs. But evaluating the form datashouldn't be done in a script.

One problem is that this script is slow. For biting its way through the data string, it must continuously invoke the afore-mentioned utilities. Hundreds of times. Second, there are a few tiny differences in the tools' implementations on various platforms, so in rare cases, obscure problems may occur.

I never expected the overwhelming feedback on my script. Unfortunately, it didn't always work out perfectly. It is much better having an integrated piece of C code that does the job than a shell script. I have decided to write such a tool, proccgi, to help all folks that were having problems getting the script to work. Unless you know what you're doing, or are looking for fascinating shell scripts, please use that program to evaluate form data in your shell CGI scripts instead, it's much easier to use.

If you are currently using the script on your site, you can simply switch over to proccgi. It works the same, and you only need to change a single line of code in your CGI scripts.

A big thank you to all who have used this shell script in the past, present, and future, and to those who commented on it.

Yet another option is to switch to the Tcl language for CGI scripting. It's powerful and easy to use; I use it for most of my scripting these days. Of course I also have a Tcl script for CGI data evaluation: proccgi.tcl.

Now back to the shell script ...

Features

  • Handles both GET and POST methods transparently.
  • Also accepts assignments on the command line (great for testing).
  • If the extra pathname features assignments (like /A=trash), it is processed as well.
  • Handles '+' (replaced by space) and '%XX' sequences.
  • Exports all found variables to the shell environment.
  • Can also handle multiline "Textarea" input fields.

Bugs

Most of them are shell limitations, and there isn't much I can do to fix them. Should you find a solution, tell me!
  • All exported variables are case sensitive.
  • Cannot properly handle newlines (%0A); they are replaced by spaces.
  • Hex escapes must be uppercase. This should be guaranteed by the remote browser.
  • Slow.

Usage

After downloading the script (with a name of 'proccgi.sh' or whatever) and installing it (don't forget to grant exec permission), all left to do in your own scripts is to call
eval `proccgi.sh $*`
In some cases, you might need to give the full pathname if it's not found automatically. After this call, you have everything in your shell.

If something goes wrong, you can also enable some debugging output by setting the variable DEBUG to 1, causing a log to be printed to standard error. To get a debugging logfile, you would call

DEBUG=1
export DEBUG
eval `proccgi.sh $* 2> logfile`

Example

This is a very simple example of an automatic software-by-email program. You can fill in your email address and a file name which is then automatically mailed to you.Do not, I repeat, do not install this piece of code. It would be a major security leak.

The Form

<form action="http://our-server/cgi-stuff/mailer" method="post">
<dl>
  <dt> Your Email <dd> <input name="email" size="50">
  <dt> Filename   <dd> <input name="file"  size="50">
</dl>
<input type="submit" value="Submit">
</form>

The Script

#!/bin/sh
eval `proccgi.sh $*`
mail $FORM_email < $FORM_file
cat - << \END
echo Content-type: text/plain
echo
echo done.
END
As you can see, after the call to proccgi.sh, the email address from the form is stored in the shell variable $FORM_email, and the file name is in $FORM_file.

Note

This was just an experiment for me to experience myself what's possible with shell scripts. I know it's not perfect, but I'm missing the time to put much more efforts into it. If you desperately need a feature, read man sh and fix it yourself.

The script may be freely used and distributed at no charge provided that the copyright notice remains at its top.

Script & Code

Don't forget to download the code, proccgi.sh.

http://www.fpx.de/fp/Software/ProcCGIsh.html

#!/bin/sh
#
# Process input to a CGI script. Written and Copyright 1995 Frank Pilhofer
# You may freely use and distribute this code free of charge provided that
# this copyright notice remains.            fp@informatik.uni-frankfurt.de
#
# All variables in here are prefixed by _F_, so you shouldn't have
# any conflicts with your own var names
#
# get query string. if $REQUEST_METHOD is "POST", then it must be read
# from stdin, else it's in $QUERY_STRING
#
if [ ${DEBUG:-0} -eq 1 ] ; then
	echo --Program Starts-- 1>&2
fi
#
if [ "$REQUEST_METHOD" = "POST" ] ; then
	_F_QUERY_STRING=`dd count=$CONTENT_LENGTH bs=1 2> /dev/null`"&"
	if [ "$QUERY_STRING" != "" ] ; then
		_F_QUERY_STRING="$_F_QUERY_STRING""$QUERY_STRING""&"
	fi
	if [ ${DEBUG:-0} -eq 1 ] ; then
		echo --Posted String-- 1>&2
	fi
else
	_F_QUERY_STRING="$QUERY_STRING""&"
	if [ ${DEBUG:-0} -eq 1 ] ; then
		echo --Query String-- 1>&2
	fi
fi
if [ ${DEBUG:-0} -eq 1 ] ; then
	( echo "  " $_F_QUERY_STRING
	  echo --Adding Arguments-- ) 1>&2
fi
#
# if there are arguments, use them as well.
#
for _F_PAR in $* ; do
	_F_QUERY_STRING="$_F_QUERY_STRING""$_F_PAR""&"
	if [ ${DEBUG:-0} -eq 1 ] ; then
		echo "  " arg $_F_PAR 1>&2
	fi
done
if [ ${DEBUG:-0} -eq 1 ] ; then
	( echo --With Added Arguments--
	  echo "  " $_F_QUERY_STRING ) 1>&2
fi
#
# if $PATH_INFO is not empty and contains definitions '=', append it as well.
# but replace slashes by ampersands
#
if echo $PATH_INFO | grep = > /dev/null ; then
	_F_PATH_INFO="$PATH_INFO""//"
	if [ ${DEBUG:-0} -eq 1 ] ; then
		( echo --Adding Path Info--
		  echo "  " $_F_PATH_INFO ) 1>&2
	fi

	while [ "$_F_PATH_INFO" != "" -a "$_F_PATH_INFO" != "/" ] ; do
		_F_QUERY_STRING="$_F_QUERY_STRING""`echo $_F_PATH_INFO | cut -d / -f 1`""&"
		_F_PATH_INFO=`echo $_F_PATH_INFO | cut -s -d / -f 2-`
	done
fi
#
# append another '&' to fool some braindead cut implementations. Test yours:
# echo 'i am braindead!' | cut -d '!' -f 2
#
_F_QUERY_STRING="$_F_QUERY_STRING""&"
#
if [ ${DEBUG:-0} -eq 1 ] ; then
	( echo --Final Query String--
	  echo "  " $_F_QUERY_STRING ) 1>&2
fi
#
while [ "$_F_QUERY_STRING" != "" -a "$_F_QUERY_STRING" != "&" ] ; do
	_F_VARDEF=`echo $_F_QUERY_STRING | cut -d \& -f 1`
#	_F_QUERY_STRING=`echo $_F_QUERY_STRING | cut -d \& -f 2-`
	_F_VAR=`echo $_F_VARDEF | cut -d = -f 1`
	_F_VAL=`echo "$_F_VARDEF""=" | cut -d = -f 2`

#
# Workaround for more braindead cut implementations that strip delimiters
# at the end of the line (i.e. HP-UX 10)
#

	if echo $_F_QUERY_STRING | grep -c \& > /dev/null ; then
		_F_QUERY_STRING=`echo $_F_QUERY_STRING | cut -d \& -f 2-`
	else
		_F_QUERY_STRING=""
	fi

	if [ ${DEBUG:-0} -eq 1 ] ; then
		( echo --Got Variable--
		  echo "  " var=$_F_VAR
		  echo "  " val=$_F_VAL
		  echo "  " rem=$_F_QUERY_STRING ) 1>&2
	fi
	if [ "$_F_VAR" = "" ] ; then
		continue
	fi

#
# replace '+' by spaces
#

	_F_VAL="$_F_VAL""++"
	_F_TMP=

	while [ "$_F_VAL" != "" -a "$_F_VAL" != "+" -a "$_F_VAL" != "++" ] ; do
		_F_TMP="$_F_TMP""`echo $_F_VAL | cut -d + -f 1`"
		_F_VAL=`echo $_F_VAL | cut -s -d + -f 2-`

		if [ "$_F_VAL" != "" -a "$_F_VAL" != "+" ] ; then
			_F_TMP="$_F_TMP"" "
		fi
	done

	if [ ${DEBUG:-0} -eq 1 ] ; then
		echo "  " vrs=$_F_TMP 1>&2
	fi

#
# replace '%XX' by ascii character. the hex sequence MUST BE uppercase
#

	_F_TMP="$_F_TMP""%%"
	_F_VAL=

	while [ "$_F_TMP" != "" -a "$_F_TMP" != "%" ] ; do
		_F_VAL="$_F_VAL""`echo $_F_TMP | cut -d % -f 1`"
		_F_TMP=`echo $_F_TMP | cut -s -d % -f 2-`

		if [ "$_F_TMP" != "" -a "$_F_TMP" != "%" ] ; then
			if [ ${DEBUG:-0} -eq 1 ] ; then
				echo "  " got hex "%" $_F_TMP 1>&2
			fi
			_F_HEX=`echo $_F_TMP | cut -c 1-2 | tr "abcdef" "ABCDEF"`
			_F_TMP=`echo $_F_TMP | cut -c 3-`
#
# can't handle newlines anyway. replace by space
#
#			if [ "$_F_HEX" = "0A" ] ; then
#				_F_HEX="20"
#			fi

			_F_VAL="$_F_VAL""`/bin/echo '\0'\`echo "16i8o"$_F_HEX"p" | dc\``"
		fi
	done

#
# replace forward quotes to backward quotes, since we have trouble handling
# the former ones.
#

	_F_VAL=`echo $_F_VAL | tr "'" '\`'`

#
# if debug, send variables to stderr
#

	if [ ${DEBUG:-0} -eq 1 ] ; then
		( echo --Final Assignment--
		  echo "FORM_$_F_VAR"=\'$_F_VAL\' ) 1>&2
	fi

#	/bin/echo "FORM_$_F_VAR"=\'$_F_VAL\'
	/bin/echo "FORM_$_F_VAR"="'"$_F_VAL"'"
done
#
if [ ${DEBUG:-0} -eq 1 ] ; then
	echo done. 1>&2
fi
#
# done.
#
exit 0


http://cyent.blog.51cto.com/905592/829034

目录
相关文章
|
11月前
[metasploit]msf启动:msf failed to load and returned this error 'cannot load such file -- bundler/setup'
[metasploit]msf启动:msf failed to load and returned this error 'cannot load such file -- bundler/setup'
|
Python
问题解决:Script file ‘Scripts\pip-script.py‘ is not present.
问题解决:Script file ‘Scripts\pip-script.py‘ is not present.
308 0
问题解决:Script file ‘Scripts\pip-script.py‘ is not present.
|
关系型数据库 MySQL 应用服务中间件
linux篇-Parse error: syntax error, unexpected ‘new’ (T_NEW) in /usr/local/nginx/html/cacti/lib/adodb
linux篇-Parse error: syntax error, unexpected ‘new’ (T_NEW) in /usr/local/nginx/html/cacti/lib/adodb
134 0
linux篇-Parse error: syntax error, unexpected ‘new’ (T_NEW) in /usr/local/nginx/html/cacti/lib/adodb
|
JavaScript 关系型数据库 PHP
Notice: Undefined index: user in D:\phpStudy\WWW\js\ls\lsmc\php\add.php on line 9
原文:Notice: Undefined index: user in D:\phpStudy\WWW\js\ls\lsmc\php\add.php on line 9 (初用数据库(mysql)做用户登录注册这一块,遇到很多问题,通过搜索找到解决方案,把问题分享出来,希望可以帮助到和我一样问题的博友们,有问题还望多多指教。
1737 0

热门文章

最新文章