2013年6月1日星期六

用C语言可以做CGI吗?

用C语言可以做CGI吗?

2011-06-22 本文行家:_张_巍_
CGIC是非常优秀的C语言CGI库函数,做嵌入式开发的童鞋想必都比较熟悉C,在此向大家推荐一个用于CGI编程的ANSIC库:cgic,官方主页为 http://www.boutell.com/cgic/ ,现在的版本号是2.05。这里主要介绍一种我使用cgic的方法,当然不一定是最好的,如有问题可以共同探讨。
 CGIC是非常优秀的C语言CGI库函数,做嵌入式开发的童鞋想必都比较熟悉C,在此向大家推荐一个用于CGI编程的ANSIC库:cgic,官方主页为http://www.boutell.com/cgic/ ,现在的版本号是2.05。这里主要介绍一种我使用cgic的方法,当然不一定是最好的,如有问题可以共同探讨。

解开压缩包后主要包括以下几个文件(project那个文件夹是我自己建的,里面放的是SourceInsight创建的工程文件,看cgic源码方便些)

|-- Makefile
|-- capture.c
|-- cgic.c
|-- cgic.h
|-- cgic.html
|-- cgic.o
|-- cgictest.c
|-- cgitest.cgi
|-- license.txt
|-- project
|   |-- cgic.IAB
|   |-- cgic.IAD
|   |-- cgic.IMB
|   |-- cgic.IMD
|   |-- cgic.PFI
|   |-- cgic.PO
|   |-- cgic.PR
|   |-- cgic.PRI
|   |-- cgic.PS
|   |-- cgic.SearchResults
|   `-- cgic.WK3
|-- readme.txt
|-- support.txt
`-- svn-commit.tmp


可以看到文件不多,比较简洁,其中,cgitest.c是测试文件,直接make后就会生成一个cgitest.cgi文件,把它放到sambar或是boa的cgi目录,然后运行就可以看到测试的页面了
。编译过程很顺利,解压后按照里面的说明文档操作就可以了,这里就不累述了。像表单的提交,文本框,按钮的提交都有相关的接口(更多的使用还请参考帮助文档),如:

char name_test[81];
cgiFormStringNoNewlines("name", name_test, 81);


是将html代码中为name的变量的值复制到数组name_test中,而name就是类似于我们登录论坛时在文本框中输入的用户名之类的字符串,这样 就完成了与用户的交互,获得了name字符串的值并保存在name_test中,这样,在应用程序中就可以对这个name的字符串进行验证了,比如是否为 合法值等。在cgic.c时,需要在自己的源文件中添加cgic.h头文件,然后将原来的main()主函数改为cgiMain()就可以用了,也就是说 将原来的源文件作为cgic的一个子函数被调用。cgic的打印输出方式为fprintf(cgiOut,"test");这在cgictest.c中就 可以看到:

void ShowForm()
{
        fprintf(cgiOut, "<!-- 2.0: multipart/form-data is required for file uploads. -->");
        fprintf(cgiOut, "<form. method="POST" enctype="multipart/form-data" ");
        fprintf(cgiOut, "        action="");
        cgiValueEscape(cgiScriptName);
        fprintf(cgiOut, ""> ");
        fprintf(cgiOut, "<p> ");
......
        fprintf(cgiOut, "Text Field containing Plaintext ");
        fprintf(cgiOut, "<p> ");
        fprintf(cgiOut, "<input type="submit" name="saveenvironment" value="Save Environment"> ");
        fprintf(cgiOut, "</form> ");
}


可见整个cgictest.cgi的测试页面都是通过fprintf()输出的,关于这一点,像这样的稍简单的测试页面还可以应付,当要处理的是复杂的html页面时再使用这种方法,对页面以后
的维护和扩展是否方便先不说,光是把页面的html代码通过fprintf()噼里啪啦写到程序里就够人受的,除非你喜欢在键盘上欢快的耕耘,享受着手指踢踏带来的乐趣,否则只好另
想它法,为此,我们可以先用网页制作工具如frontpage之类的事先设计好准备要显示的页面,然后再做个将html转换为c的接口 htmltoc(),主要功能就是负责解析html文件,也就是将html代码使用fprintf()输出给浏览器,同时检测html中需要调用cgi更 新变量的标识处,我们可以在这些地方用自己定义的标识符表示,比如用"$$$",当htmltoc()遇到"$$$"时就返回,并记住当前读取html文 件的指针位置,以便下次接着读。
如,


----------------test.html----我是分割线------------>
<html>
<head>
</head>
.....
<input type="text" name="T31" readonly size="22" style="background:#EEEEEE" value="$$$");        //文本框1
.....

<input type="text" name="T32" readonly size="22" style="background:#EEEEEE" value="$$$");        //文本框2
.....


</html>

<--------------test.html----我是分割线------------

----------------------------我是分割线------------------------>
/********************************
*负责解析html页面
********************************/
int htmltoc(void)
{
        //读取*.html
        if(遇到字符串$$$)
        {
                return 0;
        }
        else
        {
                //继续读使用fprintf输出html代码到浏览器
        }
}

//定义字符数组
char text_test1[64];
char text_test2[64];

/********************************
*负责处理变量
********************************/
int test_handle(void)
{
        //使用cgic的接口获取用户在网页上输入的文本框字符串内容;
        //对获取到的字符串根据需要判断处理;
        //如简单复制:
        //        text_test1=文本框1的字符串;
        //           text_test2=文本框2的字符串;

        //将text_test1记录到文件text_log1.txt中
        //将text_test2记录到文件text_log2.txt中
}




/********************************
*cgic的主函数
********************************/
int cgiMain(void)
{
        test_handle();       

        htmltoc();        //开始读
        fprintf(cgiOut,"%s",text_test1);       

        htmltoc();        //继续读
        fprintf(cgiOut,"%s",text_test2);

       
        return 0;
}

------------------------我是分割线-------------
其中test.html文件放在boa的web目录;连同cgic.c,将使用arm-linux-gcc编译后的cgiMain放在cgi-bin目录;
上面的主要功能就是将页面中输入的字符串原样的回显到页面中,同时也把留言记录在文件text_log1.txt和text_log2.txt中了,比如常用的网页中的留言板就可以这样实现,或
是比如把*.txt文件改为*.ini的格式作为配置文件,供后台运行的应用程序读取,就可以达到从网页上更改设备运行参数的目的了。

到此,关于cgic就总结完了,下面是上面提到的相关连接,供参考。
有关cgi的链接为:
http://www.boutell.com/cgic/
cgilua的链接为:
http://www.keplerproject.org/cgilua/
perl的链接为:
http://www.perl.org/

没有评论:

发表评论