From 4960f9fedcbce3b99fe8bf52e0ae8bac946005fd Mon Sep 17 00:00:00 2001 From: Luke Shumaker Date: Tue, 12 Apr 2016 01:34:28 -0400 Subject: tidy/reorganize --- src/freenect-server.c | 44 +++---- src/multipart-replace-http-server.c | 242 +++++++++++------------------------- src/multipart-replace.c | 1 - src/util.c | 133 +++++++++++++++++++- src/util.h | 9 +- 5 files changed, 227 insertions(+), 202 deletions(-) diff --git a/src/freenect-server.c b/src/freenect-server.c index 94f307c..f6c2016 100644 --- a/src/freenect-server.c +++ b/src/freenect-server.c @@ -39,6 +39,8 @@ #include "util.h" void stop(int sig); +int exitcode = 0; +bool running = true; #define threaderror(stat, errnum, ...) do { \ error(0, errnum, __VA_ARGS__); \ exitcode = stat; \ @@ -66,16 +68,11 @@ struct mpjpg_encoder { unsigned long jpeg_len; }; -int exitcode = 0; -bool running = true; -FILE *depth_stream = NULL; -FILE *video_stream = NULL; -FILE *accel_stream = NULL; -freenect_context *ctx = NULL; -freenect_device *dev = NULL; +/* MPJPEG encoding */ + struct mpjpg_encoder depth_encoder; struct mpjpg_encoder video_encoder; - + void mpjpg_init(struct mpjpg_encoder *e) { e->jpeg_encoder.err = jpeg_std_error(&e->jpeg_encoder_err); jpeg_create_compress(&e->jpeg_encoder); @@ -119,6 +116,12 @@ void write_imageframe(const char *name, FILE *stream, struct mpjpg_encoder *e, J stdioerror(stream, name); } +/* Stream handlers */ + +FILE *depth_stream = NULL; +FILE *video_stream = NULL; +FILE *accel_stream = NULL; + void handle_accel(freenect_device *dev UNUSED, freenect_raw_tilt_state* data) { double x, y, z, angle; freenect_get_mks_accel(data, &x, &y, &z); @@ -183,6 +186,12 @@ void handle_video(freenect_device *dev, void *rgb, uint32_t timestamp UNUSED) { write_imageframe("video.mjpg", video_stream, &video_encoder, rgb); } +/* Main program lifecycle */ + +freenect_context *ctx = NULL; +freenect_device *dev = NULL; +void cleanup(void); + void stop(int sig) { if (sig != 0) log("Caught %d", sig); @@ -190,29 +199,10 @@ void stop(int sig) { running = false; } -FILE *xfopen(const char *path, const char *mode) { - FILE *stream = fopen(path, mode); - if (stream == NULL) - error(EXIT_FAILURE, errno, "fopen: %s", path); - return stream; -} - -FILE *xfdopen(const char *path, const char *mode) { - int fd = get_fd(path); - if (fd < 0) - error(EXIT_FAILURE, -fd, "get_fd: %s", path); - FILE *stream = fdopen(fd, mode); - if (stream == NULL) - error(EXIT_FAILURE, errno, "fdopen: %s (%d)", path, fd); - return stream; -} - void usage() { printf("Usage: %s [-h] [-v video.mjpg|-V video_fd] [-d depth.mjpg|-D depth_fd] [-a accel.mjson|-A accel_fd]\n", program_invocation_name); } -void cleanup(void); - int main(int argc, char *argv[]) { int res = 0; 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 /* atexit */ #include /* for EXIT_FAILURE */ #include -#include -#include /* for open */ -#include #include #include @@ -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); +} diff --git a/src/multipart-replace.c b/src/multipart-replace.c index 658d634..8ce4f9e 100644 --- a/src/multipart-replace.c +++ b/src/multipart-replace.c @@ -15,7 +15,6 @@ * You should have received a copy of the GNU General Public License * along with this program. If not, see . */ - #include #include #include diff --git a/src/util.c b/src/util.c index 46e6842..2ebeb4e 100644 --- a/src/util.c +++ b/src/util.c @@ -15,11 +15,15 @@ * You should have received a copy of the GNU General Public License * along with this program. If not, see . */ - #include /* for isdigit */ -#include -#include #include +#include +#include /* for {get,free}addrinfo() */ +#include +#include +#include /* for open */ +#include +#include /* for unlink */ #include "util.h" @@ -86,3 +90,126 @@ int get_fd(const char *addr) { } return sock; } + +FILE *xfopen(const char *path, const char *mode) { + FILE *stream = fopen(path, mode); + if (stream == NULL) + error(EXIT_FAILURE, errno, "fopen: %s", path); + return stream; +} + +FILE *xfdopen(const char *path, const char *mode) { + int fd = get_fd(path); + if (fd < 0) + error(EXIT_FAILURE, -fd, "get_fd: %s", path); + FILE *stream = fdopen(fd, mode); + if (stream == NULL) + error(EXIT_FAILURE, errno, "fdopen: %s (%d)", path, fd); + return stream; +} + +/* 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; + + freeaddrinfo(ai_addr); + return sock; + } else { + errno = EINVAL; + return -EAI_SYSTEM; + } +} diff --git a/src/util.h b/src/util.h index 96b3293..88842ac 100644 --- a/src/util.h +++ b/src/util.h @@ -19,8 +19,9 @@ #pragma once #include /* for sig_atomic_t */ -#include /* for memset(3) */ #include +#include /* for FILE* */ +#include /* for memset(3) */ #define UNUSED __attribute__((__unused__)) #define ZERO(x) memset(&(x), 0, sizeof(x)) @@ -35,3 +36,9 @@ void *xrealloc(void *ptr, size_t size); bool is_numeric(const char *str); int get_fd(const char *addr); + +FILE *xfopen(const char *path, const char *mode); +FILE *xfdopen(const char *path, const char *mode); + + +int sockstream_listen(const char *type, const char *addr); -- cgit v1.2.3