From 7feb4362405845993783a4e90fe942dddca0ee7a Mon Sep 17 00:00:00 2001 From: Sergey Popov Date: Fri, 23 Mar 2012 14:06:39 +0400 Subject: [PATCH 1/5] socket interconnection skeleton --- daemon/Makefile.am | 4 ++-- daemon/yasnd-sock.c | 7 +++++++ daemon/yasnd-sock.h | 8 ++++++++ daemon/yasnd.c | 5 +++++ 4 files changed, 22 insertions(+), 2 deletions(-) create mode 100644 daemon/yasnd-sock.c create mode 100644 daemon/yasnd-sock.h 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..c518336 --- /dev/null +++ b/daemon/yasnd-sock.c @@ -0,0 +1,7 @@ +int sock_init() +{ +} + +void sock_close() +{ +} 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); } From f5d1239d28cf6847c7663883028ad5e4306ddbcd Mon Sep 17 00:00:00 2001 From: Sergey Popov Date: Fri, 6 Apr 2012 16:05:31 +0400 Subject: [PATCH 2/5] quick and dirty draft implementation of server-side UNIX socket handler --- daemon/yasnd-sock.c | 96 +++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 96 insertions(+) diff --git a/daemon/yasnd-sock.c b/daemon/yasnd-sock.c index c518336..c7b6ceb 100644 --- a/daemon/yasnd-sock.c +++ b/daemon/yasnd-sock.c @@ -1,7 +1,103 @@ +#include +#include +#include +#include +#include +#include +#include +#include + +#include "yasnd-log.h" + +const char sock_path[]="./demo_socket"; +pthread_t server_thread_handle; // server socket thread handle +int socket_fd; // server socket descriptor + +void* connection_handler(void* param) +{ + // Get connection descriptor + int connection_fd=*(int*)param; + + int nbytes; + char buffer[256]; + char tmpbuf[512]; + + nbytes = read(connection_fd, buffer, 256); + buffer[nbytes] = 0; + + sprintf(tmpbuf,"MESSAGE FROM CLIENT: %s\n", buffer); + log_event(tmpbuf); + + close(connection_fd); + + pthread_exit(0); +} + +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); + + if(bind(socket_fd, + (struct sockaddr *) &address, + sizeof(struct sockaddr_un)) != 0) + { + log_event("bind() call failed"); + return (void*)1; + } + + 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); } From aa32c753899e9a37e7418764c40e9d0d03a4fe41 Mon Sep 17 00:00:00 2001 From: Sergey Popov Date: Sat, 28 Apr 2012 13:27:04 +0400 Subject: [PATCH 3/5] set correct default socket path --- daemon/yasnd-sock.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/daemon/yasnd-sock.c b/daemon/yasnd-sock.c index c7b6ceb..d81655e 100644 --- a/daemon/yasnd-sock.c +++ b/daemon/yasnd-sock.c @@ -9,7 +9,7 @@ #include "yasnd-log.h" -const char sock_path[]="./demo_socket"; +const char sock_path[]="/var/run/yasnd.sock"; pthread_t server_thread_handle; // server socket thread handle int socket_fd; // server socket descriptor From 17274b11b92b673c4e4934597e0139714d0eb8ae Mon Sep 17 00:00:00 2001 From: Sergey Popov Date: Sat, 28 Apr 2012 13:33:21 +0400 Subject: [PATCH 4/5] modify socket file permissions by changing umask --- daemon/yasnd-sock.c | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/daemon/yasnd-sock.c b/daemon/yasnd-sock.c index d81655e..d810876 100644 --- a/daemon/yasnd-sock.c +++ b/daemon/yasnd-sock.c @@ -1,5 +1,6 @@ #include #include +#include #include #include #include @@ -57,6 +58,10 @@ void* server_socket(void* param) 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) @@ -65,6 +70,9 @@ void* server_socket(void* param) return (void*)1; } + // Return previous umask value + umask(old_umask); + if(listen(socket_fd, 5) != 0) { log_event("listen() call failed"); From 5686c50bdf10b9d9ec5e442dfdbe019ea61d8437 Mon Sep 17 00:00:00 2001 From: Sergey Popov Date: Sun, 13 May 2012 19:25:52 +0400 Subject: [PATCH 5/5] parsing exit and reset commands, rewrite client connection handler and return apropriate status from it --- daemon/yasnd-sock.c | 52 +++++++++++++++++++++++++++++++++++++++------ 1 file changed, 45 insertions(+), 7 deletions(-) diff --git a/daemon/yasnd-sock.c b/daemon/yasnd-sock.c index d810876..c1b2e14 100644 --- a/daemon/yasnd-sock.c +++ b/daemon/yasnd-sock.c @@ -8,30 +8,68 @@ #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; - int nbytes; + // Buffer for client command and command's actual length char buffer[256]; - char tmpbuf[512]; + int nbytes; - nbytes = read(connection_fd, buffer, 256); - buffer[nbytes] = 0; + // Token for string splitting + char* token; - sprintf(tmpbuf,"MESSAGE FROM CLIENT: %s\n", buffer); - log_event(tmpbuf); + // 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); - pthread_exit(0); + // Exit client thread and return apropriate status + pthread_exit(thread_status); } void* server_socket(void* param)