aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--TODO1
-rw-r--r--src/fs/Makefile.am1
-rw-r--r--src/fs/fs.h140
-rw-r--r--src/fs/fs_file_information.c572
-rw-r--r--src/include/Makefile.am1
-rw-r--r--src/include/gnunet_bio_lib.h281
-rw-r--r--src/include/gnunet_disk_lib.h10
-rw-r--r--src/include/gnunet_fs_service.h32
-rw-r--r--src/include/gnunet_util_lib.h1
-rw-r--r--src/util/Makefile.am1
-rw-r--r--src/util/bio.c545
-rw-r--r--src/util/container_bloomfilter.c10
-rw-r--r--src/util/disk.c8
-rw-r--r--src/util/pseudonym.c2
14 files changed, 1579 insertions, 26 deletions
diff --git a/TODO b/TODO
index 8b400d5de..94fc5d4e5 100644
--- a/TODO
+++ b/TODO
@@ -1,6 +1,7 @@
1Implementable right now (but not necessarily important), with caveats 1Implementable right now (but not necessarily important), with caveats
2(unavailable components that will limit what can be implemented right 2(unavailable components that will limit what can be implemented right
3away), in order in which they will likely be done: 3away), in order in which they will likely be done:
4* Buffered IO library (extend gnunet_disk_lib.h?)
4* TESTING 5* TESTING
5* FS (DHT not available) 6* FS (DHT not available)
6* SETUP 7* SETUP
diff --git a/src/fs/Makefile.am b/src/fs/Makefile.am
index 9fca261cb..db9567fb1 100644
--- a/src/fs/Makefile.am
+++ b/src/fs/Makefile.am
@@ -24,6 +24,7 @@ libgnunetfs_la_SOURCES = \
24 24
25libgnunetfs_la_LIBADD = \ 25libgnunetfs_la_LIBADD = \
26 $(top_builddir)/src/util/libgnunetutil.la \ 26 $(top_builddir)/src/util/libgnunetutil.la \
27 -lextractor \
27 $(GN_LIBINTL) $(XLIB) 28 $(GN_LIBINTL) $(XLIB)
28 29
29libgnunetfs_la_LDFLAGS = \ 30libgnunetfs_la_LDFLAGS = \
diff --git a/src/fs/fs.h b/src/fs/fs.h
index 024e0ecc8..0c82d5831 100644
--- a/src/fs/fs.h
+++ b/src/fs/fs.h
@@ -116,14 +116,37 @@ struct GNUNET_FS_Uri
116 * (only in URI-strings). 116 * (only in URI-strings).
117 */ 117 */
118 char **keywords; 118 char **keywords;
119
120 /**
121 * Size of the keywords array.
122 */
119 unsigned int keywordCount; 123 unsigned int keywordCount;
120 } ksk; 124 } ksk;
125
121 struct 126 struct
122 { 127 {
128 /**
129 * Hash of the public key for the namespace.
130 */
123 GNUNET_HashCode namespace; 131 GNUNET_HashCode namespace;
132
133 /**
134 * Human-readable identifier chosen for this
135 * entry in the namespace.
136 */
124 char *identifier; 137 char *identifier;
125 } sks; 138 } sks;
139
140 /**
141 * Information needed to retrieve a file (content-hash-key
142 * plus file size).
143 */
126 struct FileIdentifier chk; 144 struct FileIdentifier chk;
145
146 /**
147 * Information needed to retrieve a file including signed
148 * location (identity of a peer) of the content.
149 */
127 struct Location loc; 150 struct Location loc;
128 } data; 151 } data;
129 152
@@ -134,9 +157,124 @@ struct GNUNET_FS_Uri
134 * Information for a file or directory that is 157 * Information for a file or directory that is
135 * about to be published. 158 * about to be published.
136 */ 159 */
137struct GNUNET_FS_FileInformation 160struct GNUNET_FS_FileInformation
138{ 161{
139 162
163 /**
164 * Files in a directory are kept as a linked list.
165 */
166 struct GNUNET_FS_FileInformation *next;
167
168 /**
169 * If this is a file in a directory, "dir" refers to
170 * the directory; otherwise NULL.
171 */
172 struct GNUNET_FS_FileInformation *dir;
173
174 /**
175 * Pointer kept for the client.
176 */
177 void *client_info;
178
179 /**
180 * Metadata to use for the file.
181 */
182 struct GNUNET_CONTAINER_MetaData *meta;
183
184 /**
185 * Keywords to use for KBlocks.
186 */
187 struct GNUNET_FS_Uri *keywords;
188
189 /**
190 * At what time should the content expire?
191 */
192 struct GNUNET_TIME_Absolute expirationTime;
193
194 /**
195 * Under what filename is this struct serialized
196 * (for operational persistence).
197 */
198 char *serialization;
199
200 /**
201 * How many bytes of this file or directory have been
202 * published so far?
203 */
204 uint64_t publish_offset;
205
206 /**
207 * Data describing either the file or the directory.
208 */
209 union
210 {
211
212 /**
213 * Data for a file.
214 */
215 struct {
216
217 /**
218 * Function that can be used to read the data for the file.
219 */
220 GNUNET_FS_DataReader reader;
221
222 /**
223 * Closure for reader.
224 */
225 void *reader_cls;
226
227 /**
228 * Size of the file (in bytes).
229 */
230 uint64_t file_size;
231
232 /**
233 * Should the file be indexed or inserted?
234 */
235 int do_index;
236
237 } file;
238
239 /**
240 * Data for a directory.
241 */
242 struct {
243
244 /**
245 * Name of the directory.
246 */
247 char *dirname;
248
249 /**
250 * Linked list of entries in the directory.
251 */
252 struct GNUNET_FS_FileInformation *entries;
253
254 /**
255 * Size of the directory itself (in bytes); 0 if the
256 * size has not yet been calculated.
257 */
258 uint64_t dir_size;
259
260 } dir;
261
262 } data;
263
264 /**
265 * Is this struct for a file or directory?
266 */
267 int is_directory;
268
269 /**
270 * Desired anonymity level.
271 */
272 unsigned int anonymity;
273
274 /**
275 * Desired priority (for keeping the content in the DB).
276 */
277 unsigned int priority;
140 278
141}; 279};
142 280
diff --git a/src/fs/fs_file_information.c b/src/fs/fs_file_information.c
index d565f4397..9b806184b 100644
--- a/src/fs/fs_file_information.c
+++ b/src/fs/fs_file_information.c
@@ -22,16 +22,141 @@
22 * @file fs/fs_file_information.c 22 * @file fs/fs_file_information.c
23 * @brief Manage information for publishing directory hierarchies 23 * @brief Manage information for publishing directory hierarchies
24 * @author Christian Grothoff 24 * @author Christian Grothoff
25 *
26 * TODO:
27 * - publishing progress update API (increment offset, serialize)
28 * - serialization/deserialization (& deserialization API)
29 * - metadata filename clean up code
30 * - metadata/ksk generation for directories from contained files
25 */ 31 */
26#include "platform.h" 32#include "platform.h"
33#include <extractor.h>
27#include "gnunet_fs_service.h" 34#include "gnunet_fs_service.h"
28#include "fs.h" 35#include "fs.h"
29 36
30 37
31/** 38/**
39 * Create a temporary file disk to store the current
40 * state of "fi" in.
41 */
42static void
43fi_sync (struct GNUNET_FS_FileInformation * fi)
44{
45 if (NULL == fi->serialization)
46 {
47 fi->serialization = NULL; // FIXME
48 }
49 // FIXME...
50}
51
52
53/**
54 * Load file information from the file to which
55 * it was sync'ed.
56 *
57 * @param filename name of the file to use
58 * @return NULL on error
59 */
60static struct GNUNET_FS_FileInformation *
61fi_load (const char *filename)
62{
63 struct GNUNET_FS_FileInformation *ret;
64 // FIXME!
65 return NULL;
66}
67
68
69/**
70 * Closure for "data_reader_file".
71 */
72struct FileInfo
73{
74 /**
75 * Name of the file to read.
76 */
77 char *filename;
78
79 /**
80 * File descriptor, NULL if it has not yet been opened.
81 */
82 struct GNUNET_DISK_FileHandle *fd;
83};
84
85
86/**
87 * Function that provides data by reading from a file.
88 *
89 * @param cls closure (points to the file information)
90 * @param offset offset to read from; it is possible
91 * that the caller might need to go backwards
92 * a bit at times
93 * @param max maximum number of bytes that should be
94 * copied to buf; readers are not allowed
95 * to provide less data unless there is an error;
96 * a value of "0" will be used at the end to allow
97 * the reader to clean up its internal state
98 * @param buf where the reader should write the data
99 * @param emsg location for the reader to store an error message
100 * @return number of bytes written, usually "max", 0 on error
101 */
102static size_t
103data_reader_file(void *cls,
104 uint64_t offset,
105 size_t max,
106 void *buf,
107 char **emsg)
108{
109 struct FileInfo *fi = cls;
110 ssize_t ret;
111
112 if (max == 0)
113 {
114 if (fi->fd != NULL)
115 GNUNET_DISK_file_close (fi->fd);
116 GNUNET_free (fi->filename);
117 GNUNET_free (fi);
118 return 0;
119 }
120 if (fi->fd == NULL)
121 {
122 fi->fd = GNUNET_DISK_file_open (fi->filename,
123 GNUNET_DISK_OPEN_READ);
124 if (fi->fd == NULL)
125 {
126 GNUNET_asprintf (emsg,
127 _("Could not open file `%s': %s"),
128 fi->filename,
129 STRERROR (errno));
130 return 0;
131 }
132 }
133 GNUNET_DISK_file_seek (fi->fd, offset, GNUNET_DISK_SEEK_SET);
134 ret = GNUNET_DISK_file_read (fi->fd, buf, max);
135 if (ret == -1)
136 {
137 GNUNET_asprintf (emsg,
138 _("Could not read file `%s': %s"),
139 fi->filename,
140 STRERROR (errno));
141 return 0;
142 }
143 if (ret != max)
144 {
145 GNUNET_asprintf (emsg,
146 _("Short read reading from file `%s'!"),
147 fi->filename);
148 return 0;
149 }
150 return max;
151}
152
153
154/**
32 * Create an entry for a file in a publish-structure. 155 * Create an entry for a file in a publish-structure.
33 * 156 *
34 * @param filename name of the file or directory to publish 157 * @param filename name of the file or directory to publish
158 * @param keywords under which keywords should this file be available
159 * directly; can be NULL
35 * @param meta metadata for the file 160 * @param meta metadata for the file
36 * @param do_index GNUNET_YES for index, GNUNET_NO for insertion, 161 * @param do_index GNUNET_YES for index, GNUNET_NO for insertion,
37 * GNUNET_SYSERR for simulation 162 * GNUNET_SYSERR for simulation
@@ -45,21 +170,80 @@
45struct GNUNET_FS_FileInformation * 170struct GNUNET_FS_FileInformation *
46GNUNET_FS_file_information_create_from_file (void *client_info, 171GNUNET_FS_file_information_create_from_file (void *client_info,
47 const char *filename, 172 const char *filename,
173 const struct GNUNET_FS_Uri *keywords,
48 const struct GNUNET_CONTAINER_MetaData *meta, 174 const struct GNUNET_CONTAINER_MetaData *meta,
49 int do_index, 175 int do_index,
50 unsigned int anonymity, 176 unsigned int anonymity,
51 unsigned int priority, 177 unsigned int priority,
52 struct GNUNET_TIME_Absolute expirationTime) 178 struct GNUNET_TIME_Absolute expirationTime)
53{ 179{
54 return NULL; 180 struct FileInfo *fi;
181 struct stat sbuf;
182
183 if (0 != STAT (filename, &sbuf))
184 {
185 GNUNET_log_strerror_file (GNUNET_ERROR_TYPE_WARNING,
186 "stat",
187 filename);
188 return NULL;
189 }
190 fi = GNUNET_malloc (sizeof(struct FileInfo));
191 fi->filename = GNUNET_strdup (filename);
192 return GNUNET_FS_file_information_create_from_reader (client_info,
193 sbuf.st_size,
194 &data_reader_file,
195 fi,
196 keywords,
197 meta,
198 do_index,
199 anonymity,
200 priority,
201 expirationTime);
55} 202}
56 203
204
205/**
206 * Function that provides data by copying from a buffer.
207 *
208 * @param cls closure (points to the buffer)
209 * @param offset offset to read from; it is possible
210 * that the caller might need to go backwards
211 * a bit at times
212 * @param max maximum number of bytes that should be
213 * copied to buf; readers are not allowed
214 * to provide less data unless there is an error;
215 * a value of "0" will be used at the end to allow
216 * the reader to clean up its internal state
217 * @param buf where the reader should write the data
218 * @param emsg location for the reader to store an error message
219 * @return number of bytes written, usually "max", 0 on error
220 */
221static size_t
222data_reader_copy(void *cls,
223 uint64_t offset,
224 size_t max,
225 void *buf,
226 char **emsg)
227{
228 char *data = cls;
229 if (max == 0)
230 {
231 GNUNET_free (data);
232 return 0;
233 }
234 memcpy (buf, &data[offset], max);
235 return max;
236}
237
238
57/** 239/**
58 * Create an entry for a file in a publish-structure. 240 * Create an entry for a file in a publish-structure.
59 * 241 *
60 * @param length length of the file 242 * @param length length of the file
61 * @param data data for the file (should not be used afterwards by 243 * @param data data for the file (should not be used afterwards by
62 * the caller; caller will "free") 244 * the caller; caller will "free")
245 * @param keywords under which keywords should this file be available
246 * directly; can be NULL
63 * @param meta metadata for the file 247 * @param meta metadata for the file
64 * @param do_index GNUNET_YES for index, GNUNET_NO for insertion, 248 * @param do_index GNUNET_YES for index, GNUNET_NO for insertion,
65 * GNUNET_SYSERR for simulation 249 * GNUNET_SYSERR for simulation
@@ -74,13 +258,23 @@ struct GNUNET_FS_FileInformation *
74GNUNET_FS_file_information_create_from_data (void *client_info, 258GNUNET_FS_file_information_create_from_data (void *client_info,
75 uint64_t length, 259 uint64_t length,
76 void *data, 260 void *data,
261 const struct GNUNET_FS_Uri *keywords,
77 const struct GNUNET_CONTAINER_MetaData *meta, 262 const struct GNUNET_CONTAINER_MetaData *meta,
78 int do_index, 263 int do_index,
79 unsigned int anonymity, 264 unsigned int anonymity,
80 unsigned int priority, 265 unsigned int priority,
81 struct GNUNET_TIME_Absolute expirationTime) 266 struct GNUNET_TIME_Absolute expirationTime)
82{ 267{
83 return NULL; 268 return GNUNET_FS_file_information_create_from_reader (client_info,
269 length,
270 &data_reader_copy,
271 data,
272 keywords,
273 meta,
274 do_index,
275 anonymity,
276 priority,
277 expirationTime);
84} 278}
85 279
86 280
@@ -114,10 +308,151 @@ GNUNET_FS_file_information_create_from_reader (void *client_info,
114 unsigned int priority, 308 unsigned int priority,
115 struct GNUNET_TIME_Absolute expirationTime) 309 struct GNUNET_TIME_Absolute expirationTime)
116{ 310{
117 return NULL; 311 struct GNUNET_FS_FileInformation *ret;
312
313 ret = GNUNET_malloc (sizeof (struct GNUNET_FS_FileInformation));
314 ret->client_info = client_info;
315 ret->meta = GNUNET_CONTAINER_meta_data_duplicate (meta);
316 ret->keywords = (keywords == NULL) ? NULL : GNUNET_FS_uri_dup (keywords);
317 ret->expirationTime = expirationTime;
318 ret->data.file.reader = reader;
319 ret->data.file.reader_cls = reader_cls;
320 ret->data.file.do_index = do_index;
321 ret->anonymity = anonymity;
322 ret->priority = priority;
323 fi_sync (ret);
324 return ret;
118} 325}
119 326
120 327
328/**
329 * Closure for "dir_scan_cb".
330 */
331struct DirScanCls
332{
333 /**
334 * Metadata extractors to use.
335 */
336 struct EXTRACTOR_Extractor *extractors;
337
338 /**
339 * Function to call on each directory entry.
340 */
341 GNUNET_FS_FileProcessor proc;
342
343 /**
344 * Closure for proc.
345 */
346 void *proc_cls;
347
348 /**
349 * Scanner to use for subdirectories.
350 */
351 GNUNET_FS_DirectoryScanner scanner;
352
353 /**
354 * Closure for scanner.
355 */
356 void *scanner_cls;
357
358 /**
359 * Set to an error message (if any).
360 */
361 char *emsg;
362
363 /**
364 * Should files be indexed?
365 */
366 int do_index;
367
368 /**
369 * Desired anonymity level.
370 */
371 unsigned int anonymity;
372
373 /**
374 * Desired publishing priority.
375 */
376 unsigned int priority;
377
378 /**
379 * Expiration time for publication.
380 */
381 struct GNUNET_TIME_Absolute expiration;
382};
383
384
385/**
386 * Function called on each entry in a file to
387 * cause default-publishing.
388 * @param cls closure (struct DirScanCls)
389 * @param filename name of the file to be published
390 * @return GNUNET_OK on success, GNUNET_SYSERR to abort
391 */
392static int
393dir_scan_cb (void *cls,
394 const char *filename)
395{
396 struct DirScanCls *dsc = cls;
397 struct stat sbuf;
398 struct GNUNET_FS_FileInformation *fi;
399 struct GNUNET_FS_Uri *ksk_uri;
400 struct GNUNET_FS_Uri *keywords;
401 struct GNUNET_CONTAINER_MetaData *meta;
402
403 if (0 != STAT (filename, &sbuf))
404 {
405 GNUNET_asprintf (&dsc->emsg,
406 _("`%s' failed on file `%s': %s"),
407 "stat",
408 filename,
409 STRERROR (errno));
410 return GNUNET_SYSERR;
411 }
412 if (S_ISDIR (sbuf.st_mode))
413 {
414 fi = GNUNET_FS_file_information_create_from_directory (NULL,
415 filename,
416 dsc->scanner,
417 dsc->scanner_cls,
418 dsc->do_index,
419 dsc->anonymity,
420 dsc->priority,
421 dsc->expiration,
422 &dsc->emsg);
423 if (NULL == fi)
424 {
425 GNUNET_assert (NULL != dsc->emsg);
426 return GNUNET_SYSERR;
427 }
428 }
429 else
430 {
431 meta = GNUNET_CONTAINER_meta_data_create ();
432 GNUNET_CONTAINER_meta_data_extract_from_file (meta,
433 filename,
434 dsc->extractors);
435 // FIXME: remove path from filename in metadata!
436 keywords = GNUNET_FS_uri_ksk_create_from_meta_data (meta);
437 ksk_uri = GNUNET_FS_uri_ksk_canonicalize (keywords);
438 fi = GNUNET_FS_file_information_create_from_file (NULL,
439 filename,
440 ksk_uri,
441 meta,
442 dsc->do_index,
443 dsc->anonymity,
444 dsc->priority,
445 dsc->expiration);
446 GNUNET_CONTAINER_meta_data_destroy (meta);
447 GNUNET_FS_uri_destroy (keywords);
448 GNUNET_FS_uri_destroy (ksk_uri);
449 }
450 dsc->proc (dsc->proc_cls,
451 filename,
452 fi);
453 return GNUNET_OK;
454}
455
121 456
122/** 457/**
123 * Simple, useful default implementation of a directory scanner 458 * Simple, useful default implementation of a directory scanner
@@ -132,6 +467,10 @@ GNUNET_FS_file_information_create_from_reader (void *client_info,
132 * 467 *
133 * @param cls must be of type "struct EXTRACTOR_Extractor*" 468 * @param cls must be of type "struct EXTRACTOR_Extractor*"
134 * @param dirname name of the directory to scan 469 * @param dirname name of the directory to scan
470 * @param do_index should files be indexed or inserted
471 * @param anonymity desired anonymity level
472 * @param priority priority for publishing
473 * @param expirationTime expiration for publication
135 * @param proc function called on each entry 474 * @param proc function called on each entry
136 * @param proc_cls closure for proc 475 * @param proc_cls closure for proc
137 * @param emsg where to store an error message (on errors) 476 * @param emsg where to store an error message (on errors)
@@ -140,10 +479,70 @@ GNUNET_FS_file_information_create_from_reader (void *client_info,
140int 479int
141GNUNET_FS_directory_scanner_default (void *cls, 480GNUNET_FS_directory_scanner_default (void *cls,
142 const char *dirname, 481 const char *dirname,
482 int do_index,
483 unsigned int anonymity,
484 unsigned int priority,
485 struct GNUNET_TIME_Absolute expirationTime,
143 GNUNET_FS_FileProcessor proc, 486 GNUNET_FS_FileProcessor proc,
144 void *proc_cls) 487 void *proc_cls,
488 char **emsg)
145{ 489{
146 return GNUNET_SYSERR; 490 struct EXTRACTOR_Extractor *ex = cls;
491 struct DirScanCls dsc;
492
493 dsc.extractors = ex;
494 dsc.proc = proc;
495 dsc.proc_cls = proc_cls;
496 dsc.scanner = &GNUNET_FS_directory_scanner_default;
497 dsc.scanner_cls = cls;
498 dsc.do_index = do_index;
499 dsc.anonymity = anonymity;
500 dsc.priority = priority;
501 dsc.expiration = expirationTime;
502 if (-1 == GNUNET_DISK_directory_scan (dirname,
503 &dir_scan_cb,
504 &dsc))
505 {
506 GNUNET_assert (NULL != dsc.emsg);
507 *emsg = dsc.emsg;
508 return GNUNET_SYSERR;
509 }
510 return GNUNET_OK;
511}
512
513
514/**
515 * Closure for dirproc function.
516 */
517struct EntryProcCls
518{
519 /**
520 * Linked list of directory entries that is being
521 * created.
522 */
523 struct GNUNET_FS_FileInformation *entries;
524
525};
526
527
528/**
529 * Function that processes a directory entry that
530 * was obtained from the scanner.
531 * @param cls our closure
532 * @param filename name of the file (unused, why there???)
533 * @param fi information for publishing the file
534 */
535static void
536dirproc (void *cls,
537 const char *filename,
538 struct GNUNET_FS_FileInformation *fi)
539{
540 struct EntryProcCls *dc = cls;
541
542 GNUNET_assert (fi->next == NULL);
543 GNUNET_assert (fi->dir == NULL);
544 fi->next = dc->entries;
545 dc->entries = fi;
147} 546}
148 547
149 548
@@ -160,22 +559,61 @@ GNUNET_FS_directory_scanner_default (void *cls,
160 * @param filename name of the top-level file or directory 559 * @param filename name of the top-level file or directory
161 * @param scanner function used to get a list of files in a directory 560 * @param scanner function used to get a list of files in a directory
162 * @param scanner_cls closure for scanner 561 * @param scanner_cls closure for scanner
562 * @param do_index should files in the hierarchy be indexed?
163 * @param anonymity what is the desired anonymity level for sharing? 563 * @param anonymity what is the desired anonymity level for sharing?
164 * @param priority what is the priority for OUR node to 564 * @param priority what is the priority for OUR node to
165 * keep this file available? Use 0 for maximum anonymity and 565 * keep this file available? Use 0 for maximum anonymity and
166 * minimum reliability... 566 * minimum reliability...
167 * @param expirationTime when should this content expire? 567 * @param expirationTime when should this content expire?
568 * @param emsg where to store an error message
168 * @return publish structure entry for the directory, NULL on error 569 * @return publish structure entry for the directory, NULL on error
169 */ 570 */
170struct GNUNET_FS_FileInformation * 571struct GNUNET_FS_FileInformation *
171GNUNET_FS_file_information_create_from_directory (void *client_info, 572GNUNET_FS_file_information_create_from_directory (void *client_info,
573 const char *filename,
172 GNUNET_FS_DirectoryScanner scanner, 574 GNUNET_FS_DirectoryScanner scanner,
173 void *scanner_cls, 575 void *scanner_cls,
576 int do_index,
174 unsigned int anonymity, 577 unsigned int anonymity,
175 unsigned int priority, 578 unsigned int priority,
176 struct GNUNET_TIME_Absolute expirationTime) 579 struct GNUNET_TIME_Absolute expirationTime,
580 char **emsg)
177{ 581{
178 return NULL; 582 struct GNUNET_FS_FileInformation *ret;
583 struct EntryProcCls dc;
584 struct GNUNET_FS_Uri *ksk;
585 struct GNUNET_CONTAINER_MetaData *meta;
586
587 dc.entries = NULL;
588 meta = GNUNET_CONTAINER_meta_data_create ();
589 GNUNET_FS_meta_data_make_directory (meta);
590
591 scanner (scanner_cls,
592 filename,
593 do_index,
594 anonymity,
595 priority,
596 expirationTime,
597 &dirproc,
598 &dc,
599 emsg);
600 ksk = NULL; // FIXME...
601 // FIXME: create meta!
602 ret = GNUNET_FS_file_information_create_empty_directory (client_info,
603 meta,
604 ksk,
605 anonymity,
606 priority,
607 expirationTime);
608 ret->data.dir.entries = dc.entries;
609 while (dc.entries != NULL)
610 {
611 dc.entries->dir = ret;
612 fi_sync (dc.entries);
613 dc.entries = dc.entries->next;
614 }
615 fi_sync (ret);
616 return ret;
179} 617}
180 618
181 619
@@ -203,7 +641,18 @@ GNUNET_FS_file_information_create_empty_directory (void *client_info,
203 unsigned int priority, 641 unsigned int priority,
204 struct GNUNET_TIME_Absolute expirationTime) 642 struct GNUNET_TIME_Absolute expirationTime)
205{ 643{
206 return NULL; 644 struct GNUNET_FS_FileInformation *ret;
645
646 ret = GNUNET_malloc (sizeof (struct GNUNET_FS_FileInformation));
647 ret->client_info = client_info;
648 ret->meta = GNUNET_CONTAINER_meta_data_duplicate (meta);
649 ret->keywords = GNUNET_FS_uri_dup (keywords);
650 ret->expirationTime = expirationTime;
651 ret->is_directory = GNUNET_YES;
652 ret->anonymity = anonymity;
653 ret->priority = priority;
654 fi_sync (ret);
655 return ret;
207} 656}
208 657
209 658
@@ -213,16 +662,30 @@ GNUNET_FS_file_information_create_empty_directory (void *client_info,
213 * "GNUNET_FS_publish_start" already. 662 * "GNUNET_FS_publish_start" already.
214 * 663 *
215 * @param dir the directory 664 * @param dir the directory
216 * @param end the entry to add; the entry must not have been 665 * @param ent the entry to add; the entry must not have been
217 * added to any other directory at this point and 666 * added to any other directory at this point and
218 * must not include "dir" in its structure 667 * must not include "dir" in its structure
219 * @return GNUNET_OK on success, GNUNET_SYSERR on error 668 * @return GNUNET_OK on success, GNUNET_SYSERR on error
220 */ 669 */
221int 670int
222GNUNET_FS_file_information_add (struct GNUNET_FS_FileInformation *dir, 671GNUNET_FS_file_information_add (struct GNUNET_FS_FileInformation *dir,
223 struct GNUNET_FS_FileInformation *end) 672 struct GNUNET_FS_FileInformation *ent)
224{ 673{
225 return GNUNET_SYSERR; 674 if ( (ent->dir != NULL) ||
675 (ent->next != NULL) ||
676 (! dir->is_directory) )
677 {
678 GNUNET_break (0);
679 return GNUNET_SYSERR;
680 }
681 ent->dir = dir;
682 ent->next = dir->data.dir.entries;
683 dir->data.dir.entries = ent;
684 dir->data.dir.dir_size = 0;
685 dir->publish_offset = 0;
686 fi_sync (ent);
687 fi_sync (dir);
688 return GNUNET_OK;
226} 689}
227 690
228 691
@@ -245,6 +708,46 @@ GNUNET_FS_file_information_inspect (struct GNUNET_FS_FileInformation *dir,
245 GNUNET_FS_FileInformationProcessor proc, 708 GNUNET_FS_FileInformationProcessor proc,
246 void *proc_cls) 709 void *proc_cls)
247{ 710{
711 struct GNUNET_FS_FileInformation *pos;
712
713 if (dir->is_directory)
714 {
715 proc (proc_cls,
716 dir,
717 dir->data.dir.dir_size,
718 dir->meta,
719 &dir->keywords,
720 &dir->anonymity,
721 &dir->priority,
722 &dir->expirationTime,
723 &dir->client_info);
724 pos = dir->data.dir.entries;
725 while (pos != NULL)
726 {
727 proc (proc_cls,
728 pos,
729 pos->data.dir.dir_size,
730 pos->meta,
731 &pos->keywords,
732 &pos->anonymity,
733 &pos->priority,
734 &pos->expirationTime,
735 &pos->client_info);
736 pos = pos->next;
737 }
738 }
739 else
740 {
741 proc (proc_cls,
742 dir,
743 dir->data.file.file_size,
744 dir->meta,
745 &dir->keywords,
746 &dir->anonymity,
747 &dir->priority,
748 &dir->expirationTime,
749 &dir->client_info);
750 }
248} 751}
249 752
250 753
@@ -263,6 +766,53 @@ GNUNET_FS_file_information_destroy (struct GNUNET_FS_FileInformation *fi,
263 GNUNET_FS_FileInformationProcessor cleaner, 766 GNUNET_FS_FileInformationProcessor cleaner,
264 void *cleaner_cls) 767 void *cleaner_cls)
265{ 768{
769 struct GNUNET_FS_FileInformation *pos;
770
771 if (fi->is_directory)
772 {
773 /* clean up directory */
774 while (NULL != (pos = fi->data.dir.entries))
775 {
776 fi->data.dir.entries = pos->next;
777 GNUNET_FS_file_information_destroy (pos, cleaner, cleaner_cls);
778 }
779 /* clean up client-info */
780 cleaner (cleaner_cls,
781 fi,
782 fi->data.dir.dir_size,
783 fi->meta,
784 &fi->keywords,
785 &fi->anonymity,
786 &fi->priority,
787 &fi->expirationTime,
788 &fi->client_info);
789 GNUNET_free (fi->data.dir.dirname);
790 }
791 else
792 {
793 /* call clean-up function of the reader */
794 fi->data.file.reader (fi->data.file.reader_cls, 0, 0, NULL, NULL);
795 /* clean up client-info */
796 cleaner (cleaner_cls,
797 fi,
798 fi->data.file.file_size,
799 fi->meta,
800 &fi->keywords,
801 &fi->anonymity,
802 &fi->priority,
803 &fi->expirationTime,
804 &fi->client_info);
805 }
806
807 /* clean up serialization */
808 if (0 != UNLINK (fi->serialization))
809 GNUNET_log_strerror_file (GNUNET_ERROR_TYPE_WARNING,
810 "unlink",
811 fi->serialization);
812 GNUNET_FS_uri_destroy (fi->keywords);
813 GNUNET_CONTAINER_meta_data_destroy (fi->meta);
814 GNUNET_free (fi->serialization);
815 GNUNET_free (fi);
266} 816}
267 817
268 818
diff --git a/src/include/Makefile.am b/src/include/Makefile.am
index 69954fd30..008d6a180 100644
--- a/src/include/Makefile.am
+++ b/src/include/Makefile.am
@@ -13,6 +13,7 @@ nodist_gnunetinclude_HEADERS = \
13 13
14gnunetinclude_HEADERS = \ 14gnunetinclude_HEADERS = \
15 gnunet_arm_service.h \ 15 gnunet_arm_service.h \
16 gnunet_bio_lib.h \
16 gnunet_client_lib.h \ 17 gnunet_client_lib.h \
17 gnunet_common.h \ 18 gnunet_common.h \
18 gnunet_constants.h \ 19 gnunet_constants.h \
diff --git a/src/include/gnunet_bio_lib.h b/src/include/gnunet_bio_lib.h
new file mode 100644
index 000000000..02b04570e
--- /dev/null
+++ b/src/include/gnunet_bio_lib.h
@@ -0,0 +1,281 @@
1/*
2 This file is part of GNUnet.
3 (C) 2009 Christian Grothoff (and other contributing authors)
4
5 GNUnet is free software; you can redistribute it and/or modify
6 it under the terms of the GNU General Public License as published
7 by the Free Software Foundation; either version 2, or (at your
8 option) any later version.
9
10 GNUnet is distributed in the hope that it will be useful, but
11 WITHOUT ANY WARRANTY; without even the implied warranty of
12 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13 General Public License for more details.
14
15 You should have received a copy of the GNU General Public License
16 along with GNUnet; see the file COPYING. If not, write to the
17 Free Software Foundation, Inc., 59 Temple Place - Suite 330,
18 Boston, MA 02111-1307, USA.
19*/
20
21/**
22 * @file include/gnunet_bio_lib.h
23 * @brief buffered IO API
24 * @author Christian Grothoff
25 */
26
27#ifndef GNUNET_BIO_LIB_H
28#define GNUNET_BIO_LIB_H
29
30#include "gnunet_container_lib.h"
31
32#ifdef __cplusplus
33extern "C"
34{
35#if 0 /* keep Emacsens' auto-indent happy */
36}
37#endif
38#endif
39
40/**
41 * Handle for buffered reading.
42 */
43struct GNUNET_BIO_ReadHandle;
44
45
46/**
47 * Open a file for reading.
48 *
49 * @param fn file name to be opened
50 * @return IO handle on success, NULL on error
51 */
52struct GNUNET_BIO_ReadHandle *GNUNET_BIO_read_open (const char *fn);
53
54
55/**
56 * Close an open file. Reports if any errors reading
57 * from the file were encountered.
58 *
59 * @param h file handle
60 * @param emsg set to the error message
61 * @return GNUNET_OK on success, GNUNET_SYSERR otherwise
62 */
63int GNUNET_BIO_read_close (struct GNUNET_BIO_ReadHandle *h,
64 char **emsg);
65
66
67/**
68 * Read the contents of a binary file into a buffer.
69 *
70 * @param h handle to an open file
71 * @param what describes what is being read (for error message creation)
72 * @param result the buffer to write the result to
73 * @param len the number of bytes to read
74 * @return len on success, GNUNET_SYSERR on failure
75 */
76ssize_t GNUNET_BIO_read (struct GNUNET_BIO_ReadHandle *h,
77 const char *what,
78 void *result,
79 size_t len);
80
81/**
82 * Read 0-terminated string from a file.
83 *
84 * @param h handle to an open file
85 * @param what describes what is being read (for error message creation)
86 * @param result the buffer to store a pointer to the (allocated) string to
87 * (note that *result could be set to NULL as well)
88 * @return GNUNET_OK on success, GNUNET_SYSERR on failure
89 */
90int GNUNET_BIO_read_string (struct GNUNET_BIO_ReadHandle *h,
91 const char *what,
92 char **result);
93
94
95/**
96 * Read metadata container from a file.
97 *
98 * @param h handle to an open file
99 * @param what describes what is being read (for error message creation)
100 * @param result the buffer to store a pointer to the (allocated) metadata
101 * @return GNUNET_OK on success, GNUNET_SYSERR on failure
102 */
103int GNUNET_BIO_read_meta_data (struct GNUNET_BIO_ReadHandle *h,
104 const char *what,
105 struct GNUNET_CONTAINER_MetaData **result);
106
107
108/**
109 * Read a float.
110 *
111 * @param h hande to open file
112 * @param f address of float to read
113 */
114#define GNUNET_BIO_read_float(h, f) (sizeof(float) == GNUNET_BIO_read (h, __FILE__ "##__LINE__##", f, sizeof(float)))
115
116
117
118/**
119 * Read a double.
120 *
121 * @param h hande to open file
122 * @param f address of double to read
123 */
124#define GNUNET_BIO_read_double(h, f) (sizeof(double) == GNUNET_BIO_read (h, __FILE__ "##__LINE__##", f, sizeof(double)))
125
126
127/**
128 * Read an (u)int32_t.
129 *
130 * @param h hande to open file
131 * @param what describes what is being read (for error message creation)
132 * @param i address of 32-bit integer to read
133 * @return GNUNET_OK on success, GNUNET_SYSERR on error
134 */
135int GNUNET_BIO_read_int32__ (struct GNUNET_BIO_ReadHandle *h,
136 const char *what,
137 int32_t *i);
138
139
140/**
141 * Read an (u)int32_t.
142 *
143 * @param h hande to open file
144 * @param i address of 32-bit integer to read
145 */
146#define GNUNET_BIO_read_int32(h, i) GNUNET_BIO_read_int32__ (h, __FILE__ "##__LINE__##", (int32_t*) i)
147
148
149/**
150 * Read an (u)int64_t.
151 *
152 * @param h hande to open file
153 * @param what describes what is being read (for error message creation)
154 * @param i address of 64-bit integer to read
155 * @return GNUNET_OK on success, GNUNET_SYSERR on error
156 */
157int GNUNET_BIO_read_int64__ (struct GNUNET_BIO_ReadHandle *h,
158 const char *what,
159 int64_t *i);
160
161
162/**
163 * Read an (u)int64_t.
164 *
165 * @param h hande to open file
166 * @param i address of 64-bit integer to read
167 */
168#define GNUNET_BIO_read_int64(h, i) (sizeof(int64_t) == GNUNET_BIO_read (h, __FILE__ "##__LINE__##", (int64_t*) i, sizeof(int64_t)))
169
170
171/**
172 * Handle for buffered writing.
173 */
174struct GNUNET_BIO_WriteHandle;
175/**
176 * Open a file for writing.
177 *
178 * @param fn file name to be opened
179 * @return IO handle on success, NULL on error
180 */
181struct GNUNET_BIO_WriteHandle *GNUNET_BIO_write_open (const char *fn);
182
183
184/**
185 * Close an open file for writing.
186 *
187 * @param h file handle
188 * @return GNUNET_OK on success, GNUNET_SYSERR otherwise
189 */
190int GNUNET_BIO_write_close (struct GNUNET_BIO_WriteHandle *h);
191
192
193/**
194 * Write a buffer to a file.
195 *
196 * @param h handle to open file
197 * @param buffer the data to write
198 * @param n number of bytes to write
199 * @return GNUNET_OK on success, GNUNET_SYSERR on error
200 */
201ssize_t GNUNET_BIO_write (struct GNUNET_BIO_WriteHandle *h,
202 const void *buffer,
203 size_t n);
204
205
206/**
207 * Write a string to a file.
208 *
209 * @param h handle to open file
210 * @param s string to write (can be NULL)
211 * @return GNUNET_OK on success, GNUNET_SYSERR on error
212 */
213int GNUNET_BIO_write_string (struct GNUNET_BIO_WriteHandle *h,
214 const char *s);
215
216
217
218
219/**
220 * Write metadata container to a file.
221 *
222 * @param h handle to open file
223 * @param m metadata to write
224 * @return GNUNET_OK on success, GNUNET_SYSERR on error
225 */
226int GNUNET_BIO_write_meta_data (struct GNUNET_BIO_WriteHandle *h,
227 const struct GNUNET_CONTAINER_MetaData *m);
228
229
230
231/**
232 * Write a float.
233 *
234 * @param h hande to open file
235 * @param f float to write (must be a variable)
236 */
237#define GNUNET_BIO_write_float(h, f) (sizeof(float) == GNUNET_BIO_write (h, &f, sizeof(float)))
238
239
240
241/**
242 * Write a double.
243 *
244 * @param h hande to open file
245 * @param f double to write (must be a variable)
246 */
247#define GNUNET_BIO_write_float(h, f) (sizeof(double) == GNUNET_BIO_write (h, &f, sizeof(double)))
248
249
250/**
251 * Write an (u)int32_t.
252 *
253 * @param h hande to open file
254 * @param i address of 32-bit integer to write
255 * @return GNUNET_OK on success, GNUNET_SYSERR on error
256 */
257int GNUNET_BIO_write_int32 (struct GNUNET_BIO_ReadHandle *h,
258 int32_t i);
259
260
261/**
262 * Write an (u)int64_t.
263 *
264 * @param h hande to open file
265 * @param i address of 64-bit integer to write
266 * @return GNUNET_OK on success, GNUNET_SYSERR on error
267 */
268int GNUNET_BIO_write_int64 (struct GNUNET_BIO_ReadHandle *h,
269 int64_t i);
270
271
272#if 0 /* keep Emacsens' auto-indent happy */
273{
274#endif
275#ifdef __cplusplus
276}
277#endif
278
279/* ifndef GNUNET_BIO_LIB_H */
280#endif
281/* end of gnunet_bio_lib.h */
diff --git a/src/include/gnunet_disk_lib.h b/src/include/gnunet_disk_lib.h
index a5f279f05..f4fd6f36b 100644
--- a/src/include/gnunet_disk_lib.h
+++ b/src/include/gnunet_disk_lib.h
@@ -72,7 +72,12 @@ extern "C"
72#define GNUNET_DISK_PERM_OTHER_WRITE 128 72#define GNUNET_DISK_PERM_OTHER_WRITE 128
73#define GNUNET_DISK_PERM_OTHER_EXEC 256 73#define GNUNET_DISK_PERM_OTHER_EXEC 256
74 74
75enum GNUNET_DISK_Seek {GNUNET_SEEK_SET, GNUNET_SEEK_CUR, GNUNET_SEEK_END}; 75enum GNUNET_DISK_Seek
76 {
77 GNUNET_DISK_SEEK_SET,
78 GNUNET_DISK_SEEK_CUR,
79 GNUNET_DISK_SEEK_END
80 };
76 81
77struct GNUNET_DISK_FileHandle; 82struct GNUNET_DISK_FileHandle;
78 83
@@ -250,7 +255,8 @@ int GNUNET_DISK_file_copy (const char *src, const char *dst);
250 * @return the number of files found, -1 on error 255 * @return the number of files found, -1 on error
251 */ 256 */
252int GNUNET_DISK_directory_scan (const char *dirName, 257int GNUNET_DISK_directory_scan (const char *dirName,
253 GNUNET_FileNameCallback callback, void *data); 258 GNUNET_FileNameCallback callback,
259 void *data);
254 260
255 261
256/** 262/**
diff --git a/src/include/gnunet_fs_service.h b/src/include/gnunet_fs_service.h
index 236bdd083..45cd1e77e 100644
--- a/src/include/gnunet_fs_service.h
+++ b/src/include/gnunet_fs_service.h
@@ -1418,6 +1418,8 @@ typedef int (*GNUNET_FS_FileInformationProcessor)(void *cls,
1418 * Create an entry for a file in a publish-structure. 1418 * Create an entry for a file in a publish-structure.
1419 * 1419 *
1420 * @param filename name of the file or directory to publish 1420 * @param filename name of the file or directory to publish
1421 * @param keywords under which keywords should this file be available
1422 * directly; can be NULL
1421 * @param meta metadata for the file 1423 * @param meta metadata for the file
1422 * @param do_index GNUNET_YES for index, GNUNET_NO for insertion, 1424 * @param do_index GNUNET_YES for index, GNUNET_NO for insertion,
1423 * GNUNET_SYSERR for simulation 1425 * GNUNET_SYSERR for simulation
@@ -1431,6 +1433,7 @@ typedef int (*GNUNET_FS_FileInformationProcessor)(void *cls,
1431struct GNUNET_FS_FileInformation * 1433struct GNUNET_FS_FileInformation *
1432GNUNET_FS_file_information_create_from_file (void *client_info, 1434GNUNET_FS_file_information_create_from_file (void *client_info,
1433 const char *filename, 1435 const char *filename,
1436 const struct GNUNET_FS_Uri *keywords,
1434 const struct GNUNET_CONTAINER_MetaData *meta, 1437 const struct GNUNET_CONTAINER_MetaData *meta,
1435 int do_index, 1438 int do_index,
1436 unsigned int anonymity, 1439 unsigned int anonymity,
@@ -1444,6 +1447,8 @@ GNUNET_FS_file_information_create_from_file (void *client_info,
1444 * @param length length of the file 1447 * @param length length of the file
1445 * @param data data for the file (should not be used afterwards by 1448 * @param data data for the file (should not be used afterwards by
1446 * the caller; caller will "free") 1449 * the caller; caller will "free")
1450 * @param keywords under which keywords should this file be available
1451 * directly; can be NULL
1447 * @param meta metadata for the file 1452 * @param meta metadata for the file
1448 * @param do_index GNUNET_YES for index, GNUNET_NO for insertion, 1453 * @param do_index GNUNET_YES for index, GNUNET_NO for insertion,
1449 * GNUNET_SYSERR for simulation 1454 * GNUNET_SYSERR for simulation
@@ -1458,6 +1463,7 @@ struct GNUNET_FS_FileInformation *
1458GNUNET_FS_file_information_create_from_data (void *client_info, 1463GNUNET_FS_file_information_create_from_data (void *client_info,
1459 uint64_t length, 1464 uint64_t length,
1460 void *data, 1465 void *data,
1466 const struct GNUNET_FS_Uri *keywords,
1461 const struct GNUNET_CONTAINER_MetaData *meta, 1467 const struct GNUNET_CONTAINER_MetaData *meta,
1462 int do_index, 1468 int do_index,
1463 unsigned int anonymity, 1469 unsigned int anonymity,
@@ -1539,6 +1545,10 @@ typedef void (*GNUNET_FS_FileProcessor)(void *cls,
1539 * 1545 *
1540 * @param cls closure 1546 * @param cls closure
1541 * @param dirname name of the directory to scan 1547 * @param dirname name of the directory to scan
1548 * @param do_index should files be indexed or inserted
1549 * @param anonymity desired anonymity level
1550 * @param priority priority for publishing
1551 * @param expirationTime expiration for publication
1542 * @param proc function to call on each entry 1552 * @param proc function to call on each entry
1543 * @param proc_cls closure for proc 1553 * @param proc_cls closure for proc
1544 * @param emsg where to store an error message (on errors) 1554 * @param emsg where to store an error message (on errors)
@@ -1546,6 +1556,10 @@ typedef void (*GNUNET_FS_FileProcessor)(void *cls,
1546 */ 1556 */
1547typedef int (*GNUNET_FS_DirectoryScanner)(void *cls, 1557typedef int (*GNUNET_FS_DirectoryScanner)(void *cls,
1548 const char *dirname, 1558 const char *dirname,
1559 int do_index,
1560 unsigned int anonymity,
1561 unsigned int priority,
1562 struct GNUNET_TIME_Absolute expirationTime,
1549 GNUNET_FS_FileProcessor proc, 1563 GNUNET_FS_FileProcessor proc,
1550 void *proc_cls, 1564 void *proc_cls,
1551 char **emsg); 1565 char **emsg);
@@ -1565,6 +1579,10 @@ typedef int (*GNUNET_FS_DirectoryScanner)(void *cls,
1565 * 1579 *
1566 * @param cls must be of type "struct EXTRACTOR_Extractor*" 1580 * @param cls must be of type "struct EXTRACTOR_Extractor*"
1567 * @param dirname name of the directory to scan 1581 * @param dirname name of the directory to scan
1582 * @param do_index should files be indexed or inserted
1583 * @param anonymity desired anonymity level
1584 * @param priority priority for publishing
1585 * @param expirationTime expiration for publication
1568 * @param proc function called on each entry 1586 * @param proc function called on each entry
1569 * @param proc_cls closure for proc 1587 * @param proc_cls closure for proc
1570 * @param emsg where to store an error message (on errors) 1588 * @param emsg where to store an error message (on errors)
@@ -1573,8 +1591,13 @@ typedef int (*GNUNET_FS_DirectoryScanner)(void *cls,
1573int 1591int
1574GNUNET_FS_directory_scanner_default (void *cls, 1592GNUNET_FS_directory_scanner_default (void *cls,
1575 const char *dirname, 1593 const char *dirname,
1594 int do_index,
1595 unsigned int anonymity,
1596 unsigned int priority,
1597 struct GNUNET_TIME_Absolute expirationTime,
1576 GNUNET_FS_FileProcessor proc, 1598 GNUNET_FS_FileProcessor proc,
1577 void *proc_cls); 1599 void *proc_cls,
1600 char **emsg);
1578 1601
1579 1602
1580/** 1603/**
@@ -1590,20 +1613,25 @@ GNUNET_FS_directory_scanner_default (void *cls,
1590 * @param filename name of the top-level file or directory 1613 * @param filename name of the top-level file or directory
1591 * @param scanner function used to get a list of files in a directory 1614 * @param scanner function used to get a list of files in a directory
1592 * @param scanner_cls closure for scanner 1615 * @param scanner_cls closure for scanner
1616 * @param do_index should files in the hierarchy be indexed?
1593 * @param anonymity what is the desired anonymity level for sharing? 1617 * @param anonymity what is the desired anonymity level for sharing?
1594 * @param priority what is the priority for OUR node to 1618 * @param priority what is the priority for OUR node to
1595 * keep this file available? Use 0 for maximum anonymity and 1619 * keep this file available? Use 0 for maximum anonymity and
1596 * minimum reliability... 1620 * minimum reliability...
1597 * @param expirationTime when should this content expire? 1621 * @param expirationTime when should this content expire?
1622 * @param emsg where to store an error message
1598 * @return publish structure entry for the directory, NULL on error 1623 * @return publish structure entry for the directory, NULL on error
1599 */ 1624 */
1600struct GNUNET_FS_FileInformation * 1625struct GNUNET_FS_FileInformation *
1601GNUNET_FS_file_information_create_from_directory (void *client_info, 1626GNUNET_FS_file_information_create_from_directory (void *client_info,
1627 const char *filename,
1602 GNUNET_FS_DirectoryScanner scanner, 1628 GNUNET_FS_DirectoryScanner scanner,
1603 void *scanner_cls, 1629 void *scanner_cls,
1630 int do_index,
1604 unsigned int anonymity, 1631 unsigned int anonymity,
1605 unsigned int priority, 1632 unsigned int priority,
1606 struct GNUNET_TIME_Absolute expirationTime); 1633 struct GNUNET_TIME_Absolute expirationTime,
1634 char **emsg);
1607 1635
1608 1636
1609/** 1637/**
diff --git a/src/include/gnunet_util_lib.h b/src/include/gnunet_util_lib.h
index fe382be3f..6bb87bf4d 100644
--- a/src/include/gnunet_util_lib.h
+++ b/src/include/gnunet_util_lib.h
@@ -37,6 +37,7 @@ extern "C"
37#endif 37#endif
38 38
39#include "gnunet_common.h" 39#include "gnunet_common.h"
40#include "gnunet_bio_lib.h"
40#include "gnunet_client_lib.h" 41#include "gnunet_client_lib.h"
41#include "gnunet_configuration_lib.h" 42#include "gnunet_configuration_lib.h"
42#include "gnunet_connection_lib.h" 43#include "gnunet_connection_lib.h"
diff --git a/src/util/Makefile.am b/src/util/Makefile.am
index 46d1c3a7a..f6c1783a6 100644
--- a/src/util/Makefile.am
+++ b/src/util/Makefile.am
@@ -15,6 +15,7 @@ endif
15lib_LTLIBRARIES = libgnunetutil.la 15lib_LTLIBRARIES = libgnunetutil.la
16 16
17libgnunetutil_la_SOURCES = \ 17libgnunetutil_la_SOURCES = \
18 bio.c \
18 client.c \ 19 client.c \
19 common_allocation.c \ 20 common_allocation.c \
20 common_endian.c \ 21 common_endian.c \
diff --git a/src/util/bio.c b/src/util/bio.c
new file mode 100644
index 000000000..060b6f94b
--- /dev/null
+++ b/src/util/bio.c
@@ -0,0 +1,545 @@
1/*
2 This file is part of GNUnet.
3 (C) 2006, 2009 Christian Grothoff (and other contributing authors)
4
5 GNUnet is free software; you can redistribute it and/or modify
6 it under the terms of the GNU General Public License as published
7 by the Free Software Foundation; either version 2, or (at your
8 option) any later version.
9
10 GNUnet is distributed in the hope that it will be useful, but
11 WITHOUT ANY WARRANTY; without even the implied warranty of
12 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13 General Public License for more details.
14
15 You should have received a copy of the GNU General Public License
16 along with GNUnet; see the file COPYING. If not, write to the
17 Free Software Foundation, Inc., 59 Temple Place - Suite 330,
18 Boston, MA 02111-1307, USA.
19*/
20
21
22/**
23 * @file util/bio.c
24 * @brief functions for buffering IO
25 * @author Christian Grothoff
26 */
27#include "platform.h"
28#include "gnunet_bio_lib.h"
29
30
31/**
32 * Handle for buffered reading.
33 */
34struct GNUNET_BIO_ReadHandle
35{
36};
37
38
39/**
40 * Open a file for reading.
41 *
42 * @param fn file name to be opened
43 * @return IO handle on success, NULL on error
44 */
45struct GNUNET_BIO_ReadHandle *GNUNET_BIO_read_open (const char *fn)
46{
47 return NULL;
48}
49
50
51/**
52 * Close an open file. Reports if any errors reading
53 * from the file were encountered.
54 *
55 * @param h file handle
56 * @param emsg set to the error message
57 * @return GNUNET_OK on success, GNUNET_SYSERR otherwise
58 */
59int GNUNET_BIO_read_close (struct GNUNET_BIO_ReadHandle *h,
60 char **emsg)
61{
62 return GNUNET_SYSERR;
63}
64
65
66/**
67 * Read the contents of a binary file into a buffer.
68 *
69 * @param h handle to an open file
70 * @param what describes what is being read (for error message creation)
71 * @param result the buffer to write the result to
72 * @param len the number of bytes to read
73 * @return len on success, GNUNET_SYSERR on failure
74 */
75ssize_t GNUNET_BIO_read (struct GNUNET_BIO_ReadHandle *h,
76 const char *what,
77 void *result,
78 size_t len)
79{
80}
81
82
83/**
84 * Read 0-terminated string from a file.
85 *
86 * @param h handle to an open file
87 * @param what describes what is being read (for error message creation)
88 * @param result the buffer to store a pointer to the (allocated) string to
89 * (note that *result could be set to NULL as well)
90 * @return GNUNET_OK on success, GNUNET_SYSERR on failure
91 */
92int GNUNET_BIO_read_string (struct GNUNET_BIO_ReadHandle *h,
93 const char *what,
94 char **result)
95{
96}
97
98
99/**
100 * Read metadata container from a file.
101 *
102 * @param h handle to an open file
103 * @param what describes what is being read (for error message creation)
104 * @param result the buffer to store a pointer to the (allocated) metadata
105 * @return GNUNET_OK on success, GNUNET_SYSERR on failure
106 */
107int GNUNET_BIO_read_meta_data (struct GNUNET_BIO_ReadHandle *h,
108 const char *what,
109 struct GNUNET_CONTAINER_MetaData **result)
110{
111}
112
113
114/**
115 * Read an (u)int32_t.
116 *
117 * @param h hande to open file
118 * @param what describes what is being read (for error message creation)
119 * @param i address of 32-bit integer to read
120 * @return GNUNET_OK on success, GNUNET_SYSERR on error
121 */
122int GNUNET_BIO_read_int32__ (struct GNUNET_BIO_ReadHandle *h,
123 const char *what,
124 int32_t *i);
125
126
127/**
128 * Read an (u)int64_t.
129 *
130 * @param h hande to open file
131 * @param what describes what is being read (for error message creation)
132 * @param i address of 64-bit integer to read
133 * @return GNUNET_OK on success, GNUNET_SYSERR on error
134 */
135int GNUNET_BIO_read_int64__ (struct GNUNET_BIO_ReadHandle *h,
136 const char *what,
137 int64_t *i);
138
139/**
140 * Handle for buffered writing.
141 */
142struct GNUNET_BIO_WriteHandle
143{
144};
145
146
147/**
148 * Open a file for writing.
149 *
150 * @param fn file name to be opened
151 * @return IO handle on success, NULL on error
152 */
153struct GNUNET_BIO_WriteHandle *GNUNET_BIO_write_open (const char *fn)
154{
155 return NULL;
156}
157
158
159/**
160 * Close an open file for writing.
161 *
162 * @param h file handle
163 * @return GNUNET_OK on success, GNUNET_SYSERR otherwise
164 */
165int GNUNET_BIO_write_close (struct GNUNET_BIO_WriteHandle *h);
166
167
168/**
169 * Write a buffer to a file.
170 *
171 * @param h handle to open file
172 * @param buffer the data to write
173 * @param n number of bytes to write
174 * @return GNUNET_OK on success, GNUNET_SYSERR on error
175 */
176ssize_t GNUNET_BIO_write (struct GNUNET_BIO_WriteHandle *h,
177 const void *buffer,
178 size_t n);
179
180
181/**
182 * Write a string to a file.
183 *
184 * @param h handle to open file
185 * @param s string to write (can be NULL)
186 * @return GNUNET_OK on success, GNUNET_SYSERR on error
187 */
188int GNUNET_BIO_write_string (struct GNUNET_BIO_WriteHandle *h,
189 const char *s);
190
191
192
193
194/**
195 * Write metadata container to a file.
196 *
197 * @param h handle to open file
198 * @param m metadata to write
199 * @return GNUNET_OK on success, GNUNET_SYSERR on error
200 */
201int GNUNET_BIO_write_meta_data (struct GNUNET_BIO_WriteHandle *h,
202 const struct GNUNET_CONTAINER_MetaData *m);
203
204
205
206/**
207 * Write a float.
208 *
209 * @param h hande to open file
210 * @param f float to write (must be a variable)
211 */
212#define GNUNET_BIO_write_float(h, f) (sizeof(float) == GNUNET_BIO_write (h, &f, sizeof(float)))
213
214
215
216/**
217 * Write a double.
218 *
219 * @param h hande to open file
220 * @param f double to write (must be a variable)
221 */
222#define GNUNET_BIO_write_float(h, f) (sizeof(double) == GNUNET_BIO_write (h, &f, sizeof(double)))
223
224
225/**
226 * Write an (u)int32_t.
227 *
228 * @param h hande to open file
229 * @param i address of 32-bit integer to write
230 * @return GNUNET_OK on success, GNUNET_SYSERR on error
231 */
232int GNUNET_BIO_write_int32 (struct GNUNET_BIO_ReadHandle *h,
233 int32_t i);
234
235
236/**
237 * Write an (u)int64_t.
238 *
239 * @param h hande to open file
240 * @param i address of 64-bit integer to write
241 * @return GNUNET_OK on success, GNUNET_SYSERR on error
242 */
243int GNUNET_BIO_write_int64 (struct GNUNET_BIO_ReadHandle *h,
244 int64_t i);
245
246
247
248
249
250typedef struct
251{
252 int fd;
253 unsigned int have;
254 unsigned int size;
255 char *buffer;
256} WriteBuffer;
257
258static void
259write_buffered (WriteBuffer * wb, const void *s, unsigned int size)
260{
261 const char *src = s;
262 unsigned int min;
263 unsigned int pos;
264 int ret;
265
266 if (wb->fd == -1)
267 return;
268 pos = 0;
269 do
270 {
271 /* first, just use buffer */
272 min = wb->size - wb->have;
273 if (min > size - pos)
274 min = size - pos;
275 memcpy (&wb->buffer[wb->have], &src[pos], min);
276 pos += min;
277 wb->have += min;
278 if (pos == size)
279 return; /* done */
280 GNUNET_GE_ASSERT (NULL, wb->have == wb->size);
281 ret = WRITE (wb->fd, wb->buffer, wb->size);
282 if (ret != wb->size)
283 {
284 CLOSE (wb->fd);
285 wb->fd = -1;
286 return; /* error */
287 }
288 wb->have = 0;
289 }
290 while (pos < size); /* should always be true */
291}
292
293
294static void
295WRITEINT (WriteBuffer * wb, int val)
296{
297 int big;
298 big = htonl (val);
299 write_buffered (wb, &big, sizeof (int));
300}
301
302static void
303WRITELONG (WriteBuffer * wb, long long val)
304{
305 long long big;
306 big = GNUNET_htonll (val);
307 write_buffered (wb, &big, sizeof (long long));
308}
309
310static void
311writeURI (WriteBuffer * wb, const struct GNUNET_ECRS_URI *uri)
312{
313 char *buf;
314 unsigned int size;
315
316 buf = GNUNET_ECRS_uri_to_string (uri);
317 size = strlen (buf);
318 WRITEINT (wb, size);
319 write_buffered (wb, buf, size);
320 GNUNET_free (buf);
321}
322
323static void
324WRITESTRING (WriteBuffer * wb, const char *name)
325{
326 GNUNET_GE_BREAK (NULL, name != NULL);
327 WRITEINT (wb, strlen (name));
328 write_buffered (wb, name, strlen (name));
329}
330
331static void
332writeMetaData (struct GNUNET_GE_Context *ectx,
333 WriteBuffer * wb, const struct GNUNET_MetaData *meta)
334{
335 unsigned int size;
336 char *buf;
337
338 size = GNUNET_meta_data_get_serialized_size (meta,
339 GNUNET_SERIALIZE_FULL
340 |
341 GNUNET_SERIALIZE_NO_COMPRESS);
342 if (size > 1024 * 1024)
343 size = 1024 * 1024;
344 buf = GNUNET_malloc (size);
345 GNUNET_meta_data_serialize (ectx,
346 meta,
347 buf,
348 size,
349 GNUNET_SERIALIZE_PART |
350 GNUNET_SERIALIZE_NO_COMPRESS);
351 WRITEINT (wb, size);
352 write_buffered (wb, buf, size);
353 GNUNET_free (buf);
354}
355
356
357static void
358writeFileInfo (struct GNUNET_GE_Context *ectx, WriteBuffer * wb,
359 const GNUNET_ECRS_FileInfo * fi)
360{
361 writeMetaData (ectx, wb, fi->meta);
362 writeURI (wb, fi->uri);
363}
364
365
366
367
368typedef struct
369{
370 int fd;
371 unsigned int have;
372 unsigned int size;
373 unsigned int pos;
374 char *buffer;
375} ReadBuffer;
376
377static int
378read_buffered (ReadBuffer * rb, void *d, unsigned int size)
379{
380 char *dst = d;
381 unsigned int min;
382 unsigned int pos;
383 int ret;
384
385 if (rb->fd == -1)
386 return -1;
387 pos = 0;
388 do
389 {
390 /* first, use buffer */
391 min = rb->have - rb->pos;
392 if (min > 0)
393 {
394 if (min > size - pos)
395 min = size - pos;
396 memcpy (&dst[pos], &rb->buffer[rb->pos], min);
397 rb->pos += min;
398 pos += min;
399 }
400 if (pos == size)
401 return pos; /* done! */
402 GNUNET_GE_ASSERT (NULL, rb->have == rb->pos);
403 /* fill buffer */
404 ret = READ (rb->fd, rb->buffer, rb->size);
405 if (ret == -1)
406 {
407 CLOSE (rb->fd);
408 rb->fd = -1;
409 return -1;
410 }
411 if (ret == 0)
412 return 0;
413 rb->pos = 0;
414 rb->have = ret;
415 }
416 while (pos < size); /* should always be true */
417 return pos;
418}
419
420
421static int
422read_int (ReadBuffer * rb, int *val)
423{
424 int big;
425
426 if (sizeof (int) != read_buffered (rb, &big, sizeof (int)))
427 return GNUNET_SYSERR;
428 *val = ntohl (big);
429 return GNUNET_OK;
430}
431
432static unsigned int
433read_uint (ReadBuffer * rb, unsigned int *val)
434{
435 unsigned int big;
436
437 if (sizeof (unsigned int) !=
438 read_buffered (rb, &big, sizeof (unsigned int)))
439 return GNUNET_SYSERR;
440 *val = ntohl (big);
441 return GNUNET_OK;
442}
443
444#define READINT(a) if (GNUNET_OK != read_int(rb, (int*) &a)) return GNUNET_SYSERR;
445
446static int
447read_long (ReadBuffer * rb, long long *val)
448{
449 long long big;
450
451 if (sizeof (long long) != read_buffered (rb, &big, sizeof (long long)))
452 return GNUNET_SYSERR;
453 *val = GNUNET_ntohll (big);
454 return GNUNET_OK;
455}
456
457#define READLONG(a) if (GNUNET_OK != read_long(rb, (long long*) &a)) return GNUNET_SYSERR;
458
459static struct GNUNET_ECRS_URI *
460read_uri (struct GNUNET_GE_Context *ectx, ReadBuffer * rb)
461{
462 char *buf;
463 struct GNUNET_ECRS_URI *ret;
464 unsigned int size;
465
466 if (GNUNET_OK != read_uint (rb, &size))
467 return NULL;
468 buf = GNUNET_malloc (size + 1);
469 buf[size] = '\0';
470 if (size != read_buffered (rb, buf, size))
471 {
472 GNUNET_free (buf);
473 return NULL;
474 }
475 ret = GNUNET_ECRS_string_to_uri (ectx, buf);
476 GNUNET_GE_BREAK (ectx, ret != NULL);
477 GNUNET_free (buf);
478 return ret;
479}
480
481#define READURI(u) if (NULL == (u = read_uri(ectx, rb))) return GNUNET_SYSERR;
482
483static char *
484read_string (ReadBuffer * rb, unsigned int maxLen)
485{
486 char *buf;
487 unsigned int big;
488
489 if (GNUNET_OK != read_uint (rb, &big))
490 return NULL;
491 if (big > maxLen)
492 return NULL;
493 buf = GNUNET_malloc (big + 1);
494 buf[big] = '\0';
495 if (big != read_buffered (rb, buf, big))
496 {
497 GNUNET_free (buf);
498 return NULL;
499 }
500 return buf;
501}
502
503#define READSTRING(c, max) if (NULL == (c = read_string(rb, max))) return GNUNET_SYSERR;
504
505/**
506 * Read file info from file.
507 *
508 * @return GNUNET_OK on success, GNUNET_SYSERR on error
509 */
510static struct GNUNET_MetaData *
511read_meta (struct GNUNET_GE_Context *ectx, ReadBuffer * rb)
512{
513 unsigned int size;
514 char *buf;
515 struct GNUNET_MetaData *meta;
516
517 if (read_uint (rb, &size) != GNUNET_OK)
518 {
519 GNUNET_GE_BREAK (ectx, 0);
520 return NULL;
521 }
522 if (size > 1024 * 1024)
523 {
524 GNUNET_GE_BREAK (ectx, 0);
525 return NULL;
526 }
527 buf = GNUNET_malloc (size);
528 if (size != read_buffered (rb, buf, size))
529 {
530 GNUNET_free (buf);
531 GNUNET_GE_BREAK (ectx, 0);
532 return NULL;
533 }
534 meta = GNUNET_meta_data_deserialize (ectx, buf, size);
535 if (meta == NULL)
536 {
537 GNUNET_free (buf);
538 GNUNET_GE_BREAK (ectx, 0);
539 return NULL;
540 }
541 GNUNET_free (buf);
542 return meta;
543}
544
545/* end of bio.c */
diff --git a/src/util/container_bloomfilter.c b/src/util/container_bloomfilter.c
index cf99ac7b4..9efc2647c 100644
--- a/src/util/container_bloomfilter.c
+++ b/src/util/container_bloomfilter.c
@@ -157,7 +157,7 @@ incrementBit (char *bitArray, unsigned int bitIdx, const struct GNUNET_DISK_File
157 fileSlot = bitIdx / 2; 157 fileSlot = bitIdx / 2;
158 targetLoc = bitIdx % 2; 158 targetLoc = bitIdx % 2;
159 159
160 GNUNET_assert (fileSlot == (unsigned int) GNUNET_DISK_file_seek (fh, fileSlot, GNUNET_SEEK_SET)); 160 GNUNET_assert (fileSlot == (unsigned int) GNUNET_DISK_file_seek (fh, fileSlot, GNUNET_DISK_SEEK_SET));
161 if (1 != GNUNET_DISK_file_read (fh, &value, 1)) 161 if (1 != GNUNET_DISK_file_read (fh, &value, 1))
162 value = 0; 162 value = 0;
163 low = value & 0xF; 163 low = value & 0xF;
@@ -174,7 +174,7 @@ incrementBit (char *bitArray, unsigned int bitIdx, const struct GNUNET_DISK_File
174 high++; 174 high++;
175 } 175 }
176 value = ((high << 4) | low); 176 value = ((high << 4) | low);
177 GNUNET_assert (fileSlot == (unsigned int) GNUNET_DISK_file_seek (fh, fileSlot, GNUNET_SEEK_SET)); 177 GNUNET_assert (fileSlot == (unsigned int) GNUNET_DISK_file_seek (fh, fileSlot, GNUNET_DISK_SEEK_SET));
178 GNUNET_assert (1 == GNUNET_DISK_file_write (fh, &value, 1)); 178 GNUNET_assert (1 == GNUNET_DISK_file_write (fh, &value, 1));
179} 179}
180 180
@@ -200,7 +200,7 @@ decrementBit (char *bitArray, unsigned int bitIdx, const struct GNUNET_DISK_File
200 /* Each char slot in the counter file holds two 4 bit counters */ 200 /* Each char slot in the counter file holds two 4 bit counters */
201 fileSlot = bitIdx / 2; 201 fileSlot = bitIdx / 2;
202 targetLoc = bitIdx % 2; 202 targetLoc = bitIdx % 2;
203 GNUNET_DISK_file_seek (fh, fileSlot, GNUNET_SEEK_SET); 203 GNUNET_DISK_file_seek (fh, fileSlot, GNUNET_DISK_SEEK_SET);
204 if (1 != GNUNET_DISK_file_read (fh, &value, 1)) 204 if (1 != GNUNET_DISK_file_read (fh, &value, 1))
205 value = 0; 205 value = 0;
206 low = value & 0xF; 206 low = value & 0xF;
@@ -226,7 +226,7 @@ decrementBit (char *bitArray, unsigned int bitIdx, const struct GNUNET_DISK_File
226 } 226 }
227 } 227 }
228 value = ((high << 4) | low); 228 value = ((high << 4) | low);
229 GNUNET_DISK_file_seek (fh, fileSlot, GNUNET_SEEK_SET); 229 GNUNET_DISK_file_seek (fh, fileSlot, GNUNET_DISK_SEEK_SET);
230 GNUNET_assert (1 == GNUNET_DISK_file_write (fh, &value, 1)); 230 GNUNET_assert (1 == GNUNET_DISK_file_write (fh, &value, 1));
231} 231}
232 232
@@ -250,7 +250,7 @@ makeEmptyFile (const struct GNUNET_DISK_FileHandle *fh, unsigned int size)
250 return GNUNET_SYSERR; 250 return GNUNET_SYSERR;
251 buffer = GNUNET_malloc (BUFFSIZE); 251 buffer = GNUNET_malloc (BUFFSIZE);
252 memset (buffer, 0, BUFFSIZE); 252 memset (buffer, 0, BUFFSIZE);
253 GNUNET_DISK_file_seek (fh, 0, GNUNET_SEEK_SET); 253 GNUNET_DISK_file_seek (fh, 0, GNUNET_DISK_SEEK_SET);
254 254
255 while (bytesleft > 0) 255 while (bytesleft > 0)
256 { 256 {
diff --git a/src/util/disk.c b/src/util/disk.c
index b9fad5477..7bf8e9753 100644
--- a/src/util/disk.c
+++ b/src/util/disk.c
@@ -150,8 +150,8 @@ GNUNET_DISK_file_seek (const struct GNUNET_DISK_FileHandle *h, off_t offset,
150 150
151#ifdef MINGW 151#ifdef MINGW
152 DWORD ret; 152 DWORD ret;
153 static DWORD t[] = { [GNUNET_SEEK_SET] = FILE_BEGIN, 153 static DWORD t[] = { [GNUNET_DISK_SEEK_SET] = FILE_BEGIN,
154 [GNUNET_SEEK_CUR] = FILE_CURRENT, [GNUNET_SEEK_END] = FILE_END }; 154 [GNUNET_DISK_SEEK_CUR] = FILE_CURRENT, [GNUNET_DISK_SEEK_END] = FILE_END };
155 155
156 ret = SetFilePointer (h->h, offset, NULL, t[whence]); 156 ret = SetFilePointer (h->h, offset, NULL, t[whence]);
157 if (ret == INVALID_SET_FILE_POINTER) 157 if (ret == INVALID_SET_FILE_POINTER)
@@ -161,8 +161,8 @@ GNUNET_DISK_file_seek (const struct GNUNET_DISK_FileHandle *h, off_t offset,
161 } 161 }
162 return ret; 162 return ret;
163#else 163#else
164 static int t[] = { [GNUNET_SEEK_SET] = SEEK_SET, 164 static int t[] = { [GNUNET_DISK_SEEK_SET] = SEEK_SET,
165 [GNUNET_SEEK_CUR] = SEEK_CUR, [GNUNET_SEEK_END] = SEEK_END }; 165 [GNUNET_DISK_SEEK_CUR] = SEEK_CUR, [GNUNET_DISK_SEEK_END] = SEEK_END };
166 166
167 return lseek (h->fd, offset, t[whence]); 167 return lseek (h->fd, offset, t[whence]);
168#endif 168#endif
diff --git a/src/util/pseudonym.c b/src/util/pseudonym.c
index 441865acc..5bda78a89 100644
--- a/src/util/pseudonym.c
+++ b/src/util/pseudonym.c
@@ -391,7 +391,7 @@ GNUNET_PSEUDONYM_name_to_id (const struct GNUNET_CONFIGURATION_Handle *cfg,
391 | GNUNET_DISK_OPEN_READWRITE, GNUNET_DISK_PERM_USER_READ 391 | GNUNET_DISK_OPEN_READWRITE, GNUNET_DISK_PERM_USER_READ
392 | GNUNET_DISK_PERM_USER_WRITE); 392 | GNUNET_DISK_PERM_USER_WRITE);
393 GNUNET_free (fn); 393 GNUNET_free (fn);
394 GNUNET_DISK_file_seek (fh, idx * sizeof (GNUNET_HashCode), GNUNET_SEEK_SET); 394 GNUNET_DISK_file_seek (fh, idx * sizeof (GNUNET_HashCode), GNUNET_DISK_SEEK_SET);
395 if (sizeof (GNUNET_HashCode) != GNUNET_DISK_file_read (fh, nsid, sizeof (GNUNET_HashCode))) 395 if (sizeof (GNUNET_HashCode) != GNUNET_DISK_file_read (fh, nsid, sizeof (GNUNET_HashCode)))
396 { 396 {
397 GNUNET_DISK_file_close (fh); 397 GNUNET_DISK_file_close (fh);