diff options
Diffstat (limited to 'src/util/bio.c')
-rw-r--r-- | src/util/bio.c | 253 |
1 files changed, 123 insertions, 130 deletions
diff --git a/src/util/bio.c b/src/util/bio.c index 9c2b9d0dd..41ad5fd5d 100644 --- a/src/util/bio.c +++ b/src/util/bio.c | |||
@@ -58,8 +58,7 @@ GNUNET_BIO_read_open (const char *fn) | |||
58 | struct GNUNET_DISK_FileHandle *fd; | 58 | struct GNUNET_DISK_FileHandle *fd; |
59 | struct GNUNET_BIO_ReadHandle *h; | 59 | struct GNUNET_BIO_ReadHandle *h; |
60 | 60 | ||
61 | fd = | 61 | fd = GNUNET_DISK_file_open (fn, GNUNET_DISK_OPEN_READ, GNUNET_DISK_PERM_NONE); |
62 | GNUNET_DISK_file_open (fn, GNUNET_DISK_OPEN_READ, GNUNET_DISK_PERM_NONE); | ||
63 | if (NULL == fd) | 62 | if (NULL == fd) |
64 | return NULL; | 63 | return NULL; |
65 | h = GNUNET_malloc (sizeof (struct GNUNET_BIO_ReadHandle) + BIO_BUFFER_SIZE); | 64 | h = GNUNET_malloc (sizeof (struct GNUNET_BIO_ReadHandle) + BIO_BUFFER_SIZE); |
@@ -105,7 +104,7 @@ GNUNET_BIO_read_close (struct GNUNET_BIO_ReadHandle *h, char **emsg) | |||
105 | */ | 104 | */ |
106 | int | 105 | int |
107 | GNUNET_BIO_read (struct GNUNET_BIO_ReadHandle *h, const char *what, | 106 | GNUNET_BIO_read (struct GNUNET_BIO_ReadHandle *h, const char *what, |
108 | void *result, size_t len) | 107 | void *result, size_t len) |
109 | { | 108 | { |
110 | char *dst = result; | 109 | char *dst = result; |
111 | size_t min; | 110 | size_t min; |
@@ -116,38 +115,38 @@ GNUNET_BIO_read (struct GNUNET_BIO_ReadHandle *h, const char *what, | |||
116 | return GNUNET_SYSERR; | 115 | return GNUNET_SYSERR; |
117 | pos = 0; | 116 | pos = 0; |
118 | do | 117 | do |
118 | { | ||
119 | /* first, use buffer */ | ||
120 | min = h->have - h->pos; | ||
121 | if (min > 0) | ||
119 | { | 122 | { |
120 | /* first, use buffer */ | 123 | if (min > len - pos) |
121 | min = h->have - h->pos; | 124 | min = len - pos; |
122 | if (min > 0) | 125 | memcpy (&dst[pos], &h->buffer[h->pos], min); |
123 | { | 126 | h->pos += min; |
124 | if (min > len - pos) | 127 | pos += min; |
125 | min = len - pos; | 128 | } |
126 | memcpy (&dst[pos], &h->buffer[h->pos], min); | 129 | if (pos == len) |
127 | h->pos += min; | 130 | return GNUNET_OK; /* done! */ |
128 | pos += min; | 131 | GNUNET_assert (h->have == h->pos); |
129 | } | 132 | /* fill buffer */ |
130 | if (pos == len) | 133 | ret = GNUNET_DISK_file_read (h->fd, h->buffer, h->size); |
131 | return GNUNET_OK; /* done! */ | 134 | if (ret == -1) |
132 | GNUNET_assert (h->have == h->pos); | 135 | { |
133 | /* fill buffer */ | 136 | GNUNET_asprintf (&h->emsg, _("Error reading `%s': %s"), what, |
134 | ret = GNUNET_DISK_file_read (h->fd, h->buffer, h->size); | 137 | STRERROR (errno)); |
135 | if (ret == -1) | 138 | return GNUNET_SYSERR; |
136 | { | 139 | } |
137 | GNUNET_asprintf (&h->emsg, _("Error reading `%s': %s"), what, | 140 | if (ret == 0) |
138 | STRERROR (errno)); | 141 | { |
139 | return GNUNET_SYSERR; | 142 | GNUNET_asprintf (&h->emsg, _("Error reading `%s': %s"), what, |
140 | } | 143 | _("End of file")); |
141 | if (ret == 0) | 144 | return GNUNET_SYSERR; |
142 | { | ||
143 | GNUNET_asprintf (&h->emsg, _("Error reading `%s': %s"), what, | ||
144 | _("End of file")); | ||
145 | return GNUNET_SYSERR; | ||
146 | } | ||
147 | h->pos = 0; | ||
148 | h->have = ret; | ||
149 | } | 145 | } |
150 | while (pos < len); /* should always be true */ | 146 | h->pos = 0; |
147 | h->have = ret; | ||
148 | } | ||
149 | while (pos < len); /* should always be true */ | ||
151 | return GNUNET_OK; | 150 | return GNUNET_OK; |
152 | } | 151 | } |
153 | 152 | ||
@@ -163,8 +162,8 @@ GNUNET_BIO_read (struct GNUNET_BIO_ReadHandle *h, const char *what, | |||
163 | * @return GNUNET_OK on success, GNUNET_SYSERR on failure | 162 | * @return GNUNET_OK on success, GNUNET_SYSERR on failure |
164 | */ | 163 | */ |
165 | int | 164 | int |
166 | GNUNET_BIO_read_fn (struct GNUNET_BIO_ReadHandle *h, const char *file, | 165 | GNUNET_BIO_read_fn (struct GNUNET_BIO_ReadHandle *h, const char *file, int line, |
167 | int line, void *result, size_t len) | 166 | void *result, size_t len) |
168 | { | 167 | { |
169 | char what[1024]; | 168 | char what[1024]; |
170 | 169 | ||
@@ -185,41 +184,39 @@ GNUNET_BIO_read_fn (struct GNUNET_BIO_ReadHandle *h, const char *file, | |||
185 | */ | 184 | */ |
186 | int | 185 | int |
187 | GNUNET_BIO_read_string (struct GNUNET_BIO_ReadHandle *h, const char *what, | 186 | GNUNET_BIO_read_string (struct GNUNET_BIO_ReadHandle *h, const char *what, |
188 | char **result, size_t maxLen) | 187 | char **result, size_t maxLen) |
189 | { | 188 | { |
190 | char *buf; | 189 | char *buf; |
191 | uint32_t big; | 190 | uint32_t big; |
192 | 191 | ||
193 | if (GNUNET_OK != GNUNET_BIO_read_int32 (h, &big)) | 192 | if (GNUNET_OK != GNUNET_BIO_read_int32 (h, &big)) |
194 | { | 193 | { |
195 | GNUNET_free_non_null (h->emsg); | 194 | GNUNET_free_non_null (h->emsg); |
196 | GNUNET_asprintf (&h->emsg, _("Error reading length of string `%s'"), | 195 | GNUNET_asprintf (&h->emsg, _("Error reading length of string `%s'"), what); |
197 | what); | 196 | return GNUNET_SYSERR; |
198 | return GNUNET_SYSERR; | 197 | } |
199 | } | ||
200 | if (big == 0) | 198 | if (big == 0) |
201 | { | 199 | { |
202 | *result = NULL; | 200 | *result = NULL; |
203 | return GNUNET_OK; | 201 | return GNUNET_OK; |
204 | } | 202 | } |
205 | if (big > maxLen) | 203 | if (big > maxLen) |
206 | { | 204 | { |
207 | GNUNET_asprintf (&h->emsg, | 205 | GNUNET_asprintf (&h->emsg, _("String `%s' longer than allowed (%u > %u)"), |
208 | _("String `%s' longer than allowed (%u > %u)"), what, | 206 | what, big, maxLen); |
209 | big, maxLen); | 207 | return GNUNET_SYSERR; |
210 | return GNUNET_SYSERR; | 208 | } |
211 | } | ||
212 | buf = GNUNET_malloc (big); | 209 | buf = GNUNET_malloc (big); |
213 | *result = buf; | 210 | *result = buf; |
214 | buf[--big] = '\0'; | 211 | buf[--big] = '\0'; |
215 | if (big == 0) | 212 | if (big == 0) |
216 | return GNUNET_OK; | 213 | return GNUNET_OK; |
217 | if (GNUNET_OK != GNUNET_BIO_read (h, what, buf, big)) | 214 | if (GNUNET_OK != GNUNET_BIO_read (h, what, buf, big)) |
218 | { | 215 | { |
219 | GNUNET_free (buf); | 216 | GNUNET_free (buf); |
220 | *result = NULL; | 217 | *result = NULL; |
221 | return GNUNET_SYSERR; | 218 | return GNUNET_SYSERR; |
222 | } | 219 | } |
223 | return GNUNET_OK; | 220 | return GNUNET_OK; |
224 | } | 221 | } |
225 | 222 | ||
@@ -234,7 +231,7 @@ GNUNET_BIO_read_string (struct GNUNET_BIO_ReadHandle *h, const char *what, | |||
234 | */ | 231 | */ |
235 | int | 232 | int |
236 | GNUNET_BIO_read_meta_data (struct GNUNET_BIO_ReadHandle *h, const char *what, | 233 | GNUNET_BIO_read_meta_data (struct GNUNET_BIO_ReadHandle *h, const char *what, |
237 | struct GNUNET_CONTAINER_MetaData **result) | 234 | struct GNUNET_CONTAINER_MetaData **result) |
238 | { | 235 | { |
239 | uint32_t size; | 236 | uint32_t size; |
240 | char *buf; | 237 | char *buf; |
@@ -243,32 +240,30 @@ GNUNET_BIO_read_meta_data (struct GNUNET_BIO_ReadHandle *h, const char *what, | |||
243 | if (GNUNET_BIO_read_int32 (h, (int32_t *) & size) != GNUNET_OK) | 240 | if (GNUNET_BIO_read_int32 (h, (int32_t *) & size) != GNUNET_OK) |
244 | return GNUNET_SYSERR; | 241 | return GNUNET_SYSERR; |
245 | if (size == 0) | 242 | if (size == 0) |
246 | { | 243 | { |
247 | *result = NULL; | 244 | *result = NULL; |
248 | return GNUNET_OK; | 245 | return GNUNET_OK; |
249 | } | 246 | } |
250 | if (size > MAX_META_DATA) | 247 | if (size > MAX_META_DATA) |
251 | { | 248 | { |
252 | GNUNET_asprintf (&h->emsg, | 249 | GNUNET_asprintf (&h->emsg, |
253 | _ | 250 | _("Serialized metadata `%s' larger than allowed (%u>%u)"), |
254 | ("Serialized metadata `%s' larger than allowed (%u>%u)"), | 251 | what, size, MAX_META_DATA); |
255 | what, size, MAX_META_DATA); | 252 | return GNUNET_SYSERR; |
256 | return GNUNET_SYSERR; | 253 | } |
257 | } | ||
258 | buf = GNUNET_malloc (size); | 254 | buf = GNUNET_malloc (size); |
259 | if (GNUNET_OK != GNUNET_BIO_read (h, what, buf, size)) | 255 | if (GNUNET_OK != GNUNET_BIO_read (h, what, buf, size)) |
260 | { | 256 | { |
261 | GNUNET_free (buf); | 257 | GNUNET_free (buf); |
262 | return GNUNET_SYSERR; | 258 | return GNUNET_SYSERR; |
263 | } | 259 | } |
264 | meta = GNUNET_CONTAINER_meta_data_deserialize (buf, size); | 260 | meta = GNUNET_CONTAINER_meta_data_deserialize (buf, size); |
265 | if (meta == NULL) | 261 | if (meta == NULL) |
266 | { | 262 | { |
267 | GNUNET_free (buf); | 263 | GNUNET_free (buf); |
268 | GNUNET_asprintf (&h->emsg, _("Metadata `%s' failed to deserialize"), | 264 | GNUNET_asprintf (&h->emsg, _("Metadata `%s' failed to deserialize"), what); |
269 | what); | 265 | return GNUNET_SYSERR; |
270 | return GNUNET_SYSERR; | 266 | } |
271 | } | ||
272 | GNUNET_free (buf); | 267 | GNUNET_free (buf); |
273 | *result = meta; | 268 | *result = meta; |
274 | return GNUNET_OK; | 269 | return GNUNET_OK; |
@@ -286,7 +281,7 @@ GNUNET_BIO_read_meta_data (struct GNUNET_BIO_ReadHandle *h, const char *what, | |||
286 | */ | 281 | */ |
287 | int | 282 | int |
288 | GNUNET_BIO_read_int32__ (struct GNUNET_BIO_ReadHandle *h, const char *file, | 283 | GNUNET_BIO_read_int32__ (struct GNUNET_BIO_ReadHandle *h, const char *file, |
289 | int line, int32_t * i) | 284 | int line, int32_t * i) |
290 | { | 285 | { |
291 | int32_t big; | 286 | int32_t big; |
292 | 287 | ||
@@ -308,7 +303,7 @@ GNUNET_BIO_read_int32__ (struct GNUNET_BIO_ReadHandle *h, const char *file, | |||
308 | */ | 303 | */ |
309 | int | 304 | int |
310 | GNUNET_BIO_read_int64__ (struct GNUNET_BIO_ReadHandle *h, const char *file, | 305 | GNUNET_BIO_read_int64__ (struct GNUNET_BIO_ReadHandle *h, const char *file, |
311 | int line, int64_t * i) | 306 | int line, int64_t * i) |
312 | { | 307 | { |
313 | int64_t big; | 308 | int64_t big; |
314 | 309 | ||
@@ -344,15 +339,13 @@ GNUNET_BIO_write_open (const char *fn) | |||
344 | struct GNUNET_BIO_WriteHandle *h; | 339 | struct GNUNET_BIO_WriteHandle *h; |
345 | 340 | ||
346 | fd = GNUNET_DISK_file_open (fn, | 341 | fd = GNUNET_DISK_file_open (fn, |
347 | GNUNET_DISK_OPEN_WRITE | | 342 | GNUNET_DISK_OPEN_WRITE | GNUNET_DISK_OPEN_TRUNCATE |
348 | GNUNET_DISK_OPEN_TRUNCATE | | 343 | | GNUNET_DISK_OPEN_CREATE, |
349 | GNUNET_DISK_OPEN_CREATE, | 344 | GNUNET_DISK_PERM_USER_READ | |
350 | GNUNET_DISK_PERM_USER_READ | | 345 | GNUNET_DISK_PERM_USER_WRITE); |
351 | GNUNET_DISK_PERM_USER_WRITE); | ||
352 | if (NULL == fd) | 346 | if (NULL == fd) |
353 | return NULL; | 347 | return NULL; |
354 | h = | 348 | h = GNUNET_malloc (sizeof (struct GNUNET_BIO_WriteHandle) + BIO_BUFFER_SIZE); |
355 | GNUNET_malloc (sizeof (struct GNUNET_BIO_WriteHandle) + BIO_BUFFER_SIZE); | ||
356 | h->buffer = (char *) &h[1]; | 349 | h->buffer = (char *) &h[1]; |
357 | h->size = BIO_BUFFER_SIZE; | 350 | h->size = BIO_BUFFER_SIZE; |
358 | h->fd = fd; | 351 | h->fd = fd; |
@@ -374,18 +367,18 @@ GNUNET_BIO_write_close (struct GNUNET_BIO_WriteHandle *h) | |||
374 | int ret; | 367 | int ret; |
375 | 368 | ||
376 | if (NULL == h->fd) | 369 | if (NULL == h->fd) |
377 | { | 370 | { |
378 | ret = GNUNET_SYSERR; | 371 | ret = GNUNET_SYSERR; |
379 | } | 372 | } |
380 | else | 373 | else |
381 | { | 374 | { |
382 | wrt = GNUNET_DISK_file_write (h->fd, h->buffer, h->have); | 375 | wrt = GNUNET_DISK_file_write (h->fd, h->buffer, h->have); |
383 | if (wrt == h->have) | 376 | if (wrt == h->have) |
384 | ret = GNUNET_OK; | 377 | ret = GNUNET_OK; |
385 | else | 378 | else |
386 | ret = GNUNET_SYSERR; | 379 | ret = GNUNET_SYSERR; |
387 | GNUNET_DISK_file_close (h->fd); | 380 | GNUNET_DISK_file_close (h->fd); |
388 | } | 381 | } |
389 | GNUNET_free (h); | 382 | GNUNET_free (h); |
390 | return ret; | 383 | return ret; |
391 | } | 384 | } |
@@ -401,7 +394,7 @@ GNUNET_BIO_write_close (struct GNUNET_BIO_WriteHandle *h) | |||
401 | */ | 394 | */ |
402 | int | 395 | int |
403 | GNUNET_BIO_write (struct GNUNET_BIO_WriteHandle *h, const void *buffer, | 396 | GNUNET_BIO_write (struct GNUNET_BIO_WriteHandle *h, const void *buffer, |
404 | size_t n) | 397 | size_t n) |
405 | { | 398 | { |
406 | const char *src = buffer; | 399 | const char *src = buffer; |
407 | size_t min; | 400 | size_t min; |
@@ -412,27 +405,27 @@ GNUNET_BIO_write (struct GNUNET_BIO_WriteHandle *h, const void *buffer, | |||
412 | return GNUNET_SYSERR; | 405 | return GNUNET_SYSERR; |
413 | pos = 0; | 406 | pos = 0; |
414 | do | 407 | do |
408 | { | ||
409 | /* first, just use buffer */ | ||
410 | min = h->size - h->have; | ||
411 | if (min > n - pos) | ||
412 | min = n - pos; | ||
413 | memcpy (&h->buffer[h->have], &src[pos], min); | ||
414 | pos += min; | ||
415 | h->have += min; | ||
416 | if (pos == n) | ||
417 | return GNUNET_OK; /* done */ | ||
418 | GNUNET_assert (h->have == h->size); | ||
419 | ret = GNUNET_DISK_file_write (h->fd, h->buffer, h->size); | ||
420 | if (ret != h->size) | ||
415 | { | 421 | { |
416 | /* first, just use buffer */ | 422 | GNUNET_DISK_file_close (h->fd); |
417 | min = h->size - h->have; | 423 | h->fd = NULL; |
418 | if (min > n - pos) | 424 | return GNUNET_SYSERR; /* error */ |
419 | min = n - pos; | ||
420 | memcpy (&h->buffer[h->have], &src[pos], min); | ||
421 | pos += min; | ||
422 | h->have += min; | ||
423 | if (pos == n) | ||
424 | return GNUNET_OK; /* done */ | ||
425 | GNUNET_assert (h->have == h->size); | ||
426 | ret = GNUNET_DISK_file_write (h->fd, h->buffer, h->size); | ||
427 | if (ret != h->size) | ||
428 | { | ||
429 | GNUNET_DISK_file_close (h->fd); | ||
430 | h->fd = NULL; | ||
431 | return GNUNET_SYSERR; /* error */ | ||
432 | } | ||
433 | h->have = 0; | ||
434 | } | 425 | } |
435 | while (pos < n); /* should always be true */ | 426 | h->have = 0; |
427 | } | ||
428 | while (pos < n); /* should always be true */ | ||
436 | GNUNET_break (0); | 429 | GNUNET_break (0); |
437 | return GNUNET_OK; | 430 | return GNUNET_OK; |
438 | } | 431 | } |
@@ -468,7 +461,7 @@ GNUNET_BIO_write_string (struct GNUNET_BIO_WriteHandle *h, const char *s) | |||
468 | */ | 461 | */ |
469 | int | 462 | int |
470 | GNUNET_BIO_write_meta_data (struct GNUNET_BIO_WriteHandle *h, | 463 | GNUNET_BIO_write_meta_data (struct GNUNET_BIO_WriteHandle *h, |
471 | const struct GNUNET_CONTAINER_MetaData *m) | 464 | const struct GNUNET_CONTAINER_MetaData *m) |
472 | { | 465 | { |
473 | ssize_t size; | 466 | ssize_t size; |
474 | char *buf; | 467 | char *buf; |
@@ -477,19 +470,19 @@ GNUNET_BIO_write_meta_data (struct GNUNET_BIO_WriteHandle *h, | |||
477 | return GNUNET_BIO_write_int32 (h, 0); | 470 | return GNUNET_BIO_write_int32 (h, 0); |
478 | buf = NULL; | 471 | buf = NULL; |
479 | size = | 472 | size = |
480 | GNUNET_CONTAINER_meta_data_serialize (m, &buf, MAX_META_DATA, | 473 | GNUNET_CONTAINER_meta_data_serialize (m, &buf, MAX_META_DATA, |
481 | GNUNET_CONTAINER_META_DATA_SERIALIZE_PART); | 474 | GNUNET_CONTAINER_META_DATA_SERIALIZE_PART); |
482 | if (size == -1) | 475 | if (size == -1) |
483 | { | 476 | { |
484 | GNUNET_free (buf); | 477 | GNUNET_free (buf); |
485 | return GNUNET_SYSERR; | 478 | return GNUNET_SYSERR; |
486 | } | 479 | } |
487 | if ((GNUNET_OK != GNUNET_BIO_write_int32 (h, (uint32_t) size)) || | 480 | if ((GNUNET_OK != GNUNET_BIO_write_int32 (h, (uint32_t) size)) || |
488 | (GNUNET_OK != GNUNET_BIO_write (h, buf, size))) | 481 | (GNUNET_OK != GNUNET_BIO_write (h, buf, size))) |
489 | { | 482 | { |
490 | GNUNET_free (buf); | 483 | GNUNET_free (buf); |
491 | return GNUNET_SYSERR; | 484 | return GNUNET_SYSERR; |
492 | } | 485 | } |
493 | GNUNET_free (buf); | 486 | GNUNET_free (buf); |
494 | return GNUNET_OK; | 487 | return GNUNET_OK; |
495 | } | 488 | } |