summaryrefslogtreecommitdiff
path: root/src/fs/fs_namespace.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/fs/fs_namespace.c')
-rw-r--r--src/fs/fs_namespace.c655
1 files changed, 330 insertions, 325 deletions
diff --git a/src/fs/fs_namespace.c b/src/fs/fs_namespace.c
index b740eb2ba..6ede02afd 100644
--- a/src/fs/fs_namespace.c
+++ b/src/fs/fs_namespace.c
@@ -37,7 +37,8 @@
37 * Information about an (updateable) node in the 37 * Information about an (updateable) node in the
38 * namespace. 38 * namespace.
39 */ 39 */
40struct NamespaceUpdateNode { 40struct NamespaceUpdateNode
41{
41 /** 42 /**
42 * Identifier for this node. 43 * Identifier for this node.
43 */ 44 */
@@ -74,7 +75,8 @@ struct NamespaceUpdateNode {
74/** 75/**
75 * Handle to update information for a namespace. 76 * Handle to update information for a namespace.
76 */ 77 */
77struct GNUNET_FS_UpdateInformationGraph { 78struct GNUNET_FS_UpdateInformationGraph
79{
78 /** 80 /**
79 * Handle to the FS service context. 81 * Handle to the FS service context.
80 */ 82 */
@@ -122,7 +124,7 @@ struct GNUNET_FS_UpdateInformationGraph {
122 * @return NULL on error, otherwise the name of the directory 124 * @return NULL on error, otherwise the name of the directory
123 */ 125 */
124static char * 126static char *
125get_update_information_directory( 127get_update_information_directory (
126 struct GNUNET_FS_Handle *h, 128 struct GNUNET_FS_Handle *h,
127 const struct GNUNET_CRYPTO_EcdsaPrivateKey *ns) 129 const struct GNUNET_CRYPTO_EcdsaPrivateKey *ns)
128{ 130{
@@ -133,20 +135,20 @@ get_update_information_directory(
133 struct GNUNET_CRYPTO_HashAsciiEncoded enc; 135 struct GNUNET_CRYPTO_HashAsciiEncoded enc;
134 136
135 if (GNUNET_OK != 137 if (GNUNET_OK !=
136 GNUNET_CONFIGURATION_get_value_filename(h->cfg, "FS", "UPDATE_DIR", &dn)) 138 GNUNET_CONFIGURATION_get_value_filename (h->cfg, "FS", "UPDATE_DIR", &dn))
137 { 139 {
138 GNUNET_log_config_missing(GNUNET_ERROR_TYPE_ERROR, "fs", "UPDATE_DIR"); 140 GNUNET_log_config_missing (GNUNET_ERROR_TYPE_ERROR, "fs", "UPDATE_DIR");
139 return NULL; 141 return NULL;
140 } 142 }
141 GNUNET_CRYPTO_ecdsa_key_get_public(ns, &pub); 143 GNUNET_CRYPTO_ecdsa_key_get_public (ns, &pub);
142 GNUNET_CRYPTO_hash(&pub, sizeof(pub), &hc); 144 GNUNET_CRYPTO_hash (&pub, sizeof(pub), &hc);
143 GNUNET_CRYPTO_hash_to_enc(&hc, &enc); 145 GNUNET_CRYPTO_hash_to_enc (&hc, &enc);
144 GNUNET_asprintf(&ret, 146 GNUNET_asprintf (&ret,
145 "%s%s%s", 147 "%s%s%s",
146 dn, 148 dn,
147 DIR_SEPARATOR_STR, 149 DIR_SEPARATOR_STR,
148 (const char *)enc.encoding); 150 (const char *) enc.encoding);
149 GNUNET_free(dn); 151 GNUNET_free (dn);
150 return ret; 152 return ret;
151} 153}
152 154
@@ -157,24 +159,24 @@ get_update_information_directory(
157 * @param uig data structure to free 159 * @param uig data structure to free
158 */ 160 */
159static void 161static void
160free_update_information_graph(struct GNUNET_FS_UpdateInformationGraph *uig) 162free_update_information_graph (struct GNUNET_FS_UpdateInformationGraph *uig)
161{ 163{
162 unsigned int i; 164 unsigned int i;
163 struct NamespaceUpdateNode *nsn; 165 struct NamespaceUpdateNode *nsn;
164 166
165 for (i = 0; i < uig->update_node_count; i++) 167 for (i = 0; i < uig->update_node_count; i++)
166 { 168 {
167 nsn = uig->update_nodes[i]; 169 nsn = uig->update_nodes[i];
168 GNUNET_CONTAINER_meta_data_destroy(nsn->md); 170 GNUNET_CONTAINER_meta_data_destroy (nsn->md);
169 GNUNET_FS_uri_destroy(nsn->uri); 171 GNUNET_FS_uri_destroy (nsn->uri);
170 GNUNET_free(nsn->id); 172 GNUNET_free (nsn->id);
171 GNUNET_free(nsn->update); 173 GNUNET_free (nsn->update);
172 GNUNET_free(nsn); 174 GNUNET_free (nsn);
173 } 175 }
174 GNUNET_array_grow(uig->update_nodes, uig->update_node_count, 0); 176 GNUNET_array_grow (uig->update_nodes, uig->update_node_count, 0);
175 if (NULL != uig->update_map) 177 if (NULL != uig->update_map)
176 GNUNET_CONTAINER_multihashmap_destroy(uig->update_map); 178 GNUNET_CONTAINER_multihashmap_destroy (uig->update_map);
177 GNUNET_free(uig); 179 GNUNET_free (uig);
178} 180}
179 181
180 182
@@ -184,7 +186,7 @@ free_update_information_graph(struct GNUNET_FS_UpdateInformationGraph *uig)
184 * @param uig update information graph to dump 186 * @param uig update information graph to dump
185 */ 187 */
186static void 188static void
187write_update_information_graph(struct GNUNET_FS_UpdateInformationGraph *uig) 189write_update_information_graph (struct GNUNET_FS_UpdateInformationGraph *uig)
188{ 190{
189 char *fn; 191 char *fn;
190 struct GNUNET_BIO_WriteHandle *wh; 192 struct GNUNET_BIO_WriteHandle *wh;
@@ -192,40 +194,40 @@ write_update_information_graph(struct GNUNET_FS_UpdateInformationGraph *uig)
192 struct NamespaceUpdateNode *n; 194 struct NamespaceUpdateNode *n;
193 char *uris; 195 char *uris;
194 196
195 fn = get_update_information_directory(uig->h, &uig->ns); 197 fn = get_update_information_directory (uig->h, &uig->ns);
196 wh = GNUNET_BIO_write_open(fn); 198 wh = GNUNET_BIO_write_open (fn);
197 if (NULL == wh) 199 if (NULL == wh)
198 { 200 {
199 GNUNET_log(GNUNET_ERROR_TYPE_ERROR, 201 GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
200 _("Failed to open `%s' for writing: %s\n"), 202 _ ("Failed to open `%s' for writing: %s\n"),
201 fn, 203 fn,
202 strerror(errno)); 204 strerror (errno));
203 GNUNET_free(fn); 205 GNUNET_free (fn);
204 return; 206 return;
205 } 207 }
206 if (GNUNET_OK != GNUNET_BIO_write_int32(wh, uig->update_node_count)) 208 if (GNUNET_OK != GNUNET_BIO_write_int32 (wh, uig->update_node_count))
207 goto END; 209 goto END;
208 for (i = 0; i < uig->update_node_count; i++) 210 for (i = 0; i < uig->update_node_count; i++)
211 {
212 n = uig->update_nodes[i];
213 uris = GNUNET_FS_uri_to_string (n->uri);
214 if ((GNUNET_OK != GNUNET_BIO_write_string (wh, n->id)) ||
215 (GNUNET_OK != GNUNET_BIO_write_meta_data (wh, n->md)) ||
216 (GNUNET_OK != GNUNET_BIO_write_string (wh, n->update)) ||
217 (GNUNET_OK != GNUNET_BIO_write_string (wh, uris)))
209 { 218 {
210 n = uig->update_nodes[i]; 219 GNUNET_free (uris);
211 uris = GNUNET_FS_uri_to_string(n->uri); 220 break;
212 if ((GNUNET_OK != GNUNET_BIO_write_string(wh, n->id)) ||
213 (GNUNET_OK != GNUNET_BIO_write_meta_data(wh, n->md)) ||
214 (GNUNET_OK != GNUNET_BIO_write_string(wh, n->update)) ||
215 (GNUNET_OK != GNUNET_BIO_write_string(wh, uris)))
216 {
217 GNUNET_free(uris);
218 break;
219 }
220 GNUNET_free(uris);
221 } 221 }
222 GNUNET_free (uris);
223 }
222END: 224END:
223 if (GNUNET_OK != GNUNET_BIO_write_close(wh)) 225 if (GNUNET_OK != GNUNET_BIO_write_close (wh))
224 GNUNET_log(GNUNET_ERROR_TYPE_ERROR, 226 GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
225 _("Failed to write `%s': %s\n"), 227 _ ("Failed to write `%s': %s\n"),
226 fn, 228 fn,
227 strerror(errno)); 229 strerror (errno));
228 GNUNET_free(fn); 230 GNUNET_free (fn);
229} 231}
230 232
231 233
@@ -237,8 +239,8 @@ END:
237 * @return update graph, never NULL 239 * @return update graph, never NULL
238 */ 240 */
239static struct GNUNET_FS_UpdateInformationGraph * 241static struct GNUNET_FS_UpdateInformationGraph *
240read_update_information_graph(struct GNUNET_FS_Handle *h, 242read_update_information_graph (struct GNUNET_FS_Handle *h,
241 const struct GNUNET_CRYPTO_EcdsaPrivateKey *ns) 243 const struct GNUNET_CRYPTO_EcdsaPrivateKey *ns)
242{ 244{
243 struct GNUNET_FS_UpdateInformationGraph *uig; 245 struct GNUNET_FS_UpdateInformationGraph *uig;
244 char *fn; 246 char *fn;
@@ -249,79 +251,79 @@ read_update_information_graph(struct GNUNET_FS_Handle *h,
249 uint32_t count; 251 uint32_t count;
250 char *emsg; 252 char *emsg;
251 253
252 uig = GNUNET_new(struct GNUNET_FS_UpdateInformationGraph); 254 uig = GNUNET_new (struct GNUNET_FS_UpdateInformationGraph);
253 uig->h = h; 255 uig->h = h;
254 uig->ns = *ns; 256 uig->ns = *ns;
255 fn = get_update_information_directory(h, ns); 257 fn = get_update_information_directory (h, ns);
256 if (GNUNET_YES != GNUNET_DISK_file_test(fn)) 258 if (GNUNET_YES != GNUNET_DISK_file_test (fn))
257 { 259 {
258 GNUNET_free(fn); 260 GNUNET_free (fn);
259 return uig; 261 return uig;
260 } 262 }
261 rh = GNUNET_BIO_read_open(fn); 263 rh = GNUNET_BIO_read_open (fn);
262 if (NULL == rh) 264 if (NULL == rh)
263 { 265 {
264 GNUNET_free(fn); 266 GNUNET_free (fn);
265 return uig; 267 return uig;
266 } 268 }
267 if (GNUNET_OK != GNUNET_BIO_read_int32(rh, &count)) 269 if (GNUNET_OK != GNUNET_BIO_read_int32 (rh, &count))
268 { 270 {
269 GNUNET_break(0); 271 GNUNET_break (0);
270 goto END; 272 goto END;
271 } 273 }
272 if (count > 1024 * 1024) 274 if (count > 1024 * 1024)
273 { 275 {
274 GNUNET_break(0); 276 GNUNET_break (0);
275 goto END; 277 goto END;
276 } 278 }
277 if (0 == count) 279 if (0 == count)
278 goto END; 280 goto END;
279 uig->update_nodes = 281 uig->update_nodes =
280 GNUNET_malloc(count * sizeof(struct NamespaceUpdateNode *)); 282 GNUNET_malloc (count * sizeof(struct NamespaceUpdateNode *));
281 283
282 for (i = 0; i < count; i++) 284 for (i = 0; i < count; i++)
285 {
286 n = GNUNET_new (struct NamespaceUpdateNode);
287 if ((GNUNET_OK !=
288 GNUNET_BIO_read_string (rh, "identifier", &n->id, 1024)) ||
289 (GNUNET_OK != GNUNET_BIO_read_meta_data (rh, "meta", &n->md)) ||
290 (GNUNET_OK !=
291 GNUNET_BIO_read_string (rh, "update-id", &n->update, 1024)) ||
292 (GNUNET_OK != GNUNET_BIO_read_string (rh, "uri", &uris, 1024 * 2)))
283 { 293 {
284 n = GNUNET_new(struct NamespaceUpdateNode); 294 GNUNET_break (0);
285 if ((GNUNET_OK != 295 GNUNET_free_non_null (n->id);
286 GNUNET_BIO_read_string(rh, "identifier", &n->id, 1024)) || 296 GNUNET_free_non_null (n->update);
287 (GNUNET_OK != GNUNET_BIO_read_meta_data(rh, "meta", &n->md)) || 297 if (n->md != NULL)
288 (GNUNET_OK != 298 GNUNET_CONTAINER_meta_data_destroy (n->md);
289 GNUNET_BIO_read_string(rh, "update-id", &n->update, 1024)) || 299 GNUNET_free (n);
290 (GNUNET_OK != GNUNET_BIO_read_string(rh, "uri", &uris, 1024 * 2))) 300 break;
291 {
292 GNUNET_break(0);
293 GNUNET_free_non_null(n->id);
294 GNUNET_free_non_null(n->update);
295 if (n->md != NULL)
296 GNUNET_CONTAINER_meta_data_destroy(n->md);
297 GNUNET_free(n);
298 break;
299 }
300 n->uri = GNUNET_FS_uri_parse(uris, &emsg);
301 GNUNET_free(uris);
302 if (n->uri == NULL)
303 {
304 GNUNET_break(0);
305 GNUNET_free(emsg);
306 GNUNET_free(n->id);
307 GNUNET_free_non_null(n->update);
308 GNUNET_CONTAINER_meta_data_destroy(n->md);
309 GNUNET_free(n);
310 break;
311 }
312 uig->update_nodes[i] = n;
313 } 301 }
314 uig->update_node_count = i; 302 n->uri = GNUNET_FS_uri_parse (uris, &emsg);
315END: 303 GNUNET_free (uris);
316 if (GNUNET_OK != GNUNET_BIO_read_close(rh, &emsg)) 304 if (n->uri == NULL)
317 { 305 {
318 GNUNET_log(GNUNET_ERROR_TYPE_ERROR, 306 GNUNET_break (0);
319 _("Failed to read `%s': %s\n"), 307 GNUNET_free (emsg);
320 fn, 308 GNUNET_free (n->id);
321 emsg); 309 GNUNET_free_non_null (n->update);
322 GNUNET_free(emsg); 310 GNUNET_CONTAINER_meta_data_destroy (n->md);
311 GNUNET_free (n);
312 break;
323 } 313 }
324 GNUNET_free(fn); 314 uig->update_nodes[i] = n;
315 }
316 uig->update_node_count = i;
317END:
318 if (GNUNET_OK != GNUNET_BIO_read_close (rh, &emsg))
319 {
320 GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
321 _ ("Failed to read `%s': %s\n"),
322 fn,
323 emsg);
324 GNUNET_free (emsg);
325 }
326 GNUNET_free (fn);
325 return uig; 327 return uig;
326} 328}
327 329
@@ -329,7 +331,8 @@ END:
329/** 331/**
330 * Context for the SKS publication. 332 * Context for the SKS publication.
331 */ 333 */
332struct GNUNET_FS_PublishSksContext { 334struct GNUNET_FS_PublishSksContext
335{
333 /** 336 /**
334 * URI of the new entry in the namespace. 337 * URI of the new entry in the namespace.
335 */ 338 */
@@ -381,33 +384,33 @@ struct GNUNET_FS_PublishSksContext {
381 * @param msg error message (or NULL) 384 * @param msg error message (or NULL)
382 */ 385 */
383static void 386static void
384sks_publish_cont(void *cls, const char *msg) 387sks_publish_cont (void *cls, const char *msg)
385{ 388{
386 struct GNUNET_FS_PublishSksContext *psc = cls; 389 struct GNUNET_FS_PublishSksContext *psc = cls;
387 struct GNUNET_FS_UpdateInformationGraph *uig; 390 struct GNUNET_FS_UpdateInformationGraph *uig;
388 391
389 psc->uc = NULL; 392 psc->uc = NULL;
390 if (NULL != msg) 393 if (NULL != msg)
391 { 394 {
392 if (NULL != psc->cont) 395 if (NULL != psc->cont)
393 psc->cont(psc->cont_cls, NULL, msg); 396 psc->cont (psc->cont_cls, NULL, msg);
394 GNUNET_FS_publish_sks_cancel(psc); 397 GNUNET_FS_publish_sks_cancel (psc);
395 return; 398 return;
396 } 399 }
397 if (NULL != psc->nsn) 400 if (NULL != psc->nsn)
398 { 401 {
399 /* FIXME: this can be done much more 402 /* FIXME: this can be done much more
400 * efficiently by simply appending to the 403 * efficiently by simply appending to the
401 * file and overwriting the 4-byte header */ 404 * file and overwriting the 4-byte header */
402 uig = read_update_information_graph(psc->h, &psc->ns); 405 uig = read_update_information_graph (psc->h, &psc->ns);
403 GNUNET_array_append(uig->update_nodes, uig->update_node_count, psc->nsn); 406 GNUNET_array_append (uig->update_nodes, uig->update_node_count, psc->nsn);
404 psc->nsn = NULL; 407 psc->nsn = NULL;
405 write_update_information_graph(uig); 408 write_update_information_graph (uig);
406 free_update_information_graph(uig); 409 free_update_information_graph (uig);
407 } 410 }
408 if (NULL != psc->cont) 411 if (NULL != psc->cont)
409 psc->cont(psc->cont_cls, psc->uri, NULL); 412 psc->cont (psc->cont_cls, psc->uri, NULL);
410 GNUNET_FS_publish_sks_cancel(psc); 413 GNUNET_FS_publish_sks_cancel (psc);
411} 414}
412 415
413 416
@@ -427,59 +430,59 @@ sks_publish_cont(void *cls, const char *msg)
427 * @return NULL on error ('cont' will still be called) 430 * @return NULL on error ('cont' will still be called)
428 */ 431 */
429struct GNUNET_FS_PublishSksContext * 432struct GNUNET_FS_PublishSksContext *
430GNUNET_FS_publish_sks(struct GNUNET_FS_Handle *h, 433GNUNET_FS_publish_sks (struct GNUNET_FS_Handle *h,
431 const struct GNUNET_CRYPTO_EcdsaPrivateKey *ns, 434 const struct GNUNET_CRYPTO_EcdsaPrivateKey *ns,
432 const char *identifier, 435 const char *identifier,
433 const char *update, 436 const char *update,
434 const struct GNUNET_CONTAINER_MetaData *meta, 437 const struct GNUNET_CONTAINER_MetaData *meta,
435 const struct GNUNET_FS_Uri *uri, 438 const struct GNUNET_FS_Uri *uri,
436 const struct GNUNET_FS_BlockOptions *bo, 439 const struct GNUNET_FS_BlockOptions *bo,
437 enum GNUNET_FS_PublishOptions options, 440 enum GNUNET_FS_PublishOptions options,
438 GNUNET_FS_PublishContinuation cont, 441 GNUNET_FS_PublishContinuation cont,
439 void *cont_cls) 442 void *cont_cls)
440{ 443{
441 struct GNUNET_FS_PublishSksContext *psc; 444 struct GNUNET_FS_PublishSksContext *psc;
442 struct GNUNET_FS_Uri *sks_uri; 445 struct GNUNET_FS_Uri *sks_uri;
443 446
444 sks_uri = GNUNET_new(struct GNUNET_FS_Uri); 447 sks_uri = GNUNET_new (struct GNUNET_FS_Uri);
445 sks_uri->type = GNUNET_FS_URI_SKS; 448 sks_uri->type = GNUNET_FS_URI_SKS;
446 sks_uri->data.sks.identifier = GNUNET_strdup(identifier); 449 sks_uri->data.sks.identifier = GNUNET_strdup (identifier);
447 GNUNET_CRYPTO_ecdsa_key_get_public(ns, &sks_uri->data.sks.ns); 450 GNUNET_CRYPTO_ecdsa_key_get_public (ns, &sks_uri->data.sks.ns);
448 451
449 psc = GNUNET_new(struct GNUNET_FS_PublishSksContext); 452 psc = GNUNET_new (struct GNUNET_FS_PublishSksContext);
450 psc->h = h; 453 psc->h = h;
451 psc->uri = sks_uri; 454 psc->uri = sks_uri;
452 psc->cont = cont; 455 psc->cont = cont;
453 psc->cont_cls = cont_cls; 456 psc->cont_cls = cont_cls;
454 psc->ns = *ns; 457 psc->ns = *ns;
455 if (0 == (options & GNUNET_FS_PUBLISH_OPTION_SIMULATE_ONLY)) 458 if (0 == (options & GNUNET_FS_PUBLISH_OPTION_SIMULATE_ONLY))
459 {
460 psc->dsh = GNUNET_DATASTORE_connect (h->cfg);
461 if (NULL == psc->dsh)
456 { 462 {
457 psc->dsh = GNUNET_DATASTORE_connect(h->cfg); 463 sks_publish_cont (psc, _ ("Failed to connect to datastore."));
458 if (NULL == psc->dsh) 464 return NULL;
459 {
460 sks_publish_cont(psc, _("Failed to connect to datastore."));
461 return NULL;
462 }
463 } 465 }
466 }
464 if (NULL != update) 467 if (NULL != update)
465 { 468 {
466 psc->nsn = GNUNET_new(struct NamespaceUpdateNode); 469 psc->nsn = GNUNET_new (struct NamespaceUpdateNode);
467 psc->nsn->id = GNUNET_strdup(identifier); 470 psc->nsn->id = GNUNET_strdup (identifier);
468 psc->nsn->update = GNUNET_strdup(update); 471 psc->nsn->update = GNUNET_strdup (update);
469 psc->nsn->md = GNUNET_CONTAINER_meta_data_duplicate(meta); 472 psc->nsn->md = GNUNET_CONTAINER_meta_data_duplicate (meta);
470 psc->nsn->uri = GNUNET_FS_uri_dup(uri); 473 psc->nsn->uri = GNUNET_FS_uri_dup (uri);
471 } 474 }
472 psc->uc = GNUNET_FS_publish_ublock_(h, 475 psc->uc = GNUNET_FS_publish_ublock_ (h,
473 psc->dsh, 476 psc->dsh,
474 identifier, 477 identifier,
475 update, 478 update,
476 ns, 479 ns,
477 meta, 480 meta,
478 uri, 481 uri,
479 bo, 482 bo,
480 options, 483 options,
481 &sks_publish_cont, 484 &sks_publish_cont,
482 psc); 485 psc);
483 return psc; 486 return psc;
484} 487}
485 488
@@ -490,35 +493,36 @@ GNUNET_FS_publish_sks(struct GNUNET_FS_Handle *h,
490 * @param psc context of the operation to abort. 493 * @param psc context of the operation to abort.
491 */ 494 */
492void 495void
493GNUNET_FS_publish_sks_cancel(struct GNUNET_FS_PublishSksContext *psc) 496GNUNET_FS_publish_sks_cancel (struct GNUNET_FS_PublishSksContext *psc)
494{ 497{
495 if (NULL != psc->uc) 498 if (NULL != psc->uc)
496 { 499 {
497 GNUNET_FS_publish_ublock_cancel_(psc->uc); 500 GNUNET_FS_publish_ublock_cancel_ (psc->uc);
498 psc->uc = NULL; 501 psc->uc = NULL;
499 } 502 }
500 if (NULL != psc->dsh) 503 if (NULL != psc->dsh)
501 { 504 {
502 GNUNET_DATASTORE_disconnect(psc->dsh, GNUNET_NO); 505 GNUNET_DATASTORE_disconnect (psc->dsh, GNUNET_NO);
503 psc->dsh = NULL; 506 psc->dsh = NULL;
504 } 507 }
505 GNUNET_FS_uri_destroy(psc->uri); 508 GNUNET_FS_uri_destroy (psc->uri);
506 if (NULL != psc->nsn) 509 if (NULL != psc->nsn)
507 { 510 {
508 GNUNET_CONTAINER_meta_data_destroy(psc->nsn->md); 511 GNUNET_CONTAINER_meta_data_destroy (psc->nsn->md);
509 GNUNET_FS_uri_destroy(psc->nsn->uri); 512 GNUNET_FS_uri_destroy (psc->nsn->uri);
510 GNUNET_free(psc->nsn->id); 513 GNUNET_free (psc->nsn->id);
511 GNUNET_free(psc->nsn->update); 514 GNUNET_free (psc->nsn->update);
512 GNUNET_free(psc->nsn); 515 GNUNET_free (psc->nsn);
513 } 516 }
514 GNUNET_free(psc); 517 GNUNET_free (psc);
515} 518}
516 519
517 520
518/** 521/**
519 * Closure for 'process_update_node'. 522 * Closure for 'process_update_node'.
520 */ 523 */
521struct ProcessUpdateClosure { 524struct ProcessUpdateClosure
525{
522 /** 526 /**
523 * Function to call for each node. 527 * Function to call for each node.
524 */ 528 */
@@ -542,12 +546,12 @@ struct ProcessUpdateClosure {
542 * GNUNET_NO if not. 546 * GNUNET_NO if not.
543 */ 547 */
544static int 548static int
545process_update_node(void *cls, const struct GNUNET_HashCode *key, void *value) 549process_update_node (void *cls, const struct GNUNET_HashCode *key, void *value)
546{ 550{
547 struct ProcessUpdateClosure *pc = cls; 551 struct ProcessUpdateClosure *pc = cls;
548 struct NamespaceUpdateNode *nsn = value; 552 struct NamespaceUpdateNode *nsn = value;
549 553
550 pc->ip(pc->ip_cls, nsn->id, nsn->uri, nsn->md, nsn->update); 554 pc->ip (pc->ip_cls, nsn->id, nsn->uri, nsn->md, nsn->update);
551 return GNUNET_YES; 555 return GNUNET_YES;
552} 556}
553 557
@@ -555,7 +559,8 @@ process_update_node(void *cls, const struct GNUNET_HashCode *key, void *value)
555/** 559/**
556 * Closure for 'find_trees'. 560 * Closure for 'find_trees'.
557 */ 561 */
558struct FindTreeClosure { 562struct FindTreeClosure
563{
559 /** 564 /**
560 * UIG we are operating on. 565 * UIG we are operating on.
561 */ 566 */
@@ -604,38 +609,38 @@ struct FindTreeClosure {
604 * GNUNET_NO if not. 609 * GNUNET_NO if not.
605 */ 610 */
606static int 611static int
607find_trees(void *cls, const struct GNUNET_HashCode *key, void *value) 612find_trees (void *cls, const struct GNUNET_HashCode *key, void *value)
608{ 613{
609 struct FindTreeClosure *fc = cls; 614 struct FindTreeClosure *fc = cls;
610 struct NamespaceUpdateNode *nsn = value; 615 struct NamespaceUpdateNode *nsn = value;
611 struct GNUNET_HashCode hc; 616 struct GNUNET_HashCode hc;
612 617
613 if (nsn->nug == fc->nug) 618 if (nsn->nug == fc->nug)
614 { 619 {
615 if (UINT_MAX == nsn->tree_id) 620 if (UINT_MAX == nsn->tree_id)
616 return GNUNET_YES; /* circular */ 621 return GNUNET_YES; /* circular */
617 GNUNET_assert(nsn->tree_id < fc->tree_array_size); 622 GNUNET_assert (nsn->tree_id < fc->tree_array_size);
618 if (fc->tree_array[nsn->tree_id] != nsn) 623 if (fc->tree_array[nsn->tree_id] != nsn)
619 return GNUNET_YES; /* part of "another" (directed) TREE, 624 return GNUNET_YES; /* part of "another" (directed) TREE,
620 * and not root of it, end trace */ 625 * and not root of it, end trace */
621 if (nsn->tree_id == fc->id) 626 if (nsn->tree_id == fc->id)
622 return GNUNET_YES; /* that's our own root (can this be?) */ 627 return GNUNET_YES; /* that's our own root (can this be?) */
623 /* merge existing TREE, we have a root for both */ 628 /* merge existing TREE, we have a root for both */
624 fc->tree_array[nsn->tree_id] = NULL; 629 fc->tree_array[nsn->tree_id] = NULL;
625 if (UINT_MAX == fc->id) 630 if (UINT_MAX == fc->id)
626 fc->id = nsn->tree_id; /* take over ID */ 631 fc->id = nsn->tree_id; /* take over ID */
627 } 632 }
628 else 633 else
629 { 634 {
630 nsn->nug = fc->nug; 635 nsn->nug = fc->nug;
631 nsn->tree_id = UINT_MAX; /* mark as undef */ 636 nsn->tree_id = UINT_MAX; /* mark as undef */
632 /* trace */ 637 /* trace */
633 GNUNET_CRYPTO_hash(nsn->update, strlen(nsn->update), &hc); 638 GNUNET_CRYPTO_hash (nsn->update, strlen (nsn->update), &hc);
634 GNUNET_CONTAINER_multihashmap_get_multiple(fc->uig->update_map, 639 GNUNET_CONTAINER_multihashmap_get_multiple (fc->uig->update_map,
635 &hc, 640 &hc,
636 &find_trees, 641 &find_trees,
637 fc); 642 fc);
638 } 643 }
639 return GNUNET_YES; 644 return GNUNET_YES;
640} 645}
641 646
@@ -664,7 +669,7 @@ find_trees(void *cls, const struct GNUNET_HashCode *key, void *value)
664 * @param ip_cls closure for ip 669 * @param ip_cls closure for ip
665 */ 670 */
666void 671void
667GNUNET_FS_namespace_list_updateable( 672GNUNET_FS_namespace_list_updateable (
668 struct GNUNET_FS_Handle *h, 673 struct GNUNET_FS_Handle *h,
669 const struct GNUNET_CRYPTO_EcdsaPrivateKey *ns, 674 const struct GNUNET_CRYPTO_EcdsaPrivateKey *ns,
670 const char *next_id, 675 const char *next_id,
@@ -679,125 +684,125 @@ GNUNET_FS_namespace_list_updateable(
679 struct FindTreeClosure fc; 684 struct FindTreeClosure fc;
680 struct GNUNET_FS_UpdateInformationGraph *uig; 685 struct GNUNET_FS_UpdateInformationGraph *uig;
681 686
682 uig = read_update_information_graph(h, ns); 687 uig = read_update_information_graph (h, ns);
683 if (NULL == uig->update_nodes) 688 if (NULL == uig->update_nodes)
684 { 689 {
685 GNUNET_log(GNUNET_ERROR_TYPE_DEBUG, 690 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
686 "No updateable nodes found for ID `%s'\n", 691 "No updateable nodes found for ID `%s'\n",
687 next_id); 692 next_id);
688 free_update_information_graph(uig); 693 free_update_information_graph (uig);
689 return; /* no nodes */ 694 return; /* no nodes */
690 } 695 }
691 uig->update_map = 696 uig->update_map =
692 GNUNET_CONTAINER_multihashmap_create(2 + 3 * uig->update_node_count / 4, 697 GNUNET_CONTAINER_multihashmap_create (2 + 3 * uig->update_node_count / 4,
693 GNUNET_NO); 698 GNUNET_NO);
694 for (i = 0; i < uig->update_node_count; i++) 699 for (i = 0; i < uig->update_node_count; i++)
695 { 700 {
696 nsn = uig->update_nodes[i]; 701 nsn = uig->update_nodes[i];
697 GNUNET_CRYPTO_hash(nsn->id, strlen(nsn->id), &hc); 702 GNUNET_CRYPTO_hash (nsn->id, strlen (nsn->id), &hc);
698 GNUNET_CONTAINER_multihashmap_put( 703 GNUNET_CONTAINER_multihashmap_put (
699 uig->update_map, 704 uig->update_map,
700 &hc, 705 &hc,
701 nsn, 706 nsn,
702 GNUNET_CONTAINER_MULTIHASHMAPOPTION_MULTIPLE); 707 GNUNET_CONTAINER_MULTIHASHMAPOPTION_MULTIPLE);
703 } 708 }
704 if (NULL != next_id) 709 if (NULL != next_id)
705 { 710 {
706 GNUNET_CRYPTO_hash(next_id, strlen(next_id), &hc); 711 GNUNET_CRYPTO_hash (next_id, strlen (next_id), &hc);
707 pc.ip = ip; 712 pc.ip = ip;
708 pc.ip_cls = ip_cls; 713 pc.ip_cls = ip_cls;
709 GNUNET_CONTAINER_multihashmap_get_multiple(uig->update_map, 714 GNUNET_CONTAINER_multihashmap_get_multiple (uig->update_map,
710 &hc, 715 &hc,
711 &process_update_node, 716 &process_update_node,
712 &pc); 717 &pc);
713 free_update_information_graph(uig); 718 free_update_information_graph (uig);
714 return; 719 return;
715 } 720 }
716 GNUNET_log(GNUNET_ERROR_TYPE_DEBUG, 721 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
717 "Calculating TREEs to find roots of update trees\n"); 722 "Calculating TREEs to find roots of update trees\n");
718 /* Find heads of TREEs in update graph */ 723 /* Find heads of TREEs in update graph */
719 nug = ++uig->nug_gen; 724 nug = ++uig->nug_gen;
720 fc.tree_array = NULL; 725 fc.tree_array = NULL;
721 fc.tree_array_size = 0; 726 fc.tree_array_size = 0;
722 727
723 for (i = 0; i < uig->update_node_count; i++) 728 for (i = 0; i < uig->update_node_count; i++)
729 {
730 nsn = uig->update_nodes[i];
731 if (nsn->nug == nug)
724 { 732 {
725 nsn = uig->update_nodes[i]; 733 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
726 if (nsn->nug == nug) 734 "TREE of node `%s' is %u\n",
727 { 735 nsn->id,
728 GNUNET_log(GNUNET_ERROR_TYPE_DEBUG, 736 nsn->nug);
729 "TREE of node `%s' is %u\n", 737 continue; /* already placed in TREE */
730 nsn->id, 738 }
731 nsn->nug); 739 GNUNET_CRYPTO_hash (nsn->update, strlen (nsn->update), &hc);
732 continue; /* already placed in TREE */ 740 nsn->nug = nug;
733 } 741 nsn->tree_id = UINT_MAX;
734 GNUNET_CRYPTO_hash(nsn->update, strlen(nsn->update), &hc); 742 fc.id = UINT_MAX;
735 nsn->nug = nug; 743 fc.nug = nug;
736 nsn->tree_id = UINT_MAX; 744 fc.uig = uig;
737 fc.id = UINT_MAX; 745 GNUNET_CONTAINER_multihashmap_get_multiple (uig->update_map,
738 fc.nug = nug; 746 &hc,
739 fc.uig = uig; 747 &find_trees,
740 GNUNET_CONTAINER_multihashmap_get_multiple(uig->update_map, 748 &fc);
741 &hc, 749 if (UINT_MAX == fc.id)
742 &find_trees, 750 {
743 &fc); 751 /* start new TREE */
744 if (UINT_MAX == fc.id) 752 for (fc.id = 0; fc.id < fc.tree_array_size; fc.id++)
745 { 753 {
746 /* start new TREE */ 754 if (NULL == fc.tree_array[fc.id])
747 for (fc.id = 0; fc.id < fc.tree_array_size; fc.id++)
748 {
749 if (NULL == fc.tree_array[fc.id])
750 {
751 fc.tree_array[fc.id] = nsn;
752 nsn->tree_id = fc.id;
753 break;
754 }
755 }
756 if (fc.id == fc.tree_array_size)
757 {
758 GNUNET_array_append(fc.tree_array, fc.tree_array_size, nsn);
759 nsn->tree_id = fc.id;
760 }
761 GNUNET_log(GNUNET_ERROR_TYPE_DEBUG,
762 "Starting new TREE %u with node `%s'\n",
763 nsn->tree_id,
764 nsn->id);
765 /* put all nodes with same identifier into this TREE */
766 GNUNET_CRYPTO_hash(nsn->id, strlen(nsn->id), &hc);
767 fc.id = nsn->tree_id;
768 fc.nug = nug;
769 fc.uig = uig;
770 GNUNET_CONTAINER_multihashmap_get_multiple(uig->update_map,
771 &hc,
772 &find_trees,
773 &fc);
774 }
775 else
776 { 755 {
777 /* make head of TREE "id" */
778 fc.tree_array[fc.id] = nsn; 756 fc.tree_array[fc.id] = nsn;
779 nsn->tree_id = fc.id; 757 nsn->tree_id = fc.id;
758 break;
780 } 759 }
781 GNUNET_log(GNUNET_ERROR_TYPE_DEBUG, 760 }
782 "TREE of node `%s' is %u\n", 761 if (fc.id == fc.tree_array_size)
783 nsn->id, 762 {
784 fc.id); 763 GNUNET_array_append (fc.tree_array, fc.tree_array_size, nsn);
764 nsn->tree_id = fc.id;
765 }
766 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
767 "Starting new TREE %u with node `%s'\n",
768 nsn->tree_id,
769 nsn->id);
770 /* put all nodes with same identifier into this TREE */
771 GNUNET_CRYPTO_hash (nsn->id, strlen (nsn->id), &hc);
772 fc.id = nsn->tree_id;
773 fc.nug = nug;
774 fc.uig = uig;
775 GNUNET_CONTAINER_multihashmap_get_multiple (uig->update_map,
776 &hc,
777 &find_trees,
778 &fc);
785 } 779 }
780 else
781 {
782 /* make head of TREE "id" */
783 fc.tree_array[fc.id] = nsn;
784 nsn->tree_id = fc.id;
785 }
786 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
787 "TREE of node `%s' is %u\n",
788 nsn->id,
789 fc.id);
790 }
786 for (i = 0; i < fc.tree_array_size; i++) 791 for (i = 0; i < fc.tree_array_size; i++)
792 {
793 nsn = fc.tree_array[i];
794 if (NULL != nsn)
787 { 795 {
788 nsn = fc.tree_array[i]; 796 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
789 if (NULL != nsn) 797 "Root of TREE %u is node `%s'\n",
790 { 798 i,
791 GNUNET_log(GNUNET_ERROR_TYPE_DEBUG, 799 nsn->id);
792 "Root of TREE %u is node `%s'\n", 800 ip (ip_cls, nsn->id, nsn->uri, nsn->md, nsn->update);
793 i,
794 nsn->id);
795 ip(ip_cls, nsn->id, nsn->uri, nsn->md, nsn->update);
796 }
797 } 801 }
798 GNUNET_array_grow(fc.tree_array, fc.tree_array_size, 0); 802 }
799 GNUNET_log(GNUNET_ERROR_TYPE_DEBUG, "Done processing TREEs\n"); 803 GNUNET_array_grow (fc.tree_array, fc.tree_array_size, 0);
800 free_update_information_graph(uig); 804 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Done processing TREEs\n");
805 free_update_information_graph (uig);
801} 806}
802 807
803 808