GNUnet  0.10.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 
74 };
75 
76 
85  uint64_t total;
86 
91 
96 };
97 
98 
106 static int
108 {
109  int mode;
110 
111  mode = 0;
112  if (perm & GNUNET_DISK_PERM_USER_READ)
113  mode |= S_IRUSR;
114  if (perm & GNUNET_DISK_PERM_USER_WRITE)
115  mode |= S_IWUSR;
116  if (perm & GNUNET_DISK_PERM_USER_EXEC)
117  mode |= S_IXUSR;
118  if (perm & GNUNET_DISK_PERM_GROUP_READ)
119  mode |= S_IRGRP;
120  if (perm & GNUNET_DISK_PERM_GROUP_WRITE)
121  mode |= S_IWGRP;
122  if (perm & GNUNET_DISK_PERM_GROUP_EXEC)
123  mode |= S_IXGRP;
124  if (perm & GNUNET_DISK_PERM_OTHER_READ)
125  mode |= S_IROTH;
126  if (perm & GNUNET_DISK_PERM_OTHER_WRITE)
127  mode |= S_IWOTH;
128  if (perm & GNUNET_DISK_PERM_OTHER_EXEC)
129  mode |= S_IXOTH;
130 
131  return mode;
132 }
133 
134 
143 static int
144 getSizeRec(void *cls, const char *fn)
145 {
146  struct GetFileSizeData *gfsd = cls;
147 
148 #if defined(HAVE_STAT64) && \
149  !(defined(_FILE_OFFSET_BITS) && _FILE_OFFSET_BITS == 64)
150  struct stat64 buf;
151 
152  if (0 != stat64(fn, &buf))
153  {
155  return GNUNET_SYSERR;
156  }
157 #else
158  struct stat buf;
159 
160  if (0 != stat(fn, &buf))
161  {
163  return GNUNET_SYSERR;
164  }
165 #endif
166  if ((S_ISDIR(buf.st_mode)) && (gfsd->single_file_mode == GNUNET_YES))
167  {
168  errno = EISDIR;
169  return GNUNET_SYSERR;
170  }
171  if ((!S_ISLNK(buf.st_mode)) || (gfsd->include_sym_links == GNUNET_YES))
172  gfsd->total += buf.st_size;
173  if ((S_ISDIR(buf.st_mode)) && (0 == access(fn, X_OK)) &&
174  ((!S_ISLNK(buf.st_mode)) || (gfsd->include_sym_links == GNUNET_YES)))
175  {
177  return GNUNET_SYSERR;
178  }
179  return GNUNET_OK;
180 }
181 
182 
189 int
191 {
192  return ((!h) || (h->fd == -1)) ? GNUNET_YES : GNUNET_NO;
193 }
194 
202 int
204 {
205  struct stat sbuf;
206 
207  if (0 != fstat(fh->fd, &sbuf))
208  return GNUNET_SYSERR;
209  *size = sbuf.st_size;
210  return GNUNET_OK;
211 }
212 
213 
222 off_t
224  off_t offset,
225  enum GNUNET_DISK_Seek whence)
226 {
227  if (h == NULL)
228  {
229  errno = EINVAL;
230  return GNUNET_SYSERR;
231  }
232 
233  static int t[] = { SEEK_SET, SEEK_CUR, SEEK_END };
234 
235  return lseek(h->fd, offset, t[whence]);
236 }
237 
238 
253 int
255  uint64_t *size,
256  int include_symbolic_links,
257  int single_file_mode)
258 {
259  struct GetFileSizeData gfsd;
260  int ret;
261 
262  GNUNET_assert(size != NULL);
263  gfsd.total = 0;
264  gfsd.include_sym_links = include_symbolic_links;
266  ret = getSizeRec(&gfsd, filename);
267  *size = gfsd.total;
268  return ret;
269 }
270 
271 
287 int
289  uint64_t *dev,
290  uint64_t *ino)
291 {
292 #if HAVE_STAT
293  {
294  struct stat sbuf;
295 
296  if (0 != stat(filename, &sbuf))
297  {
298  return GNUNET_SYSERR;
299  }
300  *ino = (uint64_t)sbuf.st_ino;
301  }
302 #else
303  *ino = 0;
304 #endif
305 #if HAVE_STATVFS
306  {
307  struct statvfs fbuf;
308 
309  if (0 != statvfs(filename, &fbuf))
310  {
311  return GNUNET_SYSERR;
312  }
313  *dev = (uint64_t)fbuf.f_fsid;
314  }
315 #elif HAVE_STATFS
316  {
317  struct statfs fbuf;
318 
319  if (0 != statfs(filename, &fbuf))
320  {
321  return GNUNET_SYSERR;
322  }
323  *dev =
324  ((uint64_t)fbuf.f_fsid.val[0]) << 32 || ((uint64_t)fbuf.f_fsid.val[1]);
325  }
326 #else
327  *dev = 0;
328 #endif
329  return GNUNET_OK;
330 }
331 
332 
339 static char *
340 mktemp_name(const char *t)
341 {
342  const char *tmpdir;
343  char *tmpl;
344  char *fn;
345 
346  if ((t[0] != '/') && (t[0] != '\\'))
347  {
348  /* FIXME: This uses system codepage on W32, not UTF-8 */
349  tmpdir = getenv("TMPDIR");
350  if (NULL == tmpdir)
351  tmpdir = getenv("TMP");
352  if (NULL == tmpdir)
353  tmpdir = getenv("TEMP");
354  if (NULL == tmpdir)
355  tmpdir = "/tmp";
356  GNUNET_asprintf(&tmpl, "%s/%s%s", tmpdir, t, "XXXXXX");
357  }
358  else
359  {
360  GNUNET_asprintf(&tmpl, "%s%s", t, "XXXXXX");
361  }
362  fn = tmpl;
363  return fn;
364 }
365 
366 
375 void
377  int require_uid_match,
378  int require_gid_match)
379 {
380  mode_t mode;
381 
382  if (GNUNET_YES == require_uid_match)
383  mode = S_IRUSR | S_IWUSR | S_IXUSR;
384  else if (GNUNET_YES == require_gid_match)
385  mode = S_IRUSR | S_IWUSR | S_IXUSR | S_IRGRP | S_IWGRP | S_IXGRP;
386  else
387  mode = S_IRUSR | S_IWUSR | S_IXUSR | S_IRGRP | S_IWGRP | S_IXGRP | S_IROTH |
388  S_IWOTH | S_IXOTH;
389  if (0 != chmod(fn, mode))
391 }
392 
393 
405 char *
406 GNUNET_DISK_mkdtemp(const char *t)
407 {
408  char *fn;
409  mode_t omask;
410 
411  omask = umask(S_IWGRP | S_IWOTH | S_IRGRP | S_IROTH);
412  fn = mktemp_name(t);
413  if (fn != mkdtemp(fn))
414  {
416  GNUNET_free(fn);
417  umask(omask);
418  return NULL;
419  }
420  umask(omask);
421  return fn;
422 }
423 
424 
432 void
433 GNUNET_DISK_file_backup(const char *fil)
434 {
435  size_t slen;
436  char *target;
437  unsigned int num;
438 
439  slen = strlen(fil) + 20;
440  target = GNUNET_malloc(slen);
441  num = 0;
442  do
443  {
444  GNUNET_snprintf(target, slen, "%s.%u~", fil, num++);
445  }
446  while (0 == access(target, F_OK));
447  if (0 != rename(fil, target))
449  GNUNET_free(target);
450 }
451 
452 
464 char *
465 GNUNET_DISK_mktemp(const char *t)
466 {
467  int fd;
468  char *fn;
469  mode_t omask;
470 
471  omask = umask(S_IWGRP | S_IWOTH | S_IRGRP | S_IROTH);
472  fn = mktemp_name(t);
473  if (-1 == (fd = mkstemp(fn)))
474  {
476  GNUNET_free(fn);
477  umask(omask);
478  return NULL;
479  }
480  umask(omask);
481  if (0 != close(fd))
483  return fn;
484 }
485 
486 
499 int
500 GNUNET_DISK_directory_test(const char *fil, int is_readable)
501 {
502  struct stat filestat;
503  int ret;
504 
505  ret = stat(fil, &filestat);
506  if (ret != 0)
507  {
508  if (errno != ENOENT)
510  return GNUNET_SYSERR;
511  }
512  if (!S_ISDIR(filestat.st_mode))
513  {
515  "A file already exits with the same name %s\n",
516  fil);
517  return GNUNET_NO;
518  }
519  if (GNUNET_YES == is_readable)
520  ret = access(fil, R_OK | X_OK);
521  else
522  ret = access(fil, X_OK);
523  if (ret < 0)
524  {
526  return GNUNET_NO;
527  }
528  return GNUNET_YES;
529 }
530 
531 
540 int
541 GNUNET_DISK_file_test(const char *fil)
542 {
543  struct stat filestat;
544  int ret;
545  char *rdir;
546 
547  rdir = GNUNET_STRINGS_filename_expand(fil);
548  if (rdir == NULL)
549  return GNUNET_SYSERR;
550 
551  ret = stat(rdir, &filestat);
552  if (ret != 0)
553  {
554  if (errno != ENOENT)
555  {
557  GNUNET_free(rdir);
558  return GNUNET_SYSERR;
559  }
560  GNUNET_free(rdir);
561  return GNUNET_NO;
562  }
563  if (!S_ISREG(filestat.st_mode))
564  {
565  GNUNET_free(rdir);
566  return GNUNET_NO;
567  }
568  if (access(rdir, F_OK) < 0)
569  {
571  GNUNET_free(rdir);
572  return GNUNET_SYSERR;
573  }
574  GNUNET_free(rdir);
575  return GNUNET_YES;
576 }
577 
578 
585 int
587 {
588  char *rdir;
589  unsigned int len;
590  unsigned int pos;
591  unsigned int pos2;
592  int ret = GNUNET_OK;
593 
594  rdir = GNUNET_STRINGS_filename_expand(dir);
595  if (rdir == NULL)
596  {
597  GNUNET_break(0);
598  return GNUNET_SYSERR;
599  }
600 
601  len = strlen(rdir);
602 
603  pos = 1; /* skip heading '/' */
604 
605  /* Check which low level directories already exist */
606  pos2 = len;
607  rdir[len] = DIR_SEPARATOR;
608  while (pos <= pos2)
609  {
610  if (DIR_SEPARATOR == rdir[pos2])
611  {
612  rdir[pos2] = '\0';
614  if (GNUNET_NO == ret)
615  {
617  "Creating directory `%s' failed",
618  rdir);
619  GNUNET_free(rdir);
620  return GNUNET_SYSERR;
621  }
622  rdir[pos2] = DIR_SEPARATOR;
623  if (GNUNET_YES == ret)
624  {
625  pos2++;
626  break;
627  }
628  }
629  pos2--;
630  }
631  rdir[len] = '\0';
632  if (pos < pos2)
633  pos = pos2;
634  /* Start creating directories */
635  while (pos <= len)
636  {
637  if ((rdir[pos] == DIR_SEPARATOR) || (pos == len))
638  {
639  rdir[pos] = '\0';
641  if (GNUNET_NO == ret)
642  {
644  "Creating directory `%s' failed",
645  rdir);
646  GNUNET_free(rdir);
647  return GNUNET_SYSERR;
648  }
649  if (GNUNET_SYSERR == ret)
650  {
651  ret = mkdir(rdir,
652  S_IRUSR | S_IWUSR | S_IXUSR | S_IRGRP | S_IXGRP | S_IROTH |
653  S_IXOTH); /* 755 */
654 
655  if ((ret != 0) && (errno != EEXIST))
656  {
658  GNUNET_free(rdir);
659  return GNUNET_SYSERR;
660  }
661  }
662  rdir[pos] = DIR_SEPARATOR;
663  }
664  pos++;
665  }
666  GNUNET_free(rdir);
667  return GNUNET_OK;
668 }
669 
670 
680 int
682 {
683  char *rdir;
684  size_t len;
685  int ret;
686  int eno;
687 
688  rdir = GNUNET_STRINGS_filename_expand(filename);
689  if (NULL == rdir)
690  {
691  errno = EINVAL;
692  return GNUNET_SYSERR;
693  }
694  if (0 == access(rdir, W_OK))
695  {
696  GNUNET_free(rdir);
697  return GNUNET_OK;
698  }
699 
700  len = strlen(rdir);
701  while ((len > 0) && (rdir[len] != DIR_SEPARATOR))
702  len--;
703  rdir[len] = '\0';
704  /* The empty path is invalid and in this case refers to / */
705  if (0 == len)
706  {
707  GNUNET_free(rdir);
708  rdir = GNUNET_strdup("/");
709  }
710  ret = GNUNET_DISK_directory_create(rdir);
711  if ((GNUNET_OK == ret) && (0 != access(rdir, W_OK)))
712  ret = GNUNET_NO;
713  eno = errno;
714  GNUNET_free(rdir);
715  errno = eno;
716  return ret;
717 }
718 
719 
728 ssize_t
730  void *result,
731  size_t len)
732 {
733  if (NULL == h)
734  {
735  errno = EINVAL;
736  return GNUNET_SYSERR;
737  }
738 
739  return read(h->fd, result, len);
740 }
741 
742 
753 ssize_t
755  void *result,
756  size_t len)
757 {
758  if (NULL == h)
759  {
760  errno = EINVAL;
761  return GNUNET_SYSERR;
762  }
763 
764  int flags;
765  ssize_t ret;
766 
767  /* set to non-blocking, read, then set back */
768  flags = fcntl(h->fd, F_GETFL);
769  if (0 == (flags & O_NONBLOCK))
770  (void)fcntl(h->fd, F_SETFL, flags | O_NONBLOCK);
771  ret = read(h->fd, result, len);
772  if (0 == (flags & O_NONBLOCK))
773  {
774  int eno = errno;
775  (void)fcntl(h->fd, F_SETFL, flags);
776  errno = eno;
777  }
778  return ret;
779 }
780 
781 
790 ssize_t
791 GNUNET_DISK_fn_read(const char *fn, void *result, size_t len)
792 {
793  struct GNUNET_DISK_FileHandle *fh;
794  ssize_t ret;
795  int eno;
796 
798  if (NULL == fh)
799  return GNUNET_SYSERR;
800  ret = GNUNET_DISK_file_read(fh, result, len);
801  eno = errno;
803  errno = eno;
804  return ret;
805 }
806 
807 
816 ssize_t
818  const void *buffer,
819  size_t n)
820 {
821  if (NULL == h)
822  {
823  errno = EINVAL;
824  return GNUNET_SYSERR;
825  }
826 
827 
828  return write(h->fd, buffer, n);
829 }
830 
831 
840 ssize_t
842  const void *buffer,
843  size_t n)
844 {
845  if (NULL == h)
846  {
847  errno = EINVAL;
848  return GNUNET_SYSERR;
849  }
850 
851 
852  int flags;
853  ssize_t ret;
854 
855  /* set to blocking, write, then set back */
856  flags = fcntl(h->fd, F_GETFL);
857  if (0 != (flags & O_NONBLOCK))
858  (void)fcntl(h->fd, F_SETFL, flags - O_NONBLOCK);
859  ret = write(h->fd, buffer, n);
860  if (0 == (flags & O_NONBLOCK))
861  (void)fcntl(h->fd, F_SETFL, flags);
862  return ret;
863 }
864 
865 
876 ssize_t
878  const void *buffer,
879  size_t n,
881 {
882  struct GNUNET_DISK_FileHandle *fh;
883  ssize_t ret;
884 
885  fh =
889  mode);
890  if (!fh)
891  return GNUNET_SYSERR;
892  ret = GNUNET_DISK_file_write(fh, buffer, n);
894  return ret;
895 }
896 
897 
908 int
910  GNUNET_FileNameCallback callback,
911  void *callback_cls)
912 {
913  DIR *dinfo;
914  struct dirent *finfo;
915  struct stat istat;
916  int count = 0;
917  int ret;
918  char *name;
919  char *dname;
920  unsigned int name_len;
921  unsigned int n_size;
922 
923  GNUNET_assert(NULL != dir_name);
924  dname = GNUNET_STRINGS_filename_expand(dir_name);
925  if (NULL == dname)
926  return GNUNET_SYSERR;
927  while ((strlen(dname) > 0) && (dname[strlen(dname) - 1] == DIR_SEPARATOR))
928  dname[strlen(dname) - 1] = '\0';
929  if (0 != stat(dname, &istat))
930  {
932  GNUNET_free(dname);
933  return GNUNET_SYSERR;
934  }
935  if (!S_ISDIR(istat.st_mode))
936  {
938  _("Expected `%s' to be a directory!\n"),
939  dir_name);
940  GNUNET_free(dname);
941  return GNUNET_SYSERR;
942  }
943  errno = 0;
944  dinfo = opendir(dname);
945  if ((EACCES == errno) || (NULL == dinfo))
946  {
947  LOG_STRERROR_FILE(GNUNET_ERROR_TYPE_WARNING, "opendir", dname);
948  if (NULL != dinfo)
949  closedir(dinfo);
950  GNUNET_free(dname);
951  return GNUNET_SYSERR;
952  }
953  name_len = 256;
954  n_size = strlen(dname) + name_len + strlen(DIR_SEPARATOR_STR) + 1;
955  name = GNUNET_malloc(n_size);
956  while (NULL != (finfo = readdir(dinfo)))
957  {
958  if ((0 == strcmp(finfo->d_name, ".")) ||
959  (0 == strcmp(finfo->d_name, "..")))
960  continue;
961  if (NULL != callback)
962  {
963  if (name_len < strlen(finfo->d_name))
964  {
965  GNUNET_free(name);
966  name_len = strlen(finfo->d_name);
967  n_size = strlen(dname) + name_len + strlen(DIR_SEPARATOR_STR) + 1;
968  name = GNUNET_malloc(n_size);
969  }
970  /* dname can end in "/" only if dname == "/";
971  * if dname does not end in "/", we need to add
972  * a "/" (otherwise, we must not!) */
973  GNUNET_snprintf(name,
974  n_size,
975  "%s%s%s",
976  dname,
977  (0 == strcmp(dname, DIR_SEPARATOR_STR))
978  ? ""
980  finfo->d_name);
981  ret = callback(callback_cls, name);
982  if (GNUNET_OK != ret)
983  {
984  closedir(dinfo);
985  GNUNET_free(name);
986  GNUNET_free(dname);
987  if (GNUNET_NO == ret)
988  return count;
989  return GNUNET_SYSERR;
990  }
991  }
992  count++;
993  }
994  closedir(dinfo);
995  GNUNET_free(name);
996  GNUNET_free(dname);
997  return count;
998 }
999 
1000 
1009 static int
1010 remove_helper(void *unused, const char *fn)
1011 {
1012  (void)unused;
1013  (void)GNUNET_DISK_directory_remove(fn);
1014  return GNUNET_OK;
1015 }
1016 
1017 
1025 int
1027 {
1028  struct stat istat;
1029 
1030  if (NULL == filename)
1031  {
1032  GNUNET_break(0);
1033  return GNUNET_SYSERR;
1034  }
1035  if (0 != lstat(filename, &istat))
1036  return GNUNET_NO; /* file may not exist... */
1037  (void)chmod(filename, S_IWUSR | S_IRUSR | S_IXUSR);
1038  if (0 == unlink(filename))
1039  return GNUNET_OK;
1040  if ((errno != EISDIR) &&
1041  /* EISDIR is not sufficient in all cases, e.g.
1042  * sticky /tmp directory may result in EPERM on BSD.
1043  * So we also explicitly check "isDirectory" */
1045  {
1046  LOG_STRERROR_FILE(GNUNET_ERROR_TYPE_WARNING, "rmdir", filename);
1047  return GNUNET_SYSERR;
1048  }
1049  if (GNUNET_SYSERR ==
1050  GNUNET_DISK_directory_scan(filename, &remove_helper, NULL))
1051  return GNUNET_SYSERR;
1052  if (0 != rmdir(filename))
1053  {
1054  LOG_STRERROR_FILE(GNUNET_ERROR_TYPE_WARNING, "rmdir", filename);
1055  return GNUNET_SYSERR;
1056  }
1057  return GNUNET_OK;
1058 }
1059 
1060 
1068 int
1069 GNUNET_DISK_file_copy(const char *src, const char *dst)
1070 {
1071  char *buf;
1072  uint64_t pos;
1073  uint64_t size;
1074  size_t len;
1075  ssize_t sret;
1076  struct GNUNET_DISK_FileHandle *in;
1077  struct GNUNET_DISK_FileHandle *out;
1078 
1080  {
1082  return GNUNET_SYSERR;
1083  }
1084  pos = 0;
1085  in =
1087  if (!in)
1088  {
1090  return GNUNET_SYSERR;
1091  }
1092  out =
1100  if (!out)
1101  {
1104  return GNUNET_SYSERR;
1105  }
1107  while (pos < size)
1108  {
1109  len = COPY_BLK_SIZE;
1110  if (len > size - pos)
1111  len = size - pos;
1112  sret = GNUNET_DISK_file_read(in, buf, len);
1113  if ((sret < 0) || (len != (size_t)sret))
1114  goto FAIL;
1115  sret = GNUNET_DISK_file_write(out, buf, len);
1116  if ((sret < 0) || (len != (size_t)sret))
1117  goto FAIL;
1118  pos += len;
1119  }
1120  GNUNET_free(buf);
1123  return GNUNET_OK;
1124 FAIL:
1125  GNUNET_free(buf);
1128  return GNUNET_SYSERR;
1129 }
1130 
1131 
1136 void
1138 {
1139  char *idx;
1140  char c;
1141 
1142  for (idx = fn; *idx; idx++)
1143  {
1144  c = *idx;
1145 
1146  if (c == '/' || c == '\\' || c == ':' || c == '*' || c == '?' || c == '"' ||
1147  c == '<' || c == '>' || c == '|')
1148  {
1149  *idx = '_';
1150  }
1151  }
1152 }
1153 
1154 
1162 int
1163 GNUNET_DISK_file_change_owner(const char *filename, const char *user)
1164 {
1165  struct passwd *pws;
1166 
1167  pws = getpwnam(user);
1168  if (NULL == pws)
1169  {
1171  _("Cannot obtain information about user `%s': %s\n"),
1172  user,
1173  strerror(errno));
1174  return GNUNET_SYSERR;
1175  }
1176  if (0 != chown(filename, pws->pw_uid, pws->pw_gid))
1177  {
1178  LOG_STRERROR_FILE(GNUNET_ERROR_TYPE_WARNING, "chown", filename);
1179  return GNUNET_SYSERR;
1180  }
1181  return GNUNET_OK;
1182 }
1183 
1184 
1194 int
1196  off_t lock_start,
1197  off_t lock_end,
1198  int excl)
1199 {
1200  if (fh == NULL)
1201  {
1202  errno = EINVAL;
1203  return GNUNET_SYSERR;
1204  }
1205 
1206  struct flock fl;
1207 
1208  memset(&fl, 0, sizeof(struct flock));
1209  fl.l_type = excl ? F_WRLCK : F_RDLCK;
1210  fl.l_whence = SEEK_SET;
1211  fl.l_start = lock_start;
1212  fl.l_len = lock_end;
1213 
1214  return fcntl(fh->fd, F_SETLK, &fl) != 0 ? GNUNET_SYSERR : GNUNET_OK;
1215 }
1216 
1217 
1226 int
1228  off_t unlock_start,
1229  off_t unlock_end)
1230 {
1231  if (fh == NULL)
1232  {
1233  errno = EINVAL;
1234  return GNUNET_SYSERR;
1235  }
1236 
1237  struct flock fl;
1238 
1239  memset(&fl, 0, sizeof(struct flock));
1240  fl.l_type = F_UNLCK;
1241  fl.l_whence = SEEK_SET;
1242  fl.l_start = unlock_start;
1243  fl.l_len = unlock_end;
1244 
1245  return fcntl(fh->fd, F_SETLK, &fl) != 0 ? GNUNET_SYSERR : GNUNET_OK;
1246 }
1247 
1248 
1261 struct GNUNET_DISK_FileHandle *
1263  enum GNUNET_DISK_OpenFlags flags,
1265 {
1266  char *expfn;
1267  struct GNUNET_DISK_FileHandle *ret;
1268 
1269  int oflags;
1270  int mode;
1271  int fd;
1272 
1273  expfn = GNUNET_STRINGS_filename_expand(fn);
1274  if (NULL == expfn)
1275  return NULL;
1276 
1277  mode = 0;
1279  oflags = O_RDWR; /* note: O_RDWR is NOT always O_RDONLY | O_WRONLY */
1280  else if (flags & GNUNET_DISK_OPEN_READ)
1281  oflags = O_RDONLY;
1282  else if (flags & GNUNET_DISK_OPEN_WRITE)
1283  oflags = O_WRONLY;
1284  else
1285  {
1286  GNUNET_break(0);
1287  GNUNET_free(expfn);
1288  return NULL;
1289  }
1290  if (flags & GNUNET_DISK_OPEN_FAILIFEXISTS)
1291  oflags |= (O_CREAT | O_EXCL);
1292  if (flags & GNUNET_DISK_OPEN_TRUNCATE)
1293  oflags |= O_TRUNC;
1294  if (flags & GNUNET_DISK_OPEN_APPEND)
1295  oflags |= O_APPEND;
1296  if (GNUNET_NO == GNUNET_DISK_file_test(fn))
1297  {
1298  if (flags & GNUNET_DISK_OPEN_CREATE)
1299  {
1301  oflags |= O_CREAT;
1302  mode = translate_unix_perms(perm);
1303  }
1304  }
1305 
1306  fd = open(expfn,
1307  oflags
1308 #if O_CLOEXEC
1309  | O_CLOEXEC
1310 #endif
1311  | O_LARGEFILE,
1312  mode);
1313  if (fd == -1)
1314  {
1315  if (0 == (flags & GNUNET_DISK_OPEN_FAILIFEXISTS))
1317  else
1319  GNUNET_free(expfn);
1320  return NULL;
1321  }
1322 
1323  ret = GNUNET_new(struct GNUNET_DISK_FileHandle);
1324 
1325  ret->fd = fd;
1326 
1327  GNUNET_free(expfn);
1328  return ret;
1329 }
1330 
1331 
1338 int
1340 {
1341  int ret;
1342 
1343  if (h == NULL)
1344  {
1345  errno = EINVAL;
1346  return GNUNET_SYSERR;
1347  }
1348 
1349  ret = GNUNET_OK;
1350 
1351  if (close(h->fd) != 0)
1352  {
1354  ret = GNUNET_SYSERR;
1355  }
1356 
1357  GNUNET_free(h);
1358  return ret;
1359 }
1360 
1361 
1368 struct GNUNET_DISK_FileHandle *
1370 {
1371  struct GNUNET_DISK_FileHandle *fh;
1372 
1373  if ((((off_t)-1) == lseek(fno, 0, SEEK_CUR)) && (EBADF == errno))
1374  return NULL; /* invalid FD */
1375 
1376  fh = GNUNET_new(struct GNUNET_DISK_FileHandle);
1377 
1378  fh->fd = fno;
1379 
1380  return fh;
1381 }
1382 
1383 
1390 struct GNUNET_DISK_FileHandle *
1392 {
1393  int fno;
1394 
1395  fno = fileno(fd);
1396  if (-1 == fno)
1397  return NULL;
1398 
1400 }
1401 
1402 
1410  void *addr;
1411 
1415  size_t len;
1416 };
1417 
1418 
1419 #ifndef MAP_FAILED
1420 #define MAP_FAILED ((void *)-1)
1421 #endif
1422 
1432 void *
1434  struct GNUNET_DISK_MapHandle **m,
1435  enum GNUNET_DISK_MapType access,
1436  size_t len)
1437 {
1438  if (NULL == h)
1439  {
1440  errno = EINVAL;
1441  return NULL;
1442  }
1443 
1444  int prot;
1445 
1446  prot = 0;
1447  if (access & GNUNET_DISK_MAP_TYPE_READ)
1448  prot = PROT_READ;
1449  if (access & GNUNET_DISK_MAP_TYPE_WRITE)
1450  prot |= PROT_WRITE;
1451  *m = GNUNET_new(struct GNUNET_DISK_MapHandle);
1452  (*m)->addr = mmap(NULL, len, prot, MAP_SHARED, h->fd, 0);
1453  GNUNET_assert(NULL != (*m)->addr);
1454  if (MAP_FAILED == (*m)->addr)
1455  {
1456  GNUNET_free(*m);
1457  return NULL;
1458  }
1459  (*m)->len = len;
1460  return (*m)->addr;
1461 }
1462 
1468 int
1470 {
1471  int ret;
1472 
1473  if (h == NULL)
1474  {
1475  errno = EINVAL;
1476  return GNUNET_SYSERR;
1477  }
1478 
1479  ret = munmap(h->addr, h->len) != -1 ? GNUNET_OK : GNUNET_SYSERR;
1480 
1481  GNUNET_free(h);
1482  return ret;
1483 }
1484 
1485 
1491 int
1493 {
1494  if (h == NULL)
1495  {
1496  errno = EINVAL;
1497  return GNUNET_SYSERR;
1498  }
1499 
1500 #if defined(FREEBSD) || defined(OPENBSD) || defined(DARWIN)
1501  return fsync(h->fd) == -1 ? GNUNET_SYSERR : GNUNET_OK;
1502 #else
1503  return fdatasync(h->fd) == -1 ? GNUNET_SYSERR : GNUNET_OK;
1504 #endif
1505 }
1506 
1507 
1517 struct GNUNET_DISK_PipeHandle *
1518 GNUNET_DISK_pipe(int blocking_read,
1519  int blocking_write,
1520  int inherit_read,
1521  int inherit_write)
1522 {
1523  int fd[2];
1524  int ret;
1525  int eno;
1526 
1527  (void)inherit_read;
1528  (void)inherit_write;
1529  ret = pipe(fd);
1530  if (ret == -1)
1531  {
1532  eno = errno;
1534  errno = eno;
1535  return NULL;
1536  }
1537  return GNUNET_DISK_pipe_from_fd(blocking_read, blocking_write, fd);
1538 }
1539 
1540 
1551 struct GNUNET_DISK_PipeHandle *
1552 GNUNET_DISK_pipe_from_fd(int blocking_read, int blocking_write, int fd[2])
1553 {
1554  struct GNUNET_DISK_PipeHandle *p;
1555 
1556  p = GNUNET_new(struct GNUNET_DISK_PipeHandle);
1557 
1558  int ret;
1559  int flags;
1560  int eno = 0; /* make gcc happy */
1561 
1562  ret = 0;
1563  if (fd[0] >= 0)
1564  {
1565  p->fd[0] = GNUNET_new(struct GNUNET_DISK_FileHandle);
1566  p->fd[0]->fd = fd[0];
1567  if (!blocking_read)
1568  {
1569  flags = fcntl(fd[0], F_GETFL);
1570  flags |= O_NONBLOCK;
1571  if (0 > fcntl(fd[0], F_SETFL, flags))
1572  {
1573  ret = -1;
1574  eno = errno;
1575  }
1576  }
1577  flags = fcntl(fd[0], F_GETFD);
1578  flags |= FD_CLOEXEC;
1579  if (0 > fcntl(fd[0], F_SETFD, flags))
1580  {
1581  ret = -1;
1582  eno = errno;
1583  }
1584  }
1585 
1586  if (fd[1] >= 0)
1587  {
1588  p->fd[1] = GNUNET_new(struct GNUNET_DISK_FileHandle);
1589  p->fd[1]->fd = fd[1];
1590  if (!blocking_write)
1591  {
1592  flags = fcntl(fd[1], F_GETFL);
1593  flags |= O_NONBLOCK;
1594  if (0 > fcntl(fd[1], F_SETFL, flags))
1595  {
1596  ret = -1;
1597  eno = errno;
1598  }
1599  }
1600  flags = fcntl(fd[1], F_GETFD);
1601  flags |= FD_CLOEXEC;
1602  if (0 > fcntl(fd[1], F_SETFD, flags))
1603  {
1604  ret = -1;
1605  eno = errno;
1606  }
1607  }
1608  if (ret == -1)
1609  {
1610  errno = eno;
1612  if (p->fd[0]->fd >= 0)
1613  GNUNET_break(0 == close(p->fd[0]->fd));
1614  if (p->fd[1]->fd >= 0)
1615  GNUNET_break(0 == close(p->fd[1]->fd));
1616  GNUNET_free_non_null(p->fd[0]);
1617  GNUNET_free_non_null(p->fd[1]);
1618  GNUNET_free(p);
1619  errno = eno;
1620  return NULL;
1621  }
1622 
1623  return p;
1624 }
1625 
1626 
1634 int
1636  enum GNUNET_DISK_PipeEnd end)
1637 {
1638  int ret = GNUNET_OK;
1639 
1640  if (end == GNUNET_DISK_PIPE_END_READ)
1641  {
1642  if (p->fd[0])
1643  {
1644  ret = GNUNET_DISK_file_close(p->fd[0]);
1645  p->fd[0] = NULL;
1646  }
1647  }
1648  else if (end == GNUNET_DISK_PIPE_END_WRITE)
1649  {
1650  if (p->fd[1])
1651  {
1652  ret = GNUNET_DISK_file_close(p->fd[1]);
1653  p->fd[1] = NULL;
1654  }
1655  }
1656 
1657  return ret;
1658 }
1659 
1672 struct GNUNET_DISK_FileHandle *
1674  enum GNUNET_DISK_PipeEnd end)
1675 {
1676  struct GNUNET_DISK_FileHandle *ret = NULL;
1677 
1678  if (end == GNUNET_DISK_PIPE_END_READ)
1679  {
1680  if (p->fd[0])
1681  {
1682  ret = p->fd[0];
1683  p->fd[0] = NULL;
1684  }
1685  }
1686  else if (end == GNUNET_DISK_PIPE_END_WRITE)
1687  {
1688  if (p->fd[1])
1689  {
1690  ret = p->fd[1];
1691  p->fd[1] = NULL;
1692  }
1693  }
1694 
1695  return ret;
1696 }
1697 
1698 
1705 int
1707 {
1708  int ret = GNUNET_OK;
1709 
1710  int read_end_close;
1711  int write_end_close;
1712  int read_end_close_errno;
1713  int write_end_close_errno;
1714 
1716  read_end_close_errno = errno;
1718  write_end_close_errno = errno;
1719  GNUNET_free(p);
1720 
1721  if (GNUNET_OK != read_end_close)
1722  {
1723  errno = read_end_close_errno;
1724  ret = read_end_close;
1725  }
1726  else if (GNUNET_OK != write_end_close)
1727  {
1728  errno = write_end_close_errno;
1729  ret = write_end_close;
1730  }
1731 
1732  return ret;
1733 }
1734 
1735 
1743 const struct GNUNET_DISK_FileHandle *
1745  enum GNUNET_DISK_PipeEnd n)
1746 {
1747  switch (n)
1748  {
1751  return p->fd[n];
1752 
1753  default:
1754  GNUNET_break(0);
1755  return NULL;
1756  }
1757 }
1758 
1759 
1768 int
1770  void *dst,
1771  size_t dst_len)
1772 {
1773  if (NULL == fh)
1774  return GNUNET_SYSERR;
1775 
1776  if (dst_len < sizeof(int))
1777  return GNUNET_SYSERR;
1778  *((int *)dst) = fh->fd;
1779 
1780  return GNUNET_OK;
1781 }
1782 
1783 
1791 static int
1793 {
1794  const char *option = cls;
1795  char *tmpname;
1796 
1797  if (GNUNET_OK !=
1798  GNUNET_CONFIGURATION_get_value_filename(cfg, "PATHS", option, &tmpname))
1799  {
1801  return GNUNET_NO;
1802  }
1804  {
1806  GNUNET_free(tmpname);
1807  return GNUNET_OK;
1808  }
1809  GNUNET_free(tmpname);
1810  return GNUNET_OK;
1811 }
1812 
1813 
1821 void
1823 {
1826  &purge_cfg_dir,
1827  (void *)option));
1828 }
1829 
1830 
1831 /* 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:1822
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:541
Open the file for reading.
int GNUNET_DISK_file_sync(const struct GNUNET_DISK_FileHandle *h)
Write file changes to disk.
Definition: disk.c:1492
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:84
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:1410
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:1339
int GNUNET_DISK_file_copy(const char *src, const char *dst)
Copy a file.
Definition: disk.c:1069
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:85
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:1227
int single_file_mode
GNUNET_YES if mode is file-only (return total == -1 for directories).
Definition: disk.c:95
Closure for the recursion to determine the file size of a directory.
Definition: disk.c:81
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:1420
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:729
int GNUNET_DISK_directory_create(const char *dir)
Implementation of "mkdir -p".
Definition: disk.c:586
#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:1433
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:500
Nobody is allowed to do anything to the file.
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:681
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:288
#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:909
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:223
static int ret
Final status code.
Definition: gnunet-arm.c:89
#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:877
static int translate_unix_perms(enum GNUNET_DISK_AccessPermissions perm)
Translate GNUnet-internal permission bitmap to UNIX file access permission bitmap.
Definition: disk.c:107
#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:190
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:1744
static struct GNUNET_ARM_Handle * h
Connection with ARM.
Definition: gnunet-arm.c:94
#define O_LARGEFILE
Definition: platform.h:219
#define _(String)
GNU gettext support macro.
Definition: platform.h:181
static struct GNUNET_ARM_MonitorHandle * m
Monitor connection with ARM.
Definition: gnunet-arm.c:99
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:73
char * GNUNET_DISK_mktemp(const char *t)
Create an (empty) temporary file on disk.
Definition: disk.c:465
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:1415
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:1673
#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:1010
#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:817
#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:1026
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:90
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:433
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:841
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:1518
static struct GNUNET_CONFIGURATION_Handle * cfg
Our configuration.
Definition: gnunet-arm.c:104
static int getSizeRec(void *cls, const char *fn)
Iterate over all files in the given directory and accumulate their size.
Definition: disk.c:144
#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:1195
#define GNUNET_SYSERR
Definition: gnunet_common.h:76
static unsigned int size
Size of the "table".
Definition: peer.c:66
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:1769
Everybody can write.
int GNUNET_DISK_file_unmap(struct GNUNET_DISK_MapHandle *h)
Unmap a file.
Definition: disk.c:1469
Open the file for writing.
char * GNUNET_DISK_mkdtemp(const char *t)
Create an (empty) temporary directory on disk.
Definition: disk.c:406
char * GNUNET_STRINGS_filename_expand(const char *fil)
Complete filename (a la shell) from abbrevition.
Definition: strings.c:602
const char * name
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:254
#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:1706
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:1552
#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:1635
static int purge_cfg_dir(void *cls, const struct GNUNET_CONFIGURATION_Handle *cfg)
Helper function for GNUNET_DISK_purge_cfg_dir.
Definition: disk.c:1792
struct GNUNET_DISK_FileHandle * GNUNET_DISK_get_handle_from_int_fd(int fno)
Get a handle from a native integer FD.
Definition: disk.c:1369
configuration data
Definition: configuration.c:83
int GNUNET_DISK_file_handle_size(struct GNUNET_DISK_FileHandle *fh, off_t *size)
Get the size of an open file.
Definition: disk.c:203
#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:1163
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:376
static char * mktemp_name(const char *t)
Create the name for a temporary file or directory from a template.
Definition: disk.c:340
#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:754
struct GNUNET_DISK_FileHandle * GNUNET_DISK_get_handle_from_native(FILE *fd)
Get a handle from a native streaming FD.
Definition: disk.c:1391
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:1262
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:791
void GNUNET_DISK_filename_canonicalize(char *fn)
Removes special characters as &#39;:&#39; from a filename.
Definition: disk.c:1137
static enum @11 mode
Should we do a PUT (mode = 0) or GET (mode = 1);.
Handle for a memory-mapping operation.
Definition: disk.c:1406
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...