GNUnet debian-0.24.3-29-g453fda2cf
 
Loading...
Searching...
No Matches
disk.c File Reference

disk IO convenience methods More...

#include "platform.h"
#include "gnunet_util_lib.h"
#include "disk.h"
#include <sys/types.h>
Include dependency graph for disk.c:

Go to the source code of this file.

Data Structures

struct  GNUNET_DISK_PipeHandle
 Handle used to manage a pipe. More...
 
struct  GetFileSizeData
 Closure for the recursion to determine the file size of a directory. More...
 
struct  GlobClosure
 
struct  GNUNET_DISK_MapHandle
 Handle for a memory-mapping operation. More...
 

Macros

#define LOG(kind, ...)   GNUNET_log_from (kind, "util-disk", __VA_ARGS__)
 
#define LOG_STRERROR(kind, syscall)    GNUNET_log_from_strerror (kind, "util-disk", syscall)
 
#define LOG_STRERROR_FILE(kind, syscall, filename)    GNUNET_log_from_strerror_file (kind, "util-disk", syscall, filename)
 
#define COPY_BLK_SIZE   65536
 Block size for IO for copying files.
 
#define _IFMT   0170000 /* type of file */
 
#define _IFLNK   0120000 /* symbolic link */
 
#define S_ISLNK(m)   (((m)&_IFMT) == _IFLNK)
 
#define MAP_FAILED   ((void *) -1)
 

Functions

static int translate_unix_perms (enum GNUNET_DISK_AccessPermissions perm)
 Translate GNUnet-internal permission bitmap to UNIX file access permission bitmap.
 
static enum GNUNET_GenericReturnValue get_size_rec (void *cls, const char *fn)
 Iterate over all files in the given directory and accumulate their size.
 
enum GNUNET_GenericReturnValue GNUNET_DISK_handle_invalid (const struct GNUNET_DISK_FileHandle *h)
 Checks whether a handle is invalid.
 
enum GNUNET_GenericReturnValue GNUNET_DISK_file_handle_size (struct GNUNET_DISK_FileHandle *fh, off_t *size)
 Get the size of an open file.
 
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.
 
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).
 
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.
 
static char * mktemp_name (const char *t)
 Create the name for a temporary file or directory from a template.
 
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.
 
char * GNUNET_DISK_mkdtemp (const char *t)
 Create an (empty) temporary directory on disk.
 
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 number that is not used yet.
 
char * GNUNET_DISK_mktemp (const char *t)
 Create an (empty) temporary file on disk.
 
enum GNUNET_GenericReturnValue GNUNET_DISK_directory_test (const char *fil, int is_readable)
 Test if fil is a directory and listable.
 
static enum GNUNET_GenericReturnValue file_test_internal (const char *fil, int amode)
 Check if fil can be accessed using amode.
 
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).
 
enum GNUNET_GenericReturnValue GNUNET_DISK_file_test_read (const char *fil)
 Check that fil corresponds to a filename and the file has read permissions.
 
enum GNUNET_GenericReturnValue GNUNET_DISK_directory_create (const char *dir)
 Implementation of "mkdir -p".
 
enum GNUNET_GenericReturnValue GNUNET_DISK_directory_create_for_file (const char *filename)
 Create the directory structure for storing a file.
 
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.
 
ssize_t GNUNET_DISK_fn_read (const char *fn, void *result, size_t len)
 Read the contents of a binary file into a buffer.
 
ssize_t GNUNET_DISK_file_write (const struct GNUNET_DISK_FileHandle *h, const void *buffer, size_t n)
 Write a buffer to a file.
 
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.
 
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.
 
int GNUNET_DISK_directory_scan (const char *dir_name, GNUNET_FileNameCallback callback, void *callback_cls)
 Scan a directory for files.
 
static bool glob_match (const char *pattern, const char *str)
 Check for a simple wildcard match.
 
static enum GNUNET_GenericReturnValue glob_cb (void *cls, const char *filename)
 Function called with a filename.
 
int GNUNET_DISK_glob (const char *glob_pattern, GNUNET_FileNameCallback callback, void *callback_cls)
 Find all files matching a glob pattern.
 
static enum GNUNET_GenericReturnValue remove_helper (void *unused, const char *fn)
 Function that removes the given directory by calling GNUNET_DISK_directory_remove().
 
enum GNUNET_GenericReturnValue GNUNET_DISK_directory_remove (const char *filename)
 Remove all files in a directory (rm -rf).
 
enum GNUNET_GenericReturnValue GNUNET_DISK_file_copy (const char *src, const char *dst)
 Copy a file.
 
void GNUNET_DISK_filename_canonicalize (char *fn)
 Removes special characters as ':' from a filename.
 
enum GNUNET_GenericReturnValue GNUNET_DISK_file_change_owner (const char *filename, const char *user)
 Change owner of a file.
 
struct GNUNET_DISK_FileHandleGNUNET_DISK_file_open (const char *fn, enum GNUNET_DISK_OpenFlags flags, enum GNUNET_DISK_AccessPermissions perm)
 Open a file.
 
enum GNUNET_GenericReturnValue GNUNET_DISK_file_close (struct GNUNET_DISK_FileHandle *h)
 Close an open file.
 
struct GNUNET_DISK_FileHandleGNUNET_DISK_get_handle_from_int_fd (int fno)
 Get a handle from a native integer FD.
 
struct GNUNET_DISK_FileHandleGNUNET_DISK_get_handle_from_native (FILE *fd)
 Get a handle from a native FD.
 
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.
 
enum GNUNET_GenericReturnValue GNUNET_DISK_file_unmap (struct GNUNET_DISK_MapHandle *h)
 Unmap a file.
 
enum GNUNET_GenericReturnValue GNUNET_DISK_file_sync (const struct GNUNET_DISK_FileHandle *h)
 Write file changes to disk.
 
struct GNUNET_DISK_PipeHandleGNUNET_DISK_pipe (enum GNUNET_DISK_PipeFlags pf)
 Creates an interprocess channel.
 
struct GNUNET_DISK_PipeHandleGNUNET_DISK_pipe_from_fd (enum GNUNET_DISK_PipeFlags pf, int fd[2])
 Creates a pipe object from a couple of file descriptors.
 
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.
 
struct GNUNET_DISK_FileHandleGNUNET_DISK_pipe_detach_end (struct GNUNET_DISK_PipeHandle *p, enum GNUNET_DISK_PipeEnd end)
 Detaches one of the ends from the pipe.
 
enum GNUNET_GenericReturnValue GNUNET_DISK_pipe_close (struct GNUNET_DISK_PipeHandle *p)
 Closes an interprocess channel.
 
const struct GNUNET_DISK_FileHandleGNUNET_DISK_pipe_handle (const struct GNUNET_DISK_PipeHandle *p, enum GNUNET_DISK_PipeEnd n)
 Get the handle to a particular pipe end.
 
enum GNUNET_GenericReturnValue GNUNET_DISK_internal_file_handle_ (const struct GNUNET_DISK_FileHandle *fh, int *dst)
 Retrieve OS file handle.
 
static enum GNUNET_GenericReturnValue purge_cfg_dir (void *cls, const struct GNUNET_CONFIGURATION_Handle *cfg)
 Helper function for GNUNET_DISK_purge_cfg_dir.
 
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.
 

Detailed Description

disk IO convenience methods

Author
Christian Grothoff
Nils Durner

Definition in file disk.c.

Macro Definition Documentation

◆ LOG

#define LOG (   kind,
  ... 
)    GNUNET_log_from (kind, "util-disk", __VA_ARGS__)

Definition at line 31 of file disk.c.

◆ LOG_STRERROR

#define LOG_STRERROR (   kind,
  syscall 
)     GNUNET_log_from_strerror (kind, "util-disk", syscall)

Definition at line 33 of file disk.c.

68{
73 struct GNUNET_DISK_FileHandle *fd[2];
74};
75
76
81struct GetFileSizeData
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 != lstat64 (fn, &buf))
154 {
156 return GNUNET_SYSERR;
157 }
158#else
159 struct stat buf;
160
161 if (0 != lstat (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_NO))
173 {
174 char linkdst[PATH_MAX];
175 if (NULL == realpath (fn, linkdst))
176 {
178 return GNUNET_SYSERR;
179 }
180 return get_size_rec(gfsd, linkdst);
181 }
182 if ((! S_ISLNK (buf.st_mode)) || (gfsd->include_sym_links == GNUNET_YES))
183 gfsd->total += buf.st_size;
184 if ((S_ISDIR (buf.st_mode)) && (0 == access (fn, X_OK)) &&
185 ((! S_ISLNK (buf.st_mode)) || (gfsd->include_sym_links == GNUNET_YES)))
186 {
187 if (GNUNET_SYSERR ==
190 gfsd))
191 return GNUNET_SYSERR;
192 }
193 return GNUNET_OK;
194}
195
196
199{
200 return ((! h) || (h->fd == -1)) ? GNUNET_YES : GNUNET_NO;
201}
202
203
206 off_t *size)
207{
208 struct stat sbuf;
209
210 if (0 != fstat (fh->fd, &sbuf))
211 return GNUNET_SYSERR;
212 *size = sbuf.st_size;
213 return GNUNET_OK;
214}
215
216
217off_t
219 off_t offset,
220 enum GNUNET_DISK_Seek whence)
221{
222 static int t[] = { SEEK_SET, SEEK_CUR, SEEK_END };
223
224 if (h == NULL)
225 {
226 errno = EINVAL;
227 return GNUNET_SYSERR;
228 }
229 return lseek (h->fd, offset, t[whence]);
230}
231
232
235 uint64_t *size,
236 int include_symbolic_links,
237 int single_file_mode)
238{
239 struct GetFileSizeData gfsd;
241
242 GNUNET_assert (size != NULL);
243 gfsd.total = 0;
244 gfsd.include_sym_links = include_symbolic_links;
246 ret = get_size_rec (&gfsd, filename);
247 *size = gfsd.total;
248 return ret;
249}
250
251
254 uint64_t *dev,
255 uint64_t *ino)
256{
257#if HAVE_STAT
258 {
259 struct stat sbuf;
260
261 if (0 != stat (filename, &sbuf))
262 {
263 return GNUNET_SYSERR;
264 }
265 *ino = (uint64_t) sbuf.st_ino;
266 }
267#else
268 *ino = 0;
269#endif
270#if HAVE_STATVFS
271 {
272 struct statvfs fbuf;
273
274 if (0 != statvfs (filename, &fbuf))
275 {
276 return GNUNET_SYSERR;
277 }
278 *dev = (uint64_t) fbuf.f_fsid;
279 }
280#elif HAVE_STATFS
281 {
282 struct statfs fbuf;
283
284 if (0 != statfs (filename, &fbuf))
285 {
286 return GNUNET_SYSERR;
287 }
288 *dev =
289 ((uint64_t) fbuf.f_fsid.val[0]) << 32 || ((uint64_t) fbuf.f_fsid.val[1]);
290 }
291#else
292 *dev = 0;
293#endif
294 return GNUNET_OK;
295}
296
297
304static char *
305mktemp_name (const char *t)
306{
307 const char *tmpdir;
308 char *tmpl;
309 char *fn;
310
311 if ((t[0] != '/') && (t[0] != '\\'))
312 {
313 /* FIXME: This uses system codepage on W32, not UTF-8 */
314 tmpdir = getenv ("TMPDIR");
315 if (NULL == tmpdir)
316 tmpdir = getenv ("TMP");
317 if (NULL == tmpdir)
318 tmpdir = getenv ("TEMP");
319 if (NULL == tmpdir)
320 tmpdir = "/tmp";
321 GNUNET_asprintf (&tmpl, "%s/%s%s", tmpdir, t, "XXXXXX");
322 }
323 else
324 {
325 GNUNET_asprintf (&tmpl, "%s%s", t, "XXXXXX");
326 }
327 fn = tmpl;
328 return fn;
329}
330
331
332void
333GNUNET_DISK_fix_permissions (const char *fn,
334 int require_uid_match,
335 int require_gid_match)
336{
337 mode_t mode;
338
339 if (GNUNET_YES == require_uid_match)
340 mode = S_IRUSR | S_IWUSR | S_IXUSR;
341 else if (GNUNET_YES == require_gid_match)
342 mode = S_IRUSR | S_IWUSR | S_IXUSR | S_IRGRP | S_IWGRP | S_IXGRP;
343 else
344 mode = S_IRUSR | S_IWUSR | S_IXUSR | S_IRGRP | S_IWGRP | S_IXGRP | S_IROTH
345 | S_IWOTH | S_IXOTH;
346 if (0 != chmod (fn, mode))
348}
349
350
351char *
352GNUNET_DISK_mkdtemp (const char *t)
353{
354 char *fn;
355 mode_t omask;
356
357 omask = umask (S_IWGRP | S_IWOTH | S_IRGRP | S_IROTH);
358 fn = mktemp_name (t);
359 if (fn != mkdtemp (fn))
360 {
362 GNUNET_free (fn);
363 umask (omask);
364 return NULL;
365 }
366 umask (omask);
367 return fn;
368}
369
370
371char *
372GNUNET_DISK_file_backup (const char *fil)
373{
374 size_t slen;
375 char *target;
376 unsigned int num;
377
378 slen = strlen (fil) + 20;
379 target = GNUNET_malloc (slen);
380 num = 0;
381
382#if HAVE_RENAMEAT2
383 {
384 int fd;
385
386 do
387 {
388 GNUNET_snprintf (target,
389 slen,
390 "%s.%u~",
391 fil,
392 num++);
393 fd = open (target,
394 O_CREAT | O_EXCL,
396 } while (-1 == fd);
397 if (0 != renameat2 (AT_FDCWD,
398 fil,
399 AT_FDCWD,
400 target,
401 RENAME_EXCHANGE))
402 {
404 "renameat2",
405 fil);
406 GNUNET_break (0 ==
407 close (fd));
408 return NULL;
409 }
410 GNUNET_break (0 ==
411 close (fd));
412 }
413#else
414 do
415 {
416 GNUNET_snprintf (target, slen, "%s.%u~", fil, num++);
417 }
418 while (0 == access (target, F_OK));
419 if (0 != rename (fil, target))
420 {
422 return NULL;
423 }
424#endif
425 return target;
426}
427
428
429char *
430GNUNET_DISK_mktemp (const char *t)
431{
432 int fd;
433 char *fn;
434 mode_t omask;
435
436 omask = umask (S_IWGRP | S_IWOTH | S_IRGRP | S_IROTH);
437 fn = mktemp_name (t);
438 if (-1 == (fd = mkstemp (fn)))
439 {
441 GNUNET_free (fn);
442 umask (omask);
443 return NULL;
444 }
445 umask (omask);
446 if (0 != close (fd))
448 return fn;
449}
450
451
453GNUNET_DISK_directory_test (const char *fil, int is_readable)
454{
455 struct stat filestat;
456 int ret;
457
458 ret = stat (fil, &filestat);
459 if (ret != 0)
460 {
461 if (errno != ENOENT)
463 return GNUNET_SYSERR;
464 }
465 if (! S_ISDIR (filestat.st_mode))
466 {
468 "A file already exits with the same name %s\n",
469 fil);
470 return GNUNET_NO;
471 }
472 if (GNUNET_YES == is_readable)
473 ret = access (fil, R_OK | X_OK);
474 else
475 ret = access (fil, X_OK);
476 if (ret < 0)
477 {
479 return GNUNET_NO;
480 }
481 return GNUNET_YES;
482}
483
484
493file_test_internal (const char *fil, int amode)
494{
495 struct stat filestat;
496 int ret;
497 char *rdir;
498
500 if (rdir == NULL)
501 return GNUNET_SYSERR;
502
503 ret = stat (rdir, &filestat);
504 if (0 != ret)
505 {
506 if (errno != ENOENT)
507 {
509 GNUNET_free (rdir);
510 return GNUNET_SYSERR;
511 }
512 GNUNET_free (rdir);
513 return GNUNET_NO;
514 }
515 if (! S_ISREG (filestat.st_mode))
516 {
517 GNUNET_free (rdir);
518 return GNUNET_NO;
519 }
520 if (access (rdir, amode) < 0)
521 {
523 GNUNET_free (rdir);
524 return GNUNET_SYSERR;
525 }
526 GNUNET_free (rdir);
527 return GNUNET_YES;
528}
529
530
532GNUNET_DISK_file_test (const char *fil)
533{
534 return file_test_internal (fil, F_OK);
535}
536
537
539GNUNET_DISK_file_test_read (const char *fil)
540{
541 return file_test_internal (fil, R_OK);
542}
543
544
547{
548 char *rdir;
549 unsigned int len;
550 unsigned int pos;
551 unsigned int pos2;
552 int ret = GNUNET_OK;
553
555 if (rdir == NULL)
556 {
557 GNUNET_break (0);
558 return GNUNET_SYSERR;
559 }
560
561 len = strlen (rdir);
562
563 pos = 1; /* skip heading '/' */
564
565 /* Check which low level directories already exist */
566 pos2 = len;
567 rdir[len] = DIR_SEPARATOR;
568 while (pos <= pos2)
569 {
570 if (DIR_SEPARATOR == rdir[pos2])
571 {
572 rdir[pos2] = '\0';
574 if (GNUNET_NO == ret)
575 {
577 "Creating directory `%s' failed\n",
578 rdir);
579 GNUNET_free (rdir);
580 return GNUNET_SYSERR;
581 }
582 rdir[pos2] = DIR_SEPARATOR;
583 if (GNUNET_YES == ret)
584 {
585 pos2++;
586 break;
587 }
588 }
589 pos2--;
590 }
591 rdir[len] = '\0';
592 if (pos < pos2)
593 pos = pos2;
594 /* Start creating directories */
595 while (pos <= len)
596 {
597 if ((rdir[pos] == DIR_SEPARATOR) || (pos == len))
598 {
599 rdir[pos] = '\0';
601 if (GNUNET_NO == ret)
602 {
604 "Creating directory `%s' failed\n",
605 rdir);
606 GNUNET_free (rdir);
607 return GNUNET_SYSERR;
608 }
609 if (GNUNET_SYSERR == ret)
610 {
611 ret = mkdir (rdir,
612 S_IRUSR | S_IWUSR | S_IXUSR | S_IRGRP | S_IXGRP | S_IROTH
613 | S_IXOTH); /* 755 */
614
615 if ((ret != 0) && (errno != EEXIST))
616 {
618 GNUNET_free (rdir);
619 return GNUNET_SYSERR;
620 }
621 }
622 rdir[pos] = DIR_SEPARATOR;
623 }
624 pos++;
625 }
626 GNUNET_free (rdir);
627 return GNUNET_OK;
628}
629
630
633{
634 char *rdir;
635 size_t len;
636 int eno;
638
640 if (NULL == rdir)
641 {
642 errno = EINVAL;
643 return GNUNET_SYSERR;
644 }
645 if (0 == access (rdir, W_OK))
646 {
647 GNUNET_free (rdir);
648 return GNUNET_OK;
649 }
650 len = strlen (rdir);
651 while ((len > 0) && (rdir[len] != DIR_SEPARATOR))
652 len--;
653 rdir[len] = '\0';
654 /* The empty path is invalid and in this case refers to / */
655 if (0 == len)
656 {
657 GNUNET_free (rdir);
658 rdir = GNUNET_strdup ("/");
659 }
661 if ( (GNUNET_OK == res) &&
662 (0 != access (rdir, W_OK)) )
663 res = GNUNET_NO;
664 eno = errno;
665 GNUNET_free (rdir);
666 errno = eno;
667 return res;
668}
669
670
671ssize_t
673 void *result,
674 size_t len)
675{
676 if (NULL == h)
677 {
678 errno = EINVAL;
679 return GNUNET_SYSERR;
680 }
681 return read (h->fd, result, len);
682}
683
684
685ssize_t
686GNUNET_DISK_fn_read (const char *fn,
687 void *result,
688 size_t len)
689{
690 struct GNUNET_DISK_FileHandle *fh;
691 ssize_t ret;
692 int eno;
693
694 fh = GNUNET_DISK_file_open (fn,
697 if (NULL == fh)
698 return GNUNET_SYSERR;
699 ret = GNUNET_DISK_file_read (fh, result, len);
700 eno = errno;
703 errno = eno;
704 return ret;
705}
706
707
708ssize_t
710 const void *buffer,
711 size_t n)
712{
713 if (NULL == h)
714 {
715 errno = EINVAL;
716 return GNUNET_SYSERR;
717 }
718 return write (h->fd,
719 buffer,
720 n);
721}
722
723
724ssize_t
726 const void *buffer,
727 size_t n)
728{
729 int flags;
730 ssize_t ret;
731
732 if (NULL == h)
733 {
734 errno = EINVAL;
735 return GNUNET_SYSERR;
736 }
737 /* set to blocking, write, then set back */
738 flags = fcntl (h->fd, F_GETFL);
739 if (0 != (flags & O_NONBLOCK))
740 (void) fcntl (h->fd, F_SETFL, flags - O_NONBLOCK);
741 ret = write (h->fd, buffer, n);
742 if (0 == (flags & O_NONBLOCK))
743 (void) fcntl (h->fd, F_SETFL, flags);
744 return ret;
745}
746
747
749GNUNET_DISK_fn_write (const char *fn,
750 const void *buf,
751 size_t buf_size,
753{
754 char *tmpl;
755 int fd;
756
757 if (GNUNET_OK !=
759 {
761 "mkstemp",
762 fn);
763 return GNUNET_SYSERR;
764 }
765 {
766 char *dname;
767
768 dname = GNUNET_strdup (fn);
769 GNUNET_asprintf (&tmpl,
770 "%s/XXXXXX",
771 dirname (dname));
772 GNUNET_free (dname);
773 }
774 fd = mkstemp (tmpl);
775 if (-1 == fd)
776 {
778 "mkstemp",
779 tmpl);
780 GNUNET_free (tmpl);
781 return GNUNET_SYSERR;
782 }
783
784 if (0 != fchmod (fd,
786 {
788 "chmod",
789 tmpl);
790 GNUNET_assert (0 == close (fd));
791 if (0 != unlink (tmpl))
793 "unlink",
794 tmpl);
795 GNUNET_free (tmpl);
796 return GNUNET_SYSERR;
797 }
798 if (buf_size !=
799 write (fd,
800 buf,
801 buf_size))
802 {
804 "write",
805 tmpl);
806 GNUNET_assert (0 == close (fd));
807 if (0 != unlink (tmpl))
809 "unlink",
810 tmpl);
811 GNUNET_free (tmpl);
812 return GNUNET_SYSERR;
813 }
814 GNUNET_assert (0 == close (fd));
815
816 if (0 != link (tmpl,
817 fn))
818 {
819 if (0 != unlink (tmpl))
821 "unlink",
822 tmpl);
823 GNUNET_free (tmpl);
824 return GNUNET_NO;
825 }
826 if (0 != unlink (tmpl))
828 "unlink",
829 tmpl);
830 GNUNET_free (tmpl);
831 return GNUNET_OK;
832
833
834}
835
836
837int
840 void *callback_cls)
841{
842 DIR *dinfo;
843 struct dirent *finfo;
844 int count = 0;
846 char *name;
847 char *dname;
848 unsigned int name_len;
849 unsigned int n_size;
850
851 GNUNET_assert (NULL != dir_name);
853 if (NULL == dname)
854 return GNUNET_SYSERR;
855 while ( (strlen (dname) > 0) &&
856 (dname[strlen (dname) - 1] == DIR_SEPARATOR) )
857 dname[strlen (dname) - 1] = '\0';
858 dinfo = opendir (dname);
859 if (NULL == dinfo)
860 {
862 "opendir",
863 dname);
864 GNUNET_free (dname);
865 return GNUNET_SYSERR;
866 }
867 name_len = 256;
868 n_size = strlen (dname) + name_len + strlen (DIR_SEPARATOR_STR) + 1;
869 name = GNUNET_malloc (n_size);
870 while (NULL != (finfo = readdir (dinfo)))
871 {
872 if ((0 == strcmp (finfo->d_name, ".")) ||
873 (0 == strcmp (finfo->d_name, "..")))
874 continue;
875 if (NULL != callback)
876 {
877 if (name_len < strlen (finfo->d_name))
878 {
880 name_len = strlen (finfo->d_name);
881 n_size = strlen (dname) + name_len + strlen (DIR_SEPARATOR_STR) + 1;
882 name = GNUNET_malloc (n_size);
883 }
884 /* dname can end in "/" only if dname == "/";
885 * if dname does not end in "/", we need to add
886 * a "/" (otherwise, we must not!) */
888 n_size,
889 "%s%s%s",
890 dname,
891 (0 == strcmp (dname,
893 ? ""
895 finfo->d_name);
896 ret = callback (callback_cls,
897 name);
898 if (GNUNET_OK != ret)
899 {
900 closedir (dinfo);
902 GNUNET_free (dname);
903 if (GNUNET_NO == ret)
904 return count;
905 return GNUNET_SYSERR;
906 }
907 }
908 count++;
909 }
910 closedir (dinfo);
912 GNUNET_free (dname);
913 return count;
914}
915
916
926static bool
927glob_match (const char *pattern, const char *str)
928{
929 /* Position in the input string */
930 const char *str_pos = str;
931 /* Position in the pattern */
932 const char *pat_pos = pattern;
933 /* Backtrack position in string */
934 const char *str_bt = NULL;
935 /* Backtrack position in pattern */
936 const char *pat_bt = NULL;
937
938 for (;;)
939 {
940 if (*pat_pos == '*')
941 {
942 str_bt = str_pos;
943 pat_bt = pat_pos++;
944 }
945 else if (*pat_pos == *str_pos)
946 {
947 if ('\0' == *pat_pos)
948 return true;
949 str_pos++;
950 pat_pos++;
951 }
952 else
953 {
954 if (NULL == str_bt)
955 return false;
956 /* Backtrack to match one more
957 character as part of the asterisk. */
958 str_pos = str_bt + 1;
959 if ('\0' == *str_pos)
960 return false;
961 pat_pos = pat_bt;
962 }
963 }
964}
965
966
967struct GlobClosure
968{
969 const char *glob;
971 void *cls;
972
976 int nres;
977};
978
989glob_cb (void *cls,
990 const char *filename)
991{
992 struct GlobClosure *gc = cls;
993 const char *fn;
994
995 fn = strrchr (filename, DIR_SEPARATOR);
996 fn = (NULL == fn) ? filename : (fn + 1);
997
999 "checking glob '%s' against '%s'\n",
1000 gc->glob,
1001 fn);
1002
1003 if (glob_match (gc->glob, fn))
1004 {
1005 enum GNUNET_GenericReturnValue cbret;
1006
1008 "found glob match '%s'\n",
1009 filename);
1010 gc->nres++;
1011 cbret = gc->cb (gc->cls, filename);
1012 if (GNUNET_OK != cbret)
1013 return cbret;
1014 }
1015 return GNUNET_OK;
1016}
1017
1018
1019int
1020GNUNET_DISK_glob (const char *glob_pattern,
1021 GNUNET_FileNameCallback callback,
1022 void *callback_cls)
1023{
1024 char *mypat = GNUNET_strdup (glob_pattern);
1025 char *sep;
1026 int ret;
1027
1028 if ( (NULL != strrchr (glob_pattern, '+')) ||
1029 (NULL != strrchr (glob_pattern, '[')) ||
1030 (NULL != strrchr (glob_pattern, '~')) )
1031 {
1033 "unsupported glob pattern: '%s'\n",
1034 glob_pattern);
1035 GNUNET_free (mypat);
1036 return -1;
1037 }
1038
1039 sep = strrchr (mypat, DIR_SEPARATOR);
1040 if (NULL == sep)
1041 {
1042 GNUNET_free (mypat);
1043 return -1;
1044 }
1045
1046 *sep = '\0';
1047
1048 if (NULL != strchr (mypat, '*'))
1049 {
1050 GNUNET_free (mypat);
1051 GNUNET_break (0);
1053 "glob pattern may only contain '*' in the final path component\n");
1054 return -1;
1055 }
1056
1057 {
1058 struct GlobClosure gc = {
1059 .glob = sep + 1,
1060 .cb = callback,
1061 .cls = callback_cls,
1062 .nres = 0,
1063 };
1065 "scanning directory '%s' for glob matches on '%s'\n",
1066 mypat,
1067 gc.glob);
1069 glob_cb,
1070 &gc
1071 );
1072 GNUNET_free (mypat);
1073 return (ret < 0) ? ret : gc.nres;
1074 }
1075}
1076
1077
1086static enum GNUNET_GenericReturnValue
1087remove_helper (void *unused,
1088 const char *fn)
1089{
1090 (void) unused;
1091 (void) GNUNET_DISK_directory_remove (fn);
1092 return GNUNET_OK;
1093}
1094
1095
1098{
1099 struct stat istat;
1100
1101 if (NULL == filename)
1102 {
1103 GNUNET_break (0);
1104 return GNUNET_SYSERR;
1105 }
1106 if (0 != lstat (filename, &istat))
1107 return GNUNET_NO; /* file may not exist... */
1108 (void) chmod (filename,
1109 S_IWUSR | S_IRUSR | S_IXUSR);
1110 if (0 == unlink (filename))
1111 return GNUNET_OK;
1112 if ( (errno != EISDIR) &&
1113 /* EISDIR is not sufficient in all cases, e.g.
1114 * sticky /tmp directory may result in EPERM on BSD.
1115 * So we also explicitly check "isDirectory" */
1116 (GNUNET_YES !=
1118 GNUNET_YES)) )
1119 {
1121 "rmdir",
1122 filename);
1123 return GNUNET_SYSERR;
1124 }
1125 if (GNUNET_SYSERR ==
1128 NULL))
1129 return GNUNET_SYSERR;
1130 if (0 != rmdir (filename))
1131 {
1133 "rmdir",
1134 filename);
1135 return GNUNET_SYSERR;
1136 }
1137 return GNUNET_OK;
1138}
1139
1140
1142GNUNET_DISK_file_copy (const char *src,
1143 const char *dst)
1144{
1145 char *buf;
1146 uint64_t pos;
1147 uint64_t size;
1148 size_t len;
1149 ssize_t sret;
1150 struct GNUNET_DISK_FileHandle *in;
1151 struct GNUNET_DISK_FileHandle *out;
1152
1154 {
1156 return GNUNET_SYSERR;
1157 }
1158 pos = 0;
1159 in =
1161 if (! in)
1162 {
1164 return GNUNET_SYSERR;
1165 }
1166 out =
1174 if (! out)
1175 {
1178 return GNUNET_SYSERR;
1179 }
1181 while (pos < size)
1182 {
1183 len = COPY_BLK_SIZE;
1184 if (len > size - pos)
1185 len = size - pos;
1186 sret = GNUNET_DISK_file_read (in, buf, len);
1187 if ((sret < 0) || (len != (size_t) sret))
1188 goto FAIL;
1189 sret = GNUNET_DISK_file_write (out, buf, len);
1190 if ((sret < 0) || (len != (size_t) sret))
1191 goto FAIL;
1192 pos += len;
1193 }
1194 GNUNET_free (buf);
1199 return GNUNET_OK;
1200FAIL:
1201 GNUNET_free (buf);
1206 return GNUNET_SYSERR;
1207}
1208
1209
1210void
1212{
1213 char *idx;
1214 char c;
1215
1216 for (idx = fn; *idx; idx++)
1217 {
1218 c = *idx;
1219
1220 if ((c == '/') || (c == '\\') || (c == ':') || (c == '*') || (c == '?') ||
1221 (c ==
1222 '"')
1223 ||
1224 (c == '<') || (c == '>') || (c == '|') )
1225 {
1226 *idx = '_';
1227 }
1228 }
1229}
1230
1231
1234 const char *user)
1235{
1236 struct passwd *pws;
1237
1238 pws = getpwnam (user);
1239 if (NULL == pws)
1240 {
1242 _ ("Cannot obtain information about user `%s': %s\n"),
1243 user,
1244 strerror (errno));
1245 return GNUNET_SYSERR;
1246 }
1247 if (0 != chown (filename, pws->pw_uid, pws->pw_gid))
1248 {
1250 return GNUNET_SYSERR;
1251 }
1252 return GNUNET_OK;
1253}
1254
1255
1257GNUNET_DISK_file_open (const char *fn,
1258 enum GNUNET_DISK_OpenFlags flags,
1260{
1261 char *expfn;
1263
1264 int oflags;
1265 int mode;
1266 int fd;
1267
1268 expfn = GNUNET_STRINGS_filename_expand (fn);
1269 if (NULL == expfn)
1270 return NULL;
1271
1272 mode = 0;
1274 oflags = O_RDWR; /* note: O_RDWR is NOT always O_RDONLY | O_WRONLY */
1275 else if (flags & GNUNET_DISK_OPEN_READ)
1276 oflags = O_RDONLY;
1277 else if (flags & GNUNET_DISK_OPEN_WRITE)
1278 oflags = O_WRONLY;
1279 else
1280 {
1281 GNUNET_break (0);
1282 GNUNET_free (expfn);
1283 return NULL;
1284 }
1286 oflags |= (O_CREAT | O_EXCL);
1287 if (flags & GNUNET_DISK_OPEN_TRUNCATE)
1288 oflags |= O_TRUNC;
1289 if (flags & GNUNET_DISK_OPEN_APPEND)
1290 oflags |= O_APPEND;
1291 if (GNUNET_NO == GNUNET_DISK_file_test (fn))
1292 {
1293 if (flags & GNUNET_DISK_OPEN_CREATE)
1294 {
1296 oflags |= O_CREAT;
1297 mode = translate_unix_perms (perm);
1298 }
1299 }
1300
1301 // Setting O_CLOEXEC after pipe() may introduce
1302 // race conditions: https://bugs.gnunet.org/view.php?id=9311
1303 // This is no problem if the platform supports pipe2
1304 fd = open (expfn,
1305 oflags
1306#if O_CLOEXEC
1307 | O_CLOEXEC
1308#endif
1309 | O_LARGEFILE,
1310 mode);
1311 if (fd == -1)
1312 {
1313 if (0 == (flags & GNUNET_DISK_OPEN_FAILIFEXISTS))
1315 else
1317 GNUNET_free (expfn);
1318 return NULL;
1319 }
1320
1322
1323 ret->fd = fd;
1324
1325 GNUNET_free (expfn);
1326 return ret;
1327}
1328
1329
1332{
1334
1335 if (NULL == h)
1336 {
1337 errno = EINVAL;
1338 return GNUNET_SYSERR;
1339 }
1340
1341 ret = GNUNET_OK;
1342 if (0 != close (h->fd))
1343 {
1346 }
1347 GNUNET_free (h);
1348 return ret;
1349}
1350
1351
1354{
1355 struct GNUNET_DISK_FileHandle *fh;
1356
1357 if ((((off_t) -1) == lseek (fno, 0, SEEK_CUR)) && (EBADF == errno))
1358 return NULL; /* invalid FD */
1359
1360 fh = GNUNET_new (struct GNUNET_DISK_FileHandle);
1361
1362 fh->fd = fno;
1363
1364 return fh;
1365}
1366
1367
1370{
1371 int fno;
1372
1373 fno = fileno (fd);
1374 if (-1 == fno)
1375 return NULL;
1377}
1378
1379
1384{
1388 void *addr;
1389
1393 size_t len;
1394};
1395
1396
1397#ifndef MAP_FAILED
1398#define MAP_FAILED ((void *) -1)
1399#endif
1400
1401
1402void *
1404 struct GNUNET_DISK_MapHandle **m,
1405 enum GNUNET_DISK_MapType access,
1406 size_t len)
1407{
1408 int prot;
1409
1410 if (NULL == h)
1411 {
1412 errno = EINVAL;
1413 return NULL;
1414 }
1415 prot = 0;
1416 if (access & GNUNET_DISK_MAP_TYPE_READ)
1417 prot = PROT_READ;
1418 if (access & GNUNET_DISK_MAP_TYPE_WRITE)
1419 prot |= PROT_WRITE;
1421 (*m)->addr = mmap (NULL, len, prot, MAP_SHARED, h->fd, 0);
1422 GNUNET_assert (NULL != (*m)->addr);
1423 if (MAP_FAILED == (*m)->addr)
1424 {
1425 GNUNET_free (*m);
1426 return NULL;
1427 }
1428 (*m)->len = len;
1429 return (*m)->addr;
1430}
1431
1432
1435{
1437
1438 if (NULL == h)
1439 {
1440 errno = EINVAL;
1441 return GNUNET_SYSERR;
1442 }
1443 ret = munmap (h->addr, h->len) != -1 ? GNUNET_OK : GNUNET_SYSERR;
1444 GNUNET_free (h);
1445 return ret;
1446}
1447
1448
1451{
1452 if (h == NULL)
1453 {
1454 errno = EINVAL;
1455 return GNUNET_SYSERR;
1456 }
1457
1458#if ! defined(__linux__) || ! defined(GNU)
1459 return fsync (h->fd) == -1 ? GNUNET_SYSERR : GNUNET_OK;
1460#else
1461 return fdatasync (h->fd) == -1 ? GNUNET_SYSERR : GNUNET_OK;
1462#endif
1463}
1464
1465
1468{
1469 int fd[2];
1470
1471#if HAVE_PIPE2 && O_CLOEXEC
1472 if (-1 == pipe2 (fd, O_CLOEXEC))
1473#else
1474 if (-1 == pipe (fd))
1475#endif
1476 {
1477 int eno = errno;
1478
1480 errno = eno;
1481 return NULL;
1482 }
1483 return GNUNET_DISK_pipe_from_fd (pf, fd);
1484}
1485
1486
1489 int fd[2])
1490{
1491 struct GNUNET_DISK_PipeHandle *p;
1492 int ret = 0;
1493 int flags;
1494 int eno = 0; /* make gcc happy */
1495
1497 if (fd[0] >= 0)
1498 {
1499 p->fd[0] = GNUNET_new (struct GNUNET_DISK_FileHandle);
1500 p->fd[0]->fd = fd[0];
1501 if (0 == (GNUNET_DISK_PF_BLOCKING_READ & pf))
1502 {
1503 flags = fcntl (fd[0], F_GETFL);
1504 flags |= O_NONBLOCK;
1505 if (0 > fcntl (fd[0], F_SETFL, flags))
1506 {
1507 ret = -1;
1508 eno = errno;
1509 }
1510 }
1511 flags = fcntl (fd[0], F_GETFD);
1512 flags |= FD_CLOEXEC;
1513 if (0 > fcntl (fd[0], F_SETFD, flags))
1514 {
1515 ret = -1;
1516 eno = errno;
1517 }
1518 }
1519
1520 if (fd[1] >= 0)
1521 {
1522 p->fd[1] = GNUNET_new (struct GNUNET_DISK_FileHandle);
1523 p->fd[1]->fd = fd[1];
1524 if (0 == (GNUNET_DISK_PF_BLOCKING_WRITE & pf))
1525 {
1526 flags = fcntl (fd[1], F_GETFL);
1527 flags |= O_NONBLOCK;
1528 if (0 > fcntl (fd[1], F_SETFL, flags))
1529 {
1530 ret = -1;
1531 eno = errno;
1532 }
1533 }
1534 flags = fcntl (fd[1], F_GETFD);
1535 flags |= FD_CLOEXEC;
1536 if (0 > fcntl (fd[1], F_SETFD, flags))
1537 {
1538 ret = -1;
1539 eno = errno;
1540 }
1541 }
1542 if (ret == -1)
1543 {
1544 errno = eno;
1546 if (p->fd[0]->fd >= 0)
1547 GNUNET_break (0 == close (p->fd[0]->fd));
1548 if (p->fd[1]->fd >= 0)
1549 GNUNET_break (0 == close (p->fd[1]->fd));
1550 GNUNET_free (p->fd[0]);
1551 GNUNET_free (p->fd[1]);
1552 GNUNET_free (p);
1553 errno = eno;
1554 return NULL;
1555 }
1556 return p;
1557}
1558
1559
1563{
1565
1567 {
1568 if (p->fd[0])
1569 {
1570 ret = GNUNET_DISK_file_close (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 = GNUNET_DISK_file_close (p->fd[1]);
1579 p->fd[1] = NULL;
1580 }
1581 }
1582 return ret;
1583}
1584
1585
1589{
1590 struct GNUNET_DISK_FileHandle *ret = NULL;
1591
1593 {
1594 if (p->fd[0])
1595 {
1596 ret = p->fd[0];
1597 p->fd[0] = NULL;
1598 }
1599 }
1600 else if (end == GNUNET_DISK_PIPE_END_WRITE)
1601 {
1602 if (p->fd[1])
1603 {
1604 ret = p->fd[1];
1605 p->fd[1] = NULL;
1606 }
1607 }
1608
1609 return ret;
1610}
1611
1612
1615{
1617 enum GNUNET_GenericReturnValue read_end_close;
1618 enum GNUNET_GenericReturnValue write_end_close;
1619 int read_end_close_errno;
1620 int write_end_close_errno;
1621
1623 read_end_close_errno = errno;
1625 write_end_close_errno = errno;
1626 GNUNET_free (p);
1627
1628 if (GNUNET_OK != read_end_close)
1629 {
1630 errno = read_end_close_errno;
1631 ret = read_end_close;
1632 }
1633 else if (GNUNET_OK != write_end_close)
1634 {
1635 errno = write_end_close_errno;
1636 ret = write_end_close;
1637 }
1638
1639 return ret;
1640}
1641
1642
1643const struct GNUNET_DISK_FileHandle *
1645 enum GNUNET_DISK_PipeEnd n)
1646{
1647 switch (n)
1648 {
1651 return p->fd[n];
1652
1653 default:
1654 GNUNET_break (0);
1655 return NULL;
1656 }
1657}
1658
1659
1662 int *dst)
1663{
1664 if (NULL == fh)
1665 return GNUNET_SYSERR;
1666 *dst = fh->fd;
1667 return GNUNET_OK;
1668}
1669
1670
1678static enum GNUNET_GenericReturnValue
1679purge_cfg_dir (void *cls,
1680 const struct GNUNET_CONFIGURATION_Handle *cfg)
1681{
1682 const char *option = cls;
1683 char *tmpname;
1684
1685 if (GNUNET_OK !=
1687 "PATHS",
1688 option,
1689 &tmpname))
1690 {
1692 "PATHS",
1693 option);
1694 return GNUNET_NO;
1695 }
1696 if (GNUNET_SYSERR ==
1698 {
1700 "remove",
1701 tmpname);
1702 GNUNET_free (tmpname);
1703 return GNUNET_OK;
1704 }
1705 GNUNET_free (tmpname);
1706 return GNUNET_OK;
1707}
1708
1709
1710void
1712 const char *cfg_filename,
1713 const char *option)
1714{
1719 (void *) option));
1720}
1721
1722
1723/* 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:990
#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:494
#define S_ISLNK(m)
Definition disk.c:61
#define MAP_FAILED
Definition disk.c:1399
static bool glob_match(const char *pattern, const char *str)
Check for a simple wildcard match.
Definition disk.c:928
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:1680
#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:1088
enum GNUNET_GenericReturnValue GNUNET_DISK_internal_file_handle_(const struct GNUNET_DISK_FileHandle *fh, int *dst)
Retrieve OS file handle.
Definition disk.c:1662
char * getenv()
static struct GNUNET_ARM_MonitorHandle * m
Monitor connection with ARM.
Definition gnunet-arm.c:103
static struct GNUNET_ARM_Handle * h
Connection with ARM.
Definition gnunet-arm.c:98
static int ret
Final status code.
Definition gnunet-arm.c:93
static struct GNUNET_CONFIGURATION_Handle * cfg
Our configuration.
Definition gnunet-arm.c:108
static char * dir
Set to the directory where runtime files are stored.
Definition gnunet-arm.c:88
static int end
Set if we are to shutdown all services (including ARM).
Definition gnunet-arm.c:33
static const char * dir_name
Top-level directory we monitor to auto-publish.
static char * cfg_filename
Name of the configuration file.
static char * filename
static char * name
Name (label) of the records to list.
static char * res
Currently read line or NULL on EOF.
static int result
Global testing status.
static struct GNUNET_OS_Process * p
Helper process we started.
Definition gnunet-uri.c:38
static struct GNUNET_SCHEDULER_Task * t
Main task.
static enum @44 mode
Should we do a PUT (mode = 0) or GET (mode = 1);.
@ FAIL
enum GNUNET_GenericReturnValue GNUNET_CONFIGURATION_get_value_filename(const struct GNUNET_CONFIGURATION_Handle *cfg, const char *section, const char *option, char **value)
Get a configuration value that should be the name of a file or directory.
enum GNUNET_GenericReturnValue GNUNET_CONFIGURATION_parse_and_run(const struct GNUNET_OS_ProjectData *pd, const char *filename, GNUNET_CONFIGURATION_Callback cb, void *cb_cls)
Parse a configuration file filename and run the function cb with the resulting configuration object.
const struct GNUNET_DISK_FileHandle * GNUNET_DISK_pipe_handle(const struct GNUNET_DISK_PipeHandle *p, enum GNUNET_DISK_PipeEnd n)
Get the handle to a particular pipe end.
Definition disk.c:1645
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:1258
void GNUNET_DISK_filename_canonicalize(char *fn)
Removes special characters as ':' from a filename.
Definition disk.c:1212
int GNUNET_DISK_glob(const char *glob_pattern, GNUNET_FileNameCallback callback, void *callback_cls)
Find all files matching a glob pattern.
Definition disk.c:1021
enum GNUNET_GenericReturnValue GNUNET_DISK_file_change_owner(const char *filename, const char *user)
Change owner of a file.
Definition disk.c:1234
char * GNUNET_DISK_mktemp(const char *t)
Create an (empty) temporary file on disk.
Definition disk.c:431
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:533
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:1588
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:1489
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:710
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:1468
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:540
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:1615
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:750
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:1143
enum GNUNET_GenericReturnValue GNUNET_DISK_directory_remove(const char *filename)
Remove all files in a directory (rm -rf).
Definition disk.c:1098
enum GNUNET_GenericReturnValue GNUNET_DISK_file_sync(const struct GNUNET_DISK_FileHandle *h)
Write file changes to disk.
Definition disk.c:1451
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:454
enum GNUNET_GenericReturnValue GNUNET_DISK_file_close(struct GNUNET_DISK_FileHandle *h)
Close an open file.
Definition disk.c:1332
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:1712
struct GNUNET_DISK_FileHandle * GNUNET_DISK_get_handle_from_native(FILE *fd)
Get a handle from a native FD.
Definition disk.c:1370
enum GNUNET_GenericReturnValue GNUNET_DISK_directory_create_for_file(const char *filename)
Create the directory structure for storing a file.
Definition disk.c:633
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:1404
struct GNUNET_DISK_FileHandle * GNUNET_DISK_get_handle_from_int_fd(int fno)
Get a handle from a native integer FD.
Definition disk.c:1354
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:673
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:1562
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:726
enum GNUNET_GenericReturnValue GNUNET_DISK_file_unmap(struct GNUNET_DISK_MapHandle *h)
Unmap a file.
Definition disk.c:1435
enum GNUNET_GenericReturnValue GNUNET_DISK_directory_create(const char *dir)
Implementation of "mkdir -p".
Definition disk.c:547
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:687
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:839
@ 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:520
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:1385
void * addr
Address where the map is in memory.
Definition disk.c:1389
size_t len
Number of bytes mapped.
Definition disk.c:1394
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:971
void * cls
Definition disk.c:972
int nres
Number of files that actually matched the glob pattern.
Definition disk.c:977
const char * glob
Definition disk.c:970

◆ LOG_STRERROR_FILE

#define LOG_STRERROR_FILE (   kind,
  syscall,
  filename 
)     GNUNET_log_from_strerror_file (kind, "util-disk", syscall, filename)

Definition at line 36 of file disk.c.

◆ COPY_BLK_SIZE

#define COPY_BLK_SIZE   65536

Block size for IO for copying files.

Definition at line 42 of file disk.c.

◆ _IFMT

#define _IFMT   0170000 /* type of file */

Definition at line 59 of file disk.c.

◆ _IFLNK

#define _IFLNK   0120000 /* symbolic link */

Definition at line 60 of file disk.c.

◆ S_ISLNK

#define S_ISLNK (   m)    (((m)&_IFMT) == _IFLNK)

Definition at line 61 of file disk.c.

◆ MAP_FAILED

#define MAP_FAILED   ((void *) -1)

Definition at line 1399 of file disk.c.

Function Documentation

◆ translate_unix_perms()

static int translate_unix_perms ( enum GNUNET_DISK_AccessPermissions  perm)
static

Translate GNUnet-internal permission bitmap to UNIX file access permission bitmap.

Parameters
permfile permissions, GNUnet style
Returns
file permissions, UNIX style

Definition at line 109 of file disk.c.

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}

References GNUNET_DISK_PERM_GROUP_EXEC, GNUNET_DISK_PERM_GROUP_READ, GNUNET_DISK_PERM_GROUP_WRITE, GNUNET_DISK_PERM_OTHER_EXEC, GNUNET_DISK_PERM_OTHER_READ, GNUNET_DISK_PERM_OTHER_WRITE, GNUNET_DISK_PERM_USER_EXEC, GNUNET_DISK_PERM_USER_READ, GNUNET_DISK_PERM_USER_WRITE, and mode.

Referenced by GNUNET_DISK_file_backup(), GNUNET_DISK_file_open(), and GNUNET_DISK_fn_write().

Here is the caller graph for this function:

◆ get_size_rec()

static enum GNUNET_GenericReturnValue get_size_rec ( void *  cls,
const char *  fn 
)
static

Iterate over all files in the given directory and accumulate their size.

Parameters
clsclosure of type struct GetFileSizeData
fncurrent filename we are looking at
Returns
GNUNET_SYSERR on serious errors, otherwise GNUNET_OK

Definition at line 146 of file disk.c.

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}

References get_size_rec(), GNUNET_DISK_directory_scan(), GNUNET_ERROR_TYPE_DEBUG, GNUNET_NO, GNUNET_OK, GNUNET_SYSERR, GNUNET_YES, GetFileSizeData::include_sym_links, LOG_STRERROR_FILE, PATH_MAX, S_ISLNK, GetFileSizeData::single_file_mode, and GetFileSizeData::total.

Referenced by get_size_rec(), and GNUNET_DISK_file_size().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ mktemp_name()

static char * mktemp_name ( const char *  t)
static

Create the name for a temporary file or directory from a template.

Parameters
ttemplate (without XXXXX or "/tmp/")
Returns
name ready for passing to 'mktemp' or 'mkdtemp', NULL on error

Definition at line 306 of file disk.c.

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}

References getenv(), GNUNET_asprintf(), and t.

Referenced by GNUNET_DISK_mkdtemp(), and GNUNET_DISK_mktemp().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ file_test_internal()

static enum GNUNET_GenericReturnValue file_test_internal ( const char *  fil,
int  amode 
)
static

Check if fil can be accessed using amode.

Parameters
filfile to check for
amodeaccess mode
Returns
GNUnet error code

Definition at line 494 of file disk.c.

495{
496 struct stat filestat;
497 int ret;
498 char *rdir;
499
501 if (rdir == NULL)
502 return GNUNET_SYSERR;
503
504 ret = stat (rdir, &filestat);
505 if (0 != ret)
506 {
507 if (errno != ENOENT)
508 {
510 GNUNET_free (rdir);
511 return GNUNET_SYSERR;
512 }
513 GNUNET_free (rdir);
514 return GNUNET_NO;
515 }
516 if (! S_ISREG (filestat.st_mode))
517 {
518 GNUNET_free (rdir);
519 return GNUNET_NO;
520 }
521 if (access (rdir, amode) < 0)
522 {
524 GNUNET_free (rdir);
525 return GNUNET_SYSERR;
526 }
527 GNUNET_free (rdir);
528 return GNUNET_YES;
529}

References GNUNET_ERROR_TYPE_DEBUG, GNUNET_free, GNUNET_NO, GNUNET_STRINGS_filename_expand(), GNUNET_SYSERR, GNUNET_YES, LOG_STRERROR_FILE, and ret.

Referenced by GNUNET_DISK_file_test(), and GNUNET_DISK_file_test_read().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ glob_match()

static bool glob_match ( const char *  pattern,
const char *  str 
)
static

Check for a simple wildcard match.

Only asterisks are allowed. Asterisks match everything, including slashes.

Parameters
patternpattern with wildcards
strstring to match against
Returns
true on match, false otherwise

Definition at line 928 of file disk.c.

929{
930 /* Position in the input string */
931 const char *str_pos = str;
932 /* Position in the pattern */
933 const char *pat_pos = pattern;
934 /* Backtrack position in string */
935 const char *str_bt = NULL;
936 /* Backtrack position in pattern */
937 const char *pat_bt = NULL;
938
939 for (;;)
940 {
941 if (*pat_pos == '*')
942 {
943 str_bt = str_pos;
944 pat_bt = pat_pos++;
945 }
946 else if (*pat_pos == *str_pos)
947 {
948 if ('\0' == *pat_pos)
949 return true;
950 str_pos++;
951 pat_pos++;
952 }
953 else
954 {
955 if (NULL == str_bt)
956 return false;
957 /* Backtrack to match one more
958 character as part of the asterisk. */
959 str_pos = str_bt + 1;
960 if ('\0' == *str_pos)
961 return false;
962 pat_pos = pat_bt;
963 }
964 }
965}

Referenced by glob_cb().

Here is the caller graph for this function:

◆ glob_cb()

static enum GNUNET_GenericReturnValue glob_cb ( void *  cls,
const char *  filename 
)
static

Function called with a filename.

Parameters
clsclosure
filenamecomplete filename (absolute path)
Returns
GNUNET_OK to continue to iterate, GNUNET_NO to stop iteration with no error, GNUNET_SYSERR to abort iteration with error!

Definition at line 990 of file disk.c.

992{
993 struct GlobClosure *gc = cls;
994 const char *fn;
995
996 fn = strrchr (filename, DIR_SEPARATOR);
997 fn = (NULL == fn) ? filename : (fn + 1);
998
1000 "checking glob '%s' against '%s'\n",
1001 gc->glob,
1002 fn);
1003
1004 if (glob_match (gc->glob, fn))
1005 {
1006 enum GNUNET_GenericReturnValue cbret;
1007
1009 "found glob match '%s'\n",
1010 filename);
1011 gc->nres++;
1012 cbret = gc->cb (gc->cls, filename);
1013 if (GNUNET_OK != cbret)
1014 return cbret;
1015 }
1016 return GNUNET_OK;
1017}

References GlobClosure::cb, GlobClosure::cls, DIR_SEPARATOR, filename, GlobClosure::glob, glob_match(), GNUNET_ERROR_TYPE_DEBUG, GNUNET_OK, LOG, and GlobClosure::nres.

Referenced by GNUNET_DISK_glob().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ remove_helper()

static enum GNUNET_GenericReturnValue remove_helper ( void *  unused,
const char *  fn 
)
static

Function that removes the given directory by calling GNUNET_DISK_directory_remove().

Parameters
unusednot used
fndirectory to remove
Returns
GNUNET_OK

Definition at line 1088 of file disk.c.

1090{
1091 (void) unused;
1092 (void) GNUNET_DISK_directory_remove (fn);
1093 return GNUNET_OK;
1094}

References GNUNET_DISK_directory_remove(), and GNUNET_OK.

Referenced by GNUNET_DISK_directory_remove().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ GNUNET_DISK_internal_file_handle_()

enum GNUNET_GenericReturnValue GNUNET_DISK_internal_file_handle_ ( const struct GNUNET_DISK_FileHandle fh,
int *  dst 
)

Retrieve OS file handle.

Parameters
fhGNUnet file descriptor
dstdestination buffer
Returns
GNUNET_OK on success, GNUNET_SYSERR otherwise

Definition at line 1662 of file disk.c.

1664{
1665 if (NULL == fh)
1666 return GNUNET_SYSERR;
1667 *dst = fh->fd;
1668 return GNUNET_OK;
1669}

References GNUNET_DISK_FileHandle::fd, GNUNET_OK, and GNUNET_SYSERR.

Referenced by GNUNET_NETWORK_fdset_handle_set(), and start_process().

Here is the caller graph for this function:

◆ purge_cfg_dir()

static enum GNUNET_GenericReturnValue purge_cfg_dir ( void *  cls,
const struct GNUNET_CONFIGURATION_Handle cfg 
)
static

Helper function for GNUNET_DISK_purge_cfg_dir.

Parameters
clsa const char * with the option to purge
cfgour configuration
Returns
GNUNET_OK on success

Definition at line 1680 of file disk.c.

1682{
1683 const char *option = cls;
1684 char *tmpname;
1685
1686 if (GNUNET_OK !=
1688 "PATHS",
1689 option,
1690 &tmpname))
1691 {
1693 "PATHS",
1694 option);
1695 return GNUNET_NO;
1696 }
1697 if (GNUNET_SYSERR ==
1699 {
1701 "remove",
1702 tmpname);
1703 GNUNET_free (tmpname);
1704 return GNUNET_OK;
1705 }
1706 GNUNET_free (tmpname);
1707 return GNUNET_OK;
1708}

References cfg, GNUNET_CONFIGURATION_get_value_filename(), GNUNET_DISK_directory_remove(), GNUNET_ERROR_TYPE_ERROR, GNUNET_free, GNUNET_log_config_missing(), GNUNET_log_strerror_file, GNUNET_NO, GNUNET_OK, and GNUNET_SYSERR.

Referenced by GNUNET_DISK_purge_cfg_dir().

Here is the call graph for this function:
Here is the caller graph for this function: