#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); }