Exemplo n.º 1
0
table::~table()
{
    clear_table();
    clear_header();
    clear_status();
    endwin();
}
Exemplo n.º 2
0
// display a "WAIT" message
static void _near _fastcall list_wait( LPTSTR pszPrompt )
{
	// clear the header line
	clear_header();
	
	// display "WAIT" in blinking chars
	WriteStrAtt( 0, (( nScreenColumns / 2 ) - ( strlen( pszPrompt ) / 2 )), ( nInverse | 0x80 ), pszPrompt );
}
Exemplo n.º 3
0
static void show_404(int sock)      //404错误处理
{
	clear_header(sock);
	char* msg="HTTP/1.0 404	Not Found\r\n";
	send(sock,msg,strlen(msg),0);         //发送状态行
	send(sock,"\r\n",strlen("\r\n"),0);      //发送空行

	struct stat st;
	stat("wwwroot/404.html",&st);
	int fd=open("wwwroot/404.html",O_RDONLY);
	sendfile(sock,fd,NULL,st.st_size);
	close(fd);
}
Exemplo n.º 4
0
void echo_html(int client,char* path,size_t size)
{
	clear_header(client);//将缓冲区的内容清空,包含请求行,消息报头
	int fd=open(path,O_RDONLY,0);
	if(fd<0)
	{
		return_error_client();
		return;
	}
	else
	{
		char buf[1024];
		memset(buf,'\0',sizeof(buf));
		sprintf(buf,"HTTP/1.0 200 OK\r\n\r\n");
		send(client,buf,strlen(buf),0);
		sendfile(client,fd,NULL,size);
	}
	close(fd);
}
Exemplo n.º 5
0
Arquivo: catalog.cpp Projeto: qks1/erk
}

//--------------------------------------------------------------------------//

inline void Catalog::connects(){
    // при выборе группы из каталога - установить фильтр по группам
    QObject::connect(this->groups, SIGNAL(itemActivated(QTreeWidgetItem*, int)), SLOT(change_group(QTreeWidgetItem*, int)));

    // при нажатии кнопки сброса фильтра по группам - сбросить его
    QObject::connect(this->reset_groups, SIGNAL(clicked()), SIGNAL(hide_catalog()));

    // при выборе группы из каталога - установить заголовок каталога
    QObject::connect(this->groups, SIGNAL(itemActivated(QTreeWidgetItem*, int)), SLOT(change_header(QTreeWidgetItem*,int)));

    // при сбросе фильтра по группам - установить заголовок каталога по умолчанию
    QObject::connect(this->reset_groups, SIGNAL(clicked()), SLOT(clear_header()));
}

//--------------------------------------------------------------------------//
//--------------------------- ФУНКЦИИ --------------------------------------//
//--------------------------------------------------------------------------//

bool Catalog::addGroups(){
    return add_groups(this->groups);
}

//--------------------------------------------------------------------------//
//--------------------------- СЛОТЫ ----------------------------------------//
//--------------------------------------------------------------------------//

void Catalog::move_button(){
Exemplo n.º 6
0
static void * accept_request(void *arg)
{
	int sock = (int)arg;
	char buf[_SIZE_];

	char method[_SIZE_/10];
	char url[_SIZE_];
	char path[_SIZE_];

	memset(buf, '\0', sizeof(buf));
	memset(buf, '\0', sizeof(method));
	memset(buf, '\0', sizeof(url));
	memset(buf, '\0', sizeof(path));

	int cgi = 0;
	int ret = -1;
	char *query_string = NULL; // 数据参数
	int len = sizeof(buf) / sizeof(buf[0]);
#ifdef _DEBUG_
	do 
	{
		// http 请求 报文 按行存储
		ret = get_line(sock, buf, len);
		printf("%s", buf);
		fflush(stdout);
	} while (ret > 0 && strcmp(buf, "\n") != 0);
#endif 

	ret = get_line(sock, buf, len); // 获取请求行
printf("line:   %s\n", buf);	
	if (ret < 0)
	{
		echo_errno(sock);
		return (void*)1;
	}

	// GET / HTTP/1.0
	int i = 0; // method index
	int j = 0; // buf index

	// 请求行 包括   【方法(GET/POST)】【url】【HTTP/1.0(1.1)】
	// 获取方法 GET/POST
	while ((i < sizeof(method) - 1) && (j < sizeof(buf)) && (!isspace(buf[j])))
	{
		method[i] = buf[j];
		++i;
		++j;
	}
	method[i] = '\0';
	// strcasecmp 忽略大小写的比较
	if (strcasecmp(method, "GET") != 0 && strcasecmp(method, "POST") != 0)
	{
		echo_errno(sock);
		return (void*)2;
	}
	
	// 跳过空格
	while (j < sizeof(buf) && isspace(buf[j]))
	{
		j++;
	}

	i = 0;


	// 获取url url是除了域名 端口号之后的 /。。。
	while ((i < sizeof(url) - 1) && (j < sizeof(buf)) && (!isspace(buf[j])))
	{
		url[i++] = buf[j++];
	}

	url[i] = '\0';
	//GET  所传递的参数 在URL中, 从server的QUERY_STRING 中获取
	//POST 所传递的参数 在 数据包中 从server环境变量中CONTENT_LENGTH 环境变量中获取参数 数据的长度
	
	if (strcasecmp(method, "POST") == 0)
	{
		cgi = 1;
	}
	
	 if (strcasecmp(method, "GET") == 0)
	 {
		 query_string = url;
		 // 路径和数据参数 以?分隔 如 http:// baidu.com /s ?  k = v
		 while (*query_string != '\0' && *query_string != '?')
		 {
			 ++query_string;
		 }

		 if(*query_string == '?') // GET 带参数 需要进一步处理参数
		 {
			 cgi = 1;
			 *query_string++ = '\0';
		 }
	 }

	 // 没指定具体网页 加默认网页 和 根文件夹(安全考虑)
	 sprintf(path, "httpdoc%s", url);
	 if (path[strlen(path) - 1] == '/')
	 {
		strcat(path, "index.html");
	 }


	 // method , query_string, cgi, path
	 struct stat st;
	 if (stat(path, &st) < 0) // 测文件在不在
	 {
		 echo_errno(sock);
		 return (void*)3;
	 }
	 else
	 {
		 if (S_ISDIR(st.st_mode))// 测是不是 文件夹
		 {
			 strcat(path, "/index.html");
		 }
		 else if( (st.st_mode & S_IXUSR) ||\
				(st.st_mode & S_IXGRP) ||\
				(st.st_mode & S_IXOTH))
				//   查看cgi执行权限
		 {
				cgi = 1;
		 }
		 else
		 {}

		 if (cgi)
		 {
			  exec_cgi(sock, method, path,  query_string);
		 }
		 else
		 {
			clear_header(sock); // 
			echo_www(sock, path, st.st_size);
		 }
	 }
}
Exemplo n.º 7
0
static void exec_cgi(int sock, const char *method, const char *path, const char *query_string )
{
	char buf[_SIZE_];
	int content_length = -1;// 内容长度  方便获取内容  
	int ret = -1;
	int cgi_input[2];
	int cgi_output[2];
	char method_env[_SIZE_];
	char query_string_env[_SIZE_];
	char content_length_env[_SIZE_];

	printf("[exec_cgi ]method : %s \n", method);

	if (strcasecmp(method, "GET") == 0)
	{
		clear_header(sock);
	}
	else // POST
	{
		do
		{
			ret = get_line(sock, buf, sizeof(buf));
			if (strncasecmp(buf, "Content-Length: ", 16) == 0)
			{
				content_length = atoi(&buf[16]);
				// break               不用 break  即把参数Content-Length获取  又把  空行删除
			}
		}while ((ret > 0) && strcmp(buf, "\n") != 0);

		if (content_length == -1)
		{
			echo_errno(sock);
			return;
		}
	}

	sprintf(buf, "HTTP/1.0 200 OK\r\n\r\n");
	send(sock, buf, strlen(buf), 0);


	// 创建  父子进程之间的 通信管道 cgi_input子进程的读  cgi_output子进程的写 
	if (pipe(cgi_input) < 0)
	{
		echo_errno(sock);
		return;
	}

	if (pipe(cgi_output) < 0)
	{
		echo_errno(sock);
		return;
	}

	pid_t id = fork();
	if (id < 0)
	{
		echo_errno(sock);
		return ;
	}

	if (id == 0)// child
	{
		close(cgi_input[1]);
		close(cgi_output[0]);

		// ////////////////
		// 重定向 管道到  标准输入 和 输出     这样以后 printf()直接打到管道

		dup2(cgi_input[0], 0);
		dup2(cgi_output[1], 1);

		sprintf(method_env, "REQUEST_METHOD=%s", method);
		putenv(method_env);// 注册环境变量 这样 execl 执行二进制程序时时 获取这些参数方便getenv
		
		// GET 要得 参数 在请求字段  中  环境变量注册 quer_string_env
		// post 要的参数在 内容中  所以要知道 内容什么时候截至(内容长度)所以 只要知道content_length_env 就可以了  

		if (strcasecmp(method, "GET") == 0)
		{
			sprintf(query_string_env, "QUERY_STRING=%s", query_string);
			putenv(query_string_env);
		}
		else // post
		{
			sprintf(content_length_env, "CONTENT_LENGTH=%d", content_length);
			putenv(content_length_env);
printf("%d-----------env\n", content_length);	
		}
		// 执行  二进制 程序
		execl(path,path,NULL);
		exit(1);
	}
	else // father
	{
		close(cgi_input[0]);
		close(cgi_output[1]);

		char c = '\0';
		int i = 0;
		printf("%s --fmethod\n", method);
		if (strcasecmp(method, "POST") == 0)
		{
			printf("--father here %d\n", content_length);
			for (; i < content_length; i++)
			{
				recv(sock, &c, 1, 0);
				printf("--%c ", c);
				fflush(stdout);
				write(cgi_input[1], &c, 1);// 给子进程 发过去 
			}
		}

		printf("\n");

		int ret = 0;
		while ((ret = read(cgi_output[0], &c, 1)) > 0)// 子进程退出 文件符号关闭 read读完文件结尾 返回0
		{
			send(sock, &c, 1, 0);// 父进程 负责向sock发送子进程的数据
		}

		waitpid(id, NULL, 0);
		close(sock);
	}
}
Exemplo n.º 8
0
/**
 * Send an edcl packet and fragment it if max_packet_size < data_size
 */
static int		send_fragmented(void)
{
	unsigned int		nb_ack_packet = 0;
	unsigned int		address_offset = 0;
	unsigned int		nb_sent_packet = 0;
	unsigned int		local_data_size = config.data_size;
	edcl_packet_t*		packet = NULL;

	/* Allocating the packet of the packet */
	packet = calloc(1, min(local_data_size, MAX_DATA_SIZE) + sizeof (edcl_header_t));
	if (packet == NULL)
		goto error_malloc;

	do {
		/* Filling up the edcl header */
		clear_header(packet->header);
		set_operation(packet->header, WRITE_OP);
		set_sequence(packet->header, config.sequence_number);
		set_address(packet->header, config.memory_address + address_offset);
		set_length(packet->header, min(local_data_size, MAX_DATA_SIZE));

		if (config.verbose)
			fprintf(stderr,
				" [%d] Trying to write at 0x%08x.",
				config.sequence_number,
				config.memory_address + address_offset);

		/* Copying the data in the packet */
		memcpy(packet->data,
		       config.data_c + address_offset,
		       min(local_data_size, MAX_DATA_SIZE));

		/* Sending the packet to the ethernet IP */
		if (sendto(config.socket,
			   packet,
			   min(local_data_size, MAX_DATA_SIZE) + sizeof (edcl_header_t),
			   0, config.serv_info->ai_addr, config.serv_info->ai_addrlen)
		    == -1)
			goto error_send;

		/* Waiting for the aknowledgment */
		if (recvfrom(config.socket,  packet,
			     sizeof (edcl_header_t) + min(local_data_size, MAX_DATA_SIZE),
			     0, NULL, 0) == -1)
			goto error_recvfrom;

		/* We've been aknowledge, keep sending */
		if (get_ack(packet->header)) {
			if (config.verbose)
				fprintf(stderr,
					"\t[OK]\n");
			address_offset += min(local_data_size, MAX_DATA_SIZE);
			local_data_size -= min(local_data_size, MAX_DATA_SIZE);
			++config.sequence_number;
			++nb_ack_packet;
		}
		/* The sequence number was wrong, fix it */
		else {
			if (config.verbose)
				fprintf(stderr,
					"\t[Failed]\n  Wrong sequence number (%d) should be: %d. Fixed.\n",
					config.sequence_number, get_sequence(packet->header));
			config.sequence_number = get_sequence(packet->header);
		}

		++nb_sent_packet;
	} while (local_data_size > 0);

	if (config.verbose) {
		fprintf(stderr,
			"The datas have been fragmented in %d packets.\n", nb_ack_packet);
		fprintf(stderr,
			"\t %d packets have been sent (%d have been lost).\n",
			nb_sent_packet,
			nb_sent_packet - nb_ack_packet);
	}

	/* Releasing ressources */
	free(packet);

	return (0);

 error_recvfrom:
 error_send:
	if (config.verbose)
		fprintf(stderr,
			"Error while sending the packet.\n");
	free(packet);
	return (errno);
 error_malloc:
	if (config.verbose)
		fprintf(stderr,
			"Unable to allocate the packet.\n");
	return (errno);
}
Exemplo n.º 9
0
int handler_msg(int sock)       //浏览器请求处理函数
{
	char buf[SIZE];
	int count=get_line(sock,buf);
	int ret=0;
	char method[32];
	char url[SIZE];
	char *query_string=NULL;
	int i=0;
	int j=0;
	int cgi=0;

	//获取请求方法和请求路径
	while(j<count)
	{
		if(isspace(buf[j]))
		{
			break;
		}
		method[i]=buf[j];	
		i++;
		j++;
	}
	method[i]='\0';
	while(isspace(buf[j])&&j<SIZE)      //过滤空格
	{
		j++;
	}

	if(strcasecmp(method,"POST")&&strcasecmp(method,"GET"))
	{
		printf_log("method failed",FATAL);
		echo_error(sock,405);
		ret=5;
		goto end;
	}

	if(strcasecmp(method,"POST")==0)
	{
		cgi=1;
	}	
	
	i=0;
	while(j<count)
	{
		if(isspace(buf[j]))
		{
			break;
		}
		if(buf[j]=='?')
		{
			query_string=&url[i];
			query_string++;
			url[i]='\0';
		}
		else
			url[i]=buf[j];
		j++;
		i++;
	}
	url[i]='\0';

	if(strcasecmp(method,"GET")==0&&query_string!=NULL)
	{
		cgi=1;
	}

	//找到请求的资源路径
	char path[SIZE];
	sprintf(path,"wwwroot%s",url);       
	
	if(path[strlen(path)-1]=='/')              //判断浏览器请求的是不是目录
	{
		strcat(path,"index.html");	     //如果请求的是目录,则就把该目录下的首页返回回去
	}

	struct stat st;           
	if(stat(path,&st)<0)            //获取客户端请求的资源的相关属性
	{
		printf_log("stat path faile\n",FATAL);
		echo_error(sock,404);
		ret=6;
		goto end;
	}
	else
	{
		if(S_ISDIR(st.st_mode))
		{
			strcat(path,"/index.html");
		}

		if(st.st_mode & (S_IXUSR | S_IXOTH | S_IXGRP))
		{
			cgi=1;
		}
	}

	if(cgi)       //请求的是可执行程序或者带参数用cgi程序处理
	{
		ret=excu_cgi(sock,method,path,query_string);           //处理CGI模式的请求
	}
	else
	{
		clear_header(sock);
		ret=echo_www(sock,path,st.st_size);  //如果是GET方法,而且没有参数,请求的也不是可执行程序,则直接返回资源	
	}
	
end:
	close(sock);
	return ret;
}
Exemplo n.º 10
0
static int excu_cgi(int sock,const char* method,\
		const char* path,const char* query_string) //处理CGI模式的请求
{
	char line[SIZE];
	int ret=0;
	int content_len=-1;
	if(strcasecmp(method,"GET")==0)         //如果是GET方法的CGI
	{
		//清空消息报头
		clear_header(sock);
	}
	else              //POST方法的CGI
	{
		//获取post方法的参数大小
		do
		{
			ret=get_line(sock,line);
			if(strncmp(line,"Content-Length: ",16)==0)  //post的消息体记录正文长度的字段
			{
				content_len=atoi(line+16);	//求出正文的长度
			}
		}while(ret!=1&&(strcmp(line,"\n")!=0));
	}

	//将method、query_string、content_len导出为环境变量
	char method_env[SIZE/8];
	char query_string_env[SIZE/8];
	char content_len_env[SIZE/8];
	
	sprintf(method_env,"METHOD=%s",method);
	putenv(method_env);

	sprintf(query_string_env,"QUERY_STRING=%s",query_string);
	putenv(query_string_env);
	
	sprintf(content_len_env,"CONTENT_LEN=%d",content_len);
	putenv(content_len_env);


	int input[2];      //站在CGI程序的角度,创建两个管道
	int output[2];

	pipe(input);
	pipe(output);

	pid_t id=fork();

	if(id<0)
	{
		printf_log("fork failed",FATAL);
		echo_error(sock,500);
		return 9;
	}
	else if(id==0)     //子进程
	{
		close(input[1]);    //关闭input的写端      
		close(output[0]);  //关闭output的读端

		//将文件描述符重定向到标准输入标准输出
		dup2(input[0],0);
		dup2(output[1],1);

		execl(path,path,NULL);         //替换CGI程序
		exit(1);
	}
	else         //father
	{
		close(input[0]);      //关闭input的读端
		close(output[1]);     //关闭output的写端

		char ch='\0';
		if(strcasecmp(method,"POST")==0) //如果是post方法,则父进程需要给子进程发送参数
		{
			int i=0;
			for( i=0;i<content_len;i++)
			{
 				recv(sock,&ch,1,0);        //从sock里面一次读一个字符,总共读conten_len个字符
				write(input[1],&ch,1);
			}
		}
	
		char* msg="HTTP/1.0 200 OK\r\n\r\n";
		send(sock,msg,strlen(msg),0);

		//接收子进程的返回结果
		while(read(output[0],&ch,1))      //如果CGI程序结束,写端关闭,则读端返回0
		{
			send(sock,&ch,1,0);
		}
		waitpid(id,NULL,0);              //回收子进程
	}

	return 0;
}
Exemplo n.º 11
0
void exe_cgi(int client,const char*path,const char*method,const char*query_string)
{
	int num=0;
	char buf[1024];
	int content_length=-1;

	int cgi_input[2]={0};
	int cgi_output[2]={0};

	pid_t pid;

	if(strcasecmp(method,"GET")==0)//如果是get方法,信息都存储在query_string中,因此直接清空client
	{
		clear_header(client);
	}
	else//否则就是POST方法,需要cgi执行
	{
		do
		{
			memset(buf,'\0',sizeof(buf));
			num=get_line(client,buf,sizeof(buf));
			if(strncasecmp(buf,"Content-Length:",15)==0)
			{
				content_length=atoi(&buf[16]);//在消息报头中得到消息正文的长度		
			}
		}while(num>0 && strcmp(buf,"\n")!=0);
		if(content_length==-1)//content_length如果还是-1,则说明请求格式有问题
		{
			return_error_client();
			return;
		}
	}
	sprintf(buf,"HTTP/1.0 200 OK\r\n\r\n");//该请求被受理返回状态行信息
	send(client,buf,strlen(buf),0);

	if(pipe(cgi_input)<0)
	{
		return_error_client();
		return;
	}
	//创建两个管道
	if(pipe(cgi_output)<0)
	{
		close(cgi_input[0]);
		close(cgi_input[1]);
		return_error_client();
		return;
	}

	if((pid=fork())<0)
	{
		close(cgi_input[0]);
		close(cgi_input[1]);
		close(cgi_output[0]);
		close(cgi_output[1]);
		return_error_client();
		return;
	}
	else if(pid==0)//子进程
	{
		//设置三个数组存放环境变量
		char meth_env[1024];
		char query_env[1024];
		char content_len_env[1024];
		memset(meth_env,'\0',sizeof(meth_env));
		memset(query_env,'\0',sizeof(query_env));
		memset(content_len_env,'\0',sizeof(content_len_env));

		close(cgi_input[1]);//cgi脚本从cgi_input读取数据
		close(cgi_output[0]);//cgi脚本从cgi_output输出数据

		dup2(cgi_output[1],1);//cgi脚本的标准输出变成cgi_output管道
		dup2(cgi_input[0],0);//cgi脚本的标准输入变成cgi_input
		sprintf(meth_env,"REQUEST_METHOD=%s",method);
		putenv(meth_env);//设置环境变量

		if(strcasecmp(method,"GET")==0)//GET方法进入cgi,说明client肯定有参数传入
		{
			sprintf(query_env,"QUERY_STRING=%s",query_string);
			putenv(query_env);//将参数导出为环境变量,供cgi脚本使用
		}
		else//POST方法
		{
			sprintf(content_len_env,"CONTENT_LENGTH=%d",content_length);
			putenv(content_len_env);
		}
		execl(path,path,NULL);
		exit(1);
	}
	else//父进程
	{
		int i=0;
		char c;
		close(cgi_input[0]);
		close(cgi_output[1]);
		if(strcasecmp(method,"POST")==0)
		{
			for(;i<content_length;i++)
			{
				recv(client,&c,1,0);
				write(cgi_input[1],&c,1);
			}
		}
		while(read(cgi_output[0],&c,1)>0)
		{
			send(client,&c,1,0);
		}
		close(cgi_input[0]);
		close(cgi_output[1]);
		waitpid(pid,NULL,0);
	}

}
Exemplo n.º 12
0
void* accept_request(void* arg)
{
    pthread_detach(pthread_self());
    
    int sock = (int)arg;
    char buf[_SIZE_];
    char method[_SIZE_];
    char url[_SIZE_];
    char path[_SIZE_];

    memset(buf, '\0', sizeof(buf));
    memset(method, '\0', sizeof(method));
    memset(url, '\0', sizeof(url));
    memset(path, '\0', sizeof(path));
    
    int cgi = 0;
    int ret = -1;
    char* query_string = NULL;

#ifdef _DEBUG_
    do{
        ret = get_line(sock, buf, sizeof(buf));
        printf("%s", buf);
        fflush(stdout);
    } while((ret > 0) && (strcmp(buf, "\n") != 0));
#endif

    ret = get_line(sock, buf, sizeof(buf));
    if(ret < 0)
    {
        echo_errno(sock);
        return (void *)1;
    }

    //GET          /HTTP/1.1
    int i = 0;     // method index
    int j = 0;     // buf index

    while( (i < sizeof(method)-1) && (j < sizeof(buf)) && (!isspace(buf[j])))
    {
        method[i] = buf[j];
        i++, j++;
    }

    method[i] = '\0';
    while( isspace(buf[j]) )
    {
        j++;
    }

    if(strcasecmp(method, "GET") != 0 && strcasecmp(method, "POST") != 0)
    {
        echo_errno(sock);
        return (void*)2;
    }

    if(strcasecmp(method, "POST") == 0)
    {
        cgi = 1;
    }

    i = 0; // url index
    while( (i<sizeof(url)-1) && (j < sizeof(buf)) && (!isspace(buf[j])))
    {
        url[i] = buf[j];
        i++, j++;
    }

    if(strcasecmp(method, "GET") == 0)
    {
        query_string = url;
        while(*query_string != '\0' && *query_string != '?' )
        {
            query_string++;
        }

        if(*query_string == '?')
        {
            cgi = 1;
            *query_string = '\0';
            query_string++;
        }
    }

    // /     /aa/bb/cc
    sprintf(path, "htdoc%s", url);   // htdoc/
    if(path[strlen(path) - 1] == '/')
    {
        strcat(path, "index.html");
    }

    printf("method: %s\n", method);
    printf("path: %s\n", path);
    printf("query_string: %s\n", query_string);
    
    struct stat st;
    if(stat(path, &st) < 0)
    {
        echo_errno(sock);
        return (void*)3;
    }
    else
    {
        if(S_ISDIR(st.st_mode))
        {
            strcpy(path, "htdoc/index.html");
        }
        else if( (st.st_mode & S_IXUSR) || (st.st_mode & S_IXGRP) || (st.st_mode & S_IXOTH) )
        {
            cgi = 1;
        }
        else
        {}

        if(cgi)
        {
            exec_cgi(sock, path, method, query_string);
        }
        else
        {
            clear_header(sock);
            echo_html(sock, path, st.st_size);
        }
    }

    close(sock);
    return (void*)0;
}
Exemplo n.º 13
0
void exec_cgi(int sock, const char* path, const char* method, const char* query_string)
{
    print_debug("enter cgi\n");
    char buf[_SIZE_];
    int numchars = 0;
    int content_length = -1;
    
    // pipe
    int cgi_input[2] = {0, 0};
    int cgi_output[2] = {0, 0};
    //child proc
    pid_t id;

    print_debug(method);

    if(strcasecmp(method, "GET") == 0) // GET
    {
        clear_header(sock);
    }
    else // POST
    {
        do{
            memset(buf, '\0', sizeof(buf));
            numchars = get_line(sock, buf, sizeof(buf));
            if(strncasecmp(buf, "Content-Length:", strlen("Content-Length:")) == 0)
            {
                content_length = atoi(&buf[16]);
            }
        }while(numchars > 0 && strcmp(buf, "\n") != 0);

        if(content_length == -1)
        {
            return;
        }
    }

    memset(buf, '\0', sizeof(buf));
    strcpy(buf, HTTP_VERSION);
    strcat(buf, " 200 OK\r\n\r\n");
    send(sock, buf, strlen(buf), 0);

    if(pipe(cgi_input) == -1) // pipe error
    {
        return;
    }
    
    if(pipe(cgi_output) == -1) // 
    {
        close(cgi_input[0]);
        close(cgi_input[1]);
        return;
    }

    if((id = fork()) < 0) // fork error
    {
        close(cgi_input[0]);
        close(cgi_input[1]);
        close(cgi_output[0]);
        close(cgi_output[1]);
        return;
    }
    else if( id == 0 ) // child
    {
        char query_env[_SIZE_/10];
        char method_env[_SIZE_];
        char content_len_env[_SIZE_];
        memset(method_env, '\0', sizeof(method_env));
        memset(query_env, '\0', sizeof(query_env));
        memset(content_len_env, '\0', sizeof(content_len_env));

        close(cgi_input[1]);
        close(cgi_output[0]);

        dup2(cgi_input[0], 0);
        dup2(cgi_output[1], 1);

        sprintf(method_env, "REQUEST_METHOD=%s", method);
        putenv(method_env);
        if(strcasecmp("GET", method) == 0) // GET
        {
            sprintf(query_env, "QUERY_STRING=%s", query_string);
            putenv(query_env);
        }
        else
        {
            sprintf(content_len_env, "CONTENT_LENGTH=%d", content_length);
            putenv(content_len_env);
        }

        execl(path, path, NULL);
        exit(1);
    }
    else   // father
    {
        close(cgi_input[0]);
        close(cgi_output[1]);
        int i = 0;
        char c = '\0';
        if(strcasecmp("POST", method) == 0)
        {
            for(; i < content_length; i++)
            {
                recv(sock, &c, 1, 0);
                write(cgi_input[1], &c, 1);
            }
        }

        while( read(cgi_output[0], &c, 1) > 0)
        {
            send(sock, &c, 1, 0);
        }
        close(cgi_input[1]);
        close(cgi_output[0]);

        waitpid(id, NULL, 0);
    }
}
Exemplo n.º 14
0
static int _fastcall _list( LPTSTR pszFileName )
{
	register int c, i;
	TCHAR szDescription[512], szHeader[132], szLine[32];
	long lTemp, lRow;
	POPWINDOWPTR wn = NULL;
	FILESEARCH dir;
	
	// get default normal and inverse attributes
	if ( gpIniptr->ListColor != 0 ) {
		SetScrColor( nScreenRows, nScreenColumns, gpIniptr->ListColor );

	}
	
	// set colors
	GetAtt( (unsigned int *)&nNormal, (unsigned int *)&nInverse );
	if ( gpIniptr->ListStatusColor != 0 )
		nInverse = gpIniptr->ListStatusColor;
	
	// flip the first line to inverse video
	clear_header();
	
	// open the file & initialize buffers
	if ( ListOpenFile( pszFileName ))
		return ERROR_EXIT;
	
	// kludge for empty files or pipes
	if ( LFile.lSize == 0L )
		LFile.lSize = 1L;
	
	for ( ; ; ) {
		
		// display header
		if ( fDirtyHeader ) {
			clear_header();
			sprintf( szHeader, LIST_HEADER, fname_part(LFile.szName), gchVerticalBar, gchVerticalBar, gchVerticalBar );
			WriteStrAtt( 0, 0, nInverse, szHeader );
			fDirtyHeader = 0;
		}
		
		// display location within file
		//	(don't use color_printf() so we won't have
		//	problems with windowed sessions)

		i = sprintf( szHeader, LIST_LINE, LFile.nListHorizOffset, LFile.lCurrentLine + gpIniptr->ListRowStart, (int)((( LFile.lViewPtr + 1 ) * 100 ) / LFile.lSize ));

		WriteStrAtt( 0, ( nScreenColumns - i ), nInverse, szHeader );
		SetCurPos( 0, 0 );
		
		if ( lListFlags & LIST_SEARCH ) {
			
			lListFlags &= ~LIST_SEARCH;
			fSearchFlags = 0;
			if ( lListFlags & LIST_REVERSE ) {
				
				c = LIST_FIND_CHAR_REVERSE;
				fSearchFlags |= FFIND_REVERSE_SEARCH;
				
				// goto the last row
				while ( ListMoveLine( 1 ) != 0 )
					;
			} else
				c = LIST_FIND_CHAR;
			
			if ( lListFlags & LIST_NOWILDCARDS )
				fSearchFlags |= FFIND_NOWILDCARDS;
			bListSkipLine = 0;
			goto FindNext;
		}
		
		// get the key from the BIOS, because
		//	 STDIN might be redirected
		
		if ((( c = cvtkey( GetKeystroke( EDIT_NO_ECHO | EDIT_BIOS_KEY | EDIT_UC_SHIFT), MAP_GEN | MAP_LIST)) == (TCHAR)ESC ))
			break;
		
		switch ( c ) {
		case CTRLC:
			return CTRLC;
			
		case CUR_LEFT:
		case CTL_LEFT:
			
			if (( lListFlags & LIST_WRAP ) || ( LFile.nListHorizOffset == 0 ))
				goto bad_key;
			
			if (( LFile.nListHorizOffset -= (( c == CUR_LEFT ) ? 8 : 40 )) < 0 )
				LFile.nListHorizOffset = 0;
			break;
			
		case CUR_RIGHT:
		case CTL_RIGHT:
			
			if (( lListFlags & LIST_WRAP ) || ( LFile.nListHorizOffset >= MAXLISTLINE + 1 ))
				goto bad_key;
			
			if ((LFile.nListHorizOffset += ((c == CUR_RIGHT) ? 8 : 40 )) > MAXLISTLINE + 1 )
				LFile.nListHorizOffset = MAXLISTLINE+1;
			break;
			
		case CUR_UP:
			
			if ( ListMoveLine( -1 ) == 0 )
				goto bad_key;
			
			Scroll(1, 0, nScreenRows, nScreenColumns, -1, nNormal);
			DisplayLine( 1, LFile.lViewPtr );
			continue;
			
		case CUR_DOWN:
			
			if ( ListMoveLine( 1 ) == 0 )
				goto bad_key;
			
			Scroll( 1, 0, nScreenRows, nScreenColumns, 1, nNormal );
			
			// display last line
			lTemp = LFile.lViewPtr;
			lRow = (nScreenRows - 1);
			lTemp += MoveViewPtr( lTemp, &lRow );
			if ( lRow == ( nScreenRows - 1 ))
				DisplayLine( nScreenRows, lTemp );
			continue;
			
		case HOME:
			
			ListHome();
			break;
			
		case END:
			
			// goto the last row
			list_wait( LIST_WAIT );
			while ( ListMoveLine( 1 ) != 0 )
				;

		case PgUp:
			
			// already at TOF?
			if ( LFile.lViewPtr == 0L )
				goto bad_key;
			
			for ( i = 1; (( i < nScreenRows ) && ( ListMoveLine( -1 ) != 0 )); i++ )
				;
			
			break;
			
		case PgDn:
		case SPACE:
			
			if ( ListMoveLine( nScreenRows - 1 ) == 0 )
				goto bad_key;
			
			break;
			
		case F1:	// help

			// don't allow a ^X exit from HELP
			_help( gpInternalName, HELP_NX );

			continue;
			
		case TAB:
			// change tab size
			
			// disable ^C / ^BREAK handling
			HoldSignals();
			
			wn = wOpen( 2, 5, 4, strlen( LIST_TABSIZE ) + 10, nInverse, LIST_TABSIZE_TITLE, NULL );
			wn->nAttrib = nNormal;
			wClear();
			
			wWriteListStr( 0, 1, wn, LIST_TABSIZE );
			egets( szLine, 2, (EDIT_DIALOG | EDIT_BIOS_KEY | EDIT_NO_CRLF | EDIT_DIGITS));
			wRemove( wn );
			if (( i = atoi( szLine )) > 0 )
				TABSIZE = i;
			
			// enable ^C / ^BREAK handling
			EnableSignals();
			break;
			
		case DEL:
			// delete this file
			if (( lListFlags & LIST_STDIN ) == 0 ) {
				
				// disable ^C / ^BREAK handling
				HoldSignals();
				
				wn = wOpen( 2, 5, 4, strlen( LIST_DELETE ) + 10, nInverse, LIST_DELETE_TITLE, NULL );
				wn->nAttrib = nNormal;
				wClear();
				
				wWriteListStr( 0, 1, wn, LIST_DELETE );
				i = GetKeystroke( EDIT_ECHO | EDIT_BIOS_KEY | EDIT_UC_SHIFT );
				wRemove( wn );
				
				// enable ^C / ^BREAK handling
				EnableSignals();
				
				if ( i == (TCHAR)YES_CHAR ) {
					if ( LFile.hHandle > 0 )
						_close( LFile.hHandle );
					LFile.hHandle = -1;
					
					remove( pszFileName );
					return 0;
				}
			}
			break;
			
		case INS:
			// save to a file
			ListSaveFile();
			break;
			
		case LIST_INFO_CHAR:
			{
				unsigned int uSize = 1024;
				TCHAR _far *lpszText, _far *lpszArg;
				int fFSType, fSFN = 1;
				TCHAR szBuf[16];

				DOSFILEDATE laDir, crDir;

				// disable ^C / ^BREAK handling
				HoldSignals();
				
				memset( &dir, '\0', sizeof(FILESEARCH) );
				if (( lListFlags & LIST_STDIN ) == 0 ) {
					if ( find_file( FIND_FIRST, LFile.szName, 0x07 | FIND_CLOSE | FIND_EXACTLY, &dir, NULL ) == NULL ) {
						honk();
						continue;
					}
				}
				
				// display info on the current file
				i = (( lListFlags & LIST_STDIN ) ? 5 : 10 );
				if (( fFSType = ifs_type( LFile.szName )) != FAT )
					i = 11;
				wn = wOpen( 2, 1, i, 77, nInverse, gpInternalName, NULL );
				
				wn->nAttrib = nNormal;
				wClear();
				i = 0;
				
				if ( lListFlags & LIST_STDIN )
					wWriteStrAtt( 0, 1, nNormal, LIST_INFO_PIPE );
				
				else {
					
					szDescription[0] = _TEXT('\0');
					process_descriptions( LFile.szName, szDescription, DESCRIPTION_READ );
					
					lpszText = lpszArg = (TCHAR _far *)AllocMem( &uSize );

					strcpy(szBuf, FormatDate( dir.fd.file_date.months, dir.fd.file_date.days, dir.fd.file_date.years + 80, 0 ));
					
					if (fFSType != FAT) {
						FileTimeToDOSTime( &(dir.ftLastAccessTime), &( laDir.ft.wr_time), &( laDir.fd.wr_date) );
						FileTimeToDOSTime( &(dir.ftCreationTime), &(crDir.ft.wr_time), &(crDir.fd.wr_date) );
						strcpy( szLine, FormatDate( laDir.fd.file_date.months, laDir.fd.file_date.days, laDir.fd.file_date.years + 80, 0 ));
						sprintf_far( lpszText, LIST_INFO_LFN,
							LFile.szName, szDescription, dir.ulSize,
							szBuf,
							dir.ft.file_time.hours, gaCountryInfo.szTimeSeparator[0],dir.ft.file_time.minutes,
							szLine,
							laDir.ft.file_time.hours, gaCountryInfo.szTimeSeparator[0], laDir.ft.file_time.minutes,
							FormatDate( crDir.fd.file_date.months, crDir.fd.file_date.days, crDir.fd.file_date.years + 80, 0 ),
							crDir.ft.file_time.hours, gaCountryInfo.szTimeSeparator[0], crDir.ft.file_time.minutes);
					} else {
						
						sprintf_far( lpszText, LIST_INFO_FAT,
							LFile.szName, szDescription, dir.ulSize,
							szBuf, dir.ft.file_time.hours, 
							gaCountryInfo.szTimeSeparator[0],dir.ft.file_time.minutes );
					}

					// print the text
					for ( ; ( *lpszArg != _TEXT('\0') ); i++ ) {
						sscanf_far( lpszArg, _TEXT("%[^\n]%*c%n"), szHeader, &uSize );

						// allow for long filenames ...
						if (( i == 0 ) && ( strlen( szHeader ) > 73 )) {
							c = szHeader[73];
							szHeader[73] = _TEXT('\0');
							wWriteStrAtt( i++, 1, nNormal, szHeader );
							szHeader[73] = (TCHAR)c;
							wWriteStrAtt( i, 15, nNormal, szHeader+73 );
							fSFN = 0;
						} else

							wWriteStrAtt( i, 1, nNormal, szHeader );
						lpszArg += uSize;
					}
					
					FreeMem( lpszText );
				}
				
				wWriteListStr( i+fSFN, 1, wn, PAUSE_PROMPT );
				GetKeystroke( EDIT_NO_ECHO | EDIT_BIOS_KEY );
				
				wRemove( wn );
				
				// enable ^C / ^BREAK handling
				EnableSignals();
				
				continue;
			}
			
		case LIST_GOTO_CHAR:
			
			// goto the specified line / hex offset
			
			// disable ^C / ^BREAK handling
			HoldSignals();
			
			wn = wOpen( 2, 5, 4, strlen( LIST_GOTO_OFFSET ) + 20, nInverse, LIST_GOTO_TITLE, NULL );
			wn->nAttrib = nNormal;
			wClear();
			
			wWriteListStr( 0, 1, wn, (( lListFlags & LIST_HEX) ? LIST_GOTO_OFFSET : LIST_GOTO));
			i = egets( szLine, 10, (EDIT_DIALOG | EDIT_BIOS_KEY | EDIT_NO_CRLF));
			wRemove( wn );
			
			// enable ^C / ^BREAK handling
			EnableSignals();
			
			if ( i == 0 )
				break;
			list_wait( LIST_WAIT );
			
			// if in hex mode, jump to offset 
			if ( lListFlags & LIST_HEX ) {
				strupr( szLine );
				sscanf( szLine, _TEXT("%lx"), &lRow );
				lRow = lRow / 0x10;
			} else if ( sscanf( szLine, FMT_LONG, &lRow ) == 0 )
				continue;
			
			lRow -= gpIniptr->ListRowStart;
			if ( lRow >= 0 ) {
				LFile.lViewPtr = MoveViewPtr( 0L, &lRow );
				LFile.lCurrentLine = lRow;
			} else {
				LFile.lViewPtr += MoveViewPtr( LFile.lViewPtr, &lRow );
				LFile.lCurrentLine += lRow;
			}
			break;
			
		case LIST_HIBIT_CHAR:
			
			// toggle high bit filter
			lListFlags ^= LIST_HIBIT;
			break;
			
		case LIST_WRAP_CHAR:
			
			// toggle line wrap
			lListFlags ^= LIST_WRAP;
			nRightMargin = (( lListFlags & LIST_WRAP ) ? GetScrCols() : MAXLISTLINE );
			
			// recalculate current line
			list_wait( LIST_WAIT );
			
			// get start of line
			LFile.nListHorizOffset = 0;
			
			// line number probably changed, so recompute everything
			LFile.lCurrentLine = ComputeLines( 0L, LFile.lViewPtr );
			LFile.lViewPtr = MoveViewPtr( 0L, &(LFile.lCurrentLine ));
			break;
			
		case LIST_HEX_CHAR:
			
			// toggle hex display
			lListFlags ^= LIST_HEX;
			
			// if hex, reset to previous 16-byte
			//	 boundary
			if ( lListFlags & LIST_HEX ) {

				LFile.lViewPtr -= ( LFile.lViewPtr % 16 );
			} else {
				// if not hex, reset to start of line
				ListMoveLine( 1 );
				ListMoveLine( -1 );
			}
			
			// recalculate current line
			list_wait( LIST_WAIT );
			LFile.lCurrentLine = ComputeLines( 0L, LFile.lViewPtr );
			break;
			
		case LIST_FIND_CHAR:
		case LIST_FIND_CHAR_REVERSE:
			// find first matching string
			bListSkipLine = 0;
			//lint -fallthrough
			
		case LIST_FIND_NEXT_CHAR:
		case LIST_FIND_NEXT_CHAR_REVERSE:
			// find next matching string
			
			if (( c == LIST_FIND_CHAR ) || ( c == LIST_FIND_CHAR_REVERSE )) {
				
				// disable ^C / ^BREAK handling
				HoldSignals();
				
				fSearchFlags = 0;
				wn = wOpen( 2, 1, 4, 75, nInverse, (( c == LIST_FIND_NEXT_CHAR_REVERSE ) ? LIST_FIND_TITLE_REVERSE : LIST_FIND_TITLE ), NULL );
				wn->nAttrib = nNormal;
				wClear();
				
				if ( lListFlags & LIST_HEX ) {
					wWriteListStr( 0, 1, wn, LIST_FIND_HEX );
					if ( GetKeystroke( EDIT_ECHO | EDIT_BIOS_KEY | EDIT_UC_SHIFT ) == YES_CHAR )
						fSearchFlags |= FFIND_HEX_SEARCH;
					wClear();
				}
				
				wWriteListStr( 0, 1, wn, LIST_FIND );
				egets( szListFindWhat, 64, (EDIT_DIALOG | EDIT_BIOS_KEY | EDIT_NO_CRLF));
				wRemove( wn );
				
				// enable ^C / ^BREAK handling
				EnableSignals();
				
			} else {
FindNext:
			// a "Next" has to be from current position
			fSearchFlags &= ~FFIND_TOPSEARCH;
			}
			
			if ( szListFindWhat[0] == _TEXT('\0') )
				continue;
			
			sprintf( szDescription, LIST_FIND_WAIT, szListFindWhat );
			list_wait( szDescription );
			
			// save start position
			lTemp = LFile.lViewPtr;
			lRow = LFile.lCurrentLine;
			
			if (( c == LIST_FIND_CHAR_REVERSE ) || ( c == LIST_FIND_NEXT_CHAR_REVERSE )) {
				// start on the previous line
				fSearchFlags |= FFIND_REVERSE_SEARCH;
			} else {
				fSearchFlags &= ~FFIND_REVERSE_SEARCH;
				// skip the first line (except on /T"xxx")
				if ( bListSkipLine )
					ListMoveLine( 1 );
			}
			
			bListSkipLine = 1;
			if ( SearchFile( fSearchFlags ) != 1 ) {
				ListSetCurrent( lTemp );
				LFile.lViewPtr = lTemp;
				LFile.lCurrentLine = lRow;
			} else
				LFile.fDisplaySearch = (( fSearchFlags & FFIND_CHECK_CASE ) ? 2 : 1 );
			
			break;
			
		case LIST_PRINT_CHAR:
			
			// print the file
			ListPrintFile();
			continue;
			
		case LIST_CONTINUE_CHAR:
		case CTL_PgDn:
			return 0;
			
		case LIST_PREVIOUS_CHAR:
		case CTL_PgUp:
			// previous file
			if ( nCurrent > 0 ) {
				nCurrent--;
				return 0;
			}
			//lint -fallthrough
			
		default:
bad_key:
			honk();
			continue;
		}
		
		// rewrite the display
		ListUpdateScreen();
	}
	
	return 0;
}
Exemplo n.º 15
0
static void* accept_request(void *arg)		//static
{
	int sock = (int)arg;
	char buf[SIZE];
	int len = sizeof(buf)/sizeof(*buf);
	char method[SIZE/10];
	char url[SIZE];
	char path[SIZE];
	int ret = -1;
	int i = 0;
	int j = 0;

	char *query_string = NULL;    //aim at val(can shu)
	int cgi = 0;
#ifdef _DEBUG_
//	do
//	{
//		ret = get_line(sock, buf, len);
//		printf("%s", buf);
//		fflush(stdout);
//	}while(ret > 0 && (strcmp(buf, "\n") != 0) );
#endif

	memset(buf, '\0', sizeof(buf));
	memset(method, '\0', sizeof(method));
	memset(url, '\0', sizeof(url));
	memset(path, '\0', sizeof(buf));

	//Request Line
	ret = get_line(sock, buf, len);
	if(ret <= 0)
	{
		echo_errno(sock);
		return (void*)1;
	}
	i = 0;	//method index
	j = 0;	//buf index
	while((i < (sizeof(method)/sizeof(*method) - 1)) && (j < sizeof(buf)/sizeof(*buf) - 1) && (!isspace(buf[j]) ) )
	{
		method[i] = buf[j];
		++i;
		++j;
	}
	method[i] = '\0';
	if((strcasecmp(method, "GET") != 0) && (strcasecmp(method, "POST")) )
	{
		//echo_errno(sock);
		return (void*)2;
	}

	//URL
	while(isspace(buf[j]))	//Remove Space
	{
		++j;
	}
	i = 0;
	while( ( i < sizeof(url)/sizeof(*url)-1 ) && (j < sizeof(buf)/sizeof(*buf)) && (!isspace(buf[j])) )
	{
		url[i] = buf[j];
		++i;
		++j;
	}
	url[i] = '\0';

	if( strcasecmp(method, "POST") == 0 )
	{
		cgi = 1;
		sprintf(path, "%s", url+1);
	}

	if( strcasecmp(method, "GET") == 0 )
	{
		query_string = url;
		while( *query_string != '\0' && *query_string != '?' )
		{
			query_string++;
		}
		if(*query_string == '?')
		{
			cgi = 1;
			*query_string = '\0';
			++query_string;
		}
	}

	if( strcasecmp(method, "GET") == 0 )
	{
		sprintf(path, "htdoc%s", url);
		if( path[strlen(path)-1] == '/' )
		{
			strcat(path, "index.html");
		}
	}


	struct stat st;
	if( stat(path, &st) < 0 )
	{
		//echo_errno();	//404	
		return (void*)3;
	}
	else	//case : DIR
	{
		if( S_ISDIR(st.st_mode) )
		{
			strcat(path, "index.html");
		}
		else if( (st.st_mode & S_IXUSR) || (st.st_mode & S_IXGRP) || (st.st_mode & S_IXOTH) )      //bin(binary file)
		{
			cgi = 1;
		}
		else
		{}   //noting to do
	}
	
	printf("!@!#%@^   %s   !@%@^%\n", buf);
	if(cgi) // u+x file
	{
		printf("!!!!!!!!!!!!!!!!!!!!!!!!!!!!cgi\n");
		exe_cgi(sock, method, path, query_string);  //cgi mode
	}
	else  //.jpg   .html ...
	{
		printf("!!!!!!!!!!!!!!!!!!!!!!!!!!!!!www\n");
		clear_header(sock);  //! important!
		echo_www(sock, path, st.st_size);
	}

	close(sock);
	return 0;

	
}
Exemplo n.º 16
0
static void exe_cgi( int sock, const char *method, const char *path, const char *query_string )
{
	char buf[SIZE];
	int content_length = -1;

	//pipe named by child side
	int cgi_input[2];
	int cgi_output[2];
	char method_env[SIZE];
	char query_string_env[SIZE];
	char content_length_env[SIZE];
	char tmpc;
	
	memset(buf, '\0', sizeof(buf));				// ! ! ! ! !  M U S T     I N I T   A R R A Y ! ! !     
	memset(method_env, '\0', sizeof(method_env));
	memset(query_string_env, '\0', sizeof(query_string));
	memset(content_length_env, '\0', sizeof(content_length_env));



	if(strcasecmp(method, "GET") == 0 )
	{
		clear_header(sock);			//"GET" send val by url ,already get
	}

	int ret = 0;
	if(strcasecmp(method, "POST") == 0 )  //different
	{
		do
		{
			memset(buf, '\0', sizeof(buf));
			ret = get_line(sock, buf, sizeof(buf));
			if( strncasecmp(buf, "Content-Length: ", 16) == 0)
			{
				content_length = atoi(&buf[16]);
			}
		}while( (ret > 0) && strcmp(buf, "\n") != 0 );

		printf("content_length = %d\n", content_length);

		if( content_length == -1 )
		{
			echo_errno(sock);  
			return;
		}
	}
/////////////  (8.11)  /////////////////////////////
	
	sprintf(buf, "HTTP/1.0 200 OK\r\n\r\n");
	send(sock, buf, strlen(buf), 0);

	if( pipe(cgi_input) < 0 )
	{
		echo_errno(sock);
		return;
	}
	if( pipe(cgi_output) < 0 )
	{
		echo_errno(sock);
		return;
	}

	pid_t id = fork();
	if(id == 0)		//child
	{
		close(cgi_input[1]);
		close(cgi_output[0]);
  
		dup2(cgi_input[0], 0);
		dup2(cgi_output[1], 1);


		sprintf(method_env, "REQUEST_METHOD=%s", method);
		putenv(method_env);
		if( strcasecmp(method, "GET") == 0 )		//GET	
		{
			sprintf(query_string_env, "QUERY_STRING=%s", query_string);
			putenv(query_string_env);
		}
		else  //POST
		{
			sprintf(content_length_env, "CONTENT_LENGTH=%d", content_length);
			putenv(content_length_env);
		}
		execl(path, path, NULL);
		//run here , execl wrong
		exit(1);
	}
	else  //father
	{
		close(cgi_input[0]);
		close(cgi_output[1]);
		
	//	dup2(cgi_input[1], 1);
	//	dup2(cgi_output[0], 0);

		char c = '\0';
		int  i =0;

		if( strcasecmp(method, "POST") == 0 )
		{
			for(; i < content_length; ++i)  
			{
				recv(sock, &c, 1, 0);
				printf("%c", c);
				write(cgi_input[1], &c, 1);
			}
		}
		
		int ret = 0;
		while( read(cgi_output[0], &c, 1) > 0)
		{
			send(sock, &c, 1, 0);
		}

		waitpid(id, NULL, 0);
	}

}