aboutsummaryrefslogtreecommitdiff
path: root/src/fs/fs_namespace.c
diff options
context:
space:
mode:
authorChristian Grothoff <christian@grothoff.org>2013-08-06 20:46:22 +0000
committerChristian Grothoff <christian@grothoff.org>2013-08-06 20:46:22 +0000
commit303ab4dafbc680b1b362f95df5b12dae831b1593 (patch)
tree8b2f411b0b31e500ce2988404b2501db03bed945 /src/fs/fs_namespace.c
parent1360f8a1e5877a8796dc8e7d0c55d78481382e80 (diff)
downloadgnunet-303ab4dafbc680b1b362f95df5b12dae831b1593.tar.gz
gnunet-303ab4dafbc680b1b362f95df5b12dae831b1593.zip
-fixing main FS build, updating man page of gnunet-pseudonym
Diffstat (limited to 'src/fs/fs_namespace.c')
-rw-r--r--src/fs/fs_namespace.c772
1 files changed, 256 insertions, 516 deletions
diff --git a/src/fs/fs_namespace.c b/src/fs/fs_namespace.c
index d456dc34b..8537ba0e6 100644
--- a/src/fs/fs_namespace.c
+++ b/src/fs/fs_namespace.c
@@ -1,6 +1,6 @@
1/* 1/*
2 This file is part of GNUnet 2 This file is part of GNUnet
3 (C) 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010 Christian Grothoff (and other contributing authors) 3 (C) 2003-2013 Christian Grothoff (and other contributing authors)
4 4
5 GNUnet is free software; you can redistribute it and/or modify 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 6 it under the terms of the GNU General Public License as published
@@ -20,7 +20,7 @@
20 20
21/** 21/**
22 * @file fs/fs_namespace.c 22 * @file fs/fs_namespace.c
23 * @brief create and destroy namespaces 23 * @brief publishing to namespaces, and tracking updateable entries
24 * @author Christian Grothoff 24 * @author Christian Grothoff
25 */ 25 */
26#include "platform.h" 26#include "platform.h"
@@ -29,30 +29,91 @@
29#include "gnunet_util_lib.h" 29#include "gnunet_util_lib.h"
30#include "gnunet_fs_service.h" 30#include "gnunet_fs_service.h"
31#include "fs_api.h" 31#include "fs_api.h"
32#include "fs_publish_ublock.h"
32 33
33 34
34/** 35/**
35 * Return the name of the directory in which we store 36 * Information about an (updateable) node in the
36 * our local namespaces (or rather, their public keys). 37 * namespace.
37 *
38 * @param h global fs handle
39 * @return NULL on error, otherwise the name of the directory
40 */ 38 */
41static char * 39struct NamespaceUpdateNode
42get_namespace_directory (struct GNUNET_FS_Handle *h)
43{ 40{
44 char *dn; 41 /**
42 * Identifier for this node.
43 */
44 char *id;
45 45
46 if (GNUNET_OK != 46 /**
47 GNUNET_CONFIGURATION_get_value_filename (h->cfg, "FS", "IDENTITY_DIR", 47 * Identifier of children of this node.
48 &dn)) 48 */
49 { 49 char *update;
50 GNUNET_log_config_missing (GNUNET_ERROR_TYPE_ERROR, 50
51 "fs", "IDENTITY_DIR"); 51 /**
52 return NULL; 52 * Metadata for this entry.
53 } 53 */
54 return dn; 54 struct GNUNET_CONTAINER_MetaData *md;
55} 55
56 /**
57 * URI of this entry in the namespace.
58 */
59 struct GNUNET_FS_Uri *uri;
60
61 /**
62 * Namespace update generation ID. Used to ensure
63 * freshness of the tree_id.
64 */
65 unsigned int nug;
66
67 /**
68 * TREE this entry belongs to (if nug is current).
69 */
70 unsigned int tree_id;
71
72};
73
74
75/**
76 * Handle to update information for a namespace.
77 */
78struct GNUNET_FS_UpdateInformationGraph
79{
80
81 /**
82 * Handle to the FS service context.
83 */
84 struct GNUNET_FS_Handle *h;
85
86 /**
87 * Array with information about nodes in the namespace.
88 */
89 struct NamespaceUpdateNode **update_nodes;
90
91 /**
92 * Private key for the namespace.
93 */
94 struct GNUNET_CRYPTO_EccPrivateKey ns;
95
96 /**
97 * Hash map mapping identifiers of update nodes
98 * to the update nodes (initialized on-demand).
99 */
100 struct GNUNET_CONTAINER_MultiHashMap *update_map;
101
102 /**
103 * Size of the update nodes array.
104 */
105 unsigned int update_node_count;
106
107 /**
108 * Reference counter.
109 */
110 unsigned int rc;
111
112 /**
113 * Generator for unique nug numbers.
114 */
115 unsigned int nug_gen;
116};
56 117
57 118
58/** 119/**
@@ -63,32 +124,71 @@ get_namespace_directory (struct GNUNET_FS_Handle *h)
63 * @return NULL on error, otherwise the name of the directory 124 * @return NULL on error, otherwise the name of the directory
64 */ 125 */
65static char * 126static char *
66get_update_information_directory (struct GNUNET_FS_Namespace *ns) 127get_update_information_directory (struct GNUNET_FS_Handle *h,
128 const struct GNUNET_CRYPTO_EccPrivateKey *ns)
67{ 129{
68 char *dn; 130 char *dn;
69 char *ret; 131 char *ret;
132 struct GNUNET_CRYPTO_EccPublicKey pub;
133 struct GNUNET_CRYPTO_ShortHashCode hc;
134 struct GNUNET_CRYPTO_ShortHashAsciiEncoded enc;
70 135
71 if (GNUNET_OK != 136 if (GNUNET_OK !=
72 GNUNET_CONFIGURATION_get_value_filename (ns->h->cfg, "FS", "UPDATE_DIR", 137 GNUNET_CONFIGURATION_get_value_filename (h->cfg, "FS", "UPDATE_DIR",
73 &dn)) 138 &dn))
74 { 139 {
75 GNUNET_log_config_missing (GNUNET_ERROR_TYPE_ERROR, 140 GNUNET_log_config_missing (GNUNET_ERROR_TYPE_ERROR,
76 "fs", "UPDATE_DIR"); 141 "fs", "UPDATE_DIR");
77 return NULL; 142 return NULL;
78 } 143 }
79 GNUNET_asprintf (&ret, "%s%s%s", dn, DIR_SEPARATOR_STR, ns->name); 144 GNUNET_CRYPTO_ecc_key_get_public (ns, &pub);
145 GNUNET_CRYPTO_short_hash (&pub, sizeof (pub), &hc);
146 GNUNET_CRYPTO_short_hash_to_enc (&hc,
147 &enc);
148 GNUNET_asprintf (&ret, "%s%s%s",
149 dn,
150 DIR_SEPARATOR_STR,
151 (const char *) enc.short_encoding);
80 GNUNET_free (dn); 152 GNUNET_free (dn);
81 return ret; 153 return ret;
82} 154}
83 155
84 156
85/** 157/**
158 * Release memory occupied by UIG datastructure.
159 *
160 * @param uig data structure to free
161 */
162static void
163free_update_information_graph (struct GNUNET_FS_UpdateInformationGraph *uig)
164{
165 unsigned int i;
166 struct NamespaceUpdateNode *nsn;
167
168 for (i = 0; i < uig->update_node_count; i++)
169 {
170 nsn = uig->update_nodes[i];
171 GNUNET_CONTAINER_meta_data_destroy (nsn->md);
172 GNUNET_FS_uri_destroy (nsn->uri);
173 GNUNET_free (nsn->id);
174 GNUNET_free (nsn->update);
175 GNUNET_free (nsn);
176 }
177 GNUNET_array_grow (uig->update_nodes, uig->update_node_count,
178 0);
179 if (NULL != uig->update_map)
180 GNUNET_CONTAINER_multihashmap_destroy (uig->update_map);
181 GNUNET_free (uig);
182}
183
184
185/**
86 * Write the namespace update node graph to a file. 186 * Write the namespace update node graph to a file.
87 * 187 *
88 * @param ns namespace to dump 188 * @param ns namespace to dump
89 */ 189 */
90static void 190static void
91write_update_information_graph (struct GNUNET_FS_Namespace *ns) 191write_update_information_graph (struct GNUNET_FS_UpdateInformationGraph *uig)
92{ 192{
93 char *fn; 193 char *fn;
94 struct GNUNET_BIO_WriteHandle *wh; 194 struct GNUNET_BIO_WriteHandle *wh;
@@ -96,7 +196,8 @@ write_update_information_graph (struct GNUNET_FS_Namespace *ns)
96 struct NamespaceUpdateNode *n; 196 struct NamespaceUpdateNode *n;
97 char *uris; 197 char *uris;
98 198
99 fn = get_update_information_directory (ns); 199 fn = get_update_information_directory (uig->h,
200 &uig->ns);
100 wh = GNUNET_BIO_write_open (fn); 201 wh = GNUNET_BIO_write_open (fn);
101 if (NULL == wh) 202 if (NULL == wh)
102 { 203 {
@@ -105,11 +206,11 @@ write_update_information_graph (struct GNUNET_FS_Namespace *ns)
105 GNUNET_free (fn); 206 GNUNET_free (fn);
106 return; 207 return;
107 } 208 }
108 if (GNUNET_OK != GNUNET_BIO_write_int32 (wh, ns->update_node_count)) 209 if (GNUNET_OK != GNUNET_BIO_write_int32 (wh, uig->update_node_count))
109 goto END; 210 goto END;
110 for (i = 0; i < ns->update_node_count; i++) 211 for (i = 0; i < uig->update_node_count; i++)
111 { 212 {
112 n = ns->update_nodes[i]; 213 n = uig->update_nodes[i];
113 uris = GNUNET_FS_uri_to_string (n->uri); 214 uris = GNUNET_FS_uri_to_string (n->uri);
114 if ((GNUNET_OK != GNUNET_BIO_write_string (wh, n->id)) || 215 if ((GNUNET_OK != GNUNET_BIO_write_string (wh, n->id)) ||
115 (GNUNET_OK != GNUNET_BIO_write_meta_data (wh, n->md)) || 216 (GNUNET_OK != GNUNET_BIO_write_meta_data (wh, n->md)) ||
@@ -132,11 +233,15 @@ END:
132/** 233/**
133 * Read the namespace update node graph from a file. 234 * Read the namespace update node graph from a file.
134 * 235 *
236 * @param h FS handle to use
135 * @param ns namespace to read 237 * @param ns namespace to read
238 * @return update graph, never NULL
136 */ 239 */
137static void 240static struct GNUNET_FS_UpdateInformationGraph *
138read_update_information_graph (struct GNUNET_FS_Namespace *ns) 241read_update_information_graph (struct GNUNET_FS_Handle *h,
242 const struct GNUNET_CRYPTO_EccPrivateKey *ns)
139{ 243{
244 struct GNUNET_FS_UpdateInformationGraph *uig;
140 char *fn; 245 char *fn;
141 struct GNUNET_BIO_ReadHandle *rh; 246 struct GNUNET_BIO_ReadHandle *rh;
142 unsigned int i; 247 unsigned int i;
@@ -145,40 +250,43 @@ read_update_information_graph (struct GNUNET_FS_Namespace *ns)
145 uint32_t count; 250 uint32_t count;
146 char *emsg; 251 char *emsg;
147 252
148 fn = get_update_information_directory (ns); 253 uig = GNUNET_new (struct GNUNET_FS_UpdateInformationGraph);
254 uig->h = h;
255 uig->ns = *ns;
256 fn = get_update_information_directory (h, ns);
149 if (GNUNET_YES != GNUNET_DISK_file_test (fn)) 257 if (GNUNET_YES != GNUNET_DISK_file_test (fn))
150 { 258 {
151 GNUNET_free (fn); 259 GNUNET_free (fn);
152 return; 260 return uig;
153 } 261 }
154 rh = GNUNET_BIO_read_open (fn); 262 rh = GNUNET_BIO_read_open (fn);
155 if (NULL == rh) 263 if (NULL == rh)
156 { 264 {
157 GNUNET_free (fn); 265 GNUNET_free (fn);
158 return; 266 return uig;
159 } 267 }
160 if (GNUNET_OK != GNUNET_BIO_read_int32 (rh, &count)) 268 if (GNUNET_OK != GNUNET_BIO_read_int32 (rh, &count))
161 { 269 {
162 GNUNET_break (0); 270 GNUNET_break (0);
163 goto END; 271 goto ERROR;
164 } 272 }
165 if (count > 1024 * 1024) 273 if (count > 1024 * 1024)
166 { 274 {
167 GNUNET_break (0); 275 GNUNET_break (0);
168 goto END; 276 goto ERROR;
169 } 277 }
170 if (0 == count) 278 if (0 == count)
171 { 279 {
172 GNUNET_break (GNUNET_OK == GNUNET_BIO_read_close (rh, NULL)); 280 GNUNET_break (GNUNET_OK == GNUNET_BIO_read_close (rh, NULL));
173 GNUNET_free (fn); 281 GNUNET_free (fn);
174 return; 282 return uig;
175 } 283 }
176 ns->update_nodes = 284 uig->update_nodes =
177 GNUNET_malloc (count * sizeof (struct NamespaceUpdateNode *)); 285 GNUNET_malloc (count * sizeof (struct NamespaceUpdateNode *));
178 286
179 for (i = 0; i < count; i++) 287 for (i = 0; i < count; i++)
180 { 288 {
181 n = GNUNET_malloc (sizeof (struct NamespaceUpdateNode)); 289 n = GNUNET_new (struct NamespaceUpdateNode);
182 if ((GNUNET_OK != GNUNET_BIO_read_string (rh, "identifier", &n->id, 1024)) 290 if ((GNUNET_OK != GNUNET_BIO_read_string (rh, "identifier", &n->id, 1024))
183 || (GNUNET_OK != GNUNET_BIO_read_meta_data (rh, "meta", &n->md)) || 291 || (GNUNET_OK != GNUNET_BIO_read_meta_data (rh, "meta", &n->md)) ||
184 (GNUNET_OK != 292 (GNUNET_OK !=
@@ -205,304 +313,25 @@ read_update_information_graph (struct GNUNET_FS_Namespace *ns)
205 GNUNET_free (n); 313 GNUNET_free (n);
206 break; 314 break;
207 } 315 }
208 ns->update_nodes[i] = n; 316 uig->update_nodes[i] = n;
209 } 317 }
210 ns->update_node_count = i; 318 uig->update_node_count = i;
211END:
212 if (GNUNET_OK != GNUNET_BIO_read_close (rh, &emsg)) 319 if (GNUNET_OK != GNUNET_BIO_read_close (rh, &emsg))
213 { 320 {
214 GNUNET_log (GNUNET_ERROR_TYPE_ERROR, _("Failed to write `%s': %s\n"), emsg); 321 GNUNET_log (GNUNET_ERROR_TYPE_ERROR, _("Failed to read `%s': %s\n"),
322 fn, emsg);
215 GNUNET_free (emsg); 323 GNUNET_free (emsg);
216 } 324 }
217 GNUNET_free (fn); 325 return uig;
218} 326ERROR:
219 327 if (GNUNET_OK != GNUNET_BIO_read_close (rh, &emsg))
220
221/**
222 * Create a namespace with the given name; if one already
223 * exists, return a handle to the existing namespace.
224 *
225 * @param h handle to the file sharing subsystem
226 * @param name name to use for the namespace
227 * @return handle to the namespace, NULL on error (i.e. invalid filename)
228 */
229struct GNUNET_FS_Namespace *
230GNUNET_FS_namespace_create (struct GNUNET_FS_Handle *h, const char *name)
231{
232 char *dn;
233 char *fn;
234 struct GNUNET_FS_Namespace *ret;
235
236 dn = get_namespace_directory (h);
237 if (NULL == dn)
238 {
239 GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
240 _("Can't determine where namespace directory is\n"));
241 return NULL;
242 }
243 GNUNET_asprintf (&fn, "%s%s%s", dn, DIR_SEPARATOR_STR, name);
244 GNUNET_free (dn);
245 ret = GNUNET_malloc (sizeof (struct GNUNET_FS_Namespace));
246 ret->h = h;
247 ret->rc = 1;
248 ret->key = GNUNET_FS_pseudonym_create (fn);
249 if (NULL == ret->key)
250 {
251 GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
252 _("Failed to create or read private key for namespace `%s'\n"),
253 name);
254 GNUNET_free (ret);
255 GNUNET_free (fn);
256 return NULL;
257 }
258 ret->name = GNUNET_strdup (name);
259 ret->filename = fn;
260 return ret;
261}
262
263
264/**
265 * Open the namespace with the given name; if it does not exist,
266 * or the key file is corrupted, the function fails.
267 *
268 * @param h handle to the file sharing subsystem
269 * @param name name of the namespace
270 * @return handle to the namespace,
271 * NULL on error (i.e. invalid filename, non-existent filename)
272 */
273struct GNUNET_FS_Namespace *
274GNUNET_FS_namespace_open_existing (struct GNUNET_FS_Handle *h, const char *name)
275{
276 char *dn;
277 char *fn;
278 struct GNUNET_FS_Namespace *ret;
279
280 dn = get_namespace_directory (h);
281 if (NULL == dn)
282 {
283 GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
284 _("Can't determine where namespace directory is\n"));
285 return NULL;
286 }
287 GNUNET_asprintf (&fn, "%s%s%s", dn, DIR_SEPARATOR_STR, name);
288 GNUNET_free (dn);
289 ret = GNUNET_malloc (sizeof (struct GNUNET_FS_Namespace));
290 ret->h = h;
291 ret->rc = 1;
292 ret->key = GNUNET_FS_pseudonym_create_from_existing_file (fn);
293 if (NULL == ret->key)
294 {
295 GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
296 _("Failed to read private key for namespace `%s'\n"), name);
297 GNUNET_free (ret);
298 GNUNET_free (fn);
299 return NULL;
300 }
301 ret->name = GNUNET_strdup (name);
302 ret->filename = fn;
303 return ret;
304}
305
306
307/**
308 * Rename a local namespace.
309 *
310 * @param h handle to the file sharing subsystem
311 * @param old_name old name of the namespace
312 * @param new_name new name of the namespace
313 * @return GNUNET_OK on success, GNUNET_SYSERR on error (see errno for details)
314 */
315int
316GNUNET_FS_namespace_rename (struct GNUNET_FS_Handle *h,
317 const char *old_name,
318 const char *new_name)
319{
320 char *dn;
321 char *fn_old;
322 char *fn_new;
323 int result;
324 int save_errno;
325
326 dn = get_namespace_directory (h);
327 if (NULL == dn)
328 {
329 GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
330 _("Can't determine where namespace directory is\n"));
331 return GNUNET_SYSERR;
332 }
333 GNUNET_asprintf (&fn_old, "%s%s%s", dn, DIR_SEPARATOR_STR, old_name);
334 GNUNET_asprintf (&fn_new, "%s%s%s", dn, DIR_SEPARATOR_STR, new_name);
335 GNUNET_free (dn);
336 result = RENAME (fn_old, fn_new);
337 save_errno = errno;
338 GNUNET_free (fn_old);
339 GNUNET_free (fn_new);
340 errno = save_errno;
341 if (result == 0)
342 return GNUNET_OK;
343 return GNUNET_SYSERR;
344}
345
346
347/**
348 * Duplicate a namespace handle.
349 *
350 * @param ns namespace handle
351 * @return duplicated handle to the namespace
352 */
353struct GNUNET_FS_Namespace *
354GNUNET_FS_namespace_dup (struct GNUNET_FS_Namespace *ns)
355{
356 ns->rc++;
357 return ns;
358}
359
360
361/**
362 * Delete a namespace handle. Can be used for a clean shutdown (free
363 * memory) or also to freeze the namespace to prevent further
364 * insertions by anyone.
365 *
366 * @param ns handle to the namespace that should be deleted / freed
367 * @param freeze prevents future insertions; creating a namespace
368 * with the same name again will create a fresh namespace instead
369 *
370 * @return GNUNET_OK on success, GNUNET_SYSERR on error
371 */
372int
373GNUNET_FS_namespace_delete (struct GNUNET_FS_Namespace *ns, int freeze)
374{
375 unsigned int i;
376 struct NamespaceUpdateNode *nsn;
377
378 ns->rc--;
379 if (freeze)
380 {
381 if (0 != UNLINK (ns->filename))
382 GNUNET_log_strerror_file (GNUNET_ERROR_TYPE_ERROR, "unlink",
383 ns->filename);
384 }
385 if (0 != ns->rc)
386 return GNUNET_OK;
387 GNUNET_FS_pseudonym_destroy (ns->key);
388 GNUNET_free (ns->filename);
389 GNUNET_free (ns->name);
390 for (i = 0; i < ns->update_node_count; i++)
391 {
392 nsn = ns->update_nodes[i];
393 GNUNET_CONTAINER_meta_data_destroy (nsn->md);
394 GNUNET_FS_uri_destroy (nsn->uri);
395 GNUNET_free (nsn->id);
396 GNUNET_free (nsn->update);
397 GNUNET_free (nsn);
398 }
399 GNUNET_array_grow (ns->update_nodes, ns->update_node_count,
400 0);
401 if (ns->update_map != NULL)
402 GNUNET_CONTAINER_multihashmap_destroy (ns->update_map);
403 GNUNET_free (ns);
404 return GNUNET_OK;
405}
406
407
408/**
409 * Context for the 'process_namespace' callback.
410 * Specifies a function to call on each namespace.
411 */
412struct ProcessNamespaceContext
413{
414 /**
415 * Function to call.
416 */
417 GNUNET_FS_NamespaceInfoProcessor cb;
418
419 /**
420 * Closure for 'cb'.
421 */
422 void *cb_cls;
423};
424
425
426/**
427 * Get hash of the public key of a namespace.
428 *
429 * @param ns namespace
430 * @param id buffer to store the key in
431 * @return GNUNET_OK on success
432 * GNUNET_SYSERR on failure (contents of id remain intact)
433 */
434int
435GNUNET_FS_namespace_get_public_identifier (struct GNUNET_FS_Namespace *ns,
436 struct GNUNET_FS_PseudonymIdentifier *id)
437{
438 if ((NULL == ns) || (NULL == id))
439 return GNUNET_SYSERR;
440 GNUNET_FS_pseudonym_get_identifier (ns->key, id);
441 return GNUNET_OK;
442}
443
444
445/**
446 * Function called with a filename of a namespace. Reads the key and
447 * calls the callback.
448 *
449 * @param cls closure (struct ProcessNamespaceContext)
450 * @param filename complete filename (absolute path)
451 * @return GNUNET_OK to continue to iterate,
452 * GNUNET_SYSERR to abort iteration with error!
453 */
454static int
455process_namespace (void *cls, const char *filename)
456{
457 struct ProcessNamespaceContext *pnc = cls;
458 struct GNUNET_FS_PseudonymHandle *ph;
459 struct GNUNET_FS_PseudonymIdentifier id;
460 const char *name;
461 const char *t;
462
463 if (NULL == (ph = GNUNET_FS_pseudonym_create (filename)))
464 { 328 {
465 GNUNET_log (GNUNET_ERROR_TYPE_ERROR, 329 GNUNET_log (GNUNET_ERROR_TYPE_ERROR, _("Failed to read `%s': %s\n"),
466 _ 330 fn, emsg);
467 ("Failed to read namespace private key file `%s', deleting it!\n"), 331 GNUNET_free (emsg);
468 filename);
469 if (0 != UNLINK (filename))
470 GNUNET_log_strerror_file (GNUNET_ERROR_TYPE_WARNING, "unlink", filename);
471 return GNUNET_OK;
472 } 332 }
473 GNUNET_FS_pseudonym_get_identifier (ph, &id); 333 GNUNET_free (fn);
474 GNUNET_FS_pseudonym_destroy (ph); 334 return uig;
475 name = filename;
476 while (NULL != (t = strstr (name, DIR_SEPARATOR_STR)))
477 name = t + 1;
478 pnc->cb (pnc->cb_cls, name, &id);
479 return GNUNET_OK;
480}
481
482
483/**
484 * Build a list of all available local (!) namespaces The returned
485 * names are only the nicknames since we only iterate over the local
486 * namespaces.
487 *
488 * @param h handle to the file sharing subsystem
489 * @param cb function to call on each known namespace
490 * @param cb_cls closure for cb
491 */
492void
493GNUNET_FS_namespace_list (struct GNUNET_FS_Handle *h,
494 GNUNET_FS_NamespaceInfoProcessor cb, void *cb_cls)
495{
496 char *dn;
497 struct ProcessNamespaceContext ctx;
498
499 dn = get_namespace_directory (h);
500 if (NULL == dn)
501 return;
502 ctx.cb = cb;
503 ctx.cb_cls = cb_cls;
504 GNUNET_DISK_directory_scan (dn, &process_namespace, &ctx);
505 GNUNET_free (dn);
506} 335}
507 336
508 337
@@ -526,7 +355,7 @@ struct GNUNET_FS_PublishSksContext
526 /** 355 /**
527 * Namespace we're publishing to. 356 * Namespace we're publishing to.
528 */ 357 */
529 struct GNUNET_FS_Namespace *ns; 358 struct GNUNET_CRYPTO_EccPrivateKey ns;
530 359
531 /** 360 /**
532 * Handle to the datastore. 361 * Handle to the datastore.
@@ -534,6 +363,11 @@ struct GNUNET_FS_PublishSksContext
534 struct GNUNET_DATASTORE_Handle *dsh; 363 struct GNUNET_DATASTORE_Handle *dsh;
535 364
536 /** 365 /**
366 * Handle to FS.
367 */
368 struct GNUNET_FS_Handle *h;
369
370 /**
537 * Function to call once we're done. 371 * Function to call once we're done.
538 */ 372 */
539 GNUNET_FS_PublishContinuation cont; 373 GNUNET_FS_PublishContinuation cont;
@@ -544,31 +378,28 @@ struct GNUNET_FS_PublishSksContext
544 void *cont_cls; 378 void *cont_cls;
545 379
546 /** 380 /**
547 * Handle for our datastore request. 381 * Handle for our UBlock operation request.
548 */ 382 */
549 struct GNUNET_DATASTORE_QueueEntry *dqe; 383 struct GNUNET_FS_PublishUblockContext *uc;
550}; 384};
551 385
552 386
553/** 387/**
554 * Function called by the datastore API with 388 * Function called by the UBlock construction with
555 * the result from the PUT (UBlock) request. 389 * the result from the PUT (UBlock) request.
556 * 390 *
557 * @param cls closure of type "struct GNUNET_FS_PublishSksContext*" 391 * @param cls closure of type "struct GNUNET_FS_PublishSksContext*"
558 * @param success GNUNET_OK on success
559 * @param min_expiration minimum expiration time required for content to be stored
560 * @param msg error message (or NULL) 392 * @param msg error message (or NULL)
561 */ 393 */
562static void 394static void
563sb_put_cont (void *cls, int success, 395sks_publish_cont (void *cls,
564 struct GNUNET_TIME_Absolute min_expiration, 396 const char *msg)
565 const char *msg)
566{ 397{
567 struct GNUNET_FS_PublishSksContext *psc = cls; 398 struct GNUNET_FS_PublishSksContext *psc = cls;
568 struct GNUNET_HashCode hc; 399 struct GNUNET_FS_UpdateInformationGraph *uig;
569 400
570 psc->dqe = NULL; 401 psc->uc = NULL;
571 if (GNUNET_OK != success) 402 if (NULL != msg)
572 { 403 {
573 if (NULL != psc->cont) 404 if (NULL != psc->cont)
574 psc->cont (psc->cont_cls, NULL, msg); 405 psc->cont (psc->cont_cls, NULL, msg);
@@ -580,19 +411,14 @@ sb_put_cont (void *cls, int success,
580 /* FIXME: this can be done much more 411 /* FIXME: this can be done much more
581 * efficiently by simply appending to the 412 * efficiently by simply appending to the
582 * file and overwriting the 4-byte header */ 413 * file and overwriting the 4-byte header */
583 if (psc->ns->update_nodes == NULL) 414 uig = read_update_information_graph (psc->h,
584 read_update_information_graph (psc->ns); 415 &psc->ns);
585 GNUNET_array_append (psc->ns->update_nodes, 416 GNUNET_array_append (uig->update_nodes,
586 psc->ns->update_node_count, psc->nsn); 417 uig->update_node_count,
587 if (NULL != psc->ns->update_map) 418 psc->nsn);
588 {
589 GNUNET_CRYPTO_hash (psc->nsn->id, strlen (psc->nsn->id), &hc);
590 GNUNET_CONTAINER_multihashmap_put (psc->ns->update_map, &hc,
591 psc->nsn,
592 GNUNET_CONTAINER_MULTIHASHMAPOPTION_MULTIPLE);
593 }
594 psc->nsn = NULL; 419 psc->nsn = NULL;
595 write_update_information_graph (psc->ns); 420 write_update_information_graph (uig);
421 free_update_information_graph (uig);
596 } 422 }
597 if (NULL != psc->cont) 423 if (NULL != psc->cont)
598 psc->cont (psc->cont_cls, psc->uri, NULL); 424 psc->cont (psc->cont_cls, psc->uri, NULL);
@@ -617,7 +443,7 @@ sb_put_cont (void *cls, int success,
617 */ 443 */
618struct GNUNET_FS_PublishSksContext * 444struct GNUNET_FS_PublishSksContext *
619GNUNET_FS_publish_sks (struct GNUNET_FS_Handle *h, 445GNUNET_FS_publish_sks (struct GNUNET_FS_Handle *h,
620 struct GNUNET_FS_Namespace *ns, 446 const struct GNUNET_CRYPTO_EccPrivateKey *ns,
621 const char *identifier, const char *update, 447 const char *identifier, const char *update,
622 const struct GNUNET_CONTAINER_MetaData *meta, 448 const struct GNUNET_CONTAINER_MetaData *meta,
623 const struct GNUNET_FS_Uri *uri, 449 const struct GNUNET_FS_Uri *uri,
@@ -626,144 +452,49 @@ GNUNET_FS_publish_sks (struct GNUNET_FS_Handle *h,
626 GNUNET_FS_PublishContinuation cont, void *cont_cls) 452 GNUNET_FS_PublishContinuation cont, void *cont_cls)
627{ 453{
628 struct GNUNET_FS_PublishSksContext *psc; 454 struct GNUNET_FS_PublishSksContext *psc;
629 struct GNUNET_CRYPTO_AesSessionKey sk;
630 struct GNUNET_CRYPTO_AesInitializationVector iv;
631 struct GNUNET_FS_Uri *sks_uri; 455 struct GNUNET_FS_Uri *sks_uri;
632 char *uris; 456
633 size_t size; 457 sks_uri = GNUNET_new (struct GNUNET_FS_Uri);
634 size_t slen;
635 size_t nidlen;
636 size_t idlen;
637 ssize_t mdsize;
638 struct UBlock *ub;
639 struct UBlock *ub_enc;
640 char *dest;
641 struct GNUNET_CONTAINER_MetaData *mmeta;
642 struct GNUNET_HashCode id_hash; /* hash of thisId */
643 struct GNUNET_HashCode ns_hash; /* hash of namespace public key */
644 struct GNUNET_HashCode key; /* id_hash ^ ns_hash, for AES key */
645 struct GNUNET_HashCode signing_key; /* H(key) = input for public key */
646 struct GNUNET_HashCode query; /* H(verification_key) = query */
647
648 idlen = strlen (identifier);
649 if (NULL != update)
650 nidlen = strlen (update) + 1;
651 else
652 nidlen = 1;
653 uris = GNUNET_FS_uri_to_string (uri);
654 slen = strlen (uris) + 1;
655 if ( (slen >= MAX_UBLOCK_SIZE - sizeof (struct UBlock)) ||
656 (nidlen >= MAX_UBLOCK_SIZE - sizeof (struct UBlock) - slen) )
657 {
658 GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
659 _("Identifiers or URI too long to create UBlock"));
660 GNUNET_free (uris);
661 return NULL;
662 }
663 if (NULL == meta)
664 mmeta = GNUNET_CONTAINER_meta_data_create ();
665 else
666 mmeta = GNUNET_CONTAINER_meta_data_duplicate (meta);
667 mdsize = GNUNET_CONTAINER_meta_data_get_serialized_size (mmeta);
668 size = sizeof (struct UBlock) + slen + nidlen + mdsize;
669 if ( (size > MAX_UBLOCK_SIZE) ||
670 (size < sizeof (struct UBlock) + slen + nidlen) )
671 {
672 size = MAX_UBLOCK_SIZE;
673 mdsize = MAX_UBLOCK_SIZE - (sizeof (struct UBlock) + slen + nidlen);
674 }
675 ub = GNUNET_malloc (sizeof (struct UBlock) + size);
676 dest = (char *) &ub[1];
677 if (NULL != update)
678 memcpy (dest, update, nidlen);
679 else
680 memset (dest, 0, 1);
681 dest += nidlen;
682 memcpy (dest, uris, slen);
683 GNUNET_free (uris);
684 dest += slen;
685 mdsize =
686 GNUNET_CONTAINER_meta_data_serialize (mmeta, &dest, mdsize,
687 GNUNET_CONTAINER_META_DATA_SERIALIZE_PART);
688 GNUNET_CONTAINER_meta_data_destroy (mmeta);
689 if (-1 == mdsize)
690 {
691 GNUNET_break (0);
692 GNUNET_free (ub);
693 if (NULL != cont)
694 cont (cont_cls, NULL, _("Internal error."));
695 return NULL;
696 }
697 sks_uri = GNUNET_malloc (sizeof (struct GNUNET_FS_Uri));
698 sks_uri->type = GNUNET_FS_URI_SKS; 458 sks_uri->type = GNUNET_FS_URI_SKS;
699 sks_uri->data.sks.identifier = GNUNET_strdup (identifier); 459 sks_uri->data.sks.identifier = GNUNET_strdup (identifier);
700 GNUNET_FS_namespace_get_public_identifier (ns, 460 GNUNET_CRYPTO_ecc_key_get_public (ns,
701 &sks_uri->data.sks.ns); 461 &sks_uri->data.sks.ns);
702 462
703 size = sizeof (struct UBlock) + mdsize + slen + nidlen; 463 psc = GNUNET_new (struct GNUNET_FS_PublishSksContext);
704 ub_enc = GNUNET_malloc (size); 464 psc->h = h;
705 GNUNET_CRYPTO_hash (identifier, idlen, &id_hash);
706 GNUNET_CRYPTO_hash (&sks_uri->data.sks.ns,
707 sizeof (sks_uri->data.sks.ns), &ns_hash);
708 GNUNET_CRYPTO_hash_xor (&id_hash, &ns_hash, &key);
709 GNUNET_CRYPTO_hash_to_aes_key (&key, &sk, &iv);
710 GNUNET_CRYPTO_hash (&key, sizeof (struct GNUNET_HashCode), &signing_key);
711
712 GNUNET_CRYPTO_aes_encrypt (&ub[1],
713 size - sizeof (struct UBlock),
714 &sk, &iv,
715 &ub_enc[1]);
716 ub_enc->purpose.size = htonl (nidlen + slen + mdsize + sizeof (struct UBlock)
717 - sizeof (struct GNUNET_FS_PseudonymSignature));
718 ub_enc->purpose.purpose = htonl (GNUNET_SIGNATURE_PURPOSE_FS_UBLOCK);
719 GNUNET_FS_pseudonym_derive_verification_key (&sks_uri->data.sks.ns,
720 &signing_key,
721 &ub_enc->verification_key);
722 GNUNET_CRYPTO_hash (&ub_enc->verification_key,
723 sizeof (ub_enc->verification_key),
724 &query);
725 GNUNET_FS_pseudonym_sign (ns->key,
726 &ub_enc->purpose,
727 NULL,
728 &signing_key,
729 &ub_enc->signature);
730 psc = GNUNET_malloc (sizeof (struct GNUNET_FS_PublishSksContext));
731 psc->uri = sks_uri; 465 psc->uri = sks_uri;
732 psc->cont = cont; 466 psc->cont = cont;
733 psc->ns = GNUNET_FS_namespace_dup (ns);
734 psc->cont_cls = cont_cls; 467 psc->cont_cls = cont_cls;
735 if (0 != (options & GNUNET_FS_PUBLISH_OPTION_SIMULATE_ONLY)) 468 psc->ns = *ns;
736 { 469 if (0 == (options & GNUNET_FS_PUBLISH_OPTION_SIMULATE_ONLY))
737 GNUNET_free (ub_enc);
738 GNUNET_free (ub);
739 sb_put_cont (psc, GNUNET_OK, GNUNET_TIME_UNIT_ZERO_ABS, NULL);
740 return NULL;
741 }
742 psc->dsh = GNUNET_DATASTORE_connect (h->cfg);
743 if (NULL == psc->dsh)
744 { 470 {
745 GNUNET_free (ub_enc); 471 psc->dsh = GNUNET_DATASTORE_connect (h->cfg);
746 GNUNET_free (ub); 472 if (NULL == psc->dsh)
747 sb_put_cont (psc, GNUNET_NO, GNUNET_TIME_UNIT_ZERO_ABS, _("Failed to connect to datastore.")); 473 {
748 return NULL; 474 sks_publish_cont (psc,
475 _("Failed to connect to datastore."));
476 return NULL;
477 }
749 } 478 }
750
751 if (NULL != update) 479 if (NULL != update)
752 { 480 {
753 psc->nsn = GNUNET_malloc (sizeof (struct NamespaceUpdateNode)); 481 psc->nsn = GNUNET_new (struct NamespaceUpdateNode);
754 psc->nsn->id = GNUNET_strdup (identifier); 482 psc->nsn->id = GNUNET_strdup (identifier);
755 psc->nsn->update = GNUNET_strdup (update); 483 psc->nsn->update = GNUNET_strdup (update);
756 psc->nsn->md = GNUNET_CONTAINER_meta_data_duplicate (meta); 484 psc->nsn->md = GNUNET_CONTAINER_meta_data_duplicate (meta);
757 psc->nsn->uri = GNUNET_FS_uri_dup (uri); 485 psc->nsn->uri = GNUNET_FS_uri_dup (uri);
758 } 486 }
759 487 psc->uc = GNUNET_FS_publish_ublock_ (h,
760 psc->dqe = GNUNET_DATASTORE_put (psc->dsh, 0, &query, size, ub_enc, 488 psc->dsh,
761 GNUNET_BLOCK_TYPE_FS_UBLOCK, bo->content_priority, 489 identifier,
762 bo->anonymity_level, bo->replication_level, 490 update,
763 bo->expiration_time, -2, 1, 491 ns,
764 GNUNET_CONSTANTS_SERVICE_TIMEOUT, &sb_put_cont, psc); 492 meta,
765 GNUNET_free (ub); 493 uri,
766 GNUNET_free (ub_enc); 494 bo,
495 options,
496 &sks_publish_cont,
497 psc);
767 return psc; 498 return psc;
768} 499}
769 500
@@ -776,17 +507,16 @@ GNUNET_FS_publish_sks (struct GNUNET_FS_Handle *h,
776void 507void
777GNUNET_FS_publish_sks_cancel (struct GNUNET_FS_PublishSksContext *psc) 508GNUNET_FS_publish_sks_cancel (struct GNUNET_FS_PublishSksContext *psc)
778{ 509{
779 if (NULL != psc->dqe) 510 if (NULL != psc->uc)
780 { 511 {
781 GNUNET_DATASTORE_cancel (psc->dqe); 512 GNUNET_FS_publish_ublock_cancel_ (psc->uc);
782 psc->dqe = NULL; 513 psc->uc = NULL;
783 } 514 }
784 if (NULL != psc->dsh) 515 if (NULL != psc->dsh)
785 { 516 {
786 GNUNET_DATASTORE_disconnect (psc->dsh, GNUNET_NO); 517 GNUNET_DATASTORE_disconnect (psc->dsh, GNUNET_NO);
787 psc->dsh = NULL; 518 psc->dsh = NULL;
788 } 519 }
789 GNUNET_FS_namespace_delete (psc->ns, GNUNET_NO);
790 GNUNET_FS_uri_destroy (psc->uri); 520 GNUNET_FS_uri_destroy (psc->uri);
791 if (NULL != psc->nsn) 521 if (NULL != psc->nsn)
792 { 522 {
@@ -828,12 +558,18 @@ struct ProcessUpdateClosure
828 * GNUNET_NO if not. 558 * GNUNET_NO if not.
829 */ 559 */
830static int 560static int
831process_update_node (void *cls, const struct GNUNET_HashCode * key, void *value) 561process_update_node (void *cls,
562 const struct GNUNET_HashCode *key,
563 void *value)
832{ 564{
833 struct ProcessUpdateClosure *pc = cls; 565 struct ProcessUpdateClosure *pc = cls;
834 struct NamespaceUpdateNode *nsn = value; 566 struct NamespaceUpdateNode *nsn = value;
835 567
836 pc->ip (pc->ip_cls, nsn->id, nsn->uri, nsn->md, nsn->update); 568 pc->ip (pc->ip_cls,
569 nsn->id,
570 nsn->uri,
571 nsn->md,
572 nsn->update);
837 return GNUNET_YES; 573 return GNUNET_YES;
838} 574}
839 575
@@ -844,9 +580,9 @@ process_update_node (void *cls, const struct GNUNET_HashCode * key, void *value)
844struct FindTreeClosure 580struct FindTreeClosure
845{ 581{
846 /** 582 /**
847 * Namespace we are operating on. 583 * UIG we are operating on.
848 */ 584 */
849 struct GNUNET_FS_Namespace *ns; 585 struct GNUNET_FS_UpdateInformationGraph *uig;
850 586
851 /** 587 /**
852 * Array with 'head's of TREEs. 588 * Array with 'head's of TREEs.
@@ -891,7 +627,9 @@ struct FindTreeClosure
891 * GNUNET_NO if not. 627 * GNUNET_NO if not.
892 */ 628 */
893static int 629static int
894find_trees (void *cls, const struct GNUNET_HashCode * key, void *value) 630find_trees (void *cls,
631 const struct GNUNET_HashCode *key,
632 void *value)
895{ 633{
896 struct FindTreeClosure *fc = cls; 634 struct FindTreeClosure *fc = cls;
897 struct NamespaceUpdateNode *nsn = value; 635 struct NamespaceUpdateNode *nsn = value;
@@ -918,7 +656,7 @@ find_trees (void *cls, const struct GNUNET_HashCode * key, void *value)
918 nsn->tree_id = UINT_MAX; /* mark as undef */ 656 nsn->tree_id = UINT_MAX; /* mark as undef */
919 /* trace */ 657 /* trace */
920 GNUNET_CRYPTO_hash (nsn->update, strlen (nsn->update), &hc); 658 GNUNET_CRYPTO_hash (nsn->update, strlen (nsn->update), &hc);
921 GNUNET_CONTAINER_multihashmap_get_multiple (fc->ns->update_map, &hc, 659 GNUNET_CONTAINER_multihashmap_get_multiple (fc->uig->update_map, &hc,
922 &find_trees, fc); 660 &find_trees, fc);
923 } 661 }
924 return GNUNET_YES; 662 return GNUNET_YES;
@@ -942,13 +680,15 @@ find_trees (void *cls, const struct GNUNET_HashCode * key, void *value)
942 * I know, odd definition of a tree, but the GUI will display an actual 680 * I know, odd definition of a tree, but the GUI will display an actual
943 * tree (GtkTreeView), so that's what counts for the term here. 681 * tree (GtkTreeView), so that's what counts for the term here.
944 * 682 *
683 * @param h fs handle to use
945 * @param ns namespace to inspect for updateable content 684 * @param ns namespace to inspect for updateable content
946 * @param next_id ID to look for; use NULL to look for tree roots 685 * @param next_id ID to look for; use NULL to look for tree roots
947 * @param ip function to call on each updateable identifier 686 * @param ip function to call on each updateable identifier
948 * @param ip_cls closure for ip 687 * @param ip_cls closure for ip
949 */ 688 */
950void 689void
951GNUNET_FS_namespace_list_updateable (struct GNUNET_FS_Namespace *ns, 690GNUNET_FS_namespace_list_updateable (struct GNUNET_FS_Handle *h,
691 const struct GNUNET_CRYPTO_EccPrivateKey *ns,
952 const char *next_id, 692 const char *next_id,
953 GNUNET_FS_IdentifierProcessor ip, 693 GNUNET_FS_IdentifierProcessor ip,
954 void *ip_cls) 694 void *ip_cls)
@@ -959,50 +699,48 @@ GNUNET_FS_namespace_list_updateable (struct GNUNET_FS_Namespace *ns,
959 struct NamespaceUpdateNode *nsn; 699 struct NamespaceUpdateNode *nsn;
960 struct ProcessUpdateClosure pc; 700 struct ProcessUpdateClosure pc;
961 struct FindTreeClosure fc; 701 struct FindTreeClosure fc;
702 struct GNUNET_FS_UpdateInformationGraph *uig;
962 703
963 if (NULL == ns->update_nodes) 704 uig = read_update_information_graph (h, ns);
964 read_update_information_graph (ns); 705 if (NULL == uig->update_nodes)
965 if (NULL == ns->update_nodes)
966 { 706 {
967 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, 707 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
968 "No updateable nodes found for ID `%s'\n", next_id); 708 "No updateable nodes found for ID `%s'\n", next_id);
709 free_update_information_graph (uig);
969 return; /* no nodes */ 710 return; /* no nodes */
970 } 711 }
971 if (NULL == ns->update_map) 712 uig->update_map =
713 GNUNET_CONTAINER_multihashmap_create (2 +
714 3 * uig->update_node_count /
715 4,
716 GNUNET_NO);
717 for (i = 0; i < uig->update_node_count; i++)
972 { 718 {
973 /* need to construct */ 719 nsn = uig->update_nodes[i];
974 ns->update_map = 720 GNUNET_CRYPTO_hash (nsn->id, strlen (nsn->id), &hc);
975 GNUNET_CONTAINER_multihashmap_create (2 + 721 GNUNET_CONTAINER_multihashmap_put (uig->update_map, &hc, nsn,
976 3 * ns->update_node_count / 722 GNUNET_CONTAINER_MULTIHASHMAPOPTION_MULTIPLE);
977 4,
978 GNUNET_NO);
979 for (i = 0; i < ns->update_node_count; i++)
980 {
981 nsn = ns->update_nodes[i];
982 GNUNET_CRYPTO_hash (nsn->id, strlen (nsn->id), &hc);
983 GNUNET_CONTAINER_multihashmap_put (ns->update_map, &hc, nsn,
984 GNUNET_CONTAINER_MULTIHASHMAPOPTION_MULTIPLE);
985 }
986 } 723 }
987 if (NULL != next_id) 724 if (NULL != next_id)
988 { 725 {
989 GNUNET_CRYPTO_hash (next_id, strlen (next_id), &hc); 726 GNUNET_CRYPTO_hash (next_id, strlen (next_id), &hc);
990 pc.ip = ip; 727 pc.ip = ip;
991 pc.ip_cls = ip_cls; 728 pc.ip_cls = ip_cls;
992 GNUNET_CONTAINER_multihashmap_get_multiple (ns->update_map, &hc, 729 GNUNET_CONTAINER_multihashmap_get_multiple (uig->update_map, &hc,
993 &process_update_node, &pc); 730 &process_update_node, &pc);
731 free_update_information_graph (uig);
994 return; 732 return;
995 } 733 }
996 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, 734 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
997 "Calculating TREEs to find roots of update trees\n"); 735 "Calculating TREEs to find roots of update trees\n");
998 /* Find heads of TREEs in update graph */ 736 /* Find heads of TREEs in update graph */
999 nug = ++ns->nug_gen; 737 nug = ++uig->nug_gen;
1000 fc.tree_array = NULL; 738 fc.tree_array = NULL;
1001 fc.tree_array_size = 0; 739 fc.tree_array_size = 0;
1002 740
1003 for (i = 0; i < ns->update_node_count; i++) 741 for (i = 0; i < uig->update_node_count; i++)
1004 { 742 {
1005 nsn = ns->update_nodes[i]; 743 nsn = uig->update_nodes[i];
1006 if (nsn->nug == nug) 744 if (nsn->nug == nug)
1007 { 745 {
1008 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "TREE of node `%s' is %u\n", nsn->id, 746 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "TREE of node `%s' is %u\n", nsn->id,
@@ -1014,15 +752,15 @@ GNUNET_FS_namespace_list_updateable (struct GNUNET_FS_Namespace *ns,
1014 nsn->tree_id = UINT_MAX; 752 nsn->tree_id = UINT_MAX;
1015 fc.id = UINT_MAX; 753 fc.id = UINT_MAX;
1016 fc.nug = nug; 754 fc.nug = nug;
1017 fc.ns = ns; 755 fc.uig = uig;
1018 GNUNET_CONTAINER_multihashmap_get_multiple (ns->update_map, &hc, 756 GNUNET_CONTAINER_multihashmap_get_multiple (uig->update_map, &hc,
1019 &find_trees, &fc); 757 &find_trees, &fc);
1020 if (UINT_MAX == fc.id) 758 if (UINT_MAX == fc.id)
1021 { 759 {
1022 /* start new TREE */ 760 /* start new TREE */
1023 for (fc.id = 0; fc.id < fc.tree_array_size; fc.id++) 761 for (fc.id = 0; fc.id < fc.tree_array_size; fc.id++)
1024 { 762 {
1025 if (fc.tree_array[fc.id] == NULL) 763 if (NULL == fc.tree_array[fc.id])
1026 { 764 {
1027 fc.tree_array[fc.id] = nsn; 765 fc.tree_array[fc.id] = nsn;
1028 nsn->tree_id = fc.id; 766 nsn->tree_id = fc.id;
@@ -1041,8 +779,8 @@ GNUNET_FS_namespace_list_updateable (struct GNUNET_FS_Namespace *ns,
1041 GNUNET_CRYPTO_hash (nsn->id, strlen (nsn->id), &hc); 779 GNUNET_CRYPTO_hash (nsn->id, strlen (nsn->id), &hc);
1042 fc.id = nsn->tree_id; 780 fc.id = nsn->tree_id;
1043 fc.nug = nug; 781 fc.nug = nug;
1044 fc.ns = ns; 782 fc.uig = uig;
1045 GNUNET_CONTAINER_multihashmap_get_multiple (ns->update_map, &hc, 783 GNUNET_CONTAINER_multihashmap_get_multiple (uig->update_map, &hc,
1046 &find_trees, &fc); 784 &find_trees, &fc);
1047 } 785 }
1048 else 786 else
@@ -1051,7 +789,8 @@ GNUNET_FS_namespace_list_updateable (struct GNUNET_FS_Namespace *ns,
1051 fc.tree_array[fc.id] = nsn; 789 fc.tree_array[fc.id] = nsn;
1052 nsn->tree_id = fc.id; 790 nsn->tree_id = fc.id;
1053 } 791 }
1054 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "TREE of node `%s' is %u\n", nsn->id, 792 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
793 "TREE of node `%s' is %u\n", nsn->id,
1055 fc.id); 794 fc.id);
1056 } 795 }
1057 for (i = 0; i < fc.tree_array_size; i++) 796 for (i = 0; i < fc.tree_array_size; i++)
@@ -1066,6 +805,7 @@ GNUNET_FS_namespace_list_updateable (struct GNUNET_FS_Namespace *ns,
1066 } 805 }
1067 GNUNET_array_grow (fc.tree_array, fc.tree_array_size, 0); 806 GNUNET_array_grow (fc.tree_array, fc.tree_array_size, 0);
1068 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Done processing TREEs\n"); 807 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Done processing TREEs\n");
808 free_update_information_graph (uig);
1069} 809}
1070 810
1071 811