X-Git-Url: https://git.hcoop.net/tlb/tomd.git/blobdiff_plain/bd11173e828b0cfe14551e782b61d4ccc0bf1e64..1110e851faa51e1cbd22be8a921f283ddb97ff77:/src/tomd/main.c diff --git a/src/tomd/main.c b/src/tomd/main.c index 1b97524..cfbb8b9 100644 --- a/src/tomd/main.c +++ b/src/tomd/main.c @@ -24,11 +24,16 @@ #include #include #include +#include + +#include "../../include/macros.h" +#include "../../include/manifest.h" +#include "../../include/job.h" static void header(void) { - printf("[tomd] Tom's Daemon, Copyright (C) 2018 Thomas Balzer\n"); - printf("[tomd] GPL v3 or later license.\n"); + tomd_p("Tom's Daemon, Copyright (C) 2018 Thomas Balzer"); + tomd_p("GPL v3 or later license."); } static int sfd; @@ -46,7 +51,7 @@ static void gen_socket_filename(void) "/run/user/%d/tomd/socket", this_user_id); - printf("[tomd] making dir '%s'\n", socket_dirname); + tomd_p("making dir '%s'", socket_dirname); /* lazy way */ char buf[100]; sprintf(buf, "mkdir -p %s", socket_dirname); @@ -56,10 +61,10 @@ static void gen_socket_filename(void) /* exit(EXIT_FAILURE); */ /* } */ - printf("[tomd] removing file '%s'\n", socket_filename); + tomd_p("removing file '%s'", socket_filename); if(unlink(socket_filename) != 0){ if(errno == ENOENT){ - printf("[tomd] socket file doesn't exist\n"); + tomd_p("socket file doesn't exist"); }else{ perror("[tomd] socket unlink"); exit(EXIT_FAILURE); @@ -67,10 +72,10 @@ static void gen_socket_filename(void) } } -static void init(void) +static void socket_init(void) { gen_socket_filename(); - + /* listen on socket, respond to requests. */ /* perform all registered 'tick' operations */ sfd = @@ -92,7 +97,7 @@ static void init(void) sizeof(name.sun_path)); size = SUN_LEN(&name); - printf("[tomd] attempting to bind to '%s'\n", + tomd_p("attempting to bind to '%s'", socket_filename); if(bind(sfd, (struct sockaddr *) &name, @@ -101,10 +106,28 @@ static void init(void) exit(EXIT_FAILURE); } - printf("[tomd] initialized tomd socket connections\n"); + tomd_p("initialized tomd socket connections"); } -/* These defines are here to improve the local readability */ +static void init(void) +{ + socket_init(); + load_jobs(); +} + +#define SEND_ACK { \ + int size; \ + char ACK[4];\ + ACK[0] = 'A';\ + ACK[1] = 'C';\ + ACK[2] = 'K';\ + ACK[3] = '\0';\ +if(size = write(asfd, ACK, sizeof(ACK)) != sizeof(ACK)) { \ + tomd_p("didn't send as much as we though (%d != %d)",\ + size, sizeof(ACK)); \ + } \ + } + #define CHDIR 0 #define DONT_CHDIR 1 #define CLOSE_PIPES 0 @@ -120,6 +143,142 @@ static void daemonize(void) daemon(DONT_CHDIR, DONT_CLOSE_PIPES); } +#define READ_SOCKET {\ + memset(buf, 0, sizeof(buf)); \ + int size = read(asfd, buf, 100); \ + buf[size] = '\0'; \ + } + +static int validate_sender(int asfd, char *buf) +{ + READ_SOCKET; + if(strcmp(buf, "client:tomc") == 0){ + SEND_ACK; + return 0; + } + tomd_p("received '%s' instead of client:tomc", buf); + return -1; +} + +enum requests { KILL, STATUS, STOP, START, UNKNOWN}; +#define X(a, b) { a, b } +static struct { + char *str; + enum requests request; +} request_types[] = + { + X("kill", KILL), + X("status", STATUS), + X("start", START), + X("stop", STOP), + X(NULL, -1) + }; +#undef X + +static void handle_request(int asfd, char *buf) +{ + READ_SOCKET; + enum requests request = UNKNOWN; + int i = 0; + while(1){ + if(request_types[i].str == NULL){ + break; + } + + tomd_p("loop [%d]: comparing '%s' to '%s'", + i, buf, request_types[i].str); + if(strcmp(buf, request_types[i].str) == 0){ + request = request_types[i].request; + break; + } + + i++; + } + + if(request == UNKNOWN){ + tomd_p("unknown request type!"); + return; + } + + SEND_ACK; + READ_SOCKET; + // cross reference given name against known services + tomd_p("looking up '%s'", buf); + SEND_ACK; + struct job *jp = lookup_job(buf); + #define DOUBLE_DUTY(...) { \ + char tmp[100]; \ + tomd_p(__VA_ARGS__); \ + sprintf(tmp, __VA_ARGS__); \ + int tmplen = strlen(tmp); \ + tomd_p("__debug__:'%s'", tmp);\ + write(asfd, tmp, tmplen); \ + } + if(jp == NULL){ + DOUBLE_DUTY("lookup of '%s' failed.\n", buf); + } else { + + tomd_p("-----"); + DOUBLE_DUTY("found job record for '%s'\n", jp->name); + + if(request == STATUS){ + if(jp->pid != -1){ + int status = 0; + int n_pid = waitpid(jp->pid, &status, WNOHANG); + if(n_pid < 0){ + perror("[tomd] waitpid"); + }else if(n_pid == 0){ + DOUBLE_DUTY("waitpid == 0, check manual\n"); + }else{ + DOUBLE_DUTY("running: %s\n", + !WIFEXITED(status) ? "yes" + : "no"); + + if(WIFEXITED(status)){ + DOUBLE_DUTY(" status: %d\n", WEXITSTATUS(status)); + jp->pid = -1; + jp->last_status = status; + } + } + }else{ + DOUBLE_DUTY("running: no\n"); + DOUBLE_DUTY(" status: %d\n", jp->last_status); + } + + if(jp->pid != -1){ + DOUBLE_DUTY(" pid: %d\n", jp->pid); + } + }else{ + DOUBLE_DUTY("don't know how to handle that request.\n"); + } + } + tomd_p("-----"); + tomd_p("sending ack."); + SEND_ACK; + tomd_p("ack is sent."); + get_ack: + READ_SOCKET; + if(strcmp(buf, "ACK") != 0) + goto get_ack; + tomd_p("ack was ack'd."); +} + +static void handle_connection(int asfd) +{ + char buf[100] = {}; + + if(validate_sender(asfd, buf) != 0){ + tomd_p("invalid sender."); + return; + } + + tomd_p("validated client"); + handle_request(asfd, buf); + + shutdown(asfd, SHUT_WR); + close(asfd); +} + static void run(void) { /* loop: */ @@ -134,30 +293,26 @@ static void run(void) exit(EXIT_FAILURE); } + int i = 0; for(;;){ struct sockaddr addr; - socklen_t size; + /* sometimes gives EINVAL if not initialized. */ + socklen_t size = sizeof(addr); + tomd_p("accept loop [%d]", i++); + errno = 0; int accept_sfd = accept(sfd, &addr, /* requester info */ &size); /* len of requester info */ if(accept_sfd < 0){ + if(errno == EINVAL){ + tomd_p("EINVAL"); + } perror("[tomd] accept socket"); exit(EXIT_FAILURE); } - /* int getsockname(accept_sfd, */ - /* addr, */ - /* size); */ - - printf("[tomd] accepted socket connection from '%s'\n", - ((struct sockaddr_un *) &addr)->sun_path); - - char accept_buf[100] = {}; - - read(accept_sfd, accept_buf, 100); - printf("[tomd] got message '%s'\n, accept_buf"); - close(accept_sfd); + handle_connection(accept_sfd); } } @@ -172,9 +327,10 @@ int main(int argc, char **argv) { header(); init(); - daemonize(); + run_jobs(); + /* daemonize(); */ run(); cleanup(); - + return EXIT_SUCCESS; }