前言
本文开始是默认环境准备是没有问题的,如果环境没有搭建好,可以参考下面的文章完成环境搭建。
ps:由于本文当时是在刚接触Boa不久就编写的,所以比较混乱,如果希望有个清晰点的demo工程进行参考,可以参考我的新文章:Linux下 基于Boa的应用资源管理系统 SMS
准备环境
操作系统: Ubuntu12.04 LTS (当然在CentOS7下也适用,只不过有些操作需要微调)
环境搭建: 需要 BOA,Apache,CCGI,MySQL,GCC
Linux下嵌入式Web服务器BOA和CGI编程开发
数据库的相关知识——学习笔记 的三
mysql中文乱码问题解决 / C程序插入仍是乱码解决 / 卸载重装教学
扩展: 我还用了bootstrap框架,CSS/JS
工程下载
使用方法
环境准备好后,我们在 /var/www
下写HTML文件
在 /var/www/cgi-bin
下写c文件(根据boa.conf
的配置),编译后命名为.cgi
。
编译命令仅供参考(pthread dl mysqlclient没用到可以不加)
gcc -o login.cgi login.c cgic.c -lpthread -ldl -lmysqlclient
程序都写好后,我们开始测试。
1、开启MySQL服务 默认开启
我的程序需要事先 新建用户test
,数据库register
,表user
mysql -utest -ptest
// 创建新用户test
mysql> create user 'test'@'localhost' identified by 'test';
// 给test用户所有权限
mysql> grant all privileges on *.* to test@localhost identified by 'test';
// 刷新权限
mysql> flush privileges;
// 创建register数据库
mysql> create database register;
mysql> use register;
// 创建user表
mysql> CREATE TABLE user(username varchar(20) PRIMARY KEY,password varchar(20));
2、开启BOA服务,在/boa-0.94.13/src目录下
执行命令 sudo ./boa
(如果你的root权限就直接 ./boa
)
3、打开浏览器,访问localhost:端口号 访问的即 /var/www 目录
我直接访问 http://localhost:886/login.html 我的登录页面
其他页面都是同理。
思路讲解
开启boa服务器后,我们访问到我们在 /var/www 下编写的HTML文件,显示我们的登录页面。
我们点击“注册”按钮,跳转到 register.html
点击“注册”按钮,提交form表单信息给cgi-bin/register.cgi
cgi程序通过 cgiFormString函数试图检索发送给指定字段的字符串。存入变量中。我们连接MySQL数据库
将数据写入register数据库中的user表中(此数据库和表需要先建好)
处理完毕后,跳回 login.html 登录页面
现在我们输入数据,点击“登录”,同理将表单发给 login.cgi ,对数据在MySQL数据库中查询后,成功就来到base_config.html 配置页面。
然后我们输入相应数据,点击“提交”,交给base_config.cgi处理,之后任意发挥就好了。
我是打印出来,写入系统文件的代码暂时注释了,慎用
遇到问题可以参考页首的链接
相关源码
login.html
<!DOCTYPE html>
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<title>register</title>
<script src="js/jquery-2.2.3.min.js"></script>
<script src="js/jquery-ui.min.js"></script>
<link type="text/css" href="css/jquery-ui.min.css" rel="stylesheet">
<link href="css/bootstrap.min.css" rel="stylesheet">
<script src="js/bootstrap.min.js"></script>
<link type="text/css" href="css/login.css" rel="stylesheet">
<script src="js/my.js"></script>
<SCRIPT language = "JavaScript">
function checkUserName(){ //验证用户名
var fname = document.myform.username.value;
var reg=/^[0-9a-zA-Z]/;
if(fname.length != 0){
for(i=0;i<fname.length;i++){
if(!reg.test(fname)){
alert("只能输入字母或数字");
return false;}
}
if(fname.length<4||fname.length>16){
alert("只能输入4-16个字符")
return false;
}
}
else{ alert("请输入用户名");
document.myform.username.focus();
return false }
return true;
}
function passCheck(){ //验证密码
var userpass = document.myform.password.value;
if(userpass == ""){
alert("未输入密码 \n" + "请输入密码");
document.myform.password.focus();
return false; }
if(userpass.length < 6||userpass.length>12){
alert("密码必须在 6-12 个字符。\n");
return false; }
return true; }
function passCheck2(){
var p1=document.myform.password.value;
var p2=document.myform.password2.value;
if(p1!=p2){
alert("确认密码与密码输入不一致");
return false;
}else{
return true;
}
}
function checkEmail(){
var Email = document.getElementById("email").value;
var e = Email.indexOf("@"&&".");
if(Email.length!=0){
if(e>0){
if(Email.charAt(0)=="@"&&"."){
alert("符号@和符号.不能再邮件地址第一位");
return false;
}
else{
return true;
}
}
else{
alert("电子邮件格式不正确\n"+"必须包含@符号和.符号!");
return false;
}
}
else{
alert("请输入电子邮件!")
return false;
}
}
function checkbirthday(){ //验证用户名
var year = document.myform.birthday.value;
if(year < 1949 || year > 2007){
alert("年份范围从1949-2007年");
return false;}
return true; }
function validateform(){
if(checkUserName()&&passCheck( )&&passCheck2()&&checkEmail()&&checkbirthday())
return true;
else
return false;
}
function clearText( ) {
document.myform.user.value="" ;
document.myform.password.value="" ;
}
//显示隐藏对应的switchPwd()方法:
$(function(){
// 通过jqurey修改
$("#passwordeye").click(function(){
let type = $("#password").attr('type')
if(type === "password"){
$("#password").attr("type","text");
}else{
$("#password").attr("type","password");
}
});
});
</SCRIPT>
</head>
<body>
<img src="img/login_bg.jpg" class="bg">
<div id="head">
<img src="img/login_head.png" width=100% height=auto />
</div>
<div id="center">
<form name="myform" onSubmit="return validateform( )" enctype="multipart/form-data" action="cgi-bin/login.cgi" method="post" >
<div class="input-group">
<h3>用户名:</h3> <input class="form-control" id="username" name="username" type="text" style="height:40px" value="" placeholder="只能输入字母或数字,4-16个字符"/>
</div>
<div class="input-group">
<h3>密 码:</h3> <input class="form-control" id="password" name="password" type="password" style="height:40px" value="" placeholder="密码长度6-12位"/>
<span class="input-group-btn">
<INPUT class="btn btn-default" id="passwordeye" type="button" value="show/hide"">
</span>
</div>
<div id="btn">
<INPUT class="btn btn-primary" name="loginButton" type="submit" id="Button" value="登录" onclick="checkUserName()">
<a href="register.html"><INPUT class="btn btn-primary" name="registerButton" id="Button" type="button" value="注册"></a>
</div>
</form>
</div>
<div id="bottom">
<div class="footer" style="color:white;">
Copyright © 2013-2019 All Rights Reserved. 备案号:
</div>
</div>
</body>
</html>
对应 login.c
#include <stdio.h>
#include "cgic.h"
#include <string.h>
#include <stdlib.h>
#include <unistd.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <mysql/mysql.h>
#include <stdbool.h>
#define SQL_SIZE 256
int cgiMain(void)
{
char username[20];
char password[20];
char email[40];
//回显信息到HTML网页cgiHeaderContentType("text/html");
printf("<html>\n\n");
printf("<meta http-equiv=\"Content-Type\" content=\"text/html; charset=utf-8\" />\n\n");
printf("<p>\n\n");
if(cgiFormString("username", username, sizeof(username)) != cgiFormSuccess)
{
fprintf(stderr, "cgiFormString function username failed");
//exit(-1);
}
printf("用户名:%s\n\n",username);
printf("<br>\n\n");
// password gateway server_ip dns subnet_mask dhcp error
if(cgiFormString("password", password, sizeof(password)) != cgiFormSuccess)
{
fprintf(stderr, "cgiFormString function password failed");
//exit(-1);
}
printf("密码:%s\n\n",password);
printf("<br>\n\n");
/*
if(cgiFormString("email", email, sizeof(email)) != cgiFormSuccess)
{
fprintf(stderr, "cgiFormString function email failed");
//exit(-1);
}
printf("电子邮箱:%s\n\n",phone);
printf("<br>\n\n");
*/
/*** 将用户信息写入MySQL数据库中 ***/
//数据存储到数据库
MYSQL* conn;
bool isAutoCommit;
// 初始化 MySQL
conn = mysql_init(NULL);
if(NULL == conn)
{
printf("errno:%d error:%s\n",mysql_errno(conn),mysql_error(conn));
exit(-1);
}
char ip[16] = "127.0.0.1";
char user[20] = "test";
char passwd[20] = "test";
char database[20] = "register";
int port = 3306;
// 尝试与运行在主机上的MySQL数据库引擎建立连接
if(NULL == mysql_real_connect(conn,ip,user,passwd,database,port,NULL,0))
{
printf("---errno:%d error:%s\n\n",mysql_errno(conn),mysql_error(conn));
exit(-1);
}
isAutoCommit = true;
// 根据mysql的autocommit参数设置来决定是否自动提交
mysql_autocommit(conn,isAutoCommit);
// 设定数据库编码
mysql_query(conn,"SET NAMES 'utf8'");
mysql_query(conn,"SET CHARACTER SET utf8");
mysql_query(conn,"SET CHARACTER_SET_RESULT = utf8");
char cmd[SQL_SIZE];
// 置字节字符串cmd的前SQL_SIZE个字节为零且包括‘\0’
bzero(cmd, SQL_SIZE);
// 创建user表
// strcpy(cmd, "CREATE TABLE user(username varchar(20) PRIMARY KEY,password varchar(20));");
// 将sql语句写入cmd变量
sprintf(cmd, "select * from user where username='%s' and password='%s';",username,password);
MYSQL_RES *res;
MYSQL_ROW row;
// 向与指定的连接标识符关联的服务器中的当前活动数据库发送一条查询
if(mysql_query(conn,cmd) != 0)
{
printf("errno:%d error:%s\n\n",mysql_errno(conn),mysql_error(conn));
exit(-1);
}
int num_fields = mysql_field_count(conn);
if(num_fields == 0)
{
printf("errno:%d error:%s\n",mysql_errno(conn),mysql_error(conn));
return -1;
}
res = mysql_store_result(conn);
if(NULL == res)
{
printf("errno:%d error:%s\n",mysql_errno(conn),mysql_error(conn));
return -1;
}
printf("<br>\n\n");
printf("<br>\n\n");
int count = 0;
while((row = mysql_fetch_row(res)))
{
char arr[1000];
int i = 0;
for( ; i<num_fields; i++)
{
printf("%s ",row[i]);
}
printf("\n\n");
printf("<br>\n\n");
count++;
}
mysql_free_result(res);
if(count != 0)
{
printf("<p>登陆成功</p>\n\n");
sleep(1);
printf("<meta http-equiv=Refresh content=1;URL=../base_config.html>\n");
}
else
{
printf("<p>帐号或密码错误</p>\n\n");
sleep(1);
printf("<meta http-equiv=Refresh content=1;URL=../login.html>\n");
}
//printf("<p></p>\n\n");
return 0;
}
register.html
<!DOCTYPE html>
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<title>register</title>
<script src="js/jquery-2.2.3.min.js"></script>
<script src="js/jquery-ui.min.js"></script>
<link type="text/css" href="css/jquery-ui.min.css" rel="stylesheet">
<link type="text/css" href="css/register.css" rel="stylesheet">
<link href="css/bootstrap.min.css" rel="stylesheet">
<script src="js/bootstrap.min.js"></script>
<script src="js/my.js"></script>
<SCRIPT language = "JavaScript">
function checkUserName(){ //验证用户名
var fname = document.myform.username.value;
var reg=/^[0-9a-zA-Z]/;
if(fname.length != 0){
for(i=0;i<fname.length;i++){
if(!reg.test(fname)){
alert("只能输入字母或数字");
return false;}
}
if(fname.length<4||fname.length>16){
alert("只能输入4-16个字符")
return false;
}
}
else{ alert("请输入用户名");
document.myform.username.focus();
return false }
return true;
}
function passCheck(){ //验证密码
var userpass = document.myform.password.value;
if(userpass == ""){
alert("未输入密码 \n" + "请输入密码");
document.myform.password.focus();
return false; }
if(userpass.length < 6||userpass.length>12){
alert("密码必须在 6-12 个字符。\n");
return false; }
return true; }
function passCheck2(){
var p1=document.myform.password.value;
var p2=document.myform.password2.value;
if(p1!=p2){
alert("确认密码与密码输入不一致");
return false;
}else{
return true;
}
}
function checkEmail(){
var Email = document.getElementById("email").value;
var e = Email.indexOf("@"&&".");
if(Email.length!=0){
if(e>0){
if(Email.charAt(0)=="@"&&"."){
alert("符号@和符号.不能再邮件地址第一位");
return false;
}
else{
return true;
}
}
else{
alert("电子邮件格式不正确\n"+"必须包含@符号和.符号!");
return false;
}
}
else{
alert("请输入电子邮件!")
return false;
}
}
function checkbirthday(){ //验证用户名
var year = document.myform.birthday.value;
if(year < 1949 || year > 2007){
alert("年份范围从1949-2007年");
return false;}
return true; }
function validateform(){
if(checkUserName()&&passCheck( )&&passCheck2()&&checkEmail()&&checkbirthday())
return true;
else
return false;
}
function clearText( ) {
document.myform.user.value="" ;
document.myform.password.value="" ;
}
//显示隐藏对应的switchPwd()方法:
$(function(){
// 通过jqurey修改
$("#passwordeye").click(function(){
let type = $("#password").attr('type')
if(type === "password"){
$("#password").attr("type","text");
}else{
$("#password").attr("type","password");
}
});
$("#passwordeye2").click(function(){
let type = $("#password2").attr('type')
if(type === "password"){
$("#password2").attr("type","text");
}else{
$("#password2").attr("type","password");
}
});
});
</SCRIPT>
</head>
<body>
<img src="img/login_bg.jpg" class="bg">
<div id="head">
<img src="img/register_head.png" width=100% height=auto />
</div>
<div id="center">
<form name="myform" onSubmit="return validateform( )" enctype="multipart/form-data" action="cgi-bin/register.cgi" method="post" >
<div class="input-group">
<h3>用 户 名:</h3><input class="form-control" id="username" name="username" type="text" style="height:40px" value="" placeholder="只能输入字母或数字,4-16个字符"/>
</div>
<div class="input-group">
<h3>密 码:</h3><input class="form-control" id="password" name="password" type="password" style="height:40px" value="" placeholder="密码长度6-12位"/>
<span class="input-group-btn">
<INPUT class="btn btn-default" id="passwordeye" type="button" value="show/hide"">
</span>
</div>
<div class="input-group">
<h3>确认密码:</h3><input class="form-control" id="password2" name="password2" type="password" style="height:40px" value=""/>
<span class="input-group-btn">
<INPUT class="btn btn-default" id="passwordeye2" type="button" value="show/hide"">
</span>
</div>
<div id="btn">
<INPUT name="registerButton" class="btn btn-primary" type="submit" id="Button" value="注册" onclick="checkUserName()">
<a href="login.html"><INPUT class="btn btn-primary" name="loginButton" id="Button" type="button" value="登录"></a>
</div>
</form>
</div>
<div id="bottom">
<div class="footer" style="color:white;">
Copyright © 2013-2019 All Rights Reserved. 备案号:
</div>
</div>
</body>
</html>
对应的 register.c
#include <stdio.h>
#include "cgic.h"
#include <string.h>
#include <stdlib.h>
#include <unistd.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <mysql/mysql.h>
#include <stdbool.h>
#define SQL_SIZE 256
int cgiMain(void)
{
char username[20];
char password[20];
char email[40];
//回显信息到HTML网页cgiHeaderContentType("text/html");
printf("<html>\n\n");
printf("<meta http-equiv=\"Content-Type\" content=\"text/html; charset=utf-8\" />\n\n");
printf("<p>\n\n");
if(cgiFormString("username", username, sizeof(username)) != cgiFormSuccess)
{
fprintf(stderr, "cgiFormString function username failed");
//exit(-1);
}
printf("用户名:%s\n\n",username);
printf("<br>\n\n");
// password gateway server_ip dns subnet_mask dhcp error
if(cgiFormString("password", password, sizeof(password)) != cgiFormSuccess)
{
fprintf(stderr, "cgiFormString function password failed");
//exit(-1);
}
printf("密码:%s\n\n",password);
printf("<br>\n\n");
/*
if(cgiFormString("email", email, sizeof(email)) != cgiFormSuccess)
{
fprintf(stderr, "cgiFormString function email failed");
//exit(-1);
}
printf("电子邮箱:%s\n\n",phone);
printf("<br>\n\n");
*/
/*** 将用户信息写入MySQL数据库中 ***/
//数据存储到数据库
MYSQL* conn;
bool isAutoCommit;
// 初始化 MySQL
conn = mysql_init(NULL);
if(NULL == conn)
{
printf("errno:%d error:%s\n",mysql_errno(conn),mysql_error(conn));
exit(-1);
}
char ip[16] = "127.0.0.1";
char user[20] = "test";
char passwd[20] = "test";
char database[20] = "register";
int port = 3306;
// 尝试与运行在主机上的MySQL数据库引擎建立连接
if(NULL == mysql_real_connect(conn,ip,user,passwd,database,port,NULL,0))
{
printf("---errno:%d error:%s\n\n",mysql_errno(conn),mysql_error(conn));
exit(-1);
}
isAutoCommit = true;
// 根据mysql的autocommit参数设置来决定是否自动提交
mysql_autocommit(conn,isAutoCommit);
// 设定数据库编码
mysql_query(conn,"SET NAMES 'utf8'");
mysql_query(conn,"SET CHARACTER SET utf8");
mysql_query(conn,"SET CHARACTER_SET_RESULT = utf8");
char cmd[SQL_SIZE];
// 置字节字符串cmd的前SQL_SIZE个字节为零且包括‘\0’
bzero(cmd, SQL_SIZE);
// 创建user表
// strcpy(cmd, "CREATE TABLE user(username varchar(20) PRIMARY KEY,password varchar(20));");
// 将sql语句写入cmd变量
sprintf(cmd, "INSERT INTO user values('%s', '%s');",username,password);
printf("%s\n\n",cmd);
// 向与指定的连接标识符关联的服务器中的当前活动数据库发送一条查询
if(mysql_query(conn,cmd) != 0)
{
printf("errno:%d error:%s\n\n",mysql_errno(conn),mysql_error(conn));
printf("<p>注册失败,请重新注册</p>\n\n");
sleep(1);
printf("<meta http-equiv=Refresh content=1;URL=../register.html>\n");
}
//mysql_affected_rows(conn);
printf("<p>注册成功</p>\n\n");
printf("<br>\n\n");
printf("<p>您的用户名和密码为:</p>\n\n");
sprintf(cmd,"select * from user;");
MYSQL_RES *res;
MYSQL_ROW row;
if(mysql_query(conn,cmd) != 0)
{
printf("errno:%d error:%s\n",mysql_errno(conn),mysql_error(conn));
return -1;
}
int num_fields = mysql_field_count(conn);
if(num_fields == 0)
{
printf("errno:%d error:%s\n",mysql_errno(conn),mysql_error(conn));
return -1;
}
res = mysql_store_result(conn);
if(NULL == res)
{
printf("errno:%d error:%s\n",mysql_errno(conn),mysql_error(conn));
return -1;
}
printf("<br>\n\n");
printf("<br>\n\n");
while((row = mysql_fetch_row(res)))
{
char arr[1000];
int i = 0;
for( ; i<num_fields; i++)
{
printf("%s ",row[i]);
}
printf("\n\n");
printf("<br>\n\n");
}
mysql_free_result(res);
sleep(1);
printf("<meta http-equiv=Refresh content=1;URL=../login.html>\n");
return 0;
}
常见错误
你的配置会影响网址,502什么错误也是配置或权限有问题导致的。
如:
502 Bad Gateway
The CGI was not CGI/1.1 compliant.
cgi_header: unable to find LFLF
1.可能是网址打错了(路径是否和配置文件对应)
2.配置有问题
3.权限没给足 chmod 777 test.cgi
4.代码本身有问题(先测测 cgi-test.cgi)
提示“保存文件”
是直接运行的网页,地址不对,改成 http://localhost:886/config.html 即可。
补充
文件上传
修改boa对单个上传文件大小的限制,src下的defines.h的SINGLE_POST_LIMIT_DEFAULT,单位 字节
前端post方式上传文件到后端 /var/www/cgi-bin
目录下
upload.html
<!DOCTYPE html>
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<meta http-equiv="X-UA-Compatible" content="IE=edge,chrome=1">
<title>upload</title>
<script src="js/jquery-2.2.3.min.js"></script>
<script src="js/jquery-ui.min.js"></script>
<link type="text/css" href="css/jquery-ui.min.css" rel="stylesheet">
<link href="css/bootstrap.min.css" rel="stylesheet">
<script src="js/bootstrap.min.js"></script>
<script>
//文件上传ajax部分
function uploadFile()
{
var fd = new FormData();
fd.append("file", document.getElementById('file').files[0]);
var xhr = new XMLHttpRequest();
xhr.upload.addEventListener("progress", uploadProgress, false);
xhr.addEventListener("load", uploadComplete, false);
xhr.addEventListener("error", uploadFailed, false);
xhr.addEventListener("abort", uploadCanceled, false);
xhr.open("POST", "cgi-bin/upload.cgi"); //修改成自己的接口
xhr.send(fd);
}
function uploadProgress(evt)
{
if (evt.lengthComputable)
{
//var percentComplete = Math.round(evt.loaded * 100 / evt.total);
//document.getElementById('progressNumber').innerHTML = percentComplete.toString() + '%';
}
else
{
//document.getElementById('progressNumber').innerHTML = 'unable to compute';
}
}
function uploadComplete(evt)
{
/* 服务器端返回响应时候触发event事件*/
alert(evt.target.responseText);
document.getElementById('file').outerHTML = document.getElementById('file').outerHTML;
}
function uploadFailed(evt)
{
alert("There was an error attempting to upload the file.");
document.getElementById('file').outerHTML = document.getElementById('file').outerHTML;
}
function uploadCanceled(evt)
{
alert("The upload has been canceled by the user or the browser dropped the connection.");
document.getElementById('file').outerHTML = document.getElementById('file').outerHTML;
}
</script>
</head>
<body>
<h2>目录权限,程序权限记得都给上</h2>
<form method="post" enctype="multipart/form-data">
<input type="file" name="file" id="file"/>
<input type="button" value="上传" onclick="uploadFile();"/>
</form>
</body>
</html>
upload.c
// 编译 gcc upload.c cgic.c -o upload.cgi
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <fcntl.h>
#include <sys/stat.h>
#include <time.h>
#include "cgic.h"
#define BufferLen 1024
int cgiMain(void)
{
cgiFilePtr file;
int targetFile = 0;
mode_t mode;
char name[128] = {};
char fileNameOnServer[64] = {};
char buf[1024] = {};
char buf2[1024] = {};
char contentType[1024] = {};
char buffer[BufferLen];
char *tmpStr = NULL;
int size = 0;
int got = 0, t = 0;
cgiHeaderContentType("text/html");
//取得html页面中file元素的值,应该是文件在客户机上的路径名
if (cgiFormFileName("file", name, sizeof(name)) != cgiFormSuccess)
{
//fprintf(stderr,"could not retrieve filename\n");
printf("could not retrieve filename\n");
goto FAIL;
}
cgiFormFileSize("file", &size);
//取得文件类型,不过本例中并未使用
cgiFormFileContentType("file", contentType, sizeof(contentType));
//目前文件存在于系统临时文件夹中,通常为/tmp,通过该命令打开临时文件。临时文件的名字与用户文件的名字不同,所以不能通过路径/tmp/userfilename的方式获得文件
if (cgiFormFileOpen("file", &file) != cgiFormSuccess)
{
//fprintf(stderr,"could not open the file\n");
printf("could not open the file\n");
goto FAIL;
}
t = -1;
//从路径名解析出用户文件名
while (1)
{
tmpStr = strstr(name + t + 1, "//");
if (NULL == tmpStr)
tmpStr = strstr(name + t + 1, "/"); //if "//" is not path separator, try "/"
if (NULL != tmpStr)
t = (int)(tmpStr - name);
else
break;
}
strcpy(fileNameOnServer, name + t + 1);
mode = S_IRWXU | S_IRGRP | S_IROTH;
//在当前目录下建立新的文件,第一个参数实际上是路径名,此处的含义是在cgi程序所在的目录(当前目录))建立新文件
snprintf(buf, 200, "/var/www/cgi-bin/%s", fileNameOnServer);
targetFile = open(buf, O_RDWR | O_CREAT | O_TRUNC | O_APPEND, mode);
if (targetFile < 0)
{
//fprintf(stderr,"could not create the new file,%s\n",fileNameOnServer);
snprintf(buf2, 1000, "could not create the new file,%s\n", fileNameOnServer);
printf(buf2);
goto FAIL;
}
//从系统临时文件中读出文件内容,并放到刚创建的目标文件中
while (cgiFormFileRead(file, buffer, BufferLen, &got) == cgiFormSuccess)
{
if (got > 0)
write(targetFile, buffer, got);
}
cgiFormFileClose(file);
close(targetFile);
goto END;
FAIL:
//fprintf(stderr,"Failed to upload");
printf("Failed to upload\n");
return 1;
END:
snprintf(buf2, 1000, "File %s has been uploaded\n", fileNameOnServer);
printf(buf2);
// dos2unix filename (windows上传上来的文件换行不一样)
return 0;
}