commit fba50c0338fb76feec7fee5a12e27fc57df1972b
parent 807dec8e802737fb46d015c48a7859a6ec504f74
Author: TheJackiMonster <thejackimonster@gmail.com>
Date: Thu, 10 Mar 2022 02:18:22 +0100
Replace local files with namestore usage
Signed-off-by: TheJackiMonster <thejackimonster@gmail.com>
Diffstat:
11 files changed, 454 insertions(+), 218 deletions(-)
diff --git a/Makefile b/Makefile
@@ -25,6 +25,7 @@ LIBRARIES = gnunetarm\
gnunetfs\
gnunetidentity\
gnunetmessenger\
+ gnunetnamestore\
gnunetregex\
gnunetutil
diff --git a/include/gnunet_chat_lib.h b/include/gnunet_chat_lib.h
@@ -781,6 +781,31 @@ GNUNET_CHAT_context_iterate_files (struct GNUNET_CHAT_Context *context,
void *cls);
/**
+ * Sets a custom <i>user pointer</i> to a given <i>member</i> relative to a
+ * <i>context</i> so it can be accessed in member related callbacks.
+ *
+ * @param[in,out] context Chat context
+ * @param[in] member Contact
+ * @param[in] user_pointer Custom user pointer
+ */
+void
+GNUNET_CHAT_member_set_user_pointer (struct GNUNET_CHAT_Context *context,
+ const struct GNUNET_CHAT_Contact *member,
+ void *user_pointer);
+
+/**
+ * Returns the custom user pointer of a given <i>contact</i> or NULL if it was
+ * not set any.
+ *
+ * @param[in] context Chat context
+ * @param[in] member Contact
+ * @return Custom user pointer or NULL
+ */
+void*
+GNUNET_CHAT_member_get_user_pointer (const struct GNUNET_CHAT_Context *context,
+ const struct GNUNET_CHAT_Contact *member);
+
+/**
* Returns the kind of a given <i>message</i> to determine its content and
* related usage.
*
diff --git a/src/gnunet_chat_context.c b/src/gnunet_chat_context.c
@@ -23,6 +23,7 @@
*/
#include "gnunet_chat_context.h"
+#include "gnunet_chat_group.h"
#include "gnunet_chat_handle.h"
#include "gnunet_chat_util.h"
@@ -40,6 +41,7 @@ context_create_from_room (struct GNUNET_CHAT_Handle *handle,
context->type = GNUNET_CHAT_CONTEXT_TYPE_UNKNOWN;
context->nick = NULL;
+ context->topic = NULL;
context->timestamps = GNUNET_CONTAINER_multishortmap_create(8, GNUNET_NO);
context->messages = GNUNET_CONTAINER_multihashmap_create(8, GNUNET_NO);
@@ -51,6 +53,10 @@ context_create_from_room (struct GNUNET_CHAT_Handle *handle,
context->user_pointer = NULL;
+ context->member_pointers = GNUNET_CONTAINER_multishortmap_create(
+ 8, GNUNET_NO
+ );
+
return context;
}
@@ -66,6 +72,7 @@ context_create_from_contact (struct GNUNET_CHAT_Handle *handle,
context->type = GNUNET_CHAT_CONTEXT_TYPE_CONTACT;
context->nick = NULL;
+ context->topic = NULL;
context->timestamps = GNUNET_CONTAINER_multishortmap_create(4, GNUNET_NO);
context->messages = GNUNET_CONTAINER_multihashmap_create(4, GNUNET_NO);
@@ -77,6 +84,10 @@ context_create_from_contact (struct GNUNET_CHAT_Handle *handle,
context->user_pointer = NULL;
+ context->member_pointers = GNUNET_CONTAINER_multishortmap_create(
+ 8, GNUNET_NO
+ );
+
return context;
}
@@ -101,11 +112,16 @@ context_destroy (struct GNUNET_CHAT_Context *context)
context->invites, it_destroy_context_invites, NULL
);
+ GNUNET_CONTAINER_multishortmap_destroy(context->member_pointers);
+
GNUNET_CONTAINER_multishortmap_destroy(context->timestamps);
GNUNET_CONTAINER_multihashmap_destroy(context->messages);
GNUNET_CONTAINER_multihashmap_destroy(context->invites);
GNUNET_CONTAINER_multihashmap_destroy(context->files);
+ if (context->topic)
+ GNUNET_free(context->topic);
+
if (context->nick)
GNUNET_free(context->nick);
@@ -141,6 +157,11 @@ context_update_room (struct GNUNET_CHAT_Context *context,
GNUNET_CONTAINER_multihashmap_clear(context->files);
context->room = room;
+
+ if (!(context->room))
+ return;
+
+ context_write_records(context);
}
void
@@ -163,169 +184,235 @@ context_update_nick (struct GNUNET_CHAT_Context *context,
}
void
-context_load_config (struct GNUNET_CHAT_Context *context)
+context_read_records (struct GNUNET_CHAT_Context *context,
+ const char *label,
+ unsigned int count,
+ const struct GNUNET_GNSRECORD_Data *data)
{
GNUNET_assert((context) &&
- (context->handle) &&
- (context->room));
-
- const char *directory = handle_get_directory(context->handle);
+ (context->room));
- if (!directory)
- return;
+ char *nick = NULL;
+ char *topic = NULL;
- const struct GNUNET_HashCode *hash = GNUNET_MESSENGER_room_get_key(
- context->room
- );
+ for (unsigned int i = 0; i < count; i++)
+ {
+ if (!(GNUNET_GNSRECORD_RF_SUPPLEMENTAL & data[i].flags))
+ continue;
- char* filename;
- util_get_filename(directory, "chats", hash, &filename);
+ if (GNUNET_GNSRECORD_TYPE_NICK == data[i].record_type)
+ {
+ if (nick)
+ continue;
- if (GNUNET_YES != GNUNET_DISK_file_test(filename))
- goto free_filename;
+ nick = GNUNET_strndup(data[i].data, data[i].data_size);
+ }
- struct GNUNET_CONFIGURATION_Handle *config = GNUNET_CONFIGURATION_create();
+ if (GNUNET_DNSPARSER_TYPE_TXT == data[i].record_type)
+ {
+ if (topic)
+ continue;
- if (GNUNET_OK != GNUNET_CONFIGURATION_load(config, filename))
- goto destroy_config;
+ topic = GNUNET_strndup(data[i].data, data[i].data_size);
+ }
+ }
- char* name = NULL;
+ context_update_nick(context, nick);
- if (GNUNET_OK == GNUNET_CONFIGURATION_get_value_string(
- config, "chat", "name", &name))
- context_update_nick(context, name);
+ if (nick)
+ GNUNET_free(nick);
- if (name)
- GNUNET_free(name);
+ if (topic)
+ {
+ struct GNUNET_HashCode topic_hash;
+ GNUNET_CRYPTO_hash(topic, strlen(topic), &topic_hash);
- unsigned long long type_number;
+ const struct GNUNET_HashCode *hash = GNUNET_MESSENGER_room_get_key(
+ context->room
+ );
- if (GNUNET_OK == GNUNET_CONFIGURATION_get_value_number(
- config, "chat", "type", &type_number))
- switch (type_number) {
- case GNUNET_CHAT_CONTEXT_TYPE_CONTACT:
- context->type = GNUNET_CHAT_CONTEXT_TYPE_CONTACT;
- break;
- case GNUNET_CHAT_CONTEXT_TYPE_GROUP:
- context->type = GNUNET_CHAT_CONTEXT_TYPE_GROUP;
- break;
- default:
- context->type = GNUNET_CHAT_CONTEXT_TYPE_UNKNOWN;
- break;
+ if (0 != GNUNET_CRYPTO_hash_cmp(&topic_hash, hash))
+ {
+ GNUNET_free(topic);
+ topic = NULL;
}
+ }
-destroy_config:
- GNUNET_CONFIGURATION_destroy(config);
+ util_set_name_field(topic, &(context->topic));
-free_filename:
- GNUNET_free(filename);
+ if (topic)
+ GNUNET_free(topic);
+
+ if (0 == strncmp(label, "group_", 6))
+ context->type = GNUNET_CHAT_CONTEXT_TYPE_GROUP;
+ else if (0 == strncmp(label, "contact_", 8))
+ context->type = GNUNET_CHAT_CONTEXT_TYPE_CONTACT;
+ else
+ context->type = GNUNET_CHAT_CONTEXT_TYPE_UNKNOWN;
}
void
-context_save_config (const struct GNUNET_CHAT_Context *context)
+context_write_records (struct GNUNET_CHAT_Context *context)
{
GNUNET_assert((context) &&
- (context->handle) &&
- (context->room));
+ (context->handle) &&
+ (context->room));
- const char *directory = handle_get_directory(context->handle);
+ const struct GNUNET_IDENTITY_PrivateKey *zone = handle_get_key(
+ context->handle
+ );
- if (!directory)
+ if (!zone)
return;
- const struct GNUNET_HashCode *key = GNUNET_MESSENGER_room_get_key(
+ const struct GNUNET_HashCode *hash = GNUNET_MESSENGER_room_get_key(
context->room
);
- struct GNUNET_CONFIGURATION_Handle *config = GNUNET_CONFIGURATION_create();
+ struct GNUNET_TIME_Absolute expiration = GNUNET_TIME_absolute_get_forever_();
- if (context->room)
- GNUNET_CONFIGURATION_set_value_string(
- config, "chat", "key", GNUNET_h2s_full(key)
- );
-
- if (context->nick)
- GNUNET_CONFIGURATION_set_value_string(
- config, "chat", "name", context->nick
- );
+ struct GNUNET_MESSENGER_RoomEntryRecord room;
+ GNUNET_CRYPTO_get_peer_identity(context->handle->cfg, &(room.door));
- if (GNUNET_CHAT_CONTEXT_TYPE_UNKNOWN != context->type)
- GNUNET_CONFIGURATION_set_value_number(
- config, "chat", "type", context->type
- );
+ GNUNET_memcpy(
+ &(room.key),
+ hash,
+ sizeof(room.key)
+ );
- char* filename;
- util_get_filename(directory, "chats", key, &filename);
+ const char *nick = context->nick;
+ const char *topic = context->topic;
- if (GNUNET_OK == GNUNET_DISK_directory_create_for_file(filename))
- GNUNET_CONFIGURATION_write(config, filename);
+ if (topic)
+ {
+ struct GNUNET_HashCode topic_hash;
+ GNUNET_CRYPTO_hash(topic, strlen(topic), &topic_hash);
- GNUNET_CONFIGURATION_destroy(config);
+ if (0 != GNUNET_CRYPTO_hash_cmp(&topic_hash, hash))
+ topic = NULL;
+ }
- GNUNET_free(filename);
-}
+ unsigned int count = 1;
-enum GNUNET_GenericReturnValue
-callback_scan_for_configs (void *cls,
- const char *filename)
-{
- struct GNUNET_CHAT_Handle *handle = (struct GNUNET_CHAT_Handle*) cls;
- struct GNUNET_PeerIdentity door;
- struct GNUNET_HashCode key;
+ struct GNUNET_GNSRECORD_Data data [3];
+ data[0].record_type = GNUNET_GNSRECORD_TYPE_MESSENGER_ROOM_ENTRY;
+ data[0].data = &room;
+ data[0].data_size = sizeof(room);
+ data[0].expiration_time = expiration.abs_value_us;
+ data[0].flags = GNUNET_GNSRECORD_RF_PRIVATE;
- memset(&door, 0, sizeof(door));
- memset(&key, 0, sizeof(key));
+ if (nick)
+ {
+ data[count].record_type = GNUNET_GNSRECORD_TYPE_NICK;
+ data[count].data = nick;
+ data[count].data_size = strlen(nick);
+ data[count].expiration_time = expiration.abs_value_us;
+ data[count].flags = (
+ GNUNET_GNSRECORD_RF_PRIVATE |
+ GNUNET_GNSRECORD_RF_SUPPLEMENTAL
+ );
- if ((!filename) ||
- (GNUNET_OK != GNUNET_CRYPTO_get_peer_identity(handle->cfg, &door)))
- return GNUNET_YES;
+ count++;
+ }
- struct GNUNET_CONFIGURATION_Handle *config = GNUNET_CONFIGURATION_create();
+ if (topic)
+ {
+ data[count].record_type = GNUNET_DNSPARSER_TYPE_TXT;
+ data[count].data = topic;
+ data[count].data_size = strlen(topic);
+ data[count].expiration_time = expiration.abs_value_us;
+ data[count].flags = (
+ GNUNET_GNSRECORD_RF_PRIVATE |
+ GNUNET_GNSRECORD_RF_SUPPLEMENTAL
+ );
- if (GNUNET_OK != GNUNET_CONFIGURATION_load(config, filename))
- goto destroy_config;
+ count++;
+ }
- char* key_value = NULL;
+ const char *type_string = "chat";
- if ((GNUNET_OK == GNUNET_CONFIGURATION_get_value_string(
- config, "chat", "key", &key_value)) &&
- (GNUNET_OK == GNUNET_CRYPTO_hash_from_string(key_value, &key)))
+ switch (context->type)
{
- handle_send_room_name(handle, GNUNET_MESSENGER_enter_room(
- handle->messenger, &door, &key
- ));
+ case GNUNET_CHAT_CONTEXT_TYPE_CONTACT:
+ type_string = "contact";
+ break;
+ case GNUNET_CHAT_CONTEXT_TYPE_GROUP:
+ type_string = "group";
+ break;
+ default:
+ break;
}
- if (key_value)
- GNUNET_free(key_value);
+ char *label;
+ GNUNET_asprintf (
+ &label,
+ "%s_%s",
+ type_string,
+ GNUNET_h2s(hash)
+ );
+
+ GNUNET_NAMESTORE_records_store(
+ context->handle->namestore,
+ zone,
+ label,
+ count,
+ data,
+ cont_context_write_records,
+ context
+ );
-destroy_config:
- GNUNET_CONFIGURATION_destroy(config);
- return GNUNET_YES;
+ GNUNET_free(label);
}
void
-context_scan_configs (struct GNUNET_CHAT_Handle *handle)
+context_delete_records (struct GNUNET_CHAT_Context *context)
{
- GNUNET_assert((handle) && (handle->messenger));
+ GNUNET_assert((context) &&
+ (context->handle) &&
+ (context->room));
- const char *directory = handle_get_directory(handle);
+ const struct GNUNET_IDENTITY_PrivateKey *zone = handle_get_key(
+ context->handle
+ );
- if (!directory)
+ if (!zone)
return;
- char* dirname;
- util_get_dirname(directory, "chats", &dirname);
+ const struct GNUNET_HashCode *hash = GNUNET_MESSENGER_room_get_key(
+ context->room
+ );
- if (GNUNET_YES != GNUNET_DISK_directory_test(dirname, GNUNET_YES))
- goto free_dirname;
+ const char *type_string = "chat";
+
+ switch (context->type)
+ {
+ case GNUNET_CHAT_CONTEXT_TYPE_CONTACT:
+ type_string = "contact";
+ break;
+ case GNUNET_CHAT_CONTEXT_TYPE_GROUP:
+ type_string = "group";
+ break;
+ default:
+ break;
+ }
+
+ char *label;
+ GNUNET_asprintf (
+ &label,
+ "%s_%s",
+ type_string,
+ GNUNET_h2s(hash)
+ );
- GNUNET_DISK_directory_scan(
- dirname,
- callback_scan_for_configs,
- handle
+ GNUNET_NAMESTORE_records_store(
+ context->handle->namestore,
+ zone,
+ label,
+ 0,
+ NULL,
+ cont_context_write_records,
+ context
);
-free_dirname:
- GNUNET_free(dirname);
+ GNUNET_free(label);
}
diff --git a/src/gnunet_chat_context.h b/src/gnunet_chat_context.h
@@ -1,6 +1,6 @@
/*
This file is part of GNUnet.
- Copyright (C) 2021 GNUnet e.V.
+ Copyright (C) 2021--2022 GNUnet e.V.
GNUnet is free software: you can redistribute it and/or modify it
under the terms of the GNU Affero General Public License as published
@@ -29,6 +29,7 @@
#include <gnunet/gnunet_common.h>
#include <gnunet/gnunet_configuration_lib.h>
#include <gnunet/gnunet_container_lib.h>
+#include <gnunet/gnunet_gnsrecord_lib.h>
#include <gnunet/gnunet_messenger_service.h>
#include <gnunet/gnunet_util_lib.h>
@@ -47,6 +48,7 @@ struct GNUNET_CHAT_Context
enum GNUNET_CHAT_ContextType type;
char *nick;
+ char *topic;
struct GNUNET_CONTAINER_MultiShortmap *timestamps;
struct GNUNET_CONTAINER_MultiHashMap *messages;
@@ -57,6 +59,8 @@ struct GNUNET_CHAT_Context
const struct GNUNET_MESSENGER_Contact *contact;
void *user_pointer;
+
+ struct GNUNET_CONTAINER_MultiShortmap *member_pointers;
};
struct GNUNET_CHAT_Context*
@@ -79,12 +83,15 @@ context_update_nick (struct GNUNET_CHAT_Context *context,
const char *nick);
void
-context_load_config (struct GNUNET_CHAT_Context *context);
+context_read_records (struct GNUNET_CHAT_Context *context,
+ const char *label,
+ unsigned int count,
+ const struct GNUNET_GNSRECORD_Data *data);
void
-context_save_config (const struct GNUNET_CHAT_Context *context);
+context_write_records (struct GNUNET_CHAT_Context *context);
void
-context_scan_configs (struct GNUNET_CHAT_Handle *handle);
+context_delete_records (struct GNUNET_CHAT_Context *context);
#endif /* GNUNET_CHAT_CONTEXT_H_ */
diff --git a/src/gnunet_chat_context_intern.c b/src/gnunet_chat_context_intern.c
@@ -62,3 +62,19 @@ it_destroy_context_invites (GNUNET_UNUSED void *cls,
invitation_destroy(invitation);
return GNUNET_YES;
}
+
+void
+cont_context_write_records (void *cls,
+ GNUNET_UNUSED int32_t success,
+ const char *emsg)
+{
+ struct GNUNET_CHAT_Context *context = cls;
+
+ if (emsg)
+ handle_send_internal_message(
+ context->handle,
+ context,
+ GNUNET_CHAT_FLAG_WARNING,
+ emsg
+ );
+}
diff --git a/src/gnunet_chat_group.c b/src/gnunet_chat_group.c
@@ -38,8 +38,6 @@ group_create_from_context (struct GNUNET_CHAT_Handle *handle,
group->handle = handle;
group->context = context;
- group->topic = NULL;
-
group->announcement = NULL;
group->search = NULL;
@@ -64,9 +62,6 @@ group_destroy (struct GNUNET_CHAT_Group* group)
if (group->announcement)
GNUNET_REGEX_announce_cancel(group->announcement);
- if (group->topic)
- GNUNET_free(group->topic);
-
GNUNET_free(group);
}
@@ -74,7 +69,8 @@ void
group_publish (struct GNUNET_CHAT_Group* group)
{
GNUNET_assert((group) &&
- (group->topic) &&
+ (group->context) &&
+ (group->context->topic) &&
(group->handle) &&
(group->handle->cfg));
@@ -82,7 +78,7 @@ group_publish (struct GNUNET_CHAT_Group* group)
GNUNET_asprintf (
&topic,
"GNUNET_CHAT_%s",
- group->topic
+ group->context->topic
);
group->announcement = GNUNET_REGEX_announce(
@@ -98,82 +94,3 @@ group_publish (struct GNUNET_CHAT_Group* group)
GNUNET_free(topic);
}
-
-void
-group_load_config (struct GNUNET_CHAT_Group *group)
-{
- GNUNET_assert((group) && (group->handle));
-
- const char *directory = handle_get_directory(group->handle);
-
- if ((!directory) || (!(group->context)))
- return;
-
- const struct GNUNET_HashCode *key = GNUNET_MESSENGER_room_get_key(
- group->context->room
- );
-
- char* filename;
- util_get_filename(directory, "groups", key, &filename);
-
- if (GNUNET_YES != GNUNET_DISK_file_test(filename))
- goto free_filename;
-
- struct GNUNET_CONFIGURATION_Handle *config = GNUNET_CONFIGURATION_create();
-
- if (GNUNET_OK != GNUNET_CONFIGURATION_load(config, filename))
- goto destroy_config;
-
- char* name = NULL;
-
- if (GNUNET_OK == GNUNET_CONFIGURATION_get_value_string(
- config, "group", "topic", &name))
- util_set_name_field(name, &(group->topic));
-
- if (name)
- GNUNET_free(name);
-
-destroy_config:
- GNUNET_CONFIGURATION_destroy(config);
-
-free_filename:
- GNUNET_free(filename);
-}
-
-void
-group_save_config (const struct GNUNET_CHAT_Group *group)
-{
- GNUNET_assert((group) && (group->handle));
-
- const char *directory = handle_get_directory(group->handle);
-
- if ((!directory) || (!(group->context)))
- return;
-
- const struct GNUNET_HashCode *key = GNUNET_MESSENGER_room_get_key(
- group->context->room
- );
-
- struct GNUNET_CONFIGURATION_Handle *config = GNUNET_CONFIGURATION_create();
-
- if (group->topic)
- {
- struct GNUNET_HashCode topic_hash;
- GNUNET_CRYPTO_hash(group->topic, strlen(group->topic), &topic_hash);
-
- if (0 == GNUNET_memcmp(key, &topic_hash))
- GNUNET_CONFIGURATION_set_value_string(
- config, "group", "topic", group->topic
- );
- }
-
- char* filename;
- util_get_filename(directory, "groups", key, &filename);
-
- if (GNUNET_OK == GNUNET_DISK_directory_create_for_file(filename))
- GNUNET_CONFIGURATION_write(config, filename);
-
- GNUNET_CONFIGURATION_destroy(config);
-
- GNUNET_free(filename);
-}
diff --git a/src/gnunet_chat_group.h b/src/gnunet_chat_group.h
@@ -39,8 +39,6 @@ struct GNUNET_CHAT_Group
struct GNUNET_CHAT_Handle *handle;
struct GNUNET_CHAT_Context *context;
- char *topic;
-
struct GNUNET_REGEX_Announcement *announcement;
struct GNUNET_REGEX_Search *search;
@@ -59,10 +57,4 @@ group_destroy (struct GNUNET_CHAT_Group* group);
void
group_publish (struct GNUNET_CHAT_Group* group);
-void
-group_load_config (struct GNUNET_CHAT_Group *group);
-
-void
-group_save_config (const struct GNUNET_CHAT_Group *group);
-
#endif /* GNUNET_CHAT_GROUP_H_ */
diff --git a/src/gnunet_chat_handle.c b/src/gnunet_chat_handle.c
@@ -58,6 +58,7 @@ handle_create_from_config (const struct GNUNET_CONFIGURATION_Handle* cfg,
handle->current = NULL;
handle->creation_op = NULL;
+ handle->monitor = NULL;
handle->files = NULL;
handle->contexts = NULL;
@@ -78,6 +79,10 @@ handle_create_from_config (const struct GNUNET_CONFIGURATION_Handle* cfg,
handle
);
+ handle->namestore = GNUNET_NAMESTORE_connect(
+ handle->cfg
+ );
+
handle->fs = NULL;
handle->messenger = NULL;
@@ -114,12 +119,18 @@ handle_destroy (struct GNUNET_CHAT_Handle *handle)
if (handle->shutdown_hook)
GNUNET_SCHEDULER_cancel(handle->shutdown_hook);
+ if (handle->monitor)
+ GNUNET_NAMESTORE_zone_monitor_stop(handle->monitor);
+
if (handle->creation_op)
GNUNET_IDENTITY_cancel(handle->creation_op);
if (handle->current)
handle_disconnect(handle);
+ if (handle->namestore)
+ GNUNET_NAMESTORE_disconnect(handle->namestore);
+
if (handle->identity)
GNUNET_IDENTITY_disconnect(handle->identity);
@@ -177,6 +188,12 @@ handle_connect (struct GNUNET_CHAT_Handle *handle,
(!(handle->contexts)) &&
(!(handle->files)));
+ if (handle->monitor)
+ {
+ GNUNET_NAMESTORE_zone_monitor_stop(handle->monitor);
+ handle->monitor = NULL;
+ }
+
handle->files = GNUNET_CONTAINER_multihashmap_create(8, GNUNET_NO);
handle->contexts = GNUNET_CONTAINER_multihashmap_create(8, GNUNET_NO);
handle->contacts = GNUNET_CONTAINER_multishortmap_create(8, GNUNET_NO);
@@ -274,6 +291,19 @@ handle_get_directory (const struct GNUNET_CHAT_Handle *handle)
return handle->current->directory;
}
+const struct GNUNET_IDENTITY_PrivateKey*
+handle_get_key (const struct GNUNET_CHAT_Handle *handle)
+{
+ GNUNET_assert(handle);
+
+ if ((!(handle->current)) || (!(handle->current->ego)))
+ return NULL;
+
+ return GNUNET_IDENTITY_ego_get_private_key(
+ handle->current->ego
+ );
+}
+
void
handle_send_internal_message (struct GNUNET_CHAT_Handle *handle,
struct GNUNET_CHAT_Context *context,
@@ -351,7 +381,6 @@ handle_request_context_by_room (struct GNUNET_CHAT_Handle *handle,
return GNUNET_OK;
context = context_create_from_room(handle, room);
- context_load_config(context);
if (GNUNET_OK != GNUNET_CONTAINER_multihashmap_put(
handle->contexts, key, context,
@@ -376,9 +405,14 @@ check_type:
(GNUNET_OK == intern_provide_contact_for_member(handle,
check.contact,
context)))
+ {
+ context_delete_records(context);
context->type = GNUNET_CHAT_CONTEXT_TYPE_CONTACT;
+ context_write_records(context);
+ }
else if (checks >= 2)
{
+ context_delete_records(context);
context->type = GNUNET_CHAT_CONTEXT_TYPE_GROUP;
if (context->contact)
@@ -405,9 +439,7 @@ setup_group:
handle, context
);
- group_load_config(group);
-
- if (group->topic)
+ if (context->topic)
group_publish(group);
if (GNUNET_OK == GNUNET_CONTAINER_multihashmap_put(
@@ -421,6 +453,7 @@ setup_group:
NULL
);
+ context_write_records(context);
return GNUNET_OK;
}
diff --git a/src/gnunet_chat_handle.h b/src/gnunet_chat_handle.h
@@ -33,6 +33,7 @@
#include <gnunet/gnunet_fs_service.h>
#include <gnunet/gnunet_identity_service.h>
#include <gnunet/gnunet_messenger_service.h>
+#include <gnunet/gnunet_namestore_service.h>
#include <gnunet/gnunet_scheduler_lib.h>
#include <gnunet/gnunet_util_lib.h>
@@ -72,6 +73,7 @@ struct GNUNET_CHAT_Handle
const struct GNUNET_CHAT_Account *current;
struct GNUNET_IDENTITY_Operation *creation_op;
+ struct GNUNET_NAMESTORE_ZoneMonitor *monitor;
struct GNUNET_CONTAINER_MultiHashMap *files;
struct GNUNET_CONTAINER_MultiHashMap *contexts;
@@ -82,6 +84,7 @@ struct GNUNET_CHAT_Handle
struct GNUNET_FS_Handle *fs;
struct GNUNET_IDENTITY_Handle *identity;
struct GNUNET_MESSENGER_Handle *messenger;
+ struct GNUNET_NAMESTORE_Handle *namestore;
char *public_key;
void *user_pointer;
@@ -109,6 +112,9 @@ handle_disconnect (struct GNUNET_CHAT_Handle *handle);
const char*
handle_get_directory (const struct GNUNET_CHAT_Handle *handle);
+const struct GNUNET_IDENTITY_PrivateKey*
+handle_get_key (const struct GNUNET_CHAT_Handle *handle);
+
void
handle_send_internal_message (struct GNUNET_CHAT_Handle *handle,
struct GNUNET_CHAT_Context *context,
diff --git a/src/gnunet_chat_handle_intern.c b/src/gnunet_chat_handle_intern.c
@@ -64,6 +64,12 @@ on_handle_arm_connection(void *cls,
GNUNET_OS_INHERIT_STD_NONE,
NULL, NULL
);
+
+ GNUNET_ARM_request_service_start(
+ chat->arm, "namestore",
+ GNUNET_OS_INHERIT_STD_NONE,
+ NULL, NULL
+ );
} else {
GNUNET_ARM_request_service_start(
chat->arm, "arm",
@@ -359,6 +365,93 @@ scan_handle_room_members (void* cls,
}
void
+on_monitor_namestore_record(void *cls,
+ GNUNET_UNUSED const
+ struct GNUNET_IDENTITY_PrivateKey *zone,
+ const char *label,
+ unsigned int count,
+ const struct GNUNET_GNSRECORD_Data *data)
+{
+ struct GNUNET_CHAT_Handle *chat = cls;
+
+ if (count <= 0)
+ goto skip_records;
+
+ const struct GNUNET_MESSENGER_RoomEntryRecord *record = NULL;
+
+ for (unsigned int i = 0; i < count; i++)
+ {
+ if (GNUNET_YES == GNUNET_GNSRECORD_is_expired(data + i))
+ continue;
+
+ if ((GNUNET_GNSRECORD_TYPE_MESSENGER_ROOM_ENTRY == data[i].record_type) &&
+ (!(GNUNET_GNSRECORD_RF_SUPPLEMENTAL & data[i].flags)))
+ {
+ record = data[i].data;
+ break;
+ }
+ }
+
+ if (!record)
+ goto skip_records;
+
+ struct GNUNET_CHAT_Context *context = GNUNET_CONTAINER_multihashmap_get(
+ chat->contexts,
+ &(record->key)
+ );
+
+ if (context)
+ {
+ context_read_records(context, label, count, data);
+
+ printf("PATCH: %s %u %d %s\n", label, count, (int) context->type, context->topic);
+
+ goto skip_records;
+ }
+
+ struct GNUNET_MESSENGER_Room *room = GNUNET_MESSENGER_enter_room(
+ chat->messenger,
+ &(record->door),
+ &(record->key)
+ );
+
+ if (!room)
+ goto skip_records;
+
+ context = context_create_from_room(chat, room);
+ context_read_records(context, label, count, data);
+
+ printf("READ: %s %u %d %s\n", label, count, (int) context->type, context->topic);
+
+ handle_send_room_name(chat, room);
+
+ if (GNUNET_OK != GNUNET_CONTAINER_multihashmap_put(
+ chat->contexts, &(record->key), context,
+ GNUNET_CONTAINER_MULTIHASHMAPOPTION_UNIQUE_FAST))
+ {
+ context_destroy(context);
+ goto skip_records;
+ }
+
+ if (GNUNET_CHAT_CONTEXT_TYPE_GROUP != context->type)
+ goto skip_records;
+
+ struct GNUNET_CHAT_Group *group = group_create_from_context(chat, context);
+
+ if (context->topic)
+ group_publish(group);
+
+ if (GNUNET_OK != GNUNET_CONTAINER_multihashmap_put(
+ chat->groups, &(record->key), group,
+ GNUNET_CONTAINER_MULTIHASHMAPOPTION_UNIQUE_FAST))
+ group_destroy(group);
+
+skip_records:
+ if (chat->monitor)
+ GNUNET_NAMESTORE_zone_monitor_next(chat->monitor, 1);
+}
+
+void
on_handle_identity(void *cls,
GNUNET_UNUSED struct GNUNET_MESSENGER_Handle *messenger)
{
@@ -377,7 +470,8 @@ on_handle_identity(void *cls,
return;
GNUNET_assert(handle->messenger);
- context_scan_configs(handle);
+
+ printf("HURRAY!\n");
handle_send_internal_message(
handle,
@@ -385,6 +479,23 @@ on_handle_identity(void *cls,
GNUNET_CHAT_FLAG_LOGIN,
NULL
);
+
+ const struct GNUNET_IDENTITY_PrivateKey *zone = handle_get_key(handle);
+
+ if ((!zone) || (handle->monitor))
+ return;
+
+ handle->monitor = GNUNET_NAMESTORE_zone_monitor_start(
+ handle->cfg,
+ zone,
+ GNUNET_YES,
+ NULL,
+ NULL,
+ on_monitor_namestore_record,
+ handle,
+ NULL,
+ NULL
+ );
}
void
@@ -583,7 +694,6 @@ it_destroy_handle_groups (GNUNET_UNUSED void *cls,
GNUNET_assert(value);
struct GNUNET_CHAT_Group *group = value;
- group_save_config(group);
group_destroy(group);
return GNUNET_YES;
}
@@ -608,7 +718,6 @@ it_destroy_handle_contexts (GNUNET_UNUSED void *cls,
GNUNET_assert(value);
struct GNUNET_CHAT_Context *context = value;
- context_save_config(context);
context_destroy(context);
return GNUNET_YES;
}
diff --git a/src/gnunet_chat_lib.c b/src/gnunet_chat_lib.c
@@ -310,6 +310,8 @@ GNUNET_CHAT_group_create (struct GNUNET_CHAT_Handle *handle,
context->type = GNUNET_CHAT_CONTEXT_TYPE_GROUP;
+ util_set_name_field(topic, &(context->topic));
+
if (GNUNET_OK != GNUNET_CONTAINER_multihashmap_put(
handle->contexts, &key, context,
GNUNET_CONTAINER_MULTIHASHMAPOPTION_UNIQUE_FAST))
@@ -317,15 +319,16 @@ GNUNET_CHAT_group_create (struct GNUNET_CHAT_Handle *handle,
struct GNUNET_CHAT_Group *group = group_create_from_context(handle, context);
- util_set_name_field(topic, &(group->topic));
-
- if (group->topic)
+ if (context->topic)
group_publish(group);
if (GNUNET_OK == GNUNET_CONTAINER_multihashmap_put(
handle->groups, &key, group,
GNUNET_CONTAINER_MULTIHASHMAPOPTION_UNIQUE_FAST))
+ {
+ context_write_records(context);
return group;
+ }
group_destroy(group);
@@ -513,10 +516,13 @@ GNUNET_CHAT_group_set_name (struct GNUNET_CHAT_Group *group,
const char*
GNUNET_CHAT_group_get_name (const struct GNUNET_CHAT_Group *group)
{
- if (!group)
+ if ((!group) || (!(group->context)))
return NULL;
- return group->context->nick;
+ if (group->context->nick)
+ return group->context->nick;
+
+ return group->context->topic;
}
@@ -911,6 +917,43 @@ GNUNET_CHAT_context_iterate_files (struct GNUNET_CHAT_Context *context,
}
+void
+GNUNET_CHAT_member_set_user_pointer (struct GNUNET_CHAT_Context *context,
+ const struct GNUNET_CHAT_Contact *member,
+ void *user_pointer)
+{
+ if ((!context) || (!member))
+ return;
+
+ struct GNUNET_ShortHashCode hash;
+ util_shorthash_from_member(member->member, &hash);
+
+ GNUNET_CONTAINER_multishortmap_put(
+ context->member_pointers,
+ &hash,
+ user_pointer,
+ GNUNET_CONTAINER_MULTIHASHMAPOPTION_REPLACE
+ );
+}
+
+
+void*
+GNUNET_CHAT_member_get_user_pointer (const struct GNUNET_CHAT_Context *context,
+ const struct GNUNET_CHAT_Contact *member)
+{
+ if ((!context) || (!member))
+ return NULL;
+
+ struct GNUNET_ShortHashCode hash;
+ util_shorthash_from_member(member->member, &hash);
+
+ return GNUNET_CONTAINER_multishortmap_get(
+ context->member_pointers,
+ &hash
+ );
+}
+
+
enum GNUNET_CHAT_MessageKind
GNUNET_CHAT_message_get_kind (const struct GNUNET_CHAT_Message *message)
{