diff --git a/adsbus.c b/adsbus.c index e4271be..f26964c 100644 --- a/adsbus.c +++ b/adsbus.c @@ -4,6 +4,7 @@ #include #include #include +#include #include "common.h" #include "backend.h" @@ -35,6 +36,7 @@ static void print_usage(char *argv[]) { "\t--backend=HOST/PORT\n" "\t--dump=FORMAT\n" "\t--incoming=[HOST/]PORT\n" + "\t--listen=FORMAT=[HOST/]PORT\n" , argv[0]); } @@ -43,24 +45,25 @@ static bool parse_opts(int argc, char *argv[], int epoll_fd) { {"backend", required_argument, 0, 'b'}, {"dump", required_argument, 0, 'd'}, {"incoming", required_argument, 0, 'i'}, + {"listen", required_argument, 0, 'l'}, {"help", no_argument, 0, 'h'}, }; int opt; - char *delim; + char *delim1, *delim2; while ((opt = getopt_long_only(argc, argv, "", long_options, NULL)) != -1) { switch (opt) { case 'b': // It would be really nice if libc had a standard way to split host:port. - delim = strrchr(optarg, '/'); - if (delim == NULL) { + delim1 = strrchr(optarg, '/'); + if (delim1 == NULL) { print_usage(argv); return false; } - *delim = '\0'; - delim++; + *delim1 = '\0'; + delim1++; - backend_new(optarg, delim, epoll_fd); + backend_new(optarg, delim1, epoll_fd); break; case 'd': @@ -74,13 +77,37 @@ static bool parse_opts(int argc, char *argv[], int epoll_fd) { return false; case 'i': - delim = strrchr(optarg, '/'); - if (delim == NULL) { - incoming_new(NULL, optarg, epoll_fd, backend_new_fd); + delim1 = strrchr(optarg, '/'); + if (delim1 == NULL) { + incoming_new(NULL, optarg, epoll_fd, backend_new_fd, NULL); } else { - *delim = '\0'; - delim++; - incoming_new(optarg, delim, epoll_fd, backend_new_fd); + *delim1 = '\0'; + delim1++; + incoming_new(optarg, delim1, epoll_fd, backend_new_fd, NULL); + } + break; + + case 'l': + delim1 = strchr(optarg, '='); + if (delim1 == NULL) { + print_usage(argv); + return false; + } + *delim1 = '\0'; + delim1++; + struct serializer *serializer = client_get_serializer(optarg); + if (!serializer) { + fprintf(stderr, "Unknown format: %s\n", optarg); + return false; + } + + delim2 = strrchr(delim1, '/'); + if (delim2 == NULL) { + incoming_new(NULL, delim1, epoll_fd, client_new_fd, serializer); + } else { + *delim2 = '\0'; + delim2++; + incoming_new(delim1, delim2, epoll_fd, client_new_fd, serializer); } break; @@ -117,6 +144,8 @@ static int loop(int epoll_fd) { } int main(int argc, char *argv[]) { + signal(SIGPIPE, SIG_IGN); + server_init(); hex_init(); airspy_adsb_init(); diff --git a/backend.c b/backend.c index 04c3fba..009b4cb 100644 --- a/backend.c +++ b/backend.c @@ -63,7 +63,7 @@ void backend_new(char *node, char *service, int epoll_fd) { backend_connect(backend, epoll_fd); } -void backend_new_fd(int fd, int epoll_fd) { +void backend_new_fd(int fd, int epoll_fd, void *unused) { struct backend *backend = backend_create(); backend->peer.fd = fd; backend->peer.event_handler = backend_read; diff --git a/backend.h b/backend.h index d6c662f..3cfeadf 100644 --- a/backend.h +++ b/backend.h @@ -22,4 +22,4 @@ struct backend { }; void backend_new(char *, char *, int); -void backend_new_fd(int, int); +void backend_new_fd(int, int, void *); diff --git a/client.c b/client.c index f6a3f90..fa269b0 100644 --- a/client.c +++ b/client.c @@ -77,6 +77,11 @@ void client_add(int fd, struct serializer *serializer) { fprintf(stderr, "C %s (%s): New client\n", client->id, serializer->name); } +void client_new_fd(int fd, int epoll_fd, void *passthrough) { + struct serializer *serializer = (struct serializer *) passthrough; + client_add(fd, serializer); +} + void client_write(struct packet *packet) { for (int i = 0; i < NUM_SERIALIZERS; i++) { struct serializer *serializer = &serializers[i]; diff --git a/client.h b/client.h index 1a3f300..dca6b2a 100644 --- a/client.h +++ b/client.h @@ -5,4 +5,5 @@ struct serializer *client_get_serializer(char *); void client_add(int, struct serializer *); +void client_new_fd(int, int, void *); void client_write(struct packet *); diff --git a/incoming.c b/incoming.c index 8aa788e..8a73d97 100644 --- a/incoming.c +++ b/incoming.c @@ -18,6 +18,7 @@ struct incoming { char *node; char *service; incoming_connection_handler handler; + void *passthrough; }; @@ -44,16 +45,17 @@ static void incoming_handler(struct peer *peer, int epoll_fd) { local_hbuf, local_sbuf, peer_hbuf, peer_sbuf); - incoming->handler(fd, epoll_fd); + incoming->handler(fd, epoll_fd, incoming->passthrough); } -void incoming_new(char *node, char *service, int epoll_fd, incoming_connection_handler handler) { +void incoming_new(char *node, char *service, int epoll_fd, incoming_connection_handler handler, void *passthrough) { struct incoming *incoming = malloc(sizeof(*incoming)); incoming->peer.event_handler = incoming_handler; uuid_gen(incoming->id); incoming->node = node; incoming->service = service; incoming->handler = handler; + incoming->passthrough = passthrough; fprintf(stderr, "I %s: Resolving %s/%s...\n", incoming->id, incoming->node, incoming->service); diff --git a/incoming.h b/incoming.h index 6c7c9e1..eea923f 100644 --- a/incoming.h +++ b/incoming.h @@ -1,4 +1,4 @@ #pragma once -typedef void (*incoming_connection_handler)(int fd, int epoll_fd); -void incoming_new(char *, char *, int, incoming_connection_handler); +typedef void (*incoming_connection_handler)(int fd, int epoll_fd, void *); +void incoming_new(char *, char *, int, incoming_connection_handler, void *);