#include <sys/stat.h>
#include <sys/socket.h>
+#include "../../include/macros.h"
+#include "../../include/manifest.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;
"/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);
/* 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);
}
}
-static void init(void)
+static void socket_init(void)
{
gen_socket_filename();
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,
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; \
+ 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
daemon(DONT_CHDIR, DONT_CLOSE_PIPES);
}
+#define READ_SOCKET {\
+ 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;
+ /* lookup_job(buf); */
+}
+
+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);
+
+ close(asfd);
+}
+
static void run(void)
{
/* loop: */
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);
}
}
{
header();
init();
+ run_jobs();
daemonize();
run();
cleanup();