cgi开发遇到的问题续

1. fopen打开文件的问题

Fopen以写方式打开文件时,如果只是文件名(默认当前目录),则可以打开成功;如果指定一个相对路径,如/usr/local/apache/cgi-bin/upload/filename,则打开失败。出现这个问题的原因是因为权限不够(cgi程序运行时,是apache的用户,权限有限),虽然给cgi-bin更改了权限(chmod o+w /usr/local/apache/cgi-bin),但是它的上面几级目录没有写权限,以绝对路径打开文件时,对每一级路径都需要有写权限。于是

#chmod o+w -R /usr/local/apache/cgi-bin/upload

然后就可以打开成功了。

疑问:目录的x控制能否进去和通过目录,xr的组合控制能否列出目录,xw的组合控制能否在目录中删除、新建、修改文件。

解答:fopen以读方式打开时,只要该用户具有upload目录的读权限,在upload上几级目录有x权限即可打开成功;通过chmod o+w -R这条命令修改权限,查看local目录和apache目录的权限,对于other用户来说还是只有x权限(默认对于other用户就有x权限),如果不加-R选项,以写方式打开还是会失败,加了-R选项就可以打开成功,但是localapache目录对other的权限还是xxr组合可以列出目录,xw的组合控制能够在目录中删除、新建和修改文件。

2. Cgi获取html表格中数据的问题

通过js比较容易获取html表格中的数据,但是通过cgi就很麻烦,还不一定能成功,所以采用一个简单的办法,因为我要获取表格中的文件名来进行操作,比如

而这个文件名是通过遍历目录来得到的,因此直接将“下载”操作的文件名写死,比如

在cgi中这样写

printf("<a href=\"download.cgi?name=%s\">下载</a>", name);

其中的name是之前获取保存下来的。

3. Cgiprintf  javascript的问题

Cgi中打印javascript比较麻烦,而且很容易出错。比如上面第一个问题中的“下载”链接,之前是用按钮做的。如下:

printf("<form name=form_download method=\"get\" action=\"download.cgi?name=%s\"/>", name);

printf("<input type=\"submit\" value=\"下载\"/>");

printf("</form>");

结果点击网页之后通过getenv("QUERY_STRING")没有获取出name参数来。

所以改用简单的方法,直接用href

printf("<a href=\"download.cgi?name=%s\">下载</a>", name);

4. Cgi执行成功或失败后跳转到某一页面的方法

cgi中打印如下语句即可。

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

printf("<html>");

printf("<script language=\"javascript\">\n");

printf("window.location=\"/cgi-bin/list_dir.cgi\";");

printf("</script>");

printf("</html>");

5. 下载和删除时,文件名中有空格的问题

比如下载文件“c cgi.ppt”,文件名中有空格,通过getenv("QUERY_STRING")获取出来的文件名是“c%20gi.ppt”,因此需要把"%20"替换成“ ”。

6. Utf-8中文编码问题

网页编码一般选用utf-8,源代码里面如果有中文,需要以编码utf-8另存。

服务器的.bashrc里加上

export LANG=zh_CN.UTF-8

export LC_ALL=zh_CN.UTF-8

.vimrc里加上

set termencoding=utf-8

set fileencodings=ucs-bom,utf-8,cp936,gb18030,big5,latin1

set encoding=utf-8

language messages zh_CN.utf-8

这样用vim编写代码的时候就可以显示中文,而不是乱码了。

7. Url编解码问题

在用cgi编写程序时,一些特殊字符(如空格、&等),还有中文字符,经过url之后都很重新编码,所以c语言用getenv接收的数据会是编码之后的字符串。如“c gi.txt”经过url之后变成“c%20gi.txt”。一般url是使用urlencode来进行编码,所以cgi程序中需要使用urldecode来解码。

具体参考

http://www.cnblogs.com/greatverve/archive/2011/12/12/URL-Encoding-Decoding.html 

http://www.abc188.com/info/html/caozuoxitong/FreeBSD/20090513/132147.html 

8. Linux c获取目录下所有文件大小的问题

void list_dir(char *path)

{

DIR *dir;

struct dirent *entry;

struct stat stat_buf;

if ((dir = opendir(path)) == NULL)

{

printf("cannot open dir:%s\n", path);

return;

}

while ((entry = readdir(dir)) != NULL)

{

lstat(entry->d_name, &stat_buf);

if (!S_ISDIR(stat_buf.st_mode))

printf("%s, %d", entry->d_name, (int)stat_buf.st_size);

}

closedir(dir);

}

结果打印出来的是这种结果:

httpd-2.4.2.tar.gz, 4096

Firefox-latest.exe, 4096

Makefile.pdf, 4096

cr-SecureCRT.rar, 4096

putty.exe, 4096

结果显示大小都是4096,有时候只是其中一个文件的大小比如,都是xxx文件的大小,那个4096应该是目录"."".."的大小,这就很奇怪了,为什么打印出来的不是自身文件的大小。

后来没办法用以下方法获取文件大小:

FILE *fp = fopen(name, "r");

if (fp)

{

fseek(fp, 0L, SEEK_END);

int len = ftell(fp);

fseek(fp, 0L, SEEK_SET);

return len;

}

至于为什么用stat_buf.st_size获取的大小有问题,还没有搞清楚原因。

你可能感兴趣的:(cgi开发遇到的问题续)