commit 4d3a143438e87fb7ec5a6f2e35455270360db6cc
parent b98c7a5f62717b666d9bdaee812d2baf25d63d55
Author: Jacki <jacki@thejackimonster.de>
Date: Wed, 17 Apr 2024 17:56:08 +0200
Support FS uri parsing
Signed-off-by: Jacki <jacki@thejackimonster.de>
Diffstat:
6 files changed, 214 insertions(+), 69 deletions(-)
diff --git a/include/gnunet/gnunet_chat_lib.h b/include/gnunet/gnunet_chat_lib.h
@@ -598,7 +598,7 @@ GNUNET_CHAT_get_shared_attributes (struct GNUNET_CHAT_Handle *handle,
*
* @param[in] uri UTF-8 string to parse
* @param[out] emsg Where to store the parser error message (if any)
- * @return NULL on error
+ * @return URI on success, NULL on error
*/
struct GNUNET_CHAT_Uri*
GNUNET_CHAT_uri_parse (const char *uri,
diff --git a/src/gnunet_chat_lib.c b/src/gnunet_chat_lib.c
@@ -626,44 +626,7 @@ GNUNET_CHAT_uri_parse (const char *uri,
if (!uri)
return NULL;
- const size_t prefix_len = strlen(GNUNET_CHAT_URI_PREFIX);
-
- if (0 != strncasecmp(GNUNET_CHAT_URI_PREFIX, uri, prefix_len))
- {
- if (emsg)
- *emsg = GNUNET_strdup (_ ("CHAT URI malformed (invalid prefix)"));
-
- return NULL;
- }
-
- struct GNUNET_CRYPTO_PublicKey zone;
-
- const char *data = uri + prefix_len;
- char *end = strchr(data, '.');
-
- if (!end)
- {
- if (emsg)
- *emsg = GNUNET_strdup (_ ("CHAT URI malformed (zone key missing)"));
-
- return NULL;
- }
-
- char *zone_data = GNUNET_strndup(data, (size_t) (end - data));
-
- if (GNUNET_OK != GNUNET_CRYPTO_public_key_from_string(zone_data, &zone))
- {
- GNUNET_free(zone_data);
-
- if (emsg)
- *emsg = GNUNET_strdup (_ ("CHAT URI malformed (zone key invalid)"));
-
- return NULL;
- }
-
- GNUNET_free(zone_data);
-
- return uri_create(&zone, end + 1);
+ return uri_parse_from_string(uri, emsg);
}
@@ -675,18 +638,7 @@ GNUNET_CHAT_uri_to_string (const struct GNUNET_CHAT_Uri *uri)
if (!uri)
return NULL;
- char *key_string = GNUNET_CRYPTO_public_key_to_string(&(uri->zone));
-
- char *string;
- GNUNET_asprintf (
- &string,
- "gnunet://chat/%s.%s",
- key_string,
- uri->label
- );
-
- GNUNET_free(key_string);
- return string;
+ return uri_to_string(uri);
}
@@ -768,7 +720,8 @@ GNUNET_CHAT_lobby_join (struct GNUNET_CHAT_Handle *handle,
{
GNUNET_CHAT_VERSION_ASSERT();
- if ((!handle) || (handle->destruction) || (!uri) || (!(handle->gns)))
+ if ((!handle) || (handle->destruction) || (!(handle->gns)) ||
+ (!uri) || (GNUNET_CHAT_URI_TYPE_CHAT != uri->type))
return;
struct GNUNET_CHAT_UriLookups *lookups = GNUNET_new(
@@ -776,12 +729,15 @@ GNUNET_CHAT_lobby_join (struct GNUNET_CHAT_Handle *handle,
);
lookups->handle = handle;
- lookups->uri = uri_create(&(uri->zone), uri->label);
+ lookups->uri = uri_create_chat(
+ &(uri->chat.zone),
+ uri->chat.label
+ );
lookups->request = GNUNET_GNS_lookup(
handle->gns,
- lookups->uri->label,
- &(uri->zone),
+ lookups->uri->chat.label,
+ &(uri->chat.zone),
GNUNET_GNSRECORD_TYPE_MESSENGER_ROOM_ENTRY,
GNUNET_GNS_LO_DEFAULT,
cb_lobby_lookup,
diff --git a/src/gnunet_chat_lib_intern.c b/src/gnunet_chat_lib_intern.c
@@ -97,12 +97,13 @@ cb_lobby_lookup (void *cls,
struct GNUNET_CHAT_UriLookups *lookups = (struct GNUNET_CHAT_UriLookups*) cls;
- if ((!(lookups->handle)) || (!(lookups->uri)))
+ if ((!(lookups->handle)) || (!(lookups->uri)) ||
+ (GNUNET_CHAT_URI_TYPE_CHAT != lookups->uri->type))
goto drop_lookup;
struct GNUNET_CHAT_Context *context = handle_process_records(
lookups->handle,
- lookups->uri->label,
+ lookups->uri->chat.label,
count,
data
);
diff --git a/src/gnunet_chat_lobby_intern.c b/src/gnunet_chat_lobby_intern.c
@@ -115,13 +115,13 @@ cont_lobby_identity_create (void *cls,
char *label;
util_get_context_label(lobby->context->type, key, &label);
- lobby->uri = uri_create(&public_zone, label);
+ lobby->uri = uri_create_chat(&public_zone, label);
GNUNET_free(label);
lobby->query = GNUNET_NAMESTORE_record_set_store(
lobby->handle->namestore,
zone,
- lobby->uri->label,
+ lobby->uri->chat.label,
1,
data,
cont_lobby_write_records,
diff --git a/src/gnunet_chat_uri.c b/src/gnunet_chat_uri.c
@@ -23,29 +23,161 @@
*/
#include "gnunet_chat_uri.h"
+#include <gnunet/gnunet_common.h>
+#include <gnunet/gnunet_fs_service.h>
+
+#define _(String) ((const char*) String)
struct GNUNET_CHAT_Uri*
-uri_create (const struct GNUNET_CRYPTO_PublicKey *zone,
- const char *label)
+uri_create_chat (const struct GNUNET_CRYPTO_PublicKey *zone,
+ const char *label)
{
GNUNET_assert((zone) && (label));
struct GNUNET_CHAT_Uri *uri = GNUNET_new(struct GNUNET_CHAT_Uri);
- GNUNET_memcpy(&(uri->zone), zone, sizeof(uri->zone));
+ uri->type = GNUNET_CHAT_URI_TYPE_CHAT;
- uri->label = GNUNET_strdup(label);
+ GNUNET_memcpy(&(uri->chat.zone), zone, sizeof(uri->chat.zone));
+ uri->chat.label = GNUNET_strdup(label);
return uri;
}
+struct GNUNET_CHAT_Uri*
+uri_create_file (const struct GNUNET_FS_Uri *uri)
+{
+ GNUNET_assert(uri);
+
+ struct GNUNET_CHAT_Uri *chat_uri = GNUNET_new(struct GNUNET_CHAT_Uri);
+
+ chat_uri->type = GNUNET_CHAT_URI_TYPE_FS;
+ chat_uri->fs.uri = GNUNET_FS_uri_dup(uri);
+
+ return chat_uri;
+}
+
void
uri_destroy (struct GNUNET_CHAT_Uri *uri)
{
GNUNET_assert(uri);
- if (uri->label)
- GNUNET_free(uri->label);
+ switch (uri->type)
+ {
+ case GNUNET_CHAT_URI_TYPE_CHAT:
+ if (uri->chat.label)
+ GNUNET_free(uri->chat.label);
+ break;
+ case GNUNET_CHAT_URI_TYPE_FS:
+ if (uri->fs.uri)
+ GNUNET_FS_uri_destroy(uri->fs.uri);
+ break;
+ default:
+ break;
+ }
GNUNET_free(uri);
}
+
+static enum GNUNET_GenericReturnValue
+string_starts_with (const char *string,
+ const char *prefix,
+ size_t *prefix_len)
+{
+ GNUNET_assert((string) && (prefix) && (prefix_len));
+
+ *prefix_len = strlen(prefix);
+
+ return (0 == strncasecmp(
+ prefix, string, *prefix_len
+ )? GNUNET_YES : GNUNET_NO);
+}
+
+struct GNUNET_CHAT_Uri*
+uri_parse_from_string (const char *string,
+ char **emsg)
+{
+ GNUNET_assert(string);
+
+ size_t prefix_len;
+
+ if (GNUNET_YES == string_starts_with(string, GNUNET_CHAT_URI_PREFIX, &prefix_len))
+ {
+ struct GNUNET_CRYPTO_PublicKey zone;
+
+ const char *data = string + prefix_len;
+ char *end = strchr(data, '.');
+
+ if (!end)
+ {
+ if (emsg)
+ *emsg = GNUNET_strdup (_ ("CHAT URI malformed (zone key missing)"));
+
+ return NULL;
+ }
+
+ char *zone_data = GNUNET_strndup(data, (size_t) (end - data));
+
+ if (GNUNET_OK != GNUNET_CRYPTO_public_key_from_string(zone_data, &zone))
+ {
+ GNUNET_free(zone_data);
+
+ if (emsg)
+ *emsg = GNUNET_strdup (_ ("CHAT URI malformed (zone key invalid)"));
+
+ return NULL;
+ }
+
+ GNUNET_free(zone_data);
+
+ return uri_create_chat(&zone, end + 1);
+ }
+ else if (GNUNET_YES == string_starts_with(string, GNUNET_FS_URI_PREFIX, &prefix_len))
+ {
+ struct GNUNET_FS_Uri *fs_uri = GNUNET_FS_uri_parse(string, emsg);
+
+ if (!fs_uri)
+ return NULL;
+
+ struct GNUNET_CHAT_Uri *uri = uri_create_file(fs_uri);
+ GNUNET_FS_uri_destroy(fs_uri);
+ return uri;
+ }
+ else
+ {
+ if (emsg)
+ *emsg = GNUNET_strdup (_ ("CHAT URI malformed (invalid prefix)"));
+
+ return NULL;
+ }
+}
+
+char*
+uri_to_string (const struct GNUNET_CHAT_Uri *uri)
+{
+ GNUNET_assert(uri);
+
+ switch (uri->type)
+ {
+ case GNUNET_CHAT_URI_TYPE_CHAT:
+ {
+ char *tmp = GNUNET_CRYPTO_public_key_to_string(&(uri->chat.zone));
+ char *result;
+
+ GNUNET_asprintf (
+ &result,
+ "%s%s.%s",
+ GNUNET_CHAT_URI_PREFIX,
+ tmp,
+ uri->chat.label
+ );
+
+ GNUNET_free(tmp);
+ return result;
+ }
+ case GNUNET_CHAT_URI_TYPE_FS:
+ return GNUNET_FS_uri_to_string(uri->fs.uri);
+ default:
+ return NULL;
+ }
+}
diff --git a/src/gnunet_chat_uri.h b/src/gnunet_chat_uri.h
@@ -25,27 +25,61 @@
#ifndef GNUNET_CHAT_URI_H_
#define GNUNET_CHAT_URI_H_
+#include <gnunet/gnunet_fs_service.h>
#include <gnunet/gnunet_util_lib.h>
#include "gnunet_chat_util.h"
-struct GNUNET_CHAT_Uri
+enum GNUNET_CHAT_UriType
+{
+ GNUNET_CHAT_URI_TYPE_CHAT = 1,
+ GNUNET_CHAT_URI_TYPE_FS = 2,
+
+ GNUNET_CHAT_URI_TYPE_UNKNOWN = 0
+};
+
+struct GNUNET_CHAT_UriChat
{
struct GNUNET_CRYPTO_PublicKey zone;
char *label;
};
+struct GNUNET_CHAT_UriFile
+{
+ struct GNUNET_FS_Uri *uri;
+};
+
+struct GNUNET_CHAT_Uri
+{
+ enum GNUNET_CHAT_UriType type;
+
+ union {
+ struct GNUNET_CHAT_UriChat chat;
+ struct GNUNET_CHAT_UriFile fs;
+ };
+};
+
/**
* Creates a chat uri with a selected key as <i>zone</i>
- * and a <i>label</i>.
+ * and a <i>label</i> of type #GNUNET_CHAT_URI_TYPE_CHAT.
*
* @param[in] zone URI zone
* @param[in] label URI label
* @return New chat uri
*/
struct GNUNET_CHAT_Uri*
-uri_create (const struct GNUNET_CRYPTO_PublicKey *zone,
- const char *label);
+uri_create_chat (const struct GNUNET_CRYPTO_PublicKey *zone,
+ const char *label);
+
+/**
+ * Creates a chat uri from a selected FS <i>uri</i>
+ * setting the type to #GNUNET_CHAT_URI_TYPE_FS.
+ *
+ * @param[in] uri FS URI
+ * @return New chat uri
+ */
+struct GNUNET_CHAT_Uri*
+uri_create_file (const struct GNUNET_FS_Uri *uri);
/**
* Destroys a chat <i>uri</i> and frees its memory.
@@ -55,4 +89,26 @@ uri_create (const struct GNUNET_CRYPTO_PublicKey *zone,
void
uri_destroy (struct GNUNET_CHAT_Uri *uri);
+/**
+ * Parses an UTF-8 string to a chat URI which will
+ * be newly allocated.
+ *
+ * @param[in] string UTF-8 string to parse
+ * @param[out] emsg Where to store the parser error message (if any)
+ * @return URI on success, NULL on error
+ */
+struct GNUNET_CHAT_Uri*
+uri_parse_from_string (const char *string,
+ char **emsg);
+
+/**
+ * Returns an allocated UTF-8 string representing
+ * a given chat <i>uri</i>.
+ *
+ * @param[in] uri Chat uri
+ * @return The UTF-8 string representing the URI
+ */
+char*
+uri_to_string (const struct GNUNET_CHAT_Uri *uri);
+
#endif /* GNUNET_CHAT_URI_H_ */