From 49131fae1bf709beb20391f632d4cc0158034c2e Mon Sep 17 00:00:00 2001 From: Michael Jumper Date: Sat, 18 Sep 2010 02:11:51 -0700 Subject: [PATCH] Handoff implemented ... but registry is not shared because we're using processes instead of threads, hence it doesn't work. --- guacamole/libguac/Makefile | 2 +- guacamole/libguac/client.c | 51 +++++++++++++++++++++++---- guacamole/libguac/guacio.c | 8 ----- guacamole/libguac/include/guacio.h | 1 - guacamole/libguac/include/protocol.h | 1 + guacamole/libguac/protocol.c | 52 ++++++++++++++++++++++++++++ 6 files changed, 98 insertions(+), 17 deletions(-) diff --git a/guacamole/libguac/Makefile b/guacamole/libguac/Makefile index a25bad3e0..76d826524 100644 --- a/guacamole/libguac/Makefile +++ b/guacamole/libguac/Makefile @@ -1,5 +1,5 @@ -CFLAGS=-O2 -fPIC -pedantic -Wall -Werror -Iinclude +CFLAGS=-g -fPIC -pedantic -Wall -Werror -Iinclude LDFLAGS=-lpng -luuid .PHONY: clean doc diff --git a/guacamole/libguac/client.c b/guacamole/libguac/client.c index 63dc374d5..9234c4a49 100644 --- a/guacamole/libguac/client.c +++ b/guacamole/libguac/client.c @@ -177,7 +177,8 @@ guac_client* __guac_alloc_client(GUACIO* io) { /* Init new client */ client->io = io; - uuid_generate(client->uuid); + uuid_generate(client->uuid); + strncpy((char*) client->uuid, "0123456789ABCDEF", 16); return client; } @@ -204,14 +205,53 @@ guac_client* guac_get_client(int client_fd, guac_client_registry_node* registry, client = __guac_alloc_client(io); /* Register client */ - if (registry) + if (registry) { guac_register_client(registry, client); - /* Send UUID to web-client */ - guac_send_uuid(io, client->uuid); + /* Send UUID to web-client */ + guac_send_uuid(io, client->uuid); + guac_flush(client->io); + } + + /* FIXME: hostname and port should not be required. Should be made available in some sort of client-contained argc/argv, specified after the protocol on the commandline */ + client_init(client, hostname, port); break; } + if (strcmp(instruction.opcode, "handoff") == 0) { + + fprintf(stderr, "HANDOFF!\n"); + + /* Get UUID from instruction */ + guac_decode_base64_inplace(instruction.argv[0]); + + fprintf(stderr, "Decoded.\n"); + + /* Find client associated with UUID*/ + if (registry) { + fprintf(stderr, "Locating.\n"); + client = guac_find_client(registry, (unsigned char*) "0123456789ABCDEF" /*instruction.argv[0]*/); + fprintf(stderr, "@%p\n", (void*) client); + + /* Transfer client I/O to new connection, if client exists */ + if (client) { + + int fd = client->io->fd; + guac_close(client->io); + close(fd); + + client->io = io; + break; + } + /* TODO: Send error if client not found */ + + fprintf(stderr, "OK\n"); + } + + /* TODO: Send error if handoff sent to client without registry */ + + } + } if (retval < 0) @@ -221,9 +261,6 @@ guac_client* guac_get_client(int client_fd, guac_client_registry_node* registry, } - /* FIXME: hostname and port should not be required. Should be made available in some sort of client-contained argc/argv, specified after the protocol on the commandline */ - client_init(client, hostname, port); - guac_flush(client->io); return client; } diff --git a/guacamole/libguac/guacio.c b/guacamole/libguac/guacio.c index 8bf04b7ce..3deff95f9 100644 --- a/guacamole/libguac/guacio.c +++ b/guacamole/libguac/guacio.c @@ -55,14 +55,6 @@ GUACIO* guac_open(int fd) { } -void guac_transfer(GUACIO* io, int fd) { - - guac_flush(io); - close(fd); - io->fd = fd; - -} - void guac_close(GUACIO* io) { guac_flush(io); free(io); diff --git a/guacamole/libguac/include/guacio.h b/guacamole/libguac/include/guacio.h index c1c9d7e8d..c00119a2f 100644 --- a/guacamole/libguac/include/guacio.h +++ b/guacamole/libguac/include/guacio.h @@ -42,7 +42,6 @@ typedef struct GUACIO { } GUACIO; GUACIO* guac_open(int fd); -void guac_transfer(GUACIO* io, int fd); ssize_t guac_write_int(GUACIO* io, unsigned int i); ssize_t guac_write_string(GUACIO* io, const char* str); ssize_t guac_write_base64(GUACIO* io, const void* buf, size_t count); diff --git a/guacamole/libguac/include/protocol.h b/guacamole/libguac/include/protocol.h index 1bfc8515e..e54d834ab 100644 --- a/guacamole/libguac/include/protocol.h +++ b/guacamole/libguac/include/protocol.h @@ -38,6 +38,7 @@ typedef struct guac_instruction { void guac_free_instruction(guac_instruction* instruction); char* guac_escape_string(const char* str); char* guac_unescape_string_inplace(char* str); +char* guac_decode_base64_inplace(char* str); void guac_send_name(GUACIO* io, const char* name); void guac_send_error(GUACIO* io, const char* error); void guac_send_clipboard(GUACIO* io, const char* data); diff --git a/guacamole/libguac/protocol.c b/guacamole/libguac/protocol.c index f09371e1d..b5c81ca74 100644 --- a/guacamole/libguac/protocol.c +++ b/guacamole/libguac/protocol.c @@ -148,6 +148,58 @@ void guac_send_name(GUACIO* io, const char* name) { } +unsigned char __guac_get_base64_char_value(char c) { + + if (c >= 'A' && c <= 'Z') + return c - 'A'; + + if (c >= 'a' && c <= 'z') + return c - 'a' + 26; + + if (c >= '0' && c <= '9') + return c - '0' + 52; + + if (c == '+') + return 62; + + if (c == '/') + return 63; + + return 0; + +} + +char* guac_decode_base64_inplace(char* str) { + + char* from; + char* to; + + from = to = str; + for (;;) { + + unsigned char v1, v2, v3, v4; + char first = *(from++); + + if (first == '\0') + break; + + v1 = __guac_get_base64_char_value(first); + v2 = __guac_get_base64_char_value(*(from++)); + v3 = __guac_get_base64_char_value(*(from++)); + v4 = __guac_get_base64_char_value(*(from++)); + + *(to++) = (char) ((v1 << 2) | (v2 >> 4)); + *(to++) = (char) ((v2 << 4) | (v3 >> 2)); + *(to++) = (char) ((v3 << 6) | v4); + + } + + *to = '\0'; + + return str; + +} + void guac_send_size(GUACIO* io, int w, int h) { guac_write_string(io, "size:"); guac_write_int(io, w);