summaryrefslogtreecommitdiff
path: root/src/multipart-replace-http-server.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/multipart-replace-http-server.c')
-rw-r--r--src/multipart-replace-http-server.c242
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);
+}