GNUnet 0.21.1
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
30#define LOG(kind, ...) GNUNET_log_from (kind, "util-disk", __VA_ARGS__)
31
32#define LOG_STRERROR(kind, syscall) \
33 GNUNET_log_from_strerror (kind, "util-disk", syscall)
34
35#define LOG_STRERROR_FILE(kind, syscall, filename) \
36 GNUNET_log_from_strerror_file (kind, "util-disk", syscall, filename)
37
41#define COPY_BLK_SIZE 65536
42
43#include <sys/types.h>
44#if HAVE_SYS_VFS_H
45#include <sys/vfs.h>
46#endif
47#if HAVE_SYS_PARAM_H
48#include <sys/param.h>
49#endif
50#if HAVE_SYS_MOUNT_H
51#include <sys/mount.h>
52#endif
53#if HAVE_SYS_STATVFS_H
54#include <sys/statvfs.h>
55#endif
56
57#ifndef S_ISLNK
58#define _IFMT 0170000 /* type of file */
59#define _IFLNK 0120000 /* symbolic link */
60#define S_ISLNK(m) (((m) & _IFMT) == _IFLNK)
61#endif
62
63
68{
74};
75
76
82{
86 uint64_t total;
87
92
97};
98
99
107static int
109{
110 int mode;
111
112 mode = 0;
114 mode |= S_IRUSR;
116 mode |= S_IWUSR;
118 mode |= S_IXUSR;
120 mode |= S_IRGRP;
122 mode |= S_IWGRP;
124 mode |= S_IXGRP;
126 mode |= S_IROTH;
128 mode |= S_IWOTH;
130 mode |= S_IXOTH;
131
132 return mode;
133}
134
135
145get_size_rec (void *cls, const char *fn)
146{
147 struct GetFileSizeData *gfsd = cls;
148
149#if defined(HAVE_STAT64) && \
150 ! (defined(_FILE_OFFSET_BITS) && _FILE_OFFSET_BITS == 64)
151 struct stat64 buf;
152
153 if (0 != stat64 (fn, &buf))
154 {
156 return GNUNET_SYSERR;
157 }
158#else
159 struct stat buf;
160
161 if (0 != stat (fn, &buf))
162 {
164 return GNUNET_SYSERR;
165 }
166#endif
167 if ((S_ISDIR (buf.st_mode)) && (gfsd->single_file_mode == GNUNET_YES))
168 {
169 errno = EISDIR;
170 return GNUNET_SYSERR;
171 }
172 if ((! S_ISLNK (buf.st_mode)) || (gfsd->include_sym_links == GNUNET_YES))
173 gfsd->total += buf.st_size;
174 if ((S_ISDIR (buf.st_mode)) && (0 == access (fn, X_OK)) &&
175 ((! S_ISLNK (buf.st_mode)) || (gfsd->include_sym_links == GNUNET_YES)))
176 {
178 return GNUNET_SYSERR;
179 }
180 return GNUNET_OK;
181}
182
183
186{
187 return ((! h) || (h->fd == -1)) ? GNUNET_YES : GNUNET_NO;
188}
189
190
193 off_t *size)
194{
195 struct stat sbuf;
196
197 if (0 != fstat (fh->fd, &sbuf))
198 return GNUNET_SYSERR;
199 *size = sbuf.st_size;
200 return GNUNET_OK;
201}
202
203
204off_t
206 off_t offset,
207 enum GNUNET_DISK_Seek whence)
208{
209 static int t[] = { SEEK_SET, SEEK_CUR, SEEK_END };
210
211 if (h == NULL)
212 {
213 errno = EINVAL;
214 return GNUNET_SYSERR;
215 }
216 return lseek (h->fd, offset, t[whence]);
217}
218
219
222 uint64_t *size,
223 int include_symbolic_links,
224 int single_file_mode)
225{
226 struct GetFileSizeData gfsd;
228
229 GNUNET_assert (size != NULL);
230 gfsd.total = 0;
231 gfsd.include_sym_links = include_symbolic_links;
233 ret = get_size_rec (&gfsd, filename);
234 *size = gfsd.total;
235 return ret;
236}
237
238
241 uint64_t *dev,
242 uint64_t *ino)
243{
244#if HAVE_STAT
245 {
246 struct stat sbuf;
247
248 if (0 != stat (filename, &sbuf))
249 {
250 return GNUNET_SYSERR;
251 }
252 *ino = (uint64_t) sbuf.st_ino;
253 }
254#else
255 *ino = 0;
256#endif
257#if HAVE_STATVFS
258 {
259 struct statvfs fbuf;
260
261 if (0 != statvfs (filename, &fbuf))
262 {
263 return GNUNET_SYSERR;
264 }
265 *dev = (uint64_t) fbuf.f_fsid;
266 }
267#elif HAVE_STATFS
268 {
269 struct statfs fbuf;
270
271 if (0 != statfs (filename, &fbuf))
272 {
273 return GNUNET_SYSERR;
274 }
275 *dev =
276 ((uint64_t) fbuf.f_fsid.val[0]) << 32 || ((uint64_t) fbuf.f_fsid.val[1]);
277 }
278#else
279 *dev = 0;
280#endif
281 return GNUNET_OK;
282}
283
284
291static char *
292mktemp_name (const char *t)
293{
294 const char *tmpdir;
295 char *tmpl;
296 char *fn;
297
298 if ((t[0] != '/') && (t[0] != '\\'))
299 {
300 /* FIXME: This uses system codepage on W32, not UTF-8 */
301 tmpdir = getenv ("TMPDIR");
302 if (NULL == tmpdir)
303 tmpdir = getenv ("TMP");
304 if (NULL == tmpdir)
305 tmpdir = getenv ("TEMP");
306 if (NULL == tmpdir)
307 tmpdir = "/tmp";
308 GNUNET_asprintf (&tmpl, "%s/%s%s", tmpdir, t, "XXXXXX");
309 }
310 else
311 {
312 GNUNET_asprintf (&tmpl, "%s%s", t, "XXXXXX");
313 }
314 fn = tmpl;
315 return fn;
316}
317
318
319void
321 int require_uid_match,
322 int require_gid_match)
323{
324 mode_t mode;
325
326 if (GNUNET_YES == require_uid_match)
327 mode = S_IRUSR | S_IWUSR | S_IXUSR;
328 else if (GNUNET_YES == require_gid_match)
329 mode = S_IRUSR | S_IWUSR | S_IXUSR | S_IRGRP | S_IWGRP | S_IXGRP;
330 else
331 mode = S_IRUSR | S_IWUSR | S_IXUSR | S_IRGRP | S_IWGRP | S_IXGRP | S_IROTH
332 | S_IWOTH | S_IXOTH;
333 if (0 != chmod (fn, mode))
335}
336
337
338char *
340{
341 char *fn;
342 mode_t omask;
343
344 omask = umask (S_IWGRP | S_IWOTH | S_IRGRP | S_IROTH);
345 fn = mktemp_name (t);
346 if (fn != mkdtemp (fn))
347 {
349 GNUNET_free (fn);
350 umask (omask);
351 return NULL;
352 }
353 umask (omask);
354 return fn;
355}
356
357
358void
359GNUNET_DISK_file_backup (const char *fil)
360{
361 size_t slen;
362 char *target;
363 unsigned int num;
364
365 slen = strlen (fil) + 20;
366 target = GNUNET_malloc (slen);
367 num = 0;
368 do
369 {
370 GNUNET_snprintf (target, slen, "%s.%u~", fil, num++);
371 }
372 while (0 == access (target, F_OK));
373 if (0 != rename (fil, target))
375 GNUNET_free (target);
376}
377
378
379char *
381{
382 int fd;
383 char *fn;
384 mode_t omask;
385
386 omask = umask (S_IWGRP | S_IWOTH | S_IRGRP | S_IROTH);
387 fn = mktemp_name (t);
388 if (-1 == (fd = mkstemp (fn)))
389 {
391 GNUNET_free (fn);
392 umask (omask);
393 return NULL;
394 }
395 umask (omask);
396 if (0 != close (fd))
398 return fn;
399}
400
401
403GNUNET_DISK_directory_test (const char *fil, int is_readable)
404{
405 struct stat filestat;
406 int ret;
407
408 ret = stat (fil, &filestat);
409 if (ret != 0)
410 {
411 if (errno != ENOENT)
413 return GNUNET_SYSERR;
414 }
415 if (! S_ISDIR (filestat.st_mode))
416 {
418 "A file already exits with the same name %s\n",
419 fil);
420 return GNUNET_NO;
421 }
422 if (GNUNET_YES == is_readable)
423 ret = access (fil, R_OK | X_OK);
424 else
425 ret = access (fil, X_OK);
426 if (ret < 0)
427 {
429 return GNUNET_NO;
430 }
431 return GNUNET_YES;
432}
433
434
443file_test_internal (const char *fil, int amode)
444{
445 struct stat filestat;
446 int ret;
447 char *rdir;
448
450 if (rdir == NULL)
451 return GNUNET_SYSERR;
452
453 ret = stat (rdir, &filestat);
454 if (0 != ret)
455 {
456 if (errno != ENOENT)
457 {
459 GNUNET_free (rdir);
460 return GNUNET_SYSERR;
461 }
462 GNUNET_free (rdir);
463 return GNUNET_NO;
464 }
465 if (! S_ISREG (filestat.st_mode))
466 {
467 GNUNET_free (rdir);
468 return GNUNET_NO;
469 }
470 if (access (rdir, amode) < 0)
471 {
473 GNUNET_free (rdir);
474 return GNUNET_SYSERR;
475 }
476 GNUNET_free (rdir);
477 return GNUNET_YES;
478}
479
480
482GNUNET_DISK_file_test (const char *fil)
483{
484 return file_test_internal (fil, F_OK);
485}
486
487
490{
491 return file_test_internal (fil, R_OK);
492}
493
494
497{
498 char *rdir;
499 unsigned int len;
500 unsigned int pos;
501 unsigned int pos2;
502 int ret = GNUNET_OK;
503
505 if (rdir == NULL)
506 {
507 GNUNET_break (0);
508 return GNUNET_SYSERR;
509 }
510
511 len = strlen (rdir);
512
513 pos = 1; /* skip heading '/' */
514
515 /* Check which low level directories already exist */
516 pos2 = len;
517 rdir[len] = DIR_SEPARATOR;
518 while (pos <= pos2)
519 {
520 if (DIR_SEPARATOR == rdir[pos2])
521 {
522 rdir[pos2] = '\0';
524 if (GNUNET_NO == ret)
525 {
527 "Creating directory `%s' failed",
528 rdir);
529 GNUNET_free (rdir);
530 return GNUNET_SYSERR;
531 }
532 rdir[pos2] = DIR_SEPARATOR;
533 if (GNUNET_YES == ret)
534 {
535 pos2++;
536 break;
537 }
538 }
539 pos2--;
540 }
541 rdir[len] = '\0';
542 if (pos < pos2)
543 pos = pos2;
544 /* Start creating directories */
545 while (pos <= len)
546 {
547 if ((rdir[pos] == DIR_SEPARATOR) || (pos == len))
548 {
549 rdir[pos] = '\0';
551 if (GNUNET_NO == ret)
552 {
554 "Creating directory `%s' failed",
555 rdir);
556 GNUNET_free (rdir);
557 return GNUNET_SYSERR;
558 }
559 if (GNUNET_SYSERR == ret)
560 {
561 ret = mkdir (rdir,
562 S_IRUSR | S_IWUSR | S_IXUSR | S_IRGRP | S_IXGRP | S_IROTH
563 | S_IXOTH); /* 755 */
564
565 if ((ret != 0) && (errno != EEXIST))
566 {
568 GNUNET_free (rdir);
569 return GNUNET_SYSERR;
570 }
571 }
572 rdir[pos] = DIR_SEPARATOR;
573 }
574 pos++;
575 }
576 GNUNET_free (rdir);
577 return GNUNET_OK;
578}
579
580
583{
584 char *rdir;
585 size_t len;
586 int eno;
588
590 if (NULL == rdir)
591 {
592 errno = EINVAL;
593 return GNUNET_SYSERR;
594 }
595 if (0 == access (rdir, W_OK))
596 {
597 GNUNET_free (rdir);
598 return GNUNET_OK;
599 }
600 len = strlen (rdir);
601 while ((len > 0) && (rdir[len] != DIR_SEPARATOR))
602 len--;
603 rdir[len] = '\0';
604 /* The empty path is invalid and in this case refers to / */
605 if (0 == len)
606 {
607 GNUNET_free (rdir);
608 rdir = GNUNET_strdup ("/");
609 }
611 if ( (GNUNET_OK == res) &&
612 (0 != access (rdir, W_OK)) )
613 res = GNUNET_NO;
614 eno = errno;
615 GNUNET_free (rdir);
616 errno = eno;
617 return res;
618}
619
620
621ssize_t
623 void *result,
624 size_t len)
625{
626 if (NULL == h)
627 {
628 errno = EINVAL;
629 return GNUNET_SYSERR;
630 }
631 return read (h->fd, result, len);
632}
633
634
635ssize_t
637 void *result,
638 size_t len)
639{
640 int flags;
641 ssize_t ret;
642
643 if (NULL == h)
644 {
645 errno = EINVAL;
646 return GNUNET_SYSERR;
647 }
648 /* set to non-blocking, read, then set back */
649 flags = fcntl (h->fd, F_GETFL);
650 if (0 == (flags & O_NONBLOCK))
651 (void) fcntl (h->fd, F_SETFL, flags | O_NONBLOCK);
652 ret = read (h->fd, result, len);
653 if (0 == (flags & O_NONBLOCK))
654 {
655 int eno = errno;
656 (void) fcntl (h->fd, F_SETFL, flags);
657 errno = eno;
658 }
659 return ret;
660}
661
662
663ssize_t
664GNUNET_DISK_fn_read (const char *fn,
665 void *result,
666 size_t len)
667{
669 ssize_t ret;
670 int eno;
671
675 if (NULL == fh)
676 return GNUNET_SYSERR;
678 eno = errno;
680 errno = eno;
681 return ret;
682}
683
684
685ssize_t
687 const void *buffer,
688 size_t n)
689{
690 if (NULL == h)
691 {
692 errno = EINVAL;
693 return GNUNET_SYSERR;
694 }
695
696 return write (h->fd, buffer, n);
697}
698
699
700ssize_t
702 const void *buffer,
703 size_t n)
704{
705 int flags;
706 ssize_t ret;
707
708 if (NULL == h)
709 {
710 errno = EINVAL;
711 return GNUNET_SYSERR;
712 }
713 /* set to blocking, write, then set back */
714 flags = fcntl (h->fd, F_GETFL);
715 if (0 != (flags & O_NONBLOCK))
716 (void) fcntl (h->fd, F_SETFL, flags - O_NONBLOCK);
717 ret = write (h->fd, buffer, n);
718 if (0 == (flags & O_NONBLOCK))
719 (void) fcntl (h->fd, F_SETFL, flags);
720 return ret;
721}
722
723
725GNUNET_DISK_fn_write (const char *fn,
726 const void *buf,
727 size_t buf_size,
729{
730 char *tmpl;
731 int fd;
732
733 if (GNUNET_OK !=
735 {
737 "mkstemp",
738 fn);
739 return GNUNET_SYSERR;
740 }
741 {
742 char *dname;
743
744 dname = GNUNET_strdup (fn);
745 GNUNET_asprintf (&tmpl,
746 "%s/XXXXXX",
747 dirname (dname));
748 GNUNET_free (dname);
749 }
750 fd = mkstemp (tmpl);
751 if (-1 == fd)
752 {
754 "mkstemp",
755 tmpl);
756 GNUNET_free (tmpl);
757 return GNUNET_SYSERR;
758 }
759
760 if (0 != fchmod (fd,
762 {
764 "chmod",
765 tmpl);
766 GNUNET_assert (0 == close (fd));
767 if (0 != unlink (tmpl))
769 "unlink",
770 tmpl);
771 GNUNET_free (tmpl);
772 return GNUNET_SYSERR;
773 }
774 if (buf_size !=
775 write (fd,
776 buf,
777 buf_size))
778 {
780 "write",
781 tmpl);
782 GNUNET_assert (0 == close (fd));
783 if (0 != unlink (tmpl))
785 "unlink",
786 tmpl);
787 GNUNET_free (tmpl);
788 return GNUNET_SYSERR;
789 }
790 GNUNET_assert (0 == close (fd));
791
792 if (0 != link (tmpl,
793 fn))
794 {
795 if (0 != unlink (tmpl))
797 "unlink",
798 tmpl);
799 GNUNET_free (tmpl);
800 return GNUNET_NO;
801 }
802 if (0 != unlink (tmpl))
804 "unlink",
805 tmpl);
806 GNUNET_free (tmpl);
807 return GNUNET_OK;
808
809
810}
811
812
813int
816 void *callback_cls)
817{
818 DIR *dinfo;
819 struct dirent *finfo;
820 struct stat istat;
821 int count = 0;
823 char *name;
824 char *dname;
825 unsigned int name_len;
826 unsigned int n_size;
827
828 GNUNET_assert (NULL != dir_name);
830 if (NULL == dname)
831 return GNUNET_SYSERR;
832 while ((strlen (dname) > 0) && (dname[strlen (dname) - 1] == DIR_SEPARATOR))
833 dname[strlen (dname) - 1] = '\0';
834 if (0 != stat (dname, &istat))
835 {
837 GNUNET_free (dname);
838 return GNUNET_SYSERR;
839 }
840 if (! S_ISDIR (istat.st_mode))
841 {
843 _ ("Expected `%s' to be a directory!\n"),
844 dir_name);
845 GNUNET_free (dname);
846 return GNUNET_SYSERR;
847 }
848 errno = 0;
849 dinfo = opendir (dname);
850 if ((EACCES == errno) || (NULL == dinfo))
851 {
853 if (NULL != dinfo)
854 closedir (dinfo);
855 GNUNET_free (dname);
856 return GNUNET_SYSERR;
857 }
858 name_len = 256;
859 n_size = strlen (dname) + name_len + strlen (DIR_SEPARATOR_STR) + 1;
860 name = GNUNET_malloc (n_size);
861 while (NULL != (finfo = readdir (dinfo)))
862 {
863 if ((0 == strcmp (finfo->d_name, ".")) ||
864 (0 == strcmp (finfo->d_name, "..")))
865 continue;
866 if (NULL != callback)
867 {
868 if (name_len < strlen (finfo->d_name))
869 {
871 name_len = strlen (finfo->d_name);
872 n_size = strlen (dname) + name_len + strlen (DIR_SEPARATOR_STR) + 1;
873 name = GNUNET_malloc (n_size);
874 }
875 /* dname can end in "/" only if dname == "/";
876 * if dname does not end in "/", we need to add
877 * a "/" (otherwise, we must not!) */
879 n_size,
880 "%s%s%s",
881 dname,
882 (0 == strcmp (dname, DIR_SEPARATOR_STR))
883 ? ""
885 finfo->d_name);
886 ret = callback (callback_cls, name);
887 if (GNUNET_OK != ret)
888 {
889 closedir (dinfo);
891 GNUNET_free (dname);
892 if (GNUNET_NO == ret)
893 return count;
894 return GNUNET_SYSERR;
895 }
896 }
897 count++;
898 }
899 closedir (dinfo);
901 GNUNET_free (dname);
902 return count;
903}
904
905
915static bool
916glob_match (const char *pattern, const char *str)
917{
918 /* Position in the input string */
919 const char *str_pos = str;
920 /* Position in the pattern */
921 const char *pat_pos = pattern;
922 /* Backtrack position in string */
923 const char *str_bt = NULL;
924 /* Backtrack position in pattern */
925 const char *pat_bt = NULL;
926
927 for (;;)
928 {
929 if (*pat_pos == '*')
930 {
931 str_bt = str_pos;
932 pat_bt = pat_pos++;
933 }
934 else if (*pat_pos == *str_pos)
935 {
936 if ('\0' == *pat_pos)
937 return true;
938 str_pos++;
939 pat_pos++;
940 }
941 else
942 {
943 if (NULL == str_bt)
944 return false;
945 /* Backtrack to match one more
946 character as part of the asterisk. */
947 str_pos = str_bt + 1;
948 if ('\0' == *str_pos)
949 return false;
950 pat_pos = pat_bt;
951 }
952 }
953}
954
955
957{
958 const char *glob;
960 void *cls;
961
965 int nres;
966};
967
978glob_cb (void *cls,
979 const char *filename)
980{
981 struct GlobClosure *gc = cls;
982 const char *fn;
983
984 fn = strrchr (filename, DIR_SEPARATOR);
985 fn = (NULL == fn) ? filename : (fn + 1);
986
988 "checking glob '%s' against '%s'\n",
989 gc->glob,
990 fn);
991
992 if (glob_match (gc->glob, fn))
993 {
994 enum GNUNET_GenericReturnValue cbret;
995
997 "found glob match '%s'\n",
998 filename);
999 gc->nres++;
1000 cbret = gc->cb (gc->cls, filename);
1001 if (GNUNET_OK != cbret)
1002 return cbret;
1003 }
1004 return GNUNET_OK;
1005}
1006
1007
1008int
1009GNUNET_DISK_glob (const char *glob_pattern,
1010 GNUNET_FileNameCallback callback,
1011 void *callback_cls)
1012{
1013 char *mypat = GNUNET_strdup (glob_pattern);
1014 char *sep;
1015 int ret;
1016
1017 if ( (NULL != strrchr (glob_pattern, '+')) ||
1018 (NULL != strrchr (glob_pattern, '[')) ||
1019 (NULL != strrchr (glob_pattern, '+')) ||
1020 (NULL != strrchr (glob_pattern, '~')) )
1021 {
1023 "unsupported glob pattern: '%s'\n",
1024 glob_pattern);
1025 GNUNET_free (mypat);
1026 return -1;
1027 }
1028
1029 sep = strrchr (mypat, DIR_SEPARATOR);
1030 if (NULL == sep)
1031 {
1032 GNUNET_free (mypat);
1033 return -1;
1034 }
1035
1036 *sep = '\0';
1037
1038 if (NULL != strchr (mypat, '*'))
1039 {
1040 GNUNET_free (mypat);
1041 GNUNET_break (0);
1043 "glob pattern may only contain '*' in the final path component\n");
1044 return -1;
1045 }
1046
1047 {
1048 struct GlobClosure gc = {
1049 .glob = sep + 1,
1050 .cb = callback,
1051 .cls = callback_cls,
1052 .nres = 0,
1053 };
1055 "scanning directory '%s' for glob matches on '%s'\n",
1056 mypat,
1057 gc.glob);
1059 glob_cb,
1060 &gc
1061 );
1062 GNUNET_free (mypat);
1063 return (ret < 0) ? ret : gc.nres;
1064 }
1065}
1066
1067
1076static enum GNUNET_GenericReturnValue
1077remove_helper (void *unused,
1078 const char *fn)
1079{
1080 (void) unused;
1081 (void) GNUNET_DISK_directory_remove (fn);
1082 return GNUNET_OK;
1083}
1084
1085
1088{
1089 struct stat istat;
1090
1091 if (NULL == filename)
1092 {
1093 GNUNET_break (0);
1094 return GNUNET_SYSERR;
1095 }
1096 if (0 != lstat (filename, &istat))
1097 return GNUNET_NO; /* file may not exist... */
1098 (void) chmod (filename,
1099 S_IWUSR | S_IRUSR | S_IXUSR);
1100 if (0 == unlink (filename))
1101 return GNUNET_OK;
1102 if ( (errno != EISDIR) &&
1103 /* EISDIR is not sufficient in all cases, e.g.
1104 * sticky /tmp directory may result in EPERM on BSD.
1105 * So we also explicitly check "isDirectory" */
1106 (GNUNET_YES !=
1108 GNUNET_YES)) )
1109 {
1111 return GNUNET_SYSERR;
1112 }
1113 if (GNUNET_SYSERR ==
1115 return GNUNET_SYSERR;
1116 if (0 != rmdir (filename))
1117 {
1119 return GNUNET_SYSERR;
1120 }
1121 return GNUNET_OK;
1122}
1123
1124
1126GNUNET_DISK_file_copy (const char *src,
1127 const char *dst)
1128{
1129 char *buf;
1130 uint64_t pos;
1131 uint64_t size;
1132 size_t len;
1133 ssize_t sret;
1134 struct GNUNET_DISK_FileHandle *in;
1135 struct GNUNET_DISK_FileHandle *out;
1136
1138 {
1140 return GNUNET_SYSERR;
1141 }
1142 pos = 0;
1143 in =
1145 if (! in)
1146 {
1148 return GNUNET_SYSERR;
1149 }
1150 out =
1158 if (! out)
1159 {
1162 return GNUNET_SYSERR;
1163 }
1165 while (pos < size)
1166 {
1167 len = COPY_BLK_SIZE;
1168 if (len > size - pos)
1169 len = size - pos;
1170 sret = GNUNET_DISK_file_read (in, buf, len);
1171 if ((sret < 0) || (len != (size_t) sret))
1172 goto FAIL;
1173 sret = GNUNET_DISK_file_write (out, buf, len);
1174 if ((sret < 0) || (len != (size_t) sret))
1175 goto FAIL;
1176 pos += len;
1177 }
1178 GNUNET_free (buf);
1181 return GNUNET_OK;
1182 FAIL:
1183 GNUNET_free (buf);
1186 return GNUNET_SYSERR;
1187}
1188
1189
1190void
1192{
1193 char *idx;
1194 char c;
1195
1196 for (idx = fn; *idx; idx++)
1197 {
1198 c = *idx;
1199
1200 if ((c == '/') || (c == '\\') || (c == ':') || (c == '*') || (c == '?') ||
1201 (c ==
1202 '"')
1203 ||
1204 (c == '<') || (c == '>') || (c == '|') )
1205 {
1206 *idx = '_';
1207 }
1208 }
1209}
1210
1211
1214 const char *user)
1215{
1216 struct passwd *pws;
1217
1218 pws = getpwnam (user);
1219 if (NULL == pws)
1220 {
1222 _ ("Cannot obtain information about user `%s': %s\n"),
1223 user,
1224 strerror (errno));
1225 return GNUNET_SYSERR;
1226 }
1227 if (0 != chown (filename, pws->pw_uid, pws->pw_gid))
1228 {
1230 return GNUNET_SYSERR;
1231 }
1232 return GNUNET_OK;
1233}
1234
1235
1238 enum GNUNET_DISK_OpenFlags flags,
1240{
1241 char *expfn;
1243
1244 int oflags;
1245 int mode;
1246 int fd;
1247
1248 expfn = GNUNET_STRINGS_filename_expand (fn);
1249 if (NULL == expfn)
1250 return NULL;
1251
1252 mode = 0;
1254 oflags = O_RDWR; /* note: O_RDWR is NOT always O_RDONLY | O_WRONLY */
1255 else if (flags & GNUNET_DISK_OPEN_READ)
1256 oflags = O_RDONLY;
1257 else if (flags & GNUNET_DISK_OPEN_WRITE)
1258 oflags = O_WRONLY;
1259 else
1260 {
1261 GNUNET_break (0);
1262 GNUNET_free (expfn);
1263 return NULL;
1264 }
1266 oflags |= (O_CREAT | O_EXCL);
1267 if (flags & GNUNET_DISK_OPEN_TRUNCATE)
1268 oflags |= O_TRUNC;
1269 if (flags & GNUNET_DISK_OPEN_APPEND)
1270 oflags |= O_APPEND;
1271 if (GNUNET_NO == GNUNET_DISK_file_test (fn))
1272 {
1273 if (flags & GNUNET_DISK_OPEN_CREATE)
1274 {
1276 oflags |= O_CREAT;
1277 mode = translate_unix_perms (perm);
1278 }
1279 }
1280
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
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 (-1 == pipe (fd))
1449 {
1450 int eno = errno;
1451
1453 errno = eno;
1454 return NULL;
1455 }
1456 return GNUNET_DISK_pipe_from_fd (pf, fd);
1457}
1458
1459
1462 int fd[2])
1463{
1464 struct GNUNET_DISK_PipeHandle *p;
1465 int ret = 0;
1466 int flags;
1467 int eno = 0; /* make gcc happy */
1468
1470 if (fd[0] >= 0)
1471 {
1472 p->fd[0] = GNUNET_new (struct GNUNET_DISK_FileHandle);
1473 p->fd[0]->fd = fd[0];
1474 if (0 == (GNUNET_DISK_PF_BLOCKING_READ & pf))
1475 {
1476 flags = fcntl (fd[0], F_GETFL);
1477 flags |= O_NONBLOCK;
1478 if (0 > fcntl (fd[0], F_SETFL, flags))
1479 {
1480 ret = -1;
1481 eno = errno;
1482 }
1483 }
1484 flags = fcntl (fd[0], F_GETFD);
1485 flags |= FD_CLOEXEC;
1486 if (0 > fcntl (fd[0], F_SETFD, flags))
1487 {
1488 ret = -1;
1489 eno = errno;
1490 }
1491 }
1492
1493 if (fd[1] >= 0)
1494 {
1495 p->fd[1] = GNUNET_new (struct GNUNET_DISK_FileHandle);
1496 p->fd[1]->fd = fd[1];
1497 if (0 == (GNUNET_DISK_PF_BLOCKING_WRITE & pf))
1498 {
1499 flags = fcntl (fd[1], F_GETFL);
1500 flags |= O_NONBLOCK;
1501 if (0 > fcntl (fd[1], F_SETFL, flags))
1502 {
1503 ret = -1;
1504 eno = errno;
1505 }
1506 }
1507 flags = fcntl (fd[1], F_GETFD);
1508 flags |= FD_CLOEXEC;
1509 if (0 > fcntl (fd[1], F_SETFD, flags))
1510 {
1511 ret = -1;
1512 eno = errno;
1513 }
1514 }
1515 if (ret == -1)
1516 {
1517 errno = eno;
1519 if (p->fd[0]->fd >= 0)
1520 GNUNET_break (0 == close (p->fd[0]->fd));
1521 if (p->fd[1]->fd >= 0)
1522 GNUNET_break (0 == close (p->fd[1]->fd));
1523 GNUNET_free (p->fd[0]);
1524 GNUNET_free (p->fd[1]);
1525 GNUNET_free (p);
1526 errno = eno;
1527 return NULL;
1528 }
1529 return p;
1530}
1531
1532
1536{
1538
1540 {
1541 if (p->fd[0])
1542 {
1543 ret = GNUNET_DISK_file_close (p->fd[0]);
1544 p->fd[0] = NULL;
1545 }
1546 }
1547 else if (end == GNUNET_DISK_PIPE_END_WRITE)
1548 {
1549 if (p->fd[1])
1550 {
1551 ret = GNUNET_DISK_file_close (p->fd[1]);
1552 p->fd[1] = NULL;
1553 }
1554 }
1555 return ret;
1556}
1557
1558
1562{
1563 struct GNUNET_DISK_FileHandle *ret = NULL;
1564
1566 {
1567 if (p->fd[0])
1568 {
1569 ret = p->fd[0];
1570 p->fd[0] = NULL;
1571 }
1572 }
1573 else if (end == GNUNET_DISK_PIPE_END_WRITE)
1574 {
1575 if (p->fd[1])
1576 {
1577 ret = p->fd[1];
1578 p->fd[1] = NULL;
1579 }
1580 }
1581
1582 return ret;
1583}
1584
1585
1588{
1590 enum GNUNET_GenericReturnValue read_end_close;
1591 enum GNUNET_GenericReturnValue write_end_close;
1592 int read_end_close_errno;
1593 int write_end_close_errno;
1594
1596 read_end_close_errno = errno;
1598 write_end_close_errno = errno;
1599 GNUNET_free (p);
1600
1601 if (GNUNET_OK != read_end_close)
1602 {
1603 errno = read_end_close_errno;
1604 ret = read_end_close;
1605 }
1606 else if (GNUNET_OK != write_end_close)
1607 {
1608 errno = write_end_close_errno;
1609 ret = write_end_close;
1610 }
1611
1612 return ret;
1613}
1614
1615
1616const struct GNUNET_DISK_FileHandle *
1618 enum GNUNET_DISK_PipeEnd n)
1619{
1620 switch (n)
1621 {
1624 return p->fd[n];
1625
1626 default:
1627 GNUNET_break (0);
1628 return NULL;
1629 }
1630}
1631
1632
1635 void *dst,
1636 size_t dst_len)
1637{
1638 if (NULL == fh)
1639 return GNUNET_SYSERR;
1640 if (dst_len < sizeof(int))
1641 return GNUNET_SYSERR;
1642 *((int *) dst) = fh->fd;
1643 return GNUNET_OK;
1644}
1645
1646
1654static enum GNUNET_GenericReturnValue
1655purge_cfg_dir (void *cls,
1656 const struct GNUNET_CONFIGURATION_Handle *cfg)
1657{
1658 const char *option = cls;
1659 char *tmpname;
1660
1661 if (GNUNET_OK !=
1662 GNUNET_CONFIGURATION_get_value_filename (cfg, "PATHS", option, &tmpname))
1663 {
1665 return GNUNET_NO;
1666 }
1668 {
1670 GNUNET_free (tmpname);
1671 return GNUNET_OK;
1672 }
1673 GNUNET_free (tmpname);
1674 return GNUNET_OK;
1675}
1676
1677
1678void
1680 const char *option)
1681{
1685 (void *) option));
1686}
1687
1688
1689/* 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:145
#define COPY_BLK_SIZE
Block size for IO for copying files.
Definition: disk.c:41
static enum GNUNET_GenericReturnValue glob_cb(void *cls, const char *filename)
Function called with a filename.
Definition: disk.c:978
#define LOG_STRERROR_FILE(kind, syscall, filename)
Definition: disk.c:35
static int translate_unix_perms(enum GNUNET_DISK_AccessPermissions perm)
Translate GNUnet-internal permission bitmap to UNIX file access permission bitmap.
Definition: disk.c:108
static enum GNUNET_GenericReturnValue file_test_internal(const char *fil, int amode)
Check if fil can be accessed using amode.
Definition: disk.c:443
#define S_ISLNK(m)
Definition: disk.c:60
#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:916
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:1655
enum GNUNET_GenericReturnValue GNUNET_DISK_internal_file_handle_(const struct GNUNET_DISK_FileHandle *fh, void *dst, size_t dst_len)
Retrieve OS file handle.
Definition: disk.c:1634
#define LOG(kind,...)
Definition: disk.c:30
static char * mktemp_name(const char *t)
Create the name for a temporary file or directory from a template.
Definition: disk.c:292
#define LOG_STRERROR(kind, syscall)
Definition: disk.c:32
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:1077
char * getenv()
static struct GNUNET_ARM_MonitorHandle * m
Monitor connection with ARM.
Definition: gnunet-arm.c:104
static struct GNUNET_ARM_Handle * h
Connection with ARM.
Definition: gnunet-arm.c:99
static int ret
Final status code.
Definition: gnunet-arm.c:94
static struct GNUNET_CONFIGURATION_Handle * cfg
Our configuration.
Definition: gnunet-arm.c:109
static char * dir
Set to the directory where runtime files are stored.
Definition: gnunet-arm.c:89
static int end
Set if we are to shutdown all services (including ARM).
Definition: gnunet-arm.c:34
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_DISK_FileHandle * fh
File handle to STDIN, for reading restart/quit commands.
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 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:1617
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:1237
void GNUNET_DISK_filename_canonicalize(char *fn)
Removes special characters as ':' from a filename.
Definition: disk.c:1191
int GNUNET_DISK_glob(const char *glob_pattern, GNUNET_FileNameCallback callback, void *callback_cls)
Find all files matching a glob pattern.
Definition: disk.c:1009
enum GNUNET_GenericReturnValue GNUNET_DISK_file_change_owner(const char *filename, const char *user)
Change owner of a file.
Definition: disk.c:1213
char * GNUNET_DISK_mktemp(const char *t)
Create an (empty) temporary file on disk.
Definition: disk.c:380
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:482
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:240
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:320
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:1560
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:1461
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:686
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:636
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:1679
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:205
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:489
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:221
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:1587
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:725
char * GNUNET_DISK_mkdtemp(const char *t)
Create an (empty) temporary directory on disk.
Definition: disk.c:339
enum GNUNET_GenericReturnValue GNUNET_DISK_file_copy(const char *src, const char *dst)
Copy a file.
Definition: disk.c:1126
enum GNUNET_GenericReturnValue GNUNET_DISK_directory_remove(const char *filename)
Remove all files in a directory (rm -rf).
Definition: disk.c:1087
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:185
enum GNUNET_GenericReturnValue GNUNET_DISK_directory_test(const char *fil, int is_readable)
Test if fil is a directory and listable.
Definition: disk.c:403
enum GNUNET_GenericReturnValue GNUNET_DISK_file_close(struct GNUNET_DISK_FileHandle *h)
Close an open file.
Definition: disk.c:1308
struct GNUNET_DISK_FileHandle * GNUNET_DISK_get_handle_from_native(FILE *fd)
Get a handle from a native FD.
Definition: disk.c:1346
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:359
enum GNUNET_GenericReturnValue GNUNET_DISK_directory_create_for_file(const char *filename)
Create the directory structure for storing a file.
Definition: disk.c:582
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:622
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:192
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:1534
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:701
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:496
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:664
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:814
@ 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:495
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: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:68
struct GNUNET_DISK_FileHandle * fd[2]
File descriptors for the pipe.
Definition: disk.c:73
Closure for the recursion to determine the file size of a directory.
Definition: disk.c:82
uint64_t total
Set to the total file size.
Definition: disk.c:86
int include_sym_links
GNUNET_YES if symbolic links should be included.
Definition: disk.c:91
int single_file_mode
GNUNET_YES if mode is file-only (return total == -1 for directories).
Definition: disk.c:96
GNUNET_FileNameCallback cb
Definition: disk.c:959
void * cls
Definition: disk.c:960
int nres
Number of files that actually matched the glob pattern.
Definition: disk.c:965
const char * glob
Definition: disk.c:958