From 6081ce6fa4a8d9ffcb1ca93c811e6f0f4caeea6e Mon Sep 17 00:00:00 2001 From: Michael Jumper Date: Sun, 9 Nov 2014 22:59:53 -0800 Subject: [PATCH] GUAC-911: Greatly increase available values for guac_error. Remove use of guac_error by non-library code. --- src/guacd/client.c | 2 +- src/guacd/socket-ssl.c | 4 +- src/libguac/client.c | 2 +- src/libguac/error.c | 131 +++++++++++++++++++++++----- src/libguac/guacamole/error-types.h | 112 +++++++++++++++++++++--- src/libguac/instruction.c | 6 +- src/libguac/plugin.c | 8 +- src/libguac/protocol.c | 8 +- src/libguac/socket-fd.c | 2 +- src/protocols/rdp/guac_handlers.c | 9 +- src/terminal/terminal.c | 3 +- 11 files changed, 226 insertions(+), 61 deletions(-) diff --git a/src/guacd/client.c b/src/guacd/client.c index a5d4457c..394fb8cf 100644 --- a/src/guacd/client.c +++ b/src/guacd/client.c @@ -135,7 +135,7 @@ void* __guacd_client_input_thread(void* data) { /* Stop on error */ if (instruction == NULL) { - if (guac_error == GUAC_STATUS_INPUT_TIMEOUT) + if (guac_error == GUAC_STATUS_TIMEOUT) guac_client_abort(client, GUAC_PROTOCOL_STATUS_CLIENT_TIMEOUT, "Client is not responding."); else { diff --git a/src/guacd/socket-ssl.c b/src/guacd/socket-ssl.c index 103e0af8..adbbd94a 100644 --- a/src/guacd/socket-ssl.c +++ b/src/guacd/socket-ssl.c @@ -99,7 +99,7 @@ static int __guac_socket_ssl_select_handler(guac_socket* socket, int usec_timeou } if (retval == 0) { - guac_error = GUAC_STATUS_INPUT_TIMEOUT; + guac_error = GUAC_STATUS_TIMEOUT; guac_error_message = "Timeout while waiting for data on secure socket"; } @@ -131,7 +131,7 @@ guac_socket* guac_socket_open_secure(SSL_CTX* context, int fd) { /* Accept SSL connection, handle errors */ if (SSL_accept(data->ssl) <= 0) { - guac_error = GUAC_STATUS_BAD_STATE; + guac_error = GUAC_STATUS_INTERNAL_ERROR; guac_error_message = "SSL accept failed"; free(data); diff --git a/src/libguac/client.c b/src/libguac/client.c index 2e50d06d..521ac49d 100644 --- a/src/libguac/client.c +++ b/src/libguac/client.c @@ -169,7 +169,7 @@ static char* __guac_generate_connection_id() { if (uuid_export(uuid, UUID_FMT_STR, &identifier, &identifier_length) != UUID_RC_OK) { free(buffer); uuid_destroy(uuid); - guac_error = GUAC_STATUS_BAD_STATE; + guac_error = GUAC_STATUS_INTERNAL_ERROR; guac_error_message = "Conversion of UUID to connection ID failed"; return NULL; } diff --git a/src/libguac/error.c b/src/libguac/error.c index d32b4260..b6a93775 100644 --- a/src/libguac/error.c +++ b/src/libguac/error.c @@ -32,16 +32,34 @@ #include #endif -/* Error strings */ +/* + * Error strings + */ -const char* __GUAC_STATUS_SUCCESS_STR = "Success"; -const char* __GUAC_STATUS_NO_MEMORY_STR = "Insufficient memory"; -const char* __GUAC_STATUS_NO_INPUT_STR = "End of input stream"; -const char* __GUAC_STATUS_INPUT_TIMEOUT_STR = "Read timeout"; -const char* __GUAC_STATUS_OUTPUT_ERROR_STR = "Output error"; -const char* __GUAC_STATUS_BAD_ARGUMENT_STR = "Invalid argument"; -const char* __GUAC_STATUS_BAD_STATE_STR = "Illegal state"; -const char* __GUAC_STATUS_INVALID_STATUS_STR = "UNKNOWN STATUS CODE"; +const char* __GUAC_STATUS_SUCCESS_STR = "Success"; +const char* __GUAC_STATUS_NO_MEMORY_STR = "Insufficient memory"; +const char* __GUAC_STATUS_CLOSED_STR = "Closed"; +const char* __GUAC_STATUS_TIMEOUT_STR = "Timed out"; +const char* __GUAC_STATUS_IO_ERROR_STR = "Input/output error"; +const char* __GUAC_STATUS_INVALID_ARGUMENT_STR = "Invalid argument"; +const char* __GUAC_STATUS_INTERNAL_ERROR_STR = "Internal error"; +const char* __GUAC_STATUS_UNKNOWN_STATUS_STR = "UNKNOWN STATUS CODE"; +const char* __GUAC_STATUS_NO_SPACE_STR = "Insufficient space"; +const char* __GUAC_STATUS_INPUT_TOO_LARGE_STR = "Input too large"; +const char* __GUAC_STATUS_RESULT_TOO_LARGE_STR = "Result too large"; +const char* __GUAC_STATUS_PERMISSION_DENIED_STR = "Permission denied"; +const char* __GUAC_STATUS_BUSY_STR = "Resource busy"; +const char* __GUAC_STATUS_NOT_AVAILABLE_STR = "Resource not available"; +const char* __GUAC_STATUS_NOT_SUPPORTED_STR = "Not supported"; +const char* __GUAC_STATUS_NOT_INPLEMENTED_STR = "Not implemented"; +const char* __GUAC_STATUS_TRY_AGAIN_STR = "Temporary failure"; +const char* __GUAC_STATUS_PROTOCOL_ERROR_STR = "Protocol violation"; +const char* __GUAC_STATUS_NOT_FOUND_STR = "Not found"; +const char* __GUAC_STATUS_CANCELED_STR = "Canceled"; +const char* __GUAC_STATUS_OUT_OF_RANGE_STR = "Value out of range"; +const char* __GUAC_STATUS_REFUSED_STR = "Operation refused"; +const char* __GUAC_STATUS_TOO_MANY_STR = "Insufficient resources"; +const char* __GUAC_STATUS_WOULD_BLOCK_STR = "Operation would block"; const char* guac_status_string(guac_status status) { @@ -55,32 +73,97 @@ const char* guac_status_string(guac_status status) { case GUAC_STATUS_NO_MEMORY: return __GUAC_STATUS_NO_MEMORY_STR; - /* End of input */ - case GUAC_STATUS_NO_INPUT: - return __GUAC_STATUS_NO_INPUT_STR; + /* End of stream */ + case GUAC_STATUS_CLOSED: + return __GUAC_STATUS_CLOSED_STR; - /* Input timeout */ - case GUAC_STATUS_INPUT_TIMEOUT: - return __GUAC_STATUS_INPUT_TIMEOUT_STR; + /* Timeout */ + case GUAC_STATUS_TIMEOUT: + return __GUAC_STATUS_TIMEOUT_STR; /* Further information in errno */ case GUAC_STATUS_SEE_ERRNO: return strerror(errno); - /* Output error */ - case GUAC_STATUS_OUTPUT_ERROR: - return __GUAC_STATUS_OUTPUT_ERROR_STR; + /* Input/output error */ + case GUAC_STATUS_IO_ERROR: + return __GUAC_STATUS_IO_ERROR_STR; /* Invalid argument */ - case GUAC_STATUS_BAD_ARGUMENT: - return __GUAC_STATUS_BAD_ARGUMENT_STR; + case GUAC_STATUS_INVALID_ARGUMENT: + return __GUAC_STATUS_INVALID_ARGUMENT_STR; - /* Illegal state */ - case GUAC_STATUS_BAD_STATE: - return __GUAC_STATUS_BAD_STATE_STR; + /* Internal error */ + case GUAC_STATUS_INTERNAL_ERROR: + return __GUAC_STATUS_INTERNAL_ERROR_STR; + /* Out of space */ + case GUAC_STATUS_NO_SPACE: + return __GUAC_STATUS_NO_SPACE_STR; + + /* Input too large */ + case GUAC_STATUS_INPUT_TOO_LARGE: + return __GUAC_STATUS_INPUT_TOO_LARGE_STR; + + /* Result too large */ + case GUAC_STATUS_RESULT_TOO_LARGE: + return __GUAC_STATUS_RESULT_TOO_LARGE_STR; + + /* Permission denied */ + case GUAC_STATUS_PERMISSION_DENIED: + return __GUAC_STATUS_PERMISSION_DENIED_STR; + + /* Resource is busy */ + case GUAC_STATUS_BUSY: + return __GUAC_STATUS_BUSY_STR; + + /* Resource not available */ + case GUAC_STATUS_NOT_AVAILABLE: + return __GUAC_STATUS_NOT_AVAILABLE_STR; + + /* Not supported */ + case GUAC_STATUS_NOT_SUPPORTED: + return __GUAC_STATUS_NOT_SUPPORTED_STR; + + /* Not implemented */ + case GUAC_STATUS_NOT_INPLEMENTED: + return __GUAC_STATUS_NOT_INPLEMENTED_STR; + + /* Temporary failure */ + case GUAC_STATUS_TRY_AGAIN: + return __GUAC_STATUS_TRY_AGAIN_STR; + + /* Guacamole protocol error */ + case GUAC_STATUS_PROTOCOL_ERROR: + return __GUAC_STATUS_PROTOCOL_ERROR_STR; + + /* Resource not found */ + case GUAC_STATUS_NOT_FOUND: + return __GUAC_STATUS_NOT_FOUND_STR; + + /* Operation canceled */ + case GUAC_STATUS_CANCELED: + return __GUAC_STATUS_CANCELED_STR; + + /* Value out of range */ + case GUAC_STATUS_OUT_OF_RANGE: + return __GUAC_STATUS_OUT_OF_RANGE_STR; + + /* Operation refused */ + case GUAC_STATUS_REFUSED: + return __GUAC_STATUS_REFUSED_STR; + + /* Too many resource in use */ + case GUAC_STATUS_TOO_MANY: + return __GUAC_STATUS_TOO_MANY_STR; + + /* Operation would block */ + case GUAC_STATUS_WOULD_BLOCK: + return __GUAC_STATUS_WOULD_BLOCK_STR; + + /* Unknown status code */ default: - return __GUAC_STATUS_INVALID_STATUS_STR; + return __GUAC_STATUS_UNKNOWN_STATUS_STR; } diff --git a/src/libguac/guacamole/error-types.h b/src/libguac/guacamole/error-types.h index 7b9d4655..d7813b46 100644 --- a/src/libguac/guacamole/error-types.h +++ b/src/libguac/guacamole/error-types.h @@ -45,16 +45,15 @@ typedef enum guac_status { GUAC_STATUS_NO_MEMORY, /** - * The end of the input stream associated with the operation - * has been reached. + * The resource associated with the operation can no longer be used as it + * has reached the end of its normal lifecycle. */ - GUAC_STATUS_NO_INPUT, + GUAC_STATUS_CLOSED, /** - * A timeout occurred while reading from the input stream associated - * with the operation. + * Time ran out before the operation could complete. */ - GUAC_STATUS_INPUT_TIMEOUT, + GUAC_STATUS_TIMEOUT, /** * An error occurred, and further information about the error is already @@ -63,22 +62,109 @@ typedef enum guac_status { GUAC_STATUS_SEE_ERRNO, /** - * An error prevented the operation from writing to its associated - * output stream. + * An I/O error prevented the operation from succeeding. */ - GUAC_STATUS_OUTPUT_ERROR, + GUAC_STATUS_IO_ERROR, /** * The operation could not be performed because an invalid argument was * given. */ - GUAC_STATUS_BAD_ARGUMENT, + GUAC_STATUS_INVALID_ARGUMENT, /** - * The state of the associated system prevents an operation from being - * performed which would otherwise be allowed. + * The operation failed due to a bug in the software or a serious system + * problem. */ - GUAC_STATUS_BAD_STATE + GUAC_STATUS_INTERNAL_ERROR, + + /** + * Insufficient space remaining to complete the operation. + */ + GUAC_STATUS_NO_SPACE, + + /** + * The operation failed because the input provided is too large. + */ + GUAC_STATUS_INPUT_TOO_LARGE, + + /** + * The operation failed because the result could not be stored in the + * space provided. + */ + GUAC_STATUS_RESULT_TOO_LARGE, + + /** + * Permission was denied to perform the operation. + */ + GUAC_STATUS_PERMISSION_DENIED, + + /** + * The operation could not be performed because associated resources are + * busy. + */ + GUAC_STATUS_BUSY, + + /** + * The operation could not be performed because, while the associated + * resources do exist, they are not currently available for use. + */ + GUAC_STATUS_NOT_AVAILABLE, + + /** + * The requested operation is not supported. + */ + GUAC_STATUS_NOT_SUPPORTED, + + /** + * Support for the requested operation is not yet implemented. + */ + GUAC_STATUS_NOT_INPLEMENTED, + + /** + * The operation is temporarily unable to be performed, but may succeed if + * reattempted. + */ + GUAC_STATUS_TRY_AGAIN, + + /** + * A violation of the Guacamole protocol occurred. + */ + GUAC_STATUS_PROTOCOL_ERROR, + + /** + * The operation could not be performed because the requested resources do + * not exist. + */ + GUAC_STATUS_NOT_FOUND, + + /** + * The operation was canceled prior to completion. + */ + GUAC_STATUS_CANCELED, + + /** + * The operation could not be performed because input values are outside + * the allowed range. + */ + GUAC_STATUS_OUT_OF_RANGE, + + /** + * The operation could not be performed because access to an underlying + * resource is explicitly not allowed, though not necessarily due to + * permissions. + */ + GUAC_STATUS_REFUSED, + + /** + * The operation failed because too many resources are already in use. + */ + GUAC_STATUS_TOO_MANY, + + /** + * The operation was not performed because it would otherwise block. + */ + GUAC_STATUS_WOULD_BLOCK } guac_status; diff --git a/src/libguac/instruction.c b/src/libguac/instruction.c index d5f16070..90f9067d 100644 --- a/src/libguac/instruction.c +++ b/src/libguac/instruction.c @@ -238,7 +238,7 @@ guac_instruction* guac_instruction_read(guac_socket* socket, /* EOF */ if (retval == 0) { - guac_error = GUAC_STATUS_NO_INPUT; + guac_error = GUAC_STATUS_CLOSED; guac_error_message = "End of stream reached while " "reading instruction"; return NULL; @@ -257,7 +257,7 @@ guac_instruction* guac_instruction_read(guac_socket* socket, /* Fail on error */ if (instruction->state == GUAC_INSTRUCTION_PARSE_ERROR) { - guac_error = GUAC_STATUS_BAD_ARGUMENT; + guac_error = GUAC_STATUS_PROTOCOL_ERROR; guac_error_message = "Instruction parse error"; return NULL; } @@ -284,7 +284,7 @@ guac_instruction* guac_instruction_expect(guac_socket* socket, int usec_timeout, /* Validate instruction */ if (strcmp(instruction->opcode, opcode) != 0) { - guac_error = GUAC_STATUS_BAD_STATE; + guac_error = GUAC_STATUS_PROTOCOL_ERROR; guac_error_message = "Instruction read did not have expected opcode"; guac_instruction_free(instruction); return NULL; diff --git a/src/libguac/plugin.c b/src/libguac/plugin.c index 37070dfb..96845d48 100644 --- a/src/libguac/plugin.c +++ b/src/libguac/plugin.c @@ -57,7 +57,7 @@ guac_client_plugin* guac_client_plugin_open(const char* protocol) { /* Load client plugin */ client_plugin_handle = dlopen(protocol_lib, RTLD_LAZY); if (!client_plugin_handle) { - guac_error = GUAC_STATUS_BAD_ARGUMENT; + guac_error = GUAC_STATUS_NOT_FOUND; guac_error_message = dlerror(); return NULL; } @@ -69,7 +69,7 @@ guac_client_plugin* guac_client_plugin_open(const char* protocol) { /* Fail if cannot find guac_client_init */ if (dlerror() != NULL) { - guac_error = GUAC_STATUS_BAD_ARGUMENT; + guac_error = GUAC_STATUS_INTERNAL_ERROR; guac_error_message = dlerror(); return NULL; } @@ -79,7 +79,7 @@ guac_client_plugin* guac_client_plugin_open(const char* protocol) { /* Fail if cannot find GUAC_CLIENT_ARGS */ if (dlerror() != NULL) { - guac_error = GUAC_STATUS_BAD_ARGUMENT; + guac_error = GUAC_STATUS_INTERNAL_ERROR; guac_error_message = dlerror(); return NULL; } @@ -104,7 +104,7 @@ int guac_client_plugin_close(guac_client_plugin* plugin) { /* Unload client plugin */ if (dlclose(plugin->__client_plugin_handle)) { - guac_error = GUAC_STATUS_BAD_STATE; + guac_error = GUAC_STATUS_INTERNAL_ERROR; guac_error_message = dlerror(); return -1; } diff --git a/src/libguac/protocol.c b/src/libguac/protocol.c index 62751fce..a6c2229f 100644 --- a/src/libguac/protocol.c +++ b/src/libguac/protocol.c @@ -128,7 +128,7 @@ int __guac_socket_write_length_png_cairo(guac_socket* socket, cairo_surface_t* s png_data.data_size = 0; if (cairo_surface_write_to_png_stream(surface, __guac_socket_write_png_cairo, &png_data) != CAIRO_STATUS_SUCCESS) { - guac_error = GUAC_STATUS_OUTPUT_ERROR; + guac_error = GUAC_STATUS_INTERNAL_ERROR; guac_error_message = "Cairo PNG backend failed"; return -1; } @@ -231,7 +231,7 @@ int __guac_socket_write_length_png(guac_socket* socket, cairo_surface_t* surface /* Set up PNG writer */ png = png_create_write_struct(PNG_LIBPNG_VER_STRING, NULL, NULL, NULL); if (!png) { - guac_error = GUAC_STATUS_OUTPUT_ERROR; + guac_error = GUAC_STATUS_INTERNAL_ERROR; guac_error_message = "libpng failed to create write structure"; return -1; } @@ -239,7 +239,7 @@ int __guac_socket_write_length_png(guac_socket* socket, cairo_surface_t* surface png_info = png_create_info_struct(png); if (!png_info) { png_destroy_write_struct(&png, NULL); - guac_error = GUAC_STATUS_OUTPUT_ERROR; + guac_error = GUAC_STATUS_INTERNAL_ERROR; guac_error_message = "libpng failed to create info structure"; return -1; } @@ -247,7 +247,7 @@ int __guac_socket_write_length_png(guac_socket* socket, cairo_surface_t* surface /* Set error handler */ if (setjmp(png_jmpbuf(png))) { png_destroy_write_struct(&png, &png_info); - guac_error = GUAC_STATUS_OUTPUT_ERROR; + guac_error = GUAC_STATUS_IO_ERROR; guac_error_message = "libpng output error"; return -1; } diff --git a/src/libguac/socket-fd.c b/src/libguac/socket-fd.c index 710c6cbc..13c66edd 100644 --- a/src/libguac/socket-fd.c +++ b/src/libguac/socket-fd.c @@ -114,7 +114,7 @@ int __guac_socket_fd_select_handler(guac_socket* socket, int usec_timeout) { } if (retval == 0) { - guac_error = GUAC_STATUS_INPUT_TIMEOUT; + guac_error = GUAC_STATUS_TIMEOUT; guac_error_message = "Timeout while waiting for data on socket"; } diff --git a/src/protocols/rdp/guac_handlers.c b/src/protocols/rdp/guac_handlers.c index 2e9fac70..66a1fd21 100644 --- a/src/protocols/rdp/guac_handlers.c +++ b/src/protocols/rdp/guac_handlers.c @@ -196,16 +196,14 @@ int rdp_guac_client_handle_messages(guac_client* client) { /* Check the libfreerdp fds */ if (!freerdp_check_fds(rdp_inst)) { - guac_error = GUAC_STATUS_BAD_STATE; - guac_error_message = "Error handling RDP file descriptors"; + guac_client_log(client, GUAC_LOG_DEBUG, "Error handling RDP file descriptors"); pthread_mutex_unlock(&(guac_client_data->rdp_lock)); return 1; } /* Check channel fds */ if (!freerdp_channels_check_fds(channels, rdp_inst)) { - guac_error = GUAC_STATUS_BAD_STATE; - guac_error_message = "Error handling RDP channel file descriptors"; + guac_client_log(client, GUAC_LOG_DEBUG, "Error handling RDP channel file descriptors"); pthread_mutex_unlock(&(guac_client_data->rdp_lock)); return 1; } @@ -233,8 +231,7 @@ int rdp_guac_client_handle_messages(guac_client* client) { /* Handle RDP disconnect */ if (freerdp_shall_disconnect(rdp_inst)) { - guac_error = GUAC_STATUS_NO_INPUT; - guac_error_message = "RDP server closed connection"; + guac_client_log(client, GUAC_LOG_INFO, "RDP server closed connection"); pthread_mutex_unlock(&(guac_client_data->rdp_lock)); return 1; } diff --git a/src/terminal/terminal.c b/src/terminal/terminal.c index 6ff955af..3d9b5702 100644 --- a/src/terminal/terminal.c +++ b/src/terminal/terminal.c @@ -213,8 +213,7 @@ guac_terminal* guac_terminal_create(guac_client* client, /* Fail if display init failed */ if (term->display == NULL) { - guac_error = GUAC_STATUS_BAD_STATE; - guac_error_message = "Display initialization failed"; + guac_client_log(client, GUAC_LOG_DEBUG, "Display initialization failed"); free(term); return NULL; }