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 int
146 getSizeRec (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 
191 int
193 {
194  return ((! h) || (h->fd == -1)) ? GNUNET_YES : GNUNET_NO;
195 }
196 
197 
205 int
207 {
208  struct stat sbuf;
209 
210  if (0 != fstat (fh->fd, &sbuf))
211  return GNUNET_SYSERR;
212  *size = sbuf.st_size;
213  return GNUNET_OK;
214 }
215 
216 
225 off_t
227  off_t offset,
228  enum GNUNET_DISK_Seek whence)
229 {
230  if (h == NULL)
231  {
232  errno = EINVAL;
233  return GNUNET_SYSERR;
234  }
235 
236  static int t[] = { SEEK_SET, SEEK_CUR, SEEK_END };
237 
238  return lseek (h->fd, offset, t[whence]);
239 }
240 
241 
256 int
258  uint64_t *size,
259  int include_symbolic_links,
260  int single_file_mode)
261 {
262  struct GetFileSizeData gfsd;
263  int ret;
264 
265  GNUNET_assert (size != NULL);
266  gfsd.total = 0;
267  gfsd.include_sym_links = include_symbolic_links;
269  ret = getSizeRec (&gfsd, filename);
270  *size = gfsd.total;
271  return ret;
272 }
273 
274 
290 int
292  uint64_t *dev,
293  uint64_t *ino)
294 {
295 #if HAVE_STAT
296  {
297  struct stat sbuf;
298 
299  if (0 != stat (filename, &sbuf))
300  {
301  return GNUNET_SYSERR;
302  }
303  *ino = (uint64_t) sbuf.st_ino;
304  }
305 #else
306  *ino = 0;
307 #endif
308 #if HAVE_STATVFS
309  {
310  struct statvfs fbuf;
311 
312  if (0 != statvfs (filename, &fbuf))
313  {
314  return GNUNET_SYSERR;
315  }
316  *dev = (uint64_t) fbuf.f_fsid;
317  }
318 #elif HAVE_STATFS
319  {
320  struct statfs fbuf;
321 
322  if (0 != statfs (filename, &fbuf))
323  {
324  return GNUNET_SYSERR;
325  }
326  *dev =
327  ((uint64_t) fbuf.f_fsid.val[0]) << 32 || ((uint64_t) fbuf.f_fsid.val[1]);
328  }
329 #else
330  *dev = 0;
331 #endif
332  return GNUNET_OK;
333 }
334 
335 
342 static char *
343 mktemp_name (const char *t)
344 {
345  const char *tmpdir;
346  char *tmpl;
347  char *fn;
348 
349  if ((t[0] != '/') && (t[0] != '\\'))
350  {
351  /* FIXME: This uses system codepage on W32, not UTF-8 */
352  tmpdir = getenv ("TMPDIR");
353  if (NULL == tmpdir)
354  tmpdir = getenv ("TMP");
355  if (NULL == tmpdir)
356  tmpdir = getenv ("TEMP");
357  if (NULL == tmpdir)
358  tmpdir = "/tmp";
359  GNUNET_asprintf (&tmpl, "%s/%s%s", tmpdir, t, "XXXXXX");
360  }
361  else
362  {
363  GNUNET_asprintf (&tmpl, "%s%s", t, "XXXXXX");
364  }
365  fn = tmpl;
366  return fn;
367 }
368 
369 
378 void
380  int require_uid_match,
381  int require_gid_match)
382 {
383  mode_t mode;
384 
385  if (GNUNET_YES == require_uid_match)
386  mode = S_IRUSR | S_IWUSR | S_IXUSR;
387  else if (GNUNET_YES == require_gid_match)
388  mode = S_IRUSR | S_IWUSR | S_IXUSR | S_IRGRP | S_IWGRP | S_IXGRP;
389  else
390  mode = S_IRUSR | S_IWUSR | S_IXUSR | S_IRGRP | S_IWGRP | S_IXGRP | S_IROTH
391  | S_IWOTH | S_IXOTH;
392  if (0 != chmod (fn, mode))
394 }
395 
396 
408 char *
409 GNUNET_DISK_mkdtemp (const char *t)
410 {
411  char *fn;
412  mode_t omask;
413 
414  omask = umask (S_IWGRP | S_IWOTH | S_IRGRP | S_IROTH);
415  fn = mktemp_name (t);
416  if (fn != mkdtemp (fn))
417  {
419  GNUNET_free (fn);
420  umask (omask);
421  return NULL;
422  }
423  umask (omask);
424  return fn;
425 }
426 
427 
435 void
436 GNUNET_DISK_file_backup (const char *fil)
437 {
438  size_t slen;
439  char *target;
440  unsigned int num;
441 
442  slen = strlen (fil) + 20;
443  target = GNUNET_malloc (slen);
444  num = 0;
445  do
446  {
447  GNUNET_snprintf (target, slen, "%s.%u~", fil, num++);
448  }
449  while (0 == access (target, F_OK));
450  if (0 != rename (fil, target))
452  GNUNET_free (target);
453 }
454 
455 
467 char *
468 GNUNET_DISK_mktemp (const char *t)
469 {
470  int fd;
471  char *fn;
472  mode_t omask;
473 
474  omask = umask (S_IWGRP | S_IWOTH | S_IRGRP | S_IROTH);
475  fn = mktemp_name (t);
476  if (-1 == (fd = mkstemp (fn)))
477  {
479  GNUNET_free (fn);
480  umask (omask);
481  return NULL;
482  }
483  umask (omask);
484  if (0 != close (fd))
486  return fn;
487 }
488 
489 
502 int
503 GNUNET_DISK_directory_test (const char *fil, int is_readable)
504 {
505  struct stat filestat;
506  int ret;
507 
508  ret = stat (fil, &filestat);
509  if (ret != 0)
510  {
511  if (errno != ENOENT)
513  return GNUNET_SYSERR;
514  }
515  if (! S_ISDIR (filestat.st_mode))
516  {
518  "A file already exits with the same name %s\n",
519  fil);
520  return GNUNET_NO;
521  }
522  if (GNUNET_YES == is_readable)
523  ret = access (fil, R_OK | X_OK);
524  else
525  ret = access (fil, X_OK);
526  if (ret < 0)
527  {
529  return GNUNET_NO;
530  }
531  return GNUNET_YES;
532 }
533 
534 
543 int
544 GNUNET_DISK_file_test (const char *fil)
545 {
546  struct stat filestat;
547  int ret;
548  char *rdir;
549 
550  rdir = GNUNET_STRINGS_filename_expand (fil);
551  if (rdir == NULL)
552  return GNUNET_SYSERR;
553 
554  ret = stat (rdir, &filestat);
555  if (ret != 0)
556  {
557  if (errno != ENOENT)
558  {
560  GNUNET_free (rdir);
561  return GNUNET_SYSERR;
562  }
563  GNUNET_free (rdir);
564  return GNUNET_NO;
565  }
566  if (! S_ISREG (filestat.st_mode))
567  {
568  GNUNET_free (rdir);
569  return GNUNET_NO;
570  }
571  if (access (rdir, F_OK) < 0)
572  {
574  GNUNET_free (rdir);
575  return GNUNET_SYSERR;
576  }
577  GNUNET_free (rdir);
578  return GNUNET_YES;
579 }
580 
581 
588 int
590 {
591  char *rdir;
592  unsigned int len;
593  unsigned int pos;
594  unsigned int pos2;
595  int ret = GNUNET_OK;
596 
597  rdir = GNUNET_STRINGS_filename_expand (dir);
598  if (rdir == NULL)
599  {
600  GNUNET_break (0);
601  return GNUNET_SYSERR;
602  }
603 
604  len = strlen (rdir);
605 
606  pos = 1; /* skip heading '/' */
607 
608  /* Check which low level directories already exist */
609  pos2 = len;
610  rdir[len] = DIR_SEPARATOR;
611  while (pos <= pos2)
612  {
613  if (DIR_SEPARATOR == rdir[pos2])
614  {
615  rdir[pos2] = '\0';
617  if (GNUNET_NO == ret)
618  {
620  "Creating directory `%s' failed",
621  rdir);
622  GNUNET_free (rdir);
623  return GNUNET_SYSERR;
624  }
625  rdir[pos2] = DIR_SEPARATOR;
626  if (GNUNET_YES == ret)
627  {
628  pos2++;
629  break;
630  }
631  }
632  pos2--;
633  }
634  rdir[len] = '\0';
635  if (pos < pos2)
636  pos = pos2;
637  /* Start creating directories */
638  while (pos <= len)
639  {
640  if ((rdir[pos] == DIR_SEPARATOR) || (pos == len))
641  {
642  rdir[pos] = '\0';
644  if (GNUNET_NO == ret)
645  {
647  "Creating directory `%s' failed",
648  rdir);
649  GNUNET_free (rdir);
650  return GNUNET_SYSERR;
651  }
652  if (GNUNET_SYSERR == ret)
653  {
654  ret = mkdir (rdir,
655  S_IRUSR | S_IWUSR | S_IXUSR | S_IRGRP | S_IXGRP | S_IROTH
656  | S_IXOTH); /* 755 */
657 
658  if ((ret != 0) && (errno != EEXIST))
659  {
661  GNUNET_free (rdir);
662  return GNUNET_SYSERR;
663  }
664  }
665  rdir[pos] = DIR_SEPARATOR;
666  }
667  pos++;
668  }
669  GNUNET_free (rdir);
670  return GNUNET_OK;
671 }
672 
673 
683 int
685 {
686  char *rdir;
687  size_t len;
688  int ret;
689  int eno;
690 
691  rdir = GNUNET_STRINGS_filename_expand (filename);
692  if (NULL == rdir)
693  {
694  errno = EINVAL;
695  return GNUNET_SYSERR;
696  }
697  if (0 == access (rdir, W_OK))
698  {
699  GNUNET_free (rdir);
700  return GNUNET_OK;
701  }
702 
703  len = strlen (rdir);
704  while ((len > 0) && (rdir[len] != DIR_SEPARATOR))
705  len--;
706  rdir[len] = '\0';
707  /* The empty path is invalid and in this case refers to / */
708  if (0 == len)
709  {
710  GNUNET_free (rdir);
711  rdir = GNUNET_strdup ("/");
712  }
713  ret = GNUNET_DISK_directory_create (rdir);
714  if ((GNUNET_OK == ret) && (0 != access (rdir, W_OK)))
715  ret = GNUNET_NO;
716  eno = errno;
717  GNUNET_free (rdir);
718  errno = eno;
719  return ret;
720 }
721 
722 
731 ssize_t
733  void *result,
734  size_t len)
735 {
736  if (NULL == h)
737  {
738  errno = EINVAL;
739  return GNUNET_SYSERR;
740  }
741 
742  return read (h->fd, result, len);
743 }
744 
745 
756 ssize_t
758  void *result,
759  size_t len)
760 {
761  if (NULL == h)
762  {
763  errno = EINVAL;
764  return GNUNET_SYSERR;
765  }
766 
767  int flags;
768  ssize_t ret;
769 
770  /* set to non-blocking, read, then set back */
771  flags = fcntl (h->fd, F_GETFL);
772  if (0 == (flags & O_NONBLOCK))
773  (void) fcntl (h->fd, F_SETFL, flags | O_NONBLOCK);
774  ret = read (h->fd, result, len);
775  if (0 == (flags & O_NONBLOCK))
776  {
777  int eno = errno;
778  (void) fcntl (h->fd, F_SETFL, flags);
779  errno = eno;
780  }
781  return ret;
782 }
783 
784 
793 ssize_t
794 GNUNET_DISK_fn_read (const char *fn, void *result, size_t len)
795 {
796  struct GNUNET_DISK_FileHandle *fh;
797  ssize_t ret;
798  int eno;
799 
801  if (NULL == fh)
802  return GNUNET_SYSERR;
803  ret = GNUNET_DISK_file_read (fh, result, len);
804  eno = errno;
806  errno = eno;
807  return ret;
808 }
809 
810 
819 ssize_t
821  const void *buffer,
822  size_t n)
823 {
824  if (NULL == h)
825  {
826  errno = EINVAL;
827  return GNUNET_SYSERR;
828  }
829 
830 
831  return write (h->fd, buffer, n);
832 }
833 
834 
843 ssize_t
845  const void *buffer,
846  size_t n)
847 {
848  if (NULL == h)
849  {
850  errno = EINVAL;
851  return GNUNET_SYSERR;
852  }
853 
854 
855  int flags;
856  ssize_t ret;
857 
858  /* set to blocking, write, then set back */
859  flags = fcntl (h->fd, F_GETFL);
860  if (0 != (flags & O_NONBLOCK))
861  (void) fcntl (h->fd, F_SETFL, flags - O_NONBLOCK);
862  ret = write (h->fd, buffer, n);
863  if (0 == (flags & O_NONBLOCK))
864  (void) fcntl (h->fd, F_SETFL, flags);
865  return ret;
866 }
867 
868 
879 ssize_t
881  const void *buffer,
882  size_t n,
884 {
885  struct GNUNET_DISK_FileHandle *fh;
886  ssize_t ret;
887 
888  fh =
892  mode);
893  if (! fh)
894  return GNUNET_SYSERR;
895  ret = GNUNET_DISK_file_write (fh, buffer, n);
897  return ret;
898 }
899 
900 
911 int
913  GNUNET_FileNameCallback callback,
914  void *callback_cls)
915 {
916  DIR *dinfo;
917  struct dirent *finfo;
918  struct stat istat;
919  int count = 0;
920  int ret;
921  char *name;
922  char *dname;
923  unsigned int name_len;
924  unsigned int n_size;
925 
926  GNUNET_assert (NULL != dir_name);
927  dname = GNUNET_STRINGS_filename_expand (dir_name);
928  if (NULL == dname)
929  return GNUNET_SYSERR;
930  while ((strlen (dname) > 0) && (dname[strlen (dname) - 1] == DIR_SEPARATOR))
931  dname[strlen (dname) - 1] = '\0';
932  if (0 != stat (dname, &istat))
933  {
935  GNUNET_free (dname);
936  return GNUNET_SYSERR;
937  }
938  if (! S_ISDIR (istat.st_mode))
939  {
941  _ ("Expected `%s' to be a directory!\n"),
942  dir_name);
943  GNUNET_free (dname);
944  return GNUNET_SYSERR;
945  }
946  errno = 0;
947  dinfo = opendir (dname);
948  if ((EACCES == errno) || (NULL == dinfo))
949  {
950  LOG_STRERROR_FILE (GNUNET_ERROR_TYPE_WARNING, "opendir", dname);
951  if (NULL != dinfo)
952  closedir (dinfo);
953  GNUNET_free (dname);
954  return GNUNET_SYSERR;
955  }
956  name_len = 256;
957  n_size = strlen (dname) + name_len + strlen (DIR_SEPARATOR_STR) + 1;
958  name = GNUNET_malloc (n_size);
959  while (NULL != (finfo = readdir (dinfo)))
960  {
961  if ((0 == strcmp (finfo->d_name, ".")) ||
962  (0 == strcmp (finfo->d_name, "..")))
963  continue;
964  if (NULL != callback)
965  {
966  if (name_len < strlen (finfo->d_name))
967  {
968  GNUNET_free (name);
969  name_len = strlen (finfo->d_name);
970  n_size = strlen (dname) + name_len + strlen (DIR_SEPARATOR_STR) + 1;
971  name = GNUNET_malloc (n_size);
972  }
973  /* dname can end in "/" only if dname == "/";
974  * if dname does not end in "/", we need to add
975  * a "/" (otherwise, we must not!) */
976  GNUNET_snprintf (name,
977  n_size,
978  "%s%s%s",
979  dname,
980  (0 == strcmp (dname, DIR_SEPARATOR_STR))
981  ? ""
983  finfo->d_name);
984  ret = callback (callback_cls, name);
985  if (GNUNET_OK != ret)
986  {
987  closedir (dinfo);
988  GNUNET_free (name);
989  GNUNET_free (dname);
990  if (GNUNET_NO == ret)
991  return count;
992  return GNUNET_SYSERR;
993  }
994  }
995  count++;
996  }
997  closedir (dinfo);
998  GNUNET_free (name);
999  GNUNET_free (dname);
1000  return count;
1001 }
1002 
1003 
1012 static int
1013 remove_helper (void *unused, const char *fn)
1014 {
1015  (void) unused;
1016  (void) GNUNET_DISK_directory_remove (fn);
1017  return GNUNET_OK;
1018 }
1019 
1020 
1028 int
1030 {
1031  struct stat istat;
1032 
1033  if (NULL == filename)
1034  {
1035  GNUNET_break (0);
1036  return GNUNET_SYSERR;
1037  }
1038  if (0 != lstat (filename, &istat))
1039  return GNUNET_NO; /* file may not exist... */
1040  (void) chmod (filename, S_IWUSR | S_IRUSR | S_IXUSR);
1041  if (0 == unlink (filename))
1042  return GNUNET_OK;
1043  if ((errno != EISDIR) &&
1044  /* EISDIR is not sufficient in all cases, e.g.
1045  * sticky /tmp directory may result in EPERM on BSD.
1046  * So we also explicitly check "isDirectory" */
1048  {
1049  LOG_STRERROR_FILE (GNUNET_ERROR_TYPE_WARNING, "rmdir", filename);
1050  return GNUNET_SYSERR;
1051  }
1052  if (GNUNET_SYSERR ==
1053  GNUNET_DISK_directory_scan (filename, &remove_helper, NULL))
1054  return GNUNET_SYSERR;
1055  if (0 != rmdir (filename))
1056  {
1057  LOG_STRERROR_FILE (GNUNET_ERROR_TYPE_WARNING, "rmdir", filename);
1058  return GNUNET_SYSERR;
1059  }
1060  return GNUNET_OK;
1061 }
1062 
1063 
1071 int
1072 GNUNET_DISK_file_copy (const char *src, const char *dst)
1073 {
1074  char *buf;
1075  uint64_t pos;
1076  uint64_t size;
1077  size_t len;
1078  ssize_t sret;
1079  struct GNUNET_DISK_FileHandle *in;
1080  struct GNUNET_DISK_FileHandle *out;
1081 
1082  if (GNUNET_OK != GNUNET_DISK_file_size (src, &size, GNUNET_YES, GNUNET_YES))
1083  {
1085  return GNUNET_SYSERR;
1086  }
1087  pos = 0;
1088  in =
1090  if (! in)
1091  {
1093  return GNUNET_SYSERR;
1094  }
1095  out =
1096  GNUNET_DISK_file_open (dst,
1103  if (! out)
1104  {
1107  return GNUNET_SYSERR;
1108  }
1109  buf = GNUNET_malloc (COPY_BLK_SIZE);
1110  while (pos < size)
1111  {
1112  len = COPY_BLK_SIZE;
1113  if (len > size - pos)
1114  len = size - pos;
1115  sret = GNUNET_DISK_file_read (in, buf, len);
1116  if ((sret < 0) || (len != (size_t) sret))
1117  goto FAIL;
1118  sret = GNUNET_DISK_file_write (out, buf, len);
1119  if ((sret < 0) || (len != (size_t) sret))
1120  goto FAIL;
1121  pos += len;
1122  }
1123  GNUNET_free (buf);
1125  GNUNET_DISK_file_close (out);
1126  return GNUNET_OK;
1127 FAIL:
1128  GNUNET_free (buf);
1130  GNUNET_DISK_file_close (out);
1131  return GNUNET_SYSERR;
1132 }
1133 
1134 
1139 void
1141 {
1142  char *idx;
1143  char c;
1144 
1145  for (idx = fn; *idx; idx++)
1146  {
1147  c = *idx;
1148 
1149  if ((c == '/') || (c == '\\') || (c == ':') || (c == '*') || (c == '?') ||
1150  (c ==
1151  '"')
1152  ||
1153  (c == '<') || (c == '>') || (c == '|') )
1154  {
1155  *idx = '_';
1156  }
1157  }
1158 }
1159 
1160 
1168 int
1169 GNUNET_DISK_file_change_owner (const char *filename, const char *user)
1170 {
1171  struct passwd *pws;
1172 
1173  pws = getpwnam (user);
1174  if (NULL == pws)
1175  {
1177  _ ("Cannot obtain information about user `%s': %s\n"),
1178  user,
1179  strerror (errno));
1180  return GNUNET_SYSERR;
1181  }
1182  if (0 != chown (filename, pws->pw_uid, pws->pw_gid))
1183  {
1184  LOG_STRERROR_FILE (GNUNET_ERROR_TYPE_WARNING, "chown", filename);
1185  return GNUNET_SYSERR;
1186  }
1187  return GNUNET_OK;
1188 }
1189 
1190 
1200 int
1202  off_t lock_start,
1203  off_t lock_end,
1204  int excl)
1205 {
1206  if (fh == NULL)
1207  {
1208  errno = EINVAL;
1209  return GNUNET_SYSERR;
1210  }
1211 
1212  struct flock fl;
1213 
1214  memset (&fl, 0, sizeof(struct flock));
1215  fl.l_type = excl ? F_WRLCK : F_RDLCK;
1216  fl.l_whence = SEEK_SET;
1217  fl.l_start = lock_start;
1218  fl.l_len = lock_end;
1219 
1220  return fcntl (fh->fd, F_SETLK, &fl) != 0 ? GNUNET_SYSERR : GNUNET_OK;
1221 }
1222 
1223 
1232 int
1234  off_t unlock_start,
1235  off_t unlock_end)
1236 {
1237  if (fh == NULL)
1238  {
1239  errno = EINVAL;
1240  return GNUNET_SYSERR;
1241  }
1242 
1243  struct flock fl;
1244 
1245  memset (&fl, 0, sizeof(struct flock));
1246  fl.l_type = F_UNLCK;
1247  fl.l_whence = SEEK_SET;
1248  fl.l_start = unlock_start;
1249  fl.l_len = unlock_end;
1250 
1251  return fcntl (fh->fd, F_SETLK, &fl) != 0 ? GNUNET_SYSERR : GNUNET_OK;
1252 }
1253 
1254 
1267 struct GNUNET_DISK_FileHandle *
1269  enum GNUNET_DISK_OpenFlags flags,
1271 {
1272  char *expfn;
1273  struct GNUNET_DISK_FileHandle *ret;
1274 
1275  int oflags;
1276  int mode;
1277  int fd;
1278 
1279  expfn = GNUNET_STRINGS_filename_expand (fn);
1280  if (NULL == expfn)
1281  return NULL;
1282 
1283  mode = 0;
1285  oflags = O_RDWR; /* note: O_RDWR is NOT always O_RDONLY | O_WRONLY */
1286  else if (flags & GNUNET_DISK_OPEN_READ)
1287  oflags = O_RDONLY;
1288  else if (flags & GNUNET_DISK_OPEN_WRITE)
1289  oflags = O_WRONLY;
1290  else
1291  {
1292  GNUNET_break (0);
1293  GNUNET_free (expfn);
1294  return NULL;
1295  }
1296  if (flags & GNUNET_DISK_OPEN_FAILIFEXISTS)
1297  oflags |= (O_CREAT | O_EXCL);
1298  if (flags & GNUNET_DISK_OPEN_TRUNCATE)
1299  oflags |= O_TRUNC;
1300  if (flags & GNUNET_DISK_OPEN_APPEND)
1301  oflags |= O_APPEND;
1302  if (GNUNET_NO == GNUNET_DISK_file_test (fn))
1303  {
1304  if (flags & GNUNET_DISK_OPEN_CREATE)
1305  {
1307  oflags |= O_CREAT;
1308  mode = translate_unix_perms (perm);
1309  }
1310  }
1311 
1312  fd = open (expfn,
1313  oflags
1314 #if O_CLOEXEC
1315  | O_CLOEXEC
1316 #endif
1317  | O_LARGEFILE,
1318  mode);
1319  if (fd == -1)
1320  {
1321  if (0 == (flags & GNUNET_DISK_OPEN_FAILIFEXISTS))
1323  else
1324  LOG_STRERROR_FILE (GNUNET_ERROR_TYPE_DEBUG, "open", expfn);
1325  GNUNET_free (expfn);
1326  return NULL;
1327  }
1328 
1329  ret = GNUNET_new (struct GNUNET_DISK_FileHandle);
1330 
1331  ret->fd = fd;
1332 
1333  GNUNET_free (expfn);
1334  return ret;
1335 }
1336 
1337 
1344 int
1346 {
1347  int ret;
1348 
1349  if (h == NULL)
1350  {
1351  errno = EINVAL;
1352  return GNUNET_SYSERR;
1353  }
1354 
1355  ret = GNUNET_OK;
1356 
1357  if (close (h->fd) != 0)
1358  {
1360  ret = GNUNET_SYSERR;
1361  }
1362 
1363  GNUNET_free (h);
1364  return ret;
1365 }
1366 
1367 
1374 struct GNUNET_DISK_FileHandle *
1376 {
1377  struct GNUNET_DISK_FileHandle *fh;
1378 
1379  if ((((off_t) -1) == lseek (fno, 0, SEEK_CUR)) && (EBADF == errno))
1380  return NULL; /* invalid FD */
1381 
1382  fh = GNUNET_new (struct GNUNET_DISK_FileHandle);
1383 
1384  fh->fd = fno;
1385 
1386  return fh;
1387 }
1388 
1389 
1396 struct GNUNET_DISK_FileHandle *
1398 {
1399  int fno;
1400 
1401  fno = fileno (fd);
1402  if (-1 == fno)
1403  return NULL;
1404 
1406 }
1407 
1408 
1413 {
1417  void *addr;
1418 
1422  size_t len;
1423 };
1424 
1425 
1426 #ifndef MAP_FAILED
1427 #define MAP_FAILED ((void *) -1)
1428 #endif
1429 
1439 void *
1441  struct GNUNET_DISK_MapHandle **m,
1442  enum GNUNET_DISK_MapType access,
1443  size_t len)
1444 {
1445  if (NULL == h)
1446  {
1447  errno = EINVAL;
1448  return NULL;
1449  }
1450 
1451  int prot;
1452 
1453  prot = 0;
1454  if (access & GNUNET_DISK_MAP_TYPE_READ)
1455  prot = PROT_READ;
1456  if (access & GNUNET_DISK_MAP_TYPE_WRITE)
1457  prot |= PROT_WRITE;
1458  *m = GNUNET_new (struct GNUNET_DISK_MapHandle);
1459  (*m)->addr = mmap (NULL, len, prot, MAP_SHARED, h->fd, 0);
1460  GNUNET_assert (NULL != (*m)->addr);
1461  if (MAP_FAILED == (*m)->addr)
1462  {
1463  GNUNET_free (*m);
1464  return NULL;
1465  }
1466  (*m)->len = len;
1467  return (*m)->addr;
1468 }
1469 
1470 
1476 int
1478 {
1479  int ret;
1480 
1481  if (h == NULL)
1482  {
1483  errno = EINVAL;
1484  return GNUNET_SYSERR;
1485  }
1486 
1487  ret = munmap (h->addr, h->len) != -1 ? GNUNET_OK : GNUNET_SYSERR;
1488 
1489  GNUNET_free (h);
1490  return ret;
1491 }
1492 
1493 
1499 int
1501 {
1502  if (h == NULL)
1503  {
1504  errno = EINVAL;
1505  return GNUNET_SYSERR;
1506  }
1507 
1508 #if defined(FREEBSD) || defined(OPENBSD) || defined(DARWIN)
1509  return fsync (h->fd) == -1 ? GNUNET_SYSERR : GNUNET_OK;
1510 #else
1511  return fdatasync (h->fd) == -1 ? GNUNET_SYSERR : GNUNET_OK;
1512 #endif
1513 }
1514 
1515 
1525 struct GNUNET_DISK_PipeHandle *
1526 GNUNET_DISK_pipe (int blocking_read,
1527  int blocking_write,
1528  int inherit_read,
1529  int inherit_write)
1530 {
1531  int fd[2];
1532  int ret;
1533  int eno;
1534 
1535  (void) inherit_read;
1536  (void) inherit_write;
1537  ret = pipe (fd);
1538  if (ret == -1)
1539  {
1540  eno = errno;
1542  errno = eno;
1543  return NULL;
1544  }
1545  return GNUNET_DISK_pipe_from_fd (blocking_read, blocking_write, fd);
1546 }
1547 
1548 
1559 struct GNUNET_DISK_PipeHandle *
1560 GNUNET_DISK_pipe_from_fd (int blocking_read, int blocking_write, int fd[2])
1561 {
1562  struct GNUNET_DISK_PipeHandle *p;
1563 
1564  p = GNUNET_new (struct GNUNET_DISK_PipeHandle);
1565 
1566  int ret;
1567  int flags;
1568  int eno = 0; /* make gcc happy */
1569 
1570  ret = 0;
1571  if (fd[0] >= 0)
1572  {
1573  p->fd[0] = GNUNET_new (struct GNUNET_DISK_FileHandle);
1574  p->fd[0]->fd = fd[0];
1575  if (! blocking_read)
1576  {
1577  flags = fcntl (fd[0], F_GETFL);
1578  flags |= O_NONBLOCK;
1579  if (0 > fcntl (fd[0], F_SETFL, flags))
1580  {
1581  ret = -1;
1582  eno = errno;
1583  }
1584  }
1585  flags = fcntl (fd[0], F_GETFD);
1586  flags |= FD_CLOEXEC;
1587  if (0 > fcntl (fd[0], F_SETFD, flags))
1588  {
1589  ret = -1;
1590  eno = errno;
1591  }
1592  }
1593 
1594  if (fd[1] >= 0)
1595  {
1596  p->fd[1] = GNUNET_new (struct GNUNET_DISK_FileHandle);
1597  p->fd[1]->fd = fd[1];
1598  if (! blocking_write)
1599  {
1600  flags = fcntl (fd[1], F_GETFL);
1601  flags |= O_NONBLOCK;
1602  if (0 > fcntl (fd[1], F_SETFL, flags))
1603  {
1604  ret = -1;
1605  eno = errno;
1606  }
1607  }
1608  flags = fcntl (fd[1], F_GETFD);
1609  flags |= FD_CLOEXEC;
1610  if (0 > fcntl (fd[1], F_SETFD, flags))
1611  {
1612  ret = -1;
1613  eno = errno;
1614  }
1615  }
1616  if (ret == -1)
1617  {
1618  errno = eno;
1620  if (p->fd[0]->fd >= 0)
1621  GNUNET_break (0 == close (p->fd[0]->fd));
1622  if (p->fd[1]->fd >= 0)
1623  GNUNET_break (0 == close (p->fd[1]->fd));
1624  GNUNET_free_non_null (p->fd[0]);
1625  GNUNET_free_non_null (p->fd[1]);
1626  GNUNET_free (p);
1627  errno = eno;
1628  return NULL;
1629  }
1630 
1631  return p;
1632 }
1633 
1634 
1642 int
1644  enum GNUNET_DISK_PipeEnd end)
1645 {
1646  int ret = GNUNET_OK;
1647 
1648  if (end == GNUNET_DISK_PIPE_END_READ)
1649  {
1650  if (p->fd[0])
1651  {
1652  ret = GNUNET_DISK_file_close (p->fd[0]);
1653  p->fd[0] = NULL;
1654  }
1655  }
1656  else if (end == GNUNET_DISK_PIPE_END_WRITE)
1657  {
1658  if (p->fd[1])
1659  {
1660  ret = GNUNET_DISK_file_close (p->fd[1]);
1661  p->fd[1] = NULL;
1662  }
1663  }
1664 
1665  return ret;
1666 }
1667 
1668 
1681 struct GNUNET_DISK_FileHandle *
1683  enum GNUNET_DISK_PipeEnd end)
1684 {
1685  struct GNUNET_DISK_FileHandle *ret = NULL;
1686 
1687  if (end == GNUNET_DISK_PIPE_END_READ)
1688  {
1689  if (p->fd[0])
1690  {
1691  ret = p->fd[0];
1692  p->fd[0] = NULL;
1693  }
1694  }
1695  else if (end == GNUNET_DISK_PIPE_END_WRITE)
1696  {
1697  if (p->fd[1])
1698  {
1699  ret = p->fd[1];
1700  p->fd[1] = NULL;
1701  }
1702  }
1703 
1704  return ret;
1705 }
1706 
1707 
1714 int
1716 {
1717  int ret = GNUNET_OK;
1718 
1719  int read_end_close;
1720  int write_end_close;
1721  int read_end_close_errno;
1722  int write_end_close_errno;
1723 
1725  read_end_close_errno = errno;
1727  write_end_close_errno = errno;
1728  GNUNET_free (p);
1729 
1730  if (GNUNET_OK != read_end_close)
1731  {
1732  errno = read_end_close_errno;
1733  ret = read_end_close;
1734  }
1735  else if (GNUNET_OK != write_end_close)
1736  {
1737  errno = write_end_close_errno;
1738  ret = write_end_close;
1739  }
1740 
1741  return ret;
1742 }
1743 
1744 
1752 const struct GNUNET_DISK_FileHandle *
1754  enum GNUNET_DISK_PipeEnd n)
1755 {
1756  switch (n)
1757  {
1760  return p->fd[n];
1761 
1762  default:
1763  GNUNET_break (0);
1764  return NULL;
1765  }
1766 }
1767 
1768 
1777 int
1779  void *dst,
1780  size_t dst_len)
1781 {
1782  if (NULL == fh)
1783  return GNUNET_SYSERR;
1784 
1785  if (dst_len < sizeof(int))
1786  return GNUNET_SYSERR;
1787  *((int *) dst) = fh->fd;
1788 
1789  return GNUNET_OK;
1790 }
1791 
1792 
1800 static int
1802 {
1803  const char *option = cls;
1804  char *tmpname;
1805 
1806  if (GNUNET_OK !=
1807  GNUNET_CONFIGURATION_get_value_filename (cfg, "PATHS", option, &tmpname))
1808  {
1810  return GNUNET_NO;
1811  }
1813  {
1815  GNUNET_free (tmpname);
1816  return GNUNET_OK;
1817  }
1818  GNUNET_free (tmpname);
1819  return GNUNET_OK;
1820 }
1821 
1822 
1830 void
1832 {
1834  GNUNET_CONFIGURATION_parse_and_run (cfg_filename,
1835  &purge_cfg_dir,
1836  (void *) option));
1837 }
1838 
1839 
1840 /* 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:1831
int 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:544
Open the file for reading.
int GNUNET_DISK_file_sync(const struct GNUNET_DISK_FileHandle *h)
Write file changes to disk.
Definition: disk.c:1500
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:1417
static const char * dir_name
Top-level directory we monitor to auto-publish.
int GNUNET_DISK_file_close(struct GNUNET_DISK_FileHandle *h)
Close an open file.
Definition: disk.c:1345
static const struct GNUNET_CONFIGURATION_Handle * cfg
Configuration we are using.
Definition: gnunet-abd.c:36
int GNUNET_DISK_file_copy(const char *src, const char *dst)
Copy a file.
Definition: disk.c:1072
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
int GNUNET_DISK_file_unlock(struct GNUNET_DISK_FileHandle *fh, off_t unlock_start, off_t unlock_end)
Unlock a part of a file.
Definition: disk.c:1233
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
int GNUNET_snprintf(char *buf, size_t size, const char *format,...)
Like snprintf, just aborts if the buffer is of insufficient size.
#define MAP_FAILED
Definition: disk.c:1427
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:732
int GNUNET_DISK_directory_create(const char *dir)
Implementation of "mkdir -p".
Definition: disk.c:589
#define GNUNET_assert(cond)
Use this for fatal errors that cannot be handled.
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:1440
Everybody can execute.
int GNUNET_DISK_directory_test(const char *fil, int is_readable)
Test if fil is a directory and listable.
Definition: disk.c:503
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.
int GNUNET_DISK_directory_create_for_file(const char *filename)
Create the directory structure for storing a file.
Definition: disk.c:684
Append to the file.
#define GNUNET_NO
Definition: gnunet_common.h:78
#define GNUNET_OK
Named constants for return values.
Definition: gnunet_common.h:75
#define GNUNET_free_non_null(ptr)
Free the memory pointed to by ptr if ptr is not NULL.
int 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:291
#define GNUNET_new(type)
Allocate a struct or union of the given type.
int GNUNET_DISK_directory_scan(const char *dir_name, GNUNET_FileNameCallback callback, void *callback_cls)
Scan a directory for files.
Definition: disk.c:912
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:226
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
ssize_t GNUNET_DISK_fn_write(const char *fn, const void *buffer, size_t n, enum GNUNET_DISK_AccessPermissions mode)
Write a buffer to a file.
Definition: disk.c:880
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...
int GNUNET_DISK_handle_invalid(const struct GNUNET_DISK_FileHandle *h)
Checks whether a handle is invalid.
Definition: disk.c:192
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:1753
static struct GNUNET_ARM_Handle * h
Connection with ARM.
Definition: gnunet-arm.c:99
#define O_LARGEFILE
Definition: platform.h:220
#define _(String)
GNU gettext support macro.
Definition: platform.h:181
static struct GNUNET_ARM_MonitorHandle * m
Monitor connection with ARM.
Definition: gnunet-arm.c:104
int GNUNET_asprintf(char **buf, const char *format,...)
Like asprintf, just portable.
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:468
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:1422
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:1682
#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.
static int remove_helper(void *unused, const char *fn)
Function that removes the given directory by calling GNUNET_DISK_directory_remove().
Definition: disk.c:1013
#define COPY_BLK_SIZE
Block size for IO for copying files.
Definition: disk.c:42
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:820
#define DIR_SEPARATOR_STR
Definition: platform.h:168
int GNUNET_DISK_directory_remove(const char *filename)
Remove all files in a directory (rm -r).
Definition: disk.c:1029
Read-only memory map.
static char * option
Name of the option.
Definition: gnunet-config.c:38
static char buf[2048]
static char * filename
static int result
Global testing status.
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.
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:436
int(* GNUNET_FileNameCallback)(void *cls, const char *filename)
Function called with a filename.
#define LOG(kind,...)
Definition: disk.c:31
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:844
struct GNUNET_DISK_PipeHandle * GNUNET_DISK_pipe(int blocking_read, int blocking_write, int inherit_read, int inherit_write)
Creates an interprocess channel.
Definition: disk.c:1526
static int getSizeRec(void *cls, const char *fn)
Iterate over all files in the given directory and accumulate their size.
Definition: disk.c:146
#define DIR_SEPARATOR
Definition: platform.h:167
int GNUNET_DISK_file_lock(struct GNUNET_DISK_FileHandle *fh, off_t lock_start, off_t lock_end, int excl)
Lock a part of a file.
Definition: disk.c:1201
#define GNUNET_SYSERR
Definition: gnunet_common.h:76
static unsigned int size
Size of the "table".
Definition: peer.c:67
int GNUNET_DISK_internal_file_handle_(const struct GNUNET_DISK_FileHandle *fh, void *dst, size_t dst_len)
Retrieve OS file handle.
Definition: disk.c:1778
Everybody can write.
int GNUNET_DISK_file_unmap(struct GNUNET_DISK_MapHandle *h)
Unmap a file.
Definition: disk.c:1477
Open the file for writing.
char * GNUNET_DISK_mkdtemp(const char *t)
Create an (empty) temporary directory on disk.
Definition: disk.c:409
char * GNUNET_STRINGS_filename_expand(const char *fil)
Complete filename (a la shell) from abbrevition.
Definition: strings.c:603
char * getenv()
int 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:257
#define S_ISLNK(m)
Definition: disk.c:61
int GNUNET_DISK_pipe_close(struct GNUNET_DISK_PipeHandle *p)
Closes an interprocess channel.
Definition: disk.c:1715
struct GNUNET_DISK_PipeHandle * GNUNET_DISK_pipe_from_fd(int blocking_read, int blocking_write, int fd[2])
Creates a pipe object from a couple of file descriptors.
Definition: disk.c:1560
#define LOG_STRERROR_FILE(kind, syscall, filename)
Definition: disk.c:36
Everybody can read.
int GNUNET_DISK_pipe_close_end(struct GNUNET_DISK_PipeHandle *p, enum GNUNET_DISK_PipeEnd end)
Closes an interprocess channel.
Definition: disk.c:1643
static int purge_cfg_dir(void *cls, const struct GNUNET_CONFIGURATION_Handle *cfg)
Helper function for GNUNET_DISK_purge_cfg_dir.
Definition: disk.c:1801
struct GNUNET_DISK_FileHandle * GNUNET_DISK_get_handle_from_int_fd(int fno)
Get a handle from a native integer FD.
Definition: disk.c:1375
configuration data
Definition: configuration.c:85
const char * name
int GNUNET_DISK_file_handle_size(struct GNUNET_DISK_FileHandle *fh, off_t *size)
Get the size of an open file.
Definition: disk.c:206
#define GNUNET_log(kind,...)
GNUNET_DISK_OpenFlags
Specifies how a file should be opened.
Open the file for both reading and writing.
int GNUNET_DISK_file_change_owner(const char *filename, const char *user)
Change owner of a file.
Definition: disk.c:1169
int 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.
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:379
static char * mktemp_name(const char *t)
Create the name for a temporary file or directory from a template.
Definition: disk.c:343
#define GNUNET_YES
Definition: gnunet_common.h:77
int fd
File handle on Unix-like systems.
Fail if file already exists.
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:757
struct GNUNET_DISK_FileHandle * GNUNET_DISK_get_handle_from_native(FILE *fd)
Get a handle from a native streaming FD.
Definition: disk.c:1397
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:1268
GNUNET_DISK_PipeEnd
Enumeration identifying the two ends of a pipe.
Handle used to access files (and pipes).
Handle used to manage a pipe.
Definition: disk.c:68
int 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...
#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:794
void GNUNET_DISK_filename_canonicalize(char *fn)
Removes special characters as &#39;:&#39; from a filename.
Definition: disk.c:1140
Handle for a memory-mapping operation.
Definition: disk.c:1412
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...