summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorYorhel <git@yorhel.nl>2015-12-14 10:55:05 +0100
committerYorhel <git@yorhel.nl>2015-12-14 10:55:05 +0100
commit11070a0f4153def1616d52d38c9f60355ec4412d (patch)
treee2f42062339d2bd73fda3e2de4c6aa37da43872d
parent7ca0d8c2cadf407ea36c8924e14a01d4e86bf55a (diff)
Add cli parsing + rename input to front(end) + misc cleanup
-rw-r--r--Makefile.am7
-rwxr-xr-xinit-from-git.sh16
-rw-r--r--src/app.c145
-rw-r--r--src/app.h22
-rw-r--r--src/fcgy.h4
-rw-r--r--src/main.c66
-rw-r--r--src/main.h59
7 files changed, 241 insertions, 78 deletions
diff --git a/Makefile.am b/Makefile.am
index 76e1866..615ff0c 100644
--- a/Makefile.am
+++ b/Makefile.am
@@ -2,7 +2,7 @@ EXTRA_DIST=
noinst_LIBRARIES=
noinst_PROGRAMS=
MOSTLYCLEANFILES=
-AM_CPPFLAGS=-I$(srcdir)/src -Isrc -I$(srcdir)/deps/klib -I$(srcdir)/deps/ylib
+AM_CPPFLAGS=-I$(srcdir)/src -Isrc -I$(srcdir)/deps/ylib
# deps/ stuff
noinst_LIBRARIES+=libdeps.a
@@ -28,11 +28,8 @@ EXTRA_DIST+=\
deps/ev/ev_vars.h\
deps/ev/ev_wrap.h
-# klib
-EXTRA_DIST+=deps/klib/khash.h
-
# ylib
-EXTRA_DIST+=deps/ylib/yuri.h deps/ylib/vec.h
+EXTRA_DIST+=deps/ylib/vec.h
# fcgy
bin_PROGRAMS=fcgy
diff --git a/init-from-git.sh b/init-from-git.sh
index fe41e59..b736e1a 100755
--- a/init-from-git.sh
+++ b/init-from-git.sh
@@ -24,21 +24,10 @@ ev() {
ylib() {
U=http://g.blicky.net/ylib.git/plain
- UG=http://g.blicky.net/globster.git/plain/src/util
rm -rf ylib
mkdir -p ylib\
- && wget -q $U/yopt.h -O ylib/yopt.h\
- && wget -q $U/yuri.c -O ylib/yuri.c\
- && wget -q $U/yuri.h -O ylib/yuri.h\
- && wget -q $UG/vec.h -O ylib/vec.h
-}
-
-
-klib() {
- U=https://raw.github.com/attractivechaos/klib/master
- rm -rf klib
- mkdir -p klib\
- && wget -q $U/khash.h -O klib/khash.h
+ && wget -q $U/vec.h -O ylib/vec.h\
+ && wget -q $U/yopt.h -O ylib/yopt.h
}
@@ -48,4 +37,3 @@ cd deps
aclean
ev
ylib
-klib
diff --git a/src/app.c b/src/app.c
index 8d3088b..a48823e 100644
--- a/src/app.c
+++ b/src/app.c
@@ -23,66 +23,127 @@
#include "fcgy.h"
-fcgy_app *app_create() {
- fcgy_app *app = calloc(1, sizeof(fcgy_app));
- return app;
+static void front_accept_cb(EV_P_ ev_io *w, int revents) {
+ fprintf(stderr, "HI!\n");
+
}
-void app_add_input_unix(fcgy_app *app, const char *addr) {
- fcgy_input in = {0};
- in.type = FCGY_INPUT_UNIX;
- in.addr = strdup(addr);
- in.fd = -1;
- vec_insert_order(app->inputs, app->inputs.n, in);
+static void front_add(fcgy_app *app, fcgy_front_type t, const char *addr, uint16_t port) {
+ fcgy_front *f = vec_appendp(app->fronts);;
+ memset(f, 0, sizeof(fcgy_front));
+ f->type = t;
+ f->port = port;
+ f->fd = -1;
+ f->addr = strdup(addr);
+ ev_init(f->listener, front_accept_cb);
+ f->listener->data = app;
}
-static int app_bind_unix(fcgy_input *in) {
- struct sockaddr_un addr;
- addr.sun_family = AF_UNIX;
- int r = snprintf(addr.sun_path, sizeof(addr.sun_path), "%s", in->addr);
- /* TODO: Better error reporting */
- if(r < 0 || r >= (int)sizeof(addr.sun_path))
- return -1;
+/* TODO: Better error reporting */
+static int front_bind(fcgy_front *f) {
+ switch(f->type) {
+
+ case FCGY_FRONT_UNIX: {
+ struct sockaddr_un addr;
+ addr.sun_family = AF_UNIX;
+ int r = snprintf(addr.sun_path, sizeof(addr.sun_path), "%s", f->addr);
+ if(r < 0 || r >= (int)sizeof(addr.sun_path))
+ return -1;
- in->fd = util_serversock(AF_UNIX, &addr, sizeof(addr), FCGY_CLOEXEC|FCGY_NONBLOCK);
- if(in->fd < 0)
- return -1;
+ f->fd = util_serversock(AF_UNIX, &addr, sizeof(addr), FCGY_CLOEXEC|FCGY_NONBLOCK);
+ if(f->fd < 0)
+ return -1;
+ break;
+ }
+
+ case FCGY_FRONT_TCP:
+ case FCGY_FRONT_STDIO:
+ break; /* TODO */
+ }
return 0;
}
+static void front_start(fcgy_front *f) {
+ switch(f->type) {
+ case FCGY_FRONT_UNIX:
+ case FCGY_FRONT_TCP:
+ ev_io_set(f->listener, f->fd, EV_READ);
+ ev_io_start(EV_DEFAULT_UC_ f->listener);
+ break;
+
+ case FCGY_FRONT_STDIO:
+ /* TODO: Create connection struct */
+ break;
+ }
+}
+
+
+static void front_stop(fcgy_front *f) {
+ if(f->fd < 0)
+ return;
+
+ switch(f->type) {
+ case FCGY_FRONT_UNIX:
+ unlink(f->addr);
+ case FCGY_FRONT_TCP:
+ ev_io_stop(EV_DEFAULT_UC_ f->listener);
+ break;
+
+ case FCGY_FRONT_STDIO:
+ /* TODO: Nothing? */
+ break;
+ }
+
+ close(f->fd);
+ f->fd = -1;
+}
+
+
+fcgy_app *app_create() {
+ fcgy_app *app = calloc(1, sizeof(fcgy_app));
+ return app;
+}
+
+
+/* Returns 0 on success, -1 on error.
+ * Writes a string to *err on error. */
+int app_config(fcgy_app *app, fcgy_config_name name, const char *val, char *err, size_t errlen) {
+ switch(name) {
+ case FCGY_CONFIG_APP_UNIX:
+ front_add(app, FCGY_FRONT_UNIX, val, 0);
+ return 0;
+ default:
+ assert(0 && "app_config() called on invalid option");
+ }
+ return -1;
+}
+
+
int app_bind(fcgy_app *app) {
size_t i;
- for(i=0; i<app->inputs.n; i++) {
- int n = -1;
- switch(app->inputs.a[i].type) {
- case FCGY_INPUT_UNIX:
- n = app_bind_unix(app->inputs.a+i);
- break;
- default:
- ;/* TODO: other types */
- }
- if(n < 0)
- return n;
- }
- return 0;
+ int n = 0;
+ for(i=0; n == 0 && i<app->fronts.n; i++)
+ n = front_bind(app->fronts.a+i);
+ return n;
+}
+
+
+void app_run(fcgy_app *app) {
+ size_t i;
+ for(i=0; i<app->fronts.n; i++)
+ front_start(app->fronts.a+i);
}
void app_destroy(fcgy_app *app) {
size_t i;
- for(i=0; i<app->inputs.n; i++) {
- fcgy_input *in = app->inputs.a+i;
- if(in->fd < 0)
- continue;
- close(in->fd);
- in->fd = -1;
- if(in->type == FCGY_INPUT_UNIX)
- unlink(in->addr);
- }
- free(app->inputs.a);
+ for(i=0; i<app->fronts.n; i++)
+ front_stop(app->fronts.a+i);
+
+ free(app->fronts.a);
free(app);
}
diff --git a/src/app.h b/src/app.h
index 8f7ad94..cae85bc 100644
--- a/src/app.h
+++ b/src/app.h
@@ -23,30 +23,34 @@
#ifndef FCGY_APP_H
#define FCGY_APP_H
+
typedef enum {
- FCGY_INPUT_STDIO,
- FCGY_INPUT_UNIX,
- FCGY_INPUT_TCP
-} fcgy_input_type;
+ FCGY_FRONT_STDIO,
+ FCGY_FRONT_UNIX,
+ FCGY_FRONT_TCP
+} fcgy_front_type;
typedef struct {
- fcgy_input_type type;
- char *addr;
+ fcgy_front_type type;
uint16_t port;
int fd;
-} fcgy_input;
+ char *addr;
+ ev_io listener[1];
+} fcgy_front;
typedef struct {
- vec_t(fcgy_input) inputs;
+ vec_t(fcgy_front) fronts; /* Frontend configuration (and listen sockets) */
+ vec_t(int) fconn; /* Frontend connections */
/* TODO: uid / gid */
/* TODO: backends & options */
} fcgy_app;
fcgy_app *app_create();
-void app_add_input_unix(fcgy_app *, const char *);
+int app_config(fcgy_app *, fcgy_config_name, const char *, char *, size_t);
int app_bind(fcgy_app *);
+void app_run(fcgy_app *);
void app_destroy(fcgy_app *);
#endif
diff --git a/src/fcgy.h b/src/fcgy.h
index ddcc745..dd9ad8d 100644
--- a/src/fcgy.h
+++ b/src/fcgy.h
@@ -48,15 +48,13 @@
#include <netinet/in.h>
#include <ev.h>
-
-#include <khash.h>
-#include <yuri.h>
#include <vec.h>
/* version.c */
extern char *fcgy_version;
#include "util.h"
+#include "main.h"
#include "app.h"
#endif
diff --git a/src/main.c b/src/main.c
index f5dd5f3..71c2d83 100644
--- a/src/main.c
+++ b/src/main.c
@@ -21,16 +21,72 @@
*/
#include <fcgy.h>
+#include <yopt.h>
+
+static fcgy_app *app; /* TODO: Needs to be a global array of apps */
+
+
+static const yopt_opt_t cli_options[] = {
+#define X(N, n) { FCGY_CONFIG_GLOBAL_##N, 1, "--"n },
+ FCGY_CONFIG_GLOBAL
+#undef X
+#define X(N, n) { FCGY_CONFIG_APP_##N, 1, "--"n },
+ FCGY_CONFIG_APP
+#undef X
+#define X(N, n, a) { FCGY_CONFIG_CLI_##N, a, n },
+ FCGY_CONFIG_CLI
+#undef X
+ {0,0,NULL}
+};
+
+
+static int parse_args(int argc, char **argv) {
+ int v;
+ char *val;
+ yopt_t opts;
+ yopt_init(&opts, argc, argv, cli_options);
+
+ while((v = yopt_next(&opts, &val)) >= 0) {
+ if(FCGY_CONFIG_IS_APP(v)) {
+ if(app_config(app, v, val, opts.errbuf, sizeof(opts.errbuf)) < 0) {
+ fprintf(stderr, "fcgy: %s\n", opts.errbuf);
+ return -1;
+ }
+ continue;
+ }
+ /* TODO: Handle global options */
+ switch(v) {
+ case FCGY_CONFIG_CLI_VERSION:
+ printf("fcgy %s\n", fcgy_version);
+ exit(0);
+ case FCGY_CONFIG_CLI_HELP:
+ /* Very helpful */
+ printf("fcgy [options]\n");
+ exit(0);
+ default:
+ assert(0 && "Unhandled option");
+ }
+ }
+
+ if(v == -2) {
+ fprintf(stderr, "fcgy: %s\n", val);
+ return -1;
+ }
+
+ /* TODO: Some sanity checking (e.g. do we have an app front and backend?) */
+ return 0;
+}
int main(int argc, char **argv) {
- printf("Version: %s\n", fcgy_version);
- ev_default_loop(0);
+ app = app_create();
+ if(parse_args(argc, argv) < 0)
+ return 1;
- fcgy_app *app = app_create();
- app_add_input_unix(app, "/tmp/fcgy-test");
+ ev_default_loop(0);
app_bind(app);
- getchar();
+ app_run(app);
+ ev_run(EV_DEFAULT_UC_ 0);
app_destroy(app);
return 0;
}
diff --git a/src/main.h b/src/main.h
new file mode 100644
index 0000000..c3b313e
--- /dev/null
+++ b/src/main.h
@@ -0,0 +1,59 @@
+/* Copyright (c) 2015-2016 Yoran Heling
+
+ Permission is hereby granted, free of charge, to any person obtaining
+ a copy of this software and associated documentation files (the
+ "Software"), to deal in the Software without restriction, including
+ without limitation the rights to use, copy, modify, merge, publish,
+ distribute, sublicense, and/or sell copies of the Software, and to
+ permit persons to whom the Software is furnished to do so, subject to
+ the following conditions:
+
+ The above copyright notice and this permission notice shall be included
+ in all copies or substantial portions of the Software.
+
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
+ IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
+ CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
+ TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
+ SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+*/
+
+#ifndef FCGY_MAIN_H
+#define FCGY_MAIN_H
+
+/* Global options.
+ * X(NAME, "name") */
+#define FCGY_CONFIG_GLOBAL
+
+/* Application options.
+ * X(NAME, "name") */
+#define FCGY_CONFIG_APP \
+ X(UNIX, "unix")
+
+/* Command-line options.
+ * X(NAME, "yopt-style-name", needarg) */
+#define FCGY_CONFIG_CLI \
+ X(VERSION, "-V,--version", 0)\
+ X(HELP, "-h,--help", 0)
+
+typedef enum {
+ FCGY_CONFIG_GLOBAL_MARKER = 0x001000,
+#define X(N, n) FCGY_CONFIG_GLOBAL_##N,
+ FCGY_CONFIG_GLOBAL
+#undef X
+ FCGY_CONFIG_APP_MARKER = 0x010000,
+#define X(N, n) FCGY_CONFIG_APP_##N,
+ FCGY_CONFIG_APP
+#undef X
+ FCGY_CONFIG_CLI_MARKER = 0x100000,
+#define X(N, n, a) FCGY_CONFIG_CLI_##N,
+ FCGY_CONFIG_CLI
+#undef X
+ FCGY_CONFIG_END_MARKER
+} fcgy_config_name;
+
+#define FCGY_CONFIG_IS_APP(n) ((int)(n) & (int)FCGY_CONFIG_APP_MARKER)
+
+#endif