aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorChristian Grothoff <christian@grothoff.org>2011-09-11 11:48:40 +0000
committerChristian Grothoff <christian@grothoff.org>2011-09-11 11:48:40 +0000
commit37972ed53f447d41f14b3f2107b94e4e78cfd718 (patch)
treee8733bc7047b451976e4b3a342e24d631f005195
parent6d24252ad255ed5813cb07e191b0756c665d2255 (diff)
downloadgnunet-gtk-37972ed53f447d41f14b3f2107b94e4e78cfd718.tar.gz
gnunet-gtk-37972ed53f447d41f14b3f2107b94e4e78cfd718.zip
adding flag support
-rw-r--r--src/peerinfo/Makefile.am5
-rw-r--r--src/peerinfo/gnunet-peerinfo-gtk-flags.c144
-rw-r--r--src/peerinfo/gnunet-peerinfo-gtk-flags.h50
-rw-r--r--src/peerinfo/gnunet-peerinfo-gtk.c299
4 files changed, 464 insertions, 34 deletions
diff --git a/src/peerinfo/Makefile.am b/src/peerinfo/Makefile.am
index babc92b3..97bad8dc 100644
--- a/src/peerinfo/Makefile.am
+++ b/src/peerinfo/Makefile.am
@@ -11,12 +11,13 @@ bin_PROGRAMS = gnunet-peerinfo-gtk
11 11
12gnunet_peerinfo_gtk_SOURCES = \ 12gnunet_peerinfo_gtk_SOURCES = \
13 gnunet-peerinfo-gtk.c \ 13 gnunet-peerinfo-gtk.c \
14 gnunet-peerinfo-gtk-about.c 14 gnunet-peerinfo-gtk-about.c \
15 gnunet-peerinfo-gtk-flags.c gnunet-peerinfo-gtk-flags.h
15gnunet_peerinfo_gtk_LDADD = \ 16gnunet_peerinfo_gtk_LDADD = \
16 $(top_builddir)/src/lib/libgnunetgtk.la \ 17 $(top_builddir)/src/lib/libgnunetgtk.la \
17 @GTK_LIBS@ \ 18 @GTK_LIBS@ \
18 @GLADE_LIBS@ @GNUNET_LIBS@ \ 19 @GLADE_LIBS@ @GNUNET_LIBS@ \
19 -lgnunetutil -lgnunetpeerinfo \ 20 -lgnunetutil -lgnunetpeerinfo -lgnunetcore -lgnunettransport \
20 $(INTLLIBS) 21 $(INTLLIBS)
21gnunet_peerinfo_gtk_LDFLAGS = \ 22gnunet_peerinfo_gtk_LDFLAGS = \
22 -export-dynamic \ No newline at end of file 23 -export-dynamic \ No newline at end of file
diff --git a/src/peerinfo/gnunet-peerinfo-gtk-flags.c b/src/peerinfo/gnunet-peerinfo-gtk-flags.c
new file mode 100644
index 00000000..6c45e97c
--- /dev/null
+++ b/src/peerinfo/gnunet-peerinfo-gtk-flags.c
@@ -0,0 +1,144 @@
1/*
2 This file is part of GNUnet.
3 (C) 2007, 2011 Christian Grothoff (and other contributing authors)
4
5 GNUnet is free software; you can redistribute it and/or modify
6 it under the terms of the GNU General Public License as published
7 by the Free Software Foundation; either version 2, or (at your
8 option) any later version.
9
10 GNUnet is distributed in the hope that it will be useful, but
11 WITHOUT ANY WARRANTY; without even the implied warranty of
12 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13 General Public License for more details.
14
15 You should have received a copy of the GNU General Public License
16 along with GNUnet; see the file COPYING. If not, write to the
17 Free Software Foundation, Inc., 59 Temple Place - Suite 330,
18 Boston, MA 02111-1307, USA.
19*/
20
21/**
22 * @file src/peerinfo/gnunet-peerinfo-gtk-flags.c
23 * @brief flag lookup
24 * @author Christian Grothoff
25 */
26#include "gnunet_gtk.h"
27#include "gnunet-peerinfo-gtk-flags.h"
28
29/**
30 * Entry we keep for each flag.
31 */
32struct Flag
33{
34 /**
35 * This is a linked list.
36 */
37 struct Flag *next;
38
39 /**
40 * This is a linked list.
41 */
42 struct Flag *prev;
43
44 /**
45 * Associated country code.
46 */
47 char *cc;
48
49 /**
50 * Flag image.
51 */
52 GdkPixbuf *flag;
53};
54
55
56/**
57 * Head of the DLL of loaded flags.
58 */
59static struct Flag *flags_head;
60
61/**
62 * Tail of the DLL of loaded flags.
63 */
64static struct Flag *flags_tail;
65
66
67/**
68 * Lookup the flag image for the given country code
69 *
70 * @return NULL on error
71 */
72GdkPixbuf *
73GNUNET_PEERINFO_GTK_get_flag (const char *cc)
74{
75 GdkPixbuf *flagBuf;
76 char *mcc;
77 char *dir;
78 char *fn;
79 size_t i;
80 struct Flag *pos;
81
82 if (NULL == cc)
83 return NULL;
84 if ((0 == strcasecmp (cc, "edu")) ||
85 (0 == strcasecmp (cc, "com")) ||
86 (0 == strcasecmp (cc, "net")) ||
87 (0 == strcasecmp (cc, "org")) ||
88 (0 == strcasecmp (cc, "gov")) || (0 == strcasecmp (cc, "mil")))
89 cc = "us";
90 if (0 == strcasecmp (cc, "uk"))
91 cc = "gb";
92 if (strlen (cc) > 2)
93 return NULL;
94 pos = flags_head;
95 while (pos != NULL)
96 {
97 if (0 == strcmp (pos->cc, cc))
98 return pos->flag;
99 pos = pos->next;
100 }
101 mcc = GNUNET_strdup (cc);
102 for (i = 0; i < strlen (mcc); i++)
103 mcc[i] = tolower (mcc[i]);
104 dir = GNUNET_GTK_installation_get_path (GNUNET_OS_IPK_DATADIR);
105 GNUNET_asprintf (&fn,
106 "%sgnunet-gtk%sflags%s%s.png",
107 dir,
108 DIR_SEPARATOR_STR,
109 DIR_SEPARATOR_STR,
110 mcc);
111 GNUNET_free (dir);
112 flagBuf = gdk_pixbuf_new_from_file (fn, NULL);
113 pos = GNUNET_malloc (sizeof (struct Flag));
114 pos->cc = mcc;
115 pos->flag = flagBuf;
116 GNUNET_CONTAINER_DLL_insert (flags_head,
117 flags_tail,
118 pos);
119 return flagBuf;
120}
121
122
123/**
124 * Deallocate all cached flags.
125 */
126void
127GNUNET_PEERINFO_GTK_flags_shutdown ()
128{
129 struct Flag *flag;
130
131 while (NULL != (flag = flags_head))
132 {
133 GNUNET_CONTAINER_DLL_remove (flags_head,
134 flags_tail,
135 flag);
136 if (flag->flag != NULL)
137 g_object_unref (flag->flag);
138 GNUNET_free (flag->cc);
139 GNUNET_free (flag);
140 }
141}
142
143
144/* end of gnunet-peerinfo-gtk-flags.c */
diff --git a/src/peerinfo/gnunet-peerinfo-gtk-flags.h b/src/peerinfo/gnunet-peerinfo-gtk-flags.h
new file mode 100644
index 00000000..6e0d06fd
--- /dev/null
+++ b/src/peerinfo/gnunet-peerinfo-gtk-flags.h
@@ -0,0 +1,50 @@
1/*
2 This file is part of GNUnet.
3 (C) 2007, 2011 Christian Grothoff (and other contributing authors)
4
5 GNUnet is free software; you can redistribute it and/or modify
6 it under the terms of the GNU General Public License as published
7 by the Free Software Foundation; either version 2, or (at your
8 option) any later version.
9
10 GNUnet is distributed in the hope that it will be useful, but
11 WITHOUT ANY WARRANTY; without even the implied warranty of
12 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13 General Public License for more details.
14
15 You should have received a copy of the GNU General Public License
16 along with GNUnet; see the file COPYING. If not, write to the
17 Free Software Foundation, Inc., 59 Temple Place - Suite 330,
18 Boston, MA 02111-1307, USA.
19*/
20
21/**
22 * @file src/peerinfo/gnunet-peerinfo-gtk-flags.h
23 * @brief flag lookup
24 * @author Christian Grothoff
25 */
26#ifndef GNUNET_PEERINFO_GTK_FLAGS_H
27#define GNUNET_PEERINFO_GTK_FLAGS_H
28
29#include "gnunet_gtk.h"
30#include <ctype.h>
31#include <gdk/gdk.h>
32
33/**
34 * Lookup the flag image for the given country code
35 *
36 * @return NULL on error
37 */
38GdkPixbuf *
39GNUNET_PEERINFO_GTK_get_flag (const char *cc);
40
41
42
43/**
44 * Deallocate all cached flags.
45 */
46void
47GNUNET_PEERINFO_GTK_flags_shutdown (void);
48
49
50#endif
diff --git a/src/peerinfo/gnunet-peerinfo-gtk.c b/src/peerinfo/gnunet-peerinfo-gtk.c
index 90d501ac..28838b48 100644
--- a/src/peerinfo/gnunet-peerinfo-gtk.c
+++ b/src/peerinfo/gnunet-peerinfo-gtk.c
@@ -25,15 +25,60 @@
25 */ 25 */
26#include "gnunet_gtk.h" 26#include "gnunet_gtk.h"
27#include <gnunet/gnunet_peerinfo_service.h> 27#include <gnunet/gnunet_peerinfo_service.h>
28#include <gnunet/gnunet_transport_service.h>
29#include <gnunet/gnunet_core_service.h>
30#include "gnunet-peerinfo-gtk-flags.h"
31
32
33/**
34 * Information we track for each peer outside of the model.
35 */
36struct PeerInfo
37{
38 /**
39 * Reference to the peer in the view.
40 */
41 GtkTreeRowReference *rr;
42
43 /**
44 * Handle to an active lookup for addresses of this peer, or NULL.
45 */
46 struct GNUNET_TRANSPORT_PeerAddressLookupContext *palc;
47
48 /**
49 * Location where we store all addresses that were found during the 'palc' iteration.
50 */
51 char *palc_accumulator;
52
53 /**
54 * Total number of addresses found.
55 */
56 guint palc_counter;
57
58};
59
28 60
29/** 61/**
30 * Handle to our main loop. 62 * Handle to our main loop.
31 */ 63 */
32static struct GNUNET_GTK_MainLoop *ml; 64static struct GNUNET_GTK_MainLoop *ml;
33 65
66/**
67 * Handle for our notifications from peerinfo about new peers.
68 */
34static struct GNUNET_PEERINFO_NotifyContext *pnc; 69static struct GNUNET_PEERINFO_NotifyContext *pnc;
35 70
36/** 71/**
72 * Handle to core service.
73 */
74static struct GNUNET_CORE_Handle *core;
75
76/**
77 * Map of peer identities to the respective PeerInfo for our view.
78 */
79static struct GNUNET_CONTAINER_MultiHashMap *peer2info;
80
81/**
37 * Should gnunet-peerinfo-gtk start in tray mode? 82 * Should gnunet-peerinfo-gtk start in tray mode?
38 */ 83 */
39static int tray_only; 84static int tray_only;
@@ -48,6 +93,7 @@ get_configuration ()
48 return GNUNET_GTK_main_loop_get_configuration (ml); 93 return GNUNET_GTK_main_loop_get_configuration (ml);
49} 94}
50 95
96
51/** 97/**
52 * Get an object from the main window. 98 * Get an object from the main window.
53 * 99 *
@@ -62,6 +108,35 @@ get_object (const char *name)
62 108
63 109
64/** 110/**
111 * Function called on each entry in the 'peer2info' map
112 * to free the associated path.
113 *
114 * @param cls unused
115 * @param key peer identity
116 * @param value the 'struct PeerInfo'
117 * @return GNUNET_OK (continue to iterate)
118 */
119static int
120free_paths (void *cls,
121 const GNUNET_HashCode *key,
122 void *value)
123{
124 struct PeerInfo *info = value;
125
126 if (NULL != info->palc)
127 {
128 GNUNET_TRANSPORT_peer_address_lookup_cancel (info->palc);
129 info->palc = NULL;
130 GNUNET_free (info->palc_accumulator);
131 info->palc_accumulator = NULL;
132 }
133 gtk_tree_row_reference_free (info->rr);
134 GNUNET_free (info);
135 return GNUNET_OK;
136}
137
138
139/**
65 * Task run on shutdown. 140 * Task run on shutdown.
66 * 141 *
67 * @param cls unused 142 * @param cls unused
@@ -73,6 +148,79 @@ shutdown_task (void *cls,
73{ 148{
74 GNUNET_PEERINFO_notify_cancel (pnc); 149 GNUNET_PEERINFO_notify_cancel (pnc);
75 pnc = NULL; 150 pnc = NULL;
151 if (NULL != core)
152 {
153 GNUNET_CORE_disconnect (core);
154 core = NULL;
155 }
156 GNUNET_CONTAINER_multihashmap_iterate (peer2info,
157 &free_paths,
158 NULL);
159 GNUNET_CONTAINER_multihashmap_destroy (peer2info);
160 peer2info = NULL;
161 GNUNET_PEERINFO_GTK_flags_shutdown ();
162}
163
164
165/**
166 * Function to call with a binary format of an address
167 *
168 * @param cls the 'struct PeerInfo' for which this is a valid address
169 * @param address NULL on error, otherwise 0-terminated printable UTF-8 string
170 */
171static void
172peer_address_cb (void *cls,
173 const char *address)
174{
175 struct PeerInfo *info = cls;
176 char *tmp;
177 GtkListStore *ls;
178 GtkTreeModel *tm;
179 GtkTreeIter iter;
180 GtkTreePath *path;
181 const char *colon;
182 const char *dot;
183 char *country;
184
185 if (NULL == address)
186 {
187 /* last address, store information in model */
188 country = NULL;
189 colon = strstr (info->palc_accumulator, ":");
190 if (NULL != colon)
191 {
192 for (dot = colon - 1; dot != info->palc_accumulator; dot--)
193 if ('.' == *dot)
194 break;
195 if ('.' == *dot)
196 country = GNUNET_strndup (&dot[1], (colon - dot) - 1);
197 }
198 ls = GTK_LIST_STORE (get_object ("GNUNET_PEERINFO_GTK_list_store"));
199 tm = GTK_TREE_MODEL (ls);
200 path = gtk_tree_row_reference_get_path (info->rr);
201 GNUNET_assert (NULL != path);
202 GNUNET_assert (TRUE ==
203 gtk_tree_model_get_iter (tm, &iter, path));
204 gtk_tree_path_free (path);
205 gtk_list_store_set (ls, &iter,
206 1, info->palc_counter,
207 2, country,
208 3, GNUNET_PEERINFO_GTK_get_flag (country),
209 6, &info->palc_accumulator[1],
210 -1);
211 GNUNET_free_non_null (country);
212 info->palc = NULL;
213 GNUNET_free (info->palc_accumulator);
214 info->palc_accumulator = NULL;
215 return;
216 }
217 GNUNET_asprintf (&tmp,
218 "%s|%s",
219 info->palc_accumulator,
220 address);
221 GNUNET_free (info->palc_accumulator);
222 info->palc_accumulator = tmp;
223 info->palc_counter++;
76} 224}
77 225
78 226
@@ -93,46 +241,124 @@ peerinfo_processor (void *cls,
93 GtkListStore *ls; 241 GtkListStore *ls;
94 GtkTreeModel *tm; 242 GtkTreeModel *tm;
95 GtkTreeIter iter; 243 GtkTreeIter iter;
96 int found;
97 gchar *pid;
98 const char *npid; 244 const char *npid;
99 struct GNUNET_CRYPTO_HashAsciiEncoded enc; 245 struct GNUNET_CRYPTO_HashAsciiEncoded enc;
246 struct PeerInfo *info;
247 GtkTreePath *path;
100 248
101 GNUNET_CRYPTO_hash_to_enc (&peer->hashPubKey, &enc);
102 npid = (const char *) &enc;
103 ls = GTK_LIST_STORE (get_object ("GNUNET_PEERINFO_GTK_list_store")); 249 ls = GTK_LIST_STORE (get_object ("GNUNET_PEERINFO_GTK_list_store"));
250 if (NULL == ls)
251 {
252 GNUNET_break (0);
253 return;
254 }
104 tm = GTK_TREE_MODEL (ls); 255 tm = GTK_TREE_MODEL (ls);
105 found = GNUNET_NO; 256 info = GNUNET_CONTAINER_multihashmap_get (peer2info,
106 if (TRUE == gtk_tree_model_get_iter_first (tm, &iter)) 257 &peer->hashPubKey);
107 { 258 if (NULL == info)
108 do
109 { 259 {
110 pid = NULL; 260 GNUNET_CRYPTO_hash_to_enc (&peer->hashPubKey, &enc);
111 gtk_tree_model_get (tm, &iter, 0, &pid, -1); 261 npid = (const char *) &enc;
112 if (pid != NULL) 262 gtk_list_store_append (ls, &iter);
113 { 263 gtk_list_store_set (ls, &iter,
114 if (0 == strcmp (pid, npid)) 264 0, npid,
115 { 265 1, 0 /* number of known addresses */ ,
116 found = GNUNET_YES; 266 2, "" /* country name */ ,
117 g_free (pid); 267 3, NULL /* country flag */ ,
118 break; 268 4, (guint64) 0 /* bandwidth-in */ ,
119 } 269 5, (guint64) 0 /* bandwidth-out */ ,
120 } 270 6, "" /* addresses as strings */,
121 g_free (pid); 271 -1);
272 path = gtk_tree_model_get_path (tm, &iter);
273 info = GNUNET_malloc (sizeof (struct PeerInfo));
274 info->rr = gtk_tree_row_reference_new (tm, path);
275 GNUNET_assert (NULL != info->rr);
276 gtk_tree_path_free (path);
277 GNUNET_CONTAINER_multihashmap_put (peer2info,
278 &peer->hashPubKey,
279 info,
280 GNUNET_CONTAINER_MULTIHASHMAPOPTION_UNIQUE_ONLY);
122 } 281 }
123 while ((found == GNUNET_NO) && 282 if (NULL == info->palc)
124 (TRUE == gtk_tree_model_iter_next (tm, &iter))); 283 {
125 } 284 info->palc_accumulator = GNUNET_strdup ("|");
126 if (found == GNUNET_NO) 285 info->palc_counter = 0;
127 gtk_list_store_append (ls, &iter); 286 info->palc = GNUNET_TRANSPORT_peer_address_lookup (get_configuration(),
287 peer,
288 GNUNET_TIME_UNIT_MINUTES,
289 &peer_address_cb,
290 info);
291 }
292
293}
294
295
296/**
297 * Function called after GNUNET_CORE_connect has succeeded
298 * (or failed for good). Note that the private key of the
299 * peer is intentionally not exposed here; if you need it,
300 * your process should try to read the private key file
301 * directly (which should work if you are authorized...).
302 *
303 * @param cls closure
304 * @param server handle to the server, NULL if we failed
305 * @param my_identity ID of this peer, NULL if we failed
306 * @param publicKey public key of this peer, NULL if we failed
307 */
308static void
309init_cb (void *cls,
310 struct GNUNET_CORE_Handle * server,
311 const struct GNUNET_PeerIdentity *
312 my_identity,
313 const struct
314 GNUNET_CRYPTO_RsaPublicKeyBinaryEncoded
315 * publicKey)
316{
317 /* FIXME: should probably do something to my 'own' entry
318 in the peerinfo list to make it stand out */
319}
320
321
322/**
323 * Method called whenever a given peer has a status change.
324 *
325 * @param cls closure
326 * @param peer peer identity this notification is about
327 * @param timeout absolute time when this peer will time out
328 * unless we see some further activity from it
329 * @param bandwidth_in available amount of inbound bandwidth
330 * @param bandwidth_out available amount of outbound bandwidth
331 * @param atsi performance data for the connection
332 */
333static void
334status_cb (void *cls,
335 const struct GNUNET_PeerIdentity * peer,
336 struct GNUNET_BANDWIDTH_Value32NBO bandwidth_in,
337 struct GNUNET_BANDWIDTH_Value32NBO bandwidth_out,
338 struct GNUNET_TIME_Absolute timeout,
339 const struct GNUNET_TRANSPORT_ATS_Information* atsi)
340{
341 struct PeerInfo *info;
342 GtkListStore *ls;
343 GtkTreeModel *tm;
344 GtkTreeIter iter;
345 GtkTreePath *path;
346
347 info = GNUNET_CONTAINER_multihashmap_get (peer2info,
348 &peer->hashPubKey);
349 if (NULL == info)
350 return; /* should rarely happen... */
351 ls = GTK_LIST_STORE (get_object ("GNUNET_PEERINFO_GTK_list_store"));
352 tm = GTK_TREE_MODEL (ls);
353 path = gtk_tree_row_reference_get_path (info->rr);
354 GNUNET_assert (NULL != path);
355 GNUNET_assert (TRUE ==
356 gtk_tree_model_get_iter (tm, &iter, path));
357 gtk_tree_path_free (path);
128 gtk_list_store_set (ls, &iter, 358 gtk_list_store_set (ls, &iter,
129 0, npid, 359 4, (guint64) ntohl (bandwidth_in.value__),
130 1, 0 /* number of known addresses */ , 360 5, (guint64) ntohl (bandwidth_out.value__),
131 2, "" /* country name */ , 361 -1);
132 3, NULL /* country flag */ ,
133 4, 0 /* bandwidth */ ,
134 5, "" /* addresses as strings */,
135 -1);
136} 362}
137 363
138 364
@@ -160,6 +386,7 @@ run (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc)
160 386
161 GNUNET_GTK_set_icon_search_path (); 387 GNUNET_GTK_set_icon_search_path ();
162 GNUNET_GTK_setup_nls (); 388 GNUNET_GTK_setup_nls ();
389 peer2info = GNUNET_CONTAINER_multihashmap_create (256);
163 pnc = GNUNET_PEERINFO_notify (get_configuration(), 390 pnc = GNUNET_PEERINFO_notify (get_configuration(),
164 &peerinfo_processor, NULL); 391 &peerinfo_processor, NULL);
165 if (pnc == NULL) 392 if (pnc == NULL)
@@ -167,6 +394,14 @@ run (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc)
167 fprintf (stderr, _("Failed to initialize communication with peerinfo service!\n")); 394 fprintf (stderr, _("Failed to initialize communication with peerinfo service!\n"));
168 exit (1); 395 exit (1);
169 } 396 }
397 core = GNUNET_CORE_connect (get_configuration(),
398 1, NULL,
399 &init_cb,
400 NULL, NULL,
401 &status_cb,
402 NULL, GNUNET_NO,
403 NULL, GNUNET_NO,
404 NULL);
170 405
171 /* setup main window */ 406 /* setup main window */
172 main_window = 407 main_window =