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 do
374 {
375 GNUNET_snprintf (target, slen, "%s.%u~", fil, num++);
376 fd = open (target, O_CREAT | O_EXCL,
378 } while (-1 == fd);
379 if (0 != renameat2 (AT_FDCWD, fil, AT_FDCWD, target, RENAME_EXCHANGE))
380 {
382 close (fd);
383 return NULL;
384 }
385 close (fd);
386 }
387#else
388 do
389 {
390 GNUNET_snprintf (target, slen, "%s.%u~", fil, num++);
391 }
392 while (0 == access (target, F_OK));
393 if (0 != rename (fil, target))
394 {
396 return NULL;
397 }
398#endif
399 return target;
400}
401
402
403char *
405{
406 int fd;
407 char *fn;
408 mode_t omask;
409
410 omask = umask (S_IWGRP | S_IWOTH | S_IRGRP | S_IROTH);
411 fn = mktemp_name (t);
412 if (-1 == (fd = mkstemp (fn)))
413 {
415 GNUNET_free (fn);
416 umask (omask);
417 return NULL;
418 }
419 umask (omask);
420 if (0 != close (fd))
422 return fn;
423}
424
425
427GNUNET_DISK_directory_test (const char *fil, int is_readable)
428{
429 struct stat filestat;
430 int ret;
431
432 ret = stat (fil, &filestat);
433 if (ret != 0)
434 {
435 if (errno != ENOENT)
437 return GNUNET_SYSERR;
438 }
439 if (! S_ISDIR (filestat.st_mode))
440 {
442 "A file already exits with the same name %s\n",
443 fil);
444 return GNUNET_NO;
445 }
446 if (GNUNET_YES == is_readable)
447 ret = access (fil, R_OK | X_OK);
448 else
449 ret = access (fil, X_OK);
450 if (ret < 0)
451 {
453 return GNUNET_NO;
454 }
455 return GNUNET_YES;
456}
457
458
467file_test_internal (const char *fil, int amode)
468{
469 struct stat filestat;
470 int ret;
471 char *rdir;
472
474 if (rdir == NULL)
475 return GNUNET_SYSERR;
476
477 ret = stat (rdir, &filestat);
478 if (0 != ret)
479 {
480 if (errno != ENOENT)
481 {
483 GNUNET_free (rdir);
484 return GNUNET_SYSERR;
485 }
486 GNUNET_free (rdir);
487 return GNUNET_NO;
488 }
489 if (! S_ISREG (filestat.st_mode))
490 {
491 GNUNET_free (rdir);
492 return GNUNET_NO;
493 }
494 if (access (rdir, amode) < 0)
495 {
497 GNUNET_free (rdir);
498 return GNUNET_SYSERR;
499 }
500 GNUNET_free (rdir);
501 return GNUNET_YES;
502}
503
504
506GNUNET_DISK_file_test (const char *fil)
507{
508 return file_test_internal (fil, F_OK);
509}
510
511
514{
515 return file_test_internal (fil, R_OK);
516}
517
518
521{
522 char *rdir;
523 unsigned int len;
524 unsigned int pos;
525 unsigned int pos2;
526 int ret = GNUNET_OK;
527
529 if (rdir == NULL)
530 {
531 GNUNET_break (0);
532 return GNUNET_SYSERR;
533 }
534
535 len = strlen (rdir);
536
537 pos = 1; /* skip heading '/' */
538
539 /* Check which low level directories already exist */
540 pos2 = len;
541 rdir[len] = DIR_SEPARATOR;
542 while (pos <= pos2)
543 {
544 if (DIR_SEPARATOR == rdir[pos2])
545 {
546 rdir[pos2] = '\0';
548 if (GNUNET_NO == ret)
549 {
551 "Creating directory `%s' failed\n",
552 rdir);
553 GNUNET_free (rdir);
554 return GNUNET_SYSERR;
555 }
556 rdir[pos2] = DIR_SEPARATOR;
557 if (GNUNET_YES == ret)
558 {
559 pos2++;
560 break;
561 }
562 }
563 pos2--;
564 }
565 rdir[len] = '\0';
566 if (pos < pos2)
567 pos = pos2;
568 /* Start creating directories */
569 while (pos <= len)
570 {
571 if ((rdir[pos] == DIR_SEPARATOR) || (pos == len))
572 {
573 rdir[pos] = '\0';
575 if (GNUNET_NO == ret)
576 {
578 "Creating directory `%s' failed\n",
579 rdir);
580 GNUNET_free (rdir);
581 return GNUNET_SYSERR;
582 }
583 if (GNUNET_SYSERR == ret)
584 {
585 ret = mkdir (rdir,
586 S_IRUSR | S_IWUSR | S_IXUSR | S_IRGRP | S_IXGRP | S_IROTH
587 | S_IXOTH); /* 755 */
588
589 if ((ret != 0) && (errno != EEXIST))
590 {
592 GNUNET_free (rdir);
593 return GNUNET_SYSERR;
594 }
595 }
596 rdir[pos] = DIR_SEPARATOR;
597 }
598 pos++;
599 }
600 GNUNET_free (rdir);
601 return GNUNET_OK;
602}
603
604
607{
608 char *rdir;
609 size_t len;
610 int eno;
612
614 if (NULL == rdir)
615 {
616 errno = EINVAL;
617 return GNUNET_SYSERR;
618 }
619 if (0 == access (rdir, W_OK))
620 {
621 GNUNET_free (rdir);
622 return GNUNET_OK;
623 }
624 len = strlen (rdir);
625 while ((len > 0) && (rdir[len] != DIR_SEPARATOR))
626 len--;
627 rdir[len] = '\0';
628 /* The empty path is invalid and in this case refers to / */
629 if (0 == len)
630 {
631 GNUNET_free (rdir);
632 rdir = GNUNET_strdup ("/");
633 }
635 if ( (GNUNET_OK == res) &&
636 (0 != access (rdir, W_OK)) )
637 res = GNUNET_NO;
638 eno = errno;
639 GNUNET_free (rdir);
640 errno = eno;
641 return res;
642}
643
644
645ssize_t
647 void *result,
648 size_t len)
649{
650 if (NULL == h)
651 {
652 errno = EINVAL;
653 return GNUNET_SYSERR;
654 }
655 return read (h->fd, result, len);
656}
657
658
659ssize_t
660GNUNET_DISK_fn_read (const char *fn,
661 void *result,
662 size_t len)
663{
664 struct GNUNET_DISK_FileHandle *fh;
665 ssize_t ret;
666 int eno;
667
668 fh = GNUNET_DISK_file_open (fn,
671 if (NULL == fh)
672 return GNUNET_SYSERR;
673 ret = GNUNET_DISK_file_read (fh, result, len);
674 eno = errno;
676 errno = eno;
677 return ret;
678}
679
680
681ssize_t
683 const void *buffer,
684 size_t n)
685{
686 if (NULL == h)
687 {
688 errno = EINVAL;
689 return GNUNET_SYSERR;
690 }
691 return write (h->fd,
692 buffer,
693 n);
694}
695
696
697ssize_t
699 const void *buffer,
700 size_t n)
701{
702 int flags;
703 ssize_t ret;
704
705 if (NULL == h)
706 {
707 errno = EINVAL;
708 return GNUNET_SYSERR;
709 }
710 /* set to blocking, write, then set back */
711 flags = fcntl (h->fd, F_GETFL);
712 if (0 != (flags & O_NONBLOCK))
713 (void) fcntl (h->fd, F_SETFL, flags - O_NONBLOCK);
714 ret = write (h->fd, buffer, n);
715 if (0 == (flags & O_NONBLOCK))
716 (void) fcntl (h->fd, F_SETFL, flags);
717 return ret;
718}
719
720
722GNUNET_DISK_fn_write (const char *fn,
723 const void *buf,
724 size_t buf_size,
726{
727 char *tmpl;
728 int fd;
729
730 if (GNUNET_OK !=
732 {
734 "mkstemp",
735 fn);
736 return GNUNET_SYSERR;
737 }
738 {
739 char *dname;
740
741 dname = GNUNET_strdup (fn);
742 GNUNET_asprintf (&tmpl,
743 "%s/XXXXXX",
744 dirname (dname));
745 GNUNET_free (dname);
746 }
747 fd = mkstemp (tmpl);
748 if (-1 == fd)
749 {
751 "mkstemp",
752 tmpl);
753 GNUNET_free (tmpl);
754 return GNUNET_SYSERR;
755 }
756
757 if (0 != fchmod (fd,
759 {
761 "chmod",
762 tmpl);
763 GNUNET_assert (0 == close (fd));
764 if (0 != unlink (tmpl))
766 "unlink",
767 tmpl);
768 GNUNET_free (tmpl);
769 return GNUNET_SYSERR;
770 }
771 if (buf_size !=
772 write (fd,
773 buf,
774 buf_size))
775 {
777 "write",
778 tmpl);
779 GNUNET_assert (0 == close (fd));
780 if (0 != unlink (tmpl))
782 "unlink",
783 tmpl);
784 GNUNET_free (tmpl);
785 return GNUNET_SYSERR;
786 }
787 GNUNET_assert (0 == close (fd));
788
789 if (0 != link (tmpl,
790 fn))
791 {
792 if (0 != unlink (tmpl))
794 "unlink",
795 tmpl);
796 GNUNET_free (tmpl);
797 return GNUNET_NO;
798 }
799 if (0 != unlink (tmpl))
801 "unlink",
802 tmpl);
803 GNUNET_free (tmpl);
804 return GNUNET_OK;
805
806
807}
808
809
810int
813 void *callback_cls)
814{
815 DIR *dinfo;
816 struct dirent *finfo;
817 int count = 0;
819 char *name;
820 char *dname;
821 unsigned int name_len;
822 unsigned int n_size;
823
824 GNUNET_assert (NULL != dir_name);
826 if (NULL == dname)
827 return GNUNET_SYSERR;
828 while ((strlen (dname) > 0) && (dname[strlen (dname) - 1] == DIR_SEPARATOR))
829 dname[strlen (dname) - 1] = '\0';
830 dinfo = opendir (dname);
831 if (NULL == dinfo)
832 {
834 GNUNET_free (dname);
835 return GNUNET_SYSERR;
836 }
837 name_len = 256;
838 n_size = strlen (dname) + name_len + strlen (DIR_SEPARATOR_STR) + 1;
839 name = GNUNET_malloc (n_size);
840 while (NULL != (finfo = readdir (dinfo)))
841 {
842 if ((0 == strcmp (finfo->d_name, ".")) ||
843 (0 == strcmp (finfo->d_name, "..")))
844 continue;
845 if (NULL != callback)
846 {
847 if (name_len < strlen (finfo->d_name))
848 {
850 name_len = strlen (finfo->d_name);
851 n_size = strlen (dname) + name_len + strlen (DIR_SEPARATOR_STR) + 1;
852 name = GNUNET_malloc (n_size);
853 }
854 /* dname can end in "/" only if dname == "/";
855 * if dname does not end in "/", we need to add
856 * a "/" (otherwise, we must not!) */
858 n_size,
859 "%s%s%s",
860 dname,
861 (0 == strcmp (dname, DIR_SEPARATOR_STR))
862 ? ""
864 finfo->d_name);
865 ret = callback (callback_cls, name);
866 if (GNUNET_OK != ret)
867 {
868 closedir (dinfo);
870 GNUNET_free (dname);
871 if (GNUNET_NO == ret)
872 return count;
873 return GNUNET_SYSERR;
874 }
875 }
876 count++;
877 }
878 closedir (dinfo);
880 GNUNET_free (dname);
881 return count;
882}
883
884
894static bool
895glob_match (const char *pattern, const char *str)
896{
897 /* Position in the input string */
898 const char *str_pos = str;
899 /* Position in the pattern */
900 const char *pat_pos = pattern;
901 /* Backtrack position in string */
902 const char *str_bt = NULL;
903 /* Backtrack position in pattern */
904 const char *pat_bt = NULL;
905
906 for (;;)
907 {
908 if (*pat_pos == '*')
909 {
910 str_bt = str_pos;
911 pat_bt = pat_pos++;
912 }
913 else if (*pat_pos == *str_pos)
914 {
915 if ('\0' == *pat_pos)
916 return true;
917 str_pos++;
918 pat_pos++;
919 }
920 else
921 {
922 if (NULL == str_bt)
923 return false;
924 /* Backtrack to match one more
925 character as part of the asterisk. */
926 str_pos = str_bt + 1;
927 if ('\0' == *str_pos)
928 return false;
929 pat_pos = pat_bt;
930 }
931 }
932}
933
934
936{
937 const char *glob;
939 void *cls;
940
944 int nres;
945};
946
957glob_cb (void *cls,
958 const char *filename)
959{
960 struct GlobClosure *gc = cls;
961 const char *fn;
962
963 fn = strrchr (filename, DIR_SEPARATOR);
964 fn = (NULL == fn) ? filename : (fn + 1);
965
967 "checking glob '%s' against '%s'\n",
968 gc->glob,
969 fn);
970
971 if (glob_match (gc->glob, fn))
972 {
973 enum GNUNET_GenericReturnValue cbret;
974
976 "found glob match '%s'\n",
977 filename);
978 gc->nres++;
979 cbret = gc->cb (gc->cls, filename);
980 if (GNUNET_OK != cbret)
981 return cbret;
982 }
983 return GNUNET_OK;
984}
985
986
987int
988GNUNET_DISK_glob (const char *glob_pattern,
990 void *callback_cls)
991{
992 char *mypat = GNUNET_strdup (glob_pattern);
993 char *sep;
994 int ret;
995
996 if ( (NULL != strrchr (glob_pattern, '+')) ||
997 (NULL != strrchr (glob_pattern, '[')) ||
998 (NULL != strrchr (glob_pattern, '~')) )
999 {
1001 "unsupported glob pattern: '%s'\n",
1002 glob_pattern);
1003 GNUNET_free (mypat);
1004 return -1;
1005 }
1006
1007 sep = strrchr (mypat, DIR_SEPARATOR);
1008 if (NULL == sep)
1009 {
1010 GNUNET_free (mypat);
1011 return -1;
1012 }
1013
1014 *sep = '\0';
1015
1016 if (NULL != strchr (mypat, '*'))
1017 {
1018 GNUNET_free (mypat);
1019 GNUNET_break (0);
1021 "glob pattern may only contain '*' in the final path component\n");
1022 return -1;
1023 }
1024
1025 {
1026 struct GlobClosure gc = {
1027 .glob = sep + 1,
1028 .cb = callback,
1029 .cls = callback_cls,
1030 .nres = 0,
1031 };
1033 "scanning directory '%s' for glob matches on '%s'\n",
1034 mypat,
1035 gc.glob);
1037 glob_cb,
1038 &gc
1039 );
1040 GNUNET_free (mypat);
1041 return (ret < 0) ? ret : gc.nres;
1042 }
1043}
1044
1045
1054static enum GNUNET_GenericReturnValue
1055remove_helper (void *unused,
1056 const char *fn)
1057{
1058 (void) unused;
1059 (void) GNUNET_DISK_directory_remove (fn);
1060 return GNUNET_OK;
1061}
1062
1063
1066{
1067 struct stat istat;
1068
1069 if (NULL == filename)
1070 {
1071 GNUNET_break (0);
1072 return GNUNET_SYSERR;
1073 }
1074 if (0 != lstat (filename, &istat))
1075 return GNUNET_NO; /* file may not exist... */
1076 (void) chmod (filename,
1077 S_IWUSR | S_IRUSR | S_IXUSR);
1078 if (0 == unlink (filename))
1079 return GNUNET_OK;
1080 if ( (errno != EISDIR) &&
1081 /* EISDIR is not sufficient in all cases, e.g.
1082 * sticky /tmp directory may result in EPERM on BSD.
1083 * So we also explicitly check "isDirectory" */
1084 (GNUNET_YES !=
1086 GNUNET_YES)) )
1087 {
1089 return GNUNET_SYSERR;
1090 }
1091 if (GNUNET_SYSERR ==
1093 return GNUNET_SYSERR;
1094 if (0 != rmdir (filename))
1095 {
1097 return GNUNET_SYSERR;
1098 }
1099 return GNUNET_OK;
1100}
1101
1102
1104GNUNET_DISK_file_copy (const char *src,
1105 const char *dst)
1106{
1107 char *buf;
1108 uint64_t pos;
1109 uint64_t size;
1110 size_t len;
1111 ssize_t sret;
1112 struct GNUNET_DISK_FileHandle *in;
1113 struct GNUNET_DISK_FileHandle *out;
1114
1116 {
1118 return GNUNET_SYSERR;
1119 }
1120 pos = 0;
1121 in =
1123 if (! in)
1124 {
1126 return GNUNET_SYSERR;
1127 }
1128 out =
1136 if (! out)
1137 {
1140 return GNUNET_SYSERR;
1141 }
1143 while (pos < size)
1144 {
1145 len = COPY_BLK_SIZE;
1146 if (len > size - pos)
1147 len = size - pos;
1148 sret = GNUNET_DISK_file_read (in, buf, len);
1149 if ((sret < 0) || (len != (size_t) sret))
1150 goto FAIL;
1151 sret = GNUNET_DISK_file_write (out, buf, len);
1152 if ((sret < 0) || (len != (size_t) sret))
1153 goto FAIL;
1154 pos += len;
1155 }
1156 GNUNET_free (buf);
1159 return GNUNET_OK;
1160FAIL:
1161 GNUNET_free (buf);
1164 return GNUNET_SYSERR;
1165}
1166
1167
1168void
1170{
1171 char *idx;
1172 char c;
1173
1174 for (idx = fn; *idx; idx++)
1175 {
1176 c = *idx;
1177
1178 if ((c == '/') || (c == '\\') || (c == ':') || (c == '*') || (c == '?') ||
1179 (c ==
1180 '"')
1181 ||
1182 (c == '<') || (c == '>') || (c == '|') )
1183 {
1184 *idx = '_';
1185 }
1186 }
1187}
1188
1189
1192 const char *user)
1193{
1194 struct passwd *pws;
1195
1196 pws = getpwnam (user);
1197 if (NULL == pws)
1198 {
1200 _ ("Cannot obtain information about user `%s': %s\n"),
1201 user,
1202 strerror (errno));
1203 return GNUNET_SYSERR;
1204 }
1205 if (0 != chown (filename, pws->pw_uid, pws->pw_gid))
1206 {
1208 return GNUNET_SYSERR;
1209 }
1210 return GNUNET_OK;
1211}
1212
1213
1216 enum GNUNET_DISK_OpenFlags flags,
1218{
1219 char *expfn;
1221
1222 int oflags;
1223 int mode;
1224 int fd;
1225
1226 expfn = GNUNET_STRINGS_filename_expand (fn);
1227 if (NULL == expfn)
1228 return NULL;
1229
1230 mode = 0;
1232 oflags = O_RDWR; /* note: O_RDWR is NOT always O_RDONLY | O_WRONLY */
1233 else if (flags & GNUNET_DISK_OPEN_READ)
1234 oflags = O_RDONLY;
1235 else if (flags & GNUNET_DISK_OPEN_WRITE)
1236 oflags = O_WRONLY;
1237 else
1238 {
1239 GNUNET_break (0);
1240 GNUNET_free (expfn);
1241 return NULL;
1242 }
1244 oflags |= (O_CREAT | O_EXCL);
1245 if (flags & GNUNET_DISK_OPEN_TRUNCATE)
1246 oflags |= O_TRUNC;
1247 if (flags & GNUNET_DISK_OPEN_APPEND)
1248 oflags |= O_APPEND;
1249 if (GNUNET_NO == GNUNET_DISK_file_test (fn))
1250 {
1251 if (flags & GNUNET_DISK_OPEN_CREATE)
1252 {
1254 oflags |= O_CREAT;
1255 mode = translate_unix_perms (perm);
1256 }
1257 }
1258
1259 // Setting O_CLOEXEC after pipe() may introduce
1260 // race conditions: https://bugs.gnunet.org/view.php?id=9311
1261 // This is no problem if the platform supports pipe2
1262 fd = open (expfn,
1263 oflags
1264#if O_CLOEXEC
1265 | O_CLOEXEC
1266#endif
1267 | O_LARGEFILE,
1268 mode);
1269 if (fd == -1)
1270 {
1271 if (0 == (flags & GNUNET_DISK_OPEN_FAILIFEXISTS))
1273 else
1275 GNUNET_free (expfn);
1276 return NULL;
1277 }
1278
1280
1281 ret->fd = fd;
1282
1283 GNUNET_free (expfn);
1284 return ret;
1285}
1286
1287
1290{
1292
1293 if (NULL == h)
1294 {
1295 errno = EINVAL;
1296 return GNUNET_SYSERR;
1297 }
1298
1299 ret = GNUNET_OK;
1300 if (0 != close (h->fd))
1301 {
1304 }
1305 GNUNET_free (h);
1306 return ret;
1307}
1308
1309
1312{
1313 struct GNUNET_DISK_FileHandle *fh;
1314
1315 if ((((off_t) -1) == lseek (fno, 0, SEEK_CUR)) && (EBADF == errno))
1316 return NULL; /* invalid FD */
1317
1318 fh = GNUNET_new (struct GNUNET_DISK_FileHandle);
1319
1320 fh->fd = fno;
1321
1322 return fh;
1323}
1324
1325
1328{
1329 int fno;
1330
1331 fno = fileno (fd);
1332 if (-1 == fno)
1333 return NULL;
1335}
1336
1337
1342{
1346 void *addr;
1347
1351 size_t len;
1352};
1353
1354
1355#ifndef MAP_FAILED
1356#define MAP_FAILED ((void *) -1)
1357#endif
1358
1359
1360void *
1362 struct GNUNET_DISK_MapHandle **m,
1363 enum GNUNET_DISK_MapType access,
1364 size_t len)
1365{
1366 int prot;
1367
1368 if (NULL == h)
1369 {
1370 errno = EINVAL;
1371 return NULL;
1372 }
1373 prot = 0;
1374 if (access & GNUNET_DISK_MAP_TYPE_READ)
1375 prot = PROT_READ;
1376 if (access & GNUNET_DISK_MAP_TYPE_WRITE)
1377 prot |= PROT_WRITE;
1379 (*m)->addr = mmap (NULL, len, prot, MAP_SHARED, h->fd, 0);
1380 GNUNET_assert (NULL != (*m)->addr);
1381 if (MAP_FAILED == (*m)->addr)
1382 {
1383 GNUNET_free (*m);
1384 return NULL;
1385 }
1386 (*m)->len = len;
1387 return (*m)->addr;
1388}
1389
1390
1393{
1395
1396 if (NULL == h)
1397 {
1398 errno = EINVAL;
1399 return GNUNET_SYSERR;
1400 }
1401 ret = munmap (h->addr, h->len) != -1 ? GNUNET_OK : GNUNET_SYSERR;
1402 GNUNET_free (h);
1403 return ret;
1404}
1405
1406
1409{
1410 if (h == NULL)
1411 {
1412 errno = EINVAL;
1413 return GNUNET_SYSERR;
1414 }
1415
1416#if ! defined(__linux__) || ! defined(GNU)
1417 return fsync (h->fd) == -1 ? GNUNET_SYSERR : GNUNET_OK;
1418#else
1419 return fdatasync (h->fd) == -1 ? GNUNET_SYSERR : GNUNET_OK;
1420#endif
1421}
1422
1423
1426{
1427 int fd[2];
1428
1429#if HAVE_PIPE2 && O_CLOEXEC
1430 if (-1 == pipe2 (fd, O_CLOEXEC))
1431#else
1432 if (-1 == pipe (fd))
1433#endif
1434 {
1435 int eno = errno;
1436
1438 errno = eno;
1439 return NULL;
1440 }
1441 return GNUNET_DISK_pipe_from_fd (pf, fd);
1442}
1443
1444
1447 int fd[2])
1448{
1449 struct GNUNET_DISK_PipeHandle *p;
1450 int ret = 0;
1451 int flags;
1452 int eno = 0; /* make gcc happy */
1453
1455 if (fd[0] >= 0)
1456 {
1457 p->fd[0] = GNUNET_new (struct GNUNET_DISK_FileHandle);
1458 p->fd[0]->fd = fd[0];
1459 if (0 == (GNUNET_DISK_PF_BLOCKING_READ & pf))
1460 {
1461 flags = fcntl (fd[0], F_GETFL);
1462 flags |= O_NONBLOCK;
1463 if (0 > fcntl (fd[0], F_SETFL, flags))
1464 {
1465 ret = -1;
1466 eno = errno;
1467 }
1468 }
1469 flags = fcntl (fd[0], F_GETFD);
1470 flags |= FD_CLOEXEC;
1471 if (0 > fcntl (fd[0], F_SETFD, flags))
1472 {
1473 ret = -1;
1474 eno = errno;
1475 }
1476 }
1477
1478 if (fd[1] >= 0)
1479 {
1480 p->fd[1] = GNUNET_new (struct GNUNET_DISK_FileHandle);
1481 p->fd[1]->fd = fd[1];
1482 if (0 == (GNUNET_DISK_PF_BLOCKING_WRITE & pf))
1483 {
1484 flags = fcntl (fd[1], F_GETFL);
1485 flags |= O_NONBLOCK;
1486 if (0 > fcntl (fd[1], F_SETFL, flags))
1487 {
1488 ret = -1;
1489 eno = errno;
1490 }
1491 }
1492 flags = fcntl (fd[1], F_GETFD);
1493 flags |= FD_CLOEXEC;
1494 if (0 > fcntl (fd[1], F_SETFD, flags))
1495 {
1496 ret = -1;
1497 eno = errno;
1498 }
1499 }
1500 if (ret == -1)
1501 {
1502 errno = eno;
1504 if (p->fd[0]->fd >= 0)
1505 GNUNET_break (0 == close (p->fd[0]->fd));
1506 if (p->fd[1]->fd >= 0)
1507 GNUNET_break (0 == close (p->fd[1]->fd));
1508 GNUNET_free (p->fd[0]);
1509 GNUNET_free (p->fd[1]);
1510 GNUNET_free (p);
1511 errno = eno;
1512 return NULL;
1513 }
1514 return p;
1515}
1516
1517
1521{
1523
1525 {
1526 if (p->fd[0])
1527 {
1528 ret = GNUNET_DISK_file_close (p->fd[0]);
1529 p->fd[0] = NULL;
1530 }
1531 }
1532 else if (end == GNUNET_DISK_PIPE_END_WRITE)
1533 {
1534 if (p->fd[1])
1535 {
1536 ret = GNUNET_DISK_file_close (p->fd[1]);
1537 p->fd[1] = NULL;
1538 }
1539 }
1540 return ret;
1541}
1542
1543
1547{
1548 struct GNUNET_DISK_FileHandle *ret = NULL;
1549
1551 {
1552 if (p->fd[0])
1553 {
1554 ret = p->fd[0];
1555 p->fd[0] = NULL;
1556 }
1557 }
1558 else if (end == GNUNET_DISK_PIPE_END_WRITE)
1559 {
1560 if (p->fd[1])
1561 {
1562 ret = p->fd[1];
1563 p->fd[1] = NULL;
1564 }
1565 }
1566
1567 return ret;
1568}
1569
1570
1573{
1575 enum GNUNET_GenericReturnValue read_end_close;
1576 enum GNUNET_GenericReturnValue write_end_close;
1577 int read_end_close_errno;
1578 int write_end_close_errno;
1579
1581 read_end_close_errno = errno;
1583 write_end_close_errno = errno;
1584 GNUNET_free (p);
1585
1586 if (GNUNET_OK != read_end_close)
1587 {
1588 errno = read_end_close_errno;
1589 ret = read_end_close;
1590 }
1591 else if (GNUNET_OK != write_end_close)
1592 {
1593 errno = write_end_close_errno;
1594 ret = write_end_close;
1595 }
1596
1597 return ret;
1598}
1599
1600
1601const struct GNUNET_DISK_FileHandle *
1603 enum GNUNET_DISK_PipeEnd n)
1604{
1605 switch (n)
1606 {
1609 return p->fd[n];
1610
1611 default:
1612 GNUNET_break (0);
1613 return NULL;
1614 }
1615}
1616
1617
1620 int *dst)
1621{
1622 if (NULL == fh)
1623 return GNUNET_SYSERR;
1624 *dst = fh->fd;
1625 return GNUNET_OK;
1626}
1627
1628
1636static enum GNUNET_GenericReturnValue
1637purge_cfg_dir (void *cls,
1638 const struct GNUNET_CONFIGURATION_Handle *cfg)
1639{
1640 const char *option = cls;
1641 char *tmpname;
1642
1643 if (GNUNET_OK !=
1645 "PATHS",
1646 option,
1647 &tmpname))
1648 {
1650 "PATHS",
1651 option);
1652 return GNUNET_NO;
1653 }
1654 if (GNUNET_SYSERR ==
1656 {
1658 "remove",
1659 tmpname);
1660 GNUNET_free (tmpname);
1661 return GNUNET_OK;
1662 }
1663 GNUNET_free (tmpname);
1664 return GNUNET_OK;
1665}
1666
1667
1668void
1670 const char *cfg_filename,
1671 const char *option)
1672{
1677 (void *) option));
1678}
1679
1680
1681/* 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:957
#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:467
#define S_ISLNK(m)
Definition: disk.c:61
#define MAP_FAILED
Definition: disk.c:1356
static bool glob_match(const char *pattern, const char *str)
Check for a simple wildcard match.
Definition: disk.c:895
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:1637
#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:1055
enum GNUNET_GenericReturnValue GNUNET_DISK_internal_file_handle_(const struct GNUNET_DISK_FileHandle *fh, int *dst)
Retrieve OS file handle.
Definition: disk.c:1619
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:1602
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:1215
void GNUNET_DISK_filename_canonicalize(char *fn)
Removes special characters as ':' from a filename.
Definition: disk.c:1169
int GNUNET_DISK_glob(const char *glob_pattern, GNUNET_FileNameCallback callback, void *callback_cls)
Find all files matching a glob pattern.
Definition: disk.c:988
enum GNUNET_GenericReturnValue GNUNET_DISK_file_change_owner(const char *filename, const char *user)
Change owner of a file.
Definition: disk.c:1191
char * GNUNET_DISK_mktemp(const char *t)
Create an (empty) temporary file on disk.
Definition: disk.c:404
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:506
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:1545
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:1446
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:682
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:1425
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:513
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:1572
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:722
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:1104
enum GNUNET_GenericReturnValue GNUNET_DISK_directory_remove(const char *filename)
Remove all files in a directory (rm -rf).
Definition: disk.c:1065
enum GNUNET_GenericReturnValue GNUNET_DISK_file_sync(const struct GNUNET_DISK_FileHandle *h)
Write file changes to disk.
Definition: disk.c:1408
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:427
enum GNUNET_GenericReturnValue GNUNET_DISK_file_close(struct GNUNET_DISK_FileHandle *h)
Close an open file.
Definition: disk.c:1289
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:1669
struct GNUNET_DISK_FileHandle * GNUNET_DISK_get_handle_from_native(FILE *fd)
Get a handle from a native FD.
Definition: disk.c:1327
enum GNUNET_GenericReturnValue GNUNET_DISK_directory_create_for_file(const char *filename)
Create the directory structure for storing a file.
Definition: disk.c:606
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:1361
struct GNUNET_DISK_FileHandle * GNUNET_DISK_get_handle_from_int_fd(int fno)
Get a handle from a native integer FD.
Definition: disk.c:1311
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:646
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:1519
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:698
enum GNUNET_GenericReturnValue GNUNET_DISK_file_unmap(struct GNUNET_DISK_MapHandle *h)
Unmap a file.
Definition: disk.c:1392
enum GNUNET_GenericReturnValue GNUNET_DISK_directory_create(const char *dir)
Implementation of "mkdir -p".
Definition: disk.c:520
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:660
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:811
@ 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:165
#define O_LARGEFILE
Definition: platform.h:212
#define DIR_SEPARATOR_STR
Definition: platform.h:166
#define _(String)
GNU gettext support macro.
Definition: platform.h:178
Handle used to access files (and pipes).
int fd
File handle on Unix-like systems.
Handle for a memory-mapping operation.
Definition: disk.c:1342
void * addr
Address where the map is in memory.
Definition: disk.c:1346
size_t len
Number of bytes mapped.
Definition: disk.c:1351
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:938
void * cls
Definition: disk.c:939
int nres
Number of files that actually matched the glob pattern.
Definition: disk.c:944
const char * glob
Definition: disk.c:937