diff --git a/daemon/Makefile.am b/daemon/Makefile.am index b29e8d0..06a24eb 100644 --- a/daemon/Makefile.am +++ b/daemon/Makefile.am @@ -1,9 +1,9 @@ -include_HEADERS = $(top_srcdir)/yasnd.h +include_HEADERS = $(top_srcdir)/yasnd.h yasnd-sock.h yasnd_LDADD = ${libconfuse_LIBS} yasnd_LDADD += $(top_srcdir)/lib/libyasnd.la sbin_PROGRAMS = yasnd -yasnd_SOURCES = yasnd.c yasnd-ipc.c +yasnd_SOURCES = yasnd.c yasnd-ipc.c yasnd-sock.c yasnd_CPPFLAGS = -I$(top_srcdir) distclean-local: diff --git a/daemon/yasnd-sock.c b/daemon/yasnd-sock.c new file mode 100644 index 0000000..c1b2e14 --- /dev/null +++ b/daemon/yasnd-sock.c @@ -0,0 +1,149 @@ +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include + +#include "yasnd-log.h" +#include "yasnd-lpt.h" + +const char sock_path[]="/var/run/yasnd.sock"; +pthread_t server_thread_handle; // server socket thread handle +int socket_fd; // server socket descriptor + +#define STATUS_OK (void*)0 +#define STATUS_ERROR (void*)1 + +void* connection_handler(void* param) +{ + // Get connection descriptor + int connection_fd=*(int*)param; + + // Buffer for client command and command's actual length + char buffer[256]; + int nbytes; + + // Token for string splitting + char* token; + + // Status of command parsing (default is OK) + void* thread_status = STATUS_OK; + + while ( (nbytes = read(connection_fd, buffer, 256)) != -1 ) + { + buffer[nbytes] = 0; + + token = strtok(buffer, " "); + if (token == NULL) + { + // empty input from client + thread_status = STATUS_ERROR; + break; + } + + // Exit function + if (strncmp(token, "exit", 4) == 0) + { + // just break loop and thus close client connection + break; + } + // Reset function + if (strncmp(token, "reset", 5) == 0) + { + // Get parameter for reset call and convert it to long + long value = strtol(strtok(NULL, " "), (char **) NULL, 10); + // Call reset_pin function + reset_pin((int)value); + // continue waiting client commands + continue; + } + } + + // Close client connection descriptor + close(connection_fd); + + // Exit client thread and return apropriate status + pthread_exit(thread_status); +} + +void* server_socket(void* param) +{ + struct sockaddr_un address; + int connection_fd; + socklen_t address_length; + + pthread_t child_handle; // connection thread handle + + socket_fd = socket(PF_UNIX, SOCK_STREAM, 0); + if(socket_fd < 0) + { + log_event("socket creation failed"); + return (void*)1; + } + + // Remove old socket file + unlink(sock_path); + + // start with a clean address structure + memset(&address, 0, sizeof(struct sockaddr_un)); + + address.sun_family = AF_UNIX; + snprintf(address.sun_path, UNIX_PATH_MAX, sock_path); + + // Set umask value for new socket file + mode_t old_umask = umask(077); + + // Create(bind) socket + if(bind(socket_fd, + (struct sockaddr *) &address, + sizeof(struct sockaddr_un)) != 0) + { + log_event("bind() call failed"); + return (void*)1; + } + + // Return previous umask value + umask(old_umask); + + if(listen(socket_fd, 5) != 0) + { + log_event("listen() call failed"); + return (void*)1; + } + + while((connection_fd = accept(socket_fd, (struct sockaddr *) &address, &address_length)) > -1) + { + if(pthread_create(&child_handle,NULL,connection_handler,&connection_fd) != 0) + { + log_event("Client connection thread creation failed"); + } + else + pthread_detach(child_handle); + } + + return (void*)0; +} + +int sock_init() +{ + if(pthread_create(&server_thread_handle,NULL,server_socket,NULL) != 0) + { + log_event("Server socket thread creation failed"); + } +} + +void sock_close() +{ + // Terminate server socket handling thread + pthread_cancel(server_thread_handle); + // Close server socket + close(socket_fd); + // Remove unneeded socket file + unlink(sock_path); +} diff --git a/daemon/yasnd-sock.h b/daemon/yasnd-sock.h new file mode 100644 index 0000000..cb189df --- /dev/null +++ b/daemon/yasnd-sock.h @@ -0,0 +1,8 @@ +#ifndef YASND_SOCK_H +#define YASND_SOCK_H + +// External functions +extern int sock_init(); +extern void sock_close(); + +#endif diff --git a/daemon/yasnd.c b/daemon/yasnd.c index a1d0d30..726daba 100644 --- a/daemon/yasnd.c +++ b/daemon/yasnd.c @@ -9,6 +9,7 @@ #include "yasnd-gammu.h" #include "yasnd-log.h" #include "yasnd-lpt.h" +#include "yasnd-sock.h" cfg_t *cfg; // pointer to configuration structure char pidfile[]="/var/run/yasnd.pid"; // pidfile path @@ -154,6 +155,8 @@ void init() gammu_init(); // initialize LPT control circuit lpt_init(); + // initialize server socket + sock_init(); } void check_host(int num,host_decl* host) @@ -285,6 +288,8 @@ void signal_handler(int signum) lpt_lock(); // close log decriptor log_close(); + // close server socket + sock_close(); // exit(EXIT_SUCCESS); }