Implement pipe instruction and handlers.

This commit is contained in:
Michael Jumper 2014-02-27 16:44:56 -08:00
parent a6a72d950c
commit d0d34a63b9
5 changed files with 105 additions and 0 deletions

View File

@ -39,6 +39,7 @@ __guac_instruction_handler_mapping __guac_instruction_handler_map[] = {
{"disconnect", __guac_handle_disconnect}, {"disconnect", __guac_handle_disconnect},
{"size", __guac_handle_size}, {"size", __guac_handle_size},
{"file", __guac_handle_file}, {"file", __guac_handle_file},
{"pipe", __guac_handle_pipe},
{"ack", __guac_handle_ack}, {"ack", __guac_handle_ack},
{"blob", __guac_handle_blob}, {"blob", __guac_handle_blob},
{"end", __guac_handle_end}, {"end", __guac_handle_end},
@ -153,6 +154,43 @@ int __guac_handle_file(guac_client* client, guac_instruction* instruction) {
return 0; return 0;
} }
int __guac_handle_pipe(guac_client* client, guac_instruction* instruction) {
/* Pull corresponding stream */
int stream_index = atoi(instruction->argv[0]);
guac_stream* stream;
/* Validate stream index */
if (stream_index < 0 || stream_index >= GUAC_CLIENT_MAX_STREAMS) {
guac_stream dummy_stream;
dummy_stream.index = stream_index;
guac_protocol_send_ack(client->socket, &dummy_stream,
"Invalid stream index", GUAC_PROTOCOL_STATUS_INVALID_PARAMETER);
return 0;
}
/* Initialize stream */
stream = &(client->__input_streams[stream_index]);
stream->index = stream_index;
stream->data = NULL;
/* If supported, call handler */
if (client->pipe_handler)
return client->pipe_handler(
client,
stream,
instruction->argv[1], /* mimetype */
instruction->argv[2] /* name */
);
/* Otherwise, abort */
guac_protocol_send_ack(client->socket, stream,
"Named pipes unsupported", GUAC_PROTOCOL_STATUS_UNSUPPORTED);
return 0;
}
int __guac_handle_ack(guac_client* client, guac_instruction* instruction) { int __guac_handle_ack(guac_client* client, guac_instruction* instruction) {
guac_stream* stream; guac_stream* stream;

View File

@ -94,6 +94,13 @@ int __guac_handle_clipboard(guac_client* client, guac_instruction* instruction);
*/ */
int __guac_handle_file(guac_client* client, guac_instruction* instruction); int __guac_handle_file(guac_client* client, guac_instruction* instruction);
/**
* Internal initial handler for the pipe instruction. When a pipe instruction
* is received, this handler will be called. The client's pipe handler will
* be invoked if defined.
*/
int __guac_handle_pipe(guac_client* client, guac_instruction* instruction);
/** /**
* Internal initial handler for the ack instruction. When a ack instruction * Internal initial handler for the ack instruction. When a ack instruction
* is received, this handler will be called. The client's ack handler will * is received, this handler will be called. The client's ack handler will

View File

@ -85,6 +85,12 @@ typedef int guac_client_size_handler(guac_client* client,
typedef int guac_client_file_handler(guac_client* client, guac_stream* stream, typedef int guac_client_file_handler(guac_client* client, guac_stream* stream,
char* mimetype, char* filename); char* mimetype, char* filename);
/**
* Handler for Guacamole pipe events.
*/
typedef int guac_client_pipe_handler(guac_client* client, guac_stream* stream,
char* mimetype, char* name);
/** /**
* Handler for Guacamole stream blob events. * Handler for Guacamole stream blob events.
*/ */
@ -402,6 +408,25 @@ struct guac_client {
*/ */
guac_client_file_handler* file_handler; guac_client_file_handler* file_handler;
/**
* Handler for pipe events sent by the Guacamole web-client.
*
* The handler takes a guac_stream which contains the stream index and
* will persist through the duration of the transfer, the mimetype of
* the data being transferred, and the pipe name.
*
* Example:
* @code
* int pipe_handler(guac_client* client, guac_stream* stream,
* char* mimetype, char* name);
*
* int guac_client_init(guac_client* client, int argc, char** argv) {
* client->pipe_handler = pipe_handler;
* }
* @endcode
*/
guac_client_pipe_handler* pipe_handler;
/** /**
* Handler for ack events sent by the Guacamole web-client. * Handler for ack events sent by the Guacamole web-client.
* *

View File

@ -412,6 +412,21 @@ int guac_protocol_send_audio(guac_socket* socket, const guac_stream* stream,
int guac_protocol_send_file(guac_socket* socket, const guac_stream* stream, int guac_protocol_send_file(guac_socket* socket, const guac_stream* stream,
const char* mimetype, const char* name); const char* mimetype, const char* name);
/**
* Sends a pipe 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 socket The guac_socket connection to use.
* @param stream The stream to use.
* @param mimetype The mimetype of the data being sent.
* @param name An arbitrary name uniquely identifying this pipe.
* @return Zero on success, non-zero on error.
*/
int guac_protocol_send_pipe(guac_socket* socket, const guac_stream* stream,
const char* mimetype, const char* name);
/** /**
* Writes a block of data to the currently in-progress blob which was already * Writes a block of data to the currently in-progress blob which was already
* created. * created.

View File

@ -982,6 +982,26 @@ int guac_protocol_send_nop(guac_socket* socket) {
} }
int guac_protocol_send_pipe(guac_socket* socket, const guac_stream* stream,
const char* mimetype, const char* name) {
int ret_val;
guac_socket_instruction_begin(socket);
ret_val =
guac_socket_write_string(socket, "4.pipe,")
|| __guac_socket_write_length_int(socket, stream->index)
|| guac_socket_write_string(socket, ",")
|| __guac_socket_write_length_string(socket, mimetype)
|| guac_socket_write_string(socket, ",")
|| __guac_socket_write_length_string(socket, name)
|| guac_socket_write_string(socket, ";");
guac_socket_instruction_end(socket);
return ret_val;
}
int guac_protocol_send_png(guac_socket* socket, guac_composite_mode mode, int guac_protocol_send_png(guac_socket* socket, guac_composite_mode mode,
const guac_layer* layer, int x, int y, cairo_surface_t* surface) { const guac_layer* layer, int x, int y, cairo_surface_t* surface) {