GNUnet 0.22.2
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 */
27#include "platform.h"
28#include "gnunet_util_lib.h"
29#include "disk.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
108static int
110{
111 int mode;
112
113 mode = 0;
115 mode |= S_IRUSR;
117 mode |= S_IWUSR;
119 mode |= S_IXUSR;
121 mode |= S_IRGRP;
123 mode |= S_IWGRP;
125 mode |= S_IXGRP;
127 mode |= S_IROTH;
129 mode |= S_IWOTH;
131 mode |= S_IXOTH;
132
133 return mode;
134}
135
136
146get_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 != lstat64 (fn, &buf))
155 {
157 return GNUNET_SYSERR;
158 }
159#else
160 struct stat buf;
161
162 if (0 != lstat (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
205off_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
292static char *
293mktemp_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
320void
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
339char *
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
359char *
360GNUNET_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
370#if HAVE_RENAMEAT2
371 {
372 int fd;
373
374 do
375 {
376 GNUNET_snprintf (target,
377 slen,
378 "%s.%u~",
379 fil,
380 num++);
381 fd = open (target,
382 O_CREAT | O_EXCL,
384 } while (-1 == fd);
385 if (0 != renameat2 (AT_FDCWD,
386 fil,
387 AT_FDCWD,
388 target,
389 RENAME_EXCHANGE))
390 {
392 "renameat2",
393 fil);
394 GNUNET_break (0 ==
395 close (fd));
396 return NULL;
397 }
398 GNUNET_break (0 ==
399 close (fd));
400 }
401#else
402 do
403 {
404 GNUNET_snprintf (target, slen, "%s.%u~", fil, num++);
405 }
406 while (0 == access (target, F_OK));
407 if (0 != rename (fil, target))
408 {
410 return NULL;
411 }
412#endif
413 return target;
414}
415
416
417char *
419{
420 int fd;
421 char *fn;
422 mode_t omask;
423
424 omask = umask (S_IWGRP | S_IWOTH | S_IRGRP | S_IROTH);
425 fn = mktemp_name (t);
426 if (-1 == (fd = mkstemp (fn)))
427 {
429 GNUNET_free (fn);
430 umask (omask);
431 return NULL;
432 }
433 umask (omask);
434 if (0 != close (fd))
436 return fn;
437}
438
439
441GNUNET_DISK_directory_test (const char *fil, int is_readable)
442{
443 struct stat filestat;
444 int ret;
445
446 ret = stat (fil, &filestat);
447 if (ret != 0)
448 {
449 if (errno != ENOENT)
451 return GNUNET_SYSERR;
452 }
453 if (! S_ISDIR (filestat.st_mode))
454 {
456 "A file already exits with the same name %s\n",
457 fil);
458 return GNUNET_NO;
459 }
460 if (GNUNET_YES == is_readable)
461 ret = access (fil, R_OK | X_OK);
462 else
463 ret = access (fil, X_OK);
464 if (ret < 0)
465 {
467 return GNUNET_NO;
468 }
469 return GNUNET_YES;
470}
471
472
481file_test_internal (const char *fil, int amode)
482{
483 struct stat filestat;
484 int ret;
485 char *rdir;
486
488 if (rdir == NULL)
489 return GNUNET_SYSERR;
490
491 ret = stat (rdir, &filestat);
492 if (0 != ret)
493 {
494 if (errno != ENOENT)
495 {
497 GNUNET_free (rdir);
498 return GNUNET_SYSERR;
499 }
500 GNUNET_free (rdir);
501 return GNUNET_NO;
502 }
503 if (! S_ISREG (filestat.st_mode))
504 {
505 GNUNET_free (rdir);
506 return GNUNET_NO;
507 }
508 if (access (rdir, amode) < 0)
509 {
511 GNUNET_free (rdir);
512 return GNUNET_SYSERR;
513 }
514 GNUNET_free (rdir);
515 return GNUNET_YES;
516}
517
518
520GNUNET_DISK_file_test (const char *fil)
521{
522 return file_test_internal (fil, F_OK);
523}
524
525
528{
529 return file_test_internal (fil, R_OK);
530}
531
532
535{
536 char *rdir;
537 unsigned int len;
538 unsigned int pos;
539 unsigned int pos2;
540 int ret = GNUNET_OK;
541
543 if (rdir == NULL)
544 {
545 GNUNET_break (0);
546 return GNUNET_SYSERR;
547 }
548
549 len = strlen (rdir);
550
551 pos = 1; /* skip heading '/' */
552
553 /* Check which low level directories already exist */
554 pos2 = len;
555 rdir[len] = DIR_SEPARATOR;
556 while (pos <= pos2)
557 {
558 if (DIR_SEPARATOR == rdir[pos2])
559 {
560 rdir[pos2] = '\0';
562 if (GNUNET_NO == ret)
563 {
565 "Creating directory `%s' failed\n",
566 rdir);
567 GNUNET_free (rdir);
568 return GNUNET_SYSERR;
569 }
570 rdir[pos2] = DIR_SEPARATOR;
571 if (GNUNET_YES == ret)
572 {
573 pos2++;
574 break;
575 }
576 }
577 pos2--;
578 }
579 rdir[len] = '\0';
580 if (pos < pos2)
581 pos = pos2;
582 /* Start creating directories */
583 while (pos <= len)
584 {
585 if ((rdir[pos] == DIR_SEPARATOR) || (pos == len))
586 {
587 rdir[pos] = '\0';
589 if (GNUNET_NO == ret)
590 {
592 "Creating directory `%s' failed\n",
593 rdir);
594 GNUNET_free (rdir);
595 return GNUNET_SYSERR;
596 }
597 if (GNUNET_SYSERR == ret)
598 {
599 ret = mkdir (rdir,
600 S_IRUSR | S_IWUSR | S_IXUSR | S_IRGRP | S_IXGRP | S_IROTH
601 | S_IXOTH); /* 755 */
602
603 if ((ret != 0) && (errno != EEXIST))
604 {
606 GNUNET_free (rdir);
607 return GNUNET_SYSERR;
608 }
609 }
610 rdir[pos] = DIR_SEPARATOR;
611 }
612 pos++;
613 }
614 GNUNET_free (rdir);
615 return GNUNET_OK;
616}
617
618
621{
622 char *rdir;
623 size_t len;
624 int eno;
626
628 if (NULL == rdir)
629 {
630 errno = EINVAL;
631 return GNUNET_SYSERR;
632 }
633 if (0 == access (rdir, W_OK))
634 {
635 GNUNET_free (rdir);
636 return GNUNET_OK;
637 }
638 len = strlen (rdir);
639 while ((len > 0) && (rdir[len] != DIR_SEPARATOR))
640 len--;
641 rdir[len] = '\0';
642 /* The empty path is invalid and in this case refers to / */
643 if (0 == len)
644 {
645 GNUNET_free (rdir);
646 rdir = GNUNET_strdup ("/");
647 }
649 if ( (GNUNET_OK == res) &&
650 (0 != access (rdir, W_OK)) )
651 res = GNUNET_NO;
652 eno = errno;
653 GNUNET_free (rdir);
654 errno = eno;
655 return res;
656}
657
658
659ssize_t
661 void *result,
662 size_t len)
663{
664 if (NULL == h)
665 {
666 errno = EINVAL;
667 return GNUNET_SYSERR;
668 }
669 return read (h->fd, result, len);
670}
671
672
673ssize_t
674GNUNET_DISK_fn_read (const char *fn,
675 void *result,
676 size_t len)
677{
678 struct GNUNET_DISK_FileHandle *fh;
679 ssize_t ret;
680 int eno;
681
682 fh = GNUNET_DISK_file_open (fn,
685 if (NULL == fh)
686 return GNUNET_SYSERR;
687 ret = GNUNET_DISK_file_read (fh, result, len);
688 eno = errno;
691 errno = eno;
692 return ret;
693}
694
695
696ssize_t
698 const void *buffer,
699 size_t n)
700{
701 if (NULL == h)
702 {
703 errno = EINVAL;
704 return GNUNET_SYSERR;
705 }
706 return write (h->fd,
707 buffer,
708 n);
709}
710
711
712ssize_t
714 const void *buffer,
715 size_t n)
716{
717 int flags;
718 ssize_t ret;
719
720 if (NULL == h)
721 {
722 errno = EINVAL;
723 return GNUNET_SYSERR;
724 }
725 /* set to blocking, write, then set back */
726 flags = fcntl (h->fd, F_GETFL);
727 if (0 != (flags & O_NONBLOCK))
728 (void) fcntl (h->fd, F_SETFL, flags - O_NONBLOCK);
729 ret = write (h->fd, buffer, n);
730 if (0 == (flags & O_NONBLOCK))
731 (void) fcntl (h->fd, F_SETFL, flags);
732 return ret;
733}
734
735
737GNUNET_DISK_fn_write (const char *fn,
738 const void *buf,
739 size_t buf_size,
741{
742 char *tmpl;
743 int fd;
744
745 if (GNUNET_OK !=
747 {
749 "mkstemp",
750 fn);
751 return GNUNET_SYSERR;
752 }
753 {
754 char *dname;
755
756 dname = GNUNET_strdup (fn);
757 GNUNET_asprintf (&tmpl,
758 "%s/XXXXXX",
759 dirname (dname));
760 GNUNET_free (dname);
761 }
762 fd = mkstemp (tmpl);
763 if (-1 == fd)
764 {
766 "mkstemp",
767 tmpl);
768 GNUNET_free (tmpl);
769 return GNUNET_SYSERR;
770 }
771
772 if (0 != fchmod (fd,
774 {
776 "chmod",
777 tmpl);
778 GNUNET_assert (0 == close (fd));
779 if (0 != unlink (tmpl))
781 "unlink",
782 tmpl);
783 GNUNET_free (tmpl);
784 return GNUNET_SYSERR;
785 }
786 if (buf_size !=
787 write (fd,
788 buf,
789 buf_size))
790 {
792 "write",
793 tmpl);
794 GNUNET_assert (0 == close (fd));
795 if (0 != unlink (tmpl))
797 "unlink",
798 tmpl);
799 GNUNET_free (tmpl);
800 return GNUNET_SYSERR;
801 }
802 GNUNET_assert (0 == close (fd));
803
804 if (0 != link (tmpl,
805 fn))
806 {
807 if (0 != unlink (tmpl))
809 "unlink",
810 tmpl);
811 GNUNET_free (tmpl);
812 return GNUNET_NO;
813 }
814 if (0 != unlink (tmpl))
816 "unlink",
817 tmpl);
818 GNUNET_free (tmpl);
819 return GNUNET_OK;
820
821
822}
823
824
825int
828 void *callback_cls)
829{
830 DIR *dinfo;
831 struct dirent *finfo;
832 int count = 0;
834 char *name;
835 char *dname;
836 unsigned int name_len;
837 unsigned int n_size;
838
839 GNUNET_assert (NULL != dir_name);
841 if (NULL == dname)
842 return GNUNET_SYSERR;
843 while ((strlen (dname) > 0) && (dname[strlen (dname) - 1] == DIR_SEPARATOR))
844 dname[strlen (dname) - 1] = '\0';
845 dinfo = opendir (dname);
846 if (NULL == dinfo)
847 {
849 GNUNET_free (dname);
850 return GNUNET_SYSERR;
851 }
852 name_len = 256;
853 n_size = strlen (dname) + name_len + strlen (DIR_SEPARATOR_STR) + 1;
854 name = GNUNET_malloc (n_size);
855 while (NULL != (finfo = readdir (dinfo)))
856 {
857 if ((0 == strcmp (finfo->d_name, ".")) ||
858 (0 == strcmp (finfo->d_name, "..")))
859 continue;
860 if (NULL != callback)
861 {
862 if (name_len < strlen (finfo->d_name))
863 {
865 name_len = strlen (finfo->d_name);
866 n_size = strlen (dname) + name_len + strlen (DIR_SEPARATOR_STR) + 1;
867 name = GNUNET_malloc (n_size);
868 }
869 /* dname can end in "/" only if dname == "/";
870 * if dname does not end in "/", we need to add
871 * a "/" (otherwise, we must not!) */
873 n_size,
874 "%s%s%s",
875 dname,
876 (0 == strcmp (dname, DIR_SEPARATOR_STR))
877 ? ""
879 finfo->d_name);
880 ret = callback (callback_cls, name);
881 if (GNUNET_OK != ret)
882 {
883 closedir (dinfo);
885 GNUNET_free (dname);
886 if (GNUNET_NO == ret)
887 return count;
888 return GNUNET_SYSERR;
889 }
890 }
891 count++;
892 }
893 closedir (dinfo);
895 GNUNET_free (dname);
896 return count;
897}
898
899
909static bool
910glob_match (const char *pattern, const char *str)
911{
912 /* Position in the input string */
913 const char *str_pos = str;
914 /* Position in the pattern */
915 const char *pat_pos = pattern;
916 /* Backtrack position in string */
917 const char *str_bt = NULL;
918 /* Backtrack position in pattern */
919 const char *pat_bt = NULL;
920
921 for (;;)
922 {
923 if (*pat_pos == '*')
924 {
925 str_bt = str_pos;
926 pat_bt = pat_pos++;
927 }
928 else if (*pat_pos == *str_pos)
929 {
930 if ('\0' == *pat_pos)
931 return true;
932 str_pos++;
933 pat_pos++;
934 }
935 else
936 {
937 if (NULL == str_bt)
938 return false;
939 /* Backtrack to match one more
940 character as part of the asterisk. */
941 str_pos = str_bt + 1;
942 if ('\0' == *str_pos)
943 return false;
944 pat_pos = pat_bt;
945 }
946 }
947}
948
949
951{
952 const char *glob;
954 void *cls;
955
959 int nres;
960};
961
972glob_cb (void *cls,
973 const char *filename)
974{
975 struct GlobClosure *gc = cls;
976 const char *fn;
977
978 fn = strrchr (filename, DIR_SEPARATOR);
979 fn = (NULL == fn) ? filename : (fn + 1);
980
982 "checking glob '%s' against '%s'\n",
983 gc->glob,
984 fn);
985
986 if (glob_match (gc->glob, fn))
987 {
988 enum GNUNET_GenericReturnValue cbret;
989
991 "found glob match '%s'\n",
992 filename);
993 gc->nres++;
994 cbret = gc->cb (gc->cls, filename);
995 if (GNUNET_OK != cbret)
996 return cbret;
997 }
998 return GNUNET_OK;
999}
1000
1001
1002int
1003GNUNET_DISK_glob (const char *glob_pattern,
1004 GNUNET_FileNameCallback callback,
1005 void *callback_cls)
1006{
1007 char *mypat = GNUNET_strdup (glob_pattern);
1008 char *sep;
1009 int ret;
1010
1011 if ( (NULL != strrchr (glob_pattern, '+')) ||
1012 (NULL != strrchr (glob_pattern, '[')) ||
1013 (NULL != strrchr (glob_pattern, '~')) )
1014 {
1016 "unsupported glob pattern: '%s'\n",
1017 glob_pattern);
1018 GNUNET_free (mypat);
1019 return -1;
1020 }
1021
1022 sep = strrchr (mypat, DIR_SEPARATOR);
1023 if (NULL == sep)
1024 {
1025 GNUNET_free (mypat);
1026 return -1;
1027 }
1028
1029 *sep = '\0';
1030
1031 if (NULL != strchr (mypat, '*'))
1032 {
1033 GNUNET_free (mypat);
1034 GNUNET_break (0);
1036 "glob pattern may only contain '*' in the final path component\n");
1037 return -1;
1038 }
1039
1040 {
1041 struct GlobClosure gc = {
1042 .glob = sep + 1,
1043 .cb = callback,
1044 .cls = callback_cls,
1045 .nres = 0,
1046 };
1048 "scanning directory '%s' for glob matches on '%s'\n",
1049 mypat,
1050 gc.glob);
1052 glob_cb,
1053 &gc
1054 );
1055 GNUNET_free (mypat);
1056 return (ret < 0) ? ret : gc.nres;
1057 }
1058}
1059
1060
1069static enum GNUNET_GenericReturnValue
1070remove_helper (void *unused,
1071 const char *fn)
1072{
1073 (void) unused;
1074 (void) GNUNET_DISK_directory_remove (fn);
1075 return GNUNET_OK;
1076}
1077
1078
1081{
1082 struct stat istat;
1083
1084 if (NULL == filename)
1085 {
1086 GNUNET_break (0);
1087 return GNUNET_SYSERR;
1088 }
1089 if (0 != lstat (filename, &istat))
1090 return GNUNET_NO; /* file may not exist... */
1091 (void) chmod (filename,
1092 S_IWUSR | S_IRUSR | S_IXUSR);
1093 if (0 == unlink (filename))
1094 return GNUNET_OK;
1095 if ( (errno != EISDIR) &&
1096 /* EISDIR is not sufficient in all cases, e.g.
1097 * sticky /tmp directory may result in EPERM on BSD.
1098 * So we also explicitly check "isDirectory" */
1099 (GNUNET_YES !=
1101 GNUNET_YES)) )
1102 {
1104 return GNUNET_SYSERR;
1105 }
1106 if (GNUNET_SYSERR ==
1108 return GNUNET_SYSERR;
1109 if (0 != rmdir (filename))
1110 {
1112 return GNUNET_SYSERR;
1113 }
1114 return GNUNET_OK;
1115}
1116
1117
1119GNUNET_DISK_file_copy (const char *src,
1120 const char *dst)
1121{
1122 char *buf;
1123 uint64_t pos;
1124 uint64_t size;
1125 size_t len;
1126 ssize_t sret;
1127 struct GNUNET_DISK_FileHandle *in;
1128 struct GNUNET_DISK_FileHandle *out;
1129
1131 {
1133 return GNUNET_SYSERR;
1134 }
1135 pos = 0;
1136 in =
1138 if (! in)
1139 {
1141 return GNUNET_SYSERR;
1142 }
1143 out =
1151 if (! out)
1152 {
1155 return GNUNET_SYSERR;
1156 }
1158 while (pos < size)
1159 {
1160 len = COPY_BLK_SIZE;
1161 if (len > size - pos)
1162 len = size - pos;
1163 sret = GNUNET_DISK_file_read (in, buf, len);
1164 if ((sret < 0) || (len != (size_t) sret))
1165 goto FAIL;
1166 sret = GNUNET_DISK_file_write (out, buf, len);
1167 if ((sret < 0) || (len != (size_t) sret))
1168 goto FAIL;
1169 pos += len;
1170 }
1171 GNUNET_free (buf);
1176 return GNUNET_OK;
1177FAIL:
1178 GNUNET_free (buf);
1183 return GNUNET_SYSERR;
1184}
1185
1186
1187void
1189{
1190 char *idx;
1191 char c;
1192
1193 for (idx = fn; *idx; idx++)
1194 {
1195 c = *idx;
1196
1197 if ((c == '/') || (c == '\\') || (c == ':') || (c == '*') || (c == '?') ||
1198 (c ==
1199 '"')
1200 ||
1201 (c == '<') || (c == '>') || (c == '|') )
1202 {
1203 *idx = '_';
1204 }
1205 }
1206}
1207
1208
1211 const char *user)
1212{
1213 struct passwd *pws;
1214
1215 pws = getpwnam (user);
1216 if (NULL == pws)
1217 {
1219 _ ("Cannot obtain information about user `%s': %s\n"),
1220 user,
1221 strerror (errno));
1222 return GNUNET_SYSERR;
1223 }
1224 if (0 != chown (filename, pws->pw_uid, pws->pw_gid))
1225 {
1227 return GNUNET_SYSERR;
1228 }
1229 return GNUNET_OK;
1230}
1231
1232
1235 enum GNUNET_DISK_OpenFlags flags,
1237{
1238 char *expfn;
1240
1241 int oflags;
1242 int mode;
1243 int fd;
1244
1245 expfn = GNUNET_STRINGS_filename_expand (fn);
1246 if (NULL == expfn)
1247 return NULL;
1248
1249 mode = 0;
1251 oflags = O_RDWR; /* note: O_RDWR is NOT always O_RDONLY | O_WRONLY */
1252 else if (flags & GNUNET_DISK_OPEN_READ)
1253 oflags = O_RDONLY;
1254 else if (flags & GNUNET_DISK_OPEN_WRITE)
1255 oflags = O_WRONLY;
1256 else
1257 {
1258 GNUNET_break (0);
1259 GNUNET_free (expfn);
1260 return NULL;
1261 }
1263 oflags |= (O_CREAT | O_EXCL);
1264 if (flags & GNUNET_DISK_OPEN_TRUNCATE)
1265 oflags |= O_TRUNC;
1266 if (flags & GNUNET_DISK_OPEN_APPEND)
1267 oflags |= O_APPEND;
1268 if (GNUNET_NO == GNUNET_DISK_file_test (fn))
1269 {
1270 if (flags & GNUNET_DISK_OPEN_CREATE)
1271 {
1273 oflags |= O_CREAT;
1274 mode = translate_unix_perms (perm);
1275 }
1276 }
1277
1278 // Setting O_CLOEXEC after pipe() may introduce
1279 // race conditions: https://bugs.gnunet.org/view.php?id=9311
1280 // This is no problem if the platform supports pipe2
1281 fd = open (expfn,
1282 oflags
1283#if O_CLOEXEC
1284 | O_CLOEXEC
1285#endif
1286 | O_LARGEFILE,
1287 mode);
1288 if (fd == -1)
1289 {
1290 if (0 == (flags & GNUNET_DISK_OPEN_FAILIFEXISTS))
1292 else
1294 GNUNET_free (expfn);
1295 return NULL;
1296 }
1297
1299
1300 ret->fd = fd;
1301
1302 GNUNET_free (expfn);
1303 return ret;
1304}
1305
1306
1309{
1311
1312 if (NULL == h)
1313 {
1314 errno = EINVAL;
1315 return GNUNET_SYSERR;
1316 }
1317
1318 ret = GNUNET_OK;
1319 if (0 != close (h->fd))
1320 {
1323 }
1324 GNUNET_free (h);
1325 return ret;
1326}
1327
1328
1331{
1332 struct GNUNET_DISK_FileHandle *fh;
1333
1334 if ((((off_t) -1) == lseek (fno, 0, SEEK_CUR)) && (EBADF == errno))
1335 return NULL; /* invalid FD */
1336
1337 fh = GNUNET_new (struct GNUNET_DISK_FileHandle);
1338
1339 fh->fd = fno;
1340
1341 return fh;
1342}
1343
1344
1347{
1348 int fno;
1349
1350 fno = fileno (fd);
1351 if (-1 == fno)
1352 return NULL;
1354}
1355
1356
1361{
1365 void *addr;
1366
1370 size_t len;
1371};
1372
1373
1374#ifndef MAP_FAILED
1375#define MAP_FAILED ((void *) -1)
1376#endif
1377
1378
1379void *
1381 struct GNUNET_DISK_MapHandle **m,
1382 enum GNUNET_DISK_MapType access,
1383 size_t len)
1384{
1385 int prot;
1386
1387 if (NULL == h)
1388 {
1389 errno = EINVAL;
1390 return NULL;
1391 }
1392 prot = 0;
1393 if (access & GNUNET_DISK_MAP_TYPE_READ)
1394 prot = PROT_READ;
1395 if (access & GNUNET_DISK_MAP_TYPE_WRITE)
1396 prot |= PROT_WRITE;
1398 (*m)->addr = mmap (NULL, len, prot, MAP_SHARED, h->fd, 0);
1399 GNUNET_assert (NULL != (*m)->addr);
1400 if (MAP_FAILED == (*m)->addr)
1401 {
1402 GNUNET_free (*m);
1403 return NULL;
1404 }
1405 (*m)->len = len;
1406 return (*m)->addr;
1407}
1408
1409
1412{
1414
1415 if (NULL == h)
1416 {
1417 errno = EINVAL;
1418 return GNUNET_SYSERR;
1419 }
1420 ret = munmap (h->addr, h->len) != -1 ? GNUNET_OK : GNUNET_SYSERR;
1421 GNUNET_free (h);
1422 return ret;
1423}
1424
1425
1428{
1429 if (h == NULL)
1430 {
1431 errno = EINVAL;
1432 return GNUNET_SYSERR;
1433 }
1434
1435#if ! defined(__linux__) || ! defined(GNU)
1436 return fsync (h->fd) == -1 ? GNUNET_SYSERR : GNUNET_OK;
1437#else
1438 return fdatasync (h->fd) == -1 ? GNUNET_SYSERR : GNUNET_OK;
1439#endif
1440}
1441
1442
1445{
1446 int fd[2];
1447
1448#if HAVE_PIPE2 && O_CLOEXEC
1449 if (-1 == pipe2 (fd, O_CLOEXEC))
1450#else
1451 if (-1 == pipe (fd))
1452#endif
1453 {
1454 int eno = errno;
1455
1457 errno = eno;
1458 return NULL;
1459 }
1460 return GNUNET_DISK_pipe_from_fd (pf, fd);
1461}
1462
1463
1466 int fd[2])
1467{
1468 struct GNUNET_DISK_PipeHandle *p;
1469 int ret = 0;
1470 int flags;
1471 int eno = 0; /* make gcc happy */
1472
1474 if (fd[0] >= 0)
1475 {
1476 p->fd[0] = GNUNET_new (struct GNUNET_DISK_FileHandle);
1477 p->fd[0]->fd = fd[0];
1478 if (0 == (GNUNET_DISK_PF_BLOCKING_READ & pf))
1479 {
1480 flags = fcntl (fd[0], F_GETFL);
1481 flags |= O_NONBLOCK;
1482 if (0 > fcntl (fd[0], F_SETFL, flags))
1483 {
1484 ret = -1;
1485 eno = errno;
1486 }
1487 }
1488 flags = fcntl (fd[0], F_GETFD);
1489 flags |= FD_CLOEXEC;
1490 if (0 > fcntl (fd[0], F_SETFD, flags))
1491 {
1492 ret = -1;
1493 eno = errno;
1494 }
1495 }
1496
1497 if (fd[1] >= 0)
1498 {
1499 p->fd[1] = GNUNET_new (struct GNUNET_DISK_FileHandle);
1500 p->fd[1]->fd = fd[1];
1501 if (0 == (GNUNET_DISK_PF_BLOCKING_WRITE & pf))
1502 {
1503 flags = fcntl (fd[1], F_GETFL);
1504 flags |= O_NONBLOCK;
1505 if (0 > fcntl (fd[1], F_SETFL, flags))
1506 {
1507 ret = -1;
1508 eno = errno;
1509 }
1510 }
1511 flags = fcntl (fd[1], F_GETFD);
1512 flags |= FD_CLOEXEC;
1513 if (0 > fcntl (fd[1], F_SETFD, flags))
1514 {
1515 ret = -1;
1516 eno = errno;
1517 }
1518 }
1519 if (ret == -1)
1520 {
1521 errno = eno;
1523 if (p->fd[0]->fd >= 0)
1524 GNUNET_break (0 == close (p->fd[0]->fd));
1525 if (p->fd[1]->fd >= 0)
1526 GNUNET_break (0 == close (p->fd[1]->fd));
1527 GNUNET_free (p->fd[0]);
1528 GNUNET_free (p->fd[1]);
1529 GNUNET_free (p);
1530 errno = eno;
1531 return NULL;
1532 }
1533 return p;
1534}
1535
1536
1540{
1542
1544 {
1545 if (p->fd[0])
1546 {
1547 ret = GNUNET_DISK_file_close (p->fd[0]);
1548 p->fd[0] = NULL;
1549 }
1550 }
1551 else if (end == GNUNET_DISK_PIPE_END_WRITE)
1552 {
1553 if (p->fd[1])
1554 {
1555 ret = GNUNET_DISK_file_close (p->fd[1]);
1556 p->fd[1] = NULL;
1557 }
1558 }
1559 return ret;
1560}
1561
1562
1566{
1567 struct GNUNET_DISK_FileHandle *ret = NULL;
1568
1570 {
1571 if (p->fd[0])
1572 {
1573 ret = p->fd[0];
1574 p->fd[0] = NULL;
1575 }
1576 }
1577 else if (end == GNUNET_DISK_PIPE_END_WRITE)
1578 {
1579 if (p->fd[1])
1580 {
1581 ret = p->fd[1];
1582 p->fd[1] = NULL;
1583 }
1584 }
1585
1586 return ret;
1587}
1588
1589
1592{
1594 enum GNUNET_GenericReturnValue read_end_close;
1595 enum GNUNET_GenericReturnValue write_end_close;
1596 int read_end_close_errno;
1597 int write_end_close_errno;
1598
1600 read_end_close_errno = errno;
1602 write_end_close_errno = errno;
1603 GNUNET_free (p);
1604
1605 if (GNUNET_OK != read_end_close)
1606 {
1607 errno = read_end_close_errno;
1608 ret = read_end_close;
1609 }
1610 else if (GNUNET_OK != write_end_close)
1611 {
1612 errno = write_end_close_errno;
1613 ret = write_end_close;
1614 }
1615
1616 return ret;
1617}
1618
1619
1620const struct GNUNET_DISK_FileHandle *
1622 enum GNUNET_DISK_PipeEnd n)
1623{
1624 switch (n)
1625 {
1628 return p->fd[n];
1629
1630 default:
1631 GNUNET_break (0);
1632 return NULL;
1633 }
1634}
1635
1636
1639 int *dst)
1640{
1641 if (NULL == fh)
1642 return GNUNET_SYSERR;
1643 *dst = fh->fd;
1644 return GNUNET_OK;
1645}
1646
1647
1655static enum GNUNET_GenericReturnValue
1656purge_cfg_dir (void *cls,
1657 const struct GNUNET_CONFIGURATION_Handle *cfg)
1658{
1659 const char *option = cls;
1660 char *tmpname;
1661
1662 if (GNUNET_OK !=
1664 "PATHS",
1665 option,
1666 &tmpname))
1667 {
1669 "PATHS",
1670 option);
1671 return GNUNET_NO;
1672 }
1673 if (GNUNET_SYSERR ==
1675 {
1677 "remove",
1678 tmpname);
1679 GNUNET_free (tmpname);
1680 return GNUNET_OK;
1681 }
1682 GNUNET_free (tmpname);
1683 return GNUNET_OK;
1684}
1685
1686
1687void
1689 const char *cfg_filename,
1690 const char *option)
1691{
1696 (void *) option));
1697}
1698
1699
1700/* end of disk.c */
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
#define COPY_BLK_SIZE
Block size for IO for copying files.
Definition: disk.c:42
static enum GNUNET_GenericReturnValue glob_cb(void *cls, const char *filename)
Function called with a filename.
Definition: disk.c:972
#define LOG_STRERROR_FILE(kind, syscall, filename)
Definition: disk.c:36
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
static enum GNUNET_GenericReturnValue file_test_internal(const char *fil, int amode)
Check if fil can be accessed using amode.
Definition: disk.c:481
#define S_ISLNK(m)
Definition: disk.c:61
#define MAP_FAILED
Definition: disk.c:1375
static bool glob_match(const char *pattern, const char *str)
Check for a simple wildcard match.
Definition: disk.c:910
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:1656
#define LOG(kind,...)
Definition: disk.c:31
static char * mktemp_name(const char *t)
Create the name for a temporary file or directory from a template.
Definition: disk.c:293
#define LOG_STRERROR(kind, syscall)
Definition: disk.c:33
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:1070
enum GNUNET_GenericReturnValue GNUNET_DISK_internal_file_handle_(const struct GNUNET_DISK_FileHandle *fh, int *dst)
Retrieve OS file handle.
Definition: disk.c:1638
Internal DISK related helper functions.
char * getenv()
static struct GNUNET_ARM_MonitorHandle * m
Monitor connection with ARM.
Definition: gnunet-arm.c:103
static struct GNUNET_ARM_Handle * h
Connection with ARM.
Definition: gnunet-arm.c:98
static int ret
Final status code.
Definition: gnunet-arm.c:93
static struct GNUNET_CONFIGURATION_Handle * cfg
Our configuration.
Definition: gnunet-arm.c:108
static char * dir
Set to the directory where runtime files are stored.
Definition: gnunet-arm.c:88
static int end
Set if we are to shutdown all services (including ARM).
Definition: gnunet-arm.c:33
static const char * dir_name
Top-level directory we monitor to auto-publish.
static char * cfg_filename
Name of the configuration file.
static char * filename
static char * name
Name (label) of the records to list.
static char * res
Currently read line or NULL on EOF.
static int result
Global testing status.
static struct GNUNET_OS_Process * p
Helper process we started.
Definition: gnunet-uri.c:38
static struct GNUNET_SCHEDULER_Task * t
Main task.
static enum @44 mode
Should we do a PUT (mode = 0) or GET (mode = 1);.
@ FAIL
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.
enum GNUNET_GenericReturnValue GNUNET_CONFIGURATION_parse_and_run(const struct GNUNET_OS_ProjectData *pd, 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.
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:1621
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:1234
void GNUNET_DISK_filename_canonicalize(char *fn)
Removes special characters as ':' from a filename.
Definition: disk.c:1188
int GNUNET_DISK_glob(const char *glob_pattern, GNUNET_FileNameCallback callback, void *callback_cls)
Find all files matching a glob pattern.
Definition: disk.c:1003
enum GNUNET_GenericReturnValue GNUNET_DISK_file_change_owner(const char *filename, const char *user)
Change owner of a file.
Definition: disk.c:1210
char * GNUNET_DISK_mktemp(const char *t)
Create an (empty) temporary file on disk.
Definition: disk.c:418
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:520
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
char * 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
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
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:1564
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:1465
GNUNET_DISK_OpenFlags
Specifies how a file should be opened.
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:697
GNUNET_DISK_PipeFlags
Flags for GNUNET_DISK_pipe().
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
struct GNUNET_DISK_PipeHandle * GNUNET_DISK_pipe(enum GNUNET_DISK_PipeFlags pf)
Creates an interprocess channel.
Definition: disk.c:1444
enum GNUNET_GenericReturnValue GNUNET_DISK_file_test_read(const char *fil)
Check that fil corresponds to a filename and the file has read permissions.
Definition: disk.c:527
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
GNUNET_DISK_AccessPermissions
File access permissions, UNIX-style.
enum GNUNET_GenericReturnValue GNUNET_DISK_pipe_close(struct GNUNET_DISK_PipeHandle *p)
Closes an interprocess channel.
Definition: disk.c:1591
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:737
char * GNUNET_DISK_mkdtemp(const char *t)
Create an (empty) temporary directory on disk.
Definition: disk.c:340
enum GNUNET_GenericReturnValue GNUNET_DISK_file_copy(const char *src, const char *dst)
Copy a file.
Definition: disk.c:1119
enum GNUNET_GenericReturnValue GNUNET_DISK_directory_remove(const char *filename)
Remove all files in a directory (rm -rf).
Definition: disk.c:1080
enum GNUNET_GenericReturnValue GNUNET_DISK_file_sync(const struct GNUNET_DISK_FileHandle *h)
Write file changes to disk.
Definition: disk.c:1427
GNUNET_DISK_Seek
Constants for specifying how to seek.
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_directory_test(const char *fil, int is_readable)
Test if fil is a directory and listable.
Definition: disk.c:441
enum GNUNET_GenericReturnValue GNUNET_DISK_file_close(struct GNUNET_DISK_FileHandle *h)
Close an open file.
Definition: disk.c:1308
void GNUNET_DISK_purge_cfg_dir(const struct GNUNET_OS_ProjectData *pd, const char *cfg_filename, const char *option)
Remove the directory given under option in section [PATHS] in configuration under cfg_filename.
Definition: disk.c:1688
struct GNUNET_DISK_FileHandle * GNUNET_DISK_get_handle_from_native(FILE *fd)
Get a handle from a native FD.
Definition: disk.c:1346
enum GNUNET_GenericReturnValue GNUNET_DISK_directory_create_for_file(const char *filename)
Create the directory structure for storing a file.
Definition: disk.c:620
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:1380
struct GNUNET_DISK_FileHandle * GNUNET_DISK_get_handle_from_int_fd(int fno)
Get a handle from a native integer FD.
Definition: disk.c:1330
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:660
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
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:1538
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:713
enum GNUNET_GenericReturnValue GNUNET_DISK_file_unmap(struct GNUNET_DISK_MapHandle *h)
Unmap a file.
Definition: disk.c:1411
enum GNUNET_GenericReturnValue GNUNET_DISK_directory_create(const char *dir)
Implementation of "mkdir -p".
Definition: disk.c:534
GNUNET_DISK_PipeEnd
Enumeration identifying the two ends of a pipe.
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:674
GNUNET_DISK_MapType
Specifies what type of memory map is desired.
int GNUNET_DISK_directory_scan(const char *dir_name, GNUNET_FileNameCallback callback, void *callback_cls)
Scan a directory for files.
Definition: disk.c:826
@ GNUNET_DISK_OPEN_READ
Open the file for reading.
@ GNUNET_DISK_OPEN_FAILIFEXISTS
Fail if file already exists.
@ GNUNET_DISK_OPEN_WRITE
Open the file for writing.
@ GNUNET_DISK_OPEN_TRUNCATE
Truncate file if it exists.
@ GNUNET_DISK_OPEN_CREATE
Create file if it doesn't exist.
@ GNUNET_DISK_OPEN_APPEND
Append to the file.
@ GNUNET_DISK_OPEN_READWRITE
Open the file for both reading and writing.
@ GNUNET_DISK_PF_BLOCKING_WRITE
Configure write end to block when writing if set.
@ GNUNET_DISK_PF_BLOCKING_READ
Configure read end to block when reading if set.
@ GNUNET_DISK_PERM_OTHER_EXEC
Everybody can execute.
@ GNUNET_DISK_PERM_USER_EXEC
Owner can execute.
@ GNUNET_DISK_PERM_USER_READ
Owner can read.
@ GNUNET_DISK_PERM_NONE
Nobody is allowed to do anything to the file.
@ GNUNET_DISK_PERM_GROUP_READ
Group can read.
@ GNUNET_DISK_PERM_GROUP_EXEC
Group can execute.
@ GNUNET_DISK_PERM_GROUP_WRITE
Group can write.
@ GNUNET_DISK_PERM_USER_WRITE
Owner can write.
@ GNUNET_DISK_PERM_OTHER_READ
Everybody can read.
@ GNUNET_DISK_PERM_OTHER_WRITE
Everybody can write.
@ GNUNET_DISK_PIPE_END_WRITE
The writing-end of a pipe.
@ GNUNET_DISK_PIPE_END_READ
The reading-end of a pipe.
@ GNUNET_DISK_MAP_TYPE_WRITE
Write-able memory map.
@ GNUNET_DISK_MAP_TYPE_READ
Read-only memory map.
enum GNUNET_GenericReturnValue(* GNUNET_FileNameCallback)(void *cls, const char *filename)
Function called with a filename.
#define GNUNET_log(kind,...)
GNUNET_GenericReturnValue
Named constants for return values.
@ GNUNET_OK
@ GNUNET_YES
@ GNUNET_NO
@ GNUNET_SYSERR
#define GNUNET_assert(cond)
Use this for fatal errors that cannot be handled.
#define GNUNET_break(cond)
Use this for internal assertion violations that are not fatal (can be handled) but should not occur.
void GNUNET_log_config_missing(enum GNUNET_ErrorType kind, const char *section, const char *option)
Log error message about missing configuration option.
#define GNUNET_log_strerror_file(level, cmd, filename)
Log an error message at log-level 'level' that indicates a failure of the command 'cmd' with the mess...
@ GNUNET_ERROR_TYPE_WARNING
@ GNUNET_ERROR_TYPE_ERROR
@ GNUNET_ERROR_TYPE_DEBUG
@ GNUNET_ERROR_TYPE_INFO
int int GNUNET_asprintf(char **buf, const char *format,...) __attribute__((format(printf
Like asprintf, just portable.
#define GNUNET_strdup(a)
Wrapper around GNUNET_xstrdup_.
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.
#define GNUNET_new(type)
Allocate a struct or union of the given type.
#define GNUNET_malloc(size)
Wrapper around malloc.
#define GNUNET_free(ptr)
Wrapper around free.
char * GNUNET_STRINGS_filename_expand(const char *fil)
Complete filename (a la shell) from abbrevition.
Definition: strings.c:504
static unsigned int size
Size of the "table".
Definition: peer.c:68
#define DIR_SEPARATOR
Definition: platform.h:166
#define O_LARGEFILE
Definition: platform.h:213
#define DIR_SEPARATOR_STR
Definition: platform.h:167
#define _(String)
GNU gettext support macro.
Definition: platform.h:179
Handle used to access files (and pipes).
int fd
File handle on Unix-like systems.
Handle for a memory-mapping operation.
Definition: disk.c:1361
void * addr
Address where the map is in memory.
Definition: disk.c:1365
size_t len
Number of bytes mapped.
Definition: disk.c:1370
Handle used to manage a pipe.
Definition: disk.c:69
struct GNUNET_DISK_FileHandle * fd[2]
File descriptors for the pipe.
Definition: disk.c:74
Project-specific data used to help the OS subsystem find installation paths.
Closure for the recursion to determine the file size of a directory.
Definition: disk.c:83
uint64_t total
Set to the total file size.
Definition: disk.c:87
int include_sym_links
GNUNET_YES if symbolic links should be included.
Definition: disk.c:92
int single_file_mode
GNUNET_YES if mode is file-only (return total == -1 for directories).
Definition: disk.c:97
GNUNET_FileNameCallback cb
Definition: disk.c:953
void * cls
Definition: disk.c:954
int nres
Number of files that actually matched the glob pattern.
Definition: disk.c:959
const char * glob
Definition: disk.c:952