From fd1485e22014bfe96ea5b39141ed00177638c09b Mon Sep 17 00:00:00 2001 From: Michael Jumper Date: Tue, 8 Feb 2011 18:02:27 -0800 Subject: [PATCH 1/6] Added cross-platform logging. --- libguac/include/guaclog.h | 38 ++++++++++++++++++++++++++++++++++++++ libguac/src/client.c | 34 ++++++++++++++++------------------ 2 files changed, 54 insertions(+), 18 deletions(-) create mode 100644 libguac/include/guaclog.h diff --git a/libguac/include/guaclog.h b/libguac/include/guaclog.h new file mode 100644 index 00000000..22dd637a --- /dev/null +++ b/libguac/include/guaclog.h @@ -0,0 +1,38 @@ + +/* + * Guacamole - Clientless Remote Desktop + * Copyright (C) 2010 Michael Jumper + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Affero General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Affero General Public License for more details. + * + * You should have received a copy of the GNU Affero General Public License + * along with this program. If not, see . + */ + +#ifndef _GUACLOG_H +#define _GUACLOG_H + +#ifndef __MINGW32__ + + // Logging for UNIX + #include + #define GUAC_LOG_ERROR(...) syslog(LOG_ERR, __VA_ARGS__) + #define GUAC_LOG_INFO(...) syslog(LOG_INFO, __VA_ARGS__) + +#else + + // Logging for W32 + #define GUAC_LOG_ERROR(...) fprintf(stderr, __VA_ARGS__) + #define GUAC_LOG_INFO(...) fprintf(stderr, __VA_ARGS__) + +#endif + +#endif diff --git a/libguac/src/client.c b/libguac/src/client.c index eae2dc56..0a569130 100644 --- a/libguac/src/client.c +++ b/libguac/src/client.c @@ -20,11 +20,9 @@ #include #include #include - -#include - #include +#include "guaclog.h" #include "guacio.h" #include "protocol.h" #include "client.h" @@ -100,7 +98,7 @@ guac_client* guac_get_client(int client_fd) { int result = guac_read_instruction(io, &instruction); if (result < 0) { - syslog(LOG_ERR, "Error reading instruction while waiting for select"); + GUAC_LOG_ERROR("Error reading instruction while waiting for select"); guac_close(io); return NULL; } @@ -122,7 +120,7 @@ guac_client* guac_get_client(int client_fd) { /* Load client plugin */ client->client_plugin_handle = dlopen(protocol_lib, RTLD_LAZY); if (!(client->client_plugin_handle)) { - syslog(LOG_ERR, "Could not open client plugin for protocol \"%s\": %s\n", protocol, dlerror()); + GUAC_LOG_ERROR("Could not open client plugin for protocol \"%s\": %s\n", protocol, dlerror()); guac_send_error(io, "Could not load server-side client plugin."); guac_flush(io); guac_close(io); @@ -136,7 +134,7 @@ guac_client* guac_get_client(int client_fd) { alias.obj = dlsym(client->client_plugin_handle, "guac_client_init"); if ((error = dlerror()) != NULL) { - syslog(LOG_ERR, "Could not get guac_client_init in plugin: %s\n", error); + GUAC_LOG_ERROR("Could not get guac_client_init in plugin: %s\n", error); guac_send_error(io, "Invalid server-side client plugin."); guac_flush(io); guac_close(io); @@ -148,7 +146,7 @@ guac_client* guac_get_client(int client_fd) { client_args = (const char**) dlsym(client->client_plugin_handle, "GUAC_CLIENT_ARGS"); if ((error = dlerror()) != NULL) { - syslog(LOG_ERR, "Could not get GUAC_CLIENT_ in plugin: %s\n", error); + GUAC_LOG_ERROR("Could not get GUAC_CLIENT_ in plugin: %s\n", error); guac_send_error(io, "Invalid server-side client plugin."); guac_flush(io); guac_close(io); @@ -175,7 +173,7 @@ guac_client* guac_get_client(int client_fd) { int result = guac_read_instruction(io, &instruction); if (result < 0) { - syslog(LOG_ERR, "Error reading instruction while waiting for connect"); + GUAC_LOG_ERROR("Error reading instruction while waiting for connect"); guac_close(io); return NULL; } @@ -213,14 +211,14 @@ void guac_free_client(guac_client* client) { if (client->free_handler) { if (client->free_handler(client)) - syslog(LOG_ERR, "Error calling client free handler"); + GUAC_LOG_ERROR("Error calling client free handler"); } guac_close(client->io); /* Unload client plugin */ if (dlclose(client->client_plugin_handle)) { - syslog(LOG_ERR, "Could not close client plugin while unloading client: %s", dlerror()); + GUAC_LOG_ERROR("Could not close client plugin while unloading client: %s", dlerror()); } free(client); @@ -241,7 +239,7 @@ void guac_start_client(guac_client* client) { int retval = client->handle_messages(client); if (retval) { - syslog(LOG_ERR, "Error handling server messages"); + GUAC_LOG_ERROR("Error handling server messages"); return; } @@ -270,7 +268,7 @@ void guac_start_client(guac_client* client) { ) ) { - syslog(LOG_ERR, "Error handling mouse instruction"); + GUAC_LOG_ERROR("Error handling mouse instruction"); guac_free_instruction_data(&instruction); return; @@ -287,7 +285,7 @@ void guac_start_client(guac_client* client) { ) ) { - syslog(LOG_ERR, "Error handling key instruction"); + GUAC_LOG_ERROR("Error handling key instruction"); guac_free_instruction_data(&instruction); return; @@ -303,7 +301,7 @@ void guac_start_client(guac_client* client) { ) ) { - syslog(LOG_ERR, "Error handling clipboard instruction"); + GUAC_LOG_ERROR("Error handling clipboard instruction"); guac_free_instruction_data(&instruction); return; @@ -311,7 +309,7 @@ void guac_start_client(guac_client* client) { } else if (strcmp(instruction.opcode, "disconnect") == 0) { - syslog(LOG_INFO, "Client requested disconnect"); + GUAC_LOG_INFO("Client requested disconnect"); guac_free_instruction_data(&instruction); return; } @@ -321,13 +319,13 @@ void guac_start_client(guac_client* client) { } while ((retval = guac_read_instruction(io, &instruction)) > 0); if (retval < 0) { - syslog(LOG_ERR, "Error reading instruction from stream"); + GUAC_LOG_ERROR("Error reading instruction from stream"); return; } } if (retval < 0) { - syslog(LOG_ERR, "Error or end of stream"); + GUAC_LOG_ERROR("Error or end of stream"); return; /* EOF or error */ } @@ -335,7 +333,7 @@ void guac_start_client(guac_client* client) { } else if (wait_result < 0) { - syslog(LOG_ERR, "Error waiting for next instruction"); + GUAC_LOG_ERROR("Error waiting for next instruction"); return; } From 9c7c09cd7f47bd5fd0470614232d5d7c6f5eefde Mon Sep 17 00:00:00 2001 From: Michael Jumper Date: Tue, 8 Feb 2011 18:23:10 -0800 Subject: [PATCH 2/6] Removed transfer limit, improved cross-platform logging, added check for png_structp. --- libguac/include/guacio.h | 7 ------ libguac/include/guaclog.h | 6 ++--- libguac/src/guacio.c | 49 +++++---------------------------------- libguac/src/protocol.c | 10 ++++++++ 4 files changed, 19 insertions(+), 53 deletions(-) diff --git a/libguac/include/guacio.h b/libguac/include/guacio.h index 8499ea3e..da4aa8f5 100644 --- a/libguac/include/guacio.h +++ b/libguac/include/guacio.h @@ -79,13 +79,6 @@ typedef struct GUACIO { */ char* instructionbuf; - /** - * The transfer limit, in kilobytes per second. If 0, there is no - * transfer limit. If non-zero, sleep calls are used at the end of - * a write to ensure output never exceeds the specified limit. - */ - unsigned int transfer_limit; /* KB/sec */ - } GUACIO; /** diff --git a/libguac/include/guaclog.h b/libguac/include/guaclog.h index 22dd637a..a59c2318 100644 --- a/libguac/include/guaclog.h +++ b/libguac/include/guaclog.h @@ -20,16 +20,16 @@ #ifndef _GUACLOG_H #define _GUACLOG_H -#ifndef __MINGW32__ +#ifdef HAVE_SYSLOG_H - // Logging for UNIX + /* Logging for UNIX */ #include #define GUAC_LOG_ERROR(...) syslog(LOG_ERR, __VA_ARGS__) #define GUAC_LOG_INFO(...) syslog(LOG_INFO, __VA_ARGS__) #else - // Logging for W32 + /* Logging for W32 */ #define GUAC_LOG_ERROR(...) fprintf(stderr, __VA_ARGS__) #define GUAC_LOG_INFO(...) fprintf(stderr, __VA_ARGS__) diff --git a/libguac/src/guacio.c b/libguac/src/guacio.c index e9f0e5b9..c0a14b8e 100644 --- a/libguac/src/guacio.c +++ b/libguac/src/guacio.c @@ -23,8 +23,13 @@ #include #include -#include +#ifdef __MINGW32__ +#include +#else #include +#endif + +#include #include #include "guacio.h" @@ -48,9 +53,6 @@ GUACIO* guac_open(int fd) { io->instructionbuf = malloc(io->instructionbuf_size); io->instructionbuf_used_length = 0; - /* Set limit */ - io->transfer_limit = 0; - return io; } @@ -64,41 +66,10 @@ void guac_close(GUACIO* io) { /* Write bytes, limit rate */ ssize_t __guac_write(GUACIO* io, const char* buf, int count) { - struct timeval start, end; int retval; /* Write and time how long the write takes (microseconds) */ - gettimeofday(&start, NULL); retval = write(io->fd, buf, count); - gettimeofday(&end, NULL); - - if (retval < 0) - return retval; - - if (io->transfer_limit > 0) { - - suseconds_t elapsed; - suseconds_t required_usecs; - - /* Get elapsed time */ - elapsed = (end.tv_sec - start.tv_sec) * 1000000 + end.tv_usec - start.tv_usec; - - /* Calculate how much time we must sleep */ - required_usecs = retval * 1000 / io->transfer_limit - elapsed; /* useconds at transfer_limit KB/s*/ - - /* Sleep as necessary */ - if (required_usecs > 0) { - - struct timespec required_sleep; - - required_sleep.tv_sec = required_usecs / 1000000; - required_sleep.tv_nsec = (required_usecs % 1000000) * 1000; - - nanosleep(&required_sleep, NULL); - - } - - } return retval; } @@ -136,19 +107,11 @@ ssize_t guac_write_string(GUACIO* io, const char* str) { /* Flush when necessary, return on error */ if (io->written > 8188 /* sizeof(out_buf) - 4 */) { - struct timeval start, end; - suseconds_t elapsed; - - gettimeofday(&start, NULL); retval = __guac_write(io, out_buf, io->written); - gettimeofday(&end, NULL); if (retval < 0) return retval; - /* Get elapsed time */ - elapsed = (end.tv_sec - start.tv_sec) * 1000000 + end.tv_usec - start.tv_usec; - io->written = 0; } diff --git a/libguac/src/protocol.c b/libguac/src/protocol.c index 4d3110e6..f050a868 100644 --- a/libguac/src/protocol.c +++ b/libguac/src/protocol.c @@ -23,8 +23,18 @@ #include #include +/* If png_structp not defined in png.h, try to include pngstruct.h */ +#ifndef png_structp +#include +#endif + #include + +#ifdef __MINGW32__ +#include +#else #include +#endif #include "guacio.h" #include "protocol.h" From e37507d31282997ff81411f0fde45c512599d972 Mon Sep 17 00:00:00 2001 From: Michael Jumper Date: Tue, 8 Feb 2011 18:39:08 -0800 Subject: [PATCH 3/6] Added check for wsock32 --- libguac/configure.in | 1 + 1 file changed, 1 insertion(+) diff --git a/libguac/configure.in b/libguac/configure.in index 5ed6f722..76a93868 100644 --- a/libguac/configure.in +++ b/libguac/configure.in @@ -12,6 +12,7 @@ AC_PROG_LIBTOOL # Checks for libraries. AC_CHECK_LIB([dl], [dlopen],, AC_MSG_ERROR("libdl is required for loading client plugins")) AC_CHECK_LIB([png], [png_write_png],, AC_MSG_ERROR("libpng is required for writing png messages")) +AC_CHECK_LIB([wsock32], [main]) # Checks for header files. AC_CHECK_HEADERS([fcntl.h stdlib.h string.h sys/socket.h sys/time.h syslog.h unistd.h]) From 60897fc7f8f77c4ab7d9c2a11302091f818cbf88 Mon Sep 17 00:00:00 2001 From: Michael Jumper Date: Wed, 9 Feb 2011 01:39:27 -0800 Subject: [PATCH 4/6] Renamed guaclog.h, added newline to macro --- libguac/Makefile.am | 2 +- libguac/include/{guaclog.h => log.h} | 8 ++++---- libguac/src/client.c | 2 +- 3 files changed, 6 insertions(+), 6 deletions(-) rename libguac/include/{guaclog.h => log.h} (83%) diff --git a/libguac/Makefile.am b/libguac/Makefile.am index f20371cc..5801e5f7 100644 --- a/libguac/Makefile.am +++ b/libguac/Makefile.am @@ -4,7 +4,7 @@ ACLOCAL_AMFLAGS = -I m4 AM_CFLAGS = -Werror -Wall -Iinclude libguacincdir = $(includedir)/guacamole -libguacinc_HEADERS = include/client.h include/guacio.h include/protocol.h +libguacinc_HEADERS = include/client.h include/guacio.h include/protocol.h include/log.h lib_LTLIBRARIES = libguac.la diff --git a/libguac/include/guaclog.h b/libguac/include/log.h similarity index 83% rename from libguac/include/guaclog.h rename to libguac/include/log.h index a59c2318..e8499f16 100644 --- a/libguac/include/guaclog.h +++ b/libguac/include/log.h @@ -17,8 +17,8 @@ * along with this program. If not, see . */ -#ifndef _GUACLOG_H -#define _GUACLOG_H +#ifndef _LOG_H +#define _LOG_H #ifdef HAVE_SYSLOG_H @@ -30,8 +30,8 @@ #else /* Logging for W32 */ - #define GUAC_LOG_ERROR(...) fprintf(stderr, __VA_ARGS__) - #define GUAC_LOG_INFO(...) fprintf(stderr, __VA_ARGS__) + #define GUAC_LOG_ERROR(...) fprintf(stderr, __VA_ARGS__); fprintf(stderr, "\n") + #define GUAC_LOG_INFO(...) fprintf(stderr, __VA_ARGS__); fprintf(stderr, "\n") #endif diff --git a/libguac/src/client.c b/libguac/src/client.c index 0a569130..e5bc4979 100644 --- a/libguac/src/client.c +++ b/libguac/src/client.c @@ -22,7 +22,7 @@ #include #include -#include "guaclog.h" +#include "log.h" #include "guacio.h" #include "protocol.h" #include "client.h" From 0cb6ad1502012224c85b920999e5487c8af70ae2 Mon Sep 17 00:00:00 2001 From: Michael Jumper Date: Thu, 10 Feb 2011 00:24:17 -0800 Subject: [PATCH 5/6] Use send() instead of write() if MINGW32. --- libguac/src/guacio.c | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/libguac/src/guacio.c b/libguac/src/guacio.c index c0a14b8e..78ec98d6 100644 --- a/libguac/src/guacio.c +++ b/libguac/src/guacio.c @@ -68,8 +68,13 @@ ssize_t __guac_write(GUACIO* io, const char* buf, int count) { int retval; - /* Write and time how long the write takes (microseconds) */ +#ifdef __MINGW32__ + /* MINGW32 WINSOCK only works with send() */ + retval = send(io->fd, buf, count, 0); +#else + /* Use write() for all other platforms */ retval = write(io->fd, buf, count); +#endif return retval; } From a0cb37295f9d849af86fd8062c922c9e76b616a0 Mon Sep 17 00:00:00 2001 From: Michael Jumper Date: Thu, 10 Feb 2011 23:53:11 -0800 Subject: [PATCH 6/6] Fixed pngstruct.h detection --- libguac/configure.in | 2 +- libguac/src/protocol.c | 3 +-- 2 files changed, 2 insertions(+), 3 deletions(-) diff --git a/libguac/configure.in b/libguac/configure.in index 76a93868..c401cf1c 100644 --- a/libguac/configure.in +++ b/libguac/configure.in @@ -15,7 +15,7 @@ AC_CHECK_LIB([png], [png_write_png],, AC_MSG_ERROR("libpng is required for writi AC_CHECK_LIB([wsock32], [main]) # Checks for header files. -AC_CHECK_HEADERS([fcntl.h stdlib.h string.h sys/socket.h sys/time.h syslog.h unistd.h]) +AC_CHECK_HEADERS([fcntl.h stdlib.h string.h sys/socket.h sys/time.h syslog.h unistd.h pngstruct.h]) # Checks for typedefs, structures, and compiler characteristics. AC_TYPE_SIZE_T diff --git a/libguac/src/protocol.c b/libguac/src/protocol.c index f050a868..a2427f21 100644 --- a/libguac/src/protocol.c +++ b/libguac/src/protocol.c @@ -23,8 +23,7 @@ #include #include -/* If png_structp not defined in png.h, try to include pngstruct.h */ -#ifndef png_structp +#ifdef HAVE_PNGSTRUCT_H #include #endif