GNUnet 0.26.2-16-ge86b66bd5
 
Loading...
Searching...
No Matches
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
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_NO))
174 {
175 char linkdst[PATH_MAX];
176 if (NULL == realpath (fn, linkdst))
177 {
179 return GNUNET_SYSERR;
180 }
181 return get_size_rec (gfsd, linkdst);
182 }
183 if ((! S_ISLNK (buf.st_mode)) || (gfsd->include_sym_links == GNUNET_YES))
184 gfsd->total += buf.st_size;
185 if ((S_ISDIR (buf.st_mode)) && (0 == access (fn, X_OK)) &&
186 ((! S_ISLNK (buf.st_mode)) || (gfsd->include_sym_links == GNUNET_YES)))
187 {
188 if (GNUNET_SYSERR ==
191 gfsd))
192 return GNUNET_SYSERR;
193 }
194 return GNUNET_OK;
195}
196
197
200{
201 return ((! h) || (h->fd == -1)) ? GNUNET_YES : GNUNET_NO;
202}
203
204
207 off_t *size)
208{
209 struct stat sbuf;
210
211 if (0 != fstat (fh->fd, &sbuf))
212 return GNUNET_SYSERR;
213 *size = sbuf.st_size;
214 return GNUNET_OK;
215}
216
217
218off_t
220 off_t offset,
221 enum GNUNET_DISK_Seek whence)
222{
223 static int t[] = { SEEK_SET, SEEK_CUR, SEEK_END };
224
225 if (h == NULL)
226 {
227 errno = EINVAL;
228 return GNUNET_SYSERR;
229 }
230 return lseek (h->fd, offset, t[whence]);
231}
232
233
236 uint64_t *size,
237 int include_symbolic_links,
238 int single_file_mode)
239{
240 struct GetFileSizeData gfsd;
242
243 GNUNET_assert (size != NULL);
244 gfsd.total = 0;
245 gfsd.include_sym_links = include_symbolic_links;
247 ret = get_size_rec (&gfsd, filename);
248 *size = gfsd.total;
249 return ret;
250}
251
252
255 uint64_t *dev,
256 uint64_t *ino)
257{
258#if HAVE_STAT
259 {
260 struct stat sbuf;
261
262 if (0 != stat (filename, &sbuf))
263 {
264 return GNUNET_SYSERR;
265 }
266 *ino = (uint64_t) sbuf.st_ino;
267 }
268#else
269 *ino = 0;
270#endif
271#if HAVE_STATVFS
272 {
273 struct statvfs fbuf;
274
275 if (0 != statvfs (filename, &fbuf))
276 {
277 return GNUNET_SYSERR;
278 }
279 *dev = (uint64_t) fbuf.f_fsid;
280 }
281#elif HAVE_STATFS
282 {
283 struct statfs fbuf;
284
285 if (0 != statfs (filename, &fbuf))
286 {
287 return GNUNET_SYSERR;
288 }
289 *dev =
290 ((uint64_t) fbuf.f_fsid.val[0]) << 32 || ((uint64_t) fbuf.f_fsid.val[1]);
291 }
292#else
293 *dev = 0;
294#endif
295 return GNUNET_OK;
296}
297
298
305static char *
306mktemp_name (const char *t)
307{
308 const char *tmpdir;
309 char *tmpl;
310 char *fn;
311
312 if ((t[0] != '/') && (t[0] != '\\'))
313 {
314 /* FIXME: This uses system codepage on W32, not UTF-8 */
315 tmpdir = getenv ("TMPDIR");
316 if (NULL == tmpdir)
317 tmpdir = getenv ("TMP");
318 if (NULL == tmpdir)
319 tmpdir = getenv ("TEMP");
320 if (NULL == tmpdir)
321 tmpdir = "/tmp";
322 GNUNET_asprintf (&tmpl, "%s/%s%s", tmpdir, t, "XXXXXX");
323 }
324 else
325 {
326 GNUNET_asprintf (&tmpl, "%s%s", t, "XXXXXX");
327 }
328 fn = tmpl;
329 return fn;
330}
331
332
333void
335 int require_uid_match,
336 int require_gid_match)
337{
338 mode_t mode;
339
340 if (GNUNET_YES == require_uid_match)
341 mode = S_IRUSR | S_IWUSR | S_IXUSR;
342 else if (GNUNET_YES == require_gid_match)
343 mode = S_IRUSR | S_IWUSR | S_IXUSR | S_IRGRP | S_IWGRP | S_IXGRP;
344 else
345 mode = S_IRUSR | S_IWUSR | S_IXUSR | S_IRGRP | S_IWGRP | S_IXGRP | S_IROTH
346 | S_IWOTH | S_IXOTH;
347 if (0 != chmod (fn, mode))
349}
350
351
352char *
354{
355 char *fn;
356 mode_t omask;
357
358 omask = umask (S_IWGRP | S_IWOTH | S_IRGRP | S_IROTH);
359 fn = mktemp_name (t);
360 if (fn != mkdtemp (fn))
361 {
363 GNUNET_free (fn);
364 umask (omask);
365 return NULL;
366 }
367 umask (omask);
368 return fn;
369}
370
371
372char *
373GNUNET_DISK_file_backup (const char *fil)
374{
375 size_t slen;
376 char *target;
377 unsigned int num;
378
379 slen = strlen (fil) + 20;
380 target = GNUNET_malloc (slen);
381 num = 0;
382
383#if HAVE_RENAMEAT2
384 {
385 int fd;
386
387 do
388 {
389 GNUNET_snprintf (target,
390 slen,
391 "%s.%u~",
392 fil,
393 num++);
394 fd = open (target,
395 O_CREAT | O_EXCL,
397 } while (-1 == fd);
398 if (0 != renameat2 (AT_FDCWD,
399 fil,
400 AT_FDCWD,
401 target,
402 RENAME_EXCHANGE))
403 {
405 "renameat2",
406 fil);
407 GNUNET_break (0 ==
408 close (fd));
409 return NULL;
410 }
411 GNUNET_break (0 ==
412 close (fd));
413 }
414#else
415 do
416 {
417 GNUNET_snprintf (target,
418 slen,
419 "%s.%u~",
420 fil,
421 num++);
422 }
423 while (0 == access (target,
424 F_OK));
425 if (0 != rename (fil,
426 target))
427 {
429 "rename",
430 fil);
431 return NULL;
432 }
433#endif
434 return target;
435}
436
437
438char *
440{
441 int fd;
442 char *fn;
443 mode_t omask;
444
445 omask = umask (S_IWGRP | S_IWOTH | S_IRGRP | S_IROTH);
446 fn = mktemp_name (t);
447 if (-1 == (fd = mkstemp (fn)))
448 {
450 "mkstemp",
451 fn);
452 GNUNET_free (fn);
453 umask (omask);
454 return NULL;
455 }
456 umask (omask);
457 if (0 != close (fd))
459 "close",
460 fn);
461 return fn;
462}
463
464
467 int is_readable)
468{
469 struct stat filestat;
470 int ret;
471
472 ret = stat (fil, &filestat);
473 if (ret != 0)
474 {
475 if (errno != ENOENT)
477 "stat",
478 fil);
479 return GNUNET_SYSERR;
480 }
481 if (! S_ISDIR (filestat.st_mode))
482 {
484 "A file already exits with the same name %s\n",
485 fil);
486 return GNUNET_NO;
487 }
488 if (GNUNET_YES == is_readable)
489 ret = access (fil,
490 R_OK | X_OK);
491 else
492 ret = access (fil,
493 X_OK);
494 if (ret < 0)
495 {
497 "access",
498 fil);
499 return GNUNET_NO;
500 }
501 return GNUNET_YES;
502}
503
504
513file_test_internal (const char *fil,
514 int amode)
515{
516 struct stat filestat;
517 int ret;
518 char *rdir;
519
521 if (rdir == NULL)
522 return GNUNET_SYSERR;
523
524 ret = stat (rdir, &filestat);
525 if (0 != ret)
526 {
527 if (errno != ENOENT)
528 {
530 "stat",
531 rdir);
532 GNUNET_free (rdir);
533 return GNUNET_SYSERR;
534 }
535 GNUNET_free (rdir);
536 return GNUNET_NO;
537 }
538 if (! S_ISREG (filestat.st_mode))
539 {
540 GNUNET_free (rdir);
541 return GNUNET_NO;
542 }
543 if (access (rdir, amode) < 0)
544 {
546 "access",
547 rdir);
548 GNUNET_free (rdir);
549 return GNUNET_SYSERR;
550 }
551 GNUNET_free (rdir);
552 return GNUNET_YES;
553}
554
555
557GNUNET_DISK_file_test (const char *fil)
558{
559 return file_test_internal (fil,
560 F_OK);
561}
562
563
566{
567 return file_test_internal (fil,
568 R_OK);
569}
570
571
574{
575 char *rdir;
576 unsigned int len;
577 unsigned int pos;
578 unsigned int pos2;
579 int ret = GNUNET_OK;
580
582 if (rdir == NULL)
583 {
584 GNUNET_break (0);
585 return GNUNET_SYSERR;
586 }
587
588 len = strlen (rdir);
589
590 pos = 1; /* skip heading '/' */
591
592 /* Check which low level directories already exist */
593 pos2 = len;
594 rdir[len] = DIR_SEPARATOR;
595 while (pos <= pos2)
596 {
597 if (DIR_SEPARATOR == rdir[pos2])
598 {
599 rdir[pos2] = '\0';
601 GNUNET_NO);
602 if (GNUNET_NO == ret)
603 {
605 "Creating directory `%s' failed\n",
606 rdir);
607 GNUNET_free (rdir);
608 return GNUNET_SYSERR;
609 }
610 rdir[pos2] = DIR_SEPARATOR;
611 if (GNUNET_YES == ret)
612 {
613 pos2++;
614 break;
615 }
616 }
617 pos2--;
618 }
619 rdir[len] = '\0';
620 if (pos < pos2)
621 pos = pos2;
622 /* Start creating directories */
623 while (pos <= len)
624 {
625 if ( (rdir[pos] == DIR_SEPARATOR) ||
626 (pos == len) )
627 {
628 rdir[pos] = '\0';
630 GNUNET_NO);
631 if (GNUNET_NO == ret)
632 {
634 "Creating directory `%s' failed\n",
635 rdir);
636 GNUNET_free (rdir);
637 return GNUNET_SYSERR;
638 }
639 if (GNUNET_SYSERR == ret)
640 {
641 ret = mkdir (rdir,
642 S_IRUSR | S_IWUSR | S_IXUSR | S_IRGRP | S_IXGRP | S_IROTH
643 | S_IXOTH); /* 755 */
644
645 if ((ret != 0) && (errno != EEXIST))
646 {
648 "mkdir",
649 rdir);
650 GNUNET_free (rdir);
651 return GNUNET_SYSERR;
652 }
653 }
654 rdir[pos] = DIR_SEPARATOR;
655 }
656 pos++;
657 }
658 GNUNET_free (rdir);
659 return GNUNET_OK;
660}
661
662
665{
666 char *rdir;
667 size_t len;
668 int eno;
670
672 if (NULL == rdir)
673 {
674 errno = EINVAL;
675 return GNUNET_SYSERR;
676 }
677 if (0 == access (rdir, W_OK))
678 {
679 GNUNET_free (rdir);
680 return GNUNET_OK;
681 }
682 len = strlen (rdir);
683 while ((len > 0) && (rdir[len] != DIR_SEPARATOR))
684 len--;
685 rdir[len] = '\0';
686 /* The empty path is invalid and in this case refers to / */
687 if (0 == len)
688 {
689 GNUNET_free (rdir);
690 rdir = GNUNET_strdup ("/");
691 }
693 if ( (GNUNET_OK == res) &&
694 (0 != access (rdir, W_OK)) )
695 res = GNUNET_NO;
696 eno = errno;
697 GNUNET_free (rdir);
698 errno = eno;
699 return res;
700}
701
702
703ssize_t
705 void *result,
706 size_t len)
707{
708 if (NULL == h)
709 {
710 errno = EINVAL;
711 return GNUNET_SYSERR;
712 }
713 return read (h->fd,
714 result,
715 len);
716}
717
718
719ssize_t
720GNUNET_DISK_fn_read (const char *fn,
721 void *result,
722 size_t len)
723{
724 struct GNUNET_DISK_FileHandle *fh;
725 ssize_t ret;
726 int eno;
727
728 fh = GNUNET_DISK_file_open (fn,
731 if (NULL == fh)
732 return GNUNET_SYSERR;
734 result,
735 len);
736 eno = errno;
739 errno = eno;
740 return ret;
741}
742
743
744ssize_t
746 const void *buffer,
747 size_t n)
748{
749 if (NULL == h)
750 {
751 errno = EINVAL;
752 return GNUNET_SYSERR;
753 }
754 return write (h->fd,
755 buffer,
756 n);
757}
758
759
760ssize_t
762 const void *buffer,
763 size_t n)
764{
765 int flags;
766 ssize_t ret;
767
768 if (NULL == h)
769 {
770 errno = EINVAL;
771 return GNUNET_SYSERR;
772 }
773 /* set to blocking, write, then set back */
774 flags = fcntl (h->fd,
775 F_GETFL);
776 if (0 != (flags & O_NONBLOCK))
777 (void) fcntl (h->fd,
778 F_SETFL,
779 flags - O_NONBLOCK);
780 ret = write (h->fd,
781 buffer,
782 n);
783 if (0 == (flags & O_NONBLOCK))
784 (void) fcntl (h->fd,
785 F_SETFL,
786 flags);
787 return ret;
788}
789
790
792GNUNET_DISK_fn_write (const char *fn,
793 const void *buf,
794 size_t buf_size,
796{
797 char *tmpl;
798 int fd;
799
800 if (GNUNET_OK !=
802 {
804 "mkstemp",
805 fn);
806 return GNUNET_SYSERR;
807 }
808 {
809 char *dname;
810
811 dname = GNUNET_strdup (fn);
812 GNUNET_asprintf (&tmpl,
813 "%s/XXXXXX",
814 dirname (dname));
815 GNUNET_free (dname);
816 }
817 fd = mkstemp (tmpl);
818 if (-1 == fd)
819 {
821 "mkstemp",
822 tmpl);
823 GNUNET_free (tmpl);
824 return GNUNET_SYSERR;
825 }
826
827 if (0 != fchmod (fd,
829 {
831 "chmod",
832 tmpl);
833 GNUNET_assert (0 == close (fd));
834 if (0 != unlink (tmpl))
836 "unlink",
837 tmpl);
838 GNUNET_free (tmpl);
839 return GNUNET_SYSERR;
840 }
841 if (buf_size !=
842 write (fd,
843 buf,
844 buf_size))
845 {
847 "write",
848 tmpl);
849 GNUNET_assert (0 == close (fd));
850 if (0 != unlink (tmpl))
852 "unlink",
853 tmpl);
854 GNUNET_free (tmpl);
855 return GNUNET_SYSERR;
856 }
857 GNUNET_assert (0 == close (fd));
858
859 if (0 != link (tmpl,
860 fn))
861 {
862 if (0 != unlink (tmpl))
864 "unlink",
865 tmpl);
866 GNUNET_free (tmpl);
867 return GNUNET_NO;
868 }
869 if (0 != unlink (tmpl))
871 "unlink",
872 tmpl);
873 GNUNET_free (tmpl);
874 return GNUNET_OK;
875
876
877}
878
879
880int
883 void *callback_cls)
884{
885 DIR *dinfo;
886 struct dirent *finfo;
887 int count = 0;
889 char *name;
890 char *dname;
891 unsigned int name_len;
892 unsigned int n_size;
893
894 GNUNET_assert (NULL != dir_name);
896 if (NULL == dname)
897 return GNUNET_SYSERR;
898 while ( (strlen (dname) > 0) &&
899 (dname[strlen (dname) - 1] == DIR_SEPARATOR) )
900 dname[strlen (dname) - 1] = '\0';
901 dinfo = opendir (dname);
902 if (NULL == dinfo)
903 {
905 "opendir",
906 dname);
907 GNUNET_free (dname);
908 return GNUNET_SYSERR;
909 }
910 name_len = 256;
911 n_size = strlen (dname) + name_len + strlen (DIR_SEPARATOR_STR) + 1;
912 name = GNUNET_malloc (n_size);
913 while (NULL != (finfo = readdir (dinfo)))
914 {
915 if ((0 == strcmp (finfo->d_name, ".")) ||
916 (0 == strcmp (finfo->d_name, "..")))
917 continue;
918 if (NULL != callback)
919 {
920 if (name_len < strlen (finfo->d_name))
921 {
923 name_len = strlen (finfo->d_name);
924 n_size = strlen (dname) + name_len + strlen (DIR_SEPARATOR_STR) + 1;
925 name = GNUNET_malloc (n_size);
926 }
927 /* dname can end in "/" only if dname == "/";
928 * if dname does not end in "/", we need to add
929 * a "/" (otherwise, we must not!) */
931 n_size,
932 "%s%s%s",
933 dname,
934 (0 == strcmp (dname,
936 ? ""
938 finfo->d_name);
939 ret = callback (callback_cls,
940 name);
941 if (GNUNET_OK != ret)
942 {
943 closedir (dinfo);
945 GNUNET_free (dname);
946 if (GNUNET_NO == ret)
947 return count;
948 return GNUNET_SYSERR;
949 }
950 }
951 count++;
952 }
953 closedir (dinfo);
955 GNUNET_free (dname);
956 return count;
957}
958
959
969static bool
970glob_match (const char *pattern, const char *str)
971{
972 /* Position in the input string */
973 const char *str_pos = str;
974 /* Position in the pattern */
975 const char *pat_pos = pattern;
976 /* Backtrack position in string */
977 const char *str_bt = NULL;
978 /* Backtrack position in pattern */
979 const char *pat_bt = NULL;
980
981 for (;;)
982 {
983 if (*pat_pos == '*')
984 {
985 str_bt = str_pos;
986 pat_bt = pat_pos++;
987 }
988 else if (*pat_pos == *str_pos)
989 {
990 if ('\0' == *pat_pos)
991 return true;
992 str_pos++;
993 pat_pos++;
994 }
995 else
996 {
997 if (NULL == str_bt)
998 return false;
999 /* Backtrack to match one more
1000 character as part of the asterisk. */
1001 str_pos = str_bt + 1;
1002 if ('\0' == *str_pos)
1003 return false;
1004 pat_pos = pat_bt;
1005 }
1006 }
1007}
1008
1009
1011{
1012 const char *glob;
1014 void *cls;
1015
1019 int nres;
1020};
1021
1031static enum GNUNET_GenericReturnValue
1032glob_cb (void *cls,
1033 const char *filename)
1034{
1035 struct GlobClosure *gc = cls;
1036 const char *fn;
1037
1038 fn = strrchr (filename, DIR_SEPARATOR);
1039 fn = (NULL == fn) ? filename : (fn + 1);
1040
1042 "checking glob '%s' against '%s'\n",
1043 gc->glob,
1044 fn);
1045
1046 if (glob_match (gc->glob, fn))
1047 {
1048 enum GNUNET_GenericReturnValue cbret;
1049
1051 "found glob match '%s'\n",
1052 filename);
1053 gc->nres++;
1054 cbret = gc->cb (gc->cls, filename);
1055 if (GNUNET_OK != cbret)
1056 return cbret;
1057 }
1058 return GNUNET_OK;
1059}
1060
1061
1062int
1063GNUNET_DISK_glob (const char *glob_pattern,
1064 GNUNET_FileNameCallback callback,
1065 void *callback_cls)
1066{
1067 char *mypat = GNUNET_strdup (glob_pattern);
1068 char *sep;
1069 int ret;
1070
1071 if ( (NULL != strrchr (glob_pattern, '+')) ||
1072 (NULL != strrchr (glob_pattern, '[')) ||
1073 (NULL != strrchr (glob_pattern, '~')) )
1074 {
1076 "unsupported glob pattern: '%s'\n",
1077 glob_pattern);
1078 GNUNET_free (mypat);
1079 return -1;
1080 }
1081
1082 sep = strrchr (mypat, DIR_SEPARATOR);
1083 if (NULL == sep)
1084 {
1085 GNUNET_free (mypat);
1086 return -1;
1087 }
1088
1089 *sep = '\0';
1090
1091 if (NULL != strchr (mypat, '*'))
1092 {
1093 GNUNET_free (mypat);
1094 GNUNET_break (0);
1096 "glob pattern may only contain '*' in the final path component\n");
1097 return -1;
1098 }
1099
1100 {
1101 struct GlobClosure gc = {
1102 .glob = sep + 1,
1103 .cb = callback,
1104 .cls = callback_cls,
1105 .nres = 0,
1106 };
1108 "scanning directory '%s' for glob matches on '%s'\n",
1109 mypat,
1110 gc.glob);
1112 glob_cb,
1113 &gc
1114 );
1115 GNUNET_free (mypat);
1116 return (ret < 0) ? ret : gc.nres;
1117 }
1118}
1119
1120
1129static enum GNUNET_GenericReturnValue
1130remove_helper (void *unused,
1131 const char *fn)
1132{
1133 (void) unused;
1134 (void) GNUNET_DISK_directory_remove (fn);
1135 return GNUNET_OK;
1136}
1137
1138
1141{
1142 struct stat istat;
1143
1144 if (NULL == filename)
1145 {
1146 GNUNET_break (0);
1147 return GNUNET_SYSERR;
1148 }
1149 if (0 != lstat (filename, &istat))
1150 return GNUNET_NO; /* file may not exist... */
1151 (void) chmod (filename,
1152 S_IWUSR | S_IRUSR | S_IXUSR);
1153 if (0 == unlink (filename))
1154 return GNUNET_OK;
1155 if ( (errno != EISDIR) &&
1156 /* EISDIR is not sufficient in all cases, e.g.
1157 * sticky /tmp directory may result in EPERM on BSD.
1158 * So we also explicitly check "isDirectory" */
1159 (GNUNET_YES !=
1161 GNUNET_YES)) )
1162 {
1164 "rmdir",
1165 filename);
1166 return GNUNET_SYSERR;
1167 }
1168 if (GNUNET_SYSERR ==
1171 NULL))
1172 return GNUNET_SYSERR;
1173 if (0 != rmdir (filename))
1174 {
1176 "rmdir",
1177 filename);
1178 return GNUNET_SYSERR;
1179 }
1180 return GNUNET_OK;
1181}
1182
1183
1185GNUNET_DISK_file_copy (const char *src,
1186 const char *dst)
1187{
1188 char *buf;
1189 uint64_t pos;
1190 uint64_t size;
1191 size_t len;
1192 ssize_t sret;
1193 struct GNUNET_DISK_FileHandle *in;
1194 struct GNUNET_DISK_FileHandle *out;
1195
1196 if (GNUNET_OK !=
1198 &size,
1199 GNUNET_YES,
1200 GNUNET_YES))
1201 {
1203 "stat",
1204 src);
1205 return GNUNET_SYSERR;
1206 }
1207 pos = 0;
1208 in =
1212 if (! in)
1213 {
1215 return GNUNET_SYSERR;
1216 }
1217 out =
1225 if (! out)
1226 {
1229 return GNUNET_SYSERR;
1230 }
1232 while (pos < size)
1233 {
1234 len = COPY_BLK_SIZE;
1235 if (len > size - pos)
1236 len = size - pos;
1237 sret = GNUNET_DISK_file_read (in, buf, len);
1238 if ((sret < 0) || (len != (size_t) sret))
1239 goto FAIL;
1240 sret = GNUNET_DISK_file_write (out, buf, len);
1241 if ((sret < 0) || (len != (size_t) sret))
1242 goto FAIL;
1243 pos += len;
1244 }
1245 GNUNET_free (buf);
1250 return GNUNET_OK;
1251FAIL:
1252 GNUNET_free (buf);
1257 return GNUNET_SYSERR;
1258}
1259
1260
1261void
1263{
1264 char *idx;
1265 char c;
1266
1267 for (idx = fn; *idx; idx++)
1268 {
1269 c = *idx;
1270
1271 if ((c == '/') || (c == '\\') || (c == ':') || (c == '*') || (c == '?') ||
1272 (c ==
1273 '"')
1274 ||
1275 (c == '<') || (c == '>') || (c == '|') )
1276 {
1277 *idx = '_';
1278 }
1279 }
1280}
1281
1282
1285 const char *user)
1286{
1287 struct passwd *pws;
1288
1289 pws = getpwnam (user);
1290 if (NULL == pws)
1291 {
1293 _ ("Cannot obtain information about user `%s': %s\n"),
1294 user,
1295 strerror (errno));
1296 return GNUNET_SYSERR;
1297 }
1298 if (0 != chown (filename, pws->pw_uid, pws->pw_gid))
1299 {
1301 return GNUNET_SYSERR;
1302 }
1303 return GNUNET_OK;
1304}
1305
1306
1309 enum GNUNET_DISK_OpenFlags flags,
1311{
1312 char *expfn;
1314
1315 int oflags;
1316 int mode;
1317 int fd;
1318
1319 expfn = GNUNET_STRINGS_filename_expand (fn);
1320 if (NULL == expfn)
1321 return NULL;
1322
1323 mode = 0;
1325 oflags = O_RDWR; /* note: O_RDWR is NOT always O_RDONLY | O_WRONLY */
1326 else if (flags & GNUNET_DISK_OPEN_READ)
1327 oflags = O_RDONLY;
1328 else if (flags & GNUNET_DISK_OPEN_WRITE)
1329 oflags = O_WRONLY;
1330 else
1331 {
1332 GNUNET_break (0);
1333 GNUNET_free (expfn);
1334 return NULL;
1335 }
1337 oflags |= (O_CREAT | O_EXCL);
1338 if (flags & GNUNET_DISK_OPEN_TRUNCATE)
1339 oflags |= O_TRUNC;
1340 if (flags & GNUNET_DISK_OPEN_APPEND)
1341 oflags |= O_APPEND;
1342 if (GNUNET_NO == GNUNET_DISK_file_test (fn))
1343 {
1344 if (flags & GNUNET_DISK_OPEN_CREATE)
1345 {
1347 oflags |= O_CREAT;
1348 mode = translate_unix_perms (perm);
1349 }
1350 }
1351
1352 // Setting O_CLOEXEC after pipe() may introduce
1353 // race conditions: https://bugs.gnunet.org/view.php?id=9311
1354 // This is no problem if the platform supports pipe2
1355 fd = open (expfn,
1356 oflags
1357#if O_CLOEXEC
1358 | O_CLOEXEC
1359#endif
1360 | O_LARGEFILE,
1361 mode);
1362 if (fd == -1)
1363 {
1364 if (0 == (flags & GNUNET_DISK_OPEN_FAILIFEXISTS))
1366 "open",
1367 expfn);
1368 else
1370 "open",
1371 expfn);
1372 GNUNET_free (expfn);
1373 return NULL;
1374 }
1375
1377
1378 ret->fd = fd;
1379
1380 GNUNET_free (expfn);
1381 return ret;
1382}
1383
1384
1387{
1389
1390 if (NULL == h)
1391 {
1392 errno = EINVAL;
1393 return GNUNET_SYSERR;
1394 }
1395
1396 ret = GNUNET_OK;
1397 if (0 != close (h->fd))
1398 {
1400 "close");
1402 }
1403 GNUNET_free (h);
1404 return ret;
1405}
1406
1407
1410{
1411 struct GNUNET_DISK_FileHandle *fh;
1412
1413 if ((((off_t) -1) == lseek (fno, 0, SEEK_CUR)) && (EBADF == errno))
1414 return NULL; /* invalid FD */
1415
1416 fh = GNUNET_new (struct GNUNET_DISK_FileHandle);
1417
1418 fh->fd = fno;
1419
1420 return fh;
1421}
1422
1423
1426{
1427 int fno;
1428
1429 fno = fileno (fd);
1430 if (-1 == fno)
1431 return NULL;
1433}
1434
1435
1440{
1444 void *addr;
1445
1449 size_t len;
1450};
1451
1452
1453#ifndef MAP_FAILED
1454#define MAP_FAILED ((void *) -1)
1455#endif
1456
1457
1458void *
1460 struct GNUNET_DISK_MapHandle **m,
1461 enum GNUNET_DISK_MapType access,
1462 size_t len)
1463{
1464 int prot;
1465
1466 if (NULL == h)
1467 {
1468 errno = EINVAL;
1469 return NULL;
1470 }
1471 prot = 0;
1472 if (access & GNUNET_DISK_MAP_TYPE_READ)
1473 prot = PROT_READ;
1474 if (access & GNUNET_DISK_MAP_TYPE_WRITE)
1475 prot |= PROT_WRITE;
1477 (*m)->addr = mmap (NULL, len, prot, MAP_SHARED, h->fd, 0);
1478 GNUNET_assert (NULL != (*m)->addr);
1479 if (MAP_FAILED == (*m)->addr)
1480 {
1481 GNUNET_free (*m);
1482 return NULL;
1483 }
1484 (*m)->len = len;
1485 return (*m)->addr;
1486}
1487
1488
1491{
1493
1494 if (NULL == h)
1495 {
1496 errno = EINVAL;
1497 return GNUNET_SYSERR;
1498 }
1499 ret = munmap (h->addr, h->len) != -1 ? GNUNET_OK : GNUNET_SYSERR;
1500 GNUNET_free (h);
1501 return ret;
1502}
1503
1504
1507{
1508 if (h == NULL)
1509 {
1510 errno = EINVAL;
1511 return GNUNET_SYSERR;
1512 }
1513
1514#if ! defined(__linux__) || ! defined(GNU)
1515 return fsync (h->fd) == -1 ? GNUNET_SYSERR : GNUNET_OK;
1516#else
1517 return fdatasync (h->fd) == -1 ? GNUNET_SYSERR : GNUNET_OK;
1518#endif
1519}
1520
1521
1524{
1525 int fd[2];
1526
1527#if HAVE_PIPE2 && O_CLOEXEC
1528 if (-1 == pipe2 (fd, O_CLOEXEC))
1529#else
1530 if (-1 == pipe (fd))
1531#endif
1532 {
1533 int eno = errno;
1534
1536 errno = eno;
1537 return NULL;
1538 }
1539 return GNUNET_DISK_pipe_from_fd (pf, fd);
1540}
1541
1542
1545 int fd[2])
1546{
1547 struct GNUNET_DISK_PipeHandle *p;
1548 int ret = 0;
1549 int flags;
1550 int eno = 0; /* make gcc happy */
1551
1553 if (fd[0] >= 0)
1554 {
1555 p->fd[0] = GNUNET_new (struct GNUNET_DISK_FileHandle);
1556 p->fd[0]->fd = fd[0];
1557 if (0 == (GNUNET_DISK_PF_BLOCKING_READ & pf))
1558 {
1559 flags = fcntl (fd[0], F_GETFL);
1560 flags |= O_NONBLOCK;
1561 if (0 > fcntl (fd[0], F_SETFL, flags))
1562 {
1563 ret = -1;
1564 eno = errno;
1565 }
1566 }
1567 flags = fcntl (fd[0], F_GETFD);
1568 flags |= FD_CLOEXEC;
1569 if (0 > fcntl (fd[0], F_SETFD, flags))
1570 {
1571 ret = -1;
1572 eno = errno;
1573 }
1574 }
1575
1576 if (fd[1] >= 0)
1577 {
1578 p->fd[1] = GNUNET_new (struct GNUNET_DISK_FileHandle);
1579 p->fd[1]->fd = fd[1];
1580 if (0 == (GNUNET_DISK_PF_BLOCKING_WRITE & pf))
1581 {
1582 flags = fcntl (fd[1], F_GETFL);
1583 flags |= O_NONBLOCK;
1584 if (0 > fcntl (fd[1], F_SETFL, flags))
1585 {
1586 ret = -1;
1587 eno = errno;
1588 }
1589 }
1590 flags = fcntl (fd[1], F_GETFD);
1591 flags |= FD_CLOEXEC;
1592 if (0 > fcntl (fd[1], F_SETFD, flags))
1593 {
1594 ret = -1;
1595 eno = errno;
1596 }
1597 }
1598 if (ret == -1)
1599 {
1600 errno = eno;
1602 if (p->fd[0]->fd >= 0)
1603 GNUNET_break (0 == close (p->fd[0]->fd));
1604 if (p->fd[1]->fd >= 0)
1605 GNUNET_break (0 == close (p->fd[1]->fd));
1606 GNUNET_free (p->fd[0]);
1607 GNUNET_free (p->fd[1]);
1608 GNUNET_free (p);
1609 errno = eno;
1610 return NULL;
1611 }
1612 return p;
1613}
1614
1615
1619{
1621
1623 {
1624 if (p->fd[0])
1625 {
1626 ret = GNUNET_DISK_file_close (p->fd[0]);
1627 p->fd[0] = NULL;
1628 }
1629 }
1630 else if (end == GNUNET_DISK_PIPE_END_WRITE)
1631 {
1632 if (p->fd[1])
1633 {
1634 ret = GNUNET_DISK_file_close (p->fd[1]);
1635 p->fd[1] = NULL;
1636 }
1637 }
1638 return ret;
1639}
1640
1641
1645{
1646 struct GNUNET_DISK_FileHandle *ret = NULL;
1647
1649 {
1650 if (p->fd[0])
1651 {
1652 ret = p->fd[0];
1653 p->fd[0] = NULL;
1654 }
1655 }
1656 else if (end == GNUNET_DISK_PIPE_END_WRITE)
1657 {
1658 if (p->fd[1])
1659 {
1660 ret = p->fd[1];
1661 p->fd[1] = NULL;
1662 }
1663 }
1664
1665 return ret;
1666}
1667
1668
1671{
1673 enum GNUNET_GenericReturnValue read_end_close;
1674 enum GNUNET_GenericReturnValue write_end_close;
1675 int read_end_close_errno;
1676 int write_end_close_errno;
1677
1678 read_end_close = GNUNET_DISK_pipe_close_end (p,
1680 read_end_close_errno = errno;
1681 write_end_close = GNUNET_DISK_pipe_close_end (p,
1683 write_end_close_errno = errno;
1684 GNUNET_free (p);
1685
1686 if (GNUNET_OK != read_end_close)
1687 {
1688 errno = read_end_close_errno;
1689 ret = read_end_close;
1690 }
1691 else if (GNUNET_OK != write_end_close)
1692 {
1693 errno = write_end_close_errno;
1694 ret = write_end_close;
1695 }
1696
1697 return ret;
1698}
1699
1700
1701const struct GNUNET_DISK_FileHandle *
1703 enum GNUNET_DISK_PipeEnd n)
1704{
1705 switch (n)
1706 {
1709 return p->fd[n];
1710
1711 default:
1712 GNUNET_break (0);
1713 return NULL;
1714 }
1715}
1716
1717
1720 int *dst)
1721{
1722 if (NULL == fh)
1723 return GNUNET_SYSERR;
1724 *dst = fh->fd;
1725 return GNUNET_OK;
1726}
1727
1728
1736static enum GNUNET_GenericReturnValue
1737purge_cfg_dir (void *cls,
1738 const struct GNUNET_CONFIGURATION_Handle *cfg)
1739{
1740 const char *option = cls;
1741 char *tmpname;
1742
1743 if (GNUNET_OK !=
1745 "PATHS",
1746 option,
1747 &tmpname))
1748 {
1750 "PATHS",
1751 option);
1752 return GNUNET_NO;
1753 }
1754 if (GNUNET_SYSERR ==
1756 {
1758 "remove",
1759 tmpname);
1760 GNUNET_free (tmpname);
1761 return GNUNET_OK;
1762 }
1763 GNUNET_free (tmpname);
1764 return GNUNET_OK;
1765}
1766
1767
1768void
1770 const char *cfg_filename,
1771 const char *option)
1772{
1777 (void *) option));
1778}
1779
1780
1781/* 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:1032
#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:513
#define S_ISLNK(m)
Definition disk.c:61
#define MAP_FAILED
Definition disk.c:1454
static bool glob_match(const char *pattern, const char *str)
Check for a simple wildcard match.
Definition disk.c:970
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:1737
#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:306
#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:1130
enum GNUNET_GenericReturnValue GNUNET_DISK_internal_file_handle_(const struct GNUNET_DISK_FileHandle *fh, int *dst)
Retrieve OS file handle.
Definition disk.c:1719
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 struct GNUNET_SCHEDULER_Task * t
Main task.
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 enum @49 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:1702
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:1308
void GNUNET_DISK_filename_canonicalize(char *fn)
Removes special characters as ':' from a filename.
Definition disk.c:1262
int GNUNET_DISK_glob(const char *glob_pattern, GNUNET_FileNameCallback callback, void *callback_cls)
Find all files matching a glob pattern.
Definition disk.c:1063
enum GNUNET_GenericReturnValue GNUNET_DISK_file_change_owner(const char *filename, const char *user)
Change owner of a file.
Definition disk.c:1284
char * GNUNET_DISK_mktemp(const char *t)
Create an (empty) temporary file on disk.
Definition disk.c:439
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:557
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:254
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:373
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:334
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:1643
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:1544
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:745
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:219
struct GNUNET_DISK_PipeHandle * GNUNET_DISK_pipe(enum GNUNET_DISK_PipeFlags pf)
Creates an interprocess channel.
Definition disk.c:1523
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:565
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:235
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:1670
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:792
char * GNUNET_DISK_mkdtemp(const char *t)
Create an (empty) temporary directory on disk.
Definition disk.c:353
enum GNUNET_GenericReturnValue GNUNET_DISK_file_copy(const char *src, const char *dst)
Copy a file.
Definition disk.c:1185
enum GNUNET_GenericReturnValue GNUNET_DISK_directory_remove(const char *filename)
Remove all files in a directory (rm -rf).
Definition disk.c:1140
enum GNUNET_GenericReturnValue GNUNET_DISK_file_sync(const struct GNUNET_DISK_FileHandle *h)
Write file changes to disk.
Definition disk.c:1506
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:199
enum GNUNET_GenericReturnValue GNUNET_DISK_directory_test(const char *fil, int is_readable)
Test if fil is a directory and listable.
Definition disk.c:466
enum GNUNET_GenericReturnValue GNUNET_DISK_file_close(struct GNUNET_DISK_FileHandle *h)
Close an open file.
Definition disk.c:1386
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:1769
struct GNUNET_DISK_FileHandle * GNUNET_DISK_get_handle_from_native(FILE *fd)
Get a handle from a native FD.
Definition disk.c:1425
enum GNUNET_GenericReturnValue GNUNET_DISK_directory_create_for_file(const char *filename)
Create the directory structure for storing a file.
Definition disk.c:664
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:1459
struct GNUNET_DISK_FileHandle * GNUNET_DISK_get_handle_from_int_fd(int fno)
Get a handle from a native integer FD.
Definition disk.c:1409
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:704
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:206
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:1617
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:761
enum GNUNET_GenericReturnValue GNUNET_DISK_file_unmap(struct GNUNET_DISK_MapHandle *h)
Unmap a file.
Definition disk.c:1490
enum GNUNET_GenericReturnValue GNUNET_DISK_directory_create(const char *dir)
Implementation of "mkdir -p".
Definition disk.c:573
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:720
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:881
@ 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:525
static unsigned int size
Size of the "table".
Definition peer.c:68
#define DIR_SEPARATOR
Definition platform.h:166
#define O_LARGEFILE
Definition platform.h:213
#define DIR_SEPARATOR_STR
Definition platform.h:167
#define _(String)
GNU gettext support macro.
Definition platform.h:179
#define PATH_MAX
Assumed maximum path length.
Definition platform.h:242
Handle used to access files (and pipes).
int fd
File handle on Unix-like systems.
Handle for a memory-mapping operation.
Definition disk.c:1440
void * addr
Address where the map is in memory.
Definition disk.c:1444
size_t len
Number of bytes mapped.
Definition disk.c:1449
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:1013
void * cls
Definition disk.c:1014
int nres
Number of files that actually matched the glob pattern.
Definition disk.c:1019
const char * glob
Definition disk.c:1012
const char * str
Definition time.c:1252