From 5f5316a034d68f8825a16e7b866c8e8b2b6c6bd8 Mon Sep 17 00:00:00 2001 From: David Phillips Date: Mon, 4 Jun 2018 00:09:02 +1200 Subject: Initial dump of prototype --- alarmd/Makefile | 4 ++ alarmd/alarmd.c | 207 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 211 insertions(+) create mode 100644 alarmd/Makefile create mode 100644 alarmd/alarmd.c (limited to 'alarmd') diff --git a/alarmd/Makefile b/alarmd/Makefile new file mode 100644 index 0000000..b6c56d9 --- /dev/null +++ b/alarmd/Makefile @@ -0,0 +1,4 @@ +LDFLAGS += -L../lib -lalarm -luuid +CFLAGS += -I../inc + +all: alarmd diff --git a/alarmd/alarmd.c b/alarmd/alarmd.c new file mode 100644 index 0000000..239fc3b --- /dev/null +++ b/alarmd/alarmd.c @@ -0,0 +1,207 @@ +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "alarmd_proto.h" + +struct alarm { + UT_hash_handle hh; + char uuid[16]; + char *name; + bool is_raised; +// time_t last_change; +}; + +static struct alarm *alarms; + +int8_t read_string(int sock, char (*buffer)[128]) +{ + uint8_t length = 0; + if (recv(sock, &length, sizeof(uint8_t), 0) < sizeof(uint8_t)) { + return -1; + } + if (length >= 128) { + return -1; + } + if (recv(sock, buffer, length, 0) < 0) { + return -1; + } + (*buffer)[length] = '\0'; + return length; +} + +int main(void) +{ + int sock = 0; + int c_sock = 0; + socklen_t c_addr_l = 0; + struct addrinfo hints, *s_info, *p; + struct sockaddr_storage c_addr; + char buffer[128]; + uint32_t packet_type = 0; + ssize_t nread = 0; + uint32_t count = 0; + + int reuse = 1; + + uuid_t uuid; + char uuid_str[37]; + struct alarm *target = NULL; + + bzero(&hints, sizeof(hints)); + hints.ai_family = AF_UNSPEC; + hints.ai_socktype = SOCK_STREAM; + hints.ai_flags = AI_PASSIVE; + + if (getaddrinfo(NULL, ALARMD_PORT, &hints, &s_info) < 0) { + perror("getaddrinfo"); + return 1; + } + + for (p = s_info; p != NULL; p = p->ai_next) { + if ((sock = socket(p->ai_family, p->ai_socktype, p->ai_protocol)) < 0) { + perror("socket"); + continue; + } + if (setsockopt(sock, SOL_SOCKET, SO_REUSEADDR, &reuse, sizeof(reuse)) < 0) { + perror("setsockopt"); + return 1; + } + if (bind(sock, p->ai_addr, p->ai_addrlen) < 0) { + perror("bind"); + continue; + } + break; + } + + if (!p) { + fprintf(stderr, "No addresses to bind to\n"); + return 1; + } + + freeaddrinfo(s_info); + + if (listen(sock, 128) < 0) { + perror("listen"); + return 1; + } + + c_addr_l = sizeof(c_addr); + if ((c_sock = accept(sock, (struct sockaddr *)&c_addr, &c_addr_l)) < 0) { + perror("accept"); + return 1; + } + + while (1) { + /* read packet type */ + nread = recv(c_sock, &packet_type, sizeof(packet_type), 0); + if (nread < 0) { + perror("read"); + return 1; + } else if (nread < sizeof(packet_type)) { + fprintf(stderr, "Packet type too short\n"); + return 1; + } + packet_type = ntohl(packet_type); + + switch(packet_type) { + case ALARMD_PACKET_TYPE_REGISTER: + if (read_string(c_sock, &buffer) < 0) { + return 1; + } + uuid_generate(uuid); + //uuid_unparse(uuid, uuid_str); + //fprintf(stderr, "Registering alarm %s with uuid %s\n", buffer, uuid_str); + if (send(c_sock, uuid, sizeof(uuid), 0) != sizeof(uuid)) { + perror("send"); + return 1; + } + struct alarm *new_alarm = malloc(sizeof(*new_alarm)); + if (new_alarm == NULL) { + perror("malloc"); + return 1; + } + new_alarm->name = strdup(buffer); + memcpy(new_alarm->uuid, uuid, 16); + new_alarm->is_raised = 0; + HASH_ADD(hh, alarms, uuid, 16, new_alarm); + break; + case ALARMD_PACKET_TYPE_DEREGISTER: + /* FIXME 16 magic */ + if (recv(c_sock, &buffer, 16, 0) < 16) { + return 1; + } + uuid_unparse(buffer, uuid_str); + fprintf(stderr, "Deregistering alarm %s\n", uuid_str); + HASH_FIND(hh, alarms, buffer, 16, target); + if (target != NULL) { + HASH_DEL(alarms, target); + free(target); + } + break; + case ALARMD_PACKET_TYPE_RAISE: + /* FIXME 16 magic */ + if (recv(c_sock, &buffer, 16, 0) < 16) { + return 1; + } + uuid_unparse(buffer, uuid_str); + fprintf(stderr, "Raising alarm %s\n", uuid_str); + HASH_FIND(hh, alarms, buffer, 16, target); + if (target != NULL) { + target->is_raised = 1; + } + break; + case ALARMD_PACKET_TYPE_CLEAR: + /* FIXME 16 magic */ + if (recv(c_sock, &buffer, 16, 0) < 16) { + return 1; + } + uuid_unparse(buffer, uuid_str); + fprintf(stderr, "Clearing alarm %s\n", uuid_str); + HASH_FIND(hh, alarms, buffer, 16, target); + if (target != NULL) { + target->is_raised = 0; + } + break; + case ALARMD_PACKET_TYPE_QUERY: + /* bounds-check HASH_COUNT*/ + count = htonl(HASH_COUNT(alarms)); + uint8_t length = 0; + /* FIXME */ + struct alarm *a = NULL; + struct alarm *tmp = NULL; + HASH_ITER(hh, alarms, a, tmp) { + fprintf(stderr, "DEBUG : [%s] %s\n", a->is_raised ? "RAISE" : "CLEAR" , a->name); + if (send(c_sock, &count, sizeof(count), 0) < sizeof(count)) { + perror("send"); + } + /* FIXME factor out, idiot. also bounds check on strlen */ + length = strlen(a->name); + if (send(c_sock, &length, sizeof(length), 0) < sizeof(length)) { + perror("send"); + } + if (send(c_sock, a->name, strlen(a->name), 0) < strlen(a->name)) { + perror("send"); + } + if (send(c_sock, &(a->is_raised), sizeof(a->is_raised), 0) < sizeof(a->is_raised)) { + perror("send"); + } + fprintf(stderr, "SENT.\n"); + } + break; + default: + fprintf(stderr, "Unknown packet type %d\n", packet_type); + break; + } + } + fprintf(stderr, "Server stopping\n"); + close(sock); +} -- cgit v1.1