GNUnet  0.11.x
disk.c
Go to the documentation of this file.
1 /*
2  This file is part of GNUnet.
3  Copyright (C) 2001--2013, 2016, 2018 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  */
26 #include "platform.h"
27 #include "disk.h"
28 #include "gnunet_strings_lib.h"
29 #include "gnunet_disk_lib.h"
30 
31 #define LOG(kind, ...) GNUNET_log_from (kind, "util-disk", __VA_ARGS__)
32 
33 #define LOG_STRERROR(kind, syscall) \
34  GNUNET_log_from_strerror (kind, "util-disk", syscall)
35 
36 #define LOG_STRERROR_FILE(kind, syscall, filename) \
37  GNUNET_log_from_strerror_file (kind, "util-disk", syscall, filename)
38 
42 #define COPY_BLK_SIZE 65536
43 
44 #include <sys/types.h>
45 #if HAVE_SYS_VFS_H
46 #include <sys/vfs.h>
47 #endif
48 #if HAVE_SYS_PARAM_H
49 #include <sys/param.h>
50 #endif
51 #if HAVE_SYS_MOUNT_H
52 #include <sys/mount.h>
53 #endif
54 #if HAVE_SYS_STATVFS_H
55 #include <sys/statvfs.h>
56 #endif
57 
58 #ifndef S_ISLNK
59 #define _IFMT 0170000 /* type of file */
60 #define _IFLNK 0120000 /* symbolic link */
61 #define S_ISLNK(m) (((m) & _IFMT) == _IFLNK)
62 #endif
63 
64 
69 {
75 };
76 
77 
83 {
87  uint64_t total;
88 
93 
98 };
99 
100 
108 static int
110 {
111  int mode;
112 
113  mode = 0;
114  if (perm & GNUNET_DISK_PERM_USER_READ)
115  mode |= S_IRUSR;
116  if (perm & GNUNET_DISK_PERM_USER_WRITE)
117  mode |= S_IWUSR;
118  if (perm & GNUNET_DISK_PERM_USER_EXEC)
119  mode |= S_IXUSR;
120  if (perm & GNUNET_DISK_PERM_GROUP_READ)
121  mode |= S_IRGRP;
122  if (perm & GNUNET_DISK_PERM_GROUP_WRITE)
123  mode |= S_IWGRP;
124  if (perm & GNUNET_DISK_PERM_GROUP_EXEC)
125  mode |= S_IXGRP;
126  if (perm & GNUNET_DISK_PERM_OTHER_READ)
127  mode |= S_IROTH;
128  if (perm & GNUNET_DISK_PERM_OTHER_WRITE)
129  mode |= S_IWOTH;
130  if (perm & GNUNET_DISK_PERM_OTHER_EXEC)
131  mode |= S_IXOTH;
132 
133  return mode;
134 }
135 
136 
145 static enum GNUNET_GenericReturnValue
146 get_size_rec (void *cls, const char *fn)
147 {
148  struct GetFileSizeData *gfsd = cls;
149 
150 #if defined(HAVE_STAT64) && \
151  ! (defined(_FILE_OFFSET_BITS) && _FILE_OFFSET_BITS == 64)
152  struct stat64 buf;
153 
154  if (0 != stat64 (fn, &buf))
155  {
157  return GNUNET_SYSERR;
158  }
159 #else
160  struct stat buf;
161 
162  if (0 != stat (fn, &buf))
163  {
165  return GNUNET_SYSERR;
166  }
167 #endif
168  if ((S_ISDIR (buf.st_mode)) && (gfsd->single_file_mode == GNUNET_YES))
169  {
170  errno = EISDIR;
171  return GNUNET_SYSERR;
172  }
173  if ((! S_ISLNK (buf.st_mode)) || (gfsd->include_sym_links == GNUNET_YES))
174  gfsd->total += buf.st_size;
175  if ((S_ISDIR (buf.st_mode)) && (0 == access (fn, X_OK)) &&
176  ((! S_ISLNK (buf.st_mode)) || (gfsd->include_sym_links == GNUNET_YES)))
177  {
179  return GNUNET_SYSERR;
180  }
181  return GNUNET_OK;
182 }
183 
184 
187 {
188  return ((! h) || (h->fd == -1)) ? GNUNET_YES : GNUNET_NO;
189 }
190 
191 
194  off_t *size)
195 {
196  struct stat sbuf;
197 
198  if (0 != fstat (fh->fd, &sbuf))
199  return GNUNET_SYSERR;
200  *size = sbuf.st_size;
201  return GNUNET_OK;
202 }
203 
204 
205 off_t
207  off_t offset,
208  enum GNUNET_DISK_Seek whence)
209 {
210  static int t[] = { SEEK_SET, SEEK_CUR, SEEK_END };
211 
212  if (h == NULL)
213  {
214  errno = EINVAL;
215  return GNUNET_SYSERR;
216  }
217  return lseek (h->fd, offset, t[whence]);
218 }
219 
220 
223  uint64_t *size,
224  int include_symbolic_links,
225  int single_file_mode)
226 {
227  struct GetFileSizeData gfsd;
229 
230  GNUNET_assert (size != NULL);
231  gfsd.total = 0;
232  gfsd.include_sym_links = include_symbolic_links;
234  ret = get_size_rec (&gfsd, filename);
235  *size = gfsd.total;
236  return ret;
237 }
238 
239 
242  uint64_t *dev,
243  uint64_t *ino)
244 {
245 #if HAVE_STAT
246  {
247  struct stat sbuf;
248 
249  if (0 != stat (filename, &sbuf))
250  {
251  return GNUNET_SYSERR;
252  }
253  *ino = (uint64_t) sbuf.st_ino;
254  }
255 #else
256  *ino = 0;
257 #endif
258 #if HAVE_STATVFS
259  {
260  struct statvfs fbuf;
261 
262  if (0 != statvfs (filename, &fbuf))
263  {
264  return GNUNET_SYSERR;
265  }
266  *dev = (uint64_t) fbuf.f_fsid;
267  }
268 #elif HAVE_STATFS
269  {
270  struct statfs fbuf;
271 
272  if (0 != statfs (filename, &fbuf))
273  {
274  return GNUNET_SYSERR;
275  }
276  *dev =
277  ((uint64_t) fbuf.f_fsid.val[0]) << 32 || ((uint64_t) fbuf.f_fsid.val[1]);
278  }
279 #else
280  *dev = 0;
281 #endif
282  return GNUNET_OK;
283 }
284 
285 
292 static char *
293 mktemp_name (const char *t)
294 {
295  const char *tmpdir;
296  char *tmpl;
297  char *fn;
298 
299  if ((t[0] != '/') && (t[0] != '\\'))
300  {
301  /* FIXME: This uses system codepage on W32, not UTF-8 */
302  tmpdir = getenv ("TMPDIR");
303  if (NULL == tmpdir)
304  tmpdir = getenv ("TMP");
305  if (NULL == tmpdir)
306  tmpdir = getenv ("TEMP");
307  if (NULL == tmpdir)
308  tmpdir = "/tmp";
309  GNUNET_asprintf (&tmpl, "%s/%s%s", tmpdir, t, "XXXXXX");
310  }
311  else
312  {
313  GNUNET_asprintf (&tmpl, "%s%s", t, "XXXXXX");
314  }
315  fn = tmpl;
316  return fn;
317 }
318 
319 
320 void
322  int require_uid_match,
323  int require_gid_match)
324 {
325  mode_t mode;
326 
327  if (GNUNET_YES == require_uid_match)
328  mode = S_IRUSR | S_IWUSR | S_IXUSR;
329  else if (GNUNET_YES == require_gid_match)
330  mode = S_IRUSR | S_IWUSR | S_IXUSR | S_IRGRP | S_IWGRP | S_IXGRP;
331  else
332  mode = S_IRUSR | S_IWUSR | S_IXUSR | S_IRGRP | S_IWGRP | S_IXGRP | S_IROTH
333  | S_IWOTH | S_IXOTH;
334  if (0 != chmod (fn, mode))
336 }
337 
338 
339 char *
340 GNUNET_DISK_mkdtemp (const char *t)
341 {
342  char *fn;
343  mode_t omask;
344 
345  omask = umask (S_IWGRP | S_IWOTH | S_IRGRP | S_IROTH);
346  fn = mktemp_name (t);
347  if (fn != mkdtemp (fn))
348  {
350  GNUNET_free (fn);
351  umask (omask);
352  return NULL;
353  }
354  umask (omask);
355  return fn;
356 }
357 
358 
359 void
360 GNUNET_DISK_file_backup (const char *fil)
361 {
362  size_t slen;
363  char *target;
364  unsigned int num;
365 
366  slen = strlen (fil) + 20;
367  target = GNUNET_malloc (slen);
368  num = 0;
369  do
370  {
371  GNUNET_snprintf (target, slen, "%s.%u~", fil, num++);
372  }
373  while (0 == access (target, F_OK));
374  if (0 != rename (fil, target))
376  GNUNET_free (target);
377 }
378 
379 
380 char *
381 GNUNET_DISK_mktemp (const char *t)
382 {
383  int fd;
384  char *fn;
385  mode_t omask;
386 
387  omask = umask (S_IWGRP | S_IWOTH | S_IRGRP | S_IROTH);
388  fn = mktemp_name (t);
389  if (-1 == (fd = mkstemp (fn)))
390  {
392  GNUNET_free (fn);
393  umask (omask);
394  return NULL;
395  }
396  umask (omask);
397  if (0 != close (fd))
399  return fn;
400 }
401 
402 
404 GNUNET_DISK_directory_test (const char *fil, int is_readable)
405 {
406  struct stat filestat;
407  int ret;
408 
409  ret = stat (fil, &filestat);
410  if (ret != 0)
411  {
412  if (errno != ENOENT)
414  return GNUNET_SYSERR;
415  }
416  if (! S_ISDIR (filestat.st_mode))
417  {
419  "A file already exits with the same name %s\n",
420  fil);
421  return GNUNET_NO;
422  }
423  if (GNUNET_YES == is_readable)
424  ret = access (fil, R_OK | X_OK);
425  else
426  ret = access (fil, X_OK);
427  if (ret < 0)
428  {
430  return GNUNET_NO;
431  }
432  return GNUNET_YES;
433 }
434 
435 
437 GNUNET_DISK_file_test (const char *fil)
438 {
439  struct stat filestat;
440  int ret;
441  char *rdir;
442 
443  rdir = GNUNET_STRINGS_filename_expand (fil);
444  if (rdir == NULL)
445  return GNUNET_SYSERR;
446 
447  ret = stat (rdir, &filestat);
448  if (0 != ret)
449  {
450  if (errno != ENOENT)
451  {
453  GNUNET_free (rdir);
454  return GNUNET_SYSERR;
455  }
456  GNUNET_free (rdir);
457  return GNUNET_NO;
458  }
459  if (! S_ISREG (filestat.st_mode))
460  {
461  GNUNET_free (rdir);
462  return GNUNET_NO;
463  }
464  if (access (rdir, F_OK) < 0)
465  {
467  GNUNET_free (rdir);
468  return GNUNET_SYSERR;
469  }
470  GNUNET_free (rdir);
471  return GNUNET_YES;
472 }
473 
474 
477 {
478  char *rdir;
479  unsigned int len;
480  unsigned int pos;
481  unsigned int pos2;
482  int ret = GNUNET_OK;
483 
484  rdir = GNUNET_STRINGS_filename_expand (dir);
485  if (rdir == NULL)
486  {
487  GNUNET_break (0);
488  return GNUNET_SYSERR;
489  }
490 
491  len = strlen (rdir);
492 
493  pos = 1; /* skip heading '/' */
494 
495  /* Check which low level directories already exist */
496  pos2 = len;
497  rdir[len] = DIR_SEPARATOR;
498  while (pos <= pos2)
499  {
500  if (DIR_SEPARATOR == rdir[pos2])
501  {
502  rdir[pos2] = '\0';
504  if (GNUNET_NO == ret)
505  {
507  "Creating directory `%s' failed",
508  rdir);
509  GNUNET_free (rdir);
510  return GNUNET_SYSERR;
511  }
512  rdir[pos2] = DIR_SEPARATOR;
513  if (GNUNET_YES == ret)
514  {
515  pos2++;
516  break;
517  }
518  }
519  pos2--;
520  }
521  rdir[len] = '\0';
522  if (pos < pos2)
523  pos = pos2;
524  /* Start creating directories */
525  while (pos <= len)
526  {
527  if ((rdir[pos] == DIR_SEPARATOR) || (pos == len))
528  {
529  rdir[pos] = '\0';
531  if (GNUNET_NO == ret)
532  {
534  "Creating directory `%s' failed",
535  rdir);
536  GNUNET_free (rdir);
537  return GNUNET_SYSERR;
538  }
539  if (GNUNET_SYSERR == ret)
540  {
541  ret = mkdir (rdir,
542  S_IRUSR | S_IWUSR | S_IXUSR | S_IRGRP | S_IXGRP | S_IROTH
543  | S_IXOTH); /* 755 */
544 
545  if ((ret != 0) && (errno != EEXIST))
546  {
548  GNUNET_free (rdir);
549  return GNUNET_SYSERR;
550  }
551  }
552  rdir[pos] = DIR_SEPARATOR;
553  }
554  pos++;
555  }
556  GNUNET_free (rdir);
557  return GNUNET_OK;
558 }
559 
560 
563 {
564  char *rdir;
565  size_t len;
566  int eno;
568 
569  rdir = GNUNET_STRINGS_filename_expand (filename);
570  if (NULL == rdir)
571  {
572  errno = EINVAL;
573  return GNUNET_SYSERR;
574  }
575  if (0 == access (rdir, W_OK))
576  {
577  GNUNET_free (rdir);
578  return GNUNET_OK;
579  }
580  len = strlen (rdir);
581  while ((len > 0) && (rdir[len] != DIR_SEPARATOR))
582  len--;
583  rdir[len] = '\0';
584  /* The empty path is invalid and in this case refers to / */
585  if (0 == len)
586  {
587  GNUNET_free (rdir);
588  rdir = GNUNET_strdup ("/");
589  }
590  res = GNUNET_DISK_directory_create (rdir);
591  if ( (GNUNET_OK == res) &&
592  (0 != access (rdir, W_OK)) )
593  res = GNUNET_NO;
594  eno = errno;
595  GNUNET_free (rdir);
596  errno = eno;
597  return res;
598 }
599 
600 
601 ssize_t
603  void *result,
604  size_t len)
605 {
606  if (NULL == h)
607  {
608  errno = EINVAL;
609  return GNUNET_SYSERR;
610  }
611  return read (h->fd, result, len);
612 }
613 
614 
615 ssize_t
617  void *result,
618  size_t len)
619 {
620  int flags;
621  ssize_t ret;
622 
623  if (NULL == h)
624  {
625  errno = EINVAL;
626  return GNUNET_SYSERR;
627  }
628  /* set to non-blocking, read, then set back */
629  flags = fcntl (h->fd, F_GETFL);
630  if (0 == (flags & O_NONBLOCK))
631  (void) fcntl (h->fd, F_SETFL, flags | O_NONBLOCK);
632  ret = read (h->fd, result, len);
633  if (0 == (flags & O_NONBLOCK))
634  {
635  int eno = errno;
636  (void) fcntl (h->fd, F_SETFL, flags);
637  errno = eno;
638  }
639  return ret;
640 }
641 
642 
643 ssize_t
644 GNUNET_DISK_fn_read (const char *fn,
645  void *result,
646  size_t len)
647 {
648  struct GNUNET_DISK_FileHandle *fh;
649  ssize_t ret;
650  int eno;
651 
652  fh = GNUNET_DISK_file_open (fn,
655  if (NULL == fh)
656  return GNUNET_SYSERR;
657  ret = GNUNET_DISK_file_read (fh, result, len);
658  eno = errno;
660  errno = eno;
661  return ret;
662 }
663 
664 
665 ssize_t
667  const void *buffer,
668  size_t n)
669 {
670  if (NULL == h)
671  {
672  errno = EINVAL;
673  return GNUNET_SYSERR;
674  }
675 
676  return write (h->fd, buffer, n);
677 }
678 
679 
680 ssize_t
682  const void *buffer,
683  size_t n)
684 {
685  int flags;
686  ssize_t ret;
687 
688  if (NULL == h)
689  {
690  errno = EINVAL;
691  return GNUNET_SYSERR;
692  }
693  /* set to blocking, write, then set back */
694  flags = fcntl (h->fd, F_GETFL);
695  if (0 != (flags & O_NONBLOCK))
696  (void) fcntl (h->fd, F_SETFL, flags - O_NONBLOCK);
697  ret = write (h->fd, buffer, n);
698  if (0 == (flags & O_NONBLOCK))
699  (void) fcntl (h->fd, F_SETFL, flags);
700  return ret;
701 }
702 
703 
706  const void *buf,
707  size_t buf_size,
709 {
710  char *tmpl;
711  int fd;
712 
713  if (GNUNET_OK !=
715  {
717  "mkstemp",
718  fn);
719  return GNUNET_SYSERR;
720  }
721  {
722  char *dname;
723 
724  dname = GNUNET_strdup (fn);
725  GNUNET_asprintf (&tmpl,
726  "%s/XXXXXX",
727  dirname (dname));
728  GNUNET_free (dname);
729  }
730  fd = mkstemp (tmpl);
731  if (-1 == fd)
732  {
734  "mkstemp",
735  tmpl);
736  GNUNET_free (tmpl);
737  return GNUNET_SYSERR;
738  }
739 
740  if (0 != fchmod (fd,
741  translate_unix_perms (mode)))
742  {
744  "chmod",
745  tmpl);
746  GNUNET_assert (0 == close (fd));
747  if (0 != unlink (tmpl))
749  "unlink",
750  tmpl);
751  GNUNET_free (tmpl);
752  return GNUNET_SYSERR;
753  }
754  if (buf_size !=
755  write (fd,
756  buf,
757  buf_size))
758  {
760  "write",
761  tmpl);
762  GNUNET_assert (0 == close (fd));
763  if (0 != unlink (tmpl))
765  "unlink",
766  tmpl);
767  GNUNET_free (tmpl);
768  return GNUNET_SYSERR;
769  }
770  GNUNET_assert (0 == close (fd));
771 
772  if (0 != link (tmpl,
773  fn))
774  {
775  if (0 != unlink (tmpl))
777  "unlink",
778  tmpl);
779  GNUNET_free (tmpl);
780  return GNUNET_NO;
781  }
782  if (0 != unlink (tmpl))
784  "unlink",
785  tmpl);
786  GNUNET_free (tmpl);
787  return GNUNET_OK;
788 
789 
790 }
791 
792 
793 int
795  GNUNET_FileNameCallback callback,
796  void *callback_cls)
797 {
798  DIR *dinfo;
799  struct dirent *finfo;
800  struct stat istat;
801  int count = 0;
803  char *name;
804  char *dname;
805  unsigned int name_len;
806  unsigned int n_size;
807 
808  GNUNET_assert (NULL != dir_name);
809  dname = GNUNET_STRINGS_filename_expand (dir_name);
810  if (NULL == dname)
811  return GNUNET_SYSERR;
812  while ((strlen (dname) > 0) && (dname[strlen (dname) - 1] == DIR_SEPARATOR))
813  dname[strlen (dname) - 1] = '\0';
814  if (0 != stat (dname, &istat))
815  {
817  GNUNET_free (dname);
818  return GNUNET_SYSERR;
819  }
820  if (! S_ISDIR (istat.st_mode))
821  {
823  _ ("Expected `%s' to be a directory!\n"),
824  dir_name);
825  GNUNET_free (dname);
826  return GNUNET_SYSERR;
827  }
828  errno = 0;
829  dinfo = opendir (dname);
830  if ((EACCES == errno) || (NULL == dinfo))
831  {
832  LOG_STRERROR_FILE (GNUNET_ERROR_TYPE_WARNING, "opendir", dname);
833  if (NULL != dinfo)
834  closedir (dinfo);
835  GNUNET_free (dname);
836  return GNUNET_SYSERR;
837  }
838  name_len = 256;
839  n_size = strlen (dname) + name_len + strlen (DIR_SEPARATOR_STR) + 1;
840  name = GNUNET_malloc (n_size);
841  while (NULL != (finfo = readdir (dinfo)))
842  {
843  if ((0 == strcmp (finfo->d_name, ".")) ||
844  (0 == strcmp (finfo->d_name, "..")))
845  continue;
846  if (NULL != callback)
847  {
848  if (name_len < strlen (finfo->d_name))
849  {
850  GNUNET_free (name);
851  name_len = strlen (finfo->d_name);
852  n_size = strlen (dname) + name_len + strlen (DIR_SEPARATOR_STR) + 1;
853  name = GNUNET_malloc (n_size);
854  }
855  /* dname can end in "/" only if dname == "/";
856  * if dname does not end in "/", we need to add
857  * a "/" (otherwise, we must not!) */
858  GNUNET_snprintf (name,
859  n_size,
860  "%s%s%s",
861  dname,
862  (0 == strcmp (dname, DIR_SEPARATOR_STR))
863  ? ""
865  finfo->d_name);
866  ret = callback (callback_cls, name);
867  if (GNUNET_OK != ret)
868  {
869  closedir (dinfo);
870  GNUNET_free (name);
871  GNUNET_free (dname);
872  if (GNUNET_NO == ret)
873  return count;
874  return GNUNET_SYSERR;
875  }
876  }
877  count++;
878  }
879  closedir (dinfo);
880  GNUNET_free (name);
881  GNUNET_free (dname);
882  return count;
883 }
884 
885 
894 static enum GNUNET_GenericReturnValue
895 remove_helper (void *unused,
896  const char *fn)
897 {
898  (void) unused;
899  (void) GNUNET_DISK_directory_remove (fn);
900  return GNUNET_OK;
901 }
902 
903 
906 {
907  struct stat istat;
908 
909  if (NULL == filename)
910  {
911  GNUNET_break (0);
912  return GNUNET_SYSERR;
913  }
914  if (0 != lstat (filename, &istat))
915  return GNUNET_NO; /* file may not exist... */
916  (void) chmod (filename,
917  S_IWUSR | S_IRUSR | S_IXUSR);
918  if (0 == unlink (filename))
919  return GNUNET_OK;
920  if ( (errno != EISDIR) &&
921  /* EISDIR is not sufficient in all cases, e.g.
922  * sticky /tmp directory may result in EPERM on BSD.
923  * So we also explicitly check "isDirectory" */
924  (GNUNET_YES !=
925  GNUNET_DISK_directory_test (filename,
926  GNUNET_YES)) )
927  {
928  LOG_STRERROR_FILE (GNUNET_ERROR_TYPE_WARNING, "rmdir", filename);
929  return GNUNET_SYSERR;
930  }
931  if (GNUNET_SYSERR ==
932  GNUNET_DISK_directory_scan (filename, &remove_helper, NULL))
933  return GNUNET_SYSERR;
934  if (0 != rmdir (filename))
935  {
936  LOG_STRERROR_FILE (GNUNET_ERROR_TYPE_WARNING, "rmdir", filename);
937  return GNUNET_SYSERR;
938  }
939  return GNUNET_OK;
940 }
941 
942 
944 GNUNET_DISK_file_copy (const char *src,
945  const char *dst)
946 {
947  char *buf;
948  uint64_t pos;
949  uint64_t size;
950  size_t len;
951  ssize_t sret;
952  struct GNUNET_DISK_FileHandle *in;
953  struct GNUNET_DISK_FileHandle *out;
954 
956  {
958  return GNUNET_SYSERR;
959  }
960  pos = 0;
961  in =
963  if (! in)
964  {
966  return GNUNET_SYSERR;
967  }
968  out =
976  if (! out)
977  {
980  return GNUNET_SYSERR;
981  }
983  while (pos < size)
984  {
985  len = COPY_BLK_SIZE;
986  if (len > size - pos)
987  len = size - pos;
988  sret = GNUNET_DISK_file_read (in, buf, len);
989  if ((sret < 0) || (len != (size_t) sret))
990  goto FAIL;
991  sret = GNUNET_DISK_file_write (out, buf, len);
992  if ((sret < 0) || (len != (size_t) sret))
993  goto FAIL;
994  pos += len;
995  }
996  GNUNET_free (buf);
999  return GNUNET_OK;
1000 FAIL:
1001  GNUNET_free (buf);
1003  GNUNET_DISK_file_close (out);
1004  return GNUNET_SYSERR;
1005 }
1006 
1007 
1008 void
1010 {
1011  char *idx;
1012  char c;
1013 
1014  for (idx = fn; *idx; idx++)
1015  {
1016  c = *idx;
1017 
1018  if ((c == '/') || (c == '\\') || (c == ':') || (c == '*') || (c == '?') ||
1019  (c ==
1020  '"')
1021  ||
1022  (c == '<') || (c == '>') || (c == '|') )
1023  {
1024  *idx = '_';
1025  }
1026  }
1027 }
1028 
1029 
1032  const char *user)
1033 {
1034  struct passwd *pws;
1035 
1036  pws = getpwnam (user);
1037  if (NULL == pws)
1038  {
1040  _ ("Cannot obtain information about user `%s': %s\n"),
1041  user,
1042  strerror (errno));
1043  return GNUNET_SYSERR;
1044  }
1045  if (0 != chown (filename, pws->pw_uid, pws->pw_gid))
1046  {
1047  LOG_STRERROR_FILE (GNUNET_ERROR_TYPE_WARNING, "chown", filename);
1048  return GNUNET_SYSERR;
1049  }
1050  return GNUNET_OK;
1051 }
1052 
1053 
1054 struct GNUNET_DISK_FileHandle *
1056  enum GNUNET_DISK_OpenFlags flags,
1058 {
1059  char *expfn;
1060  struct GNUNET_DISK_FileHandle *ret;
1061 
1062  int oflags;
1063  int mode;
1064  int fd;
1065 
1066  expfn = GNUNET_STRINGS_filename_expand (fn);
1067  if (NULL == expfn)
1068  return NULL;
1069 
1070  mode = 0;
1072  oflags = O_RDWR; /* note: O_RDWR is NOT always O_RDONLY | O_WRONLY */
1073  else if (flags & GNUNET_DISK_OPEN_READ)
1074  oflags = O_RDONLY;
1075  else if (flags & GNUNET_DISK_OPEN_WRITE)
1076  oflags = O_WRONLY;
1077  else
1078  {
1079  GNUNET_break (0);
1080  GNUNET_free (expfn);
1081  return NULL;
1082  }
1083  if (flags & GNUNET_DISK_OPEN_FAILIFEXISTS)
1084  oflags |= (O_CREAT | O_EXCL);
1085  if (flags & GNUNET_DISK_OPEN_TRUNCATE)
1086  oflags |= O_TRUNC;
1087  if (flags & GNUNET_DISK_OPEN_APPEND)
1088  oflags |= O_APPEND;
1089  if (GNUNET_NO == GNUNET_DISK_file_test (fn))
1090  {
1091  if (flags & GNUNET_DISK_OPEN_CREATE)
1092  {
1094  oflags |= O_CREAT;
1095  mode = translate_unix_perms (perm);
1096  }
1097  }
1098 
1099  fd = open (expfn,
1100  oflags
1101 #if O_CLOEXEC
1102  | O_CLOEXEC
1103 #endif
1104  | O_LARGEFILE,
1105  mode);
1106  if (fd == -1)
1107  {
1108  if (0 == (flags & GNUNET_DISK_OPEN_FAILIFEXISTS))
1110  else
1111  LOG_STRERROR_FILE (GNUNET_ERROR_TYPE_DEBUG, "open", expfn);
1112  GNUNET_free (expfn);
1113  return NULL;
1114  }
1115 
1116  ret = GNUNET_new (struct GNUNET_DISK_FileHandle);
1117 
1118  ret->fd = fd;
1119 
1120  GNUNET_free (expfn);
1121  return ret;
1122 }
1123 
1124 
1127 {
1129 
1130  if (NULL == h)
1131  {
1132  errno = EINVAL;
1133  return GNUNET_SYSERR;
1134  }
1135 
1136  ret = GNUNET_OK;
1137  if (0 != close (h->fd))
1138  {
1140  ret = GNUNET_SYSERR;
1141  }
1142  GNUNET_free (h);
1143  return ret;
1144 }
1145 
1146 
1147 struct GNUNET_DISK_FileHandle *
1149 {
1150  struct GNUNET_DISK_FileHandle *fh;
1151 
1152  if ((((off_t) -1) == lseek (fno, 0, SEEK_CUR)) && (EBADF == errno))
1153  return NULL; /* invalid FD */
1154 
1155  fh = GNUNET_new (struct GNUNET_DISK_FileHandle);
1156 
1157  fh->fd = fno;
1158 
1159  return fh;
1160 }
1161 
1162 
1163 struct GNUNET_DISK_FileHandle *
1165 {
1166  int fno;
1167 
1168  fno = fileno (fd);
1169  if (-1 == fno)
1170  return NULL;
1172 }
1173 
1174 
1179 {
1183  void *addr;
1184 
1188  size_t len;
1189 };
1190 
1191 
1192 #ifndef MAP_FAILED
1193 #define MAP_FAILED ((void *) -1)
1194 #endif
1195 
1196 
1197 void *
1199  struct GNUNET_DISK_MapHandle **m,
1200  enum GNUNET_DISK_MapType access,
1201  size_t len)
1202 {
1203  int prot;
1204 
1205  if (NULL == h)
1206  {
1207  errno = EINVAL;
1208  return NULL;
1209  }
1210  prot = 0;
1211  if (access & GNUNET_DISK_MAP_TYPE_READ)
1212  prot = PROT_READ;
1213  if (access & GNUNET_DISK_MAP_TYPE_WRITE)
1214  prot |= PROT_WRITE;
1215  *m = GNUNET_new (struct GNUNET_DISK_MapHandle);
1216  (*m)->addr = mmap (NULL, len, prot, MAP_SHARED, h->fd, 0);
1217  GNUNET_assert (NULL != (*m)->addr);
1218  if (MAP_FAILED == (*m)->addr)
1219  {
1220  GNUNET_free (*m);
1221  return NULL;
1222  }
1223  (*m)->len = len;
1224  return (*m)->addr;
1225 }
1226 
1227 
1230 {
1232 
1233  if (NULL == h)
1234  {
1235  errno = EINVAL;
1236  return GNUNET_SYSERR;
1237  }
1238  ret = munmap (h->addr, h->len) != -1 ? GNUNET_OK : GNUNET_SYSERR;
1239  GNUNET_free (h);
1240  return ret;
1241 }
1242 
1243 
1246 {
1247  if (h == NULL)
1248  {
1249  errno = EINVAL;
1250  return GNUNET_SYSERR;
1251  }
1252 
1253 #if ! defined(__linux__) || ! defined(GNU)
1254  return fsync (h->fd) == -1 ? GNUNET_SYSERR : GNUNET_OK;
1255 #else
1256  return fdatasync (h->fd) == -1 ? GNUNET_SYSERR : GNUNET_OK;
1257 #endif
1258 }
1259 
1260 
1261 struct GNUNET_DISK_PipeHandle *
1263 {
1264  int fd[2];
1265 
1266  if (-1 == pipe (fd))
1267  {
1268  int eno = errno;
1269 
1271  errno = eno;
1272  return NULL;
1273  }
1274  return GNUNET_DISK_pipe_from_fd (pf, fd);
1275 }
1276 
1277 
1278 struct GNUNET_DISK_PipeHandle *
1280  int fd[2])
1281 {
1282  struct GNUNET_DISK_PipeHandle *p;
1283  int ret = 0;
1284  int flags;
1285  int eno = 0; /* make gcc happy */
1286 
1287  p = GNUNET_new (struct GNUNET_DISK_PipeHandle);
1288  if (fd[0] >= 0)
1289  {
1290  p->fd[0] = GNUNET_new (struct GNUNET_DISK_FileHandle);
1291  p->fd[0]->fd = fd[0];
1292  if (0 == (GNUNET_DISK_PF_BLOCKING_READ & pf))
1293  {
1294  flags = fcntl (fd[0], F_GETFL);
1295  flags |= O_NONBLOCK;
1296  if (0 > fcntl (fd[0], F_SETFL, flags))
1297  {
1298  ret = -1;
1299  eno = errno;
1300  }
1301  }
1302  flags = fcntl (fd[0], F_GETFD);
1303  flags |= FD_CLOEXEC;
1304  if (0 > fcntl (fd[0], F_SETFD, flags))
1305  {
1306  ret = -1;
1307  eno = errno;
1308  }
1309  }
1310 
1311  if (fd[1] >= 0)
1312  {
1313  p->fd[1] = GNUNET_new (struct GNUNET_DISK_FileHandle);
1314  p->fd[1]->fd = fd[1];
1315  if (0 == (GNUNET_DISK_PF_BLOCKING_WRITE & pf))
1316  {
1317  flags = fcntl (fd[1], F_GETFL);
1318  flags |= O_NONBLOCK;
1319  if (0 > fcntl (fd[1], F_SETFL, flags))
1320  {
1321  ret = -1;
1322  eno = errno;
1323  }
1324  }
1325  flags = fcntl (fd[1], F_GETFD);
1326  flags |= FD_CLOEXEC;
1327  if (0 > fcntl (fd[1], F_SETFD, flags))
1328  {
1329  ret = -1;
1330  eno = errno;
1331  }
1332  }
1333  if (ret == -1)
1334  {
1335  errno = eno;
1337  if (p->fd[0]->fd >= 0)
1338  GNUNET_break (0 == close (p->fd[0]->fd));
1339  if (p->fd[1]->fd >= 0)
1340  GNUNET_break (0 == close (p->fd[1]->fd));
1341  GNUNET_free (p->fd[0]);
1342  GNUNET_free (p->fd[1]);
1343  GNUNET_free (p);
1344  errno = eno;
1345  return NULL;
1346  }
1347  return p;
1348 }
1349 
1350 
1353  enum GNUNET_DISK_PipeEnd end)
1354 {
1356 
1357  if (end == GNUNET_DISK_PIPE_END_READ)
1358  {
1359  if (p->fd[0])
1360  {
1361  ret = GNUNET_DISK_file_close (p->fd[0]);
1362  p->fd[0] = NULL;
1363  }
1364  }
1365  else if (end == GNUNET_DISK_PIPE_END_WRITE)
1366  {
1367  if (p->fd[1])
1368  {
1369  ret = GNUNET_DISK_file_close (p->fd[1]);
1370  p->fd[1] = NULL;
1371  }
1372  }
1373  return ret;
1374 }
1375 
1376 
1377 struct GNUNET_DISK_FileHandle *
1379  enum GNUNET_DISK_PipeEnd end)
1380 {
1381  struct GNUNET_DISK_FileHandle *ret = NULL;
1382 
1383  if (end == GNUNET_DISK_PIPE_END_READ)
1384  {
1385  if (p->fd[0])
1386  {
1387  ret = p->fd[0];
1388  p->fd[0] = NULL;
1389  }
1390  }
1391  else if (end == GNUNET_DISK_PIPE_END_WRITE)
1392  {
1393  if (p->fd[1])
1394  {
1395  ret = p->fd[1];
1396  p->fd[1] = NULL;
1397  }
1398  }
1399 
1400  return ret;
1401 }
1402 
1403 
1406 {
1407  int ret = GNUNET_OK;
1408 
1409  int read_end_close;
1410  int write_end_close;
1411  int read_end_close_errno;
1412  int write_end_close_errno;
1413 
1415  read_end_close_errno = errno;
1417  write_end_close_errno = errno;
1418  GNUNET_free (p);
1419 
1420  if (GNUNET_OK != read_end_close)
1421  {
1422  errno = read_end_close_errno;
1423  ret = read_end_close;
1424  }
1425  else if (GNUNET_OK != write_end_close)
1426  {
1427  errno = write_end_close_errno;
1428  ret = write_end_close;
1429  }
1430 
1431  return ret;
1432 }
1433 
1434 
1435 const struct GNUNET_DISK_FileHandle *
1437  enum GNUNET_DISK_PipeEnd n)
1438 {
1439  switch (n)
1440  {
1443  return p->fd[n];
1444 
1445  default:
1446  GNUNET_break (0);
1447  return NULL;
1448  }
1449 }
1450 
1451 
1454  void *dst,
1455  size_t dst_len)
1456 {
1457  if (NULL == fh)
1458  return GNUNET_SYSERR;
1459  if (dst_len < sizeof(int))
1460  return GNUNET_SYSERR;
1461  *((int *) dst) = fh->fd;
1462  return GNUNET_OK;
1463 }
1464 
1465 
1473 static enum GNUNET_GenericReturnValue
1474 purge_cfg_dir (void *cls,
1475  const struct GNUNET_CONFIGURATION_Handle *cfg)
1476 {
1477  const char *option = cls;
1478  char *tmpname;
1479 
1480  if (GNUNET_OK !=
1481  GNUNET_CONFIGURATION_get_value_filename (cfg, "PATHS", option, &tmpname))
1482  {
1484  return GNUNET_NO;
1485  }
1487  {
1489  GNUNET_free (tmpname);
1490  return GNUNET_OK;
1491  }
1492  GNUNET_free (tmpname);
1493  return GNUNET_OK;
1494 }
1495 
1496 
1497 void
1499  const char *option)
1500 {
1502  GNUNET_CONFIGURATION_parse_and_run (cfg_filename,
1503  &purge_cfg_dir,
1504  (void *) option));
1505 }
1506 
1507 
1508 /* end of disk.c */
void GNUNET_DISK_purge_cfg_dir(const char *cfg_filename, const char *option)
Remove the directory given under option in section [PATHS] in configuration under cfg_filename...
Definition: disk.c:1498
static enum GNUNET_GenericReturnValue get_size_rec(void *cls, const char *fn)
Iterate over all files in the given directory and accumulate their size.
Definition: disk.c:146
enum GNUNET_GenericReturnValue GNUNET_DISK_file_handle_size(struct GNUNET_DISK_FileHandle *fh, off_t *size)
Get the size of an open file.
Definition: disk.c:193
Open the file for reading.
static char * cfg_filename
Name of the configuration file.
static char * dir
Set to the directory where runtime files are stored.
Definition: gnunet-arm.c:89
Create file if it doesn&#39;t exist.
GNUNET_DISK_MapType
Specifies what type of memory map is desired.
void * addr
Address where the map is in memory.
Definition: disk.c:1183
static const char * dir_name
Top-level directory we monitor to auto-publish.
static const struct GNUNET_CONFIGURATION_Handle * cfg
Configuration we are using.
Definition: gnunet-abd.c:36
static int end
Set if we are to shutdown all services (including ARM).
Definition: gnunet-arm.c:34
uint64_t total
Set to the total file size.
Definition: disk.c:87
enum GNUNET_GenericReturnValue GNUNET_DISK_file_get_identifiers(const char *filename, uint64_t *dev, uint64_t *ino)
Obtain some unique identifiers for the given file that can be used to identify it in the local system...
Definition: disk.c:241
int single_file_mode
GNUNET_YES if mode is file-only (return total == -1 for directories).
Definition: disk.c:97
Closure for the recursion to determine the file size of a directory.
Definition: disk.c:82
#define MAP_FAILED
Definition: disk.c:1193
enum GNUNET_GenericReturnValue GNUNET_DISK_file_unmap(struct GNUNET_DISK_MapHandle *h)
Unmap a file.
Definition: disk.c:1229
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:602
#define GNUNET_assert(cond)
Use this for fatal errors that cannot be handled.
enum GNUNET_GenericReturnValue GNUNET_DISK_file_close(struct GNUNET_DISK_FileHandle *h)
Close an open file.
Definition: disk.c:1126
void * GNUNET_DISK_file_map(const struct GNUNET_DISK_FileHandle *h, struct GNUNET_DISK_MapHandle **m, enum GNUNET_DISK_MapType access, size_t len)
Map a file into memory.
Definition: disk.c:1198
Everybody can execute.
Nobody is allowed to do anything to the file.
static int ret
Return value of the commandline.
Definition: gnunet-abd.c:81
GNUNET_DISK_Seek
Constants for specifying how to seek.
GNUNET_GenericReturnValue
Named constants for return values.
Definition: gnunet_common.h:83
Append to the file.
static enum GNUNET_GenericReturnValue remove_helper(void *unused, const char *fn)
Function that removes the given directory by calling GNUNET_DISK_directory_remove().
Definition: disk.c:895
#define GNUNET_new(type)
Allocate a struct or union of the given type.
enum GNUNET_GenericReturnValue GNUNET_CONFIGURATION_get_value_filename(const struct GNUNET_CONFIGURATION_Handle *cfg, const char *section, const char *option, char **value)
Get a configuration value that should be the name of a file or directory.
int GNUNET_DISK_directory_scan(const char *dir_name, GNUNET_FileNameCallback callback, void *callback_cls)
Scan a directory for files.
Definition: disk.c:794
static struct GNUNET_SCHEDULER_Task * t
Main task.
off_t GNUNET_DISK_file_seek(const struct GNUNET_DISK_FileHandle *h, off_t offset, enum GNUNET_DISK_Seek whence)
Move the read/write pointer in a file.
Definition: disk.c:206
static enum @8 mode
Should we do a PUT (mode = 0) or GET (mode = 1);.
#define GNUNET_strdup(a)
Wrapper around GNUNET_xstrdup_.
#define LOG_STRERROR(kind, syscall)
Definition: disk.c:33
static int translate_unix_perms(enum GNUNET_DISK_AccessPermissions perm)
Translate GNUnet-internal permission bitmap to UNIX file access permission bitmap.
Definition: disk.c:109
#define GNUNET_break(cond)
Use this for internal assertion violations that are not fatal (can be handled) but should not occur...
const struct GNUNET_DISK_FileHandle * GNUNET_DISK_pipe_handle(const struct GNUNET_DISK_PipeHandle *p, enum GNUNET_DISK_PipeEnd n)
Get the handle to a particular pipe end.
Definition: disk.c:1436
static struct GNUNET_ARM_Handle * h
Connection with ARM.
Definition: gnunet-arm.c:99
#define O_LARGEFILE
Definition: platform.h:217
#define _(String)
GNU gettext support macro.
Definition: platform.h:178
int GNUNET_snprintf(char *buf, size_t size, const char *format,...) __attribute__((format(printf
Like snprintf, just aborts if the buffer is of insufficient size.
static struct GNUNET_ARM_MonitorHandle * m
Monitor connection with ARM.
Definition: gnunet-arm.c:104
struct GNUNET_DISK_FileHandle * fd[2]
File descriptors for the pipe.
Definition: disk.c:74
char * GNUNET_DISK_mktemp(const char *t)
Create an (empty) temporary file on disk.
Definition: disk.c:381
static struct GNUNET_OS_Process * p
Helper process we started.
Definition: gnunet-qr.c:59
void GNUNET_log_config_missing(enum GNUNET_ErrorType kind, const char *section, const char *option)
Log error message about missing configuration option.
size_t len
Number of bytes mapped.
Definition: disk.c:1188
enum GNUNET_GenericReturnValue GNUNET_DISK_file_copy(const char *src, const char *dst)
Copy a file.
Definition: disk.c:944
struct GNUNET_DISK_FileHandle * GNUNET_DISK_pipe_detach_end(struct GNUNET_DISK_PipeHandle *p, enum GNUNET_DISK_PipeEnd end)
Detaches one of the ends from the pipe.
Definition: disk.c:1378
#define GNUNET_log_strerror_file(level, cmd, filename)
Log an error message at log-level &#39;level&#39; that indicates a failure of the command &#39;cmd&#39; with the mess...
static char * fn
Filename of the unique file.
Truncate file if it exists.
#define COPY_BLK_SIZE
Block size for IO for copying files.
Definition: disk.c:42
enum GNUNET_GenericReturnValue GNUNET_DISK_pipe_close(struct GNUNET_DISK_PipeHandle *p)
Closes an interprocess channel.
Definition: disk.c:1405
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:666
#define DIR_SEPARATOR_STR
Definition: platform.h:165
Read-only memory map.
static char * option
Name of the option.
Definition: gnunet-config.c:38
static char buf[2048]
static char * filename
struct GNUNET_DISK_PipeHandle * GNUNET_DISK_pipe_from_fd(enum GNUNET_DISK_PipeFlags pf, int fd[2])
Creates a pipe object from a couple of file descriptors.
Definition: disk.c:1279
static int result
Global testing status.
enum GNUNET_GenericReturnValue GNUNET_DISK_pipe_close_end(struct GNUNET_DISK_PipeHandle *p, enum GNUNET_DISK_PipeEnd end)
Closes one half of an interprocess channel.
Definition: disk.c:1352
GNUNET_DISK_AccessPermissions
File access permissions, UNIX-style.
The writing-end of a pipe.
int include_sym_links
GNUNET_YES if symbolic links should be included.
Definition: disk.c:92
The reading-end of a pipe.
enum GNUNET_GenericReturnValue GNUNET_DISK_directory_create(const char *dir)
Implementation of "mkdir -p".
Definition: disk.c:476
static int fh
Handle to the unique file.
void GNUNET_DISK_file_backup(const char *fil)
Move a file out of the way (create a backup) by renaming it to "orig.NUM~" where NUM is the smallest ...
Definition: disk.c:360
enum GNUNET_GenericReturnValue GNUNET_DISK_file_change_owner(const char *filename, const char *user)
Change owner of a file.
Definition: disk.c:1031
#define LOG(kind,...)
Definition: disk.c:31
static enum GNUNET_GenericReturnValue purge_cfg_dir(void *cls, const struct GNUNET_CONFIGURATION_Handle *cfg)
Helper function for GNUNET_DISK_purge_cfg_dir.
Definition: disk.c:1474
static int res
ssize_t GNUNET_DISK_file_write_blocking(const struct GNUNET_DISK_FileHandle *h, const void *buffer, size_t n)
Write a buffer to a file, blocking, if necessary.
Definition: disk.c:681
struct GNUNET_DISK_PipeHandle * GNUNET_DISK_pipe(enum GNUNET_DISK_PipeFlags pf)
Creates an interprocess channel.
Definition: disk.c:1262
int int GNUNET_asprintf(char **buf, const char *format,...) __attribute__((format(printf
Like asprintf, just portable.
#define DIR_SEPARATOR
Definition: platform.h:164
GNUNET_DISK_PipeFlags
Flags for GNUNET_DISK_pipe().
static unsigned int size
Size of the "table".
Definition: peer.c:67
Everybody can write.
Open the file for writing.
char * GNUNET_DISK_mkdtemp(const char *t)
Create an (empty) temporary directory on disk.
Definition: disk.c:340
char * GNUNET_STRINGS_filename_expand(const char *fil)
Complete filename (a la shell) from abbrevition.
Definition: strings.c:482
char * getenv()
Configure write end to block when writing if set.
enum GNUNET_GenericReturnValue GNUNET_DISK_fn_write(const char *fn, const void *buf, size_t buf_size, enum GNUNET_DISK_AccessPermissions mode)
Write a buffer to a file atomically.
Definition: disk.c:705
enum GNUNET_GenericReturnValue GNUNET_DISK_handle_invalid(const struct GNUNET_DISK_FileHandle *h)
Checks whether a handle is invalid.
Definition: disk.c:186
enum GNUNET_GenericReturnValue GNUNET_DISK_internal_file_handle_(const struct GNUNET_DISK_FileHandle *fh, void *dst, size_t dst_len)
Retrieve OS file handle.
Definition: disk.c:1453
#define S_ISLNK(m)
Definition: disk.c:61
enum GNUNET_GenericReturnValue GNUNET_DISK_file_size(const char *filename, uint64_t *size, int include_symbolic_links, int single_file_mode)
Get the size of the file (or directory) of the given file (in bytes).
Definition: disk.c:222
#define LOG_STRERROR_FILE(kind, syscall, filename)
Definition: disk.c:36
Everybody can read.
struct GNUNET_DISK_FileHandle * GNUNET_DISK_get_handle_from_int_fd(int fno)
Get a handle from a native integer FD.
Definition: disk.c:1148
configuration data
Definition: configuration.c:84
const char * name
enum GNUNET_GenericReturnValue GNUNET_DISK_file_sync(const struct GNUNET_DISK_FileHandle *h)
Write file changes to disk.
Definition: disk.c:1245
enum GNUNET_GenericReturnValue(* GNUNET_FileNameCallback)(void *cls, const char *filename)
Function called with a filename.
#define GNUNET_log(kind,...)
GNUNET_DISK_OpenFlags
Specifies how a file should be opened.
Open the file for both reading and writing.
Write-able memory map.
void GNUNET_DISK_fix_permissions(const char *fn, int require_uid_match, int require_gid_match)
Update POSIX permissions mask of a file on disk.
Definition: disk.c:321
static char * mktemp_name(const char *t)
Create the name for a temporary file or directory from a template.
Definition: disk.c:293
int fd
File handle on Unix-like systems.
Fail if file already exists.
enum GNUNET_GenericReturnValue GNUNET_DISK_directory_remove(const char *filename)
Remove all files in a directory (rm -rf).
Definition: disk.c:905
ssize_t GNUNET_DISK_file_read_non_blocking(const struct GNUNET_DISK_FileHandle *h, void *result, size_t len)
Read the contents of a binary file into a buffer.
Definition: disk.c:616
struct GNUNET_DISK_FileHandle * GNUNET_DISK_get_handle_from_native(FILE *fd)
Get a handle from a native FD.
Definition: disk.c:1164
enum GNUNET_GenericReturnValue GNUNET_DISK_directory_create_for_file(const char *filename)
Create the directory structure for storing a file.
Definition: disk.c:562
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:1055
GNUNET_DISK_PipeEnd
Enumeration identifying the two ends of a pipe.
Handle used to access files (and pipes).
enum GNUNET_GenericReturnValue GNUNET_DISK_directory_test(const char *fil, int is_readable)
Test if fil is a directory and listable.
Definition: disk.c:404
Handle used to manage a pipe.
Definition: disk.c:68
enum GNUNET_GenericReturnValue GNUNET_DISK_file_test(const char *fil)
Check that fil corresponds to a filename (of a file that exists and that is not a directory)...
Definition: disk.c:437
#define GNUNET_malloc(size)
Wrapper around malloc.
ssize_t GNUNET_DISK_fn_read(const char *fn, void *result, size_t len)
Read the contents of a binary file into a buffer.
Definition: disk.c:644
void GNUNET_DISK_filename_canonicalize(char *fn)
Removes special characters as &#39;:&#39; from a filename.
Definition: disk.c:1009
Handle for a memory-mapping operation.
Definition: disk.c:1178
Internal DISK related helper functions.
#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...
Configure read end to block when reading if set.
enum GNUNET_GenericReturnValue GNUNET_CONFIGURATION_parse_and_run(const char *filename, GNUNET_CONFIGURATION_Callback cb, void *cb_cls)
Parse a configuration file filename and run the function cb with the resulting configuration object...