diff --git a/libguac/include/protocol.h b/libguac/include/protocol.h index 685a112b..e59167f1 100644 --- a/libguac/include/protocol.h +++ b/libguac/include/protocol.h @@ -95,6 +95,15 @@ char* guac_escape_string(const char* str); */ char* guac_unescape_string_inplace(char* str); +/** + * Sends an args instruction over the given GUACIO connection. Each + * argument name will be automatically escaped for transmission. + * + * @param io The GUACIO connection to use. + * @param args The NULL-terminated array of argument names (strings). + */ +void guac_send_args(GUACIO* io, const char** name); + /** * Sends a name instruction over the given GUACIO connection. The * name given will be automatically escaped for transmission. diff --git a/libguac/src/client.c b/libguac/src/client.c index 4e9e3bb8..fa4cf16d 100644 --- a/libguac/src/client.c +++ b/libguac/src/client.c @@ -85,27 +85,30 @@ guac_client* guac_get_client(int client_fd) { char* error; + /* Client args description */ + const char** client_args; + /* Client arguments */ int argc; char** argv; - /* Connect instruction */ + /* Instruction */ guac_instruction instruction; - /* Wait for connect instruction */ + /* Wait for select instruction */ for (;;) { int result = guac_read_instruction(io, &instruction); if (result < 0) { - syslog(LOG_ERR, "Error reading instruction while waiting for connect"); + syslog(LOG_ERR, "Error reading instruction while waiting for select"); guac_close(io); return NULL; } - /* Connect instruction read */ + /* Select instruction read */ if (result > 0) { - if (strcmp(instruction.opcode, "connect") == 0) { + if (strcmp(instruction.opcode, "select") == 0) { /* Get protocol from message */ char* protocol = instruction.argv[0]; @@ -141,6 +144,47 @@ guac_client* guac_get_client(int client_fd) { return NULL; } + /* Get usage strig */ + client_args = (const char**) dlsym(client->client_plugin_handle, "GUAC_CLIENT_ARGS"); + + if ((error = dlerror()) != NULL) { + syslog(LOG_ERR, "Could not get GUAC_CLIENT_ in plugin: %s\n", error); + guac_send_error(io, "Invalid server-side client plugin."); + guac_flush(io); + guac_close(io); + guac_free_instruction_data(&instruction); + return NULL; + } + + /* Send args */ + guac_send_args(io, client_args); + guac_flush(io); + + guac_free_instruction_data(&instruction); + break; + + } /* end if select */ + + guac_free_instruction_data(&instruction); + } + + } + + /* Wait for connect instruction */ + for (;;) { + + int result = guac_read_instruction(io, &instruction); + if (result < 0) { + syslog(LOG_ERR, "Error reading instruction while waiting for connect"); + guac_close(io); + return NULL; + } + + /* Connect instruction read */ + if (result > 0) { + + if (strcmp(instruction.opcode, "connect") == 0) { + /* Initialize client arguments */ argc = instruction.argc; argv = instruction.argv; diff --git a/libguac/src/protocol.c b/libguac/src/protocol.c index a084d7b7..4d3110e6 100644 --- a/libguac/src/protocol.c +++ b/libguac/src/protocol.c @@ -134,6 +134,27 @@ char* guac_unescape_string_inplace(char* str) { } +void guac_send_args(GUACIO* io, const char** args) { + + int i; + + guac_write_string(io, "args:"); + + for (i=0; args[i] != NULL; i++) { + + if (i > 0) + guac_write_string(io, ","); + + char* escaped = guac_escape_string(args[i]); + guac_write_string(io, escaped); + free(escaped); + + } + + guac_write_string(io, ";"); + +} + void guac_send_name(GUACIO* io, const char* name) { char* escaped = guac_escape_string(name);