summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorLuke Shumaker <lukeshu@sbcglobal.net>2016-04-12 01:34:28 -0400
committerLuke Shumaker <lukeshu@sbcglobal.net>2016-04-12 01:34:28 -0400
commit4960f9fedcbce3b99fe8bf52e0ae8bac946005fd (patch)
treeed2e2e4c0c3aa4d15c876b85baf71a01434cc6c6
parent3f91935c7fdfbdd4ec299c1af3204aac0b990039 (diff)
tidy/reorganize
-rw-r--r--src/freenect-server.c44
-rw-r--r--src/multipart-replace-http-server.c242
-rw-r--r--src/multipart-replace.c1
-rw-r--r--src/util.c133
-rw-r--r--src/util.h9
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 <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);
+}
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 <http://www.gnu.org/licenses/>.
*/
-
#include <errno.h>
#include <error.h>
#include <stdio.h>
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 <http://www.gnu.org/licenses/>.
*/
-
#include <ctype.h> /* for isdigit */
-#include <stdlib.h>
-#include <error.h>
#include <errno.h>
+#include <error.h>
+#include <netdb.h> /* for {get,free}addrinfo() */
+#include <stdlib.h>
+#include <sys/socket.h>
+#include <sys/stat.h> /* for open */
+#include <sys/un.h>
+#include <unistd.h> /* 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 <signal.h> /* for sig_atomic_t */
-#include <string.h> /* for memset(3) */
#include <stdbool.h>
+#include <stdio.h> /* for FILE* */
+#include <string.h> /* 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);