コード例 #1
0
  /* Execute script in /cgi-bin*/
  void execute_script(int socket)
{
  /* Currently unsupported, return error code to client*/
  cannot_execute(socket);

  return;
}
コード例 #2
0
ファイル: httpd.c プロジェクト: dodng/CHTTPSimpleServer
void execute_cgi(int client, const char *path,
		const char *method, const char *query_string)
{
	char buf[1024];
	int cgi_output[2];
	int cgi_input[2];
	pid_t pid;
	int status;
	int i;
	char c;
	int numchars = 1;
	int content_length = -1;

	buf[0] = 'A'; buf[1] = '\0';
	if (strcasecmp(method, "GET") == 0)
		while ((numchars > 0) && strcmp("\n", buf))  /* read & discard headers */
			numchars = get_line(client, buf, sizeof(buf));
	else    /* POST */
	{
		numchars = get_line(client, buf, sizeof(buf));
		while ((numchars > 0) && strcmp("\n", buf))
		{
			buf[15] = '\0';
			if (strcasecmp(buf, "Content-Length:") == 0)
				content_length = atoi(&(buf[16]));
			numchars = get_line(client, buf, sizeof(buf));
		}
		if (content_length == -1) {
			bad_request(client);
			return;
		}
	}

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

	if (pipe(cgi_output) < 0) {
		cannot_execute(client);
		return;
	}
	if (pipe(cgi_input) < 0) {
		cannot_execute(client);
		return;
	}

	if ( (pid = fork()) < 0 ) {
		cannot_execute(client);
		return;
	}
	if (pid == 0)  /* child: CGI script */
	{
		char meth_env[255];
		char query_env[255];
		char length_env[255];

		dup2(cgi_output[1], 1);
		dup2(cgi_input[0], 0);
		close(cgi_output[0]);
		close(cgi_input[1]);
		sprintf(meth_env, "REQUEST_METHOD=%s", method);
		putenv(meth_env);
		if (strcasecmp(method, "GET") == 0) {
			sprintf(query_env, "QUERY_STRING=%s", query_string);
			putenv(query_env);
		}
		else {   /* POST */
			sprintf(length_env, "CONTENT_LENGTH=%d", content_length);
			putenv(length_env);
		}
		execl(path, path, NULL);
		exit(0);
	} else {    /* parent */
		close(cgi_output[1]);
		close(cgi_input[0]);
		if (strcasecmp(method, "POST") == 0)
			for (i = 0; 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_output[0]);
		close(cgi_input[1]);
		waitpid(pid, &status, 0);
	}
}
コード例 #3
0
ファイル: linuxeditrule.c プロジェクト: EnderUNIX/netUstad
void
editrule(nunetwork_socket client, char *path, char *method, char *query_string)
{
	char buf[1024], tmpbuf[255];
	int cgi_output[2];
	int cgi_input[2];
	pid_t pid;
	int status;
	char c;
	char *param[64];
	char *tempstr;
	char *ruleno;
	char *chain;
	int pos = 0;

	buf[0] = 'A';
	buf[1] = '\0';
/*	if (strcasecmp(method, "GET") == 0)
		nunetwork_discardheaders(client);
	else {			/ * POST * /

		unimplemented(client);
		return;
	}
*/
	if (strlen(query_string) < 13) {
		unimplemented(client);
		return;
	}

	snprintf(buf, sizeof (buf)-1,
		 "HTTP/1.1 200 OK\r\nContent-Type: text/html\r\n\r\n");
	nunetwork_send(client, buf, strlen(buf), 0);

	param[pos++] = (char *)strdup(path);
	param[pos++] = "-R";
	tempstr = (char *)strdup(query_string);

	ruleno = (char *)strdup(strtok(tempstr, "@\n"));
	chain  = (char *)strdup(strtok(NULL, "@\n"));
	param[pos++] = (char *)strdup(chain);
	param[pos] = (char *)strdup(ruleno);
	while (param[pos++] != NULL) {
		param[pos] = strtok(NULL, "@\n");
	}

	/* Replacing Rule  */
	if (pipe(cgi_output) < 0) {
		cannot_execute(client);
		return;
	}
	if (pipe(cgi_input) < 0) {
		cannot_execute(client);
		return;
	}

	if ((pid = fork()) < 0) {
		cannot_execute(client);
		return;
	}

	if (pid == 0) {		/* child: Add new rule */
		dup2(cgi_output[1], 1);
		dup2(cgi_input[0], 0);
		close(cgi_output[0]);
		close(cgi_input[1]);
		execv(path, param);
		exit(0);
	} else {		/* parent */
		close(cgi_output[1]);
		close(cgi_input[0]);
		pos = 0;
		while (read(cgi_output[0], &c, 1) > 0)
			tmpbuf[pos++] = c;
		tmpbuf[pos] = '\0';
		close(cgi_output[0]);
		close(cgi_input[1]);
		waitpid(pid, &status, 0);

		/* Log Request  */
		snprintf(log_msg_text, sizeof (log_msg_text)-1,
			 "IP: %s %s: %s:%s %s:%s %s %s\n",
			 (char *) inet_ntoa(client_name.sin_addr),
			 (char *) gettext("Edit Rule"),
			 (char *) gettext("Chain"),
			 (char *) chain,
			 (char *) gettext("Rule"),
			 (char *) ruleno,
			 (char *) gettext("Replaced with"),
			 (char *) tmpbuf);
		log_msg(logfile, log_msg_text, 1);

		snprintf(buf, sizeof (buf)-1, "<html>\n<head>\n<meta http-equiv='Refresh' content='2; URL=/$%s'>\n\
						<meta http-equiv='Pragma' content='no-cache'>\n\
						<meta http-equiv=\"Content-Type\" content=\"text/html; charset=%s\">\n\
						<title>netUstad</title></head>\n",
					server_sid,
					(char *) gettext("charset"));
		nunetwork_send(client, buf, strlen(buf), 0);
		snprintf(buf, sizeof (buf)-1, "<link rel='stylesheet' type='text/css' href='/netustad.css'>\n");
		nunetwork_send(client, buf, strlen(buf), 0);
		snprintf(buf, sizeof (buf)-1, "<body><center>\n<br><b>%s<b><br>%s</body></html>\n",
			(char *) gettext("Edit Complete"),
			(char *) gettext("Redirecting to Rule List"));
		nunetwork_send(client, buf, strlen(buf), 0);
	}
}
コード例 #4
0
ファイル: tinyhttp.c プロジェクト: ywang2014/ProgramLearning
void execute_cgi(int client, const char *path, const char *method, const char *query_string)  
{  
    char buf[1024];  
    int cgi_output[2];  
    int cgi_input[2];  
    pid_t pid;  
    int status;  
    int i;  
    char c;  
    int numchars = 1;  
    int content_length = -1;  
  
    buf[0] = 'A'; buf[1] = '\0';  
    if (strcasecmp(method, "GET") == 0)  
        /*把所有的 HTTP header 读取并丢弃*/  
        while ((numchars > 0) && strcmp("\n", buf))  /* read & discard headers */  
            numchars = get_line(client, buf, sizeof(buf));  
    else    /* POST */  
    {  
        /* 对 POST 的 HTTP 请求中找出 content_length */  
        numchars = get_line(client, buf, sizeof(buf));  
        while ((numchars > 0) && strcmp("\n", buf))  
        {  
            /*利用 \0 进行分隔 */  
            buf[15] = '\0';  
            /* HTTP 请求的特点*/  
            if (strcasecmp(buf, "Content-Length:") == 0)  
                content_length = atoi(&(buf[16]));  
            numchars = get_line(client, buf, sizeof(buf));  
        }  
        /*没有找到 content_length */  
        if (content_length == -1) {  
            /*错误请求*/  
            bad_request(client);  
            return;  
        }  
    }  
  
    /* 正确,HTTP 状态码 200 */  
    sprintf(buf, "HTTP/1.0 200 OK\r\n");  
    send(client, buf, strlen(buf), 0);  
  
    /* 建立管道*/  
    if (pipe(cgi_output) < 0) {  
        /*错误处理*/  
        cannot_execute(client);  
        return;  
    }  
    /*建立管道*/  
    if (pipe(cgi_input) < 0) {  
        /*错误处理*/  
        cannot_execute(client);  
        return;  
    }  
  
    if ((pid = fork()) < 0 ) {  
        /*错误处理*/  
        cannot_execute(client);  
        return;  
    }  
    if (pid == 0)  /* child: CGI script */  
    {  
        char meth_env[255];  
        char query_env[255];  
        char length_env[255];  
  
        /* 把 STDOUT 重定向到 cgi_output 的写入端 */  
        dup2(cgi_output[1], 1);  
        /* 把 STDIN 重定向到 cgi_input 的读取端 */  
        dup2(cgi_input[0], 0);  
        /* 关闭 cgi_input 的写入端 和 cgi_output 的读取端 */  
        close(cgi_output[0]);  
        close(cgi_input[1]);  
        /*设置 request_method 的环境变量*/  
        sprintf(meth_env, "REQUEST_METHOD=%s", method);  
        putenv(meth_env);  
        if (strcasecmp(method, "GET") == 0) {  
            /*设置 query_string 的环境变量*/  
            sprintf(query_env, "QUERY_STRING=%s", query_string);  
            putenv(query_env);  
        }  
        else {   /* POST */  
            /*设置 content_length 的环境变量*/  
            sprintf(length_env, "CONTENT_LENGTH=%d", content_length);  
            putenv(length_env);  
        }  
        /*用 execl 运行 cgi 程序*/  
        execl(path, path, NULL);  
        exit(0);  
    } else {    /* parent */  
        /* 关闭 cgi_input 的读取端 和 cgi_output 的写入端 */  
        close(cgi_output[1]);  
        close(cgi_input[0]);  
        if (strcasecmp(method, "POST") == 0)  
            /*接收 POST 过来的数据*/  
            for (i = 0; i < content_length; i++) {  
                recv(client, &c, 1, 0);  
                /*把 POST 数据写入 cgi_input,现在重定向到 STDIN */  
                write(cgi_input[1], &c, 1);  
            }  
        /*读取 cgi_output 的管道输出到客户端,该管道输入是 STDOUT */  
        while (read(cgi_output[0], &c, 1) > 0)  
            send(client, &c, 1, 0);  
  
        /*关闭管道*/  
        close(cgi_output[0]);  
        close(cgi_input[1]);  
        /*等待子进程*/  
        waitpid(pid, &status, 0);  
    }  
}  
コード例 #5
0
ファイル: httpd.c プロジェクト: codewyh/TinyHttpd
void execute_cgi(int client, const char *path,
                 const char *method, const char *query_string)
{
 char buf[1024];
 int cgi_output[2];
 int cgi_input[2];
 pid_t pid;
 int status;
 int i;
 char c;
 int numchars = 1;
 int content_length = -1;
 
 //往 buf 中填东西以保证能进入下面的 while
 buf[0] = 'A'; buf[1] = '\0';
 //如果是 http 请求是 GET 方法的话读取并忽略请求剩下的内容
 if (strcasecmp(method, "GET") == 0)
  while ((numchars > 0) && strcmp("\n", buf))  /* read & discard headers */
   numchars = get_line(client, buf, sizeof(buf));
 else    /* POST */
 {
  //只有 POST 方法才继续读内容
  numchars = get_line(client, buf, sizeof(buf));
  //这个循环的目的是读出指示 body 长度大小的参数,并记录 body 的长度大小。其余的 header 里面的参数一律忽略
  //注意这里只读完 header 的内容,body 的内容没有读
  while ((numchars > 0) && strcmp("\n", buf))
  {
   buf[15] = '\0';
   if (strcasecmp(buf, "Content-Length:") == 0)
    content_length = atoi(&(buf[16])); //记录 body 的长度大小
   numchars = get_line(client, buf, sizeof(buf));
  }
  
  //如果 http 请求的 header 没有指示 body 长度大小的参数,则报错返回
  if (content_length == -1) {
   bad_request(client);
   return;
  }
 }

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

 //下面这里创建两个管道,用于两个进程间通信
 if (pipe(cgi_output) < 0) {
  cannot_execute(client);
  return;
 }
 if (pipe(cgi_input) < 0) {
  cannot_execute(client);
  return;
 }

 //创建一个子进程
 if ( (pid = fork()) < 0 ) {
  cannot_execute(client);
  return;
 }
 
 //子进程用来执行 cgi 脚本
 if (pid == 0)  /* child: CGI script */
 {
  char meth_env[255];
  char query_env[255];
  char length_env[255];

  //dup2()包含<unistd.h>中,参读《TLPI》P97
  //将子进程的输出由标准输出重定向到 cgi_ouput 的管道写端上
  dup2(cgi_output[1], 1);
  //将子进程的输出由标准输入重定向到 cgi_ouput 的管道读端上
  dup2(cgi_input[0], 0);
  //关闭 cgi_ouput 管道的读端与cgi_input 管道的写端
  close(cgi_output[0]);
  close(cgi_input[1]);
  
  //构造一个环境变量
  sprintf(meth_env, "REQUEST_METHOD=%s", method);
  //putenv()包含于<stdlib.h>中,参读《TLPI》P128
  //将这个环境变量加进子进程的运行环境中
  putenv(meth_env);
  
  //根据http 请求的不同方法,构造并存储不同的环境变量
  if (strcasecmp(method, "GET") == 0) {
   sprintf(query_env, "QUERY_STRING=%s", query_string);
   putenv(query_env);
  }
  else {   /* POST */
   sprintf(length_env, "CONTENT_LENGTH=%d", content_length);
   putenv(length_env);
  }
  
  //execl()包含于<unistd.h>中,参读《TLPI》P567
  //最后将子进程替换成另一个进程并执行 cgi 脚本
  execl(path, path, NULL);
  exit(0);
  
 } else {    /* parent */
  //父进程则关闭了 cgi_output管道的写端和 cgi_input 管道的读端
  close(cgi_output[1]);
  close(cgi_input[0]);
  
  //如果是 POST 方法的话就继续读 body 的内容,并写到 cgi_input 管道里让子进程去读
  if (strcasecmp(method, "POST") == 0)
   for (i = 0; i < content_length; i++) {
    recv(client, &c, 1, 0);
    write(cgi_input[1], &c, 1);
   }
   
  //然后从 cgi_output 管道中读子进程的输出,并发送到客户端去
  while (read(cgi_output[0], &c, 1) > 0)
   send(client, &c, 1, 0);

  //关闭管道
  close(cgi_output[0]);
  close(cgi_input[1]);
  //等待子进程的退出
  waitpid(pid, &status, 0);
 }
}
コード例 #6
0
ファイル: httpd.c プロジェクト: sfeakes/gpioctrl
void serve_led_request(int client, char *query)
{
  char buf[1024];
  int numchars = 1;
  char *token;
  char *split;
  int r = -1;
  int g = -1;
  int b = -1;
  int pattern = 0;
  int option = 0;
  
  buf[0] = 'A'; buf[1] = '\0';
  while ((numchars > 0) && strcmp("\n", buf))  /* read & discard headers */
  {
    numchars = get_line(client, buf, sizeof(buf));
  }
  
  token = strtok(query, "&");
  while( token != NULL ) {
	  split=strchr(token,'=');
	  switch(token[0]) {
  	  case 'r':
	      r = toRGB(split+1);
	    break;
  	  case 'g':
	      g = toRGB(split+1);
	    break;
  	  case 'b':
	      b = toRGB(split+1);
	    break;
      case 'p':
	      pattern = toRGB(split+1);
	    break;
      case 'o':
	      option = toRGB(split+1);
	    break;
	  }
    token = strtok(NULL, "&");
  }
  
  if ( (r == -1 || g == -1 || b == -1) && pattern == 0) {
    logMessage (LOG_DEBUG,"Received BAD LED query:- Red=%d Green=%d, Blue=%d\n",r,g,b);
    cannot_execute(client);
    return;
  } else {
    int index = 0;
    lpd8806worker(&_gpioconfig_.lpd8806cfg[index], (uint8_t*)&pattern, (uint8_t*)&option, (uint8_t*)&r, (uint8_t*)&g, (uint8_t*)&b );
    
    sprintf(buf, "{ \"title\" : \"%s\",\r\n\"name\" : \"%s\",\r\n", _gpioconfig_.name, _gpioconfig_.name);
	  send(client, buf, strlen(buf), 0);
    sprintf(buf, "\"led\" : {\"r\" : %d, \"g\" : %d, \"b\" : %d, \"p\" : %d}\r\n}\r\n", r,g,b,pattern);
    /* This one is more accurate and should be used over the above next debug session */
    /*
    sprintf(buf, "\"led\" : {\"name\" : \"%s\", \"r\" : %d, \"g\" : %d, \"b\" : %d, \"p\" : %d}\r\n}\r\n",
                             _gpioconfig_.lpd8806cfg[index].name,
                             _gpioconfig_.lpd8806cfg[index].red,
                             _gpioconfig_.lpd8806cfg[index].green,
                             _gpioconfig_.lpd8806cfg[index].blue,
                             _gpioconfig_.lpd8806cfg[index].pattern);*/
	  send(client, buf, strlen(buf), 0);
  }
}
コード例 #7
0
ファイル: freebsddelrule.c プロジェクト: EnderUNIX/netUstad
void 
deleterule(nunetwork_socket client, char *path,
	   char *method, char *query_string)
{
	char		buf       [1024];
	int		cgi_output [2];
	int		cgi_input  [2];
	pid_t		pid;
	int		status;

	/* char c; */

	buf[0] = 'A';
	buf[1] = '\0';

	if (strlen(query_string) != 5) {
		unimplemented(client);
		return;
	}
	snprintf(buf, sizeof(buf), "HTTP/1.1 200 OK\r\nContent-Type: text/html\n\n");
	nunetwork_send(client, buf, strlen(buf), 0);

	if (pipe(cgi_output) < 0) {
		cannot_execute(client);
		return;
	}
	if (pipe(cgi_input) < 0) {
		cannot_execute(client);
		return;
	}
	if ((pid = fork()) < 0) {
		cannot_execute(client);
		return;
	}
	if (pid == 0) {		/* child: Delete rule */
		dup2(cgi_output[1], 1);
		dup2(cgi_input[0], 0);
		close(cgi_output[0]);
		close(cgi_input[1]);


		execl(path, path, "delete", query_string, NULL);

		exit(0);
	} else {		/* parent */
		close(cgi_output[1]);
		close(cgi_input[0]);



		snprintf(log_msg_text, sizeof(log_msg_text), "IP: %s %s %s\n", \
			 (char *)inet_ntoa(client_name.sin_addr), \
			 gettext("Delete Rule:"), \
			 (char *)query_string);
		log_msg(logfile, log_msg_text, 1);


                snprintf(buf, sizeof (buf)-1, "<html>\n<head>\n<meta http-equiv='Refresh' content='2; URL=/$%s'>\n\
                                                <meta http-equiv='Pragma' content='no-cache'>\n\
                                                <meta http-equiv=\"Content-Type\" content=\"text/html; charset=%s\">\n\
                                                <title>netUstad</title></head>\n",
                                                server_sid,
                                                (char *) gettext("charset"));
                nunetwork_send(client, buf, strlen(buf), 0);
                snprintf(buf, sizeof (buf)-1, "<link rel='stylesheet' type='text/css' href='/netustad.css'>\n");
                nunetwork_send(client, buf, strlen(buf), 0);

		snprintf(buf, sizeof(buf), \
				"</style>\n<body><center>\n<br><b>%s %s %s<b><br>%s</body></html>", \
				gettext("Rule"), \
				query_string, \
				gettext("is deleted"), \
				gettext("Redirecting to Rule List"));
		nunetwork_send(client, buf, strlen(buf), 0);
		close(cgi_output[0]);
		close(cgi_input[1]);

		waitpid(pid, &status, 0);
	}
}
コード例 #8
0
ファイル: httpd.c プロジェクト: houjian/Tinyhttpd
// 配置环境变量,创建子进程,执行cgi程序
void execute_cgi(int client, const char *path,
                 const char *method, const char *query_string)
{
 char buf[1024];
 int cgi_output[2];
 int cgi_input[2];
 pid_t pid;
 int status;
 int i;
 char c;
 int numchars = 1;
 int content_length = -1;

 buf[0] = 'A'; buf[1] = '\0';
 if (strcasecmp(method, "GET") == 0) // GET
  while ((numchars > 0) && strcmp("\n", buf))  /* read & discard headers */
   numchars = get_line(client, buf, sizeof(buf)); // 只处理了请求首行,忽略后面的请求头
 else    /* POST */
 {
  numchars = get_line(client, buf, sizeof(buf)); // 读取请求头中的header属性
  while ((numchars > 0) && strcmp("\n", buf))
  {
   buf[15] = '\0';
   if (strcasecmp(buf, "Content-Length:") == 0) // Content-Length:后面的数字切出来
    content_length = atoi(&(buf[16]));
   numchars = get_line(client, buf, sizeof(buf));
  }
  if (content_length == -1) { // Content-Length获取失败,该请求有问题
   bad_request(client); // 400
   return;
  }
 }

 sprintf(buf, "HTTP/1.0 200 OK\r\n"); // 响应首行
 send(client, buf, strlen(buf), 0);

 if (pipe(cgi_output) < 0) { // 打开管道
  cannot_execute(client);
  return;
 }
 if (pipe(cgi_input) < 0) { // 打开管道
  cannot_execute(client);
  return;
 }

 if ( (pid = fork()) < 0 ) { // 创建子进程
  cannot_execute(client);
  return;
 }
 if (pid == 0)  /* child: CGI script */
 { // 子进程开始执行
  char meth_env[255];
  char query_env[255];
  char length_env[255];

  dup2(cgi_output[1], 1); // 复制到标准输出
  dup2(cgi_input[0], 0); // 复制到标准输入
  close(cgi_output[0]);
  close(cgi_input[1]); // 关闭不需要的描述符
  
  // 添加几个环境变量
  sprintf(meth_env, "REQUEST_METHOD=%s", method);
  putenv(meth_env);
  if (strcasecmp(method, "GET") == 0) {
   sprintf(query_env, "QUERY_STRING=%s", query_string);
   putenv(query_env);
  }
  else {   /* POST */
   sprintf(length_env, "CONTENT_LENGTH=%d", content_length);
   putenv(length_env);
  }

  // 准备工作完毕,开始执行cgi程序
  execl(path, path, NULL);
  exit(0);
 } else {    /* parent */ // 父进程代码
  close(cgi_output[1]);
  close(cgi_input[0]); // 关闭不需要的描述符

  if (strcasecmp(method, "POST") == 0)
   for (i = 0; i < content_length; i++) {
    recv(client, &c, 1, 0);
    write(cgi_input[1], &c, 1); // 读取剩下的请求头写给子进程的cgi程序
   }
  while (read(cgi_output[0], &c, 1) > 0)
   send(client, &c, 1, 0); // 读取cgi程序的输出发送给客户端

  close(cgi_output[0]);
  close(cgi_input[1]); // 使用完毕,关闭描述符
  waitpid(pid, &status, 0); // 等待子进程退出
 }
}