From c5ec3a71a3e155dc767164e3b4334eb6998e5c97 Mon Sep 17 00:00:00 2001 From: Michael Jumper Date: Fri, 25 Nov 2011 16:30:17 -0800 Subject: [PATCH] Partial conversion to new logging, API, and naming conventions. --- guacd/src/client.c | 56 +++++++++++++--------- guacd/src/daemon.c | 117 +++++++++++++++++++++++++++++++++++---------- 2 files changed, 127 insertions(+), 46 deletions(-) diff --git a/guacd/src/client.c b/guacd/src/client.c index b4e92122..a5daea85 100644 --- a/guacd/src/client.c +++ b/guacd/src/client.c @@ -36,6 +36,7 @@ * ***** END LICENSE BLOCK ***** */ #include +#include #include #include @@ -45,6 +46,17 @@ #include "client.h" #include "thread.h" +void __guacd_sleep(int millis) { + + struct timespec sleep_period; + + sleep_period.tv_sec = millis / 1000; + sleep_period.tv_nsec = (millis % 1000) * 1000000L; + + nanosleep(&sleep_period, NULL); + +} + void guac_client_stop(guac_client* client) { client->state = STOPPING; } @@ -52,30 +64,30 @@ void guac_client_stop(guac_client* client) { void* __guac_client_output_thread(void* data) { guac_client* client = (guac_client*) data; - GUACIO* io = client->io; + guac_socket* io = client->io; - guac_timestamp last_ping_timestamp = guac_current_timestamp(); + guac_timestamp last_ping_timestamp = guac_protocol_get_timestamp(); /* Guacamole client output loop */ while (client->state == RUNNING) { /* Occasionally ping client with repeat of last sync */ - guac_timestamp timestamp = guac_current_timestamp(); + guac_timestamp timestamp = guac_protocol_get_timestamp(); if (timestamp - last_ping_timestamp > GUAC_SYNC_FREQUENCY) { /* Record time of last synnc */ last_ping_timestamp = timestamp; /* Send sync */ - if (guac_send_sync(io, client->last_sent_timestamp)) { - guac_log_error("Error sending \"sync\" instruction: %s", guac_status_string(guac_error)); + if (guac_protocol_send_sync(io, client->last_sent_timestamp)) { + guac_client_log_error(client, "Error sending \"sync\" instruction: %s", guac_status_string(guac_error)); guac_client_stop(client); return NULL; } /* Flush */ - if (guac_flush(io)) { - guac_log_error("Error flushing output: %s", guac_status_string(guac_error)); + if (guac_socket_flush(io)) { + guac_client_log_error(client, "Error flushing output: %s", guac_status_string(guac_error)); guac_client_stop(client); return NULL; } @@ -91,24 +103,24 @@ void* __guac_client_output_thread(void* data) { int retval = client->handle_messages(client); if (retval) { - guac_log_error("Error handling server messages: %s", guac_status_string(guac_error)); + guac_client_log_error(client, "Error handling server messages: %s", guac_status_string(guac_error)); guac_client_stop(client); return NULL; } /* Sleep as necessary */ - guac_sleep(GUAC_SERVER_MESSAGE_HANDLE_FREQUENCY); + __guacd_sleep(GUAC_SERVER_MESSAGE_HANDLE_FREQUENCY); /* Send sync instruction */ - client->last_sent_timestamp = guac_current_timestamp(); - if (guac_send_sync(io, client->last_sent_timestamp)) { - guac_log_error("Error sending \"sync\" instruction: %s", guac_status_string(guac_error)); + client->last_sent_timestamp = guac_protocol_get_timestamp(); + if (guac_protocol_send_sync(io, client->last_sent_timestamp)) { + guac_client_log_error(client, "Error sending \"sync\" instruction: %s", guac_status_string(guac_error)); guac_client_stop(client); return NULL; } - if (guac_flush(io)) { - guac_log_error("Error flushing output: %s", guac_status_string(guac_error)); + if (guac_socket_flush(io)) { + guac_client_log_error(client, "Error flushing output: %s", guac_status_string(guac_error)); guac_client_stop(client); return NULL; } @@ -117,13 +129,13 @@ void* __guac_client_output_thread(void* data) { /* If sync threshold exceeded, don't spin waiting for resync */ else - guac_sleep(GUAC_SERVER_MESSAGE_HANDLE_FREQUENCY); + __guacd_sleep(GUAC_SERVER_MESSAGE_HANDLE_FREQUENCY); } /* If no message handler, just sleep until next sync ping */ else - guac_sleep(GUAC_SYNC_FREQUENCY); + __guacd_sleep(GUAC_SYNC_FREQUENCY); } /* End of output loop */ @@ -135,32 +147,32 @@ void* __guac_client_output_thread(void* data) { void* __guac_client_input_thread(void* data) { guac_client* client = (guac_client*) data; - GUACIO* io = client->io; + guac_socket* io = client->io; /* Guacamole client input loop */ while (client->state == RUNNING) { /* Read instruction */ guac_instruction* instruction = - guac_read_instruction(io, GUAC_USEC_TIMEOUT); + guac_protocol_read_instruction(io, GUAC_USEC_TIMEOUT); /* Stop on error */ if (instruction == NULL) { - guac_log_error("Error reading instruction: %s", guac_status_string(guac_error)); + guac_client_log_error(client, "Error reading instruction: %s", guac_status_string(guac_error)); guac_client_stop(client); return NULL; } /* Call handler, stop on error */ if (guac_client_handle_instruction(client, instruction) < 0) { - guac_log_error("Error in client \"%s\" instruction handler: %s", instruction->opcode, guac_status_string(guac_error)); - guac_free_instruction(instruction); + guac_client_log_error(client, "Error in client \"%s\" instruction handler: %s", instruction->opcode, guac_status_string(guac_error)); + guac_instruction_free(instruction); guac_client_stop(client); return NULL; } /* Free allocated instruction */ - guac_free_instruction(instruction); + guac_instruction_free(instruction); } diff --git a/guacd/src/daemon.c b/guacd/src/daemon.c index a8abecba..642ac6d8 100644 --- a/guacd/src/daemon.c +++ b/guacd/src/daemon.c @@ -46,10 +46,10 @@ #include #include +#include #include -#include -#include +#include #include "client.h" @@ -63,30 +63,99 @@ typedef struct client_thread_data { void* start_client_thread(void* data) { guac_client* client; + guac_client_plugin* plugin; client_thread_data* thread_data = (client_thread_data*) data; + guac_socket* socket; + guac_instruction* select; + guac_instruction* connect; - guac_log_info("Spawning client"); + /* Open guac_socket */ + socket = guac_socket_open(thread_data->fd); - /* Load and start client */ - client = guac_get_client(thread_data->fd, GUAC_USEC_TIMEOUT); + /* Get protocol from select instruction */ + select = + guac_protocol_expect_instruction(socket, GUAC_USEC_TIMEOUT, "select"); + if (select == NULL) { + /* TODO: LOG */ + guac_socket_close(socket); + free(data); + return NULL; + } + + /* Validate args to select */ + if (select->argc != 1) { + guac_error = GUAC_STATUS_BAD_ARGUMENT; + guac_socket_close(socket); + free(data); + return NULL; + } + + /* Get plugin from protocol in select */ + plugin = guac_client_plugin_open(select->argv[0]); + guac_instruction_free(select); + + if (plugin == NULL) { + /* TODO: LOG ERROR */ + guac_socket_close(socket); + free(data); + return NULL; + } + + /* Send args response */ + if (guac_protocol_send_args(socket, plugin->args)) { + + if (guac_client_plugin_close(plugin)) { + /* TODO: LOG ERROR */ + } + + guac_socket_close(socket); + free(data); + return NULL; + } + + /* Get args from connect instruction */ + connect = + guac_protocol_expect_instruction(socket, GUAC_USEC_TIMEOUT, "connect"); + if (connect == NULL) { + + if (guac_client_plugin_close(plugin)) { + /* TODO: LOG ERROR */ + } + + guac_socket_close(socket); + free(data); + return NULL; + } + + /* Load and init client */ + client = guac_client_plugin_get_client(plugin, socket, + connect->argc, connect->argv); + guac_instruction_free(select); if (client == NULL) { - guac_log_error("Client retrieval failed"); + + if (guac_client_plugin_close(plugin)) { + /* TODO: LOG ERROR */ + } + + guac_socket_close(socket); free(data); return NULL; } + /* Start client threads */ guac_start_client(client); - guac_free_client(client); + + /* Clean up */ + guac_client_free(client); + if (guac_client_plugin_close(plugin)) { + /* TODO: LOG ERROR */ + } /* Close socket */ - if (close(thread_data->fd) < 0) { - guac_log_error("Error closing connection: %s", strerror(errno)); - free(data); - return NULL; - } + guac_socket_close(socket); + close(thread_data->fd); - guac_log_info("Client finished"); free(data); return NULL; @@ -189,21 +258,21 @@ int main(int argc, char* argv[]) { } #else daemon_pid = getpid(); - guac_log_info("fork() not defined at compile time."); - guac_log_info("guacd running in foreground only."); + syslog(LOG_INFO, "fork() not defined at compile time."); + syslog(LOG_INFO, "guacd running in foreground only."); #endif /* Otherwise, this is the daemon */ - guac_log_info("Started, listening on port %i", listen_port); + syslog(LOG_INFO, "Started, listening on port %i", listen_port); /* Ignore SIGPIPE */ if (signal(SIGPIPE, SIG_IGN) == SIG_ERR) { - guac_log_error("Could not set handler for SIGPIPE to ignore. SIGPIPE may cause termination of the daemon."); + syslog(LOG_ERR, "Could not set handler for SIGPIPE to ignore. SIGPIPE may cause termination of the daemon."); } /* Ignore SIGCHLD (force automatic removal of children) */ if (signal(SIGCHLD, SIG_IGN) == SIG_ERR) { - guac_log_error("Could not set handler for SIGCHLD to ignore. Child processes may pile up in the process table."); + syslog(LOG_ERR, "Could not set handler for SIGCHLD to ignore. Child processes may pile up in the process table."); } /* Daemon loop */ @@ -218,7 +287,7 @@ int main(int argc, char* argv[]) { /* Listen for connections */ if (listen(socket_fd, 5) < 0) { - guac_log_error("Could not listen on socket: %s", strerror(errno)); + syslog(LOG_ERR, "Could not listen on socket: %s", strerror(errno)); return 3; } @@ -226,7 +295,7 @@ int main(int argc, char* argv[]) { client_addr_len = sizeof(client_addr); connected_socket_fd = accept(socket_fd, (struct sockaddr*) &client_addr, &client_addr_len); if (connected_socket_fd < 0) { - guac_log_error("Could not accept client connection: %s", strerror(errno)); + syslog(LOG_ERR, "Could not accept client connection: %s", strerror(errno)); return 3; } @@ -255,7 +324,7 @@ int main(int argc, char* argv[]) { /* If error, log */ if (child_pid == -1) - guac_log_error("Error forking child process: %s\n", strerror(errno)); + syslog(LOG_ERR, "Error forking child process: %s\n", strerror(errno)); /* If child, start client, and exit when finished */ else if (child_pid == 0) { @@ -265,13 +334,13 @@ int main(int argc, char* argv[]) { /* If parent, close reference to child's descriptor */ else if (close(connected_socket_fd) < 0) { - guac_log_error("Error closing daemon reference to child descriptor: %s", strerror(errno)); + syslog(LOG_ERR, "Error closing daemon reference to child descriptor: %s", strerror(errno)); } #else if (guac_thread_create(&thread, start_client_thread, (void*) data)) - guac_log_error("Could not create client thread: %s", strerror(errno)); + syslog(LOG_ERR, "Could not create client thread: %s", strerror(errno)); #endif @@ -279,7 +348,7 @@ int main(int argc, char* argv[]) { /* Close socket */ if (close(socket_fd) < 0) { - guac_log_error("Could not close socket: %s", strerror(errno)); + syslog(LOG_ERR, "Could not close socket: %s", strerror(errno)); return 3; }