From e1e0045085ad8e73ee640b18c58494591a284a18 Mon Sep 17 00:00:00 2001 From: Michael Jumper Date: Mon, 6 Sep 2010 19:46:03 -0700 Subject: [PATCH] guac_message structure, initial parsing support --- guacamole/proxy/guacio.c | 73 ----------------------------- guacamole/proxy/guacio.h | 1 - guacamole/proxy/protocol.c | 96 ++++++++++++++++++++++++++++++++++++++ guacamole/proxy/protocol.h | 14 ++++++ guacamole/proxy/proxy.c | 8 +++- 5 files changed, 116 insertions(+), 76 deletions(-) diff --git a/guacamole/proxy/guacio.c b/guacamole/proxy/guacio.c index df0531765..281636964 100644 --- a/guacamole/proxy/guacio.c +++ b/guacamole/proxy/guacio.c @@ -4,7 +4,6 @@ #include #include #include -#include #include @@ -226,75 +225,3 @@ int guac_select(GUACIO* io, int usec_timeout) { } -int __guac_fill_messagebuf(GUACIO* io) { - - int retval; - - /* Attempt to fill buffer */ - retval = read( - io->fd, - io->messagebuf + io->messagebuf_used_length, - io->messagebuf_size - io->messagebuf_used_length - ); - - if (retval < 0) - return retval; - - io->messagebuf_used_length += retval; - - /* Expand buffer if necessary */ - if (io->messagebuf_used_length > io->messagebuf_size / 2) { - io->messagebuf_size *= 2; - io->messagebuf = realloc(io->messagebuf, io->messagebuf_size); - } - - return retval; - -} - -int guac_read_message(GUACIO* io) { - - int retval; - int i = 0; - - /* Loop until a message is read */ - for (;;) { - - /* Search for end of message */ - for (; i < io->messagebuf_used_length; i++) { - - if (io->messagebuf[i] == ';') { - - char* message = malloc(i+1); - memcpy(message, io->messagebuf, i+1); - message[i] = '\0'; /* Replace semicolon with null terminator. */ - - fprintf(stderr, "RECEIVED MESSAGE: %s\n", message); - - /* Found. Reset buffer */ - memmove(io->messagebuf, io->messagebuf + i + 1, io->messagebuf_used_length - i - 1); - io->messagebuf_used_length -= i + 1; - - /* Done */ - return 0; - } - - } - - /* No message yet? Get more data ... */ - retval = guac_select(io, 1000); - if (retval < 0) - return retval; - - /* Break if descriptor doesn't have enough data */ - if (retval == 0) - return 0; /* SOFT FAIL: No message ... yet, but is still in buffer */ - - retval = __guac_fill_messagebuf(io); - if (retval < 0 && errno != EAGAIN && errno != EWOULDBLOCK) - return retval; - - } - -} - diff --git a/guacamole/proxy/guacio.h b/guacamole/proxy/guacio.h index 7a03cdc86..f7928e8c0 100644 --- a/guacamole/proxy/guacio.h +++ b/guacamole/proxy/guacio.h @@ -27,7 +27,6 @@ ssize_t guac_write_base64(GUACIO* io, const void* buf, size_t count); ssize_t guac_flush_base64(GUACIO* io); ssize_t guac_flush(GUACIO* io); int guac_select(GUACIO* io, int usec_timeout); -int guac_read_message(GUACIO* io); void guac_close(GUACIO* io); #endif diff --git a/guacamole/proxy/protocol.c b/guacamole/proxy/protocol.c index b6455c2a9..ff2d99ea2 100644 --- a/guacamole/proxy/protocol.c +++ b/guacamole/proxy/protocol.c @@ -1,6 +1,7 @@ #include #include #include +#include #include #include "guacio.h" @@ -175,3 +176,98 @@ void guac_send_png(GUACIO* io, int x, int y, png_byte** png_rows, int w, int h) } +int __guac_fill_messagebuf(GUACIO* io) { + + int retval; + + /* Attempt to fill buffer */ + retval = read( + io->fd, + io->messagebuf + io->messagebuf_used_length, + io->messagebuf_size - io->messagebuf_used_length + ); + + if (retval < 0) + return retval; + + io->messagebuf_used_length += retval; + + /* Expand buffer if necessary */ + if (io->messagebuf_used_length > io->messagebuf_size / 2) { + io->messagebuf_size *= 2; + io->messagebuf = realloc(io->messagebuf, io->messagebuf_size); + } + + return retval; + +} + +guac_message* guac_read_message(GUACIO* io) { + + guac_message* parsed_message; + int retval; + int i = 0; + + /* Loop until a message is read */ + for (;;) { + + /* Search for end of message */ + for (; i < io->messagebuf_used_length; i++) { + + if (io->messagebuf[i] == ';') { + + /* Parse new message */ + char* message = malloc(i+1); + memcpy(message, io->messagebuf, i+1); + message[i] = '\0'; /* Replace semicolon with null terminator. */ + + parsed_message = malloc(sizeof(guac_message)); + parsed_message->opcode = message; + parsed_message->argc = 0; + parsed_message->argv = NULL; + + /* Found. Reset buffer */ + memmove(io->messagebuf, io->messagebuf + i + 1, io->messagebuf_used_length - i - 1); + io->messagebuf_used_length -= i + 1; + + /* Done */ + return parsed_message; + } + + } + + /* No message yet? Get more data ... */ + retval = guac_select(io, 1000); + if (retval < 0) + return NULL; + + /* Break if descriptor doesn't have enough data */ + if (retval == 0) + return NULL; /* SOFT FAIL: No message ... yet, but is still in buffer */ + + retval = __guac_fill_messagebuf(io); + if (retval < 0 && errno != EAGAIN && errno != EWOULDBLOCK) + return NULL; + + } + +} + +void guac_free_message(guac_message* message) { + free(message->opcode); + + if (message->argv) + free(message->argv); + + free(message); +} + + +int guac_messages_waiting(GUACIO* io) { + + if (io->messagebuf_used_length > 0) + return 1; + + return guac_select(io, 1000); +} + diff --git a/guacamole/proxy/protocol.h b/guacamole/proxy/protocol.h index edf432809..90d2c6835 100644 --- a/guacamole/proxy/protocol.h +++ b/guacamole/proxy/protocol.h @@ -6,11 +6,25 @@ #include "guacio.h" +typedef struct guac_message { + + char* opcode; + + int argc; + char** argv; + +} guac_message; + + +void guac_free_message(guac_message* message); char* guac_escape_string(const char* str); void guac_send_name(GUACIO* io, const char* name); void guac_send_size(GUACIO* io, int w, int h); void guac_send_copy(GUACIO* io, int srcx, int srcy, int w, int h, int dstx, int dsty); void guac_send_png(GUACIO* io, int x, int y, png_byte** png_rows, int w, int h); +int guac_messages_waiting(GUACIO* io); +guac_message* guac_read_message(GUACIO* io); + #endif diff --git a/guacamole/proxy/proxy.c b/guacamole/proxy/proxy.c index 6285a68cf..966f4d8ec 100644 --- a/guacamole/proxy/proxy.c +++ b/guacamole/proxy/proxy.c @@ -179,9 +179,13 @@ void proxy(int client_fd) { } - wait_result = guac_select(io, 2000); + wait_result = guac_messages_waiting(io); if (wait_result > 0) { - guac_read_message(io); + guac_message* message = guac_read_message(io); + if (message) { + fprintf(stderr, "NEW READ MESSAGE: %s\n", message->opcode); + guac_free_message(message); + } } }