diff options
Diffstat (limited to 'src/multipart-replace-http-server.c')
-rw-r--r-- | src/multipart-replace-http-server.c | 242 |
1 files changed, 72 insertions, 170 deletions
diff --git a/src/multipart-replace-http-server.c b/src/multipart-replace-http-server.c index faec814..a35f194 100644 --- a/src/multipart-replace-http-server.c +++ b/src/multipart-replace-http-server.c @@ -24,9 +24,6 @@ #include <stdlib.h> /* atexit */ #include <stdlib.h> /* for EXIT_FAILURE */ #include <string.h> -#include <sys/socket.h> -#include <sys/stat.h> /* for open */ -#include <sys/un.h> #include <unistd.h> #include <systemd/sd-daemon.h> @@ -35,6 +32,20 @@ #include "wg.h" #include "multipart-replace.h" +void stop(int sig); +int exitcode = 0; +bool running = true; +struct wg wg; +#define threaderror(stat, errnum, ...) do { \ + error(0, errnum, __VA_ARGS__); \ + exitcode = stat; \ + stop(0); \ + } while(0) + +/* File management */ + +void start_multipart_replace_reader(struct multipart_replace_stream *s, int fd, const char *filename, const char *boundary); + struct httpfile { char name[256]; struct multipart_replace_stream *stream; @@ -43,6 +54,38 @@ struct httpfile { size_t filec = 0; struct httpfile *filev = NULL; +void file_add(const char *filename) { + struct multipart_replace_stream *stream = xrealloc(NULL, sizeof(struct multipart_replace_stream)); + init_multipart_replace_stream(stream); + int fd = open(filename, O_RDONLY); + if (fd < 0) { + threaderror(EXIT_FAILURE, errno, "opening file: %s", filename); + return; + } + filev = xrealloc(filev, (++filec)*sizeof(*filev)); + char *shortname = strrchr(filename, '/'); + if (shortname == NULL) { + shortname = alloca(strlen(filename)+2); + shortname[0] = '/'; + strcpy(&shortname[1], filename); + } + strncpy(filev[filec-1].name, shortname, sizeof(filev[filec-1].name)); + log("added file #%zd: %s", filec-1, filev[filec-1].name); + filev[filec-1].stream = stream; + start_multipart_replace_reader(stream, fd, filev[filec-1].name, "ffserver" /* FIXME */); +} + +struct multipart_replace_stream *file_get(const char *filename) { + for (size_t i = 0; i < filec; i++) { + if (strncmp(filename, filev[i].name, sizeof(filev[i].name)) == 0) { + return filev[i].stream; + } + } + return NULL; +} + +/* Reader */ + struct reader_thread_args { struct multipart_replace_stream *stream; int fd; @@ -50,25 +93,6 @@ struct reader_thread_args { char *boundary; }; -int exitcode = 0; -bool running = true; -int sock; -struct wg wg; - -void stop(int sig) { - if (sig != 0) - log("Caught %d", sig); - sd_notify(0, "STOPPING=1"); - running = false; - close(sock); -} - -#define threaderror(stat, errnum, ...) do { \ - error(0, errnum, __VA_ARGS__); \ - exitcode = stat; \ - stop(0); \ - } while(0) - void *reader_thread(void *args_anon) { struct reader_thread_args *args = args_anon; @@ -98,35 +122,8 @@ void start_multipart_replace_reader(struct multipart_replace_stream *s, int fd, pthread_create(&thread, NULL, reader_thread, args); } -void file_add(const char *filename) { - struct multipart_replace_stream *stream = xrealloc(NULL, sizeof(struct multipart_replace_stream)); - init_multipart_replace_stream(stream); - int fd = open(filename, O_RDONLY); - if (fd < 0) { - threaderror(EXIT_FAILURE, errno, "opening file: %s", filename); - return; - } - filev = xrealloc(filev, (++filec)*sizeof(*filev)); - char *shortname = strrchr(filename, '/'); - if (shortname == NULL) { - shortname = alloca(strlen(filename)+2); - shortname[0] = '/'; - strcpy(&shortname[1], filename); - } - strncpy(filev[filec-1].name, shortname, sizeof(filev[filec-1].name)); - log("added file #%zd: %s", filec-1, filev[filec-1].name); - filev[filec-1].stream = stream; - start_multipart_replace_reader(stream, fd, filev[filec-1].name, "ffserver" /* FIXME */); -} - -struct multipart_replace_stream *file_get(const char *filename) { - for (size_t i = 0; i < filec; i++) { - if (strncmp(filename, filev[i].name, sizeof(filev[i].name)) == 0) { - return filev[i].stream; - } - } - return NULL; -} + +/* Writer */ void connection_handler(int fd) { FILE *netstream = fdopen(fd, "r"); @@ -212,112 +209,27 @@ void *connection_thread(void *arg_anon) { wg_sub(&wg); return NULL; } + +/* Main program lifecycle */ +pthread_t main_thread; +void cleanup(void); +int sock; -/* same error codes values as -getaddrinfo(); */ -int sockstream_listen(const char *type, const char *addr) { - int sock; - if (strcmp(type, "fd") == 0) { - sock = get_fd(addr); - if (sock < 0) { - errno = -sock; - return -EAI_SYSTEM; - } - /* make sure it's a socket */ - struct stat st; - if (fstat(sock, &st) < 0) - return -EAI_SYSTEM; - if (!S_ISSOCK(st.st_mode)) { - errno = ENOTSOCK; - return -EAI_SYSTEM; - } - /* make sure the socket is a stream */ - int fd_socktype = 0; - socklen_t l = sizeof(fd_socktype); - if (getsockopt(sock, SOL_SOCKET, SO_TYPE, &fd_socktype, &l) < 0) - return -EAI_SYSTEM; - if (l != sizeof(fd_socktype)) { - errno = EINVAL; - return -EAI_SYSTEM; - } - if (fd_socktype != SOCK_STREAM) { - errno = ENOSTR; - return -EAI_SYSTEM; - } - /* make sure the socket is listening */ - int fd_listening = 0; - l = sizeof(fd_listening); - if (getsockopt(sock, SOL_SOCKET, SO_ACCEPTCONN, &fd_listening, &l) < 0) - return -EAI_SYSTEM; - if (l != sizeof(fd_listening)) { - errno = EINVAL; - return -EAI_SYSTEM; - } - if (!fd_listening) - listen(sock, SOMAXCONN); - /* return the socket */ - return sock; - } else if (strcmp(type, "unix") == 0) { - struct sockaddr_un un_addr = { 0 }; - if (strlen(addr)+1 > sizeof(un_addr.sun_path)) { - errno = ENAMETOOLONG; - return -EAI_SYSTEM; - } - un_addr.sun_family = AF_UNIX; - strcpy(un_addr.sun_path, addr); - int sock = socket(AF_UNIX, SOCK_STREAM, 0); - if (sock < 0) - return -EAI_SYSTEM; - unlink(addr); - if (bind(sock, (struct sockaddr *)&un_addr, sizeof(un_addr)) < 0) - return -EAI_SYSTEM; - if (listen(sock, SOMAXCONN) < 0) - return -EAI_SYSTEM; - return sock; - } else if (strcmp(type, "tcp4") == 0 || strcmp(type, "tcp6") == 0) { - struct addrinfo *ai_addr = NULL; - struct addrinfo ai_hints = { 0 }; - - char *host = strdupa(addr); - char *col = strrchr(host, ':'); - if (col == NULL) { - errno = EINVAL; - return -EAI_SYSTEM; - } - char *port = &col[1]; - *col = '\0'; - if (host[0] == '\0') - host = NULL; - - ai_hints.ai_family = (strcmp(type, "tcp6") == 0) ? AF_INET6 : AF_INET; - ai_hints.ai_socktype = SOCK_STREAM; - ai_hints.ai_flags = AI_PASSIVE; - - int r = getaddrinfo(host, port, &ai_hints, &ai_addr); - if (r < 0) - return r; - if (r > 0) - return -r; - - int sock = socket(ai_addr->ai_family, ai_addr->ai_socktype, ai_addr->ai_protocol); - if (sock < 0) - return -EAI_SYSTEM; - - int yes = 1; - setsockopt(sock, SOL_SOCKET, SO_REUSEADDR, &yes, sizeof(yes)); - - if (bind(sock, ai_addr->ai_addr, ai_addr->ai_addrlen) < 0) - return -EAI_SYSTEM; - - if (listen(sock, SOMAXCONN) < 0) - return -EAI_SYSTEM; +void progname() { + char threadname[16]; + if (pthread_self() != main_thread && pthread_getname_np(pthread_self(), threadname, sizeof(threadname)) == 0) + fprintf(stderr, "%s:%s: ", program_invocation_name, threadname); + else + fprintf(stderr, "%s: ", program_invocation_name); +} - freeaddrinfo(ai_addr); - return sock; - } else { - errno = EINVAL; - return -EAI_SYSTEM; - } +void stop(int sig) { + if (sig != 0) + log("Caught %d", sig); + sd_notify(0, "STOPPING=1"); + running = false; + close(sock); } void usage() { @@ -334,22 +246,6 @@ void usage() { "the FILENAMEs should be pipes or sockets.\n"); } -void cleanup() { - fflush(stderr); - if (sd_booted() > 0) sleep(5); /* work around systemd bug dropping log messages */ - _exit(exitcode); -} - -pthread_t main_thread; - -void progname() { - char threadname[16]; - if (pthread_self() != main_thread && pthread_getname_np(pthread_self(), threadname, sizeof(threadname)) == 0) - fprintf(stderr, "%s:%s: ", program_invocation_name, threadname); - else - fprintf(stderr, "%s: ", program_invocation_name); -} - int main(int argc, char *argv[]) { if (argc >=2 && strcmp(argv[1], "-h") == 0) { usage(); @@ -397,3 +293,9 @@ int main(int argc, char *argv[]) { free(filev); return 0; } + +void cleanup() { + fflush(stderr); + if (sd_booted() > 0) sleep(5); /* work around systemd bug dropping log messages */ + _exit(exitcode); +} |