Merge lp:~ted/remote-login-service/signal-ready into lp:~ted/remote-login-service/oo-cleanup

Proposed by Ted Gould
Status: Superseded
Proposed branch: lp:~ted/remote-login-service/signal-ready
Merge into: lp:~ted/remote-login-service/oo-cleanup
Diff against target: 807 lines (+379/-41)
12 files modified
src/citrix-server.c (+71/-4)
src/citrix-server.h (+5/-0)
src/defines.h (+2/-0)
src/main.c (+52/-14)
src/rdp-server.c (+71/-4)
src/rdp-server.h (+5/-0)
src/server.c (+17/-0)
src/server.h (+13/-0)
src/uccs-server.c (+45/-6)
tests/dbus-interface.c (+54/-12)
tests/server-test.c (+43/-0)
tests/slmock (+1/-1)
To merge this branch: bzr merge lp:~ted/remote-login-service/signal-ready
Reviewer Review Type Date Requested Status
Ted Gould Pending
Review via email: mp+123644@code.launchpad.net

This proposal has been superseded by a proposal from 2012-09-10.

Commit message

Add a state to the servers to know if they're configured

To post a comment you must log in.
76. By Ted Gould

Add an executable for the build system that don't have thin-client-config-agent

77. By Ted Gould

Attaching bug

Unmerged revisions

77. By Ted Gould

Attaching bug

76. By Ted Gould

Add an executable for the build system that don't have thin-client-config-agent

75. By Ted Gould

Don't need a tuple there apparently

74. By Ted Gould

Add a test to ensure we signaled updates

73. By Ted Gould

Pulling out the set_exec code so that we can test the signal stuff

72. By Ted Gould

When the server list changes emit the dbus signal

71. By Ted Gould

Handle a race with an extra DBus message

70. By Ted Gould

Moving where the config file is parsed to the servers aren't created until we've connected to DBus

69. By Ted Gould

Watching for servers updating themselves

68. By Ted Gould

Better handle the case of zero all good servers

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
1=== modified file 'src/citrix-server.c'
2--- src/citrix-server.c 2012-08-29 19:09:54 +0000
3+++ src/citrix-server.c 2012-09-10 21:37:19 +0000
4@@ -20,6 +20,8 @@
5 #include "config.h"
6 #endif
7
8+#include <string.h>
9+
10 #include "citrix-server.h"
11 #include "defines.h"
12
13@@ -49,6 +51,10 @@
14 static void
15 citrix_server_init (CitrixServer *self)
16 {
17+ self->username = NULL;
18+ self->password = NULL;
19+ self->domain = NULL;
20+ self->domain_required = FALSE;
21
22 return;
23 }
24@@ -61,9 +67,24 @@
25 return;
26 }
27
28+/* Unlocks the memory before freeing */
29+static void
30+password_clear (gpointer data)
31+{
32+ char * pass = (char *)data;
33+ munlock(pass, strlen(pass));
34+ g_free(pass);
35+ return;
36+}
37+
38 static void
39 citrix_server_finalize (GObject *object)
40 {
41+ CitrixServer * server = CITRIX_SERVER(object);
42+
43+ g_clear_pointer(&server->username, g_free);
44+ g_clear_pointer(&server->password, password_clear);
45+ g_clear_pointer(&server->domain, g_free);
46
47 G_OBJECT_CLASS (citrix_server_parent_class)->finalize (object);
48 return;
49@@ -72,6 +93,8 @@
50 static GVariant *
51 get_properties (Server * server)
52 {
53+ CitrixServer * cserver = CITRIX_SERVER(server);
54+
55 GVariantBuilder propbuilder;
56 g_variant_builder_init(&propbuilder, G_VARIANT_TYPE_ARRAY);
57
58@@ -79,7 +102,11 @@
59 g_variant_builder_init(&namebuilder, G_VARIANT_TYPE_TUPLE);
60 g_variant_builder_add_value(&namebuilder, g_variant_new_string("username"));
61 g_variant_builder_add_value(&namebuilder, g_variant_new_boolean(TRUE));
62- g_variant_builder_add_value(&namebuilder, g_variant_new_variant(g_variant_new_string("")));
63+ if (cserver->username == NULL) {
64+ g_variant_builder_add_value(&namebuilder, g_variant_new_variant(g_variant_new_string("")));
65+ } else {
66+ g_variant_builder_add_value(&namebuilder, g_variant_new_variant(g_variant_new_string(cserver->username)));
67+ }
68 g_variant_builder_add_value(&namebuilder, g_variant_parse(G_VARIANT_TYPE_VARDICT, "{}", NULL, NULL, NULL));
69 g_variant_builder_add_value(&propbuilder, g_variant_builder_end(&namebuilder));
70
71@@ -87,15 +114,23 @@
72 g_variant_builder_init(&passbuilder, G_VARIANT_TYPE_TUPLE);
73 g_variant_builder_add_value(&passbuilder, g_variant_new_string("password"));
74 g_variant_builder_add_value(&passbuilder, g_variant_new_boolean(TRUE));
75- g_variant_builder_add_value(&passbuilder, g_variant_new_variant(g_variant_new_string("")));
76+ if (cserver->password == NULL) {
77+ g_variant_builder_add_value(&passbuilder, g_variant_new_variant(g_variant_new_string("")));
78+ } else {
79+ g_variant_builder_add_value(&passbuilder, g_variant_new_variant(g_variant_new_string(cserver->password)));
80+ }
81 g_variant_builder_add_value(&passbuilder, g_variant_parse(G_VARIANT_TYPE_VARDICT, "{}", NULL, NULL, NULL));
82 g_variant_builder_add_value(&propbuilder, g_variant_builder_end(&passbuilder));
83
84 GVariantBuilder domainbuilder;
85 g_variant_builder_init(&domainbuilder, G_VARIANT_TYPE_TUPLE);
86 g_variant_builder_add_value(&domainbuilder, g_variant_new_string("domain"));
87- g_variant_builder_add_value(&domainbuilder, g_variant_new_boolean(TRUE));
88- g_variant_builder_add_value(&domainbuilder, g_variant_new_variant(g_variant_new_string("")));
89+ g_variant_builder_add_value(&domainbuilder, g_variant_new_boolean(cserver->domain_required));
90+ if (cserver->domain == NULL) {
91+ g_variant_builder_add_value(&domainbuilder, g_variant_new_variant(g_variant_new_string("")));
92+ } else {
93+ g_variant_builder_add_value(&domainbuilder, g_variant_new_variant(g_variant_new_string(cserver->domain)));
94+ }
95 g_variant_builder_add_value(&domainbuilder, g_variant_parse(G_VARIANT_TYPE_VARDICT, "{}", NULL, NULL, NULL));
96 g_variant_builder_add_value(&propbuilder, g_variant_builder_end(&domainbuilder));
97
98@@ -148,5 +183,37 @@
99 }
100 }
101
102+ if (json_object_has_member(object, JSON_USERNAME)) {
103+ JsonNode * node = json_object_get_member(object, JSON_USERNAME);
104+ if (JSON_NODE_TYPE(node) == JSON_NODE_VALUE && json_node_get_value_type(node) == G_TYPE_STRING) {
105+ const gchar * username = json_node_get_string(node);
106+ server->username = g_strdup(username);
107+ }
108+ }
109+
110+ if (json_object_has_member(object, JSON_PASSWORD)) {
111+ JsonNode * node = json_object_get_member(object, JSON_PASSWORD);
112+ if (JSON_NODE_TYPE(node) == JSON_NODE_VALUE && json_node_get_value_type(node) == G_TYPE_STRING) {
113+ const gchar * password = json_node_get_string(node);
114+ server->password = g_strdup(password);
115+ mlock(server->password, strlen(server->password));
116+ }
117+ }
118+
119+ if (json_object_has_member(object, JSON_DOMAIN)) {
120+ JsonNode * node = json_object_get_member(object, JSON_DOMAIN);
121+ if (JSON_NODE_TYPE(node) == JSON_NODE_VALUE && json_node_get_value_type(node) == G_TYPE_STRING) {
122+ const gchar * domain = json_node_get_string(node);
123+ server->domain = g_strdup(domain);
124+ }
125+ }
126+
127+ if (json_object_has_member(object, JSON_DOMAIN_REQ)) {
128+ JsonNode * node = json_object_get_member(object, JSON_DOMAIN_REQ);
129+ if (JSON_NODE_TYPE(node) == JSON_NODE_VALUE && json_node_get_value_type(node) == G_TYPE_BOOLEAN) {
130+ server->domain_required = json_node_get_boolean(node);
131+ }
132+ }
133+
134 return SERVER(server);
135 }
136
137=== modified file 'src/citrix-server.h'
138--- src/citrix-server.h 2012-08-16 18:44:58 +0000
139+++ src/citrix-server.h 2012-09-10 21:37:19 +0000
140@@ -41,6 +41,11 @@
141
142 struct _CitrixServer {
143 Server parent;
144+
145+ gchar * username;
146+ gchar * password;
147+ gchar * domain;
148+ gboolean domain_required;
149 };
150
151 GType citrix_server_get_type (void);
152
153=== modified file 'src/defines.h'
154--- src/defines.h 2012-08-29 19:09:54 +0000
155+++ src/defines.h 2012-09-10 21:37:19 +0000
156@@ -37,5 +37,7 @@
157 #define JSON_URI "URL"
158 #define JSON_USERNAME "Username"
159 #define JSON_PASSWORD "Password"
160+#define JSON_DOMAIN_REQ "DomainRequired"
161+#define JSON_DOMAIN "WindowsDomain"
162
163 #endif /* __DEFINES_H__ */
164
165=== modified file 'src/main.c'
166--- src/main.c 2012-08-29 19:09:44 +0000
167+++ src/main.c 2012-09-10 21:37:19 +0000
168@@ -26,6 +26,8 @@
169 #include "citrix-server.h"
170 #include "uccs-server.h"
171
172+gint server_list_to_array (GVariantBuilder * builder, GList * items);
173+
174 enum {
175 ERROR_SERVER_URI,
176 ERROR_LOGIN
177@@ -44,8 +46,31 @@
178 return value;
179 }
180
181-static void
182-find_config_file (GKeyFile * parsed, const gchar * cmnd_line)
183+/* When one of the state changes on the server emit that so that everone knows there
184+ might be a new server available. */
185+static void
186+server_status_updated (Server * server, ServerState newstate, RemoteLogin * rl)
187+{
188+ GVariant * array = NULL;
189+
190+ GVariantBuilder builder;
191+ g_variant_builder_init(&builder, G_VARIANT_TYPE_ARRAY);
192+
193+ if (server_list_to_array(&builder, config_file_servers) > 0) {
194+ array = g_variant_builder_end(&builder);
195+ } else {
196+ g_variant_builder_clear(&builder);
197+ array = g_variant_new_array(G_VARIANT_TYPE("(sssba(sbva{sv})a(si))"), NULL, 0);
198+ }
199+
200+ remote_login_emit_servers_updated(rl, array);
201+ return;
202+}
203+
204+/* Looks for the config file and does some basic parsing to pull out the UCCS servers
205+ that are configured in it */
206+static void
207+find_config_file (GKeyFile * parsed, const gchar * cmnd_line, RemoteLogin * rl)
208 {
209 GError * error = NULL;
210 const gchar * file = DEFAULT_CONFIG_FILE;
211@@ -82,25 +107,37 @@
212 }
213
214 config_file_servers = g_list_append(config_file_servers, server);
215+ g_signal_connect(server, SERVER_SIGNAL_STATE_CHANGED, G_CALLBACK(server_status_updated), rl);
216 }
217
218 g_strfreev(grouplist);
219 }
220
221+ /* Signal the list of servers so that we're sure everyone's got them. This is to
222+ solve a possible race where someone could ask while we're configuring these. */
223+ server_status_updated(NULL, SERVER_STATE_ALLGOOD, rl);
224 return;
225 }
226
227-void
228+gint
229 server_list_to_array (GVariantBuilder * builder, GList * items)
230 {
231+ gint servercnt = 0;
232 GList * head = NULL;
233 for (head = items; head != NULL; head = g_list_next(head)) {
234 Server * server = SERVER(head->data);
235+
236+ /* We only want servers that are all good */
237+ if (server->state != SERVER_STATE_ALLGOOD) {
238+ continue;
239+ }
240+
241+ servercnt++;
242 GVariant * variant = server_get_variant(server);
243 g_variant_builder_add_value(builder, variant);
244 }
245
246- return;
247+ return servercnt;
248 }
249
250 static gboolean
251@@ -108,14 +145,13 @@
252 {
253 GVariant * array = NULL;
254
255- if (g_list_length(config_file_servers) > 0) {
256- GVariantBuilder builder;
257- g_variant_builder_init(&builder, G_VARIANT_TYPE_ARRAY);
258-
259- server_list_to_array(&builder, config_file_servers);
260-
261+ GVariantBuilder builder;
262+ g_variant_builder_init(&builder, G_VARIANT_TYPE_ARRAY);
263+
264+ if (server_list_to_array(&builder, config_file_servers) > 0) {
265 array = g_variant_builder_end(&builder);
266 } else {
267+ g_variant_builder_clear(&builder);
268 array = g_variant_new_array(G_VARIANT_TYPE("(sssba(sbva{sv})a(si))"), NULL, 0);
269 }
270
271@@ -279,7 +315,7 @@
272 {
273 GMainLoop * mainloop = (GMainLoop *)user_data;
274
275- g_error("Unable to get name '%s'", name);
276+ g_warning("Unable to get name '%s'. Exiting.", name);
277 g_main_loop_quit(mainloop);
278
279 return;
280@@ -313,9 +349,6 @@
281 return 1;
282 }
283
284- /* Parse config file */
285- find_config_file(config, cmnd_line_config);
286-
287 /* Start up D' Bus */
288 GDBusConnection * session_bus = g_bus_get_sync(G_BUS_TYPE_SESSION, NULL /* cancel */, &error);
289 if (error != NULL) {
290@@ -324,7 +357,9 @@
291 return -1;
292 }
293
294+ /* Build Dbus Interface */
295 RemoteLogin * skel = remote_login_skeleton_new();
296+ /* Export it */
297 g_dbus_interface_skeleton_export(G_DBUS_INTERFACE_SKELETON(skel),
298 session_bus,
299 "/com/canonical/RemoteLogin",
300@@ -341,6 +376,9 @@
301 mainloop,
302 NULL); /* mainloop free */
303
304+ /* Parse config file */
305+ find_config_file(config, cmnd_line_config, skel);
306+
307 /* Loop forever */
308 g_main_loop_run(mainloop);
309
310
311=== modified file 'src/rdp-server.c'
312--- src/rdp-server.c 2012-08-29 19:09:54 +0000
313+++ src/rdp-server.c 2012-09-10 21:37:19 +0000
314@@ -20,6 +20,8 @@
315 #include "config.h"
316 #endif
317
318+#include <string.h>
319+
320 #include "rdp-server.h"
321 #include "defines.h"
322
323@@ -49,6 +51,10 @@
324 static void
325 rdp_server_init (RdpServer *self)
326 {
327+ self->username = NULL;
328+ self->password = NULL;
329+ self->domain = NULL;
330+ self->domain_required = FALSE;
331
332 return;
333 }
334@@ -61,9 +67,24 @@
335 return;
336 }
337
338+/* Unlocks the memory before freeing */
339+static void
340+password_clear (gpointer data)
341+{
342+ char * pass = (char *)data;
343+ munlock(pass, strlen(pass));
344+ g_free(pass);
345+ return;
346+}
347+
348 static void
349 rdp_server_finalize (GObject *object)
350 {
351+ RdpServer * server = RDP_SERVER(object);
352+
353+ g_clear_pointer(&server->username, g_free);
354+ g_clear_pointer(&server->password, password_clear);
355+ g_clear_pointer(&server->domain, g_free);
356
357 G_OBJECT_CLASS (rdp_server_parent_class)->finalize (object);
358 return;
359@@ -72,6 +93,8 @@
360 static GVariant *
361 get_properties (Server * server)
362 {
363+ RdpServer * rserver = RDP_SERVER(server);
364+
365 GVariantBuilder propbuilder;
366 g_variant_builder_init(&propbuilder, G_VARIANT_TYPE_ARRAY);
367
368@@ -79,7 +102,11 @@
369 g_variant_builder_init(&namebuilder, G_VARIANT_TYPE_TUPLE);
370 g_variant_builder_add_value(&namebuilder, g_variant_new_string("username"));
371 g_variant_builder_add_value(&namebuilder, g_variant_new_boolean(TRUE));
372- g_variant_builder_add_value(&namebuilder, g_variant_new_variant(g_variant_new_string("")));
373+ if (rserver->username == NULL) {
374+ g_variant_builder_add_value(&namebuilder, g_variant_new_variant(g_variant_new_string("")));
375+ } else {
376+ g_variant_builder_add_value(&namebuilder, g_variant_new_variant(g_variant_new_string(rserver->username)));
377+ }
378 g_variant_builder_add_value(&namebuilder, g_variant_parse(G_VARIANT_TYPE_VARDICT, "{}", NULL, NULL, NULL));
379 g_variant_builder_add_value(&propbuilder, g_variant_builder_end(&namebuilder));
380
381@@ -87,15 +114,23 @@
382 g_variant_builder_init(&passbuilder, G_VARIANT_TYPE_TUPLE);
383 g_variant_builder_add_value(&passbuilder, g_variant_new_string("password"));
384 g_variant_builder_add_value(&passbuilder, g_variant_new_boolean(TRUE));
385- g_variant_builder_add_value(&passbuilder, g_variant_new_variant(g_variant_new_string("")));
386+ if (rserver->password == NULL) {
387+ g_variant_builder_add_value(&passbuilder, g_variant_new_variant(g_variant_new_string("")));
388+ } else {
389+ g_variant_builder_add_value(&passbuilder, g_variant_new_variant(g_variant_new_string(rserver->password)));
390+ }
391 g_variant_builder_add_value(&passbuilder, g_variant_parse(G_VARIANT_TYPE_VARDICT, "{}", NULL, NULL, NULL));
392 g_variant_builder_add_value(&propbuilder, g_variant_builder_end(&passbuilder));
393
394 GVariantBuilder domainbuilder;
395 g_variant_builder_init(&domainbuilder, G_VARIANT_TYPE_TUPLE);
396 g_variant_builder_add_value(&domainbuilder, g_variant_new_string("domain"));
397- g_variant_builder_add_value(&domainbuilder, g_variant_new_boolean(TRUE));
398- g_variant_builder_add_value(&domainbuilder, g_variant_new_variant(g_variant_new_string("")));
399+ g_variant_builder_add_value(&domainbuilder, g_variant_new_boolean(rserver->domain_required));
400+ if (rserver->domain == NULL) {
401+ g_variant_builder_add_value(&domainbuilder, g_variant_new_variant(g_variant_new_string("")));
402+ } else {
403+ g_variant_builder_add_value(&domainbuilder, g_variant_new_variant(g_variant_new_string(rserver->domain)));
404+ }
405 g_variant_builder_add_value(&domainbuilder, g_variant_parse(G_VARIANT_TYPE_VARDICT, "{}", NULL, NULL, NULL));
406 g_variant_builder_add_value(&propbuilder, g_variant_builder_end(&domainbuilder));
407
408@@ -148,5 +183,37 @@
409 }
410 }
411
412+ if (json_object_has_member(object, JSON_USERNAME)) {
413+ JsonNode * node = json_object_get_member(object, JSON_USERNAME);
414+ if (JSON_NODE_TYPE(node) == JSON_NODE_VALUE && json_node_get_value_type(node) == G_TYPE_STRING) {
415+ const gchar * username = json_node_get_string(node);
416+ server->username = g_strdup(username);
417+ }
418+ }
419+
420+ if (json_object_has_member(object, JSON_PASSWORD)) {
421+ JsonNode * node = json_object_get_member(object, JSON_PASSWORD);
422+ if (JSON_NODE_TYPE(node) == JSON_NODE_VALUE && json_node_get_value_type(node) == G_TYPE_STRING) {
423+ const gchar * password = json_node_get_string(node);
424+ server->password = g_strdup(password);
425+ mlock(server->password, strlen(server->password));
426+ }
427+ }
428+
429+ if (json_object_has_member(object, JSON_DOMAIN)) {
430+ JsonNode * node = json_object_get_member(object, JSON_DOMAIN);
431+ if (JSON_NODE_TYPE(node) == JSON_NODE_VALUE && json_node_get_value_type(node) == G_TYPE_STRING) {
432+ const gchar * domain = json_node_get_string(node);
433+ server->domain = g_strdup(domain);
434+ }
435+ }
436+
437+ if (json_object_has_member(object, JSON_DOMAIN_REQ)) {
438+ JsonNode * node = json_object_get_member(object, JSON_DOMAIN_REQ);
439+ if (JSON_NODE_TYPE(node) == JSON_NODE_VALUE && json_node_get_value_type(node) == G_TYPE_BOOLEAN) {
440+ server->domain_required = json_node_get_boolean(node);
441+ }
442+ }
443+
444 return SERVER(server);
445 }
446
447=== modified file 'src/rdp-server.h'
448--- src/rdp-server.h 2012-08-16 18:44:58 +0000
449+++ src/rdp-server.h 2012-09-10 21:37:19 +0000
450@@ -41,6 +41,11 @@
451
452 struct _RdpServer {
453 Server parent;
454+
455+ gchar * username;
456+ gchar * password;
457+ gchar * domain;
458+ gboolean domain_required;
459 };
460
461 GType rdp_server_get_type (void);
462
463=== modified file 'src/server.c'
464--- src/server.c 2012-08-29 18:49:21 +0000
465+++ src/server.c 2012-09-10 21:37:19 +0000
466@@ -31,8 +31,16 @@
467 static void server_dispose (GObject *object);
468 static void server_finalize (GObject *object);
469
470+/* Signals */
471+enum {
472+ STATE_CHANGED,
473+ LAST_SIGNAL
474+};
475+
476 G_DEFINE_TYPE (Server, server, G_TYPE_OBJECT);
477
478+static guint signals[LAST_SIGNAL] = { 0 };
479+
480 static void
481 server_class_init (ServerClass *klass)
482 {
483@@ -41,6 +49,14 @@
484 object_class->dispose = server_dispose;
485 object_class->finalize = server_finalize;
486
487+ signals[STATE_CHANGED] = g_signal_new(SERVER_SIGNAL_STATE_CHANGED,
488+ G_TYPE_FROM_CLASS(klass),
489+ G_SIGNAL_RUN_LAST,
490+ G_STRUCT_OFFSET(ServerClass, state_changed),
491+ NULL, NULL,
492+ g_cclosure_marshal_VOID__INT,
493+ G_TYPE_NONE, 1, G_TYPE_INT, G_TYPE_NONE);
494+
495 return;
496 }
497
498@@ -50,6 +66,7 @@
499 self->name = NULL;
500 self->uri = NULL;
501 self->last_used = FALSE;
502+ self->state = SERVER_STATE_ALLGOOD;
503
504 return;
505 }
506
507=== modified file 'src/server.h'
508--- src/server.h 2012-08-29 18:34:04 +0000
509+++ src/server.h 2012-09-10 21:37:19 +0000
510@@ -31,8 +31,16 @@
511 #define IS_SERVER_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), SERVER_TYPE))
512 #define SERVER_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), SERVER_TYPE, ServerClass))
513
514+#define SERVER_SIGNAL_STATE_CHANGED "state-changed"
515+
516 typedef struct _Server Server;
517 typedef struct _ServerClass ServerClass;
518+typedef enum _ServerState ServerState;
519+
520+enum _ServerState {
521+ SERVER_STATE_ALLGOOD,
522+ SERVER_STATE_UNAVAILABLE
523+};
524
525 struct _ServerClass {
526 GObjectClass parent_class;
527@@ -40,6 +48,9 @@
528 GVariant * (*get_applications) (Server * server);
529 GVariant * (*get_domains) (Server * server);
530 Server * (*find_uri) (Server * server, const gchar * uri);
531+
532+ /* signals */
533+ void (*state_changed) (Server * server, ServerState newstate, gpointer user_data);
534 };
535
536 struct _Server {
537@@ -48,6 +59,8 @@
538 gchar * name;
539 gchar * uri;
540 gboolean last_used;
541+
542+ ServerState state;
543 };
544
545 GType server_get_type (void);
546
547=== modified file 'src/uccs-server.c'
548--- src/uccs-server.c 2012-08-29 19:09:54 +0000
549+++ src/uccs-server.c 2012-09-10 21:37:19 +0000
550@@ -90,6 +90,10 @@
551 self->json_stream = NULL;
552 self->pass_stream = NULL;
553
554+ if (self->exec == NULL) {
555+ self->parent.state = SERVER_STATE_UNAVAILABLE;
556+ }
557+
558 return;
559 }
560
561@@ -234,6 +238,33 @@
562 return g_variant_builder_end(&propbuilder);
563 }
564
565+/* Set the exec value for the server */
566+const gchar *
567+uccs_server_set_exec (UccsServer * server, const gchar * exec)
568+{
569+ g_return_val_if_fail(IS_UCCS_SERVER(server), NULL);
570+
571+ g_clear_pointer(&server->exec, g_free);
572+
573+ if (exec != NULL) {
574+ server->exec = g_find_program_in_path(exec);
575+ }
576+
577+ ServerState oldstate = server->parent.state;
578+ if (server->exec != NULL) {
579+ server->parent.state = SERVER_STATE_ALLGOOD;
580+ } else {
581+ server->parent.state = SERVER_STATE_UNAVAILABLE;
582+ }
583+
584+ if (server->parent.state != oldstate) {
585+ g_signal_emit_by_name(server, SERVER_SIGNAL_STATE_CHANGED, server->parent.state);
586+ }
587+
588+ return server->exec;
589+}
590+
591+/* Build a new uccs server from a keyfile and a group in it */
592 Server *
593 uccs_server_new_from_keyfile (GKeyFile * keyfile, const gchar * groupname)
594 {
595@@ -256,9 +287,8 @@
596 }
597
598 if (g_key_file_has_key(keyfile, groupname, CONFIG_UCCS_EXEC, NULL)) {
599- g_free(server->exec);
600 gchar * key = g_key_file_get_string(keyfile, groupname, CONFIG_UCCS_EXEC, NULL);
601- server->exec = g_find_program_in_path(key);
602+ uccs_server_set_exec(server, key);
603 g_free(key);
604 }
605
606@@ -572,18 +602,27 @@
607 return null_server_array();
608 }
609
610- if (g_list_length(server->subservers) == 0) {
611- return null_server_array();
612- }
613-
614 GVariantBuilder array;
615 g_variant_builder_init(&array, G_VARIANT_TYPE_ARRAY);
616 GList * lserver;
617+ gint servercnt = 0;
618 for (lserver = server->subservers; lserver != NULL; lserver = g_list_next(lserver)) {
619 Server * serv = SERVER(lserver->data);
620+
621+ /* We only want servers that are all good */
622+ if (serv->state != SERVER_STATE_ALLGOOD) {
623+ continue;
624+ }
625+
626+ servercnt++;
627 g_variant_builder_add_value(&array, server_get_variant(serv));
628 }
629
630+ if (servercnt == 0) {
631+ g_variant_builder_clear(&array);
632+ return null_server_array();
633+ }
634+
635 return g_variant_builder_end(&array);
636 }
637
638
639=== modified file 'tests/dbus-interface.c'
640--- tests/dbus-interface.c 2012-08-27 15:45:46 +0000
641+++ tests/dbus-interface.c 2012-09-10 21:37:19 +0000
642@@ -16,28 +16,31 @@
643 const gchar * name;
644 const gchar * uri;
645 const gchar * type;
646- /* TODO: Add more as we get more working */
647+ const gchar * username;
648+ const gchar * password;
649+ const gchar * domain;
650 };
651
652 slmock_server_t citrix_server_table[] = {
653- {"Citrix USA", "107.21.17.35", "ica"},
654- {"Citrix 2", "107.21.17.35", "ica"},
655- {"Citrix 3", "107.21.17.35", "ica"},
656+ {"Citrix USA", "107.21.17.35", "ica", "useradmin1", "", "IP-0A00001E"},
657+ {"Citrix 2", "107.21.17.35", "ica", "useradmin2", "", "IP-0A00001E"},
658+ {"Citrix 3", "107.21.17.35", "ica", "useradmin3", "", "IP-0A00001E"},
659+ {"Citrix 4", "107.21.17.35", "ica", "useradmin4", "userpass", "IP-0A00001E"},
660 {NULL, NULL, NULL}
661 };
662
663 slmock_server_t freerdp_server_table[] = {
664- {"FreeRDP US", "23.21.151.133", "freerdp"},
665- {"FreeRDP Asia", "46.137.222.181", "freerdp"},
666- {"FreeRDP UK", "46.137.189.194", "freerdp"},
667+ {"FreeRDP US", "23.21.151.133", "freerdp", "Administrator", "", ""},
668+ {"FreeRDP Asia", "46.137.222.181", "freerdp", "Administrator", "", ""},
669+ {"FreeRDP UK", "46.137.189.194", "freerdp", "Administrator", "", ""},
670 {NULL, NULL, NULL}
671 };
672
673 slmock_server_t big_server_table[] = {
674- {"XenServer", "107.21.17.35", "ica"},
675- {"Citrix2", "http://1.2.3.4", "ica"},
676- {"Accenture", "10.21.17.35", "freerdp"},
677- {"Accenture 2", "https://4.5.6.7", "freerdp"},
678+ {"XenServer", "107.21.17.35", "ica", "", "", "ASIA"},
679+ {"Citrix2", "http://1.2.3.4", "ica", "fakeuser", "fakepassword", "DOMAIN1"},
680+ {"Accenture", "10.21.17.35", "freerdp", "fakeuser", "", "EUROPE"},
681+ {"Accenture 2", "https://4.5.6.7", "freerdp", "", "", "domain2"},
682 {NULL, NULL, NULL}
683 };
684
685@@ -79,8 +82,47 @@
686 continue;
687 }
688
689+ gboolean match_username = FALSE;
690+ gboolean match_password = FALSE;
691+ gboolean match_domain = FALSE;
692+
693+ GVariant * props = g_variant_get_child_value(child, 4);
694+ int iprop;
695+ for (iprop = 0; iprop < g_variant_n_children(props); iprop++) {
696+ GVariant * prop = g_variant_get_child_value(props, iprop);
697+
698+ GVariant * prop_type = g_variant_get_child_value(prop, 0);
699+ GVariant * prop_value_wrap = g_variant_get_child_value(prop, 2);
700+ GVariant * prop_value = g_variant_get_variant(prop_value_wrap);
701+
702+ if (g_strcmp0(g_variant_get_string(prop_type, NULL), "username") == 0) {
703+ if (g_strcmp0(g_variant_get_string(prop_value, NULL), server->username) == 0) {
704+ match_username = TRUE;
705+ }
706+ } else if (g_strcmp0(g_variant_get_string(prop_type, NULL), "password") == 0) {
707+ if (g_strcmp0(g_variant_get_string(prop_value, NULL), server->password) == 0) {
708+ match_password = TRUE;
709+ }
710+ } else if (g_strcmp0(g_variant_get_string(prop_type, NULL), "domain") == 0) {
711+ if (g_strcmp0(g_variant_get_string(prop_value, NULL), server->domain) == 0) {
712+ match_domain = TRUE;
713+ }
714+ }
715+
716+ g_variant_unref(prop_value);
717+ g_variant_unref(prop_value_wrap);
718+ g_variant_unref(prop_type);
719+ g_variant_unref(prop);
720+ }
721+ g_variant_unref(props);
722+
723 g_variant_unref(child);
724- return TRUE;
725+
726+ if (match_username && match_password && match_domain) {
727+ return TRUE;
728+ } else {
729+ continue;
730+ }
731 }
732
733 return FALSE;
734
735=== modified file 'tests/server-test.c'
736--- tests/server-test.c 2012-08-29 19:44:17 +0000
737+++ tests/server-test.c 2012-09-10 21:37:19 +0000
738@@ -7,6 +7,48 @@
739 #include "uccs-server.h"
740
741 static void
742+state_signal (Server * server, ServerState newstate, gboolean * signaled)
743+{
744+ *signaled = TRUE;
745+ return;
746+}
747+
748+static void
749+test_update_signal (void)
750+{
751+ GKeyFile * keyfile = g_key_file_new();
752+ const gchar * groupname = CONFIG_SERVER_PREFIX " Server Name";
753+ g_key_file_set_string(keyfile, groupname, CONFIG_SERVER_NAME, "My Server");
754+ g_key_file_set_string(keyfile, groupname, CONFIG_SERVER_URI, "http://my.domain.com");
755+
756+ Server * server = NULL;
757+ server = server_new_from_keyfile(keyfile, groupname);
758+ g_assert(server != NULL);
759+ g_assert(g_strcmp0(server->name, "My Server") == 0);
760+ g_assert(g_strcmp0(server->uri, "http://my.domain.com") == 0);
761+
762+ UccsServer * userver = UCCS_SERVER(server);
763+ g_assert(userver != NULL);
764+
765+ gboolean signaled = FALSE;
766+ g_signal_connect(G_OBJECT(server), SERVER_SIGNAL_STATE_CHANGED, G_CALLBACK(state_signal), &signaled);
767+
768+ if (server->state == SERVER_STATE_ALLGOOD) {
769+ signaled = FALSE;
770+ uccs_server_set_exec(userver, "thisshouldnotexist");
771+ g_assert(signaled);
772+ g_assert(server->state == SERVER_STATE_UNAVAILABLE);
773+ }
774+
775+ signaled = FALSE;
776+ uccs_server_set_exec(userver, "ls");
777+ g_assert(signaled);
778+ g_assert(server->state == SERVER_STATE_ALLGOOD);
779+
780+ return;
781+}
782+
783+static void
784 test_uccs_domains (void)
785 {
786 GKeyFile * keyfile = g_key_file_new();
787@@ -199,6 +241,7 @@
788
789 g_test_add_func ("/server/uccs/exec", test_uccs_exec);
790 g_test_add_func ("/server/uccs/domains", test_uccs_domains);
791+ g_test_add_func ("/server/uccs/signal", test_update_signal);
792
793 return;
794 }
795
796=== modified file 'tests/slmock'
797--- tests/slmock 2012-08-21 15:46:54 +0000
798+++ tests/slmock 2012-09-10 21:37:19 +0000
799@@ -93,7 +93,7 @@
800 ts3 = TerminalServer("107.21.17.35", "Citrix 3", "ICA", True,
801 "useradmin3")
802 ts4 = TerminalServer("107.21.17.35", "Citrix 4", "ICA", True,
803- "useradmin4")
804+ "useradmin4", "userpass")
805 ts1.add_domain("IP-0A00001E")
806 ts2.add_domain("IP-0A00001E")
807 ts3.add_domain("IP-0A00001E")

Subscribers

People subscribed via source and target branches

to all changes: