aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorChristian Grothoff <christian@grothoff.org>2009-08-25 10:59:00 +0000
committerChristian Grothoff <christian@grothoff.org>2009-08-25 10:59:00 +0000
commit9cbff87bf9b68c08242b1a6a79221311dc157fc0 (patch)
tree6dacb93610d32de7f16e71765874fe2fb6e3a704 /src
parent3d0444f9e6d64d6bc6b109cb743b9e08abcada0e (diff)
downloadgnunet-9cbff87bf9b68c08242b1a6a79221311dc157fc0.tar.gz
gnunet-9cbff87bf9b68c08242b1a6a79221311dc157fc0.zip
hxing
Diffstat (limited to 'src')
-rw-r--r--src/fs/fs.c37
-rw-r--r--src/fs/fs.h39
-rw-r--r--src/fs/fs_file_information.c44
-rw-r--r--src/include/gnunet_bio_lib.h26
-rw-r--r--src/include/gnunet_fs_service.h36
-rw-r--r--src/util/bio.c633
6 files changed, 448 insertions, 367 deletions
diff --git a/src/fs/fs.c b/src/fs/fs.c
index 0522b7941..157f4ef22 100644
--- a/src/fs/fs.c
+++ b/src/fs/fs.c
@@ -29,7 +29,6 @@
29#include "fs.h" 29#include "fs.h"
30 30
31 31
32
33/** 32/**
34 * Setup a connection to the file-sharing service. 33 * Setup a connection to the file-sharing service.
35 * 34 *
@@ -46,7 +45,35 @@ GNUNET_FS_start (struct GNUNET_SCHEDULER_Handle *sched,
46 GNUNET_FS_ProgressCallback upcb, 45 GNUNET_FS_ProgressCallback upcb,
47 void *upcb_cls) 46 void *upcb_cls)
48{ 47{
49 return NULL; 48 struct GNUNET_FS_Handle *ret;
49 struct GNUNET_CLIENT_Connection *client;
50
51 client = GNUNET_CLIENT_connect (sched,
52 "fs",
53 cfg);
54 if (NULL == client)
55 return NULL;
56 ret = GNUNET_malloc (sizeof (struct GNUNET_FS_Handle));
57 ret->sched = sched;
58 ret->cfg = cfg;
59 ret->client_name = GNUNET_strdup (client_name);
60 ret->upcb = upcb;
61 ret->upcb_cls = upcb_cls;
62 ret->client = client;
63 // FIXME: setup receive-loop with client
64 // FIXME: deserialize state; use client-name to find master-directory!
65 // Deserialize-Upload:
66 // * read FNs for upload FIs, deserialize each
67 // Deserialize Search:
68 // * read search queries
69 // * for each query, read file with search results
70 // * for each search result with active download, deserialize download
71 // * for each directory search result, check for active downloads of contents
72 // Deserialize Download:
73 // * always part of search???
74 // Deserialize Unindex:
75 // * read FNs for unindex with progress offset
76 return ret;
50} 77}
51 78
52 79
@@ -60,6 +87,12 @@ GNUNET_FS_start (struct GNUNET_SCHEDULER_Handle *sched,
60void 87void
61GNUNET_FS_stop (struct GNUNET_FS_Handle *h) 88GNUNET_FS_stop (struct GNUNET_FS_Handle *h)
62{ 89{
90 // FIXME: serialize state!? (or is it always serialized???)
91 // FIXME: terminate receive-loop with client
92 GNUNET_CLIENT_disconnect (h->client);
93 GNUNET_free (h->client_name);
94 GNUNET_free (h);
63} 95}
64 96
97
65/* end of fs.c */ 98/* end of fs.c */
diff --git a/src/fs/fs.h b/src/fs/fs.h
index 0c82d5831..1a8a6b0f7 100644
--- a/src/fs/fs.h
+++ b/src/fs/fs.h
@@ -279,4 +279,43 @@ struct GNUNET_FS_FileInformation
279}; 279};
280 280
281 281
282/**
283 * Master context for most FS operations.
284 */
285struct GNUNET_FS_Handle
286{
287 /**
288 * Scheduler.
289 */
290 struct GNUNET_SCHEDULER_Handle *sched;
291
292 /**
293 * Configuration to use.
294 */
295 const struct GNUNET_CONFIGURATION_Handle *cfg;
296
297 /**
298 * Name of our client.
299 */
300 char *client_name;
301
302 /**
303 * Function to call with updates on our progress.
304 */
305 GNUNET_FS_ProgressCallback upcb;
306
307 /**
308 * Closure for upcb.
309 */
310 void *upcb_cls;
311
312 /**
313 * Connection to the FS service.
314 */
315 struct GNUNET_CLIENT_Connection *client;
316
317
318};
319
320
282#endif 321#endif
diff --git a/src/fs/fs_file_information.c b/src/fs/fs_file_information.c
index 9b806184b..540b518dc 100644
--- a/src/fs/fs_file_information.c
+++ b/src/fs/fs_file_information.c
@@ -24,7 +24,6 @@
24 * @author Christian Grothoff 24 * @author Christian Grothoff
25 * 25 *
26 * TODO: 26 * TODO:
27 * - publishing progress update API (increment offset, serialize)
28 * - serialization/deserialization (& deserialization API) 27 * - serialization/deserialization (& deserialization API)
29 * - metadata filename clean up code 28 * - metadata filename clean up code
30 * - metadata/ksk generation for directories from contained files 29 * - metadata/ksk generation for directories from contained files
@@ -36,15 +35,15 @@
36 35
37 36
38/** 37/**
39 * Create a temporary file disk to store the current 38 * Create a temporary file on disk to store the current
40 * state of "fi" in. 39 * state of "fi" in.
41 */ 40 */
42static void 41void
43fi_sync (struct GNUNET_FS_FileInformation * fi) 42GNUNET_FS_file_information_sync (struct GNUNET_FS_FileInformation * fi)
44{ 43{
45 if (NULL == fi->serialization) 44 if (NULL == fi->serialization)
46 { 45 {
47 fi->serialization = NULL; // FIXME 46 fi->serialization = NULL; // FIXME -- need cfg!
48 } 47 }
49 // FIXME... 48 // FIXME...
50} 49}
@@ -57,8 +56,8 @@ fi_sync (struct GNUNET_FS_FileInformation * fi)
57 * @param filename name of the file to use 56 * @param filename name of the file to use
58 * @return NULL on error 57 * @return NULL on error
59 */ 58 */
60static struct GNUNET_FS_FileInformation * 59struct GNUNET_FS_FileInformation *
61fi_load (const char *filename) 60GNUNET_FS_file_information_recover (const char *name)
62{ 61{
63 struct GNUNET_FS_FileInformation *ret; 62 struct GNUNET_FS_FileInformation *ret;
64 // FIXME! 63 // FIXME!
@@ -67,6 +66,25 @@ fi_load (const char *filename)
67 66
68 67
69/** 68/**
69 * Obtain the name under which this file information
70 * structure is stored on disk. Only works for top-level
71 * file information structures.
72 *
73 * @param s structure to get the filename for
74 * @return NULL on error, otherwise filename that
75 * can be passed to "GNUNET_FS_file_information_recover"
76 * to read this fi-struct from disk.
77 */
78const char *
79GNUNET_FS_file_information_get_id (struct GNUNET_FS_FileInformation *s)
80{
81 if (NULL != s->dir)
82 return NULL;
83 return s->serialization;
84}
85
86
87/**
70 * Closure for "data_reader_file". 88 * Closure for "data_reader_file".
71 */ 89 */
72struct FileInfo 90struct FileInfo
@@ -320,7 +338,7 @@ GNUNET_FS_file_information_create_from_reader (void *client_info,
320 ret->data.file.do_index = do_index; 338 ret->data.file.do_index = do_index;
321 ret->anonymity = anonymity; 339 ret->anonymity = anonymity;
322 ret->priority = priority; 340 ret->priority = priority;
323 fi_sync (ret); 341 GNUNET_FS_file_information_sync (ret);
324 return ret; 342 return ret;
325} 343}
326 344
@@ -609,10 +627,10 @@ GNUNET_FS_file_information_create_from_directory (void *client_info,
609 while (dc.entries != NULL) 627 while (dc.entries != NULL)
610 { 628 {
611 dc.entries->dir = ret; 629 dc.entries->dir = ret;
612 fi_sync (dc.entries); 630 GNUNET_FS_file_information_sync (dc.entries);
613 dc.entries = dc.entries->next; 631 dc.entries = dc.entries->next;
614 } 632 }
615 fi_sync (ret); 633 GNUNET_FS_file_information_sync (ret);
616 return ret; 634 return ret;
617} 635}
618 636
@@ -651,7 +669,7 @@ GNUNET_FS_file_information_create_empty_directory (void *client_info,
651 ret->is_directory = GNUNET_YES; 669 ret->is_directory = GNUNET_YES;
652 ret->anonymity = anonymity; 670 ret->anonymity = anonymity;
653 ret->priority = priority; 671 ret->priority = priority;
654 fi_sync (ret); 672 GNUNET_FS_file_information_sync (ret);
655 return ret; 673 return ret;
656} 674}
657 675
@@ -683,8 +701,8 @@ GNUNET_FS_file_information_add (struct GNUNET_FS_FileInformation *dir,
683 dir->data.dir.entries = ent; 701 dir->data.dir.entries = ent;
684 dir->data.dir.dir_size = 0; 702 dir->data.dir.dir_size = 0;
685 dir->publish_offset = 0; 703 dir->publish_offset = 0;
686 fi_sync (ent); 704 GNUNET_FS_file_information_sync (ent);
687 fi_sync (dir); 705 GNUNET_FS_file_information_sync (dir);
688 return GNUNET_OK; 706 return GNUNET_OK;
689} 707}
690 708
diff --git a/src/include/gnunet_bio_lib.h b/src/include/gnunet_bio_lib.h
index 02b04570e..2765b4695 100644
--- a/src/include/gnunet_bio_lib.h
+++ b/src/include/gnunet_bio_lib.h
@@ -71,12 +71,12 @@ int GNUNET_BIO_read_close (struct GNUNET_BIO_ReadHandle *h,
71 * @param what describes what is being read (for error message creation) 71 * @param what describes what is being read (for error message creation)
72 * @param result the buffer to write the result to 72 * @param result the buffer to write the result to
73 * @param len the number of bytes to read 73 * @param len the number of bytes to read
74 * @return len on success, GNUNET_SYSERR on failure 74 * @return GNUNET_OK on success, GNUNET_SYSERR on failure
75 */ 75 */
76ssize_t GNUNET_BIO_read (struct GNUNET_BIO_ReadHandle *h, 76int GNUNET_BIO_read (struct GNUNET_BIO_ReadHandle *h,
77 const char *what, 77 const char *what,
78 void *result, 78 void *result,
79 size_t len); 79 size_t len);
80 80
81/** 81/**
82 * Read 0-terminated string from a file. 82 * Read 0-terminated string from a file.
@@ -85,11 +85,13 @@ ssize_t GNUNET_BIO_read (struct GNUNET_BIO_ReadHandle *h,
85 * @param what describes what is being read (for error message creation) 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 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) 87 * (note that *result could be set to NULL as well)
88 * @param maxLen maximum allowed length for the string
88 * @return GNUNET_OK on success, GNUNET_SYSERR on failure 89 * @return GNUNET_OK on success, GNUNET_SYSERR on failure
89 */ 90 */
90int GNUNET_BIO_read_string (struct GNUNET_BIO_ReadHandle *h, 91int GNUNET_BIO_read_string (struct GNUNET_BIO_ReadHandle *h,
91 const char *what, 92 const char *what,
92 char **result); 93 char **result,
94 size_t maxLen);
93 95
94 96
95/** 97/**
@@ -198,9 +200,9 @@ int GNUNET_BIO_write_close (struct GNUNET_BIO_WriteHandle *h);
198 * @param n number of bytes to write 200 * @param n number of bytes to write
199 * @return GNUNET_OK on success, GNUNET_SYSERR on error 201 * @return GNUNET_OK on success, GNUNET_SYSERR on error
200 */ 202 */
201ssize_t GNUNET_BIO_write (struct GNUNET_BIO_WriteHandle *h, 203int GNUNET_BIO_write (struct GNUNET_BIO_WriteHandle *h,
202 const void *buffer, 204 const void *buffer,
203 size_t n); 205 size_t n);
204 206
205 207
206/** 208/**
@@ -244,7 +246,7 @@ int GNUNET_BIO_write_meta_data (struct GNUNET_BIO_WriteHandle *h,
244 * @param h hande to open file 246 * @param h hande to open file
245 * @param f double to write (must be a variable) 247 * @param f double to write (must be a variable)
246 */ 248 */
247#define GNUNET_BIO_write_float(h, f) (sizeof(double) == GNUNET_BIO_write (h, &f, sizeof(double))) 249#define GNUNET_BIO_write_double(h, f) (sizeof(double) == GNUNET_BIO_write (h, &f, sizeof(double)))
248 250
249 251
250/** 252/**
@@ -254,7 +256,7 @@ int GNUNET_BIO_write_meta_data (struct GNUNET_BIO_WriteHandle *h,
254 * @param i address of 32-bit integer to write 256 * @param i address of 32-bit integer to write
255 * @return GNUNET_OK on success, GNUNET_SYSERR on error 257 * @return GNUNET_OK on success, GNUNET_SYSERR on error
256 */ 258 */
257int GNUNET_BIO_write_int32 (struct GNUNET_BIO_ReadHandle *h, 259int GNUNET_BIO_write_int32 (struct GNUNET_BIO_WriteHandle *h,
258 int32_t i); 260 int32_t i);
259 261
260 262
@@ -265,7 +267,7 @@ int GNUNET_BIO_write_int32 (struct GNUNET_BIO_ReadHandle *h,
265 * @param i address of 64-bit integer to write 267 * @param i address of 64-bit integer to write
266 * @return GNUNET_OK on success, GNUNET_SYSERR on error 268 * @return GNUNET_OK on success, GNUNET_SYSERR on error
267 */ 269 */
268int GNUNET_BIO_write_int64 (struct GNUNET_BIO_ReadHandle *h, 270int GNUNET_BIO_write_int64 (struct GNUNET_BIO_WriteHandle *h,
269 int64_t i); 271 int64_t i);
270 272
271 273
diff --git a/src/include/gnunet_fs_service.h b/src/include/gnunet_fs_service.h
index 45cd1e77e..7c6fc0549 100644
--- a/src/include/gnunet_fs_service.h
+++ b/src/include/gnunet_fs_service.h
@@ -1415,6 +1415,42 @@ typedef int (*GNUNET_FS_FileInformationProcessor)(void *cls,
1415 1415
1416 1416
1417/** 1417/**
1418 * Recover file information structure from disk.
1419 *
1420 * @param name filename for the structure on disk
1421 * @return NULL on error
1422 */
1423struct GNUNET_FS_FileInformation *
1424GNUNET_FS_file_information_recover (const char *name);
1425
1426
1427/**
1428 * Obtain the name under which this file information
1429 * structure is stored on disk. Only works for top-level
1430 * file information structures.
1431 *
1432 * @param s structure to get the filename for
1433 * @return NULL on error, otherwise filename that
1434 * can be passed to "GNUNET_FS_file_information_recover"
1435 * to read this fi-struct from disk.
1436 */
1437const char *
1438GNUNET_FS_file_information_get_id (struct GNUNET_FS_FileInformation *s);
1439
1440
1441/**
1442 * Synchronize this file-information struct with its mirror
1443 * on disk. Note that all internal FS-operations that change
1444 * file information data should already call "sync" internally,
1445 * so this function is likely not useful for clients.
1446 *
1447 * @param s the struct to sync
1448 */
1449void
1450GNUNET_FS_file_information_sync (struct GNUNET_FS_FileInformation *s);
1451
1452
1453/**
1418 * Create an entry for a file in a publish-structure. 1454 * Create an entry for a file in a publish-structure.
1419 * 1455 *
1420 * @param filename name of the file or directory to publish 1456 * @param filename name of the file or directory to publish
diff --git a/src/util/bio.c b/src/util/bio.c
index 060b6f94b..8c3daed15 100644
--- a/src/util/bio.c
+++ b/src/util/bio.c
@@ -17,8 +17,6 @@
17 Free Software Foundation, Inc., 59 Temple Place - Suite 330, 17 Free Software Foundation, Inc., 59 Temple Place - Suite 330,
18 Boston, MA 02111-1307, USA. 18 Boston, MA 02111-1307, USA.
19*/ 19*/
20
21
22/** 20/**
23 * @file util/bio.c 21 * @file util/bio.c
24 * @brief functions for buffering IO 22 * @brief functions for buffering IO
@@ -26,13 +24,23 @@
26 */ 24 */
27#include "platform.h" 25#include "platform.h"
28#include "gnunet_bio_lib.h" 26#include "gnunet_bio_lib.h"
27#include "gnunet_disk_lib.h"
28
29#define BIO_BUFFER_SIZE 65536
29 30
31#define MAX_META_DATA (1024 * 1024)
30 32
31/** 33/**
32 * Handle for buffered reading. 34 * Handle for buffered reading.
33 */ 35 */
34struct GNUNET_BIO_ReadHandle 36struct GNUNET_BIO_ReadHandle
35{ 37{
38 struct GNUNET_DISK_FileHandle *fd;
39 char *emsg;
40 char *buffer;
41 size_t have;
42 size_t size;
43 off_t pos;
36}; 44};
37 45
38 46
@@ -42,9 +50,20 @@ struct GNUNET_BIO_ReadHandle
42 * @param fn file name to be opened 50 * @param fn file name to be opened
43 * @return IO handle on success, NULL on error 51 * @return IO handle on success, NULL on error
44 */ 52 */
45struct GNUNET_BIO_ReadHandle *GNUNET_BIO_read_open (const char *fn) 53struct GNUNET_BIO_ReadHandle *
54GNUNET_BIO_read_open (const char *fn)
46{ 55{
47 return NULL; 56 struct GNUNET_DISK_FileHandle *fd;
57 struct GNUNET_BIO_ReadHandle *h;
58
59 fd = GNUNET_DISK_file_open (fn, GNUNET_DISK_OPEN_READ);
60 if (NULL == fd)
61 return NULL;
62 h = GNUNET_malloc (sizeof(struct GNUNET_BIO_ReadHandle) + BIO_BUFFER_SIZE);
63 h->buffer = (char*) &h[1];
64 h->size = BIO_BUFFER_SIZE;
65 h->fd = fd;
66 return h;
48} 67}
49 68
50 69
@@ -59,7 +78,10 @@ struct GNUNET_BIO_ReadHandle *GNUNET_BIO_read_open (const char *fn)
59int GNUNET_BIO_read_close (struct GNUNET_BIO_ReadHandle *h, 78int GNUNET_BIO_read_close (struct GNUNET_BIO_ReadHandle *h,
60 char **emsg) 79 char **emsg)
61{ 80{
62 return GNUNET_SYSERR; 81 *emsg = h->emsg;
82 GNUNET_DISK_file_close (h->fd);
83 GNUNET_free (h);
84 return (NULL == *emsg) ? GNUNET_OK : GNUNET_SYSERR;
63} 85}
64 86
65 87
@@ -70,13 +92,61 @@ int GNUNET_BIO_read_close (struct GNUNET_BIO_ReadHandle *h,
70 * @param what describes what is being read (for error message creation) 92 * @param what describes what is being read (for error message creation)
71 * @param result the buffer to write the result to 93 * @param result the buffer to write the result to
72 * @param len the number of bytes to read 94 * @param len the number of bytes to read
73 * @return len on success, GNUNET_SYSERR on failure 95 * @return GNUNET_OK on success, GNUNET_SYSERR on failure
74 */ 96 */
75ssize_t GNUNET_BIO_read (struct GNUNET_BIO_ReadHandle *h, 97int GNUNET_BIO_read (struct GNUNET_BIO_ReadHandle *h,
76 const char *what, 98 const char *what,
77 void *result, 99 void *result,
78 size_t len) 100 size_t len)
79{ 101{
102 char *dst = result;
103 size_t min;
104 size_t pos;
105 ssize_t ret;
106
107 if (h->emsg != NULL)
108 return GNUNET_SYSERR;
109 pos = 0;
110 do
111 {
112 /* first, use buffer */
113 min = h->have - h->pos;
114 if (min > 0)
115 {
116 if (min > len - pos)
117 min = len - pos;
118 memcpy (&dst[pos], &h->buffer[h->pos], min);
119 h->pos += min;
120 pos += min;
121 }
122 if (pos == len)
123 return GNUNET_OK; /* done! */
124 GNUNET_assert (h->have == h->pos);
125 /* fill buffer */
126 ret = GNUNET_DISK_file_read (h->fd,
127 h->buffer,
128 h->size);
129 if (ret == -1)
130 {
131 GNUNET_asprintf (&h->emsg,
132 _("Error reading `%s': %s"),
133 what,
134 STRERROR (errno));
135 return GNUNET_SYSERR;
136 }
137 if (ret == 0)
138 {
139 GNUNET_asprintf (&h->emsg,
140 _("Error reading `%s': %s"),
141 what,
142 _("End of file"));
143 return GNUNET_SYSERR;
144 }
145 h->pos = 0;
146 h->have = ret;
147 }
148 while (pos < len); /* should always be true */
149 return GNUNET_OK;
80} 150}
81 151
82 152
@@ -87,12 +157,42 @@ ssize_t GNUNET_BIO_read (struct GNUNET_BIO_ReadHandle *h,
87 * @param what describes what is being read (for error message creation) 157 * @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 158 * @param result the buffer to store a pointer to the (allocated) string to
89 * (note that *result could be set to NULL as well) 159 * (note that *result could be set to NULL as well)
160 * @param maxLen maximum allowed length for the string
90 * @return GNUNET_OK on success, GNUNET_SYSERR on failure 161 * @return GNUNET_OK on success, GNUNET_SYSERR on failure
91 */ 162 */
92int GNUNET_BIO_read_string (struct GNUNET_BIO_ReadHandle *h, 163int GNUNET_BIO_read_string (struct GNUNET_BIO_ReadHandle *h,
93 const char *what, 164 const char *what,
94 char **result) 165 char **result,
166 size_t maxLen)
95{ 167{
168 char *buf;
169 uint32_t big;
170
171 if (! GNUNET_BIO_read_int32 (h, &big))
172 return GNUNET_SYSERR;
173 if (big == 0)
174 {
175 *result = NULL;
176 return GNUNET_OK;
177 }
178 if (big > maxLen)
179 {
180 GNUNET_asprintf (&h->emsg,
181 _("String `%s' longer than allowed (%u > %u)"),
182 what,
183 big,
184 maxLen);
185 return GNUNET_SYSERR;
186 }
187 buf = GNUNET_malloc (big);
188 buf[--big] = '\0';
189 if (big != GNUNET_BIO_read (h, what, buf, big))
190 {
191 GNUNET_free (buf);
192 return GNUNET_SYSERR;
193 }
194 *result = buf;
195 return GNUNET_OK;
96} 196}
97 197
98 198
@@ -108,6 +208,42 @@ int GNUNET_BIO_read_meta_data (struct GNUNET_BIO_ReadHandle *h,
108 const char *what, 208 const char *what,
109 struct GNUNET_CONTAINER_MetaData **result) 209 struct GNUNET_CONTAINER_MetaData **result)
110{ 210{
211 uint32_t size;
212 char *buf;
213 struct GNUNET_CONTAINER_MetaData *meta;
214
215 if (GNUNET_BIO_read_int32__ (h,
216 what,
217 (int32_t*) &size) != GNUNET_OK)
218 return GNUNET_SYSERR;
219 if (size > MAX_META_DATA)
220 {
221 GNUNET_asprintf (&h->emsg,
222 _("Serialized metadata `%s' larger than allowed (%u > %u)"),
223 what,
224 size,
225 MAX_META_DATA);
226 return GNUNET_SYSERR;
227 }
228 buf = GNUNET_malloc (size);
229 if (size !=
230 GNUNET_BIO_read (h, what, buf, size))
231 {
232 GNUNET_free (buf);
233 return GNUNET_SYSERR;
234 }
235 meta = GNUNET_CONTAINER_meta_data_deserialize (buf, size);
236 if (meta == NULL)
237 {
238 GNUNET_free (buf);
239 GNUNET_asprintf (&h->emsg,
240 _("Metadata `%s' failed to deserialize"),
241 what);
242 return GNUNET_SYSERR;
243 }
244 GNUNET_free (buf);
245 *result = meta;
246 return GNUNET_OK;
111} 247}
112 248
113 249
@@ -121,7 +257,19 @@ int GNUNET_BIO_read_meta_data (struct GNUNET_BIO_ReadHandle *h,
121 */ 257 */
122int GNUNET_BIO_read_int32__ (struct GNUNET_BIO_ReadHandle *h, 258int GNUNET_BIO_read_int32__ (struct GNUNET_BIO_ReadHandle *h,
123 const char *what, 259 const char *what,
124 int32_t *i); 260 int32_t *i)
261{
262 int32_t big;
263
264 if (sizeof (int32_t) !=
265 GNUNET_BIO_read (h,
266 what,
267 &big,
268 sizeof (int32_t)))
269 return GNUNET_SYSERR;
270 *i = ntohl (big);
271 return GNUNET_OK;
272}
125 273
126 274
127/** 275/**
@@ -134,13 +282,30 @@ int GNUNET_BIO_read_int32__ (struct GNUNET_BIO_ReadHandle *h,
134 */ 282 */
135int GNUNET_BIO_read_int64__ (struct GNUNET_BIO_ReadHandle *h, 283int GNUNET_BIO_read_int64__ (struct GNUNET_BIO_ReadHandle *h,
136 const char *what, 284 const char *what,
137 int64_t *i); 285 int64_t *i)
286{
287 int64_t big;
288
289 if (sizeof (int64_t) !=
290 GNUNET_BIO_read (h,
291 what,
292 &big,
293 sizeof (int64_t)))
294 return GNUNET_SYSERR;
295 *i = GNUNET_ntohll (big);
296 return GNUNET_OK;
297}
298
138 299
139/** 300/**
140 * Handle for buffered writing. 301 * Handle for buffered writing.
141 */ 302 */
142struct GNUNET_BIO_WriteHandle 303struct GNUNET_BIO_WriteHandle
143{ 304{
305 struct GNUNET_DISK_FileHandle *fd;
306 char *buffer;
307 size_t have;
308 size_t size;
144}; 309};
145 310
146 311
@@ -152,7 +317,19 @@ struct GNUNET_BIO_WriteHandle
152 */ 317 */
153struct GNUNET_BIO_WriteHandle *GNUNET_BIO_write_open (const char *fn) 318struct GNUNET_BIO_WriteHandle *GNUNET_BIO_write_open (const char *fn)
154{ 319{
155 return NULL; 320 struct GNUNET_DISK_FileHandle *fd;
321 struct GNUNET_BIO_WriteHandle *h;
322
323 fd = GNUNET_DISK_file_open (fn,
324 GNUNET_DISK_OPEN_WRITE | GNUNET_DISK_OPEN_TRUNCATE | GNUNET_DISK_OPEN_CREATE,
325 GNUNET_DISK_PERM_USER_READ | GNUNET_DISK_PERM_USER_WRITE);
326 if (NULL == fd)
327 return NULL;
328 h = GNUNET_malloc (sizeof(struct GNUNET_BIO_WriteHandle) + BIO_BUFFER_SIZE);
329 h->buffer = (char*) &h[1];
330 h->size = BIO_BUFFER_SIZE;
331 h->fd = fd;
332 return h;
156} 333}
157 334
158 335
@@ -162,7 +339,22 @@ struct GNUNET_BIO_WriteHandle *GNUNET_BIO_write_open (const char *fn)
162 * @param h file handle 339 * @param h file handle
163 * @return GNUNET_OK on success, GNUNET_SYSERR otherwise 340 * @return GNUNET_OK on success, GNUNET_SYSERR otherwise
164 */ 341 */
165int GNUNET_BIO_write_close (struct GNUNET_BIO_WriteHandle *h); 342int GNUNET_BIO_write_close (struct GNUNET_BIO_WriteHandle *h)
343{
344 int ret;
345
346 if (NULL == h->fd)
347 {
348 ret = GNUNET_SYSERR;
349 }
350 else
351 {
352 GNUNET_DISK_file_close (h->fd);
353 ret = GNUNET_OK;
354 }
355 GNUNET_free (h);
356 return ret;
357}
166 358
167 359
168/** 360/**
@@ -173,9 +365,42 @@ int GNUNET_BIO_write_close (struct GNUNET_BIO_WriteHandle *h);
173 * @param n number of bytes to write 365 * @param n number of bytes to write
174 * @return GNUNET_OK on success, GNUNET_SYSERR on error 366 * @return GNUNET_OK on success, GNUNET_SYSERR on error
175 */ 367 */
176ssize_t GNUNET_BIO_write (struct GNUNET_BIO_WriteHandle *h, 368int GNUNET_BIO_write (struct GNUNET_BIO_WriteHandle *h,
177 const void *buffer, 369 const void *buffer,
178 size_t n); 370 size_t n)
371{
372 const char *src = buffer;
373 size_t min;
374 size_t pos;
375 ssize_t ret;
376
377 if (NULL == h->fd)
378 return GNUNET_SYSERR;
379 pos = 0;
380 do
381 {
382 /* first, just use buffer */
383 min = h->size - h->have;
384 if (min > n - pos)
385 min = n - pos;
386 memcpy (&h->buffer[h->have], &src[pos], min);
387 pos += min;
388 h->have += min;
389 if (pos == n)
390 return GNUNET_OK; /* done */
391 GNUNET_assert (h->have == h->size);
392 ret = GNUNET_DISK_file_write (h->fd, h->buffer, h->size);
393 if (ret != h->size)
394 {
395 GNUNET_DISK_file_close (h->fd);
396 h->fd = NULL;
397 return GNUNET_SYSERR; /* error */
398 }
399 h->have = 0;
400 }
401 while (pos < n); /* should always be true */
402 return GNUNET_OK;
403}
179 404
180 405
181/** 406/**
@@ -186,9 +411,18 @@ ssize_t GNUNET_BIO_write (struct GNUNET_BIO_WriteHandle *h,
186 * @return GNUNET_OK on success, GNUNET_SYSERR on error 411 * @return GNUNET_OK on success, GNUNET_SYSERR on error
187 */ 412 */
188int GNUNET_BIO_write_string (struct GNUNET_BIO_WriteHandle *h, 413int GNUNET_BIO_write_string (struct GNUNET_BIO_WriteHandle *h,
189 const char *s); 414 const char *s)
190 415{
416 uint32_t slen;
191 417
418 slen = (uint32_t) ((s == NULL) ? 0 : strlen(s) + 1);
419 if (GNUNET_OK !=
420 GNUNET_BIO_write_int32 (h, slen))
421 return GNUNET_SYSERR;
422 if (0 != slen)
423 return GNUNET_BIO_write (h, s, slen - 1);
424 return GNUNET_OK;
425}
192 426
193 427
194/** 428/**
@@ -199,27 +433,34 @@ int GNUNET_BIO_write_string (struct GNUNET_BIO_WriteHandle *h,
199 * @return GNUNET_OK on success, GNUNET_SYSERR on error 433 * @return GNUNET_OK on success, GNUNET_SYSERR on error
200 */ 434 */
201int GNUNET_BIO_write_meta_data (struct GNUNET_BIO_WriteHandle *h, 435int GNUNET_BIO_write_meta_data (struct GNUNET_BIO_WriteHandle *h,
202 const struct GNUNET_CONTAINER_MetaData *m); 436 const struct GNUNET_CONTAINER_MetaData *m)
203 437{
204 438 unsigned int size;
205 439 char *buf;
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 440
216/** 441 size = GNUNET_CONTAINER_meta_data_get_serialized_size (m,
217 * Write a double. 442 GNUNET_CONTAINER_META_DATA_SERIALIZE_FULL
218 * 443 |
219 * @param h hande to open file 444 GNUNET_CONTAINER_META_DATA_SERIALIZE_NO_COMPRESS);
220 * @param f double to write (must be a variable) 445 if (size > MAX_META_DATA)
221 */ 446 size = MAX_META_DATA;
222#define GNUNET_BIO_write_float(h, f) (sizeof(double) == GNUNET_BIO_write (h, &f, sizeof(double))) 447 buf = GNUNET_malloc (size);
448 GNUNET_CONTAINER_meta_data_serialize (m,
449 buf,
450 size,
451 GNUNET_CONTAINER_META_DATA_SERIALIZE_PART |
452 GNUNET_CONTAINER_META_DATA_SERIALIZE_NO_COMPRESS);
453 if ( (GNUNET_OK !=
454 GNUNET_BIO_write_int32 (h, size)) ||
455 (GNUNET_OK !=
456 GNUNET_BIO_write (h, buf, size)) )
457 {
458 GNUNET_free (buf);
459 return GNUNET_SYSERR;
460 }
461 GNUNET_free (buf);
462 return GNUNET_OK;
463}
223 464
224 465
225/** 466/**
@@ -229,8 +470,13 @@ int GNUNET_BIO_write_meta_data (struct GNUNET_BIO_WriteHandle *h,
229 * @param i address of 32-bit integer to write 470 * @param i address of 32-bit integer to write
230 * @return GNUNET_OK on success, GNUNET_SYSERR on error 471 * @return GNUNET_OK on success, GNUNET_SYSERR on error
231 */ 472 */
232int GNUNET_BIO_write_int32 (struct GNUNET_BIO_ReadHandle *h, 473int GNUNET_BIO_write_int32 (struct GNUNET_BIO_WriteHandle *h,
233 int32_t i); 474 int32_t i)
475{
476 int32_t big;
477 big = htonl (i);
478 return GNUNET_BIO_write (h, &big, sizeof (int32_t));
479}
234 480
235 481
236/** 482/**
@@ -240,306 +486,13 @@ int GNUNET_BIO_write_int32 (struct GNUNET_BIO_ReadHandle *h,
240 * @param i address of 64-bit integer to write 486 * @param i address of 64-bit integer to write
241 * @return GNUNET_OK on success, GNUNET_SYSERR on error 487 * @return GNUNET_OK on success, GNUNET_SYSERR on error
242 */ 488 */
243int GNUNET_BIO_write_int64 (struct GNUNET_BIO_ReadHandle *h, 489int GNUNET_BIO_write_int64 (struct GNUNET_BIO_WriteHandle *h,
244 int64_t i); 490 int64_t i)
245
246
247
248
249
250typedef struct
251{ 491{
252 int fd; 492 int64_t big;
253 unsigned int have; 493 big = GNUNET_htonll (i);
254 unsigned int size; 494 return GNUNET_BIO_write (h, &big, sizeof (int64_t));
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} 495}
292 496
293 497
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 */ 498/* end of bio.c */