17
#include <framework/mod/options.h>
19
#define MPFD_BASE OPTION_STRING_GET(base)
20
#define MPFD_BASE_LEN strlen(MPFD_BASE)
23
static char mpfd_g_buf[BUFF_SZ];
30
static char *strstrp(const char *s, const char *h) {
31
char *f = strstr(s, h);
38
static int mpfd_expect(struct parseenv *pe, const char *s) {
40
if (0 != strncmp(pe->pb, s, slen)) {
48
static char *mpfd_store_till(struct parseenv *pe, const char *s, size_t *ssize) {
49
char *found = strstr(pe->pb, s);
61
pe->blen -= found - pb + slen;
62
pe->pb = found + slen;
67
static int mpfd_skip_till(struct parseenv *pe, const char *s) {
68
return !!mpfd_store_till(pe, s, NULL);
71
static int mpfd_parse(struct parseenv *pe, const char *bound, char *fname, size_t fname_len) {
74
int pres = mpfd_expect(pe, "--") &&
75
mpfd_expect(pe, bound) &&
76
mpfd_expect(pe, "\r\nContent-Disposition: form-data; name=\"") &&
77
mpfd_store_till(pe, "\"; filename=\"", NULL) &&
78
(filename = mpfd_store_till(pe, "\"\r\n", &filenamelen)) &&
79
mpfd_skip_till(pe, "\r\n\r\n");
82
*(filename + filenamelen) = '\0';
83
strncat(fname, filename, fname_len);
89
int main(int argc, char *argv[]) {
92
method = getenv("REQUEST_METHOD");
93
if (0 == strcmp("POST", method)) {
95
char *bound = strstrp(getenv("CONTENT_TYPE"), "boundary=");
96
int clen = atoi(getenv("CONTENT_LENGTH"));
102
clen -= strlen("\r\n--") + strlen(bound) + strlen("--\r\n");
105
_pe.blen = read(STDIN_FILENO, mpfd_g_buf, min(BUFF_SZ, clen));
107
strncpy(path, MPFD_BASE, sizeof(path));
109
if (!mpfd_parse(&_pe, bound, path + MPFD_BASE_LEN, sizeof(path) - MPFD_BASE_LEN)) {
110
fprintf(stderr, "parse_error\n");
115
fd = open(path, O_WRONLY | O_CREAT, 0755);
117
fprintf(stderr, "can't open output file %s: %s\n", path, strerror(errno));
122
write(fd, _pe.pb, _pe.blen);
124
int len = read(STDIN_FILENO, mpfd_g_buf, min(BUFF_SZ, clen));
125
write(fd, mpfd_g_buf, len);
133
printf("HTTP/1.1 %d %s\r\n"
134
"Content-Type: %s\r\n"
135
"Connection: close\r\n"
136
"\r\n", httpcode, "OK", "text/plain");