aboutsummaryrefslogtreecommitdiff
path: root/src/messenger/gnunet-service-messenger_message_store.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/messenger/gnunet-service-messenger_message_store.c')
-rw-r--r--src/messenger/gnunet-service-messenger_message_store.c324
1 files changed, 205 insertions, 119 deletions
diff --git a/src/messenger/gnunet-service-messenger_message_store.c b/src/messenger/gnunet-service-messenger_message_store.c
index e137e9d93..d4bccca5c 100644
--- a/src/messenger/gnunet-service-messenger_message_store.c
+++ b/src/messenger/gnunet-service-messenger_message_store.c
@@ -30,7 +30,7 @@
30void 30void
31init_message_store (struct GNUNET_MESSENGER_MessageStore *store) 31init_message_store (struct GNUNET_MESSENGER_MessageStore *store)
32{ 32{
33 GNUNET_assert(store); 33 GNUNET_assert (store);
34 34
35 store->storage_messages = NULL; 35 store->storage_messages = NULL;
36 36
@@ -42,6 +42,7 @@ init_message_store (struct GNUNET_MESSENGER_MessageStore *store)
42 store->write_links = GNUNET_NO; 42 store->write_links = GNUNET_NO;
43} 43}
44 44
45
45static int 46static int
46iterate_destroy_entries (void *cls, 47iterate_destroy_entries (void *cls,
47 const struct GNUNET_HashCode *key, 48 const struct GNUNET_HashCode *key,
@@ -49,11 +50,12 @@ iterate_destroy_entries (void *cls,
49{ 50{
50 struct GNUNET_MESSENGER_MessageEntry *entry = value; 51 struct GNUNET_MESSENGER_MessageEntry *entry = value;
51 52
52 GNUNET_free(entry); 53 GNUNET_free (entry);
53 54
54 return GNUNET_YES; 55 return GNUNET_YES;
55} 56}
56 57
58
57static int 59static int
58iterate_destroy_messages (void *cls, 60iterate_destroy_messages (void *cls,
59 const struct GNUNET_HashCode *key, 61 const struct GNUNET_HashCode *key,
@@ -66,6 +68,7 @@ iterate_destroy_messages (void *cls,
66 return GNUNET_YES; 68 return GNUNET_YES;
67} 69}
68 70
71
69static int 72static int
70iterate_destroy_links (void *cls, 73iterate_destroy_links (void *cls,
71 const struct GNUNET_HashCode *key, 74 const struct GNUNET_HashCode *key,
@@ -73,15 +76,16 @@ iterate_destroy_links (void *cls,
73{ 76{
74 struct GNUNET_HashCode *previous = value; 77 struct GNUNET_HashCode *previous = value;
75 78
76 GNUNET_free(previous); 79 GNUNET_free (previous);
77 80
78 return GNUNET_YES; 81 return GNUNET_YES;
79} 82}
80 83
84
81void 85void
82clear_message_store (struct GNUNET_MESSENGER_MessageStore *store) 86clear_message_store (struct GNUNET_MESSENGER_MessageStore *store)
83{ 87{
84 GNUNET_assert(store); 88 GNUNET_assert (store);
85 89
86 if (store->storage_messages) 90 if (store->storage_messages)
87 { 91 {
@@ -90,15 +94,19 @@ clear_message_store (struct GNUNET_MESSENGER_MessageStore *store)
90 store->storage_messages = NULL; 94 store->storage_messages = NULL;
91 } 95 }
92 96
93 GNUNET_CONTAINER_multihashmap_iterate (store->entries, iterate_destroy_entries, NULL); 97 GNUNET_CONTAINER_multihashmap_iterate (store->entries,
94 GNUNET_CONTAINER_multihashmap_iterate (store->messages, iterate_destroy_messages, NULL); 98 iterate_destroy_entries, NULL);
95 GNUNET_CONTAINER_multihashmap_iterate (store->links, iterate_destroy_links, NULL); 99 GNUNET_CONTAINER_multihashmap_iterate (store->messages,
100 iterate_destroy_messages, NULL);
101 GNUNET_CONTAINER_multihashmap_iterate (store->links, iterate_destroy_links,
102 NULL);
96 103
97 GNUNET_CONTAINER_multihashmap_destroy (store->entries); 104 GNUNET_CONTAINER_multihashmap_destroy (store->entries);
98 GNUNET_CONTAINER_multihashmap_destroy (store->messages); 105 GNUNET_CONTAINER_multihashmap_destroy (store->messages);
99 GNUNET_CONTAINER_multihashmap_destroy (store->links); 106 GNUNET_CONTAINER_multihashmap_destroy (store->links);
100} 107}
101 108
109
102struct GNUNET_MESSENGER_MessageEntryStorage 110struct GNUNET_MESSENGER_MessageEntryStorage
103{ 111{
104 struct GNUNET_HashCode hash; 112 struct GNUNET_HashCode hash;
@@ -106,10 +114,12 @@ struct GNUNET_MESSENGER_MessageEntryStorage
106}; 114};
107 115
108#define load_message_store_attribute_failed(file, attribute) \ 116#define load_message_store_attribute_failed(file, attribute) \
109 sizeof(attribute) != GNUNET_DISK_file_read(file, &(attribute), sizeof(attribute)) 117 sizeof(attribute) != GNUNET_DISK_file_read (file, &(attribute), \
118 sizeof(attribute))
110 119
111#define save_message_store_attribute_failed(file, attribute) \ 120#define save_message_store_attribute_failed(file, attribute) \
112 sizeof(attribute) != GNUNET_DISK_file_write(file, &(attribute), sizeof(attribute)) 121 sizeof(attribute) != GNUNET_DISK_file_write (file, &(attribute), \
122 sizeof(attribute))
113 123
114static void 124static void
115load_message_store_entries (struct GNUNET_MESSENGER_MessageStore *store, 125load_message_store_entries (struct GNUNET_MESSENGER_MessageStore *store,
@@ -117,31 +127,36 @@ load_message_store_entries (struct GNUNET_MESSENGER_MessageStore *store,
117{ 127{
118 enum GNUNET_DISK_AccessPermissions permission = (GNUNET_DISK_PERM_USER_READ); 128 enum GNUNET_DISK_AccessPermissions permission = (GNUNET_DISK_PERM_USER_READ);
119 129
120 struct GNUNET_DISK_FileHandle *entries = GNUNET_DISK_file_open (filename, GNUNET_DISK_OPEN_READ, permission); 130 struct GNUNET_DISK_FileHandle *entries = GNUNET_DISK_file_open (filename,
131 GNUNET_DISK_OPEN_READ,
132 permission);
121 133
122 if (!entries) 134 if (! entries)
123 return; 135 return;
124 136
125 struct GNUNET_MESSENGER_MessageEntryStorage storage; 137 struct GNUNET_MESSENGER_MessageEntryStorage storage;
126 struct GNUNET_MESSENGER_MessageEntry *entry; 138 struct GNUNET_MESSENGER_MessageEntry *entry;
127 139
128 memset(&storage, 0, sizeof(storage)); 140 memset (&storage, 0, sizeof(storage));
129 141
130 do 142 do
131 { 143 {
132 entry = NULL; 144 entry = NULL;
133 145
134 if ((load_message_store_attribute_failed(entries, storage.hash)) || 146 if ((load_message_store_attribute_failed (entries, storage.hash)) ||
135 (load_message_store_attribute_failed(entries, storage.entry.offset)) || 147 (load_message_store_attribute_failed (entries, storage.entry.offset)) ||
136 (load_message_store_attribute_failed(entries, storage.entry.length))) 148 (load_message_store_attribute_failed (entries, storage.entry.length)))
137 break; 149 break;
138 150
139 entry = GNUNET_new(struct GNUNET_MESSENGER_MessageEntry); 151 entry = GNUNET_new (struct GNUNET_MESSENGER_MessageEntry);
140 152
141 GNUNET_memcpy(entry, &(storage.entry), sizeof(*entry)); 153 GNUNET_memcpy (entry, &(storage.entry), sizeof(*entry));
142 154
143 if ((GNUNET_YES == GNUNET_CONTAINER_multihashmap_contains (store->entries, &(storage.hash))) || 155 if ((GNUNET_YES == GNUNET_CONTAINER_multihashmap_contains (store->entries,
144 (GNUNET_OK != GNUNET_CONTAINER_multihashmap_put (store->entries, &(storage.hash), entry, 156 &(storage.hash)))
157 ||
158 (GNUNET_OK != GNUNET_CONTAINER_multihashmap_put (store->entries,
159 &(storage.hash), entry,
145 GNUNET_CONTAINER_MULTIHASHMAPOPTION_UNIQUE_FAST))) 160 GNUNET_CONTAINER_MULTIHASHMAPOPTION_UNIQUE_FAST)))
146 { 161 {
147 store->rewrite_entries = GNUNET_YES; 162 store->rewrite_entries = GNUNET_YES;
@@ -151,11 +166,12 @@ load_message_store_entries (struct GNUNET_MESSENGER_MessageStore *store,
151 while (entry); 166 while (entry);
152 167
153 if (entry) 168 if (entry)
154 GNUNET_free(entry); 169 GNUNET_free (entry);
155 170
156 GNUNET_DISK_file_close (entries); 171 GNUNET_DISK_file_close (entries);
157} 172}
158 173
174
159struct GNUNET_MESSENGER_MessageLinkStorage 175struct GNUNET_MESSENGER_MessageLinkStorage
160{ 176{
161 struct GNUNET_HashCode hash; 177 struct GNUNET_HashCode hash;
@@ -168,51 +184,59 @@ load_message_store_links (struct GNUNET_MESSENGER_MessageStore *store,
168{ 184{
169 enum GNUNET_DISK_AccessPermissions permission = (GNUNET_DISK_PERM_USER_READ); 185 enum GNUNET_DISK_AccessPermissions permission = (GNUNET_DISK_PERM_USER_READ);
170 186
171 struct GNUNET_DISK_FileHandle *entries = GNUNET_DISK_file_open (filename, GNUNET_DISK_OPEN_READ, permission); 187 struct GNUNET_DISK_FileHandle *entries = GNUNET_DISK_file_open (filename,
188 GNUNET_DISK_OPEN_READ,
189 permission);
172 190
173 if (!entries) 191 if (! entries)
174 return; 192 return;
175 193
176 struct GNUNET_MESSENGER_MessageLinkStorage storage; 194 struct GNUNET_MESSENGER_MessageLinkStorage storage;
177 struct GNUNET_MESSENGER_MessageLink *link; 195 struct GNUNET_MESSENGER_MessageLink *link;
178 196
179 memset(&storage, 0, sizeof(storage)); 197 memset (&storage, 0, sizeof(storage));
180 198
181 do 199 do
182 { 200 {
183 link = NULL; 201 link = NULL;
184 202
185 if ((load_message_store_attribute_failed(entries, storage.hash)) || 203 if ((load_message_store_attribute_failed (entries, storage.hash)) ||
186 (load_message_store_attribute_failed(entries, storage.link.multiple)) || 204 (load_message_store_attribute_failed (entries,
187 (load_message_store_attribute_failed(entries, storage.link.first)) || 205 storage.link.multiple)) ||
206 (load_message_store_attribute_failed (entries, storage.link.first)) ||
188 ((GNUNET_YES == storage.link.multiple) && 207 ((GNUNET_YES == storage.link.multiple) &&
189 (load_message_store_attribute_failed(entries, storage.link.second)))) 208 (load_message_store_attribute_failed (entries, storage.link.second))))
190 break; 209 break;
191 210
192 link = GNUNET_new(struct GNUNET_MESSENGER_MessageLink); 211 link = GNUNET_new (struct GNUNET_MESSENGER_MessageLink);
193 212
194 GNUNET_memcpy(link, &(storage.link), sizeof(*link)); 213 GNUNET_memcpy (link, &(storage.link), sizeof(*link));
195 214
196 if ((GNUNET_YES == GNUNET_CONTAINER_multihashmap_contains (store->links, &(storage.hash))) || 215 if ((GNUNET_YES == GNUNET_CONTAINER_multihashmap_contains (store->links,
197 (GNUNET_OK != GNUNET_CONTAINER_multihashmap_put (store->links, &(storage.hash), link, 216 &(storage.hash)))
217 ||
218 (GNUNET_OK != GNUNET_CONTAINER_multihashmap_put (store->links,
219 &(storage.hash), link,
198 GNUNET_CONTAINER_MULTIHASHMAPOPTION_UNIQUE_FAST))) 220 GNUNET_CONTAINER_MULTIHASHMAPOPTION_UNIQUE_FAST)))
199 break; 221 break;
200 } 222 }
201 while (link); 223 while (link);
202 224
203 if (link) 225 if (link)
204 GNUNET_free(link); 226 GNUNET_free (link);
205 227
206 GNUNET_DISK_file_close (entries); 228 GNUNET_DISK_file_close (entries);
207} 229}
208 230
231
209void 232void
210load_message_store (struct GNUNET_MESSENGER_MessageStore *store, 233load_message_store (struct GNUNET_MESSENGER_MessageStore *store,
211 const char *directory) 234 const char *directory)
212{ 235{
213 GNUNET_assert((store) && (directory)); 236 GNUNET_assert ((store) && (directory));
214 237
215 enum GNUNET_DISK_AccessPermissions permission = (GNUNET_DISK_PERM_USER_READ | GNUNET_DISK_PERM_USER_WRITE); 238 enum GNUNET_DISK_AccessPermissions permission = (GNUNET_DISK_PERM_USER_READ
239 | GNUNET_DISK_PERM_USER_WRITE);
216 240
217 if (store->storage_messages) 241 if (store->storage_messages)
218 GNUNET_DISK_file_close (store->storage_messages); 242 GNUNET_DISK_file_close (store->storage_messages);
@@ -221,30 +245,33 @@ load_message_store (struct GNUNET_MESSENGER_MessageStore *store,
221 GNUNET_asprintf (&filename, "%s%s", directory, "messages.store"); 245 GNUNET_asprintf (&filename, "%s%s", directory, "messages.store");
222 246
223 if (GNUNET_YES == GNUNET_DISK_file_test (filename)) 247 if (GNUNET_YES == GNUNET_DISK_file_test (filename))
224 store->storage_messages = GNUNET_DISK_file_open (filename, GNUNET_DISK_OPEN_READWRITE, permission); 248 store->storage_messages = GNUNET_DISK_file_open (filename,
249 GNUNET_DISK_OPEN_READWRITE,
250 permission);
225 else 251 else
226 store->storage_messages = NULL; 252 store->storage_messages = NULL;
227 253
228 GNUNET_free(filename); 254 GNUNET_free (filename);
229 255
230 if (!store->storage_messages) 256 if (! store->storage_messages)
231 return; 257 return;
232 258
233 GNUNET_asprintf (&filename, "%s%s", directory, "entries.store"); 259 GNUNET_asprintf (&filename, "%s%s", directory, "entries.store");
234 260
235 if (GNUNET_YES == GNUNET_DISK_file_test (filename)) 261 if (GNUNET_YES == GNUNET_DISK_file_test (filename))
236 load_message_store_entries(store, filename); 262 load_message_store_entries (store, filename);
237 263
238 GNUNET_free(filename); 264 GNUNET_free (filename);
239 265
240 GNUNET_asprintf (&filename, "%s%s", directory, "links.store"); 266 GNUNET_asprintf (&filename, "%s%s", directory, "links.store");
241 267
242 if (GNUNET_YES == GNUNET_DISK_file_test (filename)) 268 if (GNUNET_YES == GNUNET_DISK_file_test (filename))
243 load_message_store_links(store, filename); 269 load_message_store_links (store, filename);
244 270
245 GNUNET_free(filename); 271 GNUNET_free (filename);
246} 272}
247 273
274
248struct GNUNET_MESSENGER_ClosureMessageSave 275struct GNUNET_MESSENGER_ClosureMessageSave
249{ 276{
250 struct GNUNET_MESSENGER_MessageStore *store; 277 struct GNUNET_MESSENGER_MessageStore *store;
@@ -261,12 +288,15 @@ iterate_save_entries (void *cls,
261 struct GNUNET_MESSENGER_MessageEntry *entry = value; 288 struct GNUNET_MESSENGER_MessageEntry *entry = value;
262 289
263 GNUNET_DISK_file_write (save->storage, key, sizeof(*key)); 290 GNUNET_DISK_file_write (save->storage, key, sizeof(*key));
264 GNUNET_DISK_file_write (save->storage, &(entry->offset), sizeof(entry->offset)); 291 GNUNET_DISK_file_write (save->storage, &(entry->offset),
265 GNUNET_DISK_file_write (save->storage, &(entry->length), sizeof(entry->length)); 292 sizeof(entry->offset));
293 GNUNET_DISK_file_write (save->storage, &(entry->length),
294 sizeof(entry->length));
266 295
267 return GNUNET_YES; 296 return GNUNET_YES;
268} 297}
269 298
299
270static int 300static int
271iterate_save_messages (void *cls, 301iterate_save_messages (void *cls,
272 const struct GNUNET_HashCode *key, 302 const struct GNUNET_HashCode *key,
@@ -274,36 +304,42 @@ iterate_save_messages (void *cls,
274{ 304{
275 struct GNUNET_MESSENGER_ClosureMessageSave *save = cls; 305 struct GNUNET_MESSENGER_ClosureMessageSave *save = cls;
276 306
277 if (GNUNET_NO != GNUNET_CONTAINER_multihashmap_contains (save->store->entries, key)) 307 if (GNUNET_NO != GNUNET_CONTAINER_multihashmap_contains (save->store->entries,
308 key))
278 return GNUNET_YES; 309 return GNUNET_YES;
279 310
280 struct GNUNET_MESSENGER_Message *message = value; 311 struct GNUNET_MESSENGER_Message *message = value;
281 struct GNUNET_MESSENGER_MessageEntryStorage storage; 312 struct GNUNET_MESSENGER_MessageEntryStorage storage;
282 313
283 GNUNET_memcpy(&(storage.hash), key, sizeof(storage.hash)); 314 GNUNET_memcpy (&(storage.hash), key, sizeof(storage.hash));
284 315
285 storage.entry.length = get_message_size (message, GNUNET_YES); 316 storage.entry.length = get_message_size (message, GNUNET_YES);
286 storage.entry.offset = GNUNET_DISK_file_seek (save->store->storage_messages, 0, GNUNET_DISK_SEEK_END); 317 storage.entry.offset = GNUNET_DISK_file_seek (save->store->storage_messages,
318 0, GNUNET_DISK_SEEK_END);
287 319
288 if ((GNUNET_SYSERR == storage.entry.offset) || 320 if ((GNUNET_SYSERR == storage.entry.offset) ||
289 (save_message_store_attribute_failed(save->storage, storage.hash)) || 321 (save_message_store_attribute_failed (save->storage, storage.hash)) ||
290 (save_message_store_attribute_failed(save->storage, storage.entry.offset)) || 322 (save_message_store_attribute_failed (save->storage,
291 (save_message_store_attribute_failed(save->storage, storage.entry.length))) 323 storage.entry.offset)) ||
324 (save_message_store_attribute_failed (save->storage,
325 storage.entry.length)))
292 return GNUNET_YES; 326 return GNUNET_YES;
293 327
294 GNUNET_log(GNUNET_ERROR_TYPE_DEBUG, "Storing message with hash: %s\n", 328 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Storing message with hash: %s\n",
295 GNUNET_h2s (&(storage.hash))); 329 GNUNET_h2s (&(storage.hash)));
296 330
297 char *buffer = GNUNET_malloc(storage.entry.length); 331 char *buffer = GNUNET_malloc (storage.entry.length);
298 332
299 encode_message (message, storage.entry.length, buffer, GNUNET_YES); 333 encode_message (message, storage.entry.length, buffer, GNUNET_YES);
300 334
301 GNUNET_DISK_file_write (save->store->storage_messages, buffer, storage.entry.length); 335 GNUNET_DISK_file_write (save->store->storage_messages, buffer,
336 storage.entry.length);
302 337
303 GNUNET_free(buffer); 338 GNUNET_free (buffer);
304 return GNUNET_YES; 339 return GNUNET_YES;
305} 340}
306 341
342
307static int 343static int
308iterate_save_links (void *cls, 344iterate_save_links (void *cls,
309 const struct GNUNET_HashCode *key, 345 const struct GNUNET_HashCode *key,
@@ -313,24 +349,28 @@ iterate_save_links (void *cls,
313 struct GNUNET_MESSENGER_MessageLink *link = value; 349 struct GNUNET_MESSENGER_MessageLink *link = value;
314 350
315 GNUNET_DISK_file_write (save->storage, key, sizeof(*key)); 351 GNUNET_DISK_file_write (save->storage, key, sizeof(*key));
316 GNUNET_DISK_file_write (save->storage, &(link->multiple), sizeof(link->multiple)); 352 GNUNET_DISK_file_write (save->storage, &(link->multiple),
353 sizeof(link->multiple));
317 GNUNET_DISK_file_write (save->storage, &(link->first), sizeof(link->first)); 354 GNUNET_DISK_file_write (save->storage, &(link->first), sizeof(link->first));
318 355
319 if (GNUNET_YES == link->multiple) 356 if (GNUNET_YES == link->multiple)
320 GNUNET_DISK_file_write (save->storage, &(link->second), sizeof(link->second)); 357 GNUNET_DISK_file_write (save->storage, &(link->second),
358 sizeof(link->second));
321 359
322 return GNUNET_YES; 360 return GNUNET_YES;
323} 361}
324 362
363
325void 364void
326save_message_store (struct GNUNET_MESSENGER_MessageStore *store, 365save_message_store (struct GNUNET_MESSENGER_MessageStore *store,
327 const char *directory) 366 const char *directory)
328{ 367{
329 GNUNET_assert((store) && (directory)); 368 GNUNET_assert ((store) && (directory));
330 369
331 struct GNUNET_MESSENGER_ClosureMessageSave save; 370 struct GNUNET_MESSENGER_ClosureMessageSave save;
332 371
333 enum GNUNET_DISK_AccessPermissions permission = (GNUNET_DISK_PERM_USER_READ | GNUNET_DISK_PERM_USER_WRITE); 372 enum GNUNET_DISK_AccessPermissions permission = (GNUNET_DISK_PERM_USER_READ
373 | GNUNET_DISK_PERM_USER_WRITE);
334 374
335 char *filename; 375 char *filename;
336 376
@@ -340,17 +380,20 @@ save_message_store (struct GNUNET_MESSENGER_MessageStore *store,
340 GNUNET_asprintf (&filename, "%s%s", directory, "links.store"); 380 GNUNET_asprintf (&filename, "%s%s", directory, "links.store");
341 381
342 save.store = store; 382 save.store = store;
343 save.storage = GNUNET_DISK_file_open (filename, GNUNET_DISK_OPEN_WRITE | GNUNET_DISK_OPEN_CREATE, permission); 383 save.storage = GNUNET_DISK_file_open (filename, GNUNET_DISK_OPEN_WRITE
384 | GNUNET_DISK_OPEN_CREATE, permission);
344 385
345 GNUNET_free(filename); 386 GNUNET_free (filename);
346 387
347 if (!save.storage) 388 if (! save.storage)
348 goto save_entries; 389 goto save_entries;
349 390
350 if (GNUNET_SYSERR == GNUNET_DISK_file_seek (save.storage, 0, GNUNET_DISK_SEEK_SET)) 391 if (GNUNET_SYSERR == GNUNET_DISK_file_seek (save.storage, 0,
392 GNUNET_DISK_SEEK_SET))
351 goto close_links; 393 goto close_links;
352 394
353 GNUNET_CONTAINER_multihashmap_iterate (store->links, iterate_save_links, &save); 395 GNUNET_CONTAINER_multihashmap_iterate (store->links, iterate_save_links,
396 &save);
354 store->write_links = GNUNET_NO; 397 store->write_links = GNUNET_NO;
355 398
356close_links: 399close_links:
@@ -360,22 +403,26 @@ save_entries:
360 GNUNET_asprintf (&filename, "%s%s", directory, "entries.store"); 403 GNUNET_asprintf (&filename, "%s%s", directory, "entries.store");
361 404
362 save.store = store; 405 save.store = store;
363 save.storage = GNUNET_DISK_file_open (filename, GNUNET_DISK_OPEN_WRITE | GNUNET_DISK_OPEN_CREATE, permission); 406 save.storage = GNUNET_DISK_file_open (filename, GNUNET_DISK_OPEN_WRITE
407 | GNUNET_DISK_OPEN_CREATE, permission);
364 408
365 GNUNET_free(filename); 409 GNUNET_free (filename);
366 410
367 if (!save.storage) 411 if (! save.storage)
368 return; 412 return;
369 413
370 if (GNUNET_YES == store->rewrite_entries) 414 if (GNUNET_YES == store->rewrite_entries)
371 { 415 {
372 if (GNUNET_SYSERR == GNUNET_DISK_file_seek (save.storage, 0, GNUNET_DISK_SEEK_SET)) 416 if (GNUNET_SYSERR == GNUNET_DISK_file_seek (save.storage, 0,
417 GNUNET_DISK_SEEK_SET))
373 goto close_entries; 418 goto close_entries;
374 419
375 GNUNET_CONTAINER_multihashmap_iterate (store->entries, iterate_save_entries, &save); 420 GNUNET_CONTAINER_multihashmap_iterate (store->entries, iterate_save_entries,
421 &save);
376 store->rewrite_entries = GNUNET_NO; 422 store->rewrite_entries = GNUNET_NO;
377 } 423 }
378 else if (GNUNET_SYSERR == GNUNET_DISK_file_seek (save.storage, 0, GNUNET_DISK_SEEK_END)) 424 else if (GNUNET_SYSERR == GNUNET_DISK_file_seek (save.storage, 0,
425 GNUNET_DISK_SEEK_END))
379 goto close_entries; 426 goto close_entries;
380 427
381 if (store->storage_messages) 428 if (store->storage_messages)
@@ -383,14 +430,17 @@ save_entries:
383 430
384 GNUNET_asprintf (&filename, "%s%s", directory, "messages.store"); 431 GNUNET_asprintf (&filename, "%s%s", directory, "messages.store");
385 432
386 store->storage_messages = GNUNET_DISK_file_open (filename, GNUNET_DISK_OPEN_READWRITE | GNUNET_DISK_OPEN_CREATE, 433 store->storage_messages = GNUNET_DISK_file_open (filename,
434 GNUNET_DISK_OPEN_READWRITE
435 | GNUNET_DISK_OPEN_CREATE,
387 permission); 436 permission);
388 437
389 GNUNET_free(filename); 438 GNUNET_free (filename);
390 439
391 if (store->storage_messages) 440 if (store->storage_messages)
392 { 441 {
393 GNUNET_CONTAINER_multihashmap_iterate (store->messages, iterate_save_messages, &save); 442 GNUNET_CONTAINER_multihashmap_iterate (store->messages,
443 iterate_save_messages, &save);
394 444
395 GNUNET_DISK_file_sync (store->storage_messages); 445 GNUNET_DISK_file_sync (store->storage_messages);
396 GNUNET_DISK_file_sync (save.storage); 446 GNUNET_DISK_file_sync (save.storage);
@@ -400,80 +450,94 @@ close_entries:
400 GNUNET_DISK_file_close (save.storage); 450 GNUNET_DISK_file_close (save.storage);
401} 451}
402 452
453
403int 454int
404contains_store_message (const struct GNUNET_MESSENGER_MessageStore *store, 455contains_store_message (const struct GNUNET_MESSENGER_MessageStore *store,
405 const struct GNUNET_HashCode *hash) 456 const struct GNUNET_HashCode *hash)
406{ 457{
407 GNUNET_assert((store) && (hash)); 458 GNUNET_assert ((store) && (hash));
408 459
409 if (GNUNET_YES == GNUNET_CONTAINER_multihashmap_contains (store->messages, hash)) 460 if (GNUNET_YES == GNUNET_CONTAINER_multihashmap_contains (store->messages,
461 hash))
410 return GNUNET_YES; 462 return GNUNET_YES;
411 463
412 return GNUNET_CONTAINER_multihashmap_contains (store->entries, hash); 464 return GNUNET_CONTAINER_multihashmap_contains (store->entries, hash);
413} 465}
414 466
467
415const struct GNUNET_MESSENGER_Message* 468const struct GNUNET_MESSENGER_Message*
416get_store_message (struct GNUNET_MESSENGER_MessageStore *store, 469get_store_message (struct GNUNET_MESSENGER_MessageStore *store,
417 const struct GNUNET_HashCode *hash) 470 const struct GNUNET_HashCode *hash)
418{ 471{
419 GNUNET_assert((store) && (hash)); 472 GNUNET_assert ((store) && (hash));
420 473
421 struct GNUNET_MESSENGER_Message *message = GNUNET_CONTAINER_multihashmap_get (store->messages, hash); 474 struct GNUNET_MESSENGER_Message *message = GNUNET_CONTAINER_multihashmap_get (
475 store->messages, hash);
422 476
423 if (message) 477 if (message)
424 return message; 478 return message;
425 479
426 if (!store->storage_messages) 480 if (! store->storage_messages)
427 return NULL; 481 return NULL;
428 482
429 const struct GNUNET_MESSENGER_MessageEntry *entry = GNUNET_CONTAINER_multihashmap_get (store->entries, hash); 483 const struct GNUNET_MESSENGER_MessageEntry *entry =
484 GNUNET_CONTAINER_multihashmap_get (store->entries, hash);
430 485
431 if (!entry) 486 if (! entry)
432 return NULL; 487 return NULL;
433 488
434 if (entry->offset != GNUNET_DISK_file_seek (store->storage_messages, entry->offset, GNUNET_DISK_SEEK_SET)) 489 if (entry->offset != GNUNET_DISK_file_seek (store->storage_messages,
490 entry->offset,
491 GNUNET_DISK_SEEK_SET))
435 return message; 492 return message;
436 493
437 char *buffer = GNUNET_malloc(entry->length); 494 char *buffer = GNUNET_malloc (entry->length);
438 495
439 if (!buffer) 496 if (! buffer)
440 return NULL; 497 return NULL;
441 498
442 if ((GNUNET_DISK_file_read (store->storage_messages, buffer, entry->length) != entry->length) || 499 if ((GNUNET_DISK_file_read (store->storage_messages, buffer, entry->length) !=
443 (entry->length < get_message_kind_size(GNUNET_MESSENGER_KIND_UNKNOWN, GNUNET_YES))) 500 entry->length) ||
501 (entry->length < get_message_kind_size (GNUNET_MESSENGER_KIND_UNKNOWN,
502 GNUNET_YES)))
444 goto free_buffer; 503 goto free_buffer;
445 504
446 message = create_message (GNUNET_MESSENGER_KIND_UNKNOWN); 505 message = create_message (GNUNET_MESSENGER_KIND_UNKNOWN);
447 506
448 const int decoding = decode_message (message, entry->length, buffer, GNUNET_YES, NULL); 507 const int decoding = decode_message (message, entry->length, buffer,
508 GNUNET_YES, NULL);
449 509
450 struct GNUNET_HashCode check; 510 struct GNUNET_HashCode check;
451 hash_message (message, entry->length, buffer, &check); 511 hash_message (message, entry->length, buffer, &check);
452 512
453 if ((GNUNET_YES != decoding) || (GNUNET_CRYPTO_hash_cmp (hash, &check) != 0)) 513 if ((GNUNET_YES != decoding) || (GNUNET_CRYPTO_hash_cmp (hash, &check) != 0))
454 { 514 {
455 if (GNUNET_YES != GNUNET_CONTAINER_multihashmap_remove (store->entries, hash, entry)) 515 if (GNUNET_YES != GNUNET_CONTAINER_multihashmap_remove (store->entries,
456 GNUNET_log(GNUNET_ERROR_TYPE_WARNING, "Corrupted entry could not be removed from store: %s\n", 516 hash, entry))
457 GNUNET_h2s(hash)); 517 GNUNET_log (GNUNET_ERROR_TYPE_WARNING,
518 "Corrupted entry could not be removed from store: %s\n",
519 GNUNET_h2s (hash));
458 520
459 store->rewrite_entries = GNUNET_YES; 521 store->rewrite_entries = GNUNET_YES;
460 522
461 goto free_message; 523 goto free_message;
462 } 524 }
463 525
464 if (GNUNET_OK == GNUNET_CONTAINER_multihashmap_put (store->messages, hash, message, 526 if (GNUNET_OK == GNUNET_CONTAINER_multihashmap_put (store->messages, hash,
527 message,
465 GNUNET_CONTAINER_MULTIHASHMAPOPTION_UNIQUE_FAST)) 528 GNUNET_CONTAINER_MULTIHASHMAPOPTION_UNIQUE_FAST))
466 goto free_buffer; 529 goto free_buffer;
467 530
468free_message: destroy_message (message); 531 free_message : destroy_message (message);
469 message = NULL; 532 message = NULL;
470 533
471free_buffer: 534free_buffer:
472 GNUNET_free(buffer); 535 GNUNET_free (buffer);
473 536
474 return message; 537 return message;
475} 538}
476 539
540
477const struct GNUNET_MESSENGER_MessageLink* 541const struct GNUNET_MESSENGER_MessageLink*
478get_store_message_link (struct GNUNET_MESSENGER_MessageStore *store, 542get_store_message_link (struct GNUNET_MESSENGER_MessageStore *store,
479 const struct GNUNET_HashCode *hash, 543 const struct GNUNET_HashCode *hash,
@@ -482,21 +546,26 @@ get_store_message_link (struct GNUNET_MESSENGER_MessageStore *store,
482 if (deleted_only) 546 if (deleted_only)
483 goto get_link; 547 goto get_link;
484 548
485 const struct GNUNET_MESSENGER_Message *message = get_store_message(store, hash); 549 const struct GNUNET_MESSENGER_Message *message = get_store_message (store,
550 hash);
486 551
487 if (!message) 552 if (! message)
488 goto get_link; 553 goto get_link;
489 554
490 static struct GNUNET_MESSENGER_MessageLink link; 555 static struct GNUNET_MESSENGER_MessageLink link;
491 556
492 GNUNET_memcpy(&(link.first), &(message->header.previous), sizeof(link.first)); 557 GNUNET_memcpy (&(link.first), &(message->header.previous),
558 sizeof(link.first));
493 559
494 link.multiple = GNUNET_MESSENGER_KIND_MERGE == message->header.kind? GNUNET_YES : GNUNET_NO; 560 link.multiple = GNUNET_MESSENGER_KIND_MERGE == message->header.kind?
561 GNUNET_YES : GNUNET_NO;
495 562
496 if (GNUNET_YES == link.multiple) 563 if (GNUNET_YES == link.multiple)
497 GNUNET_memcpy(&(link.second), &(message->body.merge.previous), sizeof(link.second)); 564 GNUNET_memcpy (&(link.second), &(message->body.merge.previous),
565 sizeof(link.second));
498 else 566 else
499 GNUNET_memcpy(&(link.second), &(message->header.previous), sizeof(link.second)); 567 GNUNET_memcpy (&(link.second), &(message->header.previous),
568 sizeof(link.second));
500 569
501 return &link; 570 return &link;
502 571
@@ -504,78 +573,95 @@ get_link:
504 return GNUNET_CONTAINER_multihashmap_get (store->links, hash); 573 return GNUNET_CONTAINER_multihashmap_get (store->links, hash);
505} 574}
506 575
576
507int 577int
508put_store_message (struct GNUNET_MESSENGER_MessageStore *store, 578put_store_message (struct GNUNET_MESSENGER_MessageStore *store,
509 const struct GNUNET_HashCode *hash, 579 const struct GNUNET_HashCode *hash,
510 struct GNUNET_MESSENGER_Message *message) 580 struct GNUNET_MESSENGER_Message *message)
511{ 581{
512 GNUNET_assert((store) && (hash) && (message)); 582 GNUNET_assert ((store) && (hash) && (message));
513 583
514 return GNUNET_CONTAINER_multihashmap_put (store->messages, hash, message, 584 return GNUNET_CONTAINER_multihashmap_put (store->messages, hash, message,
515 GNUNET_CONTAINER_MULTIHASHMAPOPTION_UNIQUE_FAST); 585 GNUNET_CONTAINER_MULTIHASHMAPOPTION_UNIQUE_FAST);
516} 586}
517 587
588
518static void 589static void
519add_link (struct GNUNET_MESSENGER_MessageStore *store, 590add_link (struct GNUNET_MESSENGER_MessageStore *store,
520 const struct GNUNET_HashCode *hash, 591 const struct GNUNET_HashCode *hash,
521 const struct GNUNET_MESSENGER_Message *message) 592 const struct GNUNET_MESSENGER_Message *message)
522{ 593{
523 struct GNUNET_MESSENGER_MessageLink *link = GNUNET_new(struct GNUNET_MESSENGER_MessageLink); 594 struct GNUNET_MESSENGER_MessageLink *link = GNUNET_new (struct
595 GNUNET_MESSENGER_MessageLink);
524 596
525 GNUNET_memcpy(&(link->first), &(message->header.previous), sizeof(link->first)); 597 GNUNET_memcpy (&(link->first), &(message->header.previous),
598 sizeof(link->first));
526 599
527 link->multiple = GNUNET_MESSENGER_KIND_MERGE == message->header.kind? GNUNET_YES : GNUNET_NO; 600 link->multiple = GNUNET_MESSENGER_KIND_MERGE == message->header.kind?
601 GNUNET_YES : GNUNET_NO;
528 602
529 if (GNUNET_YES == link->multiple) 603 if (GNUNET_YES == link->multiple)
530 GNUNET_memcpy(&(link->second), &(message->body.merge.previous), sizeof(link->second)); 604 GNUNET_memcpy (&(link->second), &(message->body.merge.previous),
605 sizeof(link->second));
531 else 606 else
532 GNUNET_memcpy(&(link->second), &(message->header.previous), sizeof(link->second)); 607 GNUNET_memcpy (&(link->second), &(message->header.previous),
608 sizeof(link->second));
533 609
534 if (GNUNET_OK != GNUNET_CONTAINER_multihashmap_put(store->links, hash, link, 610 if (GNUNET_OK != GNUNET_CONTAINER_multihashmap_put (store->links, hash, link,
535 GNUNET_CONTAINER_MULTIHASHMAPOPTION_UNIQUE_FAST)) 611 GNUNET_CONTAINER_MULTIHASHMAPOPTION_UNIQUE_FAST))
536 GNUNET_free(link); 612 GNUNET_free (link);
537} 613}
538 614
615
539int 616int
540delete_store_message (struct GNUNET_MESSENGER_MessageStore *store, 617delete_store_message (struct GNUNET_MESSENGER_MessageStore *store,
541 const struct GNUNET_HashCode *hash) 618 const struct GNUNET_HashCode *hash)
542{ 619{
543 GNUNET_assert((store) && (hash)); 620 GNUNET_assert ((store) && (hash));
544 621
545 const struct GNUNET_MESSENGER_MessageEntry *entry = GNUNET_CONTAINER_multihashmap_get (store->entries, hash); 622 const struct GNUNET_MESSENGER_MessageEntry *entry =
623 GNUNET_CONTAINER_multihashmap_get (store->entries, hash);
546 624
547 if (!entry) 625 if (! entry)
548 goto clear_memory; 626 goto clear_memory;
549 627
550 const struct GNUNET_MESSENGER_Message *message = get_store_message(store, hash); 628 const struct GNUNET_MESSENGER_Message *message = get_store_message (store,
629 hash);
551 630
552 if (message) 631 if (message)
553 add_link (store, hash, message); 632 add_link (store, hash, message);
554 633
555 if (!store->storage_messages) 634 if (! store->storage_messages)
556 goto clear_entry; 635 goto clear_entry;
557 636
558 if (entry->offset != GNUNET_DISK_file_seek (store->storage_messages, entry->offset, GNUNET_DISK_SEEK_SET)) 637 if (entry->offset != GNUNET_DISK_file_seek (store->storage_messages,
638 entry->offset,
639 GNUNET_DISK_SEEK_SET))
559 return GNUNET_SYSERR; 640 return GNUNET_SYSERR;
560 641
561 char *clear_buffer = GNUNET_malloc(entry->length); 642 char *clear_buffer = GNUNET_malloc (entry->length);
562 643
563 if (!clear_buffer) 644 if (! clear_buffer)
564 return GNUNET_SYSERR; 645 return GNUNET_SYSERR;
565 646
566 GNUNET_CRYPTO_zero_keys (clear_buffer, entry->length); 647 GNUNET_CRYPTO_zero_keys (clear_buffer, entry->length);
567 648
568 if ((entry->length != GNUNET_DISK_file_write (store->storage_messages, clear_buffer, entry->length)) || (GNUNET_OK 649 if ((entry->length != GNUNET_DISK_file_write (store->storage_messages,
569 != GNUNET_DISK_file_sync (store->storage_messages))) 650 clear_buffer, entry->length)) ||
651 (GNUNET_OK
652 !=
653 GNUNET_DISK_file_sync (
654 store->storage_messages)))
570 { 655 {
571 GNUNET_free(clear_buffer); 656 GNUNET_free (clear_buffer);
572 return GNUNET_SYSERR; 657 return GNUNET_SYSERR;
573 } 658 }
574 659
575 GNUNET_free(clear_buffer); 660 GNUNET_free (clear_buffer);
576 661
577clear_entry: 662clear_entry:
578 if (GNUNET_YES == GNUNET_CONTAINER_multihashmap_remove (store->entries, hash, entry)) 663 if (GNUNET_YES == GNUNET_CONTAINER_multihashmap_remove (store->entries, hash,
664 entry))
579 store->rewrite_entries = GNUNET_YES; 665 store->rewrite_entries = GNUNET_YES;
580 666
581clear_memory: 667clear_memory: