aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorChristian Grothoff <christian@grothoff.org>2012-03-01 08:24:17 +0000
committerChristian Grothoff <christian@grothoff.org>2012-03-01 08:24:17 +0000
commit2768306ebbaee4936fdd57398f2f54e7e4018b1f (patch)
tree03261d585de6289b50a3f850cd6f33b302ab4407
parentff56613c903265d0c96b782b064bffa10d1c1fdc (diff)
downloadgnunet-2768306ebbaee4936fdd57398f2f54e7e4018b1f.tar.gz
gnunet-2768306ebbaee4936fdd57398f2f54e7e4018b1f.zip
LRN: updates to pseudonym API from #1952, change pseudonym management
-rw-r--r--src/chat/gnunet-chat.c96
-rw-r--r--src/fs/fs_uri.c12
-rw-r--r--src/fs/gnunet-pseudonym.c23
-rw-r--r--src/include/gnunet_pseudonym_lib.h72
-rw-r--r--src/util/pseudonym.c201
-rw-r--r--src/util/test_pseudonym.c30
6 files changed, 344 insertions, 90 deletions
diff --git a/src/chat/gnunet-chat.c b/src/chat/gnunet-chat.c
index 4abc58c9f..fb958d98a 100644
--- a/src/chat/gnunet-chat.c
+++ b/src/chat/gnunet-chat.c
@@ -114,14 +114,27 @@ receive_cb (void *cls, struct GNUNET_CHAT_Room *room,
114 const char *message, struct GNUNET_TIME_Absolute timestamp, 114 const char *message, struct GNUNET_TIME_Absolute timestamp,
115 enum GNUNET_CHAT_MsgOptions options) 115 enum GNUNET_CHAT_MsgOptions options)
116{ 116{
117 char *non_unique_nick;
117 char *nick; 118 char *nick;
119 int nick_is_a_dup;
118 char *time; 120 char *time;
119 const char *fmt; 121 const char *fmt;
120 122
121 if (NULL != sender) 123 if (NULL == sender)
122 nick = GNUNET_PSEUDONYM_id_to_name (cfg, sender);
123 else
124 nick = GNUNET_strdup (_("anonymous")); 124 nick = GNUNET_strdup (_("anonymous"));
125 else
126 {
127 if (GNUNET_OK != GNUNET_PSEUDONYM_get_info (cfg,
128 sender, NULL, NULL, &non_unique_nick, &nick_is_a_dup)
129 || (nick_is_a_dup == GNUNET_YES))
130 {
131 GNUNET_free (non_unique_nick);
132 non_unique_nick = GNUNET_strdup (_("anonymous"));
133 }
134 nick = GNUNET_PSEUDONYM_name_uniquify (cfg, sender, non_unique_nick, NULL);
135 GNUNET_free (non_unique_nick);
136 }
137
125 fmt = NULL; 138 fmt = NULL;
126 switch ((int) options) 139 switch ((int) options)
127 { 140 {
@@ -188,9 +201,20 @@ confirmation_cb (void *cls, struct GNUNET_CHAT_Room *room,
188 const GNUNET_HashCode * receiver) 201 const GNUNET_HashCode * receiver)
189{ 202{
190 char *nick; 203 char *nick;
204 char *unique_nick;
205 int nick_is_a_dup;
191 206
192 nick = GNUNET_PSEUDONYM_id_to_name (cfg, receiver); 207 if (GNUNET_OK != GNUNET_PSEUDONYM_get_info (cfg,
193 FPRINTF (stdout, _("'%s' acknowledged message #%d\n"), nick, orig_seq_number); 208 receiver, NULL, NULL, &nick, &nick_is_a_dup)
209 || (nick_is_a_dup == GNUNET_YES))
210 {
211 GNUNET_free (nick);
212 nick = GNUNET_strdup (_("anonymous"));
213 }
214 unique_nick = GNUNET_PSEUDONYM_name_uniquify (cfg, receiver, nick, NULL);
215 GNUNET_free (nick);
216 FPRINTF (stdout, _("'%s' acknowledged message #%d\n"), unique_nick, orig_seq_number);
217 GNUNET_free (unique_nick);
194 return GNUNET_OK; 218 return GNUNET_OK;
195} 219}
196 220
@@ -210,7 +234,8 @@ member_list_cb (void *cls, const struct GNUNET_CONTAINER_MetaData *member_info,
210 const struct GNUNET_CRYPTO_RsaPublicKeyBinaryEncoded *member_id, 234 const struct GNUNET_CRYPTO_RsaPublicKeyBinaryEncoded *member_id,
211 enum GNUNET_CHAT_MsgOptions options) 235 enum GNUNET_CHAT_MsgOptions options)
212{ 236{
213 char *nick; 237 char *nick, *non_unique_nick;
238 int nick_is_a_dup;
214 GNUNET_HashCode id; 239 GNUNET_HashCode id;
215 struct UserList *pos; 240 struct UserList *pos;
216 struct UserList *prev; 241 struct UserList *prev;
@@ -218,7 +243,16 @@ member_list_cb (void *cls, const struct GNUNET_CONTAINER_MetaData *member_info,
218 GNUNET_CRYPTO_hash (member_id, 243 GNUNET_CRYPTO_hash (member_id,
219 sizeof (struct GNUNET_CRYPTO_RsaPublicKeyBinaryEncoded), 244 sizeof (struct GNUNET_CRYPTO_RsaPublicKeyBinaryEncoded),
220 &id); 245 &id);
221 nick = GNUNET_PSEUDONYM_id_to_name (cfg, &id); 246 if (GNUNET_OK != GNUNET_PSEUDONYM_get_info (cfg,
247 &id, NULL, NULL, &non_unique_nick, &nick_is_a_dup)
248 || (nick_is_a_dup == GNUNET_YES))
249 {
250 GNUNET_free (non_unique_nick);
251 non_unique_nick = GNUNET_strdup (_("anonymous"));
252 }
253 nick = GNUNET_PSEUDONYM_name_uniquify (cfg, &id, non_unique_nick, NULL);
254 GNUNET_free (non_unique_nick);
255
222 FPRINTF (stdout, 256 FPRINTF (stdout,
223 member_info != 257 member_info !=
224 NULL ? _("`%s' entered the room\n") : _("`%s' left the room\n"), 258 NULL ? _("`%s' entered the room\n") : _("`%s' left the room\n"),
@@ -267,6 +301,7 @@ static int
267do_join (const char *arg, const void *xtra) 301do_join (const char *arg, const void *xtra)
268{ 302{
269 char *my_name; 303 char *my_name;
304 int my_name_is_a_dup;
270 GNUNET_HashCode me; 305 GNUNET_HashCode me;
271 306
272 if (arg[0] == '#') 307 if (arg[0] == '#')
@@ -284,7 +319,16 @@ do_join (const char *arg, const void *xtra)
284 FPRINTF (stdout, "%s", _("Could not change username\n")); 319 FPRINTF (stdout, "%s", _("Could not change username\n"));
285 return GNUNET_SYSERR; 320 return GNUNET_SYSERR;
286 } 321 }
287 my_name = GNUNET_PSEUDONYM_id_to_name (cfg, &me); 322 if ((GNUNET_OK != GNUNET_PSEUDONYM_get_info (cfg,
323 &me, NULL, NULL, &my_name, &my_name_is_a_dup)) ||
324 (my_name_is_a_dup == GNUNET_YES))
325 {
326 GNUNET_free (my_name);
327 my_name = GNUNET_strdup (_("anonymous"));
328 }
329 /* Don't uniquify our own name - other people will have a different
330 * suffix for our own name anyway.
331 */
288 FPRINTF (stdout, _("Joining room `%s' as user `%s'...\n"), room_name, 332 FPRINTF (stdout, _("Joining room `%s' as user `%s'...\n"), room_name,
289 my_name); 333 my_name);
290 GNUNET_free (my_name); 334 GNUNET_free (my_name);
@@ -296,6 +340,7 @@ static int
296do_nick (const char *msg, const void *xtra) 340do_nick (const char *msg, const void *xtra)
297{ 341{
298 char *my_name; 342 char *my_name;
343 int my_name_is_a_dup;
299 GNUNET_HashCode me; 344 GNUNET_HashCode me;
300 345
301 GNUNET_CHAT_leave_room (room); 346 GNUNET_CHAT_leave_room (room);
@@ -316,7 +361,13 @@ do_nick (const char *msg, const void *xtra)
316 FPRINTF (stdout, "%s", _("Could not change username\n")); 361 FPRINTF (stdout, "%s", _("Could not change username\n"));
317 return GNUNET_SYSERR; 362 return GNUNET_SYSERR;
318 } 363 }
319 my_name = GNUNET_PSEUDONYM_id_to_name (cfg, &me); 364 if ((GNUNET_OK != GNUNET_PSEUDONYM_get_info (cfg,
365 &me, NULL, NULL, &my_name, &my_name_is_a_dup)) ||
366 (my_name_is_a_dup == GNUNET_YES))
367 {
368 GNUNET_free (my_name);
369 my_name = GNUNET_strdup (_("anonymous"));
370 }
320 FPRINTF (stdout, _("Changed username to `%s'\n"), my_name); 371 FPRINTF (stdout, _("Changed username to `%s'\n"), my_name);
321 GNUNET_free (my_name); 372 GNUNET_free (my_name);
322 return GNUNET_OK; 373 return GNUNET_OK;
@@ -327,6 +378,8 @@ static int
327do_names (const char *msg, const void *xtra) 378do_names (const char *msg, const void *xtra)
328{ 379{
329 char *name; 380 char *name;
381 char *unique_name;
382 int name_is_a_dup;
330 struct UserList *pos; 383 struct UserList *pos;
331 GNUNET_HashCode pid; 384 GNUNET_HashCode pid;
332 385
@@ -337,9 +390,17 @@ do_names (const char *msg, const void *xtra)
337 GNUNET_CRYPTO_hash (&pos->pkey, 390 GNUNET_CRYPTO_hash (&pos->pkey,
338 sizeof (struct GNUNET_CRYPTO_RsaPublicKeyBinaryEncoded), 391 sizeof (struct GNUNET_CRYPTO_RsaPublicKeyBinaryEncoded),
339 &pid); 392 &pid);
340 name = GNUNET_PSEUDONYM_id_to_name (cfg, &pid); 393 if (GNUNET_OK != GNUNET_PSEUDONYM_get_info (cfg,
341 FPRINTF (stdout, "`%s' ", name); 394 &pid, NULL, NULL, &name, &name_is_a_dup)
395 || (name_is_a_dup == GNUNET_YES))
396 {
397 GNUNET_free (name);
398 name = GNUNET_strdup (_("anonymous"));
399 }
400 unique_name = GNUNET_PSEUDONYM_name_uniquify (cfg, &pid, name, NULL);
342 GNUNET_free (name); 401 GNUNET_free (name);
402 FPRINTF (stdout, "`%s' ", unique_name);
403 GNUNET_free (unique_name);
343 pos = pos->next; 404 pos = pos->next;
344 } 405 }
345 FPRINTF (stdout, "%s", "\n"); 406 FPRINTF (stdout, "%s", "\n");
@@ -376,7 +437,9 @@ do_send_pm (const char *msg, const void *xtra)
376 msg += strlen (user) + 1; 437 msg += strlen (user) + 1;
377 if (GNUNET_OK != GNUNET_PSEUDONYM_name_to_id (cfg, user, &uid)) 438 if (GNUNET_OK != GNUNET_PSEUDONYM_name_to_id (cfg, user, &uid))
378 { 439 {
379 FPRINTF (stderr, _("Unknown user `%s'\n"), user); 440 FPRINTF (stderr,
441 _("Unknown user `%s'. Make sure you specify its numeric suffix, if any.\n"),
442 user);
380 GNUNET_free (user); 443 GNUNET_free (user);
381 return GNUNET_OK; 444 return GNUNET_OK;
382 } 445 }
@@ -598,6 +661,7 @@ run (void *cls, char *const *args, const char *cfgfile,
598{ 661{
599 GNUNET_HashCode me; 662 GNUNET_HashCode me;
600 char *my_name; 663 char *my_name;
664 int my_name_is_a_dup;
601 665
602 cfg = c; 666 cfg = c;
603 /* check arguments */ 667 /* check arguments */
@@ -626,7 +690,13 @@ run (void *cls, char *const *args, const char *cfgfile,
626 ret = -1; 690 ret = -1;
627 return; 691 return;
628 } 692 }
629 my_name = GNUNET_PSEUDONYM_id_to_name (cfg, &me); 693 if ((GNUNET_OK != GNUNET_PSEUDONYM_get_info (cfg,
694 &me, NULL, NULL, &my_name, &my_name_is_a_dup)) ||
695 (my_name_is_a_dup == GNUNET_YES))
696 {
697 GNUNET_free (my_name);
698 my_name = GNUNET_strdup (_("anonymous"));
699 }
630 FPRINTF (stdout, _("Joining room `%s' as user `%s'...\n"), room_name, 700 FPRINTF (stdout, _("Joining room `%s' as user `%s'...\n"), room_name,
631 my_name); 701 my_name);
632 GNUNET_free (my_name); 702 GNUNET_free (my_name);
diff --git a/src/fs/fs_uri.c b/src/fs/fs_uri.c
index 5dfdcb54d..43cf2c5bd 100644
--- a/src/fs/fs_uri.c
+++ b/src/fs/fs_uri.c
@@ -1377,15 +1377,17 @@ GNUNET_FS_uri_sks_to_string_fancy (struct GNUNET_CONFIGURATION_Handle *cfg,
1377 const struct GNUNET_FS_Uri *uri) 1377 const struct GNUNET_FS_Uri *uri)
1378{ 1378{
1379 char *ret; 1379 char *ret;
1380 char *name; 1380 char *name, *unique_name;
1381 int getinfo_result;
1381 1382
1382 if (uri->type != sks) 1383 if (uri->type != sks)
1383 return NULL; 1384 return NULL;
1384 name = GNUNET_PSEUDONYM_id_to_name (cfg, &uri->data.sks.namespace); 1385 getinfo_result = GNUNET_PSEUDONYM_get_info (cfg, &uri->data.sks.namespace,
1385 if (name == NULL) 1386 NULL, NULL, &name, NULL);
1386 return GNUNET_FS_uri_to_string (uri); 1387 unique_name = GNUNET_PSEUDONYM_name_uniquify (cfg, &uri->data.sks.namespace, name, NULL);
1387 GNUNET_asprintf (&ret, "%s: %s", name, uri->data.sks.identifier);
1388 GNUNET_free (name); 1388 GNUNET_free (name);
1389 GNUNET_asprintf (&ret, "%s: %s", unique_name, uri->data.sks.identifier);
1390 GNUNET_free (unique_name);
1389 return ret; 1391 return ret;
1390} 1392}
1391 1393
diff --git a/src/fs/gnunet-pseudonym.c b/src/fs/gnunet-pseudonym.c
index 412ddd2b0..247a5a0d8 100644
--- a/src/fs/gnunet-pseudonym.c
+++ b/src/fs/gnunet-pseudonym.c
@@ -106,20 +106,28 @@ ns_printer (void *cls, const char *name, const GNUNET_HashCode * id)
106 106
107static int 107static int
108pseudo_printer (void *cls, const GNUNET_HashCode * pseudonym, 108pseudo_printer (void *cls, const GNUNET_HashCode * pseudonym,
109 const char *name, const char *unique_name,
109 const struct GNUNET_CONTAINER_MetaData *md, int rating) 110 const struct GNUNET_CONTAINER_MetaData *md, int rating)
110{ 111{
111 char *id; 112 char *id, *unique_id;
112 113 int getinfo_result;
113 id = GNUNET_PSEUDONYM_id_to_name (cfg, pseudonym); 114
114 if (id == NULL) 115 /* While we get a name from the caller, it might be NULL.
116 * GNUNET_PSEUDONYM_get_info () never returns NULL.
117 */
118 getinfo_result = GNUNET_PSEUDONYM_get_info (cfg, pseudonym,
119 NULL, NULL, &id, NULL);
120 if (getinfo_result != GNUNET_OK)
115 { 121 {
116 GNUNET_break (0); 122 GNUNET_break (0);
117 return GNUNET_OK; 123 return GNUNET_OK;
118 } 124 }
119 FPRINTF (stdout, "%s (%d):\n", id, rating); 125 unique_id = GNUNET_PSEUDONYM_name_uniquify (cfg, pseudonym, id, NULL);
126 GNUNET_free (id);
127 FPRINTF (stdout, "%s (%d):\n", unique_id, rating);
120 GNUNET_CONTAINER_meta_data_iterate (md, &EXTRACTOR_meta_data_print, stdout); 128 GNUNET_CONTAINER_meta_data_iterate (md, &EXTRACTOR_meta_data_print, stdout);
121 FPRINTF (stdout, "%s", "\n"); 129 FPRINTF (stdout, "%s", "\n");
122 GNUNET_free (id); 130 GNUNET_free (unique_id);
123 return GNUNET_OK; 131 return GNUNET_OK;
124} 132}
125 133
@@ -162,7 +170,8 @@ post_advertising (void *cls, const struct GNUNET_FS_Uri *uri, const char *emsg)
162 } 170 }
163 else 171 else
164 { 172 {
165 GNUNET_log (GNUNET_ERROR_TYPE_ERROR, _("Namespace `%s' unknown.\n"), 173 GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
174 ("Namespace `%s' unknown. Make sure you specify its numeric suffix, if any.\n"),
166 rating_change); 175 rating_change);
167 } 176 }
168 } 177 }
diff --git a/src/include/gnunet_pseudonym_lib.h b/src/include/gnunet_pseudonym_lib.h
index bde98ef8f..8fd938da8 100644
--- a/src/include/gnunet_pseudonym_lib.h
+++ b/src/include/gnunet_pseudonym_lib.h
@@ -44,12 +44,16 @@ extern "C"
44 * 44 *
45 * @param cls closure 45 * @param cls closure
46 * @param pseudonym hash code of public key of pseudonym 46 * @param pseudonym hash code of public key of pseudonym
47 * @param name name of the pseudonym (might be NULL)
48 * @param unique_name unique name of the pseudonym (might be NULL)
47 * @param md meta data known about the pseudonym 49 * @param md meta data known about the pseudonym
48 * @param rating the local rating of the pseudonym 50 * @param rating the local rating of the pseudonym
49 * @return GNUNET_OK to continue iteration, GNUNET_SYSERR to abort 51 * @return GNUNET_OK to continue iteration, GNUNET_SYSERR to abort
50 */ 52 */
51typedef int (*GNUNET_PSEUDONYM_Iterator) (void *cls, 53typedef int (*GNUNET_PSEUDONYM_Iterator) (void *cls,
52 const GNUNET_HashCode * pseudonym, 54 const GNUNET_HashCode * pseudonym,
55 const char *name,
56 const char *unique_name,
53 const struct GNUNET_CONTAINER_MetaData 57 const struct GNUNET_CONTAINER_MetaData
54 * md, int rating); 58 * md, int rating);
55 59
@@ -110,22 +114,76 @@ GNUNET_PSEUDONYM_discovery_callback_unregister (GNUNET_PSEUDONYM_Iterator
110 iterator, void *closure); 114 iterator, void *closure);
111 115
112/** 116/**
113 * Return the unique, human readable name for the given pseudonym. 117 * Return unique variant of the namespace name.
118 * Use after GNUNET_PSEUDONYM_id_to_name() to make sure
119 * that name is unique.
114 * 120 *
115 * @return NULL on failure (should never happen) 121 * @param cfg configuration
122 * @param nsid cryptographic ID of the namespace
123 * @param name name to uniquify
124 * @param suffix if not NULL, filled with the suffix value
125 * @return NULL on failure (should never happen), name on success.
126 * Free the name with GNUNET_free().
116 */ 127 */
117char * 128char *
118GNUNET_PSEUDONYM_id_to_name (const struct GNUNET_CONFIGURATION_Handle *cfg, 129GNUNET_PSEUDONYM_name_uniquify (const struct GNUNET_CONFIGURATION_Handle *cfg,
119 const GNUNET_HashCode * pseudo); 130 const GNUNET_HashCode * nsid, const char *name, unsigned int *suffix);
120 131
121/** 132/**
122 * Get the pseudonym ID belonging to the given human readable name. 133 * Get namespace name, metadata and rank
134 * This is a wrapper around internal read_info() call, and ensures that
135 * returned data is not invalid (not NULL).
136 * Writing back information returned by this function will give
137 * a name "no-name" to pseudonyms that have no name. This side-effect is
138 * unavoidable, but hardly harmful.
123 * 139 *
124 * @return GNUNET_OK on success 140 * @param cfg configuration
141 * @param nsid cryptographic ID of the namespace
142 * @param ret_meta a location to store metadata pointer. NULL, if metadata
143 * is not needed. Destroy with GNUNET_CONTAINER_meta_data_destroy().
144 * @param ret_rank a location to store rank. NULL, if rank not needed.
145 * @param ret_name a location to store human-readable name. Name is not unique.
146 * NULL, if name is not needed. Free with GNUNET_free().
147 * @param name_is_a_dup is set to GNUNET_YES, if ret_name was filled with
148 * a duplicate of a "no-name" placeholder
149 * @return GNUNET_OK on success. GNUENT_SYSERR if the data was
150 * unobtainable (in that case ret_* are filled with placeholders -
151 * empty metadata container, rank -1 and a "no-name" name).
152 */
153int
154GNUNET_PSEUDONYM_get_info (const struct GNUNET_CONFIGURATION_Handle *cfg,
155 const GNUNET_HashCode * nsid, struct GNUNET_CONTAINER_MetaData **ret_meta,
156 int32_t *ret_rank, char **ret_name, int *name_is_a_dup);
157
158
159/**
160 * Get the namespace ID belonging to the given namespace name.
161 *
162 * @param cfg configuration to use
163 * @param ns_uname unique (!) human-readable name for the namespace
164 * @param nsid set to namespace ID based on 'ns_uname'
165 * @return GNUNET_OK on success, GNUNET_SYSERR on failure
125 */ 166 */
126int 167int
127GNUNET_PSEUDONYM_name_to_id (const struct GNUNET_CONFIGURATION_Handle *cfg, 168GNUNET_PSEUDONYM_name_to_id (const struct GNUNET_CONFIGURATION_Handle *cfg,
128 const char *hname, GNUNET_HashCode * psid); 169 const char *ns_uname, GNUNET_HashCode * nsid);
170
171/**
172 * Set the pseudonym metadata, rank and name.
173 *
174 * @param cfg overall configuration
175 * @param nsid id of the pseudonym
176 * @param name name to set. Must be the non-unique version of it.
177 * May be NULL, in which case it erases pseudonym's name!
178 * @param md metadata to set
179 * May be NULL, in which case it erases pseudonym's metadata!
180 * @param rank rank to assign
181 * @return GNUNET_OK on success, GNUNET_SYSERR on failure
182 */
183int
184GNUNET_PSEUDONYM_set_info (const struct GNUNET_CONFIGURATION_Handle *cfg,
185 const GNUNET_HashCode * nsid, const char *name,
186 const struct GNUNET_CONTAINER_MetaData *md, int rank);
129 187
130 188
131#if 0 /* keep Emacsens' auto-indent happy */ 189#if 0 /* keep Emacsens' auto-indent happy */
diff --git a/src/util/pseudonym.c b/src/util/pseudonym.c
index 782a405fc..dd8ad08b3 100644
--- a/src/util/pseudonym.c
+++ b/src/util/pseudonym.c
@@ -96,7 +96,7 @@ internal_notify (const GNUNET_HashCode * id,
96 pos = head; 96 pos = head;
97 while (pos != NULL) 97 while (pos != NULL)
98 { 98 {
99 pos->callback (pos->closure, id, md, rating); 99 pos->callback (pos->closure, id, NULL, NULL, md, rating);
100 pos = pos->next; 100 pos = pos->next;
101 } 101 }
102} 102}
@@ -104,6 +104,9 @@ internal_notify (const GNUNET_HashCode * id,
104/** 104/**
105 * Register callback to be invoked whenever we discover 105 * Register callback to be invoked whenever we discover
106 * a new pseudonym. 106 * a new pseudonym.
107 * Will immediately call provided iterator callback for all
108 * already discovered pseudonyms.
109 *
107 * @param cfg configuration to use 110 * @param cfg configuration to use
108 * @param iterator iterator over pseudonym 111 * @param iterator iterator over pseudonym
109 * @param closure point to a closure 112 * @param closure point to a closure
@@ -185,7 +188,7 @@ get_data_filename (const struct GNUNET_CONFIGURATION_Handle *cfg,
185 * @param nsid hash code of a pseudonym 188 * @param nsid hash code of a pseudonym
186 * @param meta meta data to be written into a file 189 * @param meta meta data to be written into a file
187 * @param ranking ranking of a pseudonym 190 * @param ranking ranking of a pseudonym
188 * @param ns_name name of a pseudonym 191 * @param ns_name non-unique name of a pseudonym
189 */ 192 */
190static void 193static void
191write_pseudonym_info (const struct GNUNET_CONFIGURATION_Handle *cfg, 194write_pseudonym_info (const struct GNUNET_CONFIGURATION_Handle *cfg,
@@ -219,9 +222,9 @@ write_pseudonym_info (const struct GNUNET_CONFIGURATION_Handle *cfg,
219 } 222 }
220 GNUNET_free (fn); 223 GNUNET_free (fn);
221 /* create entry for pseudonym name in names */ 224 /* create entry for pseudonym name in names */
222 /* FIXME: 90% of what this call does is not needed 225 if (ns_name != NULL)
223 * here => refactor code to only create the entry! */ 226 GNUNET_free_non_null (GNUNET_PSEUDONYM_name_uniquify (cfg, nsid, ns_name,
224 GNUNET_free_non_null (GNUNET_PSEUDONYM_id_to_name (cfg, nsid)); 227 NULL));
225} 228}
226 229
227 230
@@ -285,57 +288,31 @@ read_info (const struct GNUNET_CONFIGURATION_Handle *cfg,
285 return GNUNET_OK; 288 return GNUNET_OK;
286} 289}
287 290
288
289
290/** 291/**
291 * Return the unique, human readable name for the given namespace. 292 * Return unique variant of the namespace name.
293 * Use it after GNUNET_PSEUDONYM_get_info() to make sure
294 * that name is unique.
292 * 295 *
293 * @param cfg configuration 296 * @param cfg configuration
294 * @param nsid cryptographic ID of the namespace 297 * @param nsid cryptographic ID of the namespace
295 * @return NULL on failure (should never happen) 298 * @param name name to uniquify
299 * @param suffix if not NULL, filled with the suffix value
300 * @return NULL on failure (should never happen), name on success.
301 * Free the name with GNUNET_free().
296 */ 302 */
297char * 303char *
298GNUNET_PSEUDONYM_id_to_name (const struct GNUNET_CONFIGURATION_Handle *cfg, 304GNUNET_PSEUDONYM_name_uniquify (const struct GNUNET_CONFIGURATION_Handle *cfg,
299 const GNUNET_HashCode * nsid) 305 const GNUNET_HashCode * nsid, const char *name, unsigned int *suffix)
300{ 306{
301 struct GNUNET_CONTAINER_MetaData *meta;
302 char *name;
303 GNUNET_HashCode nh; 307 GNUNET_HashCode nh;
304 char *fn;
305 uint64_t len; 308 uint64_t len;
309 char *fn;
306 struct GNUNET_DISK_FileHandle *fh; 310 struct GNUNET_DISK_FileHandle *fh;
307 unsigned int i; 311 unsigned int i;
308 unsigned int idx; 312 unsigned int idx;
309 char *ret; 313 char *ret;
310 struct stat sbuf; 314 struct stat sbuf;
311 int32_t temp = 0;
312 int32_t *rank = &temp;
313 315
314 meta = NULL;
315 name = NULL;
316 if (GNUNET_OK == read_info (cfg, nsid, &meta, rank, &name))
317 {
318 if ((meta != NULL) && (name == NULL))
319 name =
320 GNUNET_CONTAINER_meta_data_get_first_by_types (meta,
321 EXTRACTOR_METATYPE_TITLE,
322 EXTRACTOR_METATYPE_GNUNET_ORIGINAL_FILENAME,
323 EXTRACTOR_METATYPE_FILENAME,
324 EXTRACTOR_METATYPE_DESCRIPTION,
325 EXTRACTOR_METATYPE_SUBJECT,
326 EXTRACTOR_METATYPE_PUBLISHER,
327 EXTRACTOR_METATYPE_AUTHOR_NAME,
328 EXTRACTOR_METATYPE_COMMENT,
329 EXTRACTOR_METATYPE_SUMMARY,
330 -1);
331 if (meta != NULL)
332 {
333 GNUNET_CONTAINER_meta_data_destroy (meta);
334 meta = NULL;
335 }
336 }
337 if (name == NULL)
338 name = GNUNET_strdup (_("no-name"));
339 GNUNET_CRYPTO_hash (name, strlen (name), &nh); 316 GNUNET_CRYPTO_hash (name, strlen (name), &nh);
340 fn = get_data_filename (cfg, PS_NAMES_DIR, &nh); 317 fn = get_data_filename (cfg, PS_NAMES_DIR, &nh);
341 GNUNET_assert (fn != NULL); 318 GNUNET_assert (fn != NULL);
@@ -372,22 +349,107 @@ GNUNET_PSEUDONYM_id_to_name (const struct GNUNET_CONFIGURATION_Handle *cfg,
372 GNUNET_DISK_file_close (fh); 349 GNUNET_DISK_file_close (fh);
373 ret = GNUNET_malloc (strlen (name) + 32); 350 ret = GNUNET_malloc (strlen (name) + 32);
374 GNUNET_snprintf (ret, strlen (name) + 32, "%s-%u", name, idx); 351 GNUNET_snprintf (ret, strlen (name) + 32, "%s-%u", name, idx);
375 GNUNET_free (name); 352 if (suffix != NULL)
353 *suffix = idx;
376 GNUNET_free (fn); 354 GNUNET_free (fn);
377 return ret; 355 return ret;
378} 356}
379 357
380/** 358/**
359 * Get namespace name, metadata and rank
360 * This is a wrapper around internal read_info() call, and ensures that
361 * returned data is not invalid (not NULL).
362 *
363 * @param cfg configuration
364 * @param nsid cryptographic ID of the namespace
365 * @param ret_meta a location to store metadata pointer. NULL, if metadata
366 * is not needed. Destroy with GNUNET_CONTAINER_meta_data_destroy().
367 * @param ret_rank a location to store rank. NULL, if rank not needed.
368 * @param ret_name a location to store human-readable name. Name is not unique.
369 * NULL, if name is not needed. Free with GNUNET_free().
370 * @param name_is_a_dup is set to GNUNET_YES, if ret_name was filled with
371 * a duplicate of a "no-name" placeholder
372 * @return GNUNET_OK on success. GNUENT_SYSERR if the data was
373 * unobtainable (in that case ret_* are filled with placeholders -
374 * empty metadata container, rank -1 and a "no-name" name).
375 */
376int
377GNUNET_PSEUDONYM_get_info (const struct GNUNET_CONFIGURATION_Handle *cfg,
378 const GNUNET_HashCode * nsid, struct GNUNET_CONTAINER_MetaData **ret_meta,
379 int32_t *ret_rank, char **ret_name, int *name_is_a_dup)
380{
381 struct GNUNET_CONTAINER_MetaData *meta;
382 char *name;
383 int32_t rank = -1;
384
385 meta = NULL;
386 name = NULL;
387 if (GNUNET_OK == read_info (cfg, nsid, &meta, &rank, &name))
388 {
389 if ((meta != NULL) && (name == NULL))
390 name =
391 GNUNET_CONTAINER_meta_data_get_first_by_types (meta,
392 EXTRACTOR_METATYPE_TITLE,
393 EXTRACTOR_METATYPE_GNUNET_ORIGINAL_FILENAME,
394 EXTRACTOR_METATYPE_FILENAME,
395 EXTRACTOR_METATYPE_DESCRIPTION,
396 EXTRACTOR_METATYPE_SUBJECT,
397 EXTRACTOR_METATYPE_PUBLISHER,
398 EXTRACTOR_METATYPE_AUTHOR_NAME,
399 EXTRACTOR_METATYPE_COMMENT,
400 EXTRACTOR_METATYPE_SUMMARY,
401 -1);
402 if (ret_name != NULL)
403 {
404 if (name == NULL)
405 {
406 name = GNUNET_strdup (_("no-name"));
407 if (name_is_a_dup != NULL)
408 *name_is_a_dup = GNUNET_YES;
409 }
410 else if (name_is_a_dup != NULL)
411 *name_is_a_dup = GNUNET_NO;
412 *ret_name = name;
413 }
414 else if (name != NULL)
415 GNUNET_free (name);
416
417 if (ret_meta != NULL)
418 {
419 if (meta == NULL)
420 meta = GNUNET_CONTAINER_meta_data_create ();
421 *ret_meta = meta;
422 }
423 else if (meta != NULL)
424 GNUNET_CONTAINER_meta_data_destroy (meta);
425
426 if (ret_rank != NULL)
427 *ret_rank = rank;
428
429 return GNUNET_OK;
430 }
431 if (ret_name != NULL)
432 *ret_name = GNUNET_strdup (_("no-name"));
433 if (ret_meta != NULL)
434 *ret_meta = GNUNET_CONTAINER_meta_data_create ();
435 if (ret_rank != NULL)
436 *ret_rank = -1;
437 if (name_is_a_dup != NULL)
438 *name_is_a_dup = GNUNET_YES;
439 return GNUNET_SYSERR;
440}
441
442/**
381 * Get the namespace ID belonging to the given namespace name. 443 * Get the namespace ID belonging to the given namespace name.
382 * 444 *
383 * @param cfg configuration to use 445 * @param cfg configuration to use
384 * @param ns_uname human-readable name for the namespace 446 * @param ns_uname unique (!) human-readable name for the namespace
385 * @param nsid set to namespace ID based on 'ns_uname' 447 * @param nsid set to namespace ID based on 'ns_uname'
386 * @return GNUNET_OK on success 448 * @return GNUNET_OK on success, GNUNET_SYSERR on failure
387 */ 449 */
388int 450int
389GNUNET_PSEUDONYM_name_to_id (const struct GNUNET_CONFIGURATION_Handle *cfg, 451GNUNET_PSEUDONYM_name_to_id (const struct GNUNET_CONFIGURATION_Handle *cfg,
390 const char *ns_uname, GNUNET_HashCode * nsid) 452 const char *ns_uname, GNUNET_HashCode * nsid)
391{ 453{
392 size_t slen; 454 size_t slen;
393 uint64_t len; 455 uint64_t len;
@@ -405,6 +467,7 @@ GNUNET_PSEUDONYM_name_to_id (const struct GNUNET_CONFIGURATION_Handle *cfg,
405 return GNUNET_SYSERR; 467 return GNUNET_SYSERR;
406 name = GNUNET_strdup (ns_uname); 468 name = GNUNET_strdup (ns_uname);
407 name[slen - 1] = '\0'; 469 name[slen - 1] = '\0';
470
408 GNUNET_CRYPTO_hash (name, strlen (name), &nh); 471 GNUNET_CRYPTO_hash (name, strlen (name), &nh);
409 GNUNET_free (name); 472 GNUNET_free (name);
410 fn = get_data_filename (cfg, PS_NAMES_DIR, &nh); 473 fn = get_data_filename (cfg, PS_NAMES_DIR, &nh);
@@ -472,10 +535,10 @@ list_pseudonym_helper (void *cls, const char *fullname)
472 struct ListPseudonymClosure *c = cls; 535 struct ListPseudonymClosure *c = cls;
473 int ret; 536 int ret;
474 GNUNET_HashCode id; 537 GNUNET_HashCode id;
475 int rating; 538 int32_t rating;
476 struct GNUNET_CONTAINER_MetaData *meta; 539 struct GNUNET_CONTAINER_MetaData *meta;
477 const char *fn; 540 const char *fn;
478 char *str; 541 char *str, *name_unique;
479 542
480 if (strlen (fullname) < sizeof (struct GNUNET_CRYPTO_HashAsciiEncoded)) 543 if (strlen (fullname) < sizeof (struct GNUNET_CRYPTO_HashAsciiEncoded))
481 return GNUNET_OK; 544 return GNUNET_OK;
@@ -487,11 +550,22 @@ list_pseudonym_helper (void *cls, const char *fullname)
487 if (GNUNET_OK != GNUNET_CRYPTO_hash_from_string (fn, &id)) 550 if (GNUNET_OK != GNUNET_CRYPTO_hash_from_string (fn, &id))
488 return GNUNET_OK; /* invalid name */ 551 return GNUNET_OK; /* invalid name */
489 str = NULL; 552 str = NULL;
490 if (GNUNET_OK != read_info (c->cfg, &id, &meta, &rating, &str)) 553 if (GNUNET_OK != GNUNET_PSEUDONYM_get_info (c->cfg, &id, &meta, &rating,
491 return GNUNET_OK; /* ignore entry */ 554 &str, NULL))
492 GNUNET_free_non_null (str); 555 {
556 /* ignore entry. FIXME: Why? Lack of data about a pseudonym is not a reason
557 * to ignore it... So yeah, it will have placeholders instead of name,
558 * empty metadata container and a default rank == -1, so what? We know
559 * its nsid - that's all we really need. Right? */
560 GNUNET_free (str);
561 GNUNET_CONTAINER_meta_data_destroy (meta);
562 return GNUNET_OK;
563 }
564 name_unique = GNUNET_PSEUDONYM_name_uniquify (c->cfg, &id, str, NULL);
493 if (c->iterator != NULL) 565 if (c->iterator != NULL)
494 ret = c->iterator (c->closure, &id, meta, rating); 566 ret = c->iterator (c->closure, &id, str, name_unique, meta, rating);
567 GNUNET_free_non_null (str);
568 GNUNET_free_non_null (name_unique);
495 GNUNET_CONTAINER_meta_data_destroy (meta); 569 GNUNET_CONTAINER_meta_data_destroy (meta);
496 return ret; 570 return ret;
497} 571}
@@ -559,6 +633,31 @@ GNUNET_PSEUDONYM_rank (const struct GNUNET_CONFIGURATION_Handle *cfg,
559 633
560 634
561/** 635/**
636 * Set the pseudonym metadata, rank and name.
637 *
638 * @param cfg overall configuration
639 * @param nsid id of the pseudonym
640 * @param name name to set. Must be the non-unique version of it.
641 * May be NULL, in which case it erases pseudonym's name!
642 * @param md metadata to set
643 * May be NULL, in which case it erases pseudonym's metadata!
644 * @param rank rank to assign
645 * @return GNUNET_OK on success, GNUNET_SYSERR on failure
646 */
647int
648GNUNET_PSEUDONYM_set_info (const struct GNUNET_CONFIGURATION_Handle *cfg,
649 const GNUNET_HashCode * nsid, const char *name,
650 const struct GNUNET_CONTAINER_MetaData *md, int rank)
651{
652 GNUNET_assert (cfg != NULL);
653 GNUNET_assert (nsid != NULL);
654
655 write_pseudonym_info (cfg, nsid, md, rank, name);
656 return GNUNET_OK;
657}
658
659
660/**
562 * Add a pseudonym to the set of known pseudonyms. 661 * Add a pseudonym to the set of known pseudonyms.
563 * For all pseudonym advertisements that we discover 662 * For all pseudonym advertisements that we discover
564 * FS should automatically call this function. 663 * FS should automatically call this function.
diff --git a/src/util/test_pseudonym.c b/src/util/test_pseudonym.c
index 20a3d3d96..4ce8b3853 100644
--- a/src/util/test_pseudonym.c
+++ b/src/util/test_pseudonym.c
@@ -39,6 +39,7 @@ static GNUNET_HashCode id1;
39 39
40static int 40static int
41iter (void *cls, const GNUNET_HashCode * pseudonym, 41iter (void *cls, const GNUNET_HashCode * pseudonym,
42 const char *name, const char *unique_name,
42 const struct GNUNET_CONTAINER_MetaData *md, int rating) 43 const struct GNUNET_CONTAINER_MetaData *md, int rating)
43{ 44{
44 int *ok = cls; 45 int *ok = cls;
@@ -54,6 +55,7 @@ iter (void *cls, const GNUNET_HashCode * pseudonym,
54 55
55static int 56static int
56noti_callback (void *cls, const GNUNET_HashCode * pseudonym, 57noti_callback (void *cls, const GNUNET_HashCode * pseudonym,
58 const char *name, const char *unique_name,
57 const struct GNUNET_CONTAINER_MetaData *md, int rating) 59 const struct GNUNET_CONTAINER_MetaData *md, int rating)
58{ 60{
59 int *ret = cls; 61 int *ret = cls;
@@ -64,6 +66,7 @@ noti_callback (void *cls, const GNUNET_HashCode * pseudonym,
64 66
65static int 67static int
66fake_noti_callback (void *cls, const GNUNET_HashCode * pseudonym, 68fake_noti_callback (void *cls, const GNUNET_HashCode * pseudonym,
69 const char *name, const char *unique_name,
67 const struct GNUNET_CONTAINER_MetaData *md, int rating) 70 const struct GNUNET_CONTAINER_MetaData *md, int rating)
68{ 71{
69 int *ret = cls; 72 int *ret = cls;
@@ -74,6 +77,7 @@ fake_noti_callback (void *cls, const GNUNET_HashCode * pseudonym,
74 77
75static int 78static int
76false_callback (void *cls, const GNUNET_HashCode * pseudonym, 79false_callback (void *cls, const GNUNET_HashCode * pseudonym,
80 const char *name, const char *unique_name,
77 const struct GNUNET_CONTAINER_MetaData *md, int rating) 81 const struct GNUNET_CONTAINER_MetaData *md, int rating)
78{ 82{
79 return GNUNET_OK; 83 return GNUNET_OK;
@@ -95,7 +99,10 @@ main (int argc, char *argv[])
95 char *name1; 99 char *name1;
96 char *name2; 100 char *name2;
97 char *name3; 101 char *name3;
102 char *name1_unique;
103 char *name2_unique;
98 char *noname; 104 char *noname;
105 int noname_is_a_dup;
99 int notiCount, fakenotiCount; 106 int notiCount, fakenotiCount;
100 int count; 107 int count;
101 static char m[1024 * 1024 * 10]; 108 static char m[1024 * 1024 * 10];
@@ -152,15 +159,21 @@ main (int argc, char *argv[])
152 strlen (m) + 1)); 159 strlen (m) + 1));
153 GNUNET_CRYPTO_hash_create_random (GNUNET_CRYPTO_QUALITY_WEAK, &id3); 160 GNUNET_CRYPTO_hash_create_random (GNUNET_CRYPTO_QUALITY_WEAK, &id3);
154 GNUNET_PSEUDONYM_add (cfg, &id3, meta); 161 GNUNET_PSEUDONYM_add (cfg, &id3, meta);
155 name3 = GNUNET_PSEUDONYM_id_to_name (cfg, &id3); 162 GNUNET_PSEUDONYM_get_info (cfg, &id3, NULL, NULL, &name3, NULL);
156 name2 = GNUNET_PSEUDONYM_id_to_name (cfg, &id2); 163 CHECK (name3 != NULL);
164 GNUNET_PSEUDONYM_get_info (cfg, &id2, NULL, NULL, &name2, NULL);
157 CHECK (name2 != NULL); 165 CHECK (name2 != NULL);
158 name1 = GNUNET_PSEUDONYM_id_to_name (cfg, &id1); 166 GNUNET_PSEUDONYM_get_info (cfg, &id1, NULL, NULL, &name1, NULL);
159 CHECK (name1 != NULL); 167 CHECK (name1 != NULL);
160 CHECK (0 != strcmp (name1, name2)); 168 CHECK (0 == strcmp (name1, name2));
169 name1_unique = GNUNET_PSEUDONYM_name_uniquify (cfg, &id1, name1, NULL);
170 name2_unique = GNUNET_PSEUDONYM_name_uniquify (cfg, &id2, name2, NULL);
171 CHECK (0 != strcmp (name1_unique, name2_unique));
161 CHECK (GNUNET_SYSERR == GNUNET_PSEUDONYM_name_to_id (cfg, "fake", &rid2)); 172 CHECK (GNUNET_SYSERR == GNUNET_PSEUDONYM_name_to_id (cfg, "fake", &rid2));
162 CHECK (GNUNET_OK == GNUNET_PSEUDONYM_name_to_id (cfg, name2, &rid2)); 173 CHECK (GNUNET_SYSERR == GNUNET_PSEUDONYM_name_to_id (cfg, name2, &rid2));
163 CHECK (GNUNET_OK == GNUNET_PSEUDONYM_name_to_id (cfg, name1, &rid1)); 174 CHECK (GNUNET_SYSERR == GNUNET_PSEUDONYM_name_to_id (cfg, name1, &rid1));
175 CHECK (GNUNET_OK == GNUNET_PSEUDONYM_name_to_id (cfg, name2_unique, &rid2));
176 CHECK (GNUNET_OK == GNUNET_PSEUDONYM_name_to_id (cfg, name1_unique, &rid1));
164 CHECK (0 == memcmp (&id1, &rid1, sizeof (GNUNET_HashCode))); 177 CHECK (0 == memcmp (&id1, &rid1, sizeof (GNUNET_HashCode)));
165 CHECK (0 == memcmp (&id2, &rid2, sizeof (GNUNET_HashCode))); 178 CHECK (0 == memcmp (&id2, &rid2, sizeof (GNUNET_HashCode)));
166 179
@@ -168,14 +181,17 @@ main (int argc, char *argv[])
168 GNUNET_log_skip (1, GNUNET_NO); 181 GNUNET_log_skip (1, GNUNET_NO);
169 CHECK (0 == GNUNET_PSEUDONYM_rank (cfg, &fid, 0)); 182 CHECK (0 == GNUNET_PSEUDONYM_rank (cfg, &fid, 0));
170 GNUNET_log_skip (0, GNUNET_YES); 183 GNUNET_log_skip (0, GNUNET_YES);
171 noname = GNUNET_PSEUDONYM_id_to_name (cfg, &fid); 184 CHECK (GNUNET_OK == GNUNET_PSEUDONYM_get_info (cfg, &fid, NULL, NULL, &noname, &noname_is_a_dup));
172 CHECK (noname != NULL); 185 CHECK (noname != NULL);
186 CHECK (noname_is_a_dup == GNUNET_YES);
173 CHECK (0 == GNUNET_PSEUDONYM_rank (cfg, &id1, 0)); 187 CHECK (0 == GNUNET_PSEUDONYM_rank (cfg, &id1, 0));
174 CHECK (5 == GNUNET_PSEUDONYM_rank (cfg, &id1, 5)); 188 CHECK (5 == GNUNET_PSEUDONYM_rank (cfg, &id1, 5));
175 CHECK (-5 == GNUNET_PSEUDONYM_rank (cfg, &id1, -10)); 189 CHECK (-5 == GNUNET_PSEUDONYM_rank (cfg, &id1, -10));
176 CHECK (0 == GNUNET_PSEUDONYM_rank (cfg, &id1, 5)); 190 CHECK (0 == GNUNET_PSEUDONYM_rank (cfg, &id1, 5));
177 GNUNET_free (name1); 191 GNUNET_free (name1);
178 GNUNET_free (name2); 192 GNUNET_free (name2);
193 GNUNET_free (name1_unique);
194 GNUNET_free (name2_unique);
179 GNUNET_free (name3); 195 GNUNET_free (name3);
180 GNUNET_free (noname); 196 GNUNET_free (noname);
181 /* END OF TEST CODE */ 197 /* END OF TEST CODE */