diff options
author | TheJackiMonster <thejackimonster@gmail.com> | 2022-03-10 02:18:22 +0100 |
---|---|---|
committer | TheJackiMonster <thejackimonster@gmail.com> | 2022-03-10 02:18:22 +0100 |
commit | fba50c0338fb76feec7fee5a12e27fc57df1972b (patch) | |
tree | 22dcdbf1d1c091d4f41a1b7e8b9f0ce12e9d9319 /src/gnunet_chat_context.c | |
parent | 807dec8e802737fb46d015c48a7859a6ec504f74 (diff) | |
download | libgnunetchat-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.c | 303 |
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 | ||
146 | void | 167 | void |
@@ -163,169 +184,235 @@ context_update_nick (struct GNUNET_CHAT_Context *context, | |||
163 | } | 184 | } |
164 | 185 | ||
165 | void | 186 | void |
166 | context_load_config (struct GNUNET_CHAT_Context *context) | 187 | context_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 | ||
217 | destroy_config: | 241 | util_set_name_field(topic, &(context->topic)); |
218 | GNUNET_CONFIGURATION_destroy(config); | ||
219 | 242 | ||
220 | free_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 | ||
224 | void | 254 | void |
225 | context_save_config (const struct GNUNET_CHAT_Context *context) | 255 | context_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 | ||
268 | enum GNUNET_GenericReturnValue | 297 | struct GNUNET_GNSRECORD_Data data [3]; |
269 | callback_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 | ||
302 | destroy_config: | 364 | GNUNET_free(label); |
303 | GNUNET_CONFIGURATION_destroy(config); | ||
304 | return GNUNET_YES; | ||
305 | } | 365 | } |
306 | 366 | ||
307 | void | 367 | void |
308 | context_scan_configs (struct GNUNET_CHAT_Handle *handle) | 368 | context_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 | ||
329 | free_dirname: | 417 | GNUNET_free(label); |
330 | GNUNET_free(dirname); | ||
331 | } | 418 | } |