Conversion to new naming conventions, partial logging.
This commit is contained in:
parent
c6d1916afa
commit
682344f778
@ -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
|
||||
|
||||
|
@ -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.
|
||||
*/
|
||||
|
@ -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
|
@ -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
|
||||
|
@ -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
|
||||
|
@ -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 */
|
||||
|
@ -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);
|
||||
|
||||
}
|
||||
|
@ -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
|
||||
|
||||
|
@ -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;
|
Loading…
Reference in New Issue
Block a user