-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathcgi.c
126 lines (106 loc) · 2.42 KB
/
cgi.c
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
#include <stdio.h>
#include <string.h>
#include <unistd.h>
#include <stdlib.h>
#include "cgi.h"
#include "log.h"
CGI_envp *new_cgi_envp ()
{
CGI_envp *cgi_envp ;
if ((cgi_envp = (CGI_envp *) malloc (sizeof(CGI_envp))) == NULL)
return NULL ;
cgi_envp->capacity = 8 ;
cgi_envp->size = 0 ;
if ((cgi_envp->envp = (char **) malloc (cgi_envp->capacity * sizeof(char **))) == NULL)
return NULL ;
cgi_envp->envp[0] = NULL ;
return cgi_envp ;
}
void free_cgi_envp (CGI_envp *cgi_envp)
{
int i ;
for (i = 0; i < cgi_envp->size; i++)
free (cgi_envp->envp[i]) ;
free (cgi_envp->envp) ;
free (cgi_envp) ;
}
int fill_cgi_envp (CGI_envp *cgi_envp, const char *name, const char *value)
{
if (cgi_envp->size + 1 == cgi_envp->capacity)
{
cgi_envp->capacity <<= 1 ;
if ((cgi_envp->envp = (char **) realloc (cgi_envp->envp, cgi_envp->capacity * sizeof(char **))) == NULL)
{
LOG_ERROR ("Can not alloc envp for cgi.") ;
return -1 ;
}
}
if ((cgi_envp->envp[cgi_envp->size] = (char *) malloc (strlen(name) + strlen(value) + 2)) == NULL)
{
LOG_ERROR ("Can not alloc envp for cgi.") ;
return -1 ;
}
strcpy (cgi_envp->envp[cgi_envp->size], name) ;
strcat (cgi_envp->envp[cgi_envp->size], "=") ;
strcat (cgi_envp->envp[cgi_envp->size], value) ;
cgi_envp->size++ ;
cgi_envp->envp[cgi_envp->size] = NULL ;
return 0 ;
}
char *get_cgi_query (char *req_path)
{
char *qmark = strstr (req_path, "?") ;
if (qmark)
return qmark + 1 ;
return NULL ;
}
CGI *new_cgi (char *argv[], CGI_envp *cgi_envp)
{
CGI *cgi ;
int stdin_pipe[2] ;
int stdout_pipe[2] ;
if (argv[0] == NULL)
{
LOG_ERROR ("No CGI filename in the argument.");
return NULL ;
}
if (pipe(stdin_pipe) < 0)
{
LOG_ERROR ("Error piping for stdin.");
return NULL ;
}
if (pipe(stdout_pipe) < 0)
{
LOG_ERROR ("Error piping for stdout.");
return NULL ;
}
switch (fork())
{
case -1:
LOG_ERROR ("Faild to fork.") ;
return NULL ;
case 0:
close(stdout_pipe[0]) ;
close(stdin_pipe[1]) ;
dup2 (stdin_pipe[0], STDIN_FILENO) ;
dup2 (stdout_pipe[1], STDOUT_FILENO) ;
if (execve(argv[0], argv, cgi_envp->envp))
{
LOG_ERROR ("Error execute CGI [%s].", argv[0]);
return NULL ;
}
default:
close(stdout_pipe[1]) ;
close(stdin_pipe[0]) ;
cgi = (CGI *) malloc (sizeof(CGI)) ;
cgi->in = stdout_pipe[0] ;
cgi->out = stdin_pipe[1] ;
}
return cgi ;
}
void free_cgi (CGI *cgi)
{
close (cgi->in) ;
close (cgi->out) ;
free (cgi) ;
}