您的位置:首页 > 编程语言 > C语言/C++

cgi和fastcgi获取所有环境变量(C语言)

2014-01-28 16:59 435 查看
参考:http://blog.chinaunix.net/uid-620765-id-2084386.html

还记得C语言main函数的完整声明吗?

int main(int argc, char **argv, char **envp);

这个就是c语言中main函数的完整声明, argc表示参数个数,argv表示参数字符串,而这个envp就表示环境变量字符串。参数和环境变量都可以不止一个,所以,用指向字符串指针的指针来表示。

比如我们用C语言写了一个程序,运行在命令行下,带有2个参数

C:> cpfile.exe c:\test.txt d:\test.txt

那么这里的

argc=3;

argv[0] = "cpfile.exe";

argv[1] = "c:\test.txt";

argv[2] = "d:\test.txt";

在c语言中的stdlib.h中有一个

extern char **environ; 或者

extern char **_environ;的声明

这个envp的参数实际上就是environ。

好,我们看看在cgi程序(其实就是一个C语言程序)里面怎么枚举这些环境变量

先写一个html页面:(当然也可以不要)

<!DOCTYPE html>
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<meta http-equiv="Cache-Control" content="no-cache, must-revalidate">
<title>test</title>
<script type="text/javascript">
function post_submit()
{
document.getElementById( "mainform" ).method = "post";
document.getElementById( "mainform" ).submit();
}

function get_submit()
{
document.getElementById( "mainform" ).method = "get";
document.getElementById( "mainform" ).submit();
}
</script>
</head>
<body>
<div class="editView">
<form id="mainform" method="post" action="/printenv.cgi" enctype="multipart/form-data">
<fieldset class="">
<legend>测试页面</legend>
<dl class="nowrap">
<dd>
<span>名称</span>:
<input id="name" name="name" type="text" value="ldapserver_name">
<span>IP</span>:
<input id="ip" name="ip" type="text">
</dd>
</dl>
<dl class="nowrap">
<dd>
<span>复选框1</span>:
<input id="checkbox1" name="checkbox1" type="checkbox" checked/>
<span>    复选框1</span>:
<input id="checkbox2" name="checkbox2" type="checkbox" />
</dd>
</dl>
<dl class="nowrap">
<dd>
<label for="radiotest1">单选按钮1</label>
<input name="radiotest" id="radiotest1" type="radio" value="1"/>
<label for="radiotest2">  单选按钮2</label>
<input name="radiotest" id="radiotest2" type="radio" value="2" checked/>
<label for="radiotest3">  单选按钮3</label>
<input name="radiotest" id="radiotest3" type="radio" value="3"/>
</dd>
</dl>
<dl class="nowrap" id="dl_ca">
<dd>
<span>上传文件</span>
<input class="" name="uploadfile" id="uploadfile" type="file"/>
</dd>
</dl>
<dl class="nowrap">
<dd><span>下拉框</span>:
<select name="dropbox" id="dropbox">
<option value="3">3</option>
<option value="2">2</option>
</select>
</dd>
</dl>
</fieldset>
<fieldset class="btnfield">
<dl class="nowrap">
<dt> </dt>
<dd>
<a id="submit" href="javascript:;" value="Submit" onclick="javascript: post_submit();">post提交</a>
  <a id="submit" href="javascript:;" value="Submit" onclick="javascript: get_submit();">get提交</a>
  <a href="javascript:;">取消</a>
</dd>
</dl>
</fieldset>
</form>
</div>
</body>
</html>


呈现效果如下:



cgi程序源码:

/* env.c */

#include <stdio.h>
#include <stdlib.h>
#include <string.h>

int main()
{
extern char   **environ;
int nlen = 0;
int i;
char *psz_content = NULL;
char **pp_env;

printf("Content-type: text/html\n\n");

for ( pp_env = environ; *pp_env; pp_env++ )
printf("%s<br>", *pp_env);

if ( strcmp("GET", getenv("REQUEST_METHOD")) == 0 )
{

printf("<p>%s</p>", getenv("QUERY_STRING"));
}
else
{
nlen = atoi(getenv("CONTENT_LENGTH"));
psz_content = ( char * )malloc( nlen + 1 );
memset( psz_content, 0, nlen + 1 );
printf("<p>char value:</p><p>");
for (i = 0; i < nlen; i++ )
{
psz_content[i] = fgetc(stdin);
printf( "%c", psz_content[i] );
}
printf("</p><p>string value: %s</p>", psz_content);
}
return 0;
}


如果是fastcgi可以用以下代码打印环境变量:

#include <stdio.h>
#include <stdlib.h>
#include <string.h>

#include <fcgi_stdio.h>

int main()
{
extern char   **environ;
int nlen = 0;
int i;
char *psz_content = NULL;
char **pp_env;

while(FCGI_Accept() >= 0)
{
printf("Content-type: text/html\n\n");

for ( pp_env = environ; *pp_env; pp_env++ )
printf("%s<br>", *pp_env);

if ( strcmp("GET", getenv("REQUEST_METHOD")) == 0 )
{

printf("<p>%s</p>", getenv("QUERY_STRING"));
}
else
{
nlen = atoi(getenv("CONTENT_LENGTH"));
psz_content = ( char * )malloc( nlen + 1 );
memset( psz_content, 0, nlen + 1 );
printf("<p>char value:</p><p>");
for (i = 0; i < nlen; i++ )
{
psz_content[i] = fgetc(stdin);
printf( "%c", psz_content[i] );
}
printf("</p><p>string value: %s</p>", psz_content);
}
}
return 0;
}

注意:

1、这里使用fgetc函数从标准输入读数据,不能使用gets代替

2、FCGX中,头和环境信息在FCGX_Request->envp中,不能用genenv获取,要用FCGX_GetParam获取。

在地址栏 http://localhost/testenv.htm
假设我们输入的用户名和密码分别为abcd和efgh,提交表单之后,在我的机器上显示的结果如下:

COMSPEC=C:\WINDOWS\system32\cmd.exe

CONTENT_LENGTH=31

CONTENT_TYPE=application/x-www-form-urlencoded

DOCUMENT_ROOT=d:/chateaurt4/www

HTTP_ACCEPT=text/xml,application/xml,application/xhtml+xml,text/html;q=0.9,text/plain;q=0.8,image/png,*/*;q=0.5

HTTP_ACCEPT_CHARSET=gb2312,utf-8;q=0.7,*;q=0.7

HTTP_ACCEPT_ENCODING=gzip,deflate

HTTP_ACCEPT_LANGUAGE=zh-cn,zh;q=0.5

HTTP_CONNECTION=keep-alive

HTTP_HOST=localhost

HTTP_KEEP_ALIVE=300

HTTP_REFERER=http://localhost/testenv.htm

HTTP_USER_AGENT=Mozilla/5.0 (Windows; U; Windows NT 5.1; zh-CN; rv:1.8.1.3) Gecko/20070309 Firefox/2.0.0.3

PATH=C:\WINDOWS\system32;C:\WINDOWS;C:\WINDOWS\System32\Wbem;D:\MicrosoftVisual Studio\Common\Tools\WinNT;D:\Microsoft VisualStudio\Common\MSDev98\Bin;D:\Microsoft VisualStudio\Common\Tools;D:\Microsoft VisualStudio\VC98\bin;D:\AppServ\Apache2.2\bin;D:\AppServ\php5;D:\AppServ\MySQL\bin

REMOTE_ADDR=127.0.0.1

REMOTE_PORT=1644

SCRIPT_FILENAME=d:/chateaurt4/www/cgi-bin/env.cgi

SERVER_ADDR=127.0.0.1

SERVER_ADMIN=who@where.net

SERVER_NAME=localhost

SERVER_PORT=80

SERVER_SIGNATURE=
Apache/1.3.33 Server at localhost Port 80

SERVER_SOFTWARE=Apache/1.3.33 (Win32)

SystemRoot=C:\WINDOWS

WINDIR=C:\WINDOWS

GATEWAY_INTERFACE=CGI/1.1

SERVER_PROTOCOL=HTTP/1.1

REQUEST_METHOD=POST

QUERY_STRING=

REQUEST_URI=/cgi-bin/env.cgi

SCRIPT_NAME=/cgi-bin/env.cgi

usr=abcd&pwd=efgh&submit=Submit

当然不同的机器,它输出的有些结果可能不一样。如果单纯为了输出环境变量,我们可以这样做:

#include <stdio.h>

int main (int argc, char **argv, char **envp)
{
char **var = envp;
while (*var)
printf ("%s \n",*var++);

return 0;
}


这里面得到的环境变量结果和CGI程序里面的结果差别比较大,因为一个是获得与web应用程序有关的环境变量,而一个获得的是系统的环境变量。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: