From fdc39509763f7d60429b903474916684da6653eb Mon Sep 17 00:00:00 2001 From: Mike Gabriel Date: Sun, 2 Nov 2014 20:44:45 +0100 Subject: Imported Upstream version 1.0.0 --- src/server.c | 292 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 292 insertions(+) create mode 100644 src/server.c (limited to 'src/server.c') diff --git a/src/server.c b/src/server.c new file mode 100644 index 0000000..2f36898 --- /dev/null +++ b/src/server.c @@ -0,0 +1,292 @@ +/* + * Copyright © 2012 Canonical Ltd. + * + * This program is free software: you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 3, as + * published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranties of + * MERCHANTABILITY, SATISFACTORY QUALITY, or FITNESS FOR A PARTICULAR + * PURPOSE. See the GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License along + * with this program. If not, see . + * + * Author: Ted Gould + */ + +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + +#include "server.h" +#include "defines.h" +#include "citrix-server.h" +#include "rdp-server.h" +#include "uccs-server.h" + +static void server_class_init (ServerClass *klass); +static void server_init (Server *self); +static void server_dispose (GObject *object); +static void server_finalize (GObject *object); + +/* Signals */ +enum { + STATE_CHANGED, + LAST_SIGNAL +}; + +G_DEFINE_TYPE (Server, server, G_TYPE_OBJECT); + +static guint signals[LAST_SIGNAL] = { 0 }; + +static void +server_class_init (ServerClass *klass) +{ + GObjectClass *object_class = G_OBJECT_CLASS (klass); + + object_class->dispose = server_dispose; + object_class->finalize = server_finalize; + + signals[STATE_CHANGED] = g_signal_new(SERVER_SIGNAL_STATE_CHANGED, + G_TYPE_FROM_CLASS(klass), + G_SIGNAL_RUN_LAST, + G_STRUCT_OFFSET(ServerClass, state_changed), + NULL, NULL, + g_cclosure_marshal_VOID__INT, + G_TYPE_NONE, 1, G_TYPE_INT, G_TYPE_NONE); + + return; +} + +static void +server_init (Server *self) +{ + self->name = NULL; + self->uri = NULL; + self->last_used = FALSE; + self->state = SERVER_STATE_ALLGOOD; + + return; +} + +static void +server_dispose (GObject *object) +{ + + G_OBJECT_CLASS (server_parent_class)->dispose (object); + return; +} + +static void +server_finalize (GObject *object) +{ + Server * server = SERVER(object); + + g_free(server->name); + g_free(server->uri); + + G_OBJECT_CLASS (server_parent_class)->finalize (object); + return; +} + +/** + * server_new_from_keyfile: + * @keyfile: The keyfile with the @group in it to define the server + * @group: Group name for this server + * + * Looks at a group within the keyfile and builds a server based on + * it's type. Mostly works with a subclass based on the type. + * + * Return value: A new Server object or NULL if error + */ +Server * +server_new_from_keyfile (GKeyFile * keyfile, const gchar * group) +{ + g_return_val_if_fail(keyfile != NULL, NULL); + g_return_val_if_fail(group != NULL, NULL); + + if (!g_key_file_has_group(keyfile, group)) { + return NULL; + } + + gchar * type = NULL; + if (g_key_file_has_key(keyfile, group, CONFIG_SERVER_TYPE, NULL)) { + type = g_key_file_get_string(keyfile, group, CONFIG_SERVER_TYPE, NULL); + } + + if (g_strcmp0(type, CONFIG_SERVER_TYPE_RDP) == 0) { + return SERVER(rdp_server_new_from_keyfile(keyfile, group)); + } else if (g_strcmp0(type, CONFIG_SERVER_TYPE_ICA) == 0) { + return SERVER(citrix_server_new_from_keyfile(keyfile, group)); + } else { + return SERVER(uccs_server_new_from_keyfile(keyfile, group)); + } + + return NULL; +} + +/** + * server_new_from_json: + * @object: JSON object with server definition + * + * Looks at the type and then uses a subclassed function to build the + * server. + * + * Return value: A new Server object or NULL if error + */ +Server * +server_new_from_json (JsonObject * object) +{ + g_return_val_if_fail(object != NULL, NULL); + + if (!json_object_has_member(object, "Protocol")) { + return NULL; + } + + JsonNode * proto_node = json_object_get_member(object, "Protocol"); + if (JSON_NODE_TYPE(proto_node) != JSON_NODE_VALUE) { + return NULL; + } + if (json_node_get_value_type(proto_node) != G_TYPE_STRING) { + return NULL; + } + + const gchar * proto = json_node_get_string(proto_node); + Server * newserver = NULL; + + if (g_strcmp0(proto, "ICA") == 0 || g_strcmp0(proto, "ica") == 0) { + newserver = citrix_server_new_from_json(object); + } + else if (g_strcmp0(proto, "freerdp") == 0 || g_strcmp0(proto, "rdp") == 0 || g_strcmp0(proto, "RDP") == 0 || g_strcmp0(proto, "FreeRDP") == 0) { + newserver = rdp_server_new_from_json(object); + } + + return newserver; +} + +GVariant * +server_get_variant (Server * server) +{ + /* Okay, this doesn't do anything useful, but it will generate an error + which could be a good thing */ + g_return_val_if_fail(IS_SERVER(server), NULL); + + ServerClass * klass = SERVER_GET_CLASS(server); + if (klass->get_properties != NULL) { + GVariantBuilder tuple; + g_variant_builder_init(&tuple, G_VARIANT_TYPE_TUPLE); + + if (IS_CITRIX_SERVER(server)) { + g_variant_builder_add_value(&tuple, g_variant_new_string("ica")); + } else if (IS_RDP_SERVER(server)) { + g_variant_builder_add_value(&tuple, g_variant_new_string("freerdp")); + } else if (IS_UCCS_SERVER(server)) { + g_variant_builder_add_value(&tuple, g_variant_new_string("uccs")); + } else { + g_assert_not_reached(); + } + + if (server->name != NULL) { + g_variant_builder_add_value(&tuple, g_variant_new_string(server->name)); + } else { + g_warning("Server has no name"); + g_variant_builder_add_value(&tuple, g_variant_new_string("")); + } + + if (server->uri != NULL) { + g_variant_builder_add_value(&tuple, g_variant_new_string(server->uri)); + } else { + g_warning("Server has no URI"); + g_variant_builder_add_value(&tuple, g_variant_new_string("")); + } + + g_variant_builder_add_value(&tuple, g_variant_new_boolean(server->last_used)); + + GVariant * props = klass->get_properties(server); + g_variant_builder_add_value(&tuple, props); + + if (klass->get_applications != NULL) { + GVariant * array = klass->get_applications(server); + g_variant_builder_add_value(&tuple, array); + } else { + /* NULL array of applications */ + g_variant_builder_add_value(&tuple, g_variant_new_array(G_VARIANT_TYPE("(si)"), NULL, 0)); + } + + return g_variant_builder_end(&tuple); + } + + return NULL; +} + +/** + * server_cached_domains: + * @server: Where should we find those domains? + * + * Gets a list of cached domains for a particular server, if this function + * isn't overriden, then a null array is returned. + */ +GVariant * +server_cached_domains (Server * server) +{ + g_return_val_if_fail(IS_SERVER(server), NULL); + + ServerClass * klass = SERVER_GET_CLASS(server); + if (klass->get_domains != NULL) { + return klass->get_domains(server); + } + + return g_variant_new_array(G_VARIANT_TYPE_STRING, NULL, 0); +} + +/** + * server_find_uri: + * @server: Server to look in + * @uri: URI to search for + * + * Checks the URI of this server to see if it matches, and then look + * to see if subclasses have a way to match it another way. + */ +Server * +server_find_uri (Server * server, const gchar * uri) +{ + g_return_val_if_fail(IS_SERVER(server), NULL); + + if (g_strcmp0(server->uri, uri) == 0) { + return server; + } + + ServerClass * klass = SERVER_GET_CLASS(server); + + if (klass->find_uri != NULL) { + return klass->find_uri(server, uri); + } + + return NULL; +} + +/** + * server_set_last_used: + * @server: Server to look in + * @uri: URI to set as last used + * + * Checks the URI of this server to see if it matches, and then look + * to see if subclasses have a way to match it another way. + */ +void +server_set_last_used_server (Server * server, const gchar * uri) +{ + g_return_if_fail(IS_SERVER(server)); + + if (g_strcmp0(server->uri, uri) == 0) { + server->last_used = TRUE; + } else { + ServerClass * klass = SERVER_GET_CLASS(server); + + if (klass->set_last_used_server != NULL) { + klass->set_last_used_server(server, uri); + } + } +} -- cgit v1.2.3