aboutsummaryrefslogtreecommitdiff
path: root/src/gnunet_chat_context.c
diff options
context:
space:
mode:
authorTheJackiMonster <thejackimonster@gmail.com>2022-03-10 02:18:22 +0100
committerTheJackiMonster <thejackimonster@gmail.com>2022-03-10 02:18:22 +0100
commitfba50c0338fb76feec7fee5a12e27fc57df1972b (patch)
tree22dcdbf1d1c091d4f41a1b7e8b9f0ce12e9d9319 /src/gnunet_chat_context.c
parent807dec8e802737fb46d015c48a7859a6ec504f74 (diff)
downloadlibgnunetchat-fba50c0338fb76feec7fee5a12e27fc57df1972b.tar.gz
libgnunetchat-fba50c0338fb76feec7fee5a12e27fc57df1972b.zip
Replace local files with namestore usage
Signed-off-by: TheJackiMonster <thejackimonster@gmail.com>
Diffstat (limited to 'src/gnunet_chat_context.c')
-rw-r--r--src/gnunet_chat_context.c303
1 files changed, 195 insertions, 108 deletions
diff --git a/src/gnunet_chat_context.c b/src/gnunet_chat_context.c
index 316ffc1..cf7046b 100644
--- a/src/gnunet_chat_context.c
+++ b/src/gnunet_chat_context.c
@@ -23,6 +23,7 @@
23 */ 23 */
24 24
25#include "gnunet_chat_context.h" 25#include "gnunet_chat_context.h"
26#include "gnunet_chat_group.h"
26#include "gnunet_chat_handle.h" 27#include "gnunet_chat_handle.h"
27#include "gnunet_chat_util.h" 28#include "gnunet_chat_util.h"
28 29
@@ -40,6 +41,7 @@ context_create_from_room (struct GNUNET_CHAT_Handle *handle,
40 41
41 context->type = GNUNET_CHAT_CONTEXT_TYPE_UNKNOWN; 42 context->type = GNUNET_CHAT_CONTEXT_TYPE_UNKNOWN;
42 context->nick = NULL; 43 context->nick = NULL;
44 context->topic = NULL;
43 45
44 context->timestamps = GNUNET_CONTAINER_multishortmap_create(8, GNUNET_NO); 46 context->timestamps = GNUNET_CONTAINER_multishortmap_create(8, GNUNET_NO);
45 context->messages = GNUNET_CONTAINER_multihashmap_create(8, GNUNET_NO); 47 context->messages = GNUNET_CONTAINER_multihashmap_create(8, GNUNET_NO);
@@ -51,6 +53,10 @@ context_create_from_room (struct GNUNET_CHAT_Handle *handle,
51 53
52 context->user_pointer = NULL; 54 context->user_pointer = NULL;
53 55
56 context->member_pointers = GNUNET_CONTAINER_multishortmap_create(
57 8, GNUNET_NO
58 );
59
54 return context; 60 return context;
55} 61}
56 62
@@ -66,6 +72,7 @@ context_create_from_contact (struct GNUNET_CHAT_Handle *handle,
66 72
67 context->type = GNUNET_CHAT_CONTEXT_TYPE_CONTACT; 73 context->type = GNUNET_CHAT_CONTEXT_TYPE_CONTACT;
68 context->nick = NULL; 74 context->nick = NULL;
75 context->topic = NULL;
69 76
70 context->timestamps = GNUNET_CONTAINER_multishortmap_create(4, GNUNET_NO); 77 context->timestamps = GNUNET_CONTAINER_multishortmap_create(4, GNUNET_NO);
71 context->messages = GNUNET_CONTAINER_multihashmap_create(4, GNUNET_NO); 78 context->messages = GNUNET_CONTAINER_multihashmap_create(4, GNUNET_NO);
@@ -77,6 +84,10 @@ context_create_from_contact (struct GNUNET_CHAT_Handle *handle,
77 84
78 context->user_pointer = NULL; 85 context->user_pointer = NULL;
79 86
87 context->member_pointers = GNUNET_CONTAINER_multishortmap_create(
88 8, GNUNET_NO
89 );
90
80 return context; 91 return context;
81} 92}
82 93
@@ -101,11 +112,16 @@ context_destroy (struct GNUNET_CHAT_Context *context)
101 context->invites, it_destroy_context_invites, NULL 112 context->invites, it_destroy_context_invites, NULL
102 ); 113 );
103 114
115 GNUNET_CONTAINER_multishortmap_destroy(context->member_pointers);
116
104 GNUNET_CONTAINER_multishortmap_destroy(context->timestamps); 117 GNUNET_CONTAINER_multishortmap_destroy(context->timestamps);
105 GNUNET_CONTAINER_multihashmap_destroy(context->messages); 118 GNUNET_CONTAINER_multihashmap_destroy(context->messages);
106 GNUNET_CONTAINER_multihashmap_destroy(context->invites); 119 GNUNET_CONTAINER_multihashmap_destroy(context->invites);
107 GNUNET_CONTAINER_multihashmap_destroy(context->files); 120 GNUNET_CONTAINER_multihashmap_destroy(context->files);
108 121
122 if (context->topic)
123 GNUNET_free(context->topic);
124
109 if (context->nick) 125 if (context->nick)
110 GNUNET_free(context->nick); 126 GNUNET_free(context->nick);
111 127
@@ -141,6 +157,11 @@ context_update_room (struct GNUNET_CHAT_Context *context,
141 GNUNET_CONTAINER_multihashmap_clear(context->files); 157 GNUNET_CONTAINER_multihashmap_clear(context->files);
142 158
143 context->room = room; 159 context->room = room;
160
161 if (!(context->room))
162 return;
163
164 context_write_records(context);
144} 165}
145 166
146void 167void
@@ -163,169 +184,235 @@ context_update_nick (struct GNUNET_CHAT_Context *context,
163} 184}
164 185
165void 186void
166context_load_config (struct GNUNET_CHAT_Context *context) 187context_read_records (struct GNUNET_CHAT_Context *context,
188 const char *label,
189 unsigned int count,
190 const struct GNUNET_GNSRECORD_Data *data)
167{ 191{
168 GNUNET_assert((context) && 192 GNUNET_assert((context) &&
169 (context->handle) && 193 (context->room));
170 (context->room));
171
172 const char *directory = handle_get_directory(context->handle);
173 194
174 if (!directory) 195 char *nick = NULL;
175 return; 196 char *topic = NULL;
176 197
177 const struct GNUNET_HashCode *hash = GNUNET_MESSENGER_room_get_key( 198 for (unsigned int i = 0; i < count; i++)
178 context->room 199 {
179 ); 200 if (!(GNUNET_GNSRECORD_RF_SUPPLEMENTAL & data[i].flags))
201 continue;
180 202
181 char* filename; 203 if (GNUNET_GNSRECORD_TYPE_NICK == data[i].record_type)
182 util_get_filename(directory, "chats", hash, &filename); 204 {
205 if (nick)
206 continue;
183 207
184 if (GNUNET_YES != GNUNET_DISK_file_test(filename)) 208 nick = GNUNET_strndup(data[i].data, data[i].data_size);
185 goto free_filename; 209 }
186 210
187 struct GNUNET_CONFIGURATION_Handle *config = GNUNET_CONFIGURATION_create(); 211 if (GNUNET_DNSPARSER_TYPE_TXT == data[i].record_type)
212 {
213 if (topic)
214 continue;
188 215
189 if (GNUNET_OK != GNUNET_CONFIGURATION_load(config, filename)) 216 topic = GNUNET_strndup(data[i].data, data[i].data_size);
190 goto destroy_config; 217 }
218 }
191 219
192 char* name = NULL; 220 context_update_nick(context, nick);
193 221
194 if (GNUNET_OK == GNUNET_CONFIGURATION_get_value_string( 222 if (nick)
195 config, "chat", "name", &name)) 223 GNUNET_free(nick);
196 context_update_nick(context, name);
197 224
198 if (name) 225 if (topic)
199 GNUNET_free(name); 226 {
227 struct GNUNET_HashCode topic_hash;
228 GNUNET_CRYPTO_hash(topic, strlen(topic), &topic_hash);
200 229
201 unsigned long long type_number; 230 const struct GNUNET_HashCode *hash = GNUNET_MESSENGER_room_get_key(
231 context->room
232 );
202 233
203 if (GNUNET_OK == GNUNET_CONFIGURATION_get_value_number( 234 if (0 != GNUNET_CRYPTO_hash_cmp(&topic_hash, hash))
204 config, "chat", "type", &type_number)) 235 {
205 switch (type_number) { 236 GNUNET_free(topic);
206 case GNUNET_CHAT_CONTEXT_TYPE_CONTACT: 237 topic = NULL;
207 context->type = GNUNET_CHAT_CONTEXT_TYPE_CONTACT;
208 break;
209 case GNUNET_CHAT_CONTEXT_TYPE_GROUP:
210 context->type = GNUNET_CHAT_CONTEXT_TYPE_GROUP;
211 break;
212 default:
213 context->type = GNUNET_CHAT_CONTEXT_TYPE_UNKNOWN;
214 break;
215 } 238 }
239 }
216 240
217destroy_config: 241 util_set_name_field(topic, &(context->topic));
218 GNUNET_CONFIGURATION_destroy(config);
219 242
220free_filename: 243 if (topic)
221 GNUNET_free(filename); 244 GNUNET_free(topic);
245
246 if (0 == strncmp(label, "group_", 6))
247 context->type = GNUNET_CHAT_CONTEXT_TYPE_GROUP;
248 else if (0 == strncmp(label, "contact_", 8))
249 context->type = GNUNET_CHAT_CONTEXT_TYPE_CONTACT;
250 else
251 context->type = GNUNET_CHAT_CONTEXT_TYPE_UNKNOWN;
222} 252}
223 253
224void 254void
225context_save_config (const struct GNUNET_CHAT_Context *context) 255context_write_records (struct GNUNET_CHAT_Context *context)
226{ 256{
227 GNUNET_assert((context) && 257 GNUNET_assert((context) &&
228 (context->handle) && 258 (context->handle) &&
229 (context->room)); 259 (context->room));
230 260
231 const char *directory = handle_get_directory(context->handle); 261 const struct GNUNET_IDENTITY_PrivateKey *zone = handle_get_key(
262 context->handle
263 );
232 264
233 if (!directory) 265 if (!zone)
234 return; 266 return;
235 267
236 const struct GNUNET_HashCode *key = GNUNET_MESSENGER_room_get_key( 268 const struct GNUNET_HashCode *hash = GNUNET_MESSENGER_room_get_key(
237 context->room 269 context->room
238 ); 270 );
239 271
240 struct GNUNET_CONFIGURATION_Handle *config = GNUNET_CONFIGURATION_create(); 272 struct GNUNET_TIME_Absolute expiration = GNUNET_TIME_absolute_get_forever_();
241 273
242 if (context->room) 274 struct GNUNET_MESSENGER_RoomEntryRecord room;
243 GNUNET_CONFIGURATION_set_value_string( 275 GNUNET_CRYPTO_get_peer_identity(context->handle->cfg, &(room.door));
244 config, "chat", "key", GNUNET_h2s_full(key)
245 );
246
247 if (context->nick)
248 GNUNET_CONFIGURATION_set_value_string(
249 config, "chat", "name", context->nick
250 );
251 276
252 if (GNUNET_CHAT_CONTEXT_TYPE_UNKNOWN != context->type) 277 GNUNET_memcpy(
253 GNUNET_CONFIGURATION_set_value_number( 278 &(room.key),
254 config, "chat", "type", context->type 279 hash,
255 ); 280 sizeof(room.key)
281 );
256 282
257 char* filename; 283 const char *nick = context->nick;
258 util_get_filename(directory, "chats", key, &filename); 284 const char *topic = context->topic;
259 285
260 if (GNUNET_OK == GNUNET_DISK_directory_create_for_file(filename)) 286 if (topic)
261 GNUNET_CONFIGURATION_write(config, filename); 287 {
288 struct GNUNET_HashCode topic_hash;
289 GNUNET_CRYPTO_hash(topic, strlen(topic), &topic_hash);
262 290
263 GNUNET_CONFIGURATION_destroy(config); 291 if (0 != GNUNET_CRYPTO_hash_cmp(&topic_hash, hash))
292 topic = NULL;
293 }
264 294
265 GNUNET_free(filename); 295 unsigned int count = 1;
266}
267 296
268enum GNUNET_GenericReturnValue 297 struct GNUNET_GNSRECORD_Data data [3];
269callback_scan_for_configs (void *cls, 298 data[0].record_type = GNUNET_GNSRECORD_TYPE_MESSENGER_ROOM_ENTRY;
270 const char *filename) 299 data[0].data = &room;
271{ 300 data[0].data_size = sizeof(room);
272 struct GNUNET_CHAT_Handle *handle = (struct GNUNET_CHAT_Handle*) cls; 301 data[0].expiration_time = expiration.abs_value_us;
273 struct GNUNET_PeerIdentity door; 302 data[0].flags = GNUNET_GNSRECORD_RF_PRIVATE;
274 struct GNUNET_HashCode key;
275 303
276 memset(&door, 0, sizeof(door)); 304 if (nick)
277 memset(&key, 0, sizeof(key)); 305 {
306 data[count].record_type = GNUNET_GNSRECORD_TYPE_NICK;
307 data[count].data = nick;
308 data[count].data_size = strlen(nick);
309 data[count].expiration_time = expiration.abs_value_us;
310 data[count].flags = (
311 GNUNET_GNSRECORD_RF_PRIVATE |
312 GNUNET_GNSRECORD_RF_SUPPLEMENTAL
313 );
278 314
279 if ((!filename) || 315 count++;
280 (GNUNET_OK != GNUNET_CRYPTO_get_peer_identity(handle->cfg, &door))) 316 }
281 return GNUNET_YES;
282 317
283 struct GNUNET_CONFIGURATION_Handle *config = GNUNET_CONFIGURATION_create(); 318 if (topic)
319 {
320 data[count].record_type = GNUNET_DNSPARSER_TYPE_TXT;
321 data[count].data = topic;
322 data[count].data_size = strlen(topic);
323 data[count].expiration_time = expiration.abs_value_us;
324 data[count].flags = (
325 GNUNET_GNSRECORD_RF_PRIVATE |
326 GNUNET_GNSRECORD_RF_SUPPLEMENTAL
327 );
284 328
285 if (GNUNET_OK != GNUNET_CONFIGURATION_load(config, filename)) 329 count++;
286 goto destroy_config; 330 }
287 331
288 char* key_value = NULL; 332 const char *type_string = "chat";
289 333
290 if ((GNUNET_OK == GNUNET_CONFIGURATION_get_value_string( 334 switch (context->type)
291 config, "chat", "key", &key_value)) &&
292 (GNUNET_OK == GNUNET_CRYPTO_hash_from_string(key_value, &key)))
293 { 335 {
294 handle_send_room_name(handle, GNUNET_MESSENGER_enter_room( 336 case GNUNET_CHAT_CONTEXT_TYPE_CONTACT:
295 handle->messenger, &door, &key 337 type_string = "contact";
296 )); 338 break;
339 case GNUNET_CHAT_CONTEXT_TYPE_GROUP:
340 type_string = "group";
341 break;
342 default:
343 break;
297 } 344 }
298 345
299 if (key_value) 346 char *label;
300 GNUNET_free(key_value); 347 GNUNET_asprintf (
348 &label,
349 "%s_%s",
350 type_string,
351 GNUNET_h2s(hash)
352 );
353
354 GNUNET_NAMESTORE_records_store(
355 context->handle->namestore,
356 zone,
357 label,
358 count,
359 data,
360 cont_context_write_records,
361 context
362 );
301 363
302destroy_config: 364 GNUNET_free(label);
303 GNUNET_CONFIGURATION_destroy(config);
304 return GNUNET_YES;
305} 365}
306 366
307void 367void
308context_scan_configs (struct GNUNET_CHAT_Handle *handle) 368context_delete_records (struct GNUNET_CHAT_Context *context)
309{ 369{
310 GNUNET_assert((handle) && (handle->messenger)); 370 GNUNET_assert((context) &&
371 (context->handle) &&
372 (context->room));
311 373
312 const char *directory = handle_get_directory(handle); 374 const struct GNUNET_IDENTITY_PrivateKey *zone = handle_get_key(
375 context->handle
376 );
313 377
314 if (!directory) 378 if (!zone)
315 return; 379 return;
316 380
317 char* dirname; 381 const struct GNUNET_HashCode *hash = GNUNET_MESSENGER_room_get_key(
318 util_get_dirname(directory, "chats", &dirname); 382 context->room
383 );
319 384
320 if (GNUNET_YES != GNUNET_DISK_directory_test(dirname, GNUNET_YES)) 385 const char *type_string = "chat";
321 goto free_dirname; 386
387 switch (context->type)
388 {
389 case GNUNET_CHAT_CONTEXT_TYPE_CONTACT:
390 type_string = "contact";
391 break;
392 case GNUNET_CHAT_CONTEXT_TYPE_GROUP:
393 type_string = "group";
394 break;
395 default:
396 break;
397 }
398
399 char *label;
400 GNUNET_asprintf (
401 &label,
402 "%s_%s",
403 type_string,
404 GNUNET_h2s(hash)
405 );
322 406
323 GNUNET_DISK_directory_scan( 407 GNUNET_NAMESTORE_records_store(
324 dirname, 408 context->handle->namestore,
325 callback_scan_for_configs, 409 zone,
326 handle 410 label,
411 0,
412 NULL,
413 cont_context_write_records,
414 context
327 ); 415 );
328 416
329free_dirname: 417 GNUNET_free(label);
330 GNUNET_free(dirname);
331} 418}