htpipe/htpipe.c

80 lines
2 KiB
C

#include "minimal_multipart_parser.h"
#include <libowfat/buffer.h>
#include <libowfat/errmsg.h>
#include <unistd.h>
#undef die
#undef diesys
#define die(n,...) \
do { \
carp(__VA_ARGS__,(char*)0); \
dieservererr(n,__VA_ARGS__,(char*)0); \
} while(0)
#define diesys(n,...) \
do { \
carpsys(__VA_ARGS__,(char*)0); \
dieservererr(n,__VA_ARGS__,(char*)0); \
} while(0)
static buffer topipe;
static void dieservererr(int n,char *args,...)
{
char *header = "HTTP/1.0 500 Internal Server Error\r\n"
"Connection: close\r\n"
"\r\n";
msg(header,args);
exit(n);
}
static void dienodata(void)
{
char *header = "HTTP/1.0 400 Bad Request\r\n"
"Connection: close\r\n"
"\r\n";
msg(header,"HTTP multipart/form-data field expected.");
exit(100);
}
static void run(void) {
MinimalMultipartParserContext ctx = {0};
unsigned int ev;
int r;
char c;
for (;;) {
r = buffer_getc(buffer_0,&c);
if (r==0) break;
if (r<0) diesys(111,"read stdin");
ev = minimal_multipart_parser_process(&ctx,c);
if (ev==MultipartParserEvent_DataBufferAvailable) {
if (buffer_put(&topipe,
minimal_multipart_parser_get_data_buffer(&ctx),
minimal_multipart_parser_get_data_size(&ctx))<0
) diesys(111,"write to pipe");
} else if (ev==MultipartParserEvent_DataStreamCompleted)
break;
}
if (!minimal_multipart_parser_is_file_received(&ctx))
dienodata();
if (buffer_flush(&topipe)<0)
diesys(111,"flush pipe write");
}
int main(int argc,char **argv)
{
char buf[4096];
int pipefds[2];
argc--; argv++;
(void)argc;
if (pipe(pipefds)<0) diesys(111,"pipe");
buffer_init_write(&topipe,pipefds[1],buf,sizeof buf);
run();
if (dup2(pipefds[0],0)<0) diesys(111,"dup2");
execvp(*argv,argv);
diesys(111,"exec ",*argv);
}