aboutsummaryrefslogtreecommitdiff
path: root/src/fs/fs_namespace.c
diff options
context:
space:
mode:
authorLRN <lrn1986@gmail.com>2013-02-19 04:04:35 +0000
committerLRN <lrn1986@gmail.com>2013-02-19 04:04:35 +0000
commit046e90172489ca6091346685bf444a037b1187ee (patch)
treeb4649fab6e1cc543e26dcdd51d1aa8a79ec3d9d7 /src/fs/fs_namespace.c
parentd924f127fd9633ce3e484d54a7efdcdee590dc34 (diff)
downloadgnunet-046e90172489ca6091346685bf444a037b1187ee.tar.gz
gnunet-046e90172489ca6091346685bf444a037b1187ee.zip
Asynchronous namespace creation. With a test.
Diffstat (limited to 'src/fs/fs_namespace.c')
-rw-r--r--src/fs/fs_namespace.c149
1 files changed, 149 insertions, 0 deletions
diff --git a/src/fs/fs_namespace.c b/src/fs/fs_namespace.c
index f9cee5ff9..46121aa9c 100644
--- a/src/fs/fs_namespace.c
+++ b/src/fs/fs_namespace.c
@@ -38,6 +38,43 @@
38 38
39 39
40/** 40/**
41 * Context for creating a namespace asynchronously.
42 */
43struct GNUNET_FS_NamespaceCreationContext
44{
45 /**
46 * Context for asynchronous key creation.
47 */
48 struct GNUNET_CRYPTO_RsaKeyGenerationContext *keycreator;
49
50 /**
51 * Name of the file to store key in / read key from.
52 */
53 char *filename;
54
55 /**
56 * Name of the namespace.
57 */
58 char *name;
59
60 /**
61 * Global fs handle
62 */
63 struct GNUNET_FS_Handle *h;
64
65 /**
66 * Function to call when generation ends (successfully or not)
67 */
68 GNUNET_FS_NamespaceCreationCallback cont;
69
70 /**
71 * Client value to pass to continuation function.
72 */
73 void *cont_cls;
74};
75
76
77/**
41 * Return the name of the directory in which we store 78 * Return the name of the directory in which we store
42 * our local namespaces (or rather, their public keys). 79 * our local namespaces (or rather, their public keys).
43 * 80 *
@@ -268,6 +305,118 @@ GNUNET_FS_namespace_create (struct GNUNET_FS_Handle *h, const char *name)
268 305
269 306
270/** 307/**
308 * Function called upon completion of 'GNUNET_CRYPTO_rsa_key_create_start'.
309 *
310 * @param cls closure
311 * @param pk NULL on error, otherwise the private key (which must be free'd by the callee)
312 * @param emsg NULL on success, otherwise an error message
313 */
314static void
315ns_key_created (void *cls, struct GNUNET_CRYPTO_RsaPrivateKey *pk,
316 const char *emsg)
317{
318 struct GNUNET_FS_NamespaceCreationContext *ncc = cls;
319
320 ncc->keycreator = NULL;
321
322 if (pk)
323 {
324 struct GNUNET_FS_Namespace *ret;
325 ret = GNUNET_malloc (sizeof (struct GNUNET_FS_Namespace));
326 ret->rc = 1;
327 ret->key = pk;
328 ret->h = ncc->h;
329 ret->name = ncc->name;
330 ret->filename = ncc->filename;
331 ncc->cont (ncc->cont_cls, ret, NULL);
332 }
333 else
334 {
335 GNUNET_free (ncc->filename);
336 GNUNET_free (ncc->name);
337 ncc->cont (ncc->cont_cls, NULL, emsg);
338 }
339 GNUNET_free (ncc);
340}
341
342
343/**
344 * Create a namespace with the given name.
345 * If one already exists, the continuation will be called with a handle to
346 * the existing namespace.
347 * Otherwise creates a new namespace.
348 *
349 * @param h handle to the file sharing subsystem
350 * @param name name to use for the namespace
351 * @return namespace creation context, NULL on error (i.e. invalid filename)
352 */
353struct GNUNET_FS_NamespaceCreationContext *
354GNUNET_FS_namespace_create_start (struct GNUNET_FS_Handle *h, const char *name,
355 GNUNET_FS_NamespaceCreationCallback cont, void *cont_cls)
356{
357 char *dn;
358 char *fn;
359 struct GNUNET_FS_NamespaceCreationContext *ret;
360
361 dn = get_namespace_directory (h);
362 if (NULL == dn)
363 {
364 GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
365 _("Can't determine where namespace directory is\n"));
366 return NULL;
367 }
368 GNUNET_asprintf (&fn, "%s%s%s", dn, DIR_SEPARATOR_STR, name);
369 GNUNET_free (dn);
370
371 ret = GNUNET_malloc (sizeof (struct GNUNET_FS_NamespaceCreationContext));
372 ret->filename = fn;
373 ret->h = h;
374 ret->name = GNUNET_strdup (name);
375 ret->cont = cont;
376 ret->cont_cls = cont_cls;
377
378 ret->keycreator = GNUNET_CRYPTO_rsa_key_create_start (fn,
379 ns_key_created, ret);
380
381 if (NULL == ret->keycreator)
382 {
383 GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
384 _("Failed to start creating or reading private key for namespace `%s'\n"),
385 name);
386 GNUNET_free (fn);
387 GNUNET_free (ret->name);
388 GNUNET_free (ret);
389 return NULL;
390 }
391 return ret;
392}
393
394
395/**
396 * Abort namespace creation.
397 *
398 * @param ncc namespace creation context to abort
399 */
400void
401GNUNET_FS_namespace_create_stop (struct GNUNET_FS_NamespaceCreationContext *ncc)
402{
403 if (NULL != ncc->keycreator)
404 {
405 GNUNET_CRYPTO_rsa_key_create_stop (ncc->keycreator);
406 ncc->keycreator = NULL;
407 }
408 if (NULL != ncc->filename)
409 {
410 if (0 != UNLINK (ncc->filename))
411 GNUNET_log_strerror_file (GNUNET_ERROR_TYPE_WARNING, "unlink", ncc->filename);
412 GNUNET_free (ncc->filename);
413 }
414 GNUNET_free_non_null (ncc->name);
415 GNUNET_free (ncc);
416}
417
418
419/**
271 * Duplicate a namespace handle. 420 * Duplicate a namespace handle.
272 * 421 *
273 * @param ns namespace handle 422 * @param ns namespace handle