mirror of
https://github.com/gyurix1968/guacamole-client.git
synced 2025-09-06 21:27:40 +00:00
Beginnings of threads instead of processes, pluggable client specified at command line
This commit is contained in:
@@ -184,7 +184,7 @@ guac_client* __guac_alloc_client(GUACIO* io) {
|
||||
}
|
||||
|
||||
|
||||
guac_client* guac_get_client(int client_fd, guac_client_registry_node* registry, guac_client_init_handler* client_init, const char* hostname, int port) {
|
||||
guac_client* guac_get_client(int client_fd, guac_client_registry_node* registry, guac_client_init_handler* client_init, int argc, char** argv) {
|
||||
|
||||
guac_client* client;
|
||||
GUACIO* io = guac_open(client_fd);
|
||||
@@ -214,7 +214,7 @@ 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);
|
||||
client_init(client, argc, argv);
|
||||
break;
|
||||
}
|
||||
|
||||
|
@@ -78,7 +78,7 @@ struct guac_client {
|
||||
* @code
|
||||
* void handle_messages(guac_client* client);
|
||||
*
|
||||
* void guac_client_init(guac_client* client) {
|
||||
* void guac_client_init(guac_client* client, int argc, char** argv) {
|
||||
* client->handle_messages = handle_messages;
|
||||
* }
|
||||
* @endcode
|
||||
@@ -105,7 +105,7 @@ struct guac_client {
|
||||
* @code
|
||||
* void mouse_handler(guac_client* client, int x, int y, int button_mask);
|
||||
*
|
||||
* void guac_client_init(guac_client* client) {
|
||||
* void guac_client_init(guac_client* client, int argc, char** argv) {
|
||||
* client->mouse_handler = mouse_handler;
|
||||
* }
|
||||
* @endcode
|
||||
@@ -123,7 +123,7 @@ struct guac_client {
|
||||
* @code
|
||||
* void key_handler(guac_client* client, int keysym, int pressed);
|
||||
*
|
||||
* void guac_client_init(guac_client* client) {
|
||||
* void guac_client_init(guac_client* client, int argc, char** argv) {
|
||||
* client->key_handler = key_handler;
|
||||
* }
|
||||
* @endcode
|
||||
@@ -144,7 +144,7 @@ struct guac_client {
|
||||
* @code
|
||||
* void clipboard_handler(guac_client* client, char* copied);
|
||||
*
|
||||
* void guac_client_init(guac_client* client) {
|
||||
* void guac_client_init(guac_client* client, int argc, char** argv) {
|
||||
* client->clipboard_handler = clipboard_handler;
|
||||
* }
|
||||
* @endcode
|
||||
@@ -164,7 +164,7 @@ struct guac_client {
|
||||
* @code
|
||||
* void free_handler(guac_client* client);
|
||||
*
|
||||
* void guac_client_init(guac_client* client) {
|
||||
* void guac_client_init(guac_client* client, int argc, char** argv) {
|
||||
* client->free_handler = free_handler;
|
||||
* }
|
||||
* @endcode
|
||||
@@ -173,7 +173,7 @@ struct guac_client {
|
||||
|
||||
};
|
||||
|
||||
typedef void guac_client_init_handler(guac_client* client, const char* hostname, int port);
|
||||
typedef void guac_client_init_handler(guac_client* client, int argc, char** argv);
|
||||
|
||||
/**
|
||||
* Initialize and return a new guac_client using the specified client init handler (guac_client_init_handler).
|
||||
@@ -184,11 +184,11 @@ typedef void guac_client_init_handler(guac_client* client, const char* hostname,
|
||||
* web-client tunnel.
|
||||
* @param client_init Function pointer to the client init handler which will initialize the new guac_client
|
||||
* when called. The given hostname and port will be passed to this handler.
|
||||
* @param hostname The hostname of the host that the proxy client should connect to.
|
||||
* @param port The port of the host that the proxy client should connect to.
|
||||
* @return A pointer to the newly initialized client.
|
||||
* @param argc The number of arguments being passed to this client.
|
||||
* @param argv The arguments being passed to this client.
|
||||
* @return A pointer to the newly initialized (or found) client.
|
||||
*/
|
||||
guac_client* guac_get_client(int client_fd, guac_client_registry_node* registry, guac_client_init_handler* client_init, const char* hostname, int port);
|
||||
guac_client* guac_get_client(int client_fd, guac_client_registry_node* registry, guac_client_init_handler* client_init, int argc, char** argv);
|
||||
|
||||
/**
|
||||
* Enter the main network message handling loop for the given client.
|
||||
|
@@ -28,17 +28,58 @@
|
||||
|
||||
#include "client.h"
|
||||
|
||||
|
||||
typedef struct client_thread_data {
|
||||
|
||||
int fd;
|
||||
guac_client_init_handler* client_init;
|
||||
guac_client_registry_node* registry;
|
||||
|
||||
int argc;
|
||||
char** argv;
|
||||
|
||||
} client_thread_data;
|
||||
|
||||
|
||||
void* start_client_thread(void* data) {
|
||||
|
||||
guac_client* client;
|
||||
client_thread_data* thread_data = (client_thread_data*) data;
|
||||
|
||||
fprintf(stderr, "[guacamole] spawning client\n");
|
||||
|
||||
/* Load and start client */
|
||||
client = guac_get_client(thread_data->fd, thread_data->registry, thread_data->client_init, thread_data->argc, thread_data->argv);
|
||||
guac_start_client(client);
|
||||
|
||||
/* FIXME: Need to free client, but only if the client is not
|
||||
* being used. This line will be reached if handoff occurs
|
||||
*/
|
||||
guac_free_client(client, thread_data->registry);
|
||||
|
||||
/* Close socket */
|
||||
if (close(thread_data->fd) < 0) {
|
||||
perror("Error closing connection");
|
||||
free(data);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
fprintf(stderr, "[guacamole] client finished\n");
|
||||
free(data);
|
||||
return NULL;
|
||||
|
||||
}
|
||||
|
||||
int main(int argc, char* argv[]) {
|
||||
|
||||
/* Client registry */
|
||||
guac_client_registry_node* registry;
|
||||
|
||||
/* Pluggable client */
|
||||
guac_client* client;
|
||||
void* client_plugin_handle;
|
||||
|
||||
union {
|
||||
void (*client_init)(guac_client* client, const char* hostname, int port);
|
||||
guac_client_init_handler* client_init;
|
||||
void* obj;
|
||||
} alias;
|
||||
|
||||
@@ -55,18 +96,23 @@ int main(int argc, char* argv[]) {
|
||||
pid_t client_pid ;
|
||||
|
||||
int listen_port;
|
||||
const char* connect_host;
|
||||
int connect_port;
|
||||
|
||||
if (argc < 4) {
|
||||
fprintf(stderr, "USAGE: %s LISTENPORT CONNECTHOST CONNECTPORT\n", argv[0]);
|
||||
int client_argc;
|
||||
char** client_argv;
|
||||
|
||||
char protocol_lib[256] = "libguac_client_";
|
||||
|
||||
if (argc < 3) {
|
||||
fprintf(stderr, "USAGE: %s LISTENPORT PROTOCOL [PROTOCOL OPTIONS]\n", argv[0]);
|
||||
return 1;
|
||||
}
|
||||
|
||||
listen_port = atoi(argv[1]);
|
||||
connect_host = argv[2];
|
||||
connect_port = atoi(argv[3]);
|
||||
strcat(protocol_lib, argv[2]);
|
||||
strcat(protocol_lib, ".so");
|
||||
|
||||
client_argc = argc - 3;
|
||||
client_argv = &(argv[3]);
|
||||
|
||||
/* Get binding address */
|
||||
memset(&server_addr, 0, sizeof(server_addr)); /* Zero struct */
|
||||
@@ -91,7 +137,7 @@ int main(int argc, char* argv[]) {
|
||||
fprintf(stderr, "[guacamole] loading pluggable client\n");
|
||||
|
||||
/* Load client plugin */
|
||||
client_plugin_handle = dlopen("libguac_client_vnc.so", RTLD_LAZY);
|
||||
client_plugin_handle = dlopen(protocol_lib, RTLD_LAZY);
|
||||
if (!client_plugin_handle) {
|
||||
fprintf(stderr, "[guacamole] could not open client plugin: %s\n", dlerror());
|
||||
return 2;
|
||||
@@ -109,7 +155,7 @@ int main(int argc, char* argv[]) {
|
||||
|
||||
|
||||
|
||||
fprintf(stderr, "[guacamole] listening on port %i, forwarding to %s:%i\n", listen_port, connect_host, connect_port);
|
||||
fprintf(stderr, "[guacamole] listening on port %i\n", listen_port);
|
||||
|
||||
/* Allocate registry */
|
||||
registry = guac_create_client_registry();
|
||||
@@ -117,6 +163,8 @@ int main(int argc, char* argv[]) {
|
||||
/* Daemon loop */
|
||||
for (;;) {
|
||||
|
||||
client_thread_data* data;
|
||||
|
||||
/* Listen for connections */
|
||||
if (listen(socket_fd, 5) < 0) {
|
||||
perror("Error listening on socket");
|
||||
@@ -141,25 +189,16 @@ int main(int argc, char* argv[]) {
|
||||
/* In child ... */
|
||||
else if (client_pid == 0) {
|
||||
|
||||
fprintf(stderr, "[guacamole] spawning client\n");
|
||||
data = malloc(sizeof(client_thread_data));
|
||||
|
||||
/* Load and start client */
|
||||
client = guac_get_client(connected_socket_fd, registry, alias.client_init, connect_host, connect_port);
|
||||
guac_start_client(client);
|
||||
data->fd = connected_socket_fd;
|
||||
data->client_init = alias.client_init;
|
||||
data->registry = registry;
|
||||
data->argc = client_argc;
|
||||
data->argv = client_argv;
|
||||
|
||||
/* FIXME: Need to free client, but only if the client is not
|
||||
* being used. This line will be reached if handoff occurs
|
||||
*/
|
||||
guac_free_client(client, registry);
|
||||
start_client_thread(data);
|
||||
|
||||
/* Close socket */
|
||||
if (close(connected_socket_fd) < 0) {
|
||||
perror("Error closing connection");
|
||||
return 3;
|
||||
}
|
||||
|
||||
fprintf(stderr, "[guacamole] client finished\n");
|
||||
return 0;
|
||||
}
|
||||
|
||||
}
|
||||
|
@@ -264,7 +264,7 @@ void vnc_guac_client_free_handler(guac_client* client) {
|
||||
}
|
||||
|
||||
|
||||
void guac_client_init(guac_client* client, const char* hostname, int port) {
|
||||
void guac_client_init(guac_client* client, int argc, char** argv) {
|
||||
|
||||
char* hostname_copy;
|
||||
|
||||
@@ -294,10 +294,10 @@ void guac_client_init(guac_client* client, const char* hostname, int port) {
|
||||
|
||||
/* Connect */
|
||||
hostname_copy = malloc(1024);
|
||||
strncpy(hostname_copy, hostname, 1024);
|
||||
strncpy(hostname_copy, argv[0], 1024);
|
||||
|
||||
rfb_client->serverHost = hostname_copy;
|
||||
rfb_client->serverPort = port;
|
||||
rfb_client->serverPort = atoi(argv[1]);
|
||||
|
||||
rfbInitClient(rfb_client, NULL, NULL);
|
||||
|
||||
|
Reference in New Issue
Block a user