GNUnet 0.22.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#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 != stat64 (fn, &buf))
155 {
157 return GNUNET_SYSERR;
158 }
159#else
160 struct stat buf;
161
162 if (0 != stat (fn, &buf))
163 {
165 return GNUNET_SYSERR;
166 }
167#endif
168 if ((S_ISDIR (buf.st_mode)) && (gfsd->single_file_mode == GNUNET_YES))
169 {
170 errno = EISDIR;
171 return GNUNET_SYSERR;
172 }
173 if ((! S_ISLNK (buf.st_mode)) || (gfsd->include_sym_links == GNUNET_YES))
174 gfsd->total += buf.st_size;
175 if ((S_ISDIR (buf.st_mode)) && (0 == access (fn, X_OK)) &&
176 ((! S_ISLNK (buf.st_mode)) || (gfsd->include_sym_links == GNUNET_YES)))
177 {
179 return GNUNET_SYSERR;
180 }
181 return GNUNET_OK;
182}
183
184
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
359void
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 do
370 {
371 GNUNET_snprintf (target, slen, "%s.%u~", fil, num++);
372 }
373 while (0 == access (target, F_OK));
374 if (0 != rename (fil, target))
376 GNUNET_free (target);
377}
378
379
380char *
382{
383 int fd;
384 char *fn;
385 mode_t omask;
386
387 omask = umask (S_IWGRP | S_IWOTH | S_IRGRP | S_IROTH);
388 fn = mktemp_name (t);
389 if (-1 == (fd = mkstemp (fn)))
390 {
392 GNUNET_free (fn);
393 umask (omask);
394 return NULL;
395 }
396 umask (omask);
397 if (0 != close (fd))
399 return fn;
400}
401
402
404GNUNET_DISK_directory_test (const char *fil, int is_readable)
405{
406 struct stat filestat;
407 int ret;
408
409 ret = stat (fil, &filestat);
410 if (ret != 0)
411 {
412 if (errno != ENOENT)
414 return GNUNET_SYSERR;
415 }
416 if (! S_ISDIR (filestat.st_mode))
417 {
419 "A file already exits with the same name %s\n",
420 fil);
421 return GNUNET_NO;
422 }
423 if (GNUNET_YES == is_readable)
424 ret = access (fil, R_OK | X_OK);
425 else
426 ret = access (fil, X_OK);
427 if (ret < 0)
428 {
430 return GNUNET_NO;
431 }
432 return GNUNET_YES;
433}
434
435
444file_test_internal (const char *fil, int amode)
445{
446 struct stat filestat;
447 int ret;
448 char *rdir;
449
451 if (rdir == NULL)
452 return GNUNET_SYSERR;
453
454 ret = stat (rdir, &filestat);
455 if (0 != ret)
456 {
457 if (errno != ENOENT)
458 {
460 GNUNET_free (rdir);
461 return GNUNET_SYSERR;
462 }
463 GNUNET_free (rdir);
464 return GNUNET_NO;
465 }
466 if (! S_ISREG (filestat.st_mode))
467 {
468 GNUNET_free (rdir);
469 return GNUNET_NO;
470 }
471 if (access (rdir, amode) < 0)
472 {
474 GNUNET_free (rdir);
475 return GNUNET_SYSERR;
476 }
477 GNUNET_free (rdir);
478 return GNUNET_YES;
479}
480
481
483GNUNET_DISK_file_test (const char *fil)
484{
485 return file_test_internal (fil, F_OK);
486}
487
488
491{
492 return file_test_internal (fil, R_OK);
493}
494
495
498{
499 char *rdir;
500 unsigned int len;
501 unsigned int pos;
502 unsigned int pos2;
503 int ret = GNUNET_OK;
504
506 if (rdir == NULL)
507 {
508 GNUNET_break (0);
509 return GNUNET_SYSERR;
510 }
511
512 len = strlen (rdir);
513
514 pos = 1; /* skip heading '/' */
515
516 /* Check which low level directories already exist */
517 pos2 = len;
518 rdir[len] = DIR_SEPARATOR;
519 while (pos <= pos2)
520 {
521 if (DIR_SEPARATOR == rdir[pos2])
522 {
523 rdir[pos2] = '\0';
525 if (GNUNET_NO == ret)
526 {
528 "Creating directory `%s' failed\n",
529 rdir);
530 GNUNET_free (rdir);
531 return GNUNET_SYSERR;
532 }
533 rdir[pos2] = DIR_SEPARATOR;
534 if (GNUNET_YES == ret)
535 {
536 pos2++;
537 break;
538 }
539 }
540 pos2--;
541 }
542 rdir[len] = '\0';
543 if (pos < pos2)
544 pos = pos2;
545 /* Start creating directories */
546 while (pos <= len)
547 {
548 if ((rdir[pos] == DIR_SEPARATOR) || (pos == len))
549 {
550 rdir[pos] = '\0';
552 if (GNUNET_NO == ret)
553 {
555 "Creating directory `%s' failed\n",
556 rdir);
557 GNUNET_free (rdir);
558 return GNUNET_SYSERR;
559 }
560 if (GNUNET_SYSERR == ret)
561 {
562 ret = mkdir (rdir,
563 S_IRUSR | S_IWUSR | S_IXUSR | S_IRGRP | S_IXGRP | S_IROTH
564 | S_IXOTH); /* 755 */
565
566 if ((ret != 0) && (errno != EEXIST))
567 {
569 GNUNET_free (rdir);
570 return GNUNET_SYSERR;
571 }
572 }
573 rdir[pos] = DIR_SEPARATOR;
574 }
575 pos++;
576 }
577 GNUNET_free (rdir);
578 return GNUNET_OK;
579}
580
581
584{
585 char *rdir;
586 size_t len;
587 int eno;
589
591 if (NULL == rdir)
592 {
593 errno = EINVAL;
594 return GNUNET_SYSERR;
595 }
596 if (0 == access (rdir, W_OK))
597 {
598 GNUNET_free (rdir);
599 return GNUNET_OK;
600 }
601 len = strlen (rdir);
602 while ((len > 0) && (rdir[len] != DIR_SEPARATOR))
603 len--;
604 rdir[len] = '\0';
605 /* The empty path is invalid and in this case refers to / */
606 if (0 == len)
607 {
608 GNUNET_free (rdir);
609 rdir = GNUNET_strdup ("/");
610 }
612 if ( (GNUNET_OK == res) &&
613 (0 != access (rdir, W_OK)) )
614 res = GNUNET_NO;
615 eno = errno;
616 GNUNET_free (rdir);
617 errno = eno;
618 return res;
619}
620
621
622ssize_t
624 void *result,
625 size_t len)
626{
627 if (NULL == h)
628 {
629 errno = EINVAL;
630 return GNUNET_SYSERR;
631 }
632 return read (h->fd, result, len);
633}
634
635
636ssize_t
638 void *result,
639 size_t len)
640{
641 int flags;
642 ssize_t ret;
643
644 if (NULL == h)
645 {
646 errno = EINVAL;
647 return GNUNET_SYSERR;
648 }
649 /* set to non-blocking, read, then set back */
650 flags = fcntl (h->fd, F_GETFL);
651 if (0 == (flags & O_NONBLOCK))
652 (void) fcntl (h->fd, F_SETFL, flags | O_NONBLOCK);
653 ret = read (h->fd, result, len);
654 if (0 == (flags & O_NONBLOCK))
655 {
656 int eno = errno;
657 (void) fcntl (h->fd, F_SETFL, flags);
658 errno = eno;
659 }
660 return ret;
661}
662
663
664ssize_t
665GNUNET_DISK_fn_read (const char *fn,
666 void *result,
667 size_t len)
668{
669 struct GNUNET_DISK_FileHandle *fh;
670 ssize_t ret;
671 int eno;
672
673 fh = GNUNET_DISK_file_open (fn,
676 if (NULL == fh)
677 return GNUNET_SYSERR;
678 ret = GNUNET_DISK_file_read (fh, result, len);
679 eno = errno;
681 errno = eno;
682 return ret;
683}
684
685
686ssize_t
688 const void *buffer,
689 size_t n)
690{
691 if (NULL == h)
692 {
693 errno = EINVAL;
694 return GNUNET_SYSERR;
695 }
696
697 return write (h->fd, buffer, n);
698}
699
700
701ssize_t
703 const void *buffer,
704 size_t n)
705{
706 int flags;
707 ssize_t ret;
708
709 if (NULL == h)
710 {
711 errno = EINVAL;
712 return GNUNET_SYSERR;
713 }
714 /* set to blocking, write, then set back */
715 flags = fcntl (h->fd, F_GETFL);
716 if (0 != (flags & O_NONBLOCK))
717 (void) fcntl (h->fd, F_SETFL, flags - O_NONBLOCK);
718 ret = write (h->fd, buffer, n);
719 if (0 == (flags & O_NONBLOCK))
720 (void) fcntl (h->fd, F_SETFL, flags);
721 return ret;
722}
723
724
726GNUNET_DISK_fn_write (const char *fn,
727 const void *buf,
728 size_t buf_size,
730{
731 char *tmpl;
732 int fd;
733
734 if (GNUNET_OK !=
736 {
738 "mkstemp",
739 fn);
740 return GNUNET_SYSERR;
741 }
742 {
743 char *dname;
744
745 dname = GNUNET_strdup (fn);
746 GNUNET_asprintf (&tmpl,
747 "%s/XXXXXX",
748 dirname (dname));
749 GNUNET_free (dname);
750 }
751 fd = mkstemp (tmpl);
752 if (-1 == fd)
753 {
755 "mkstemp",
756 tmpl);
757 GNUNET_free (tmpl);
758 return GNUNET_SYSERR;
759 }
760
761 if (0 != fchmod (fd,
763 {
765 "chmod",
766 tmpl);
767 GNUNET_assert (0 == close (fd));
768 if (0 != unlink (tmpl))
770 "unlink",
771 tmpl);
772 GNUNET_free (tmpl);
773 return GNUNET_SYSERR;
774 }
775 if (buf_size !=
776 write (fd,
777 buf,
778 buf_size))
779 {
781 "write",
782 tmpl);
783 GNUNET_assert (0 == close (fd));
784 if (0 != unlink (tmpl))
786 "unlink",
787 tmpl);
788 GNUNET_free (tmpl);
789 return GNUNET_SYSERR;
790 }
791 GNUNET_assert (0 == close (fd));
792
793 if (0 != link (tmpl,
794 fn))
795 {
796 if (0 != unlink (tmpl))
798 "unlink",
799 tmpl);
800 GNUNET_free (tmpl);
801 return GNUNET_NO;
802 }
803 if (0 != unlink (tmpl))
805 "unlink",
806 tmpl);
807 GNUNET_free (tmpl);
808 return GNUNET_OK;
809
810
811}
812
813
814int
817 void *callback_cls)
818{
819 DIR *dinfo;
820 struct dirent *finfo;
821 struct stat istat;
822 int count = 0;
824 char *name;
825 char *dname;
826 unsigned int name_len;
827 unsigned int n_size;
828
829 GNUNET_assert (NULL != dir_name);
831 if (NULL == dname)
832 return GNUNET_SYSERR;
833 while ((strlen (dname) > 0) && (dname[strlen (dname) - 1] == DIR_SEPARATOR))
834 dname[strlen (dname) - 1] = '\0';
835 if (0 != stat (dname, &istat))
836 {
838 GNUNET_free (dname);
839 return GNUNET_SYSERR;
840 }
841 if (! S_ISDIR (istat.st_mode))
842 {
844 _ ("Expected `%s' to be a directory!\n"),
845 dir_name);
846 GNUNET_free (dname);
847 return GNUNET_SYSERR;
848 }
849 errno = 0;
850 dinfo = opendir (dname);
851 if ((EACCES == errno) || (NULL == dinfo))
852 {
854 if (NULL != dinfo)
855 closedir (dinfo);
856 GNUNET_free (dname);
857 return GNUNET_SYSERR;
858 }
859 name_len = 256;
860 n_size = strlen (dname) + name_len + strlen (DIR_SEPARATOR_STR) + 1;
861 name = GNUNET_malloc (n_size);
862 while (NULL != (finfo = readdir (dinfo)))
863 {
864 if ((0 == strcmp (finfo->d_name, ".")) ||
865 (0 == strcmp (finfo->d_name, "..")))
866 continue;
867 if (NULL != callback)
868 {
869 if (name_len < strlen (finfo->d_name))
870 {
872 name_len = strlen (finfo->d_name);
873 n_size = strlen (dname) + name_len + strlen (DIR_SEPARATOR_STR) + 1;
874 name = GNUNET_malloc (n_size);
875 }
876 /* dname can end in "/" only if dname == "/";
877 * if dname does not end in "/", we need to add
878 * a "/" (otherwise, we must not!) */
880 n_size,
881 "%s%s%s",
882 dname,
883 (0 == strcmp (dname, DIR_SEPARATOR_STR))
884 ? ""
886 finfo->d_name);
887 ret = callback (callback_cls, name);
888 if (GNUNET_OK != ret)
889 {
890 closedir (dinfo);
892 GNUNET_free (dname);
893 if (GNUNET_NO == ret)
894 return count;
895 return GNUNET_SYSERR;
896 }
897 }
898 count++;
899 }
900 closedir (dinfo);
902 GNUNET_free (dname);
903 return count;
904}
905
906
916static bool
917glob_match (const char *pattern, const char *str)
918{
919 /* Position in the input string */
920 const char *str_pos = str;
921 /* Position in the pattern */
922 const char *pat_pos = pattern;
923 /* Backtrack position in string */
924 const char *str_bt = NULL;
925 /* Backtrack position in pattern */
926 const char *pat_bt = NULL;
927
928 for (;;)
929 {
930 if (*pat_pos == '*')
931 {
932 str_bt = str_pos;
933 pat_bt = pat_pos++;
934 }
935 else if (*pat_pos == *str_pos)
936 {
937 if ('\0' == *pat_pos)
938 return true;
939 str_pos++;
940 pat_pos++;
941 }
942 else
943 {
944 if (NULL == str_bt)
945 return false;
946 /* Backtrack to match one more
947 character as part of the asterisk. */
948 str_pos = str_bt + 1;
949 if ('\0' == *str_pos)
950 return false;
951 pat_pos = pat_bt;
952 }
953 }
954}
955
956
958{
959 const char *glob;
961 void *cls;
962
966 int nres;
967};
968
979glob_cb (void *cls,
980 const char *filename)
981{
982 struct GlobClosure *gc = cls;
983 const char *fn;
984
985 fn = strrchr (filename, DIR_SEPARATOR);
986 fn = (NULL == fn) ? filename : (fn + 1);
987
989 "checking glob '%s' against '%s'\n",
990 gc->glob,
991 fn);
992
993 if (glob_match (gc->glob, fn))
994 {
995 enum GNUNET_GenericReturnValue cbret;
996
998 "found glob match '%s'\n",
999 filename);
1000 gc->nres++;
1001 cbret = gc->cb (gc->cls, filename);
1002 if (GNUNET_OK != cbret)
1003 return cbret;
1004 }
1005 return GNUNET_OK;
1006}
1007
1008
1009int
1010GNUNET_DISK_glob (const char *glob_pattern,
1011 GNUNET_FileNameCallback callback,
1012 void *callback_cls)
1013{
1014 char *mypat = GNUNET_strdup (glob_pattern);
1015 char *sep;
1016 int ret;
1017
1018 if ( (NULL != strrchr (glob_pattern, '+')) ||
1019 (NULL != strrchr (glob_pattern, '[')) ||
1020 (NULL != strrchr (glob_pattern, '+')) ||
1021 (NULL != strrchr (glob_pattern, '~')) )
1022 {
1024 "unsupported glob pattern: '%s'\n",
1025 glob_pattern);
1026 GNUNET_free (mypat);
1027 return -1;
1028 }
1029
1030 sep = strrchr (mypat, DIR_SEPARATOR);
1031 if (NULL == sep)
1032 {
1033 GNUNET_free (mypat);
1034 return -1;
1035 }
1036
1037 *sep = '\0';
1038
1039 if (NULL != strchr (mypat, '*'))
1040 {
1041 GNUNET_free (mypat);
1042 GNUNET_break (0);
1044 "glob pattern may only contain '*' in the final path component\n");
1045 return -1;
1046 }
1047
1048 {
1049 struct GlobClosure gc = {
1050 .glob = sep + 1,
1051 .cb = callback,
1052 .cls = callback_cls,
1053 .nres = 0,
1054 };
1056 "scanning directory '%s' for glob matches on '%s'\n",
1057 mypat,
1058 gc.glob);
1060 glob_cb,
1061 &gc
1062 );
1063 GNUNET_free (mypat);
1064 return (ret < 0) ? ret : gc.nres;
1065 }
1066}
1067
1068
1077static enum GNUNET_GenericReturnValue
1078remove_helper (void *unused,
1079 const char *fn)
1080{
1081 (void) unused;
1082 (void) GNUNET_DISK_directory_remove (fn);
1083 return GNUNET_OK;
1084}
1085
1086
1089{
1090 struct stat istat;
1091
1092 if (NULL == filename)
1093 {
1094 GNUNET_break (0);
1095 return GNUNET_SYSERR;
1096 }
1097 if (0 != lstat (filename, &istat))
1098 return GNUNET_NO; /* file may not exist... */
1099 (void) chmod (filename,
1100 S_IWUSR | S_IRUSR | S_IXUSR);
1101 if (0 == unlink (filename))
1102 return GNUNET_OK;
1103 if ( (errno != EISDIR) &&
1104 /* EISDIR is not sufficient in all cases, e.g.
1105 * sticky /tmp directory may result in EPERM on BSD.
1106 * So we also explicitly check "isDirectory" */
1107 (GNUNET_YES !=
1109 GNUNET_YES)) )
1110 {
1112 return GNUNET_SYSERR;
1113 }
1114 if (GNUNET_SYSERR ==
1116 return GNUNET_SYSERR;
1117 if (0 != rmdir (filename))
1118 {
1120 return GNUNET_SYSERR;
1121 }
1122 return GNUNET_OK;
1123}
1124
1125
1127GNUNET_DISK_file_copy (const char *src,
1128 const char *dst)
1129{
1130 char *buf;
1131 uint64_t pos;
1132 uint64_t size;
1133 size_t len;
1134 ssize_t sret;
1135 struct GNUNET_DISK_FileHandle *in;
1136 struct GNUNET_DISK_FileHandle *out;
1137
1139 {
1141 return GNUNET_SYSERR;
1142 }
1143 pos = 0;
1144 in =
1146 if (! in)
1147 {
1149 return GNUNET_SYSERR;
1150 }
1151 out =
1159 if (! out)
1160 {
1163 return GNUNET_SYSERR;
1164 }
1166 while (pos < size)
1167 {
1168 len = COPY_BLK_SIZE;
1169 if (len > size - pos)
1170 len = size - pos;
1171 sret = GNUNET_DISK_file_read (in, buf, len);
1172 if ((sret < 0) || (len != (size_t) sret))
1173 goto FAIL;
1174 sret = GNUNET_DISK_file_write (out, buf, len);
1175 if ((sret < 0) || (len != (size_t) sret))
1176 goto FAIL;
1177 pos += len;
1178 }
1179 GNUNET_free (buf);
1182 return GNUNET_OK;
1183 FAIL:
1184 GNUNET_free (buf);
1187 return GNUNET_SYSERR;
1188}
1189
1190
1191void
1193{
1194 char *idx;
1195 char c;
1196
1197 for (idx = fn; *idx; idx++)
1198 {
1199 c = *idx;
1200
1201 if ((c == '/') || (c == '\\') || (c == ':') || (c == '*') || (c == '?') ||
1202 (c ==
1203 '"')
1204 ||
1205 (c == '<') || (c == '>') || (c == '|') )
1206 {
1207 *idx = '_';
1208 }
1209 }
1210}
1211
1212
1215 const char *user)
1216{
1217 struct passwd *pws;
1218
1219 pws = getpwnam (user);
1220 if (NULL == pws)
1221 {
1223 _ ("Cannot obtain information about user `%s': %s\n"),
1224 user,
1225 strerror (errno));
1226 return GNUNET_SYSERR;
1227 }
1228 if (0 != chown (filename, pws->pw_uid, pws->pw_gid))
1229 {
1231 return GNUNET_SYSERR;
1232 }
1233 return GNUNET_OK;
1234}
1235
1236
1239 enum GNUNET_DISK_OpenFlags flags,
1241{
1242 char *expfn;
1244
1245 int oflags;
1246 int mode;
1247 int fd;
1248
1249 expfn = GNUNET_STRINGS_filename_expand (fn);
1250 if (NULL == expfn)
1251 return NULL;
1252
1253 mode = 0;
1255 oflags = O_RDWR; /* note: O_RDWR is NOT always O_RDONLY | O_WRONLY */
1256 else if (flags & GNUNET_DISK_OPEN_READ)
1257 oflags = O_RDONLY;
1258 else if (flags & GNUNET_DISK_OPEN_WRITE)
1259 oflags = O_WRONLY;
1260 else
1261 {
1262 GNUNET_break (0);
1263 GNUNET_free (expfn);
1264 return NULL;
1265 }
1267 oflags |= (O_CREAT | O_EXCL);
1268 if (flags & GNUNET_DISK_OPEN_TRUNCATE)
1269 oflags |= O_TRUNC;
1270 if (flags & GNUNET_DISK_OPEN_APPEND)
1271 oflags |= O_APPEND;
1272 if (GNUNET_NO == GNUNET_DISK_file_test (fn))
1273 {
1274 if (flags & GNUNET_DISK_OPEN_CREATE)
1275 {
1277 oflags |= O_CREAT;
1278 mode = translate_unix_perms (perm);
1279 }
1280 }
1281
1282 fd = open (expfn,
1283 oflags
1284#if O_CLOEXEC
1285 | O_CLOEXEC
1286#endif
1287 | O_LARGEFILE,
1288 mode);
1289 if (fd == -1)
1290 {
1291 if (0 == (flags & GNUNET_DISK_OPEN_FAILIFEXISTS))
1293 else
1295 GNUNET_free (expfn);
1296 return NULL;
1297 }
1298
1300
1301 ret->fd = fd;
1302
1303 GNUNET_free (expfn);
1304 return ret;
1305}
1306
1307
1310{
1312
1313 if (NULL == h)
1314 {
1315 errno = EINVAL;
1316 return GNUNET_SYSERR;
1317 }
1318
1319 ret = GNUNET_OK;
1320 if (0 != close (h->fd))
1321 {
1324 }
1325 GNUNET_free (h);
1326 return ret;
1327}
1328
1329
1332{
1333 struct GNUNET_DISK_FileHandle *fh;
1334
1335 if ((((off_t) -1) == lseek (fno, 0, SEEK_CUR)) && (EBADF == errno))
1336 return NULL; /* invalid FD */
1337
1338 fh = GNUNET_new (struct GNUNET_DISK_FileHandle);
1339
1340 fh->fd = fno;
1341
1342 return fh;
1343}
1344
1345
1348{
1349 int fno;
1350
1351 fno = fileno (fd);
1352 if (-1 == fno)
1353 return NULL;
1355}
1356
1357
1362{
1366 void *addr;
1367
1371 size_t len;
1372};
1373
1374
1375#ifndef MAP_FAILED
1376#define MAP_FAILED ((void *) -1)
1377#endif
1378
1379
1380void *
1382 struct GNUNET_DISK_MapHandle **m,
1383 enum GNUNET_DISK_MapType access,
1384 size_t len)
1385{
1386 int prot;
1387
1388 if (NULL == h)
1389 {
1390 errno = EINVAL;
1391 return NULL;
1392 }
1393 prot = 0;
1394 if (access & GNUNET_DISK_MAP_TYPE_READ)
1395 prot = PROT_READ;
1396 if (access & GNUNET_DISK_MAP_TYPE_WRITE)
1397 prot |= PROT_WRITE;
1399 (*m)->addr = mmap (NULL, len, prot, MAP_SHARED, h->fd, 0);
1400 GNUNET_assert (NULL != (*m)->addr);
1401 if (MAP_FAILED == (*m)->addr)
1402 {
1403 GNUNET_free (*m);
1404 return NULL;
1405 }
1406 (*m)->len = len;
1407 return (*m)->addr;
1408}
1409
1410
1413{
1415
1416 if (NULL == h)
1417 {
1418 errno = EINVAL;
1419 return GNUNET_SYSERR;
1420 }
1421 ret = munmap (h->addr, h->len) != -1 ? GNUNET_OK : GNUNET_SYSERR;
1422 GNUNET_free (h);
1423 return ret;
1424}
1425
1426
1429{
1430 if (h == NULL)
1431 {
1432 errno = EINVAL;
1433 return GNUNET_SYSERR;
1434 }
1435
1436#if ! defined(__linux__) || ! defined(GNU)
1437 return fsync (h->fd) == -1 ? GNUNET_SYSERR : GNUNET_OK;
1438#else
1439 return fdatasync (h->fd) == -1 ? GNUNET_SYSERR : GNUNET_OK;
1440#endif
1441}
1442
1443
1446{
1447 int fd[2];
1448
1449 if (-1 == pipe (fd))
1450 {
1451 int eno = errno;
1452
1454 errno = eno;
1455 return NULL;
1456 }
1457 return GNUNET_DISK_pipe_from_fd (pf, fd);
1458}
1459
1460
1463 int fd[2])
1464{
1465 struct GNUNET_DISK_PipeHandle *p;
1466 int ret = 0;
1467 int flags;
1468 int eno = 0; /* make gcc happy */
1469
1471 if (fd[0] >= 0)
1472 {
1473 p->fd[0] = GNUNET_new (struct GNUNET_DISK_FileHandle);
1474 p->fd[0]->fd = fd[0];
1475 if (0 == (GNUNET_DISK_PF_BLOCKING_READ & pf))
1476 {
1477 flags = fcntl (fd[0], F_GETFL);
1478 flags |= O_NONBLOCK;
1479 if (0 > fcntl (fd[0], F_SETFL, flags))
1480 {
1481 ret = -1;
1482 eno = errno;
1483 }
1484 }
1485 flags = fcntl (fd[0], F_GETFD);
1486 flags |= FD_CLOEXEC;
1487 if (0 > fcntl (fd[0], F_SETFD, flags))
1488 {
1489 ret = -1;
1490 eno = errno;
1491 }
1492 }
1493
1494 if (fd[1] >= 0)
1495 {
1496 p->fd[1] = GNUNET_new (struct GNUNET_DISK_FileHandle);
1497 p->fd[1]->fd = fd[1];
1498 if (0 == (GNUNET_DISK_PF_BLOCKING_WRITE & pf))
1499 {
1500 flags = fcntl (fd[1], F_GETFL);
1501 flags |= O_NONBLOCK;
1502 if (0 > fcntl (fd[1], F_SETFL, flags))
1503 {
1504 ret = -1;
1505 eno = errno;
1506 }
1507 }
1508 flags = fcntl (fd[1], F_GETFD);
1509 flags |= FD_CLOEXEC;
1510 if (0 > fcntl (fd[1], F_SETFD, flags))
1511 {
1512 ret = -1;
1513 eno = errno;
1514 }
1515 }
1516 if (ret == -1)
1517 {
1518 errno = eno;
1520 if (p->fd[0]->fd >= 0)
1521 GNUNET_break (0 == close (p->fd[0]->fd));
1522 if (p->fd[1]->fd >= 0)
1523 GNUNET_break (0 == close (p->fd[1]->fd));
1524 GNUNET_free (p->fd[0]);
1525 GNUNET_free (p->fd[1]);
1526 GNUNET_free (p);
1527 errno = eno;
1528 return NULL;
1529 }
1530 return p;
1531}
1532
1533
1537{
1539
1541 {
1542 if (p->fd[0])
1543 {
1544 ret = GNUNET_DISK_file_close (p->fd[0]);
1545 p->fd[0] = NULL;
1546 }
1547 }
1548 else if (end == GNUNET_DISK_PIPE_END_WRITE)
1549 {
1550 if (p->fd[1])
1551 {
1552 ret = GNUNET_DISK_file_close (p->fd[1]);
1553 p->fd[1] = NULL;
1554 }
1555 }
1556 return ret;
1557}
1558
1559
1563{
1564 struct GNUNET_DISK_FileHandle *ret = NULL;
1565
1567 {
1568 if (p->fd[0])
1569 {
1570 ret = p->fd[0];
1571 p->fd[0] = NULL;
1572 }
1573 }
1574 else if (end == GNUNET_DISK_PIPE_END_WRITE)
1575 {
1576 if (p->fd[1])
1577 {
1578 ret = p->fd[1];
1579 p->fd[1] = NULL;
1580 }
1581 }
1582
1583 return ret;
1584}
1585
1586
1589{
1591 enum GNUNET_GenericReturnValue read_end_close;
1592 enum GNUNET_GenericReturnValue write_end_close;
1593 int read_end_close_errno;
1594 int write_end_close_errno;
1595
1597 read_end_close_errno = errno;
1599 write_end_close_errno = errno;
1600 GNUNET_free (p);
1601
1602 if (GNUNET_OK != read_end_close)
1603 {
1604 errno = read_end_close_errno;
1605 ret = read_end_close;
1606 }
1607 else if (GNUNET_OK != write_end_close)
1608 {
1609 errno = write_end_close_errno;
1610 ret = write_end_close;
1611 }
1612
1613 return ret;
1614}
1615
1616
1617const struct GNUNET_DISK_FileHandle *
1619 enum GNUNET_DISK_PipeEnd n)
1620{
1621 switch (n)
1622 {
1625 return p->fd[n];
1626
1627 default:
1628 GNUNET_break (0);
1629 return NULL;
1630 }
1631}
1632
1633
1636 void *dst,
1637 size_t dst_len)
1638{
1639 if (NULL == fh)
1640 return GNUNET_SYSERR;
1641 if (dst_len < sizeof(int))
1642 return GNUNET_SYSERR;
1643 *((int *) 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 !=
1663 GNUNET_CONFIGURATION_get_value_filename (cfg, "PATHS", option, &tmpname))
1664 {
1666 return GNUNET_NO;
1667 }
1669 {
1671 GNUNET_free (tmpname);
1672 return GNUNET_OK;
1673 }
1674 GNUNET_free (tmpname);
1675 return GNUNET_OK;
1676}
1677
1678
1679void
1681 const char *option)
1682{
1686 (void *) option));
1687}
1688
1689
1690/* 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:979
#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:444
#define S_ISLNK(m)
Definition: disk.c:61
#define MAP_FAILED
Definition: disk.c:1376
static bool glob_match(const char *pattern, const char *str)
Check for a simple wildcard match.
Definition: disk.c:917
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
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:1635
#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:1078
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 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:1618
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:1238
void GNUNET_DISK_filename_canonicalize(char *fn)
Removes special characters as ':' from a filename.
Definition: disk.c:1192
int GNUNET_DISK_glob(const char *glob_pattern, GNUNET_FileNameCallback callback, void *callback_cls)
Find all files matching a glob pattern.
Definition: disk.c:1010
enum GNUNET_GenericReturnValue GNUNET_DISK_file_change_owner(const char *filename, const char *user)
Change owner of a file.
Definition: disk.c:1214
char * GNUNET_DISK_mktemp(const char *t)
Create an (empty) temporary file on disk.
Definition: disk.c:381
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:483
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
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:1561
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:1462
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:687
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:637
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:1680
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:1445
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:490
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:1588
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:726
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:1127
enum GNUNET_GenericReturnValue GNUNET_DISK_directory_remove(const char *filename)
Remove all files in a directory (rm -rf).
Definition: disk.c:1088
enum GNUNET_GenericReturnValue GNUNET_DISK_file_sync(const struct GNUNET_DISK_FileHandle *h)
Write file changes to disk.
Definition: disk.c:1428
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:404
enum GNUNET_GenericReturnValue GNUNET_DISK_file_close(struct GNUNET_DISK_FileHandle *h)
Close an open file.
Definition: disk.c:1309
struct GNUNET_DISK_FileHandle * GNUNET_DISK_get_handle_from_native(FILE *fd)
Get a handle from a native FD.
Definition: disk.c:1347
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:360
enum GNUNET_GenericReturnValue GNUNET_DISK_directory_create_for_file(const char *filename)
Create the directory structure for storing a file.
Definition: disk.c:583
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:1381
struct GNUNET_DISK_FileHandle * GNUNET_DISK_get_handle_from_int_fd(int fno)
Get a handle from a native integer FD.
Definition: disk.c:1331
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:623
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:1535
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:702
enum GNUNET_GenericReturnValue GNUNET_DISK_file_unmap(struct GNUNET_DISK_MapHandle *h)
Unmap a file.
Definition: disk.c:1412
enum GNUNET_GenericReturnValue GNUNET_DISK_directory_create(const char *dir)
Implementation of "mkdir -p".
Definition: disk.c:497
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:665
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:815
@ 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:1362
void * addr
Address where the map is in memory.
Definition: disk.c:1366
size_t len
Number of bytes mapped.
Definition: disk.c:1371
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
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:960
void * cls
Definition: disk.c:961
int nres
Number of files that actually matched the glob pattern.
Definition: disk.c:966
const char * glob
Definition: disk.c:959