9eb7b485e5fa698b64da260326ffdd44044ad6ce
11 parse_command(const char *cmdline
)
13 const char *p
= cmdline
, *s
;
14 char **argv
= NULL
, *out
;
19 while (isspace(*cmdline
))
22 for (p
= cmdline
, s
= p
, esc
= false; p
; p
++) {
26 else if (*p
== '\\' && p
[1] != 0) {
29 else if (isspace(*p
) || *p
== 0) {
32 arglen
+= sizeof(char *) + (p
- s
) + 1;
45 argv
= calloc(1, arglen
+ sizeof(char *));
50 out
= (char *)argv
+ sizeof(char *) * (argnum
+ 1);
53 for (p
= cmdline
, s
= p
, esc
= false, argnum
= 0; p
; p
++) {
58 else if (*p
== '\\' && p
[1] != 0) {
61 else if (isspace(*p
) || *p
== 0) {
84 postdecode(char **fields
, int n_fields
)
88 int i
, field
, found
= 0;
89 ssize_t len
= 0, rlen
= 0, content_length
= 0;
91 var
= getenv("CONTENT_TYPE");
93 if (!var
|| strncmp(var
, "application/x-www-form-urlencoded", 33))
96 var
= getenv("CONTENT_LENGTH");
101 content_length
= strtol(var
, &p
, 10);
103 if (p
== var
|| content_length
<= 0 || content_length
>= POST_LIMIT
)
106 postbuf
= calloc(1, content_length
+ 1);
111 for (len
= 0; len
< content_length
; )
113 rlen
= read(0, postbuf
+ len
, content_length
- len
);
121 if (len
< content_length
)
127 for (p
= postbuf
, i
= 0; i
<= len
; i
++)
129 if (postbuf
[i
] == '=')
133 for (field
= 0; field
< (n_fields
* 2); field
+= 2)
135 if (!strcmp(p
, fields
[field
]))
137 fields
[field
+ 1] = postbuf
+ i
+ 1;
142 else if (postbuf
[i
] == '&' || postbuf
[i
] == '\0')
146 if (found
>= n_fields
)
153 for (field
= 0; field
< (n_fields
* 2); field
+= 2)
155 if (!urldecode(fields
[field
+ 1]))
166 datadup(const void *in
, size_t len
)
168 char *out
= malloc(len
+ 1);
173 memcpy(out
, in
, len
);
181 canonicalize_path(const char *path
, size_t len
)
183 char *canonpath
, *cp
;
186 if (path
== NULL
|| *path
== '\0')
189 canonpath
= datadup(path
, len
);
191 if (canonpath
== NULL
)
195 for (cp
= canonpath
, p
= path
, e
= path
+ len
; p
< e
; ) {
199 /* skip repeating / */
200 if ((p
+ 1 < e
) && (p
[1] == '/')) {
206 if ((p
+ 1 < e
) && (p
[1] == '.')) {
208 if ((p
+ 2 >= e
) || (p
[2] == '/')) {
213 /* collapse /x/../ */
214 if ((p
+ 2 < e
) && (p
[2] == '.') && ((p
+ 3 >= e
) || (p
[3] == '/'))) {
215 while ((cp
> canonpath
) && (*--cp
!= '/'))
227 /* remove trailing slash if not root / */
228 if ((cp
> canonpath
+ 1) && (cp
[-1] == '/'))
230 else if (cp
== canonpath
)
247 (((x) <= '9') ? ((x) - '0') : \
248 (((x) <= 'F') ? ((x) - 'A' + 10) : \
251 for (c
= p
= buf
; *p
; c
++)
255 if (!isxdigit(*(p
+ 1)) || !isxdigit(*(p
+ 2)))
258 *c
= (char)(16 * hex(*(p
+ 1)) + hex(*(p
+ 2)));