Conversion to new naming conventions, partial logging.

This commit is contained in:
Michael Jumper 2011-11-25 12:17:20 -08:00
parent c6d1916afa
commit 682344f778
9 changed files with 455 additions and 480 deletions

View File

@ -40,11 +40,11 @@ ACLOCAL_AMFLAGS = -I m4
AM_CFLAGS = -Werror -Wall -pedantic -Iinclude
libguacincdir = $(includedir)/guacamole
libguacinc_HEADERS = include/client.h include/guacio.h include/protocol.h include/client-handlers.h include/log.h include/error.h
libguacinc_HEADERS = include/client.h include/socket.h include/protocol.h include/client-handlers.h include/error.h
lib_LTLIBRARIES = libguac.la
libguac_la_SOURCES = src/client.c src/guacio.c src/protocol.c src/client-handlers.c src/log.c src/error.c
libguac_la_SOURCES = src/client.c src/socket.c src/protocol.c src/client-handlers.c src/error.c
libguac_la_LDFLAGS = -version-info 2:0:0

View File

@ -39,7 +39,9 @@
#ifndef _GUAC_CLIENT_H
#define _GUAC_CLIENT_H
#include "guacio.h"
#include <stdarg.h>
#include "socket.h"
#include "protocol.h"
/**
@ -77,6 +79,11 @@ typedef int guac_client_clipboard_handler(guac_client* client, char* copied);
*/
typedef int guac_client_free_handler(guac_client* client);
/**
* Handler for logging messages
*/
typedef void guac_client_log_handler(guac_client* client, const char* format, va_list args);
/**
* Possible current states of the Guacamole client. Currently, the only
* two states are RUNNING and STOPPING.
@ -106,12 +113,12 @@ typedef enum guac_client_state {
struct guac_client {
/**
* The GUACIO structure to be used to communicate with the web-client. It is
* The guac_socket structure to be used to communicate with the web-client. It is
* expected that the implementor of any Guacamole proxy client will provide
* their own mechanism of I/O for their protocol. The GUACIO structure is
* their own mechanism of I/O for their protocol. The guac_socket structure is
* used only to communicate conveniently with the Guacamole web-client.
*/
GUACIO* io;
guac_socket* io;
/**
* The current state of the client. When the client is first allocated,
@ -169,7 +176,7 @@ struct guac_client {
*
* Example:
* @code
* void handle_messages(guac_client* client);
* int handle_messages(guac_client* client);
*
* int guac_client_init(guac_client* client, int argc, char** argv) {
* client->handle_messages = handle_messages;
@ -196,7 +203,7 @@ struct guac_client {
* Example:
* @code
* void mouse_handler(guac_client* client, int x, int y, int button_mask);
* int mouse_handler(guac_client* client, int x, int y, int button_mask);
*
* int guac_client_init(guac_client* client, int argc, char** argv) {
* client->mouse_handler = mouse_handler;
@ -214,7 +221,7 @@ struct guac_client {
*
* Example:
* @code
* void key_handler(guac_client* client, int keysym, int pressed);
* int key_handler(guac_client* client, int keysym, int pressed);
*
* int guac_client_init(guac_client* client, int argc, char** argv) {
* client->key_handler = key_handler;
@ -235,7 +242,7 @@ struct guac_client {
*
* Example:
* @code
* void clipboard_handler(guac_client* client, char* copied);
* int clipboard_handler(guac_client* client, char* copied);
*
* int guac_client_init(guac_client* client, int argc, char** argv) {
* client->clipboard_handler = clipboard_handler;
@ -255,7 +262,7 @@ struct guac_client {
*
* Example:
* @code
* void free_handler(guac_client* client);
* int free_handler(guac_client* client);
*
* int guac_client_init(guac_client* client, int argc, char** argv) {
* client->free_handler = free_handler;
@ -264,6 +271,60 @@ struct guac_client {
*/
guac_client_free_handler* free_handler;
/**
* Handler for logging informational messages. This handler will be called
* via guac_client_log_info() when the client needs to log information.
*
* In general, only programs loading the client should implement this
* handler, as those are the programs that would provide the logging
* facilities.
*
* Client implementations should expect these handlers to already be
* set.
*
* Example:
* @code
* void log_handler(guac_client* client, const char* format, va_list args);
*
* void function_of_daemon() {
*
* guac_client* client = [client from guac_get_client()];
*
* client->log_info_handler = log_handler;
*
* }
* @endcode
*/
guac_client_log_handler* log_info_handler;
/**
* Handler for logging error messages. This handler will be called
* via guac_client_log_error() when the client needs to log an error.
*
* In general, only programs loading the client should implement this
* handler, as those are the programs that would provide the logging
* facilities.
*
* Client implementations should expect these handlers to already be
* set.
*
* Example:
* @code
* void log_handler(guac_client* client, const char* format, va_list args);
*
* void function_of_daemon() {
*
* guac_client* client = [client from guac_get_client()];
*
* client->log_error_handler = log_handler;
*
* }
* @endcode
*/
guac_client_log_handler* log_error_handler;
};
/**
@ -272,8 +333,9 @@ struct guac_client {
typedef int guac_client_init_handler(guac_client* client, int argc, char** argv);
/**
* Initialize and return a new guac_client. The pluggable client will be chosen based on
* the first connect message received on the given file descriptor.
* Initialize and return a new guac_client. The pluggable client will be
* chosen based on the first connect message received on the given file
* descriptor.
*
* @param client_fd The file descriptor associated with the socket associated
* with the connection to the web-client tunnel.
@ -288,7 +350,7 @@ guac_client* guac_get_client(int client_fd, int usec_timeout);
*
* @param client The proxy client to free all reasources of.
*/
void guac_free_client(guac_client* client);
void guac_client_free(guac_client* client);
/**
* Call the appropriate handler defined by the given client for the given
@ -330,6 +392,56 @@ guac_layer* guac_client_alloc_layer(guac_client* client, int index);
*/
void guac_client_free_buffer(guac_client* client, guac_layer* layer);
/**
* Logs an informational message in the log used by the given client. The
* logger used will normally be defined by guacd (or whichever program loads
* the proxy client) by setting the logging handlers of the client when it is
* loaded.
*
* @param client The proxy client to log an informational message for.
* @param format A printf-style format string to log.
* @param ... Arguments to use when filling the format string for printing.
*/
void guac_client_log_info(guac_client* client, const char* format, ...);
/**
* Logs an error message in the log used by the given client. The logger
* used will normally be defined by guacd (or whichever program loads the
* proxy client) by setting the logging handlers of the client when it is
* loaded.
*
* @param client The proxy client to log an error for.
* @param format A printf-style format string to log.
* @param ... Arguments to use when filling the format string for printing.
*/
void guac_client_log_error(guac_client* client, const char* format, ...);
/**
* Logs an informational message in the log used by the given client. The
* logger used will normally be defined by guacd (or whichever program loads
* the proxy client) by setting the logging handlers of the client when it is
* loaded.
*
* @param client The proxy client to log an informational message for.
* @param format A printf-style format string to log.
* @param ap The va_list containing the arguments to be used when filling the
* format string for printing.
*/
void vguac_client_log_info(guac_client* client, const char* format, va_list ap);
/**
* Logs an error message in the log used by the given client. The logger
* used will normally be defined by guacd (or whichever program loads the
* proxy client) by setting the logging handlers of the client when it is
* loaded.
*
* @param client The proxy client to log an error for.
* @param format A printf-style format string to log.
* @param ap The va_list containing the arguments to be used when filling the
* format string for printing.
*/
void vguac_client_log_error(guac_client* client, const char* format, va_list ap);
/**
* The default Guacamole client layer, layer 0.
*/

View File

@ -1,95 +0,0 @@
/* ***** BEGIN LICENSE BLOCK *****
* Version: MPL 1.1/GPL 2.0/LGPL 2.1
*
* The contents of this file are subject to the Mozilla Public License Version
* 1.1 (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
* http://www.mozilla.org/MPL/
*
* Software distributed under the License is distributed on an "AS IS" basis,
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
* for the specific language governing rights and limitations under the
* License.
*
* The Original Code is libguac.
*
* The Initial Developer of the Original Code is
* Michael Jumper.
* Portions created by the Initial Developer are Copyright (C) 2010
* the Initial Developer. All Rights Reserved.
*
* Contributor(s):
*
* Alternatively, the contents of this file may be used under the terms of
* either the GNU General Public License Version 2 or later (the "GPL"), or
* the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
* in which case the provisions of the GPL or the LGPL are applicable instead
* of those above. If you wish to allow use of your version of this file only
* under the terms of either the GPL or the LGPL, and not to allow others to
* use your version of this file under the terms of the MPL, indicate your
* decision by deleting the provisions above and replace them with the notice
* and other provisions required by the GPL or the LGPL. If you do not delete
* the provisions above, a recipient may use your version of this file under
* the terms of any one of the MPL, the GPL or the LGPL.
*
* ***** END LICENSE BLOCK ***** */
#ifndef _GUAC_LOG_H
#define _GUAC_LOG_H
#include <stdarg.h>
/**
* Provides basic cross-platform logging facilities.
*
* @file log.h
*/
/**
* Logs an informational message in the system log, whatever
* that may be for the system being used. This will currently
* log to syslog for platforms supporting it, and stderr for
* all others.
*
* @param format A printf-style format string to log.
* @param ... Arguments to use when filling the format string for printing.
*/
void guac_log_info(const char* format, ...);
/**
* Logs an informational message in the system log, whatever
* that may be for the system being used. This will currently
* log to syslog for platforms supporting it, and stderr for
* all others.
*
* @param format A printf-style format string to log.
* @param ap The va_list containing the arguments to be used when filling the
* format string for printing.
*/
void vguac_log_info(const char* format, va_list ap);
/**
* Logs an error message in the system log, whatever
* that may be for the system being used. This will currently
* log to syslog for platforms supporting it, and stderr for
* all others.
*
* @param format A printf-style format string to log.
* @param ... Arguments to use when filling the format string for printing.
*/
void guac_log_error(const char* format, ...);
/**
* Logs an error message in the system log, whatever
* that may be for the system being used. This will currently
* log to syslog for platforms supporting it, and stderr for
* all others.
*
* @param format A printf-style format string to log.
* @param ap The va_list containing the arguments to be used when filling the
* format string for printing.
*/
void vguac_log_error(const char* format, va_list ap);
#endif

View File

@ -40,11 +40,11 @@
#include <cairo/cairo.h>
#include "guacio.h"
#include "socket.h"
/**
* Provides functions and structures required for communicating using the
* Guacamole protocol over a GUACIO connection, such as that provided by
* Guacamole protocol over a guac_socket connection, such as that provided by
* guac_client objects.
*
* @file protocol.h
@ -147,86 +147,86 @@ typedef struct guac_instruction {
*
* @param instruction The instruction to free.
*/
void guac_free_instruction(guac_instruction* instruction);
void guac_instruction_free(guac_instruction* instruction);
/**
* Sends an args instruction over the given GUACIO connection.
* Sends an args instruction over the given guac_socket connection.
*
* If an error occurs sending the instruction, a non-zero value is
* returned, and guac_error is set appropriately.
*
* @param io The GUACIO connection to use.
* @param io The guac_socket connection to use.
* @param args The NULL-terminated array of argument names (strings).
* @return Zero on success, non-zero on error.
*/
int guac_send_args(GUACIO* io, const char** name);
int guac_protocol_send_args(guac_socket* io, const char** name);
/**
* Sends a name instruction over the given GUACIO connection.
* Sends a name instruction over the given guac_socket connection.
*
* @param io The GUACIO connection to use.
* @param io The guac_socket connection to use.
* @param name The name to send within the name instruction.
* @return Zero on success, non-zero on error.
*/
int guac_send_name(GUACIO* io, const char* name);
int guac_protocol_send_name(guac_socket* io, const char* name);
/**
* Sends a sync instruction over the given GUACIO connection. The
* Sends a sync instruction over the given guac_socket connection. The
* current time in milliseconds should be passed in as the timestamp.
*
* If an error occurs sending the instruction, a non-zero value is
* returned, and guac_error is set appropriately.
*
* @param io The GUACIO connection to use.
* @param io The guac_socket connection to use.
* @param timestamp The current timestamp (in milliseconds).
* @return Zero on success, non-zero on error.
*/
int guac_send_sync(GUACIO* io, guac_timestamp timestamp);
int guac_protocol_send_sync(guac_socket* io, guac_timestamp timestamp);
/**
* Sends an error instruction over the given GUACIO connection.
* Sends an error instruction over the given guac_socket connection.
*
* If an error occurs sending the instruction, a non-zero value is
* returned, and guac_error is set appropriately.
*
* @param io The GUACIO connection to use.
* @param io The guac_socket connection to use.
* @param error The description associated with the error.
* @return Zero on success, non-zero on error.
*/
int guac_send_error(GUACIO* io, const char* error);
int guac_protocol_send_error(guac_socket* io, const char* error);
/**
* Sends a clipboard instruction over the given GUACIO connection.
* Sends a clipboard instruction over the given guac_socket connection.
*
* If an error occurs sending the instruction, a non-zero value is
* returned, and guac_error is set appropriately.
*
* @param io The GUACIO connection to use.
* @param io The guac_socket connection to use.
* @param data The clipboard data to send.
* @return Zero on success, non-zero on error.
*/
int guac_send_clipboard(GUACIO* io, const char* data);
int guac_protocol_send_clipboard(guac_socket* io, const char* data);
/**
* Sends a size instruction over the given GUACIO connection.
* Sends a size instruction over the given guac_socket connection.
*
* If an error occurs sending the instruction, a non-zero value is
* returned, and guac_error is set appropriately.
*
* @param io The GUACIO connection to use.
* @param io The guac_socket connection to use.
* @param w The width of the display.
* @param h The height of the display.
* @return Zero on success, non-zero on error.
*/
int guac_send_size(GUACIO* io, int w, int h);
int guac_protocol_send_size(guac_socket* io, int w, int h);
/**
* Sends a copy instruction over the given GUACIO connection.
* Sends a copy instruction over the given guac_socket connection.
*
* If an error occurs sending the instruction, a non-zero value is
* returned, and guac_error is set appropriately.
*
* @param io The GUACIO connection to use.
* @param io The guac_socket connection to use.
* @param srcl The source layer.
* @param srcx The X coordinate of the source rectangle.
* @param srcy The Y coordinate of the source rectangle.
@ -240,17 +240,17 @@ int guac_send_size(GUACIO* io, int w, int h);
* should be copied.
* @return Zero on success, non-zero on error.
*/
int guac_send_copy(GUACIO* io,
int guac_protocol_send_copy(guac_socket* io,
const guac_layer* srcl, int srcx, int srcy, int w, int h,
guac_composite_mode mode, const guac_layer* dstl, int dstx, int dsty);
/**
* Sends a rect instruction over the given GUACIO connection.
* Sends a rect instruction over the given guac_socket connection.
*
* If an error occurs sending the instruction, a non-zero value is
* returned, and guac_error is set appropriately.
*
* @param io The GUACIO connection to use.
* @param io The guac_socket connection to use.
* @param mode The composite mode to use.
* @param layer The destination layer.
* @param x The X coordinate of the rectangle.
@ -263,18 +263,18 @@ int guac_send_copy(GUACIO* io,
* @param a The alpha (transparency) component of the color of the rectangle.
* @return Zero on success, non-zero on error.
*/
int guac_send_rect(GUACIO* io,
int guac_protocol_send_rect(guac_socket* io,
guac_composite_mode mode, const guac_layer* layer,
int x, int y, int width, int height,
int r, int g, int b, int a);
/**
* Sends a clip instruction over the given GUACIO connection.
* Sends a clip instruction over the given guac_socket connection.
*
* If an error occurs sending the instruction, a non-zero value is
* returned, and guac_error is set appropriately.
*
* @param io The GUACIO connection to use.
* @param io The guac_socket connection to use.
* @param layer The layer to set the clipping region of.
* @param x The X coordinate of the clipping rectangle.
* @param y The Y coordinate of the clipping rectangle.
@ -282,17 +282,17 @@ int guac_send_rect(GUACIO* io,
* @param height The height of the clipping rectangle.
* @return Zero on success, non-zero on error.
*/
int guac_send_clip(GUACIO* io, const guac_layer* layer,
int guac_protocol_send_clip(guac_socket* io, const guac_layer* layer,
int x, int y, int width, int height);
/**
* Sends a png instruction over the given GUACIO connection. The PNG image data
* Sends a png instruction over the given guac_socket connection. The PNG image data
* given will be automatically base64-encoded for transmission.
*
* If an error occurs sending the instruction, a non-zero value is
* returned, and guac_error is set appropriately.
*
* @param io The GUACIO connection to use.
* @param io The guac_socket connection to use.
* @param mode The composite mode to use.
* @param layer The destination layer.
* @param x The destination X coordinate.
@ -300,53 +300,75 @@ int guac_send_clip(GUACIO* io, const guac_layer* layer,
* @param surface A cairo surface containing the image data to send.
* @return Zero on success, non-zero on error.
*/
int guac_send_png(GUACIO* io, guac_composite_mode mode,
int guac_protocol_send_png(guac_socket* io, guac_composite_mode mode,
const guac_layer* layer, int x, int y, cairo_surface_t* surface);
/**
* Sends a cursor instruction over the given GUACIO connection. The PNG image
* Sends a cursor instruction over the given guac_socket connection. The PNG image
* data given will be automatically base64-encoded for transmission.
*
* If an error occurs sending the instruction, a non-zero value is
* returned, and guac_error is set appropriately.
*
* @param io The GUACIO connection to use.
* @param io The guac_socket connection to use.
* @param x The X coordinate of the cursor hotspot.
* @param y The Y coordinate of the cursor hotspot.
* @param surface A cairo surface containing the image data to send.
* @return Zero on success, non-zero on error.
*/
int guac_send_cursor(GUACIO* io, int x, int y, cairo_surface_t* surface);
int guac_protocol_send_cursor(guac_socket* io, int x, int y, cairo_surface_t* surface);
/**
* Returns whether new instruction data is available on the given GUACIO
* Returns whether new instruction data is available on the given guac_socket
* connection for parsing.
*
* @param io The GUACIO connection to use.
* @param io The guac_socket connection to use.
* @param usec_timeout The maximum number of microseconds to wait before
* giving up.
* @return A positive value if data is available, negative on error, or
* zero if no data is currently available.
*/
int guac_instructions_waiting(GUACIO* io, int usec_timeout);
int guac_protocol_instructions_waiting(guac_socket* io, int usec_timeout);
/**
* Reads a single instruction from the given GUACIO connection.
* Reads a single instruction from the given guac_socket connection.
*
* If an error occurs reading the instruction, NULL is returned,
* and guac_error is set appropriately.
*
* @param io The GUACIO connection to use.
* @param io The guac_socket connection to use.
* @param usec_timeout The maximum number of microseconds to wait before
* giving up.
* @return A new instruction if data was successfully read, NULL on
* error or if the instruction could not be read completely
* because the timeout elapsed, in which case guac_error will be
* set to GUAC_STATUS_INPUT_TIMEOUT and subsequent calls to
* guac_read_instruction() will return the parsed instruction once
* guac_protocol_read_instruction() will return the parsed instruction once
* enough data is available.
*/
guac_instruction* guac_read_instruction(GUACIO* io, int usec_timeout);
guac_instruction* guac_protocol_read_instruction(guac_socket* io, int usec_timeout);
/**
* Reads a single instruction with the given opcode from the given guac_socket
* connection.
*
* If an error occurs reading the instruction, NULL is returned,
* and guac_error is set appropriately.
*
* If the instruction read is not the expected instruction, NULL is returned,
* and guac_error is set to GUAC_STATUS_BAD_STATE.
*
* @param io The guac_socket connection to use.
* @param usec_timeout The maximum number of microseconds to wait before
* giving up.
* @param opcode The opcode of the instruction to read.
* @return A new instruction if an instruction with the given opcode was read,
* NULL otherwise. If an instruction was read, but the instruction had
* a different opcode, NULL is returned and guac_error is set to
* GUAC_STATUS_BAD_STATE.
*/
guac_instruction* guac_protocol_expect_instruction(guac_socket* io, int usec_timeout,
const char* opcode);
/**
* Returns an arbitrary timestamp. The difference between return values of any
@ -356,7 +378,7 @@ guac_instruction* guac_read_instruction(GUACIO* io, int usec_timeout);
*
* @return An arbitrary millisecond timestamp.
*/
guac_timestamp guac_current_timestamp();
guac_timestamp guac_protocol_get_timestamp();
/**
* Suspends execution of the current thread for the given number of

View File

@ -35,24 +35,24 @@
*
* ***** END LICENSE BLOCK ***** */
#ifndef _GUAC_GUACIO_H
#define _GUAC_GUACIO_H
#ifndef _GUAC_SOCKET_H
#define _GUAC_SOCKET_H
#include <stdint.h>
#include <unistd.h>
/**
* Defines the GUACIO object and functionss for using and manipulating it.
* Defines the guac_socket object and functionss for using and manipulating it.
*
* @file guacio.h
* @file socket.h
*/
/**
* The core I/O object of Guacamole. GUACIO provides buffered input and output
* as well as convenience methods for efficiently writing base64 data.
* The core I/O object of Guacamole. guac_socket provides buffered input and
* output as well as convenience methods for efficiently writing base64 data.
*/
typedef struct GUACIO {
typedef struct guac_socket {
/**
* The file descriptor to be read from / written to.
@ -114,21 +114,21 @@ typedef struct GUACIO {
*/
char* __instructionbuf_elementv[64];
} GUACIO;
} guac_socket;
/**
* Allocates and initializes a new GUACIO object with the given open
* Allocates and initializes a new guac_socket object with the given open
* file descriptor.
*
* If an error occurs while allocating the GUACIO object, NULL is returned,
* If an error occurs while allocating the guac_socket object, NULL is returned,
* and guac_error is set appropriately.
*
* @param fd An open file descriptor that this GUACIO object should manage.
* @return A newly allocated GUACIO object associated with the given
* @param fd An open file descriptor that this guac_socket object should manage.
* @return A newly allocated guac_socket object associated with the given
* file descriptor, or NULL if an error occurs while allocating
* the GUACIO object.
* the guac_socket object.
*/
GUACIO* guac_open(int fd);
guac_socket* guac_socket_open(int fd);
/**
* Parses the given string as a decimal number, returning the result as
@ -142,21 +142,21 @@ GUACIO* guac_open(int fd);
int64_t guac_parse_int(const char* str);
/**
* Writes the given unsigned int to the given GUACIO object. The data
* Writes the given unsigned int to the given guac_socket object. The data
* written may be buffered until the buffer is flushed automatically or
* manually.
*
* If an error occurs while writing, a non-zero value is returned, and
* guac_error is set appropriately.
*
* @param io The GUACIO object to write to.
* @param io The guac_socket object to write to.
* @param i The unsigned int to write.
* @return Zero on success, or non-zero if an error occurs while writing.
*/
ssize_t guac_write_int(GUACIO* io, int64_t i);
ssize_t guac_socket_write_int(guac_socket* io, int64_t i);
/**
* Writes the given string to the given GUACIO object. The data
* Writes the given string to the given guac_socket object. The data
* written may be buffered until the buffer is flushed automatically or
* manually. Note that if the string can contain characters used
* internally by the Guacamole protocol (commas, semicolons, or
@ -165,29 +165,29 @@ ssize_t guac_write_int(GUACIO* io, int64_t i);
* If an error occurs while writing, a non-zero value is returned, and
* guac_error is set appropriately.
*
* @param io The GUACIO object to write to.
* @param io The guac_socket object to write to.
* @param str The string to write.
* @return Zero on success, or non-zero if an error occurs while writing.
*/
ssize_t guac_write_string(GUACIO* io, const char* str);
ssize_t guac_socket_write_string(guac_socket* io, const char* str);
/**
* Writes the given binary data to the given GUACIO object as base64-encoded
* Writes the given binary data to the given guac_socket object as base64-encoded
* data. The data written may be buffered until the buffer is flushed
* automatically or manually. Beware that because base64 data is buffered
* on top of the write buffer already used, a call to guac_flush_base64() must
* on top of the write buffer already used, a call to guac_socket_flush_base64() must
* be made before non-base64 writes (or writes of an independent block of
* base64 data) can be made.
*
* If an error occurs while writing, a non-zero value is returned, and
* guac_error is set appropriately.
*
* @param io The GUACIO object to write to.
* @param io The guac_socket object to write to.
* @param buf A buffer containing the data to write.
* @param count The number of bytes to write.
* @return Zero on success, or non-zero if an error occurs while writing.
*/
ssize_t guac_write_base64(GUACIO* io, const void* buf, size_t count);
ssize_t guac_socket_write_base64(guac_socket* io, const void* buf, size_t count);
/**
* Flushes the base64 buffer, writing padding characters as necessary.
@ -195,10 +195,10 @@ ssize_t guac_write_base64(GUACIO* io, const void* buf, size_t count);
* If an error occurs while writing, a non-zero value is returned, and
* guac_error is set appropriately.
*
* @param io The GUACIO object to flush
* @param io The guac_socket object to flush
* @return Zero on success, or non-zero if an error occurs during flush.
*/
ssize_t guac_flush_base64(GUACIO* io);
ssize_t guac_socket_flush_base64(guac_socket* io);
/**
* Flushes the write buffer.
@ -206,14 +206,14 @@ ssize_t guac_flush_base64(GUACIO* io);
* If an error occurs while writing, a non-zero value is returned, and
* guac_error is set appropriately.
*
* @param io The GUACIO object to flush
* @param io The guac_socket object to flush
* @return Zero on success, or non-zero if an error occurs during flush.
*/
ssize_t guac_flush(GUACIO* io);
ssize_t guac_socket_flush(guac_socket* io);
/**
* Waits for input to be available on the given GUACIO object until the
* Waits for input to be available on the given guac_socket object until the
* specified timeout elapses.
*
* If an error occurs while waiting, a negative value is returned, and
@ -222,22 +222,22 @@ ssize_t guac_flush(GUACIO* io);
* If a timeout occurs while waiting, zero value is returned, and
* guac_error is set to GUAC_STATUS_INPUT_TIMEOUT.
*
* @param io The GUACIO object to wait for.
* @param io The guac_socket object to wait for.
* @param usec_timeout The maximum number of microseconds to wait for data, or
* -1 to potentially wait forever.
* @return Positive on success, zero if the timeout elapsed and no data is
* available, negative on error.
*/
int guac_select(GUACIO* io, int usec_timeout);
int guac_socket_select(guac_socket* io, int usec_timeout);
/**
* Frees resources allocated to the given GUACIO object. Note that this
* Frees resources allocated to the given guac_socket object. Note that this
* implicitly flush all buffers, but will NOT close the associated file
* descriptor.
*
* @param io The GUACIO object to close.
* @param io The guac_socket object to close.
*/
void guac_close(GUACIO* io);
void guac_socket_close(guac_socket* io);
#endif

View File

@ -40,8 +40,7 @@
#include <string.h>
#include <dlfcn.h>
#include "log.h"
#include "guacio.h"
#include "socket.h"
#include "protocol.h"
#include "client.h"
#include "client-handlers.h"
@ -57,7 +56,7 @@ guac_layer __GUAC_DEFAULT_LAYER = {
const guac_layer* GUAC_DEFAULT_LAYER = &__GUAC_DEFAULT_LAYER;
guac_client* __guac_alloc_client(GUACIO* io) {
guac_client* __guac_alloc_client(guac_socket* io) {
/* Allocate new client (not handoff) */
guac_client* client = malloc(sizeof(guac_client));
@ -65,7 +64,7 @@ guac_client* __guac_alloc_client(GUACIO* io) {
/* Init new client */
client->io = io;
client->last_received_timestamp = client->last_sent_timestamp = guac_current_timestamp();
client->last_received_timestamp = client->last_sent_timestamp = guac_protocol_get_timestamp();
client->state = RUNNING;
client->__all_layers = NULL;
@ -131,7 +130,7 @@ void guac_client_free_buffer(guac_client* client, guac_layer* layer) {
guac_client* guac_get_client(int client_fd, int usec_timeout) {
guac_client* client;
GUACIO* io = guac_open(client_fd);
guac_socket* io = guac_socket_open(client_fd);
/* Pluggable client */
char protocol_lib[256] = "libguac-client-";
@ -159,22 +158,22 @@ guac_client* guac_get_client(int client_fd, int usec_timeout) {
int result;
/* Wait for data until timeout */
result = guac_instructions_waiting(io, usec_timeout);
result = guac_protocol_instructions_waiting(io, usec_timeout);
if (result == 0) {
guac_send_error(io, "Select timeout.");
guac_close(io);
guac_protocol_send_error(io, "Select timeout.");
guac_socket_close(io);
return NULL;
}
/* If error occurs while waiting, exit with failure */
if (result < 0) {
guac_close(io);
guac_socket_close(io);
return NULL;
}
instruction = guac_read_instruction(io, usec_timeout);
instruction = guac_protocol_read_instruction(io, usec_timeout);
if (instruction == NULL) {
guac_close(io);
guac_socket_close(io);
return NULL;
}
@ -195,11 +194,11 @@ guac_client* guac_get_client(int client_fd, int usec_timeout) {
/* Load client plugin */
client->__client_plugin_handle = dlopen(protocol_lib, RTLD_LAZY);
if (!(client->__client_plugin_handle)) {
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);
guac_free_instruction(instruction);
guac_client_log_error(client, "Could not open client plugin for protocol \"%s\": %s\n", protocol, dlerror());
guac_protocol_send_error(io, "Could not load server-side client plugin.");
guac_socket_flush(io);
guac_socket_close(io);
guac_instruction_free(instruction);
return NULL;
}
@ -209,11 +208,11 @@ guac_client* guac_get_client(int client_fd, int usec_timeout) {
alias.obj = dlsym(client->__client_plugin_handle, "guac_client_init");
if ((error = dlerror()) != NULL) {
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);
guac_free_instruction(instruction);
guac_client_log_error(client, "Could not get guac_client_init in plugin: %s\n", error);
guac_protocol_send_error(io, "Invalid server-side client plugin.");
guac_socket_flush(io);
guac_socket_close(io);
guac_instruction_free(instruction);
return NULL;
}
@ -221,29 +220,29 @@ guac_client* guac_get_client(int client_fd, int usec_timeout) {
client_args = (const char**) dlsym(client->__client_plugin_handle, "GUAC_CLIENT_ARGS");
if ((error = dlerror()) != NULL) {
guac_log_error("Could not get GUAC_CLIENT_ARGS in plugin: %s\n", error);
guac_send_error(io, "Invalid server-side client plugin.");
guac_flush(io);
guac_close(io);
guac_free_instruction(instruction);
guac_client_log_error(client, "Could not get GUAC_CLIENT_ARGS in plugin: %s\n", error);
guac_protocol_send_error(io, "Invalid server-side client plugin.");
guac_socket_flush(io);
guac_socket_close(io);
guac_instruction_free(instruction);
return NULL;
}
if ( /* Send args */
guac_send_args(io, client_args)
|| guac_flush(io)
guac_protocol_send_args(io, client_args)
|| guac_socket_flush(io)
) {
guac_close(io);
guac_free_instruction(instruction);
guac_socket_close(io);
guac_instruction_free(instruction);
return NULL;
}
guac_free_instruction(instruction);
guac_instruction_free(instruction);
break;
} /* end if select */
guac_free_instruction(instruction);
guac_instruction_free(instruction);
}
}
@ -254,23 +253,23 @@ guac_client* guac_get_client(int client_fd, int usec_timeout) {
int result;
/* Wait for data until timeout */
result = guac_instructions_waiting(io, usec_timeout);
result = guac_protocol_instructions_waiting(io, usec_timeout);
if (result == 0) {
guac_send_error(io, "Connect timeout.");
guac_close(io);
guac_protocol_send_error(io, "Connect timeout.");
guac_socket_close(io);
return NULL;
}
/* If error occurs while waiting, exit with failure */
if (result < 0) {
guac_close(io);
guac_socket_close(io);
return NULL;
}
instruction = guac_read_instruction(io, usec_timeout);
instruction = guac_protocol_read_instruction(io, usec_timeout);
if (instruction == NULL) {
guac_log_error("Error reading instruction while waiting for connect");
guac_close(io);
guac_client_log_error(client, "Error reading instruction while waiting for connect");
guac_socket_close(io);
return NULL;
}
@ -285,35 +284,35 @@ guac_client* guac_get_client(int client_fd, int usec_timeout) {
if (alias.client_init(client, argc, argv) != 0) {
/* NOTE: On error, proxy client will send appropriate error message */
guac_free_instruction(instruction);
guac_close(io);
guac_instruction_free(instruction);
guac_socket_close(io);
return NULL;
}
guac_free_instruction(instruction);
guac_instruction_free(instruction);
return client;
} /* end if connect */
guac_free_instruction(instruction);
guac_instruction_free(instruction);
}
}
}
void guac_free_client(guac_client* client) {
void guac_client_free(guac_client* client) {
if (client->free_handler) {
if (client->free_handler(client))
guac_log_error("Error calling client free handler");
guac_client_log_error(client, "Error calling client free handler");
}
guac_close(client->io);
guac_socket_close(client->io);
/* Unload client plugin */
if (dlclose(client->__client_plugin_handle)) {
guac_log_error("Could not close client plugin while unloading client: %s", dlerror());
guac_client_log_error(client, "Could not close client plugin while unloading client: %s", dlerror());
}
/* Free all layers */

View File

@ -1,89 +0,0 @@
/* ***** BEGIN LICENSE BLOCK *****
* Version: MPL 1.1/GPL 2.0/LGPL 2.1
*
* The contents of this file are subject to the Mozilla Public License Version
* 1.1 (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
* http://www.mozilla.org/MPL/
*
* Software distributed under the License is distributed on an "AS IS" basis,
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
* for the specific language governing rights and limitations under the
* License.
*
* The Original Code is libguac.
*
* The Initial Developer of the Original Code is
* Michael Jumper.
* Portions created by the Initial Developer are Copyright (C) 2010
* the Initial Developer. All Rights Reserved.
*
* Contributor(s):
*
* Alternatively, the contents of this file may be used under the terms of
* either the GNU General Public License Version 2 or later (the "GPL"), or
* the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
* in which case the provisions of the GPL or the LGPL are applicable instead
* of those above. If you wish to allow use of your version of this file only
* under the terms of either the GPL or the LGPL, and not to allow others to
* use your version of this file under the terms of the MPL, indicate your
* decision by deleting the provisions above and replace them with the notice
* and other provisions required by the GPL or the LGPL. If you do not delete
* the provisions above, a recipient may use your version of this file under
* the terms of any one of the MPL, the GPL or the LGPL.
*
* ***** END LICENSE BLOCK ***** */
#ifdef HAVE_SYSLOG_H
#include <syslog.h>
#else
#include <stdio.h>
#endif
#include <stdarg.h>
#include "log.h"
void vguac_log_info(const char* format, va_list ap) {
#ifdef HAVE_SYSLOG_H
vsyslog(LOG_ERR, format, ap);
#else
fprintf(stderr, "guacamole: info: ");
vfprintf(stderr, format, ap);
fprintf(stderr, "\n");
#endif
}
void vguac_log_error(const char* format, va_list ap) {
#ifdef HAVE_SYSLOG_H
vsyslog(LOG_INFO, format, ap);
#else
fprintf(stderr, "guacamole: error: ");
vfprintf(stderr, format, ap);
fprintf(stderr, "\n");
#endif
}
void guac_log_info(const char* format, ...) {
va_list args;
va_start(args, format);
vguac_log_info(format, args);
va_end(args);
}
void guac_log_error(const char* format, ...) {
va_list args;
va_start(args, format);
vguac_log_error(format, args);
va_end(args);
}

View File

@ -60,181 +60,181 @@
#include <sys/socket.h>
#endif
#include "guacio.h"
#include "socket.h"
#include "protocol.h"
#include "error.h"
ssize_t __guac_write_length_string(GUACIO* io, const char* str) {
ssize_t __guac_socket_write_length_string(guac_socket* io, const char* str) {
return
guac_write_int(io, strlen(str))
|| guac_write_string(io, ".")
|| guac_write_string(io, str);
guac_socket_write_int(io, strlen(str))
|| guac_socket_write_string(io, ".")
|| guac_socket_write_string(io, str);
}
ssize_t __guac_write_length_int(GUACIO* io, int64_t i) {
ssize_t __guac_socket_write_length_int(guac_socket* io, int64_t i) {
char buffer[128];
snprintf(buffer, sizeof(buffer), "%"PRIi64, i);
return __guac_write_length_string(io, buffer);
return __guac_socket_write_length_string(io, buffer);
}
int guac_send_args(GUACIO* io, const char** args) {
int guac_protocol_send_args(guac_socket* io, const char** args) {
int i;
if (guac_write_string(io, "4.args")) return -1;
if (guac_socket_write_string(io, "4.args")) return -1;
for (i=0; args[i] != NULL; i++) {
if (guac_write_string(io, ","))
if (guac_socket_write_string(io, ","))
return -1;
if (__guac_write_length_string(io, args[i]))
if (__guac_socket_write_length_string(io, args[i]))
return -1;
}
return guac_write_string(io, ";");
return guac_socket_write_string(io, ";");
}
int guac_send_name(GUACIO* io, const char* name) {
int guac_protocol_send_name(guac_socket* io, const char* name) {
return
guac_write_string(io, "4.name,")
|| __guac_write_length_string(io, name)
|| guac_write_string(io, ";");
guac_socket_write_string(io, "4.name,")
|| __guac_socket_write_length_string(io, name)
|| guac_socket_write_string(io, ";");
}
int guac_send_size(GUACIO* io, int w, int h) {
int guac_protocol_send_size(guac_socket* io, int w, int h) {
return
guac_write_string(io, "4.size,")
|| __guac_write_length_int(io, w)
|| guac_write_string(io, ",")
|| __guac_write_length_int(io, h)
|| guac_write_string(io, ";");
guac_socket_write_string(io, "4.size,")
|| __guac_socket_write_length_int(io, w)
|| guac_socket_write_string(io, ",")
|| __guac_socket_write_length_int(io, h)
|| guac_socket_write_string(io, ";");
}
int guac_send_clipboard(GUACIO* io, const char* data) {
int guac_protocol_send_clipboard(guac_socket* io, const char* data) {
return
guac_write_string(io, "9.clipboard,")
|| __guac_write_length_string(io, data)
|| guac_write_string(io, ";");
guac_socket_write_string(io, "9.clipboard,")
|| __guac_socket_write_length_string(io, data)
|| guac_socket_write_string(io, ";");
}
int guac_send_error(GUACIO* io, const char* error) {
int guac_protocol_send_error(guac_socket* io, const char* error) {
return
guac_write_string(io, "5.error,")
|| __guac_write_length_string(io, error)
|| guac_write_string(io, ";");
guac_socket_write_string(io, "5.error,")
|| __guac_socket_write_length_string(io, error)
|| guac_socket_write_string(io, ";");
}
int guac_send_sync(GUACIO* io, guac_timestamp timestamp) {
int guac_protocol_send_sync(guac_socket* io, guac_timestamp timestamp) {
return
guac_write_string(io, "4.sync,")
|| __guac_write_length_int(io, timestamp)
|| guac_write_string(io, ";");
guac_socket_write_string(io, "4.sync,")
|| __guac_socket_write_length_int(io, timestamp)
|| guac_socket_write_string(io, ";");
}
int guac_send_copy(GUACIO* io,
int guac_protocol_send_copy(guac_socket* io,
const guac_layer* srcl, int srcx, int srcy, int w, int h,
guac_composite_mode mode, const guac_layer* dstl, int dstx, int dsty) {
return
guac_write_string(io, "4.copy,")
|| __guac_write_length_int(io, srcl->index)
|| guac_write_string(io, ",")
|| __guac_write_length_int(io, srcx)
|| guac_write_string(io, ",")
|| __guac_write_length_int(io, srcy)
|| guac_write_string(io, ",")
|| __guac_write_length_int(io, w)
|| guac_write_string(io, ",")
|| __guac_write_length_int(io, h)
|| guac_write_string(io, ",")
|| __guac_write_length_int(io, mode)
|| guac_write_string(io, ",")
|| __guac_write_length_int(io, dstl->index)
|| guac_write_string(io, ",")
|| __guac_write_length_int(io, dstx)
|| guac_write_string(io, ",")
|| __guac_write_length_int(io, dsty)
|| guac_write_string(io, ";");
guac_socket_write_string(io, "4.copy,")
|| __guac_socket_write_length_int(io, srcl->index)
|| guac_socket_write_string(io, ",")
|| __guac_socket_write_length_int(io, srcx)
|| guac_socket_write_string(io, ",")
|| __guac_socket_write_length_int(io, srcy)
|| guac_socket_write_string(io, ",")
|| __guac_socket_write_length_int(io, w)
|| guac_socket_write_string(io, ",")
|| __guac_socket_write_length_int(io, h)
|| guac_socket_write_string(io, ",")
|| __guac_socket_write_length_int(io, mode)
|| guac_socket_write_string(io, ",")
|| __guac_socket_write_length_int(io, dstl->index)
|| guac_socket_write_string(io, ",")
|| __guac_socket_write_length_int(io, dstx)
|| guac_socket_write_string(io, ",")
|| __guac_socket_write_length_int(io, dsty)
|| guac_socket_write_string(io, ";");
}
int guac_send_rect(GUACIO* io,
int guac_protocol_send_rect(guac_socket* io,
guac_composite_mode mode, const guac_layer* layer,
int x, int y, int width, int height,
int r, int g, int b, int a) {
return
guac_write_string(io, "4.rect,")
|| __guac_write_length_int(io, mode)
|| guac_write_string(io, ",")
|| __guac_write_length_int(io, layer->index)
|| guac_write_string(io, ",")
|| __guac_write_length_int(io, x)
|| guac_write_string(io, ",")
|| __guac_write_length_int(io, y)
|| guac_write_string(io, ",")
|| __guac_write_length_int(io, width)
|| guac_write_string(io, ",")
|| __guac_write_length_int(io, height)
|| guac_write_string(io, ",")
|| __guac_write_length_int(io, r)
|| guac_write_string(io, ",")
|| __guac_write_length_int(io, g)
|| guac_write_string(io, ",")
|| __guac_write_length_int(io, b)
|| guac_write_string(io, ",")
|| __guac_write_length_int(io, a)
|| guac_write_string(io, ";");
guac_socket_write_string(io, "4.rect,")
|| __guac_socket_write_length_int(io, mode)
|| guac_socket_write_string(io, ",")
|| __guac_socket_write_length_int(io, layer->index)
|| guac_socket_write_string(io, ",")
|| __guac_socket_write_length_int(io, x)
|| guac_socket_write_string(io, ",")
|| __guac_socket_write_length_int(io, y)
|| guac_socket_write_string(io, ",")
|| __guac_socket_write_length_int(io, width)
|| guac_socket_write_string(io, ",")
|| __guac_socket_write_length_int(io, height)
|| guac_socket_write_string(io, ",")
|| __guac_socket_write_length_int(io, r)
|| guac_socket_write_string(io, ",")
|| __guac_socket_write_length_int(io, g)
|| guac_socket_write_string(io, ",")
|| __guac_socket_write_length_int(io, b)
|| guac_socket_write_string(io, ",")
|| __guac_socket_write_length_int(io, a)
|| guac_socket_write_string(io, ";");
}
int guac_send_clip(GUACIO* io, const guac_layer* layer,
int guac_protocol_send_clip(guac_socket* io, const guac_layer* layer,
int x, int y, int width, int height) {
return
guac_write_string(io, "4.clip,")
|| __guac_write_length_int(io, layer->index)
|| guac_write_string(io, ",")
|| __guac_write_length_int(io, x)
|| guac_write_string(io, ",")
|| __guac_write_length_int(io, y)
|| guac_write_string(io, ",")
|| __guac_write_length_int(io, width)
|| guac_write_string(io, ",")
|| __guac_write_length_int(io, height)
|| guac_write_string(io, ";");
guac_socket_write_string(io, "4.clip,")
|| __guac_socket_write_length_int(io, layer->index)
|| guac_socket_write_string(io, ",")
|| __guac_socket_write_length_int(io, x)
|| guac_socket_write_string(io, ",")
|| __guac_socket_write_length_int(io, y)
|| guac_socket_write_string(io, ",")
|| __guac_socket_write_length_int(io, width)
|| guac_socket_write_string(io, ",")
|| __guac_socket_write_length_int(io, height)
|| guac_socket_write_string(io, ";");
}
typedef struct __guac_write_png_data {
typedef struct __guac_socket_write_png_data {
GUACIO* io;
guac_socket* io;
char* buffer;
int buffer_size;
int data_size;
} __guac_write_png_data;
} __guac_socket_write_png_data;
cairo_status_t __guac_write_png(void* closure, const unsigned char* data, unsigned int length) {
cairo_status_t __guac_socket_write_png(void* closure, const unsigned char* data, unsigned int length) {
__guac_write_png_data* png_data = (__guac_write_png_data*) closure;
__guac_socket_write_png_data* png_data = (__guac_socket_write_png_data*) closure;
/* Calculate next buffer size */
int next_size = png_data->data_size + length;
@ -262,9 +262,9 @@ cairo_status_t __guac_write_png(void* closure, const unsigned char* data, unsign
}
int __guac_write_length_png(GUACIO* io, cairo_surface_t* surface) {
int __guac_socket_write_length_png(guac_socket* io, cairo_surface_t* surface) {
__guac_write_png_data png_data;
__guac_socket_write_png_data png_data;
int base64_length;
/* Write surface */
@ -274,7 +274,7 @@ int __guac_write_length_png(GUACIO* io, cairo_surface_t* surface) {
png_data.buffer = malloc(png_data.buffer_size);
png_data.data_size = 0;
if (cairo_surface_write_to_png_stream(surface, __guac_write_png, &png_data) != CAIRO_STATUS_SUCCESS) {
if (cairo_surface_write_to_png_stream(surface, __guac_socket_write_png, &png_data) != CAIRO_STATUS_SUCCESS) {
return -1;
}
@ -282,10 +282,10 @@ int __guac_write_length_png(GUACIO* io, cairo_surface_t* surface) {
/* Write length and data */
if (
guac_write_int(io, base64_length)
|| guac_write_string(io, ".")
|| guac_write_base64(io, png_data.buffer, png_data.data_size)
|| guac_flush_base64(io)) {
guac_socket_write_int(io, base64_length)
|| guac_socket_write_string(io, ".")
|| guac_socket_write_base64(io, png_data.buffer, png_data.data_size)
|| guac_socket_flush_base64(io)) {
free(png_data.buffer);
return -1;
}
@ -296,40 +296,40 @@ int __guac_write_length_png(GUACIO* io, cairo_surface_t* surface) {
}
int guac_send_png(GUACIO* io, guac_composite_mode mode,
int guac_protocol_send_png(guac_socket* io, guac_composite_mode mode,
const guac_layer* layer, int x, int y, cairo_surface_t* surface) {
return
guac_write_string(io, "3.png,")
|| __guac_write_length_int(io, mode)
|| guac_write_string(io, ",")
|| __guac_write_length_int(io, layer->index)
|| guac_write_string(io, ",")
|| __guac_write_length_int(io, x)
|| guac_write_string(io, ",")
|| __guac_write_length_int(io, y)
|| guac_write_string(io, ",")
|| __guac_write_length_png(io, surface)
|| guac_write_string(io, ";");
guac_socket_write_string(io, "3.png,")
|| __guac_socket_write_length_int(io, mode)
|| guac_socket_write_string(io, ",")
|| __guac_socket_write_length_int(io, layer->index)
|| guac_socket_write_string(io, ",")
|| __guac_socket_write_length_int(io, x)
|| guac_socket_write_string(io, ",")
|| __guac_socket_write_length_int(io, y)
|| guac_socket_write_string(io, ",")
|| __guac_socket_write_length_png(io, surface)
|| guac_socket_write_string(io, ";");
}
int guac_send_cursor(GUACIO* io, int x, int y, cairo_surface_t* surface) {
int guac_protocol_send_cursor(guac_socket* io, int x, int y, cairo_surface_t* surface) {
return
guac_write_string(io, "6.cursor,")
|| __guac_write_length_int(io, x)
|| guac_write_string(io, ",")
|| __guac_write_length_int(io, y)
|| guac_write_string(io, ",")
|| __guac_write_length_png(io, surface)
|| guac_write_string(io, ";");
guac_socket_write_string(io, "6.cursor,")
|| __guac_socket_write_length_int(io, x)
|| guac_socket_write_string(io, ",")
|| __guac_socket_write_length_int(io, y)
|| guac_socket_write_string(io, ",")
|| __guac_socket_write_length_png(io, surface)
|| guac_socket_write_string(io, ";");
}
int __guac_fill_instructionbuf(GUACIO* io) {
int __guac_fill_instructionbuf(guac_socket* io) {
int retval;
@ -357,7 +357,7 @@ int __guac_fill_instructionbuf(GUACIO* io) {
}
/* Returns new instruction if one exists, or NULL if no more instructions. */
guac_instruction* guac_read_instruction(GUACIO* io, int usec_timeout) {
guac_instruction* guac_protocol_read_instruction(guac_socket* io, int usec_timeout) {
int retval;
int i = io->__instructionbuf_parse_start;
@ -482,7 +482,7 @@ guac_instruction* guac_read_instruction(GUACIO* io, int usec_timeout) {
}
/* No instruction yet? Get more data ... */
retval = guac_select(io, usec_timeout);
retval = guac_socket_select(io, usec_timeout);
if (retval <= 0)
return NULL;
@ -503,28 +503,54 @@ guac_instruction* guac_read_instruction(GUACIO* io, int usec_timeout) {
}
void guac_free_instruction_data(guac_instruction* instruction) {
guac_instruction* guac_protocol_expect_instruction(guac_socket* io, int usec_timeout,
const char* opcode) {
guac_instruction* instruction;
/* Wait for data until timeout */
if (guac_protocol_instructions_waiting(io, usec_timeout) <= 0)
return NULL;
/* Read available instruction */
instruction = guac_protocol_read_instruction(io, usec_timeout);
if (instruction == NULL)
return NULL;
/* Validate instruction */
if (strcmp(instruction->opcode, opcode) != 0) {
guac_error = GUAC_STATUS_BAD_STATE;
guac_instruction_free(instruction);
return NULL;
}
/* Return instruction if valid */
return instruction;
}
void guac_instruction_free_data(guac_instruction* instruction) {
free(instruction->opcode);
if (instruction->argv)
free(instruction->argv);
}
void guac_free_instruction(guac_instruction* instruction) {
guac_free_instruction_data(instruction);
void guac_instruction_free(guac_instruction* instruction) {
guac_instruction_free_data(instruction);
free(instruction);
}
int guac_instructions_waiting(GUACIO* io, int usec_timeout) {
int guac_protocol_instructions_waiting(guac_socket* io, int usec_timeout) {
if (io->__instructionbuf_used_length > 0)
return 1;
return guac_select(io, usec_timeout);
return guac_socket_select(io, usec_timeout);
}
guac_timestamp guac_current_timestamp() {
guac_timestamp guac_protocol_get_timestamp() {
#ifdef HAVE_CLOCK_GETTIME

View File

@ -52,19 +52,19 @@
#include <time.h>
#include <sys/time.h>
#include "guacio.h"
#include "socket.h"
#include "error.h"
char __GUACIO_BASE64_CHARACTERS[64] = {
char __guac_socket_BASE64_CHARACTERS[64] = {
'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J', 'K', 'L', 'M', 'N', 'O', 'P',
'Q', 'R', 'S', 'T', 'U', 'V', 'W', 'X', 'Y', 'Z', 'a', 'b', 'c', 'd', 'e', 'f',
'g', 'h', 'i', 'j', 'k', 'l', 'm', 'n', 'o', 'p', 'q', 'r', 's', 't', 'u', 'v',
'w', 'x', 'y', 'z', '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', '+', '/',
};
GUACIO* guac_open(int fd) {
guac_socket* guac_socket_open(int fd) {
GUACIO* io = malloc(sizeof(GUACIO));
guac_socket* io = malloc(sizeof(guac_socket));
/* If no memory available, return with error */
if (io == NULL) {
@ -96,14 +96,14 @@ GUACIO* guac_open(int fd) {
}
void guac_close(GUACIO* io) {
guac_flush(io);
void guac_socket_close(guac_socket* io) {
guac_socket_flush(io);
free(io->__instructionbuf);
free(io);
}
/* Write bytes, limit rate */
ssize_t __guac_write(GUACIO* io, const char* buf, int count) {
ssize_t __guac_socket_write(guac_socket* io, const char* buf, int count) {
int retval;
@ -140,15 +140,15 @@ int64_t guac_parse_int(const char* str) {
}
ssize_t guac_write_int(GUACIO* io, int64_t i) {
ssize_t guac_socket_write_int(guac_socket* io, int64_t i) {
char buffer[128];
snprintf(buffer, sizeof(buffer), "%"PRIi64, i);
return guac_write_string(io, buffer);
return guac_socket_write_string(io, buffer);
}
ssize_t guac_write_string(GUACIO* io, const char* str) {
ssize_t guac_socket_write_string(guac_socket* io, const char* str) {
char* __out_buf = io->__out_buf;
@ -161,7 +161,7 @@ ssize_t guac_write_string(GUACIO* io, const char* str) {
/* Flush when necessary, return on error */
if (io->__written > 8188 /* sizeof(__out_buf) - 4 */) {
retval = __guac_write(io, __out_buf, io->__written);
retval = __guac_socket_write(io, __out_buf, io->__written);
if (retval < 0)
return retval;
@ -175,29 +175,29 @@ ssize_t guac_write_string(GUACIO* io, const char* str) {
}
ssize_t __guac_write_base64_triplet(GUACIO* io, int a, int b, int c) {
ssize_t __guac_socket_write_base64_triplet(guac_socket* io, int a, int b, int c) {
char* __out_buf = io->__out_buf;
int retval;
/* Byte 1 */
__out_buf[io->__written++] = __GUACIO_BASE64_CHARACTERS[(a & 0xFC) >> 2]; /* [AAAAAA]AABBBB BBBBCC CCCCCC */
__out_buf[io->__written++] = __guac_socket_BASE64_CHARACTERS[(a & 0xFC) >> 2]; /* [AAAAAA]AABBBB BBBBCC CCCCCC */
if (b >= 0) {
__out_buf[io->__written++] = __GUACIO_BASE64_CHARACTERS[((a & 0x03) << 4) | ((b & 0xF0) >> 4)]; /* AAAAAA[AABBBB]BBBBCC CCCCCC */
__out_buf[io->__written++] = __guac_socket_BASE64_CHARACTERS[((a & 0x03) << 4) | ((b & 0xF0) >> 4)]; /* AAAAAA[AABBBB]BBBBCC CCCCCC */
if (c >= 0) {
__out_buf[io->__written++] = __GUACIO_BASE64_CHARACTERS[((b & 0x0F) << 2) | ((c & 0xC0) >> 6)]; /* AAAAAA AABBBB[BBBBCC]CCCCCC */
__out_buf[io->__written++] = __GUACIO_BASE64_CHARACTERS[c & 0x3F]; /* AAAAAA AABBBB BBBBCC[CCCCCC] */
__out_buf[io->__written++] = __guac_socket_BASE64_CHARACTERS[((b & 0x0F) << 2) | ((c & 0xC0) >> 6)]; /* AAAAAA AABBBB[BBBBCC]CCCCCC */
__out_buf[io->__written++] = __guac_socket_BASE64_CHARACTERS[c & 0x3F]; /* AAAAAA AABBBB BBBBCC[CCCCCC] */
}
else {
__out_buf[io->__written++] = __GUACIO_BASE64_CHARACTERS[((b & 0x0F) << 2)]; /* AAAAAA AABBBB[BBBB--]------ */
__out_buf[io->__written++] = __guac_socket_BASE64_CHARACTERS[((b & 0x0F) << 2)]; /* AAAAAA AABBBB[BBBB--]------ */
__out_buf[io->__written++] = '='; /* AAAAAA AABBBB BBBB--[------] */
}
}
else {
__out_buf[io->__written++] = __GUACIO_BASE64_CHARACTERS[((a & 0x03) << 4)]; /* AAAAAA[AA----]------ ------ */
__out_buf[io->__written++] = __guac_socket_BASE64_CHARACTERS[((a & 0x03) << 4)]; /* AAAAAA[AA----]------ ------ */
__out_buf[io->__written++] = '='; /* AAAAAA AA----[------]------ */
__out_buf[io->__written++] = '='; /* AAAAAA AA---- ------[------] */
}
@ -206,7 +206,7 @@ ssize_t __guac_write_base64_triplet(GUACIO* io, int a, int b, int c) {
/* Flush when necessary, return on error */
if (io->__written > 8188 /* sizeof(__out_buf) - 4 */) {
retval = __guac_write(io, __out_buf, io->__written);
retval = __guac_socket_write(io, __out_buf, io->__written);
if (retval < 0)
return retval;
@ -223,7 +223,7 @@ ssize_t __guac_write_base64_triplet(GUACIO* io, int a, int b, int c) {
}
ssize_t __guac_write_base64_byte(GUACIO* io, char buf) {
ssize_t __guac_socket_write_base64_byte(guac_socket* io, char buf) {
int* __ready_buf = io->__ready_buf;
@ -233,7 +233,7 @@ ssize_t __guac_write_base64_byte(GUACIO* io, char buf) {
/* Flush triplet */
if (io->__ready == 3) {
retval = __guac_write_base64_triplet(io, __ready_buf[0], __ready_buf[1], __ready_buf[2]);
retval = __guac_socket_write_base64_triplet(io, __ready_buf[0], __ready_buf[1], __ready_buf[2]);
if (retval < 0)
return retval;
@ -243,7 +243,7 @@ ssize_t __guac_write_base64_byte(GUACIO* io, char buf) {
return 1;
}
ssize_t guac_write_base64(GUACIO* io, const void* buf, size_t count) {
ssize_t guac_socket_write_base64(guac_socket* io, const void* buf, size_t count) {
int retval;
@ -252,7 +252,7 @@ ssize_t guac_write_base64(GUACIO* io, const void* buf, size_t count) {
while (char_buf < end) {
retval = __guac_write_base64_byte(io, *(char_buf++));
retval = __guac_socket_write_base64_byte(io, *(char_buf++));
if (retval < 0)
return retval;
@ -262,13 +262,13 @@ ssize_t guac_write_base64(GUACIO* io, const void* buf, size_t count) {
}
ssize_t guac_flush(GUACIO* io) {
ssize_t guac_socket_flush(guac_socket* io) {
int retval;
/* Flush remaining bytes in buffer */
if (io->__written > 0) {
retval = __guac_write(io, io->__out_buf, io->__written);
retval = __guac_socket_write(io, io->__out_buf, io->__written);
if (retval < 0)
return retval;
@ -279,13 +279,13 @@ ssize_t guac_flush(GUACIO* io) {
}
ssize_t guac_flush_base64(GUACIO* io) {
ssize_t guac_socket_flush_base64(guac_socket* io) {
int retval;
/* Flush triplet to output buffer */
while (io->__ready > 0) {
retval = __guac_write_base64_byte(io, -1);
retval = __guac_socket_write_base64_byte(io, -1);
if (retval < 0)
return retval;
}
@ -295,7 +295,7 @@ ssize_t guac_flush_base64(GUACIO* io) {
}
int guac_select(GUACIO* io, int usec_timeout) {
int guac_socket_select(guac_socket* io, int usec_timeout) {
fd_set fds;
struct timeval timeout;