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 | |
parent | 807dec8e802737fb46d015c48a7859a6ec504f74 (diff) | |
download | libgnunetchat-fba50c0338fb76feec7fee5a12e27fc57df1972b.tar.gz libgnunetchat-fba50c0338fb76feec7fee5a12e27fc57df1972b.zip |
Replace local files with namestore usage
Signed-off-by: TheJackiMonster <thejackimonster@gmail.com>
-rw-r--r-- | Makefile | 1 | ||||
-rw-r--r-- | include/gnunet_chat_lib.h | 25 | ||||
-rw-r--r-- | src/gnunet_chat_context.c | 303 | ||||
-rw-r--r-- | src/gnunet_chat_context.h | 15 | ||||
-rw-r--r-- | src/gnunet_chat_context_intern.c | 16 | ||||
-rw-r--r-- | src/gnunet_chat_group.c | 89 | ||||
-rw-r--r-- | src/gnunet_chat_group.h | 8 | ||||
-rw-r--r-- | src/gnunet_chat_handle.c | 41 | ||||
-rw-r--r-- | src/gnunet_chat_handle.h | 6 | ||||
-rw-r--r-- | src/gnunet_chat_handle_intern.c | 115 | ||||
-rw-r--r-- | src/gnunet_chat_lib.c | 53 |
11 files changed, 454 insertions, 218 deletions
@@ -25,6 +25,7 @@ LIBRARIES = gnunetarm\ | |||
25 | gnunetfs\ | 25 | gnunetfs\ |
26 | gnunetidentity\ | 26 | gnunetidentity\ |
27 | gnunetmessenger\ | 27 | gnunetmessenger\ |
28 | gnunetnamestore\ | ||
28 | gnunetregex\ | 29 | gnunetregex\ |
29 | gnunetutil | 30 | gnunetutil |
30 | 31 | ||
diff --git a/include/gnunet_chat_lib.h b/include/gnunet_chat_lib.h index e09643e..10e36a4 100644 --- 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, | |||
781 | void *cls); | 781 | void *cls); |
782 | 782 | ||
783 | /** | 783 | /** |
784 | * Sets a custom <i>user pointer</i> to a given <i>member</i> relative to a | ||
785 | * <i>context</i> so it can be accessed in member related callbacks. | ||
786 | * | ||
787 | * @param[in,out] context Chat context | ||
788 | * @param[in] member Contact | ||
789 | * @param[in] user_pointer Custom user pointer | ||
790 | */ | ||
791 | void | ||
792 | GNUNET_CHAT_member_set_user_pointer (struct GNUNET_CHAT_Context *context, | ||
793 | const struct GNUNET_CHAT_Contact *member, | ||
794 | void *user_pointer); | ||
795 | |||
796 | /** | ||
797 | * Returns the custom user pointer of a given <i>contact</i> or NULL if it was | ||
798 | * not set any. | ||
799 | * | ||
800 | * @param[in] context Chat context | ||
801 | * @param[in] member Contact | ||
802 | * @return Custom user pointer or NULL | ||
803 | */ | ||
804 | void* | ||
805 | GNUNET_CHAT_member_get_user_pointer (const struct GNUNET_CHAT_Context *context, | ||
806 | const struct GNUNET_CHAT_Contact *member); | ||
807 | |||
808 | /** | ||
784 | * Returns the kind of a given <i>message</i> to determine its content and | 809 | * Returns the kind of a given <i>message</i> to determine its content and |
785 | * related usage. | 810 | * related usage. |
786 | * | 811 | * |
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 | } |
diff --git a/src/gnunet_chat_context.h b/src/gnunet_chat_context.h index f68ecb8..f0272f0 100644 --- a/src/gnunet_chat_context.h +++ b/src/gnunet_chat_context.h | |||
@@ -1,6 +1,6 @@ | |||
1 | /* | 1 | /* |
2 | This file is part of GNUnet. | 2 | This file is part of GNUnet. |
3 | Copyright (C) 2021 GNUnet e.V. | 3 | Copyright (C) 2021--2022 GNUnet e.V. |
4 | 4 | ||
5 | GNUnet is free software: you can redistribute it and/or modify it | 5 | GNUnet is free software: you can redistribute it and/or modify it |
6 | under the terms of the GNU Affero General Public License as published | 6 | under the terms of the GNU Affero General Public License as published |
@@ -29,6 +29,7 @@ | |||
29 | #include <gnunet/gnunet_common.h> | 29 | #include <gnunet/gnunet_common.h> |
30 | #include <gnunet/gnunet_configuration_lib.h> | 30 | #include <gnunet/gnunet_configuration_lib.h> |
31 | #include <gnunet/gnunet_container_lib.h> | 31 | #include <gnunet/gnunet_container_lib.h> |
32 | #include <gnunet/gnunet_gnsrecord_lib.h> | ||
32 | #include <gnunet/gnunet_messenger_service.h> | 33 | #include <gnunet/gnunet_messenger_service.h> |
33 | #include <gnunet/gnunet_util_lib.h> | 34 | #include <gnunet/gnunet_util_lib.h> |
34 | 35 | ||
@@ -47,6 +48,7 @@ struct GNUNET_CHAT_Context | |||
47 | 48 | ||
48 | enum GNUNET_CHAT_ContextType type; | 49 | enum GNUNET_CHAT_ContextType type; |
49 | char *nick; | 50 | char *nick; |
51 | char *topic; | ||
50 | 52 | ||
51 | struct GNUNET_CONTAINER_MultiShortmap *timestamps; | 53 | struct GNUNET_CONTAINER_MultiShortmap *timestamps; |
52 | struct GNUNET_CONTAINER_MultiHashMap *messages; | 54 | struct GNUNET_CONTAINER_MultiHashMap *messages; |
@@ -57,6 +59,8 @@ struct GNUNET_CHAT_Context | |||
57 | const struct GNUNET_MESSENGER_Contact *contact; | 59 | const struct GNUNET_MESSENGER_Contact *contact; |
58 | 60 | ||
59 | void *user_pointer; | 61 | void *user_pointer; |
62 | |||
63 | struct GNUNET_CONTAINER_MultiShortmap *member_pointers; | ||
60 | }; | 64 | }; |
61 | 65 | ||
62 | struct GNUNET_CHAT_Context* | 66 | struct GNUNET_CHAT_Context* |
@@ -79,12 +83,15 @@ context_update_nick (struct GNUNET_CHAT_Context *context, | |||
79 | const char *nick); | 83 | const char *nick); |
80 | 84 | ||
81 | void | 85 | void |
82 | context_load_config (struct GNUNET_CHAT_Context *context); | 86 | context_read_records (struct GNUNET_CHAT_Context *context, |
87 | const char *label, | ||
88 | unsigned int count, | ||
89 | const struct GNUNET_GNSRECORD_Data *data); | ||
83 | 90 | ||
84 | void | 91 | void |
85 | context_save_config (const struct GNUNET_CHAT_Context *context); | 92 | context_write_records (struct GNUNET_CHAT_Context *context); |
86 | 93 | ||
87 | void | 94 | void |
88 | context_scan_configs (struct GNUNET_CHAT_Handle *handle); | 95 | context_delete_records (struct GNUNET_CHAT_Context *context); |
89 | 96 | ||
90 | #endif /* GNUNET_CHAT_CONTEXT_H_ */ | 97 | #endif /* GNUNET_CHAT_CONTEXT_H_ */ |
diff --git a/src/gnunet_chat_context_intern.c b/src/gnunet_chat_context_intern.c index ed1cd27..c4a3d5b 100644 --- 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, | |||
62 | invitation_destroy(invitation); | 62 | invitation_destroy(invitation); |
63 | return GNUNET_YES; | 63 | return GNUNET_YES; |
64 | } | 64 | } |
65 | |||
66 | void | ||
67 | cont_context_write_records (void *cls, | ||
68 | GNUNET_UNUSED int32_t success, | ||
69 | const char *emsg) | ||
70 | { | ||
71 | struct GNUNET_CHAT_Context *context = cls; | ||
72 | |||
73 | if (emsg) | ||
74 | handle_send_internal_message( | ||
75 | context->handle, | ||
76 | context, | ||
77 | GNUNET_CHAT_FLAG_WARNING, | ||
78 | emsg | ||
79 | ); | ||
80 | } | ||
diff --git a/src/gnunet_chat_group.c b/src/gnunet_chat_group.c index 7fcc98e..d102893 100644 --- 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, | |||
38 | group->handle = handle; | 38 | group->handle = handle; |
39 | group->context = context; | 39 | group->context = context; |
40 | 40 | ||
41 | group->topic = NULL; | ||
42 | |||
43 | group->announcement = NULL; | 41 | group->announcement = NULL; |
44 | group->search = NULL; | 42 | group->search = NULL; |
45 | 43 | ||
@@ -64,9 +62,6 @@ group_destroy (struct GNUNET_CHAT_Group* group) | |||
64 | if (group->announcement) | 62 | if (group->announcement) |
65 | GNUNET_REGEX_announce_cancel(group->announcement); | 63 | GNUNET_REGEX_announce_cancel(group->announcement); |
66 | 64 | ||
67 | if (group->topic) | ||
68 | GNUNET_free(group->topic); | ||
69 | |||
70 | GNUNET_free(group); | 65 | GNUNET_free(group); |
71 | } | 66 | } |
72 | 67 | ||
@@ -74,7 +69,8 @@ void | |||
74 | group_publish (struct GNUNET_CHAT_Group* group) | 69 | group_publish (struct GNUNET_CHAT_Group* group) |
75 | { | 70 | { |
76 | GNUNET_assert((group) && | 71 | GNUNET_assert((group) && |
77 | (group->topic) && | 72 | (group->context) && |
73 | (group->context->topic) && | ||
78 | (group->handle) && | 74 | (group->handle) && |
79 | (group->handle->cfg)); | 75 | (group->handle->cfg)); |
80 | 76 | ||
@@ -82,7 +78,7 @@ group_publish (struct GNUNET_CHAT_Group* group) | |||
82 | GNUNET_asprintf ( | 78 | GNUNET_asprintf ( |
83 | &topic, | 79 | &topic, |
84 | "GNUNET_CHAT_%s", | 80 | "GNUNET_CHAT_%s", |
85 | group->topic | 81 | group->context->topic |
86 | ); | 82 | ); |
87 | 83 | ||
88 | group->announcement = GNUNET_REGEX_announce( | 84 | group->announcement = GNUNET_REGEX_announce( |
@@ -98,82 +94,3 @@ group_publish (struct GNUNET_CHAT_Group* group) | |||
98 | 94 | ||
99 | GNUNET_free(topic); | 95 | GNUNET_free(topic); |
100 | } | 96 | } |
101 | |||
102 | void | ||
103 | group_load_config (struct GNUNET_CHAT_Group *group) | ||
104 | { | ||
105 | GNUNET_assert((group) && (group->handle)); | ||
106 | |||
107 | const char *directory = handle_get_directory(group->handle); | ||
108 | |||
109 | if ((!directory) || (!(group->context))) | ||
110 | return; | ||
111 | |||
112 | const struct GNUNET_HashCode *key = GNUNET_MESSENGER_room_get_key( | ||
113 | group->context->room | ||
114 | ); | ||
115 | |||
116 | char* filename; | ||
117 | util_get_filename(directory, "groups", key, &filename); | ||
118 | |||
119 | if (GNUNET_YES != GNUNET_DISK_file_test(filename)) | ||
120 | goto free_filename; | ||
121 | |||
122 | struct GNUNET_CONFIGURATION_Handle *config = GNUNET_CONFIGURATION_create(); | ||
123 | |||
124 | if (GNUNET_OK != GNUNET_CONFIGURATION_load(config, filename)) | ||
125 | goto destroy_config; | ||
126 | |||
127 | char* name = NULL; | ||
128 | |||
129 | if (GNUNET_OK == GNUNET_CONFIGURATION_get_value_string( | ||
130 | config, "group", "topic", &name)) | ||
131 | util_set_name_field(name, &(group->topic)); | ||
132 | |||
133 | if (name) | ||
134 | GNUNET_free(name); | ||
135 | |||
136 | destroy_config: | ||
137 | GNUNET_CONFIGURATION_destroy(config); | ||
138 | |||
139 | free_filename: | ||
140 | GNUNET_free(filename); | ||
141 | } | ||
142 | |||
143 | void | ||
144 | group_save_config (const struct GNUNET_CHAT_Group *group) | ||
145 | { | ||
146 | GNUNET_assert((group) && (group->handle)); | ||
147 | |||
148 | const char *directory = handle_get_directory(group->handle); | ||
149 | |||
150 | if ((!directory) || (!(group->context))) | ||
151 | return; | ||
152 | |||
153 | const struct GNUNET_HashCode *key = GNUNET_MESSENGER_room_get_key( | ||
154 | group->context->room | ||
155 | ); | ||
156 | |||
157 | struct GNUNET_CONFIGURATION_Handle *config = GNUNET_CONFIGURATION_create(); | ||
158 | |||
159 | if (group->topic) | ||
160 | { | ||
161 | struct GNUNET_HashCode topic_hash; | ||
162 | GNUNET_CRYPTO_hash(group->topic, strlen(group->topic), &topic_hash); | ||
163 | |||
164 | if (0 == GNUNET_memcmp(key, &topic_hash)) | ||
165 | GNUNET_CONFIGURATION_set_value_string( | ||
166 | config, "group", "topic", group->topic | ||
167 | ); | ||
168 | } | ||
169 | |||
170 | char* filename; | ||
171 | util_get_filename(directory, "groups", key, &filename); | ||
172 | |||
173 | if (GNUNET_OK == GNUNET_DISK_directory_create_for_file(filename)) | ||
174 | GNUNET_CONFIGURATION_write(config, filename); | ||
175 | |||
176 | GNUNET_CONFIGURATION_destroy(config); | ||
177 | |||
178 | GNUNET_free(filename); | ||
179 | } | ||
diff --git a/src/gnunet_chat_group.h b/src/gnunet_chat_group.h index a02c8aa..4c2bf9d 100644 --- a/src/gnunet_chat_group.h +++ b/src/gnunet_chat_group.h | |||
@@ -39,8 +39,6 @@ struct GNUNET_CHAT_Group | |||
39 | struct GNUNET_CHAT_Handle *handle; | 39 | struct GNUNET_CHAT_Handle *handle; |
40 | struct GNUNET_CHAT_Context *context; | 40 | struct GNUNET_CHAT_Context *context; |
41 | 41 | ||
42 | char *topic; | ||
43 | |||
44 | struct GNUNET_REGEX_Announcement *announcement; | 42 | struct GNUNET_REGEX_Announcement *announcement; |
45 | struct GNUNET_REGEX_Search *search; | 43 | struct GNUNET_REGEX_Search *search; |
46 | 44 | ||
@@ -59,10 +57,4 @@ group_destroy (struct GNUNET_CHAT_Group* group); | |||
59 | void | 57 | void |
60 | group_publish (struct GNUNET_CHAT_Group* group); | 58 | group_publish (struct GNUNET_CHAT_Group* group); |
61 | 59 | ||
62 | void | ||
63 | group_load_config (struct GNUNET_CHAT_Group *group); | ||
64 | |||
65 | void | ||
66 | group_save_config (const struct GNUNET_CHAT_Group *group); | ||
67 | |||
68 | #endif /* GNUNET_CHAT_GROUP_H_ */ | 60 | #endif /* GNUNET_CHAT_GROUP_H_ */ |
diff --git a/src/gnunet_chat_handle.c b/src/gnunet_chat_handle.c index 732dfbd..5205aa9 100644 --- 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, | |||
58 | 58 | ||
59 | handle->current = NULL; | 59 | handle->current = NULL; |
60 | handle->creation_op = NULL; | 60 | handle->creation_op = NULL; |
61 | handle->monitor = NULL; | ||
61 | 62 | ||
62 | handle->files = NULL; | 63 | handle->files = NULL; |
63 | handle->contexts = NULL; | 64 | handle->contexts = NULL; |
@@ -78,6 +79,10 @@ handle_create_from_config (const struct GNUNET_CONFIGURATION_Handle* cfg, | |||
78 | handle | 79 | handle |
79 | ); | 80 | ); |
80 | 81 | ||
82 | handle->namestore = GNUNET_NAMESTORE_connect( | ||
83 | handle->cfg | ||
84 | ); | ||
85 | |||
81 | handle->fs = NULL; | 86 | handle->fs = NULL; |
82 | handle->messenger = NULL; | 87 | handle->messenger = NULL; |
83 | 88 | ||
@@ -114,12 +119,18 @@ handle_destroy (struct GNUNET_CHAT_Handle *handle) | |||
114 | if (handle->shutdown_hook) | 119 | if (handle->shutdown_hook) |
115 | GNUNET_SCHEDULER_cancel(handle->shutdown_hook); | 120 | GNUNET_SCHEDULER_cancel(handle->shutdown_hook); |
116 | 121 | ||
122 | if (handle->monitor) | ||
123 | GNUNET_NAMESTORE_zone_monitor_stop(handle->monitor); | ||
124 | |||
117 | if (handle->creation_op) | 125 | if (handle->creation_op) |
118 | GNUNET_IDENTITY_cancel(handle->creation_op); | 126 | GNUNET_IDENTITY_cancel(handle->creation_op); |
119 | 127 | ||
120 | if (handle->current) | 128 | if (handle->current) |
121 | handle_disconnect(handle); | 129 | handle_disconnect(handle); |
122 | 130 | ||
131 | if (handle->namestore) | ||
132 | GNUNET_NAMESTORE_disconnect(handle->namestore); | ||
133 | |||
123 | if (handle->identity) | 134 | if (handle->identity) |
124 | GNUNET_IDENTITY_disconnect(handle->identity); | 135 | GNUNET_IDENTITY_disconnect(handle->identity); |
125 | 136 | ||
@@ -177,6 +188,12 @@ handle_connect (struct GNUNET_CHAT_Handle *handle, | |||
177 | (!(handle->contexts)) && | 188 | (!(handle->contexts)) && |
178 | (!(handle->files))); | 189 | (!(handle->files))); |
179 | 190 | ||
191 | if (handle->monitor) | ||
192 | { | ||
193 | GNUNET_NAMESTORE_zone_monitor_stop(handle->monitor); | ||
194 | handle->monitor = NULL; | ||
195 | } | ||
196 | |||
180 | handle->files = GNUNET_CONTAINER_multihashmap_create(8, GNUNET_NO); | 197 | handle->files = GNUNET_CONTAINER_multihashmap_create(8, GNUNET_NO); |
181 | handle->contexts = GNUNET_CONTAINER_multihashmap_create(8, GNUNET_NO); | 198 | handle->contexts = GNUNET_CONTAINER_multihashmap_create(8, GNUNET_NO); |
182 | handle->contacts = GNUNET_CONTAINER_multishortmap_create(8, GNUNET_NO); | 199 | handle->contacts = GNUNET_CONTAINER_multishortmap_create(8, GNUNET_NO); |
@@ -274,6 +291,19 @@ handle_get_directory (const struct GNUNET_CHAT_Handle *handle) | |||
274 | return handle->current->directory; | 291 | return handle->current->directory; |
275 | } | 292 | } |
276 | 293 | ||
294 | const struct GNUNET_IDENTITY_PrivateKey* | ||
295 | handle_get_key (const struct GNUNET_CHAT_Handle *handle) | ||
296 | { | ||
297 | GNUNET_assert(handle); | ||
298 | |||
299 | if ((!(handle->current)) || (!(handle->current->ego))) | ||
300 | return NULL; | ||
301 | |||
302 | return GNUNET_IDENTITY_ego_get_private_key( | ||
303 | handle->current->ego | ||
304 | ); | ||
305 | } | ||
306 | |||
277 | void | 307 | void |
278 | handle_send_internal_message (struct GNUNET_CHAT_Handle *handle, | 308 | handle_send_internal_message (struct GNUNET_CHAT_Handle *handle, |
279 | struct GNUNET_CHAT_Context *context, | 309 | struct GNUNET_CHAT_Context *context, |
@@ -351,7 +381,6 @@ handle_request_context_by_room (struct GNUNET_CHAT_Handle *handle, | |||
351 | return GNUNET_OK; | 381 | return GNUNET_OK; |
352 | 382 | ||
353 | context = context_create_from_room(handle, room); | 383 | context = context_create_from_room(handle, room); |
354 | context_load_config(context); | ||
355 | 384 | ||
356 | if (GNUNET_OK != GNUNET_CONTAINER_multihashmap_put( | 385 | if (GNUNET_OK != GNUNET_CONTAINER_multihashmap_put( |
357 | handle->contexts, key, context, | 386 | handle->contexts, key, context, |
@@ -376,9 +405,14 @@ check_type: | |||
376 | (GNUNET_OK == intern_provide_contact_for_member(handle, | 405 | (GNUNET_OK == intern_provide_contact_for_member(handle, |
377 | check.contact, | 406 | check.contact, |
378 | context))) | 407 | context))) |
408 | { | ||
409 | context_delete_records(context); | ||
379 | context->type = GNUNET_CHAT_CONTEXT_TYPE_CONTACT; | 410 | context->type = GNUNET_CHAT_CONTEXT_TYPE_CONTACT; |
411 | context_write_records(context); | ||
412 | } | ||
380 | else if (checks >= 2) | 413 | else if (checks >= 2) |
381 | { | 414 | { |
415 | context_delete_records(context); | ||
382 | context->type = GNUNET_CHAT_CONTEXT_TYPE_GROUP; | 416 | context->type = GNUNET_CHAT_CONTEXT_TYPE_GROUP; |
383 | 417 | ||
384 | if (context->contact) | 418 | if (context->contact) |
@@ -405,9 +439,7 @@ setup_group: | |||
405 | handle, context | 439 | handle, context |
406 | ); | 440 | ); |
407 | 441 | ||
408 | group_load_config(group); | 442 | if (context->topic) |
409 | |||
410 | if (group->topic) | ||
411 | group_publish(group); | 443 | group_publish(group); |
412 | 444 | ||
413 | if (GNUNET_OK == GNUNET_CONTAINER_multihashmap_put( | 445 | if (GNUNET_OK == GNUNET_CONTAINER_multihashmap_put( |
@@ -421,6 +453,7 @@ setup_group: | |||
421 | NULL | 453 | NULL |
422 | ); | 454 | ); |
423 | 455 | ||
456 | context_write_records(context); | ||
424 | return GNUNET_OK; | 457 | return GNUNET_OK; |
425 | } | 458 | } |
426 | 459 | ||
diff --git a/src/gnunet_chat_handle.h b/src/gnunet_chat_handle.h index 6004e5d..0713bf1 100644 --- a/src/gnunet_chat_handle.h +++ b/src/gnunet_chat_handle.h | |||
@@ -33,6 +33,7 @@ | |||
33 | #include <gnunet/gnunet_fs_service.h> | 33 | #include <gnunet/gnunet_fs_service.h> |
34 | #include <gnunet/gnunet_identity_service.h> | 34 | #include <gnunet/gnunet_identity_service.h> |
35 | #include <gnunet/gnunet_messenger_service.h> | 35 | #include <gnunet/gnunet_messenger_service.h> |
36 | #include <gnunet/gnunet_namestore_service.h> | ||
36 | #include <gnunet/gnunet_scheduler_lib.h> | 37 | #include <gnunet/gnunet_scheduler_lib.h> |
37 | #include <gnunet/gnunet_util_lib.h> | 38 | #include <gnunet/gnunet_util_lib.h> |
38 | 39 | ||
@@ -72,6 +73,7 @@ struct GNUNET_CHAT_Handle | |||
72 | 73 | ||
73 | const struct GNUNET_CHAT_Account *current; | 74 | const struct GNUNET_CHAT_Account *current; |
74 | struct GNUNET_IDENTITY_Operation *creation_op; | 75 | struct GNUNET_IDENTITY_Operation *creation_op; |
76 | struct GNUNET_NAMESTORE_ZoneMonitor *monitor; | ||
75 | 77 | ||
76 | struct GNUNET_CONTAINER_MultiHashMap *files; | 78 | struct GNUNET_CONTAINER_MultiHashMap *files; |
77 | struct GNUNET_CONTAINER_MultiHashMap *contexts; | 79 | struct GNUNET_CONTAINER_MultiHashMap *contexts; |
@@ -82,6 +84,7 @@ struct GNUNET_CHAT_Handle | |||
82 | struct GNUNET_FS_Handle *fs; | 84 | struct GNUNET_FS_Handle *fs; |
83 | struct GNUNET_IDENTITY_Handle *identity; | 85 | struct GNUNET_IDENTITY_Handle *identity; |
84 | struct GNUNET_MESSENGER_Handle *messenger; | 86 | struct GNUNET_MESSENGER_Handle *messenger; |
87 | struct GNUNET_NAMESTORE_Handle *namestore; | ||
85 | 88 | ||
86 | char *public_key; | 89 | char *public_key; |
87 | void *user_pointer; | 90 | void *user_pointer; |
@@ -109,6 +112,9 @@ handle_disconnect (struct GNUNET_CHAT_Handle *handle); | |||
109 | const char* | 112 | const char* |
110 | handle_get_directory (const struct GNUNET_CHAT_Handle *handle); | 113 | handle_get_directory (const struct GNUNET_CHAT_Handle *handle); |
111 | 114 | ||
115 | const struct GNUNET_IDENTITY_PrivateKey* | ||
116 | handle_get_key (const struct GNUNET_CHAT_Handle *handle); | ||
117 | |||
112 | void | 118 | void |
113 | handle_send_internal_message (struct GNUNET_CHAT_Handle *handle, | 119 | handle_send_internal_message (struct GNUNET_CHAT_Handle *handle, |
114 | struct GNUNET_CHAT_Context *context, | 120 | struct GNUNET_CHAT_Context *context, |
diff --git a/src/gnunet_chat_handle_intern.c b/src/gnunet_chat_handle_intern.c index d3f4694..0662850 100644 --- a/src/gnunet_chat_handle_intern.c +++ b/src/gnunet_chat_handle_intern.c | |||
@@ -64,6 +64,12 @@ on_handle_arm_connection(void *cls, | |||
64 | GNUNET_OS_INHERIT_STD_NONE, | 64 | GNUNET_OS_INHERIT_STD_NONE, |
65 | NULL, NULL | 65 | NULL, NULL |
66 | ); | 66 | ); |
67 | |||
68 | GNUNET_ARM_request_service_start( | ||
69 | chat->arm, "namestore", | ||
70 | GNUNET_OS_INHERIT_STD_NONE, | ||
71 | NULL, NULL | ||
72 | ); | ||
67 | } else { | 73 | } else { |
68 | GNUNET_ARM_request_service_start( | 74 | GNUNET_ARM_request_service_start( |
69 | chat->arm, "arm", | 75 | chat->arm, "arm", |
@@ -359,6 +365,93 @@ scan_handle_room_members (void* cls, | |||
359 | } | 365 | } |
360 | 366 | ||
361 | void | 367 | void |
368 | on_monitor_namestore_record(void *cls, | ||
369 | GNUNET_UNUSED const | ||
370 | struct GNUNET_IDENTITY_PrivateKey *zone, | ||
371 | const char *label, | ||
372 | unsigned int count, | ||
373 | const struct GNUNET_GNSRECORD_Data *data) | ||
374 | { | ||
375 | struct GNUNET_CHAT_Handle *chat = cls; | ||
376 | |||
377 | if (count <= 0) | ||
378 | goto skip_records; | ||
379 | |||
380 | const struct GNUNET_MESSENGER_RoomEntryRecord *record = NULL; | ||
381 | |||
382 | for (unsigned int i = 0; i < count; i++) | ||
383 | { | ||
384 | if (GNUNET_YES == GNUNET_GNSRECORD_is_expired(data + i)) | ||
385 | continue; | ||
386 | |||
387 | if ((GNUNET_GNSRECORD_TYPE_MESSENGER_ROOM_ENTRY == data[i].record_type) && | ||
388 | (!(GNUNET_GNSRECORD_RF_SUPPLEMENTAL & data[i].flags))) | ||
389 | { | ||
390 | record = data[i].data; | ||
391 | break; | ||
392 | } | ||
393 | } | ||
394 | |||
395 | if (!record) | ||
396 | goto skip_records; | ||
397 | |||
398 | struct GNUNET_CHAT_Context *context = GNUNET_CONTAINER_multihashmap_get( | ||
399 | chat->contexts, | ||
400 | &(record->key) | ||
401 | ); | ||
402 | |||
403 | if (context) | ||
404 | { | ||
405 | context_read_records(context, label, count, data); | ||
406 | |||
407 | printf("PATCH: %s %u %d %s\n", label, count, (int) context->type, context->topic); | ||
408 | |||
409 | goto skip_records; | ||
410 | } | ||
411 | |||
412 | struct GNUNET_MESSENGER_Room *room = GNUNET_MESSENGER_enter_room( | ||
413 | chat->messenger, | ||
414 | &(record->door), | ||
415 | &(record->key) | ||
416 | ); | ||
417 | |||
418 | if (!room) | ||
419 | goto skip_records; | ||
420 | |||
421 | context = context_create_from_room(chat, room); | ||
422 | context_read_records(context, label, count, data); | ||
423 | |||
424 | printf("READ: %s %u %d %s\n", label, count, (int) context->type, context->topic); | ||
425 | |||
426 | handle_send_room_name(chat, room); | ||
427 | |||
428 | if (GNUNET_OK != GNUNET_CONTAINER_multihashmap_put( | ||
429 | chat->contexts, &(record->key), context, | ||
430 | GNUNET_CONTAINER_MULTIHASHMAPOPTION_UNIQUE_FAST)) | ||
431 | { | ||
432 | context_destroy(context); | ||
433 | goto skip_records; | ||
434 | } | ||
435 | |||
436 | if (GNUNET_CHAT_CONTEXT_TYPE_GROUP != context->type) | ||
437 | goto skip_records; | ||
438 | |||
439 | struct GNUNET_CHAT_Group *group = group_create_from_context(chat, context); | ||
440 | |||
441 | if (context->topic) | ||
442 | group_publish(group); | ||
443 | |||
444 | if (GNUNET_OK != GNUNET_CONTAINER_multihashmap_put( | ||
445 | chat->groups, &(record->key), group, | ||
446 | GNUNET_CONTAINER_MULTIHASHMAPOPTION_UNIQUE_FAST)) | ||
447 | group_destroy(group); | ||
448 | |||
449 | skip_records: | ||
450 | if (chat->monitor) | ||
451 | GNUNET_NAMESTORE_zone_monitor_next(chat->monitor, 1); | ||
452 | } | ||
453 | |||
454 | void | ||
362 | on_handle_identity(void *cls, | 455 | on_handle_identity(void *cls, |
363 | GNUNET_UNUSED struct GNUNET_MESSENGER_Handle *messenger) | 456 | GNUNET_UNUSED struct GNUNET_MESSENGER_Handle *messenger) |
364 | { | 457 | { |
@@ -377,7 +470,8 @@ on_handle_identity(void *cls, | |||
377 | return; | 470 | return; |
378 | 471 | ||
379 | GNUNET_assert(handle->messenger); | 472 | GNUNET_assert(handle->messenger); |
380 | context_scan_configs(handle); | 473 | |
474 | printf("HURRAY!\n"); | ||
381 | 475 | ||
382 | handle_send_internal_message( | 476 | handle_send_internal_message( |
383 | handle, | 477 | handle, |
@@ -385,6 +479,23 @@ on_handle_identity(void *cls, | |||
385 | GNUNET_CHAT_FLAG_LOGIN, | 479 | GNUNET_CHAT_FLAG_LOGIN, |
386 | NULL | 480 | NULL |
387 | ); | 481 | ); |
482 | |||
483 | const struct GNUNET_IDENTITY_PrivateKey *zone = handle_get_key(handle); | ||
484 | |||
485 | if ((!zone) || (handle->monitor)) | ||
486 | return; | ||
487 | |||
488 | handle->monitor = GNUNET_NAMESTORE_zone_monitor_start( | ||
489 | handle->cfg, | ||
490 | zone, | ||
491 | GNUNET_YES, | ||
492 | NULL, | ||
493 | NULL, | ||
494 | on_monitor_namestore_record, | ||
495 | handle, | ||
496 | NULL, | ||
497 | NULL | ||
498 | ); | ||
388 | } | 499 | } |
389 | 500 | ||
390 | void | 501 | void |
@@ -583,7 +694,6 @@ it_destroy_handle_groups (GNUNET_UNUSED void *cls, | |||
583 | GNUNET_assert(value); | 694 | GNUNET_assert(value); |
584 | 695 | ||
585 | struct GNUNET_CHAT_Group *group = value; | 696 | struct GNUNET_CHAT_Group *group = value; |
586 | group_save_config(group); | ||
587 | group_destroy(group); | 697 | group_destroy(group); |
588 | return GNUNET_YES; | 698 | return GNUNET_YES; |
589 | } | 699 | } |
@@ -608,7 +718,6 @@ it_destroy_handle_contexts (GNUNET_UNUSED void *cls, | |||
608 | GNUNET_assert(value); | 718 | GNUNET_assert(value); |
609 | 719 | ||
610 | struct GNUNET_CHAT_Context *context = value; | 720 | struct GNUNET_CHAT_Context *context = value; |
611 | context_save_config(context); | ||
612 | context_destroy(context); | 721 | context_destroy(context); |
613 | return GNUNET_YES; | 722 | return GNUNET_YES; |
614 | } | 723 | } |
diff --git a/src/gnunet_chat_lib.c b/src/gnunet_chat_lib.c index 16fb27d..8c6a109 100644 --- 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, | |||
310 | 310 | ||
311 | context->type = GNUNET_CHAT_CONTEXT_TYPE_GROUP; | 311 | context->type = GNUNET_CHAT_CONTEXT_TYPE_GROUP; |
312 | 312 | ||
313 | util_set_name_field(topic, &(context->topic)); | ||
314 | |||
313 | if (GNUNET_OK != GNUNET_CONTAINER_multihashmap_put( | 315 | if (GNUNET_OK != GNUNET_CONTAINER_multihashmap_put( |
314 | handle->contexts, &key, context, | 316 | handle->contexts, &key, context, |
315 | GNUNET_CONTAINER_MULTIHASHMAPOPTION_UNIQUE_FAST)) | 317 | GNUNET_CONTAINER_MULTIHASHMAPOPTION_UNIQUE_FAST)) |
@@ -317,15 +319,16 @@ GNUNET_CHAT_group_create (struct GNUNET_CHAT_Handle *handle, | |||
317 | 319 | ||
318 | struct GNUNET_CHAT_Group *group = group_create_from_context(handle, context); | 320 | struct GNUNET_CHAT_Group *group = group_create_from_context(handle, context); |
319 | 321 | ||
320 | util_set_name_field(topic, &(group->topic)); | 322 | if (context->topic) |
321 | |||
322 | if (group->topic) | ||
323 | group_publish(group); | 323 | group_publish(group); |
324 | 324 | ||
325 | if (GNUNET_OK == GNUNET_CONTAINER_multihashmap_put( | 325 | if (GNUNET_OK == GNUNET_CONTAINER_multihashmap_put( |
326 | handle->groups, &key, group, | 326 | handle->groups, &key, group, |
327 | GNUNET_CONTAINER_MULTIHASHMAPOPTION_UNIQUE_FAST)) | 327 | GNUNET_CONTAINER_MULTIHASHMAPOPTION_UNIQUE_FAST)) |
328 | { | ||
329 | context_write_records(context); | ||
328 | return group; | 330 | return group; |
331 | } | ||
329 | 332 | ||
330 | group_destroy(group); | 333 | group_destroy(group); |
331 | 334 | ||
@@ -513,10 +516,13 @@ GNUNET_CHAT_group_set_name (struct GNUNET_CHAT_Group *group, | |||
513 | const char* | 516 | const char* |
514 | GNUNET_CHAT_group_get_name (const struct GNUNET_CHAT_Group *group) | 517 | GNUNET_CHAT_group_get_name (const struct GNUNET_CHAT_Group *group) |
515 | { | 518 | { |
516 | if (!group) | 519 | if ((!group) || (!(group->context))) |
517 | return NULL; | 520 | return NULL; |
518 | 521 | ||
519 | return group->context->nick; | 522 | if (group->context->nick) |
523 | return group->context->nick; | ||
524 | |||
525 | return group->context->topic; | ||
520 | } | 526 | } |
521 | 527 | ||
522 | 528 | ||
@@ -911,6 +917,43 @@ GNUNET_CHAT_context_iterate_files (struct GNUNET_CHAT_Context *context, | |||
911 | } | 917 | } |
912 | 918 | ||
913 | 919 | ||
920 | void | ||
921 | GNUNET_CHAT_member_set_user_pointer (struct GNUNET_CHAT_Context *context, | ||
922 | const struct GNUNET_CHAT_Contact *member, | ||
923 | void *user_pointer) | ||
924 | { | ||
925 | if ((!context) || (!member)) | ||
926 | return; | ||
927 | |||
928 | struct GNUNET_ShortHashCode hash; | ||
929 | util_shorthash_from_member(member->member, &hash); | ||
930 | |||
931 | GNUNET_CONTAINER_multishortmap_put( | ||
932 | context->member_pointers, | ||
933 | &hash, | ||
934 | user_pointer, | ||
935 | GNUNET_CONTAINER_MULTIHASHMAPOPTION_REPLACE | ||
936 | ); | ||
937 | } | ||
938 | |||
939 | |||
940 | void* | ||
941 | GNUNET_CHAT_member_get_user_pointer (const struct GNUNET_CHAT_Context *context, | ||
942 | const struct GNUNET_CHAT_Contact *member) | ||
943 | { | ||
944 | if ((!context) || (!member)) | ||
945 | return NULL; | ||
946 | |||
947 | struct GNUNET_ShortHashCode hash; | ||
948 | util_shorthash_from_member(member->member, &hash); | ||
949 | |||
950 | return GNUNET_CONTAINER_multishortmap_get( | ||
951 | context->member_pointers, | ||
952 | &hash | ||
953 | ); | ||
954 | } | ||
955 | |||
956 | |||
914 | enum GNUNET_CHAT_MessageKind | 957 | enum GNUNET_CHAT_MessageKind |
915 | GNUNET_CHAT_message_get_kind (const struct GNUNET_CHAT_Message *message) | 958 | GNUNET_CHAT_message_get_kind (const struct GNUNET_CHAT_Message *message) |
916 | { | 959 | { |