Initial connect message implementation
authorMichael Jumper <zhangmaike@users.sourceforge.net>
Fri, 26 Nov 2010 01:19:11 +0000 (17:19 -0800)
committerMichael Jumper <zhangmaike@users.sourceforge.net>
Fri, 26 Nov 2010 01:19:11 +0000 (17:19 -0800)
libguac/include/protocol.h
libguac/src/client.c
libguac/src/protocol.c

index 47f3ba3..685a112 100644 (file)
@@ -58,7 +58,19 @@ typedef struct guac_instruction {
 
 
 /**
- * Frees all memory allocated to the given instruction.
+ * Frees all memory allocated to the given instruction opcode
+ * and arguments. The instruction structure itself will not
+ * be freed.
+ *
+ * @param instruction The instruction to free.
+ */
+void guac_free_instruction_data(guac_instruction* instruction);
+
+
+/**
+ * Frees all memory allocated to the given instruction. This
+ * includes freeing memory allocated for the structure
+ * itself.
  *
  * @param instruction The instruction to free.
  */
index 375e00b..ee4ee01 100644 (file)
@@ -76,7 +76,6 @@ guac_client* guac_get_client(int client_fd) {
     GUACIO* io = guac_open(client_fd);
 
     /* Pluggable client */
-    char* protocol;
     char protocol_lib[256] = "libguac_client_";
     
     union {
@@ -86,33 +85,65 @@ guac_client* guac_get_client(int client_fd) {
 
     char* error;
 
-    strcat(protocol_lib, protocol);
-    strcat(protocol_lib, ".so");
+    /* Client arguments */
+    int argc;
+    char** argv;
 
-    /* Load client plugin */
-    client->client_plugin_handle = dlopen(protocol_lib, RTLD_LAZY);
-    if (!(client->client_plugin_handle)) {
-        fprintf(stderr, "Could not open client plugin for protocol \"%s\": %s\n", protocol, dlerror());
-        exit(EXIT_FAILURE);
-    }
+    /* Connect instruction */
+    guac_instruction instruction;
 
-    dlerror(); /* Clear errors */
+    /* Wait for connect instruction */
+    for (;;) {
 
-    /* Get init function */
-    alias.obj = dlsym(client->client_plugin_handle, "guac_client_init");
+        int result = guac_read_instruction(io, &instruction);
+        if (result < 0) {
+            syslog(LOG_ERR, "Error reading instruction while waiting for connect");
+            return NULL;            
+        }
 
-    if ((error = dlerror()) != NULL) {
-        fprintf(stderr, "Could not get guac_client_init in  plugin: %s\n", error);
-        exit(EXIT_FAILURE);
-    }
+        /* Connect instruction read */
+        if (result > 0 && strcmp(instruction.opcode, "connect") == 0) {
+
+            /* Get protocol from message */
+            char* protocol = instruction.argv[0];
+
+            strcat(protocol_lib, protocol);
+            strcat(protocol_lib, ".so");
+
+            /* Create new client */
+            client = __guac_alloc_client(io);
+
+            /* Load client plugin */
+            client->client_plugin_handle = dlopen(protocol_lib, RTLD_LAZY);
+            if (!(client->client_plugin_handle)) {
+                fprintf(stderr, "Could not open client plugin for protocol \"%s\": %s\n", protocol, dlerror());
+                exit(EXIT_FAILURE);
+            }
 
+            dlerror(); /* Clear errors */
 
-    /* Create new client */
-    client = __guac_alloc_client(io);
+            /* Get init function */
+            alias.obj = dlsym(client->client_plugin_handle, "guac_client_init");
+
+            if ((error = dlerror()) != NULL) {
+                fprintf(stderr, "Could not get guac_client_init in plugin: %s\n", error);
+                exit(EXIT_FAILURE);
+            }
+
+            /* Initialize client arguments */
+            argc = instruction.argc;
+            argv = instruction.argv;
+
+            break;
+        }
+
+    }
 
     if (alias.client_init(client, argc, argv) != 0)
         return NULL;
 
+    guac_free_instruction_data(&instruction);
+
     return client;
 
 }
@@ -179,6 +210,7 @@ void guac_start_client(guac_client* client) {
                                ) {
 
                                 syslog(LOG_ERR, "Error handling mouse instruction");
+                                guac_free_instruction_data(&instruction);
                                 return;
 
                             }
@@ -195,6 +227,7 @@ void guac_start_client(guac_client* client) {
                                ) {
 
                                 syslog(LOG_ERR, "Error handling key instruction");
+                                guac_free_instruction_data(&instruction);
                                 return;
 
                             }
@@ -210,6 +243,7 @@ void guac_start_client(guac_client* client) {
                                ) {
 
                                 syslog(LOG_ERR, "Error handling clipboard instruction");
+                                guac_free_instruction_data(&instruction);
                                 return;
 
                             }
@@ -217,9 +251,12 @@ void guac_start_client(guac_client* client) {
 
                     else if (strcmp(instruction.opcode, "disconnect") == 0) {
                         syslog(LOG_INFO, "Client requested disconnect");
+                        guac_free_instruction_data(&instruction);
                         return;
                     }
 
+                    guac_free_instruction_data(&instruction);
+
                 } while ((retval = guac_read_instruction(io, &instruction)) > 0);
 
                 if (retval < 0) {
index e0bb909..a084d7b 100644 (file)
@@ -441,12 +441,15 @@ int guac_read_instruction(GUACIO* io, guac_instruction* parsed_instruction) {
 
 }
 
-void guac_free_instruction(guac_instruction* instruction) {
+void guac_free_instruction_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);
     free(instruction);
 }