31#define LOG(kind, ...) GNUNET_log_from (kind, "util-disk", __VA_ARGS__)
33#define LOG_STRERROR(kind, syscall) \
34 GNUNET_log_from_strerror (kind, "util-disk", syscall)
36#define LOG_STRERROR_FILE(kind, syscall, filename) \
37 GNUNET_log_from_strerror_file (kind, "util-disk", syscall, filename)
42#define COPY_BLK_SIZE 65536
55#include <sys/statvfs.h>
61#define S_ISLNK(m) (((m)&_IFMT) == _IFLNK)
150#if defined(HAVE_STAT64) && \
151 ! (defined(_FILE_OFFSET_BITS) && _FILE_OFFSET_BITS == 64)
154 if (0 != lstat64 (fn, &buf))
162 if (0 != lstat (fn, &buf))
174 gfsd->
total += buf.st_size;
175 if ((S_ISDIR (buf.st_mode)) && (0 == access (fn, X_OK)) &&
198 if (0 != fstat (fh->
fd, &sbuf))
200 *
size = sbuf.st_size;
210 static int t[] = { SEEK_SET, SEEK_CUR, SEEK_END };
217 return lseek (
h->fd, offset,
t[whence]);
224 int include_symbolic_links,
225 int single_file_mode)
253 *ino = (uint64_t) sbuf.st_ino;
266 *dev = (uint64_t) fbuf.f_fsid;
277 ((uint64_t) fbuf.f_fsid.val[0]) << 32 || ((uint64_t) fbuf.f_fsid.val[1]);
299 if ((
t[0] !=
'/') && (
t[0] !=
'\\'))
302 tmpdir =
getenv (
"TMPDIR");
322 int require_uid_match,
323 int require_gid_match)
328 mode = S_IRUSR | S_IWUSR | S_IXUSR;
330 mode = S_IRUSR | S_IWUSR | S_IXUSR | S_IRGRP | S_IWGRP | S_IXGRP;
332 mode = S_IRUSR | S_IWUSR | S_IXUSR | S_IRGRP | S_IWGRP | S_IXGRP | S_IROTH
334 if (0 != chmod (fn,
mode))
345 omask = umask (S_IWGRP | S_IWOTH | S_IRGRP | S_IROTH);
347 if (fn != mkdtemp (fn))
366 slen = strlen (fil) + 20;
376 fd = open (target, O_CREAT | O_EXCL,
379 if (0 != renameat2 (AT_FDCWD, fil, AT_FDCWD, target, RENAME_EXCHANGE))
392 while (0 == access (target, F_OK));
393 if (0 != rename (fil, target))
410 omask = umask (S_IWGRP | S_IWOTH | S_IRGRP | S_IROTH);
412 if (-1 == (fd = mkstemp (fn)))
429 struct stat filestat;
432 ret = stat (fil, &filestat);
439 if (! S_ISDIR (filestat.st_mode))
442 "A file already exits with the same name %s\n",
447 ret = access (fil, R_OK | X_OK);
449 ret = access (fil, X_OK);
469 struct stat filestat;
477 ret = stat (rdir, &filestat);
489 if (! S_ISREG (filestat.st_mode))
494 if (access (rdir, amode) < 0)
551 "Creating directory `%s' failed\n",
578 "Creating directory `%s' failed\n",
586 S_IRUSR | S_IWUSR | S_IXUSR | S_IRGRP | S_IXGRP | S_IROTH
589 if ((
ret != 0) && (errno != EEXIST))
619 if (0 == access (rdir, W_OK))
636 (0 != access (rdir, W_OK)) )
655 return read (
h->fd,
result, len);
711 flags = fcntl (
h->fd, F_GETFL);
712 if (0 != (flags & O_NONBLOCK))
713 (void) fcntl (
h->fd, F_SETFL, flags - O_NONBLOCK);
714 ret = write (
h->fd, buffer, n);
715 if (0 == (flags & O_NONBLOCK))
716 (void) fcntl (
h->fd, F_SETFL, flags);
764 if (0 != unlink (tmpl))
780 if (0 != unlink (tmpl))
792 if (0 != unlink (tmpl))
799 if (0 != unlink (tmpl))
816 struct dirent *finfo;
821 unsigned int name_len;
828 while ((strlen (dname) > 0) && (dname[strlen (dname) - 1] ==
DIR_SEPARATOR))
829 dname[strlen (dname) - 1] =
'\0';
830 dinfo = opendir (dname);
840 while (NULL != (finfo = readdir (dinfo)))
842 if ((0 == strcmp (finfo->d_name,
".")) ||
843 (0 == strcmp (finfo->d_name,
"..")))
845 if (NULL != callback)
847 if (name_len < strlen (finfo->d_name))
850 name_len = strlen (finfo->d_name);
865 ret = callback (callback_cls,
name);
898 const char *str_pos = str;
900 const char *pat_pos = pattern;
902 const char *str_bt = NULL;
904 const char *pat_bt = NULL;
913 else if (*pat_pos == *str_pos)
915 if (
'\0' == *pat_pos)
926 str_pos = str_bt + 1;
927 if (
'\0' == *str_pos)
964 fn = (NULL == fn) ?
filename : (fn + 1);
967 "checking glob '%s' against '%s'\n",
976 "found glob match '%s'\n",
996 if ( (NULL != strrchr (glob_pattern,
'+')) ||
997 (NULL != strrchr (glob_pattern,
'[')) ||
998 (NULL != strrchr (glob_pattern,
'~')) )
1001 "unsupported glob pattern: '%s'\n",
1016 if (NULL != strchr (mypat,
'*'))
1021 "glob pattern may only contain '*' in the final path component\n");
1029 .cls = callback_cls,
1033 "scanning directory '%s' for glob matches on '%s'\n",
1077 S_IWUSR | S_IRUSR | S_IXUSR);
1080 if ( (errno != EISDIR) &&
1146 if (len >
size - pos)
1149 if ((sret < 0) || (len != (
size_t) sret))
1152 if ((sret < 0) || (len != (
size_t) sret))
1174 for (idx = fn; *idx; idx++)
1178 if ((c ==
'/') || (c ==
'\\') || (c ==
':') || (c ==
'*') || (c ==
'?') ||
1182 (c ==
'<') || (c ==
'>') || (c ==
'|') )
1196 pws = getpwnam (user);
1200 _ (
"Cannot obtain information about user `%s': %s\n"),
1205 if (0 != chown (
filename, pws->pw_uid, pws->pw_gid))
1244 oflags |= (O_CREAT | O_EXCL);
1300 if (0 != close (
h->fd))
1315 if ((((off_t) -1) == lseek (fno, 0, SEEK_CUR)) && (EBADF == errno))
1356#define MAP_FAILED ((void *) -1)
1379 (*m)->addr = mmap (NULL, len, prot, MAP_SHARED,
h->fd, 0);
1416#if ! defined(__linux__) || ! defined(GNU)
1429#if HAVE_PIPE2 && O_CLOEXEC
1430 if (-1 == pipe2 (
fd, O_CLOEXEC))
1432 if (-1 == pipe (
fd))
1458 p->fd[0]->fd =
fd[0];
1461 flags = fcntl (
fd[0], F_GETFL);
1462 flags |= O_NONBLOCK;
1463 if (0 > fcntl (
fd[0], F_SETFL, flags))
1469 flags = fcntl (
fd[0], F_GETFD);
1470 flags |= FD_CLOEXEC;
1471 if (0 > fcntl (
fd[0], F_SETFD, flags))
1481 p->fd[1]->fd =
fd[1];
1484 flags = fcntl (
fd[1], F_GETFL);
1485 flags |= O_NONBLOCK;
1486 if (0 > fcntl (
fd[1], F_SETFL, flags))
1492 flags = fcntl (
fd[1], F_GETFD);
1493 flags |= FD_CLOEXEC;
1494 if (0 > fcntl (
fd[1], F_SETFD, flags))
1504 if (
p->fd[0]->fd >= 0)
1506 if (
p->fd[1]->fd >= 0)
1577 int read_end_close_errno;
1578 int write_end_close_errno;
1581 read_end_close_errno = errno;
1583 write_end_close_errno = errno;
1588 errno = read_end_close_errno;
1589 ret = read_end_close;
1593 errno = write_end_close_errno;
1594 ret = write_end_close;
1640 const char *option = cls;
static enum GNUNET_GenericReturnValue get_size_rec(void *cls, const char *fn)
Iterate over all files in the given directory and accumulate their size.
#define COPY_BLK_SIZE
Block size for IO for copying files.
static enum GNUNET_GenericReturnValue glob_cb(void *cls, const char *filename)
Function called with a filename.
#define LOG_STRERROR_FILE(kind, syscall, filename)
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 file_test_internal(const char *fil, int amode)
Check if fil can be accessed using amode.
static bool glob_match(const char *pattern, const char *str)
Check for a simple wildcard match.
static enum GNUNET_GenericReturnValue purge_cfg_dir(void *cls, const struct GNUNET_CONFIGURATION_Handle *cfg)
Helper function for GNUNET_DISK_purge_cfg_dir.
static char * mktemp_name(const char *t)
Create the name for a temporary file or directory from a template.
#define LOG_STRERROR(kind, syscall)
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_internal_file_handle_(const struct GNUNET_DISK_FileHandle *fh, int *dst)
Retrieve OS file handle.
Internal DISK related helper functions.
static struct GNUNET_ARM_MonitorHandle * m
Monitor connection with ARM.
static struct GNUNET_ARM_Handle * h
Connection with ARM.
static int ret
Final status code.
static struct GNUNET_CONFIGURATION_Handle * cfg
Our configuration.
static char * dir
Set to the directory where runtime files are stored.
static int end
Set if we are to shutdown all services (including ARM).
static const char * dir_name
Top-level directory we monitor to auto-publish.
static char * cfg_filename
Name of the configuration file.
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.
static struct GNUNET_SCHEDULER_Task * t
Main task.
static enum @44 mode
Should we do a PUT (mode = 0) or GET (mode = 1);.
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.
struct GNUNET_DISK_FileHandle * GNUNET_DISK_file_open(const char *fn, enum GNUNET_DISK_OpenFlags flags, enum GNUNET_DISK_AccessPermissions perm)
Open a file.
void GNUNET_DISK_filename_canonicalize(char *fn)
Removes special characters as ':' from a filename.
int GNUNET_DISK_glob(const char *glob_pattern, GNUNET_FileNameCallback callback, void *callback_cls)
Find all files matching a glob pattern.
enum GNUNET_GenericReturnValue GNUNET_DISK_file_change_owner(const char *filename, const char *user)
Change owner of a file.
char * GNUNET_DISK_mktemp(const char *t)
Create an (empty) temporary file on disk.
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_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...
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 ...
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.
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.
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.
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.
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.
struct GNUNET_DISK_PipeHandle * GNUNET_DISK_pipe(enum GNUNET_DISK_PipeFlags pf)
Creates an interprocess channel.
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_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).
GNUNET_DISK_AccessPermissions
File access permissions, UNIX-style.
enum GNUNET_GenericReturnValue GNUNET_DISK_pipe_close(struct GNUNET_DISK_PipeHandle *p)
Closes an interprocess channel.
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.
char * GNUNET_DISK_mkdtemp(const char *t)
Create an (empty) temporary directory on disk.
enum GNUNET_GenericReturnValue GNUNET_DISK_file_copy(const char *src, const char *dst)
Copy a file.
enum GNUNET_GenericReturnValue GNUNET_DISK_directory_remove(const char *filename)
Remove all files in a directory (rm -rf).
enum GNUNET_GenericReturnValue GNUNET_DISK_file_sync(const struct GNUNET_DISK_FileHandle *h)
Write file changes to disk.
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.
enum GNUNET_GenericReturnValue GNUNET_DISK_directory_test(const char *fil, int is_readable)
Test if fil is a directory and listable.
enum GNUNET_GenericReturnValue GNUNET_DISK_file_close(struct GNUNET_DISK_FileHandle *h)
Close an open file.
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.
struct GNUNET_DISK_FileHandle * GNUNET_DISK_get_handle_from_native(FILE *fd)
Get a handle from a native FD.
enum GNUNET_GenericReturnValue GNUNET_DISK_directory_create_for_file(const char *filename)
Create the directory structure for storing a file.
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.
struct GNUNET_DISK_FileHandle * GNUNET_DISK_get_handle_from_int_fd(int fno)
Get a handle from a native integer FD.
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.
enum GNUNET_GenericReturnValue GNUNET_DISK_file_handle_size(struct GNUNET_DISK_FileHandle *fh, off_t *size)
Get the size of an open file.
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.
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_file_unmap(struct GNUNET_DISK_MapHandle *h)
Unmap a file.
enum GNUNET_GenericReturnValue GNUNET_DISK_directory_create(const char *dir)
Implementation of "mkdir -p".
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.
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.
@ 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.
#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
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.
static unsigned int size
Size of the "table".
Handle used to access files (and pipes).
int fd
File handle on Unix-like systems.
Handle for a memory-mapping operation.
void * addr
Address where the map is in memory.
size_t len
Number of bytes mapped.
Handle used to manage a pipe.
struct GNUNET_DISK_FileHandle * fd[2]
File descriptors for the pipe.
Project-specific data used to help the OS subsystem find installation paths.
Closure for the recursion to determine the file size of a directory.
uint64_t total
Set to the total file size.
int include_sym_links
GNUNET_YES if symbolic links should be included.
int single_file_mode
GNUNET_YES if mode is file-only (return total == -1 for directories).
GNUNET_FileNameCallback cb
int nres
Number of files that actually matched the glob pattern.