+void guacd_handle_connection_xml(int fd, char* xmlconfig) {
+
+ guac_client* client = NULL;
+ guac_client_plugin* plugin = NULL;
+ char ** protocol_argv = NULL;
+ int protocol_argc = 0;
+ xmlDoc * pDoc = NULL;
+ char * protocol = NULL;
+ guac_socket* socket = NULL;
+
+ if (NULL == (socket = guac_socket_open(fd))) {
+ guacd_log_guac_error("Could not open socket");
+ goto error;
+ }
+
+ if (NULL == (pDoc = xmlParseMemory (xmlconfig, strlen(xmlconfig)))) {
+ guacd_log_guac_error("Could not parse XML");
+ goto error;
+ }
+
+ if (NULL == (protocol = xml_get_string(pDoc, "/params/protocol"))) {
+ guacd_log_guac_error("Could not parse XML");
+ goto error;
+ }
+
+ guacd_log_info("Opening protocol '%s'", protocol);
+
+ /* Get plugin from protocol in select */
+ if (NULL == (plugin = guac_client_plugin_open(protocol))) {
+ guacd_log_guac_error("Error loading client plugin");
+ goto error;
+ }
+
+ /* Now parse protocol strings */
+ const char ** arg;
+ const char * params = "/params/";
+ int lparams = strlen(params);
+ for (arg = plugin->args; *arg && **arg; arg++)
+ protocol_argc++;
+ if (NULL == (protocol_argv = calloc(sizeof(char *), protocol_argc+1))) {
+ guacd_log_guac_error("Cannot allocate protocol arguments");
+ goto error;
+ }
+
+ int i;
+ for (i=0; i<protocol_argc; i++) {
+ const char * p;
+ char * q;
+ int l = strlen(plugin->args[i]);
+ char * argname = malloc(lparams+l+1);
+ if (!argname) {
+ guacd_log_guac_error("Error duplicating argument list");
+ goto error;
+ }
+ strncpy(argname, params, lparams);
+ /* replace non-alpha characters by '_' for XML */
+ for (p = plugin->args[i], q = argname+lparams; *p; p++, q++)
+ *q = isalnum(*p)?*p:'_';
+ *q='\0';
+ char * value = xml_get_string(pDoc, argname);
+ if (!value)
+ value = strdup("");
+ guacd_log_info("Argument '%s' set to '%s'", plugin->args[i], value);
+ protocol_argv[i]=value;
+ }
+
+ guacd_log_info("Starting protocol %s, %d arguments", protocol, protocol_argc);
+
+ /* Load and init client */
+ if (NULL == (client = guac_client_plugin_get_client(plugin, socket,
+ protocol_argc, protocol_argv,
+ guacd_client_log_info, guacd_client_log_error))) {
+ guacd_log_guac_error("Error instantiating client");
+ goto error;
+ }
+
+ /* Start client threads */
+ guacd_log_info("Starting client");
+ if (guacd_client_start(client))
+ guacd_log_error("Client finished abnormally");
+ else
+ guacd_log_info("Client finished normally");
+
+ error:
+ /* Clean up */
+ if (client)
+ guac_client_free(client);
+
+ if (plugin && guac_client_plugin_close(plugin))
+ guacd_log_error("Error closing client plugin");
+
+ if (protocol_argv) {
+ char **parg;
+ for (parg = protocol_argv ; *parg; parg++)
+ free(*parg);
+ free(protocol_argv);
+ }
+ if (pDoc)
+ xmlFreeDoc(pDoc);
+ if (protocol)
+ free (protocol);
+ if (socket)
+ guac_socket_close(socket);
+
+ return;
+}
+