From 11070a0f4153def1616d52d38c9f60355ec4412d Mon Sep 17 00:00:00 2001 From: Yorhel Date: Mon, 14 Dec 2015 10:55:05 +0100 Subject: Add cli parsing + rename input to front(end) + misc cleanup --- Makefile.am | 7 +-- init-from-git.sh | 16 +----- src/app.c | 145 +++++++++++++++++++++++++++++++++++++++---------------- src/app.h | 22 +++++---- src/fcgy.h | 4 +- src/main.c | 66 +++++++++++++++++++++++-- src/main.h | 59 ++++++++++++++++++++++ 7 files changed, 241 insertions(+), 78 deletions(-) create mode 100644 src/main.h 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; iinputs.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 && ifronts.n; i++) + n = front_bind(app->fronts.a+i); + return n; +} + + +void app_run(fcgy_app *app) { + size_t i; + for(i=0; ifronts.n; i++) + front_start(app->fronts.a+i); } void app_destroy(fcgy_app *app) { size_t i; - for(i=0; iinputs.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; ifronts.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 #include - -#include -#include #include /* 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 +#include + +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 -- cgit v1.2.3