GNUnet  0.10.x
bio.c
Go to the documentation of this file.
1 /*
2  This file is part of GNUnet.
3  Copyright (C) 2006, 2009, 2013 GNUnet e.V.
4 
5  GNUnet is free software: you can redistribute it and/or modify it
6  under the terms of the GNU Affero General Public License as published
7  by the Free Software Foundation, either version 3 of the License,
8  or (at your 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  Affero General Public License for more details.
14 
15  You should have received a copy of the GNU Affero General Public License
16  along with this program. If not, see <http://www.gnu.org/licenses/>.
17 
18  SPDX-License-Identifier: AGPL3.0-or-later
19 */
25 #include "platform.h"
26 #include "gnunet_util_lib.h"
27 
28 #define LOG(kind,...) GNUNET_log_from (kind, "util-bio",__VA_ARGS__)
29 
30 #ifndef PATH_MAX
31 
34 #define PATH_MAX 4096
35 #endif
36 
37 
41 #define BIO_BUFFER_SIZE 65536
42 
47 #define MAX_META_DATA (1024 * 1024)
48 
49 
54 {
59 
63  char *emsg;
64 
68  char *buffer;
69 
73  size_t have;
74 
78  size_t size;
79 
83  off_t pos;
84 };
85 
86 
93 struct GNUNET_BIO_ReadHandle *
94 GNUNET_BIO_read_open (const char *fn)
95 {
96  struct GNUNET_DISK_FileHandle *fd;
97  struct GNUNET_BIO_ReadHandle *h;
98 
100  if (NULL == fd)
101  return NULL;
102  h = GNUNET_malloc (sizeof (struct GNUNET_BIO_ReadHandle) + BIO_BUFFER_SIZE);
103  h->buffer = (char *) &h[1];
104  h->size = BIO_BUFFER_SIZE;
105  h->fd = fd;
106  return h;
107 }
108 
109 
118 int
120  char **emsg)
121 {
122  int err;
123 
124  err = (NULL == h->emsg) ? GNUNET_OK : GNUNET_SYSERR;
125  if (emsg != NULL)
126  *emsg = h->emsg;
127  else
130  GNUNET_free (h);
131  return err;
132 }
133 
134 
144 int
146  const char *what,
147  void *result, size_t len)
148 {
149  char *dst = result;
150  size_t min;
151  size_t pos;
152  ssize_t ret;
153 
154  if (NULL != h->emsg)
155  return GNUNET_SYSERR;
156  pos = 0;
157  do
158  {
159  /* first, use buffer */
160  min = h->have - h->pos;
161  if (min > 0)
162  {
163  if (min > len - pos)
164  min = len - pos;
165  GNUNET_memcpy (&dst[pos],
166  &h->buffer[h->pos],
167  min);
168  h->pos += min;
169  pos += min;
170  }
171  if (pos == len)
172  return GNUNET_OK; /* done! */
173  GNUNET_assert (((off_t) h->have) == h->pos);
174  /* fill buffer */
175  ret = GNUNET_DISK_file_read (h->fd,
176  h->buffer,
177  h->size);
178  if (-1 == ret)
179  {
180  GNUNET_asprintf (&h->emsg,
181  _("Error reading `%s': %s"),
182  what,
183  STRERROR (errno));
184  return GNUNET_SYSERR;
185  }
186  if (0 == ret)
187  {
188  GNUNET_asprintf (&h->emsg,
189  _("Error reading `%s': %s"),
190  what,
191  _("End of file"));
192  return GNUNET_SYSERR;
193  }
194  h->pos = 0;
195  h->have = ret;
196  }
197  while (pos < len); /* should always be true */
198  return GNUNET_OK;
199 }
200 
201 
212 int
214  const char *file,
215  int line,
216  void *result,
217  size_t len)
218 {
219  char what[PATH_MAX + 1024];
220 
221  GNUNET_snprintf (what, sizeof (what), "%s:%d", file, line);
222  return GNUNET_BIO_read (h, what, result, len);
223 }
224 
225 
236 int
238  const char *what,
239  char **result,
240  size_t max_length)
241 {
242  char *buf;
243  uint32_t big;
244 
245  if (GNUNET_OK != GNUNET_BIO_read_int32 (h, &big))
246  {
248  GNUNET_asprintf (&h->emsg, _("Error reading length of string `%s'"), what);
249  return GNUNET_SYSERR;
250  }
251  if (0 == big)
252  {
253  *result = NULL;
254  return GNUNET_OK;
255  }
256  if (big > max_length)
257  {
258  GNUNET_asprintf (&h->emsg, _("String `%s' longer than allowed (%u > %u)"),
259  what, big, max_length);
260  return GNUNET_SYSERR;
261  }
262  buf = GNUNET_malloc (big);
263  *result = buf;
264  buf[--big] = '\0';
265  if (0 == big)
266  return GNUNET_OK;
267  if (GNUNET_OK != GNUNET_BIO_read (h, what, buf, big))
268  {
269  GNUNET_free (buf);
270  *result = NULL;
271  return GNUNET_SYSERR;
272  }
273  return GNUNET_OK;
274 }
275 
276 
285 int
287  const char *what,
289 {
290  uint32_t size;
291  char *buf;
293 
294  if (GNUNET_OK !=
296  (int32_t *) & size))
297  return GNUNET_SYSERR;
298  if (size == 0)
299  {
300  *result = NULL;
301  return GNUNET_OK;
302  }
303  if (size > MAX_META_DATA)
304  {
305  GNUNET_asprintf (&h->emsg,
306  _("Serialized metadata `%s' larger than allowed (%u>%u)"),
307  what,
308  size,
309  MAX_META_DATA);
310  return GNUNET_SYSERR;
311  }
312  buf = GNUNET_malloc (size);
313  if (GNUNET_OK !=
314  GNUNET_BIO_read (h,
315  what,
316  buf,
317  size))
318  {
319  GNUNET_free (buf);
320  return GNUNET_SYSERR;
321  }
323  size);
324  if (NULL == meta)
325  {
326  GNUNET_free (buf);
327  GNUNET_asprintf (&h->emsg,
328  _("Metadata `%s' failed to deserialize"),
329  what);
330  return GNUNET_SYSERR;
331  }
332  GNUNET_free (buf);
333  *result = meta;
334  return GNUNET_OK;
335 }
336 
337 
347 int
349  const char *file,
350  int line,
351  int32_t * i)
352 {
353  int32_t big;
354 
355  if (GNUNET_OK !=
357  file,
358  line,
359  &big,
360  sizeof (int32_t)))
361  return GNUNET_SYSERR;
362  *i = ntohl (big);
363  return GNUNET_OK;
364 }
365 
366 
376 int
378  const char *file,
379  int line,
380  int64_t *i)
381 {
382  int64_t big;
383 
384  if (GNUNET_OK !=
386  file,
387  line,
388  &big,
389  sizeof (int64_t)))
390  return GNUNET_SYSERR;
391  *i = GNUNET_ntohll (big);
392  return GNUNET_OK;
393 }
394 
395 
400 {
405 
409  char *buffer;
410 
414  size_t have;
415 
419  size_t size;
420 };
421 
422 
429 struct GNUNET_BIO_WriteHandle *
431 {
432  struct GNUNET_DISK_FileHandle *fd;
433  struct GNUNET_BIO_WriteHandle *h;
434 
435  fd = GNUNET_DISK_file_open (fn,
440  if (NULL == fd)
441  return NULL;
442  h = GNUNET_malloc (sizeof (struct GNUNET_BIO_WriteHandle) + BIO_BUFFER_SIZE);
443  h->buffer = (char *) &h[1];
444  h->size = BIO_BUFFER_SIZE;
445  h->fd = fd;
446  return h;
447 }
448 
449 
456 int
458 {
459  int ret;
460 
461  ret = GNUNET_SYSERR;
462  if ( (NULL != h->fd) &&
463  (GNUNET_OK == (ret = GNUNET_BIO_flush (h))) )
465  GNUNET_free (h);
466  return ret;
467 }
468 
469 
477 int
479 {
480  ssize_t ret;
481 
482  ret = GNUNET_DISK_file_write (h->fd,
483  h->buffer,
484  h->have);
485  if (ret != (ssize_t) h->have)
486  {
488  h->fd = NULL;
489  return GNUNET_SYSERR; /* error */
490  }
491  h->have = 0;
492  return GNUNET_OK;
493 }
494 
495 
504 int
506  const void *buffer,
507  size_t n)
508 {
509  const char *src = buffer;
510  size_t min;
511  size_t pos;
512 
513  if (NULL == h->fd)
514  return GNUNET_SYSERR;
515  pos = 0;
516  do
517  {
518  /* first, just use buffer */
519  min = h->size - h->have;
520  if (min > n - pos)
521  min = n - pos;
522  GNUNET_memcpy (&h->buffer[h->have],
523  &src[pos],
524  min);
525  pos += min;
526  h->have += min;
527  if (pos == n)
528  return GNUNET_OK; /* done */
529  GNUNET_assert (h->have == h->size);
530  if (GNUNET_OK != GNUNET_BIO_flush (h))
531  return GNUNET_SYSERR; /* error */
532  }
533  while (pos < n); /* should always be true */
534  GNUNET_break (0);
535  return GNUNET_OK;
536 }
537 
538 
546 int
548  const char *s)
549 {
550  uint32_t slen;
551 
552  slen = (uint32_t) ((s == NULL) ? 0 : strlen (s) + 1);
553  if (GNUNET_OK != GNUNET_BIO_write_int32 (h, slen))
554  return GNUNET_SYSERR;
555  if (0 != slen)
556  return GNUNET_BIO_write (h, s, slen - 1);
557  return GNUNET_OK;
558 }
559 
560 
568 int
570  const struct GNUNET_CONTAINER_MetaData *m)
571 {
572  ssize_t size;
573  char *buf;
574 
575  if (m == NULL)
576  return GNUNET_BIO_write_int32 (h, 0);
577  buf = NULL;
578  size =
581  if (size == -1)
582  {
583  GNUNET_free (buf);
584  return GNUNET_SYSERR;
585  }
586  if ((GNUNET_OK != GNUNET_BIO_write_int32 (h, (uint32_t) size)) ||
587  (GNUNET_OK != GNUNET_BIO_write (h, buf, size)))
588  {
589  GNUNET_free (buf);
590  return GNUNET_SYSERR;
591  }
592  GNUNET_free (buf);
593  return GNUNET_OK;
594 }
595 
596 
604 int
606  int32_t i)
607 {
608  int32_t big;
609 
610  big = htonl (i);
611  return GNUNET_BIO_write (h, &big, sizeof (int32_t));
612 }
613 
614 
622 int
624  int64_t i)
625 {
626  int64_t big;
627 
628  big = GNUNET_htonll (i);
629  return GNUNET_BIO_write (h, &big, sizeof (int64_t));
630 }
631 
632 
633 /* end of bio.c */
int GNUNET_BIO_write_meta_data(struct GNUNET_BIO_WriteHandle *h, const struct GNUNET_CONTAINER_MetaData *m)
Write metadata container to a file.
Definition: bio.c:569
Open the file for reading.
Create file if it doesn&#39;t exist.
ssize_t GNUNET_CONTAINER_meta_data_serialize(const struct GNUNET_CONTAINER_MetaData *md, char **target, size_t max, enum GNUNET_CONTAINER_MetaDataSerializationOptions opt)
Serialize meta-data to target.
int GNUNET_DISK_file_close(struct GNUNET_DISK_FileHandle *h)
Close an open file.
Definition: disk.c:1817
If not enough space is available, it is acceptable to only serialize some of the metadata.
int GNUNET_snprintf(char *buf, size_t size, const char *format,...)
Like snprintf, just aborts if the buffer is of insufficient size.
ssize_t GNUNET_DISK_file_read(const struct GNUNET_DISK_FileHandle *h, void *result, size_t len)
Read the contents of a binary file into a buffer.
Definition: disk.c:881
int GNUNET_BIO_write_string(struct GNUNET_BIO_WriteHandle *h, const char *s)
Write a string to a file.
Definition: bio.c:547
int GNUNET_BIO_flush(struct GNUNET_BIO_WriteHandle *h)
Force a buffered writer to flush its buffer.
Definition: bio.c:478
#define GNUNET_assert(cond)
Use this for fatal errors that cannot be handled.
int GNUNET_BIO_write_int64(struct GNUNET_BIO_WriteHandle *h, int64_t i)
Write an (u)int64_t.
Definition: bio.c:623
#define STRERROR(i)
Definition: plibc.h:676
int GNUNET_BIO_read_int32__(struct GNUNET_BIO_ReadHandle *h, const char *file, int line, int32_t *i)
Read an (u)int32_t.
Definition: bio.c:348
struct GNUNET_DISK_FileHandle * fd
Underlying file abstraction.
Definition: bio.c:58
Nobody is allowed to do anything to the file.
struct GNUNET_CONTAINER_MetaData * GNUNET_CONTAINER_meta_data_deserialize(const char *input, size_t size)
Deserialize meta-data.
#define MAX_META_DATA
Maximum size allowed for meta data written/read from disk.
Definition: bio.c:47
#define GNUNET_OK
Named constants for return values.
Definition: gnunet_common.h:78
#define GNUNET_free_non_null(ptr)
Free the memory pointed to by ptr if ptr is not NULL.
#define BIO_BUFFER_SIZE
Size for I/O buffers.
Definition: bio.c:41
struct GNUNET_DISK_FileHandle * fd
Underlying file handle.
Definition: bio.c:404
static int ret
Final status code.
Definition: gnunet-arm.c:89
int GNUNET_BIO_read_close(struct GNUNET_BIO_ReadHandle *h, char **emsg)
Close an open file.
Definition: bio.c:119
size_t size
Total size of buffer.
Definition: bio.c:78
#define GNUNET_break(cond)
Use this for internal assertion violations that are not fatal (can be handled) but should not occur...
static struct GNUNET_ARM_Handle * h
Connection with ARM.
Definition: gnunet-arm.c:94
#define _(String)
GNU gettext support macro.
Definition: platform.h:208
struct GNUNET_BIO_ReadHandle * GNUNET_BIO_read_open(const char *fn)
Open a file for reading.
Definition: bio.c:94
static struct GNUNET_ARM_MonitorHandle * m
Monitor connection with ARM.
Definition: gnunet-arm.c:99
int GNUNET_BIO_read(struct GNUNET_BIO_ReadHandle *h, const char *what, void *result, size_t len)
Read the contents of a binary file into a buffer.
Definition: bio.c:145
int GNUNET_asprintf(char **buf, const char *format,...)
Like asprintf, just portable.
Meta data to associate with a file, directory or namespace.
#define GNUNET_memcpy(dst, src, n)
static char * line
Desired phone line (string to be converted to a hash).
static char * fn
Filename of the unique file.
Truncate file if it exists.
ssize_t GNUNET_DISK_file_write(const struct GNUNET_DISK_FileHandle *h, const void *buffer, size_t n)
Write a buffer to a file.
Definition: disk.c:1049
static char buf[2048]
size_t have
Number of bytes available in read buffer.
Definition: bio.c:73
size_t have
Number of bytes already in buffer.
Definition: bio.c:414
static int result
Global testing status.
char * buffer
I/O buffer.
Definition: bio.c:409
Handle for buffered writing.
Definition: bio.c:399
char * buffer
I/O buffer.
Definition: bio.c:68
off_t pos
Current read offset in buffer.
Definition: bio.c:83
int GNUNET_BIO_read_string(struct GNUNET_BIO_ReadHandle *h, const char *what, char **result, size_t max_length)
Read 0-terminated string from a file.
Definition: bio.c:237
uint64_t GNUNET_htonll(uint64_t n)
Convert unsigned 64-bit integer to network byte order.
Definition: common_endian.c:35
#define GNUNET_SYSERR
Definition: gnunet_common.h:79
#define GNUNET_BIO_read_int32(h, i)
Read an (u)int32_t.
Open the file for writing.
int GNUNET_BIO_write_close(struct GNUNET_BIO_WriteHandle *h)
Close an open file for writing.
Definition: bio.c:457
#define PATH_MAX
Assumed maximum path length (for source file names).
Definition: bio.c:34
int GNUNET_BIO_read_fn(struct GNUNET_BIO_ReadHandle *h, const char *file, int line, void *result, size_t len)
Read the contents of a binary file into a buffer.
Definition: bio.c:213
struct GNUNET_BIO_WriteHandle * GNUNET_BIO_write_open(const char *fn)
Open a file for writing.
Definition: bio.c:430
static struct GNUNET_CONTAINER_MetaData * meta
Meta-data provided via command-line option.
int GNUNET_BIO_read_int64__(struct GNUNET_BIO_ReadHandle *h, const char *file, int line, int64_t *i)
Read an (u)int64_t.
Definition: bio.c:377
size_t size
Total size of buffer.
Definition: bio.c:419
int GNUNET_BIO_write_int32(struct GNUNET_BIO_WriteHandle *h, int32_t i)
Write an (u)int32_t.
Definition: bio.c:605
int GNUNET_BIO_read_meta_data(struct GNUNET_BIO_ReadHandle *h, const char *what, struct GNUNET_CONTAINER_MetaData **result)
Read metadata container from a file.
Definition: bio.c:286
int GNUNET_BIO_write(struct GNUNET_BIO_WriteHandle *h, const void *buffer, size_t n)
Write a buffer to a file.
Definition: bio.c:505
struct GNUNET_DISK_FileHandle * GNUNET_DISK_file_open(const char *fn, enum GNUNET_DISK_OpenFlags flags, enum GNUNET_DISK_AccessPermissions perm)
Open a file.
Definition: disk.c:1673
char * emsg
Error message, NULL if there were no errors.
Definition: bio.c:63
Handle used to access files (and pipes).
#define GNUNET_malloc(size)
Wrapper around malloc.
Handle for buffered reading.
Definition: bio.c:53
uint64_t GNUNET_ntohll(uint64_t n)
Convert unsigned 64-bit integer to host byte order.
Definition: common_endian.c:48
#define GNUNET_free(ptr)
Wrapper around free.
uint16_t len
length of data (which is always a uint32_t, but presumably this can be used to specify that fewer byt...