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 44 #include <sys/types.h> 49 #include <sys/param.h> 52 #include <sys/mount.h> 54 #if HAVE_SYS_STATVFS_H 55 #include <sys/statvfs.h> 60 #define _IFLNK 0120000 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 != stat64 (fn, &buf))
162 if (0 != stat (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)
249 if (0 != stat (filename, &sbuf))
253 *ino = (uint64_t) sbuf.st_ino;
262 if (0 != statvfs (filename, &fbuf))
266 *dev = (uint64_t) fbuf.f_fsid;
272 if (0 != statfs (filename, &fbuf))
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;
373 while (0 == access (target, F_OK));
374 if (0 != rename (fil, target))
387 omask = umask (S_IWGRP | S_IWOTH | S_IRGRP | S_IROTH);
389 if (-1 == (fd = mkstemp (fn)))
406 struct stat filestat;
409 ret = stat (fil, &filestat);
416 if (! S_ISDIR (filestat.st_mode))
419 "A file already exits with the same name %s\n",
424 ret = access (fil, R_OK | X_OK);
426 ret = access (fil, X_OK);
439 struct stat filestat;
447 ret = stat (rdir, &filestat);
459 if (! S_ISREG (filestat.st_mode))
464 if (access (rdir, F_OK) < 0)
507 "Creating directory `%s' failed",
534 "Creating directory `%s' failed",
542 S_IRUSR | S_IWUSR | S_IXUSR | S_IRGRP | S_IXGRP | S_IROTH
545 if ((ret != 0) && (errno != EEXIST))
575 if (0 == access (rdir, W_OK))
592 (0 != access (rdir, W_OK)) )
611 return read (h->
fd, result, len);
629 flags = fcntl (h->
fd, F_GETFL);
630 if (0 == (flags & O_NONBLOCK))
631 (void) fcntl (h->
fd, F_SETFL, flags | O_NONBLOCK);
632 ret = read (h->
fd, result, len);
633 if (0 == (flags & O_NONBLOCK))
636 (void) fcntl (h->
fd, F_SETFL, flags);
676 return write (h->
fd, buffer, n);
694 flags = fcntl (h->
fd, F_GETFL);
695 if (0 != (flags & O_NONBLOCK))
696 (void) fcntl (h->
fd, F_SETFL, flags - O_NONBLOCK);
697 ret = write (h->
fd, buffer, n);
698 if (0 == (flags & O_NONBLOCK))
699 (void) fcntl (h->
fd, F_SETFL, flags);
747 if (0 != unlink (tmpl))
763 if (0 != unlink (tmpl))
775 if (0 != unlink (tmpl))
782 if (0 != unlink (tmpl))
799 struct dirent *finfo;
805 unsigned int name_len;
812 while ((strlen (dname) > 0) && (dname[strlen (dname) - 1] ==
DIR_SEPARATOR))
813 dname[strlen (dname) - 1] =
'\0';
814 if (0 != stat (dname, &istat))
820 if (! S_ISDIR (istat.st_mode))
823 _ (
"Expected `%s' to be a directory!\n"),
829 dinfo = opendir (dname);
830 if ((EACCES == errno) || (NULL == dinfo))
841 while (NULL != (finfo = readdir (dinfo)))
843 if ((0 == strcmp (finfo->d_name,
".")) ||
844 (0 == strcmp (finfo->d_name,
"..")))
846 if (NULL != callback)
848 if (name_len < strlen (finfo->d_name))
851 name_len = strlen (finfo->d_name);
866 ret = callback (callback_cls, name);
909 if (NULL == filename)
914 if (0 != lstat (filename, &istat))
916 (void) chmod (filename,
917 S_IWUSR | S_IRUSR | S_IXUSR);
918 if (0 == unlink (filename))
920 if ( (errno != EISDIR) &&
934 if (0 != rmdir (filename))
986 if (len > size - pos)
989 if ((sret < 0) || (len != (
size_t) sret))
992 if ((sret < 0) || (len != (
size_t) sret))
1014 for (idx = fn; *idx; idx++)
1018 if ((c ==
'/') || (c ==
'\\') || (c ==
':') || (c ==
'*') || (c ==
'?') ||
1022 (c ==
'<') || (c ==
'>') || (c ==
'|') )
1036 pws = getpwnam (user);
1040 _ (
"Cannot obtain information about user `%s': %s\n"),
1045 if (0 != chown (filename, pws->pw_uid, pws->pw_gid))
1084 oflags |= (O_CREAT | O_EXCL);
1108 if (0 == (flags & GNUNET_DISK_OPEN_FAILIFEXISTS))
1137 if (0 != close (h->
fd))
1152 if ((((off_t) -1) == lseek (fno, 0, SEEK_CUR)) && (EBADF == errno))
1193 #define MAP_FAILED ((void *) -1) 1216 (*m)->addr = mmap (NULL, len, prot, MAP_SHARED, h->
fd, 0);
1253 #if ! defined(__linux__) || ! defined(GNU) 1266 if (-1 == pipe (fd))
1291 p->
fd[0]->
fd = fd[0];
1294 flags = fcntl (fd[0], F_GETFL);
1295 flags |= O_NONBLOCK;
1296 if (0 > fcntl (fd[0], F_SETFL, flags))
1302 flags = fcntl (fd[0], F_GETFD);
1303 flags |= FD_CLOEXEC;
1304 if (0 > fcntl (fd[0], F_SETFD, flags))
1314 p->
fd[1]->
fd = fd[1];
1317 flags = fcntl (fd[1], F_GETFL);
1318 flags |= O_NONBLOCK;
1319 if (0 > fcntl (fd[1], F_SETFL, flags))
1325 flags = fcntl (fd[1], F_GETFD);
1326 flags |= FD_CLOEXEC;
1327 if (0 > fcntl (fd[1], F_SETFD, flags))
1337 if (p->
fd[0]->
fd >= 0)
1339 if (p->
fd[1]->
fd >= 0)
1410 int write_end_close;
1411 int read_end_close_errno;
1412 int write_end_close_errno;
1415 read_end_close_errno = errno;
1417 write_end_close_errno = errno;
1422 errno = read_end_close_errno;
1423 ret = read_end_close;
1427 errno = write_end_close_errno;
1428 ret = write_end_close;
1459 if (dst_len <
sizeof(
int))
1461 *((
int *) dst) = fh->
fd;
1477 const char *
option = cls;
void GNUNET_DISK_purge_cfg_dir(const char *cfg_filename, const char *option)
Remove the directory given under option in section [PATHS] in configuration under cfg_filename...
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_file_handle_size(struct GNUNET_DISK_FileHandle *fh, off_t *size)
Get the size of an open file.
Open the file for reading.
static char * cfg_filename
Name of the configuration file.
static char * dir
Set to the directory where runtime files are stored.
Create file if it doesn't exist.
GNUNET_DISK_MapType
Specifies what type of memory map is desired.
void * addr
Address where the map is in memory.
static const char * dir_name
Top-level directory we monitor to auto-publish.
static const struct GNUNET_CONFIGURATION_Handle * cfg
Configuration we are using.
static int end
Set if we are to shutdown all services (including ARM).
uint64_t total
Set to the total file size.
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...
int single_file_mode
GNUNET_YES if mode is file-only (return total == -1 for directories).
Closure for the recursion to determine the file size of a directory.
enum GNUNET_GenericReturnValue GNUNET_DISK_file_unmap(struct GNUNET_DISK_MapHandle *h)
Unmap 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.
#define GNUNET_assert(cond)
Use this for fatal errors that cannot be handled.
enum GNUNET_GenericReturnValue GNUNET_DISK_file_close(struct GNUNET_DISK_FileHandle *h)
Close an open 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.
Nobody is allowed to do anything to the file.
static int ret
Return value of the commandline.
GNUNET_DISK_Seek
Constants for specifying how to seek.
GNUNET_GenericReturnValue
Named constants for return values.
static enum GNUNET_GenericReturnValue remove_helper(void *unused, const char *fn)
Function that removes the given directory by calling GNUNET_DISK_directory_remove().
#define GNUNET_new(type)
Allocate a struct or union of the given type.
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.
int GNUNET_DISK_directory_scan(const char *dir_name, GNUNET_FileNameCallback callback, void *callback_cls)
Scan a directory for files.
static struct GNUNET_SCHEDULER_Task * t
Main task.
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.
static enum @8 mode
Should we do a PUT (mode = 0) or GET (mode = 1);.
#define GNUNET_strdup(a)
Wrapper around GNUNET_xstrdup_.
#define LOG_STRERROR(kind, syscall)
static int translate_unix_perms(enum GNUNET_DISK_AccessPermissions perm)
Translate GNUnet-internal permission bitmap to UNIX file access permission bitmap.
#define GNUNET_break(cond)
Use this for internal assertion violations that are not fatal (can be handled) but should not occur...
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.
static struct GNUNET_ARM_Handle * h
Connection with ARM.
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.
static struct GNUNET_ARM_MonitorHandle * m
Monitor connection with ARM.
struct GNUNET_DISK_FileHandle * fd[2]
File descriptors for the pipe.
char * GNUNET_DISK_mktemp(const char *t)
Create an (empty) temporary file on disk.
static struct GNUNET_OS_Process * p
Helper process we started.
void GNUNET_log_config_missing(enum GNUNET_ErrorType kind, const char *section, const char *option)
Log error message about missing configuration option.
size_t len
Number of bytes mapped.
enum GNUNET_GenericReturnValue GNUNET_DISK_file_copy(const char *src, const char *dst)
Copy a file.
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.
#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...
static char * fn
Filename of the unique file.
Truncate file if it exists.
#define COPY_BLK_SIZE
Block size for IO for copying files.
enum GNUNET_GenericReturnValue GNUNET_DISK_pipe_close(struct GNUNET_DISK_PipeHandle *p)
Closes an interprocess channel.
ssize_t GNUNET_DISK_file_write(const struct GNUNET_DISK_FileHandle *h, const void *buffer, size_t n)
Write a buffer to a file.
static char * option
Name of the option.
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.
static int result
Global testing status.
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.
GNUNET_DISK_AccessPermissions
File access permissions, UNIX-style.
The writing-end of a pipe.
int include_sym_links
GNUNET_YES if symbolic links should be included.
The reading-end of a pipe.
enum GNUNET_GenericReturnValue GNUNET_DISK_directory_create(const char *dir)
Implementation of "mkdir -p".
static int fh
Handle to the unique file.
void GNUNET_DISK_file_backup(const char *fil)
Move a file out of the way (create a backup) by renaming it to "orig.NUM~" where NUM is the smallest ...
enum GNUNET_GenericReturnValue GNUNET_DISK_file_change_owner(const char *filename, const char *user)
Change owner of a file.
static enum GNUNET_GenericReturnValue purge_cfg_dir(void *cls, const struct GNUNET_CONFIGURATION_Handle *cfg)
Helper function for GNUNET_DISK_purge_cfg_dir.
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.
struct GNUNET_DISK_PipeHandle * GNUNET_DISK_pipe(enum GNUNET_DISK_PipeFlags pf)
Creates an interprocess channel.
int int GNUNET_asprintf(char **buf, const char *format,...) __attribute__((format(printf
Like asprintf, just portable.
GNUNET_DISK_PipeFlags
Flags for GNUNET_DISK_pipe().
static unsigned int size
Size of the "table".
Open the file for writing.
char * GNUNET_DISK_mkdtemp(const char *t)
Create an (empty) temporary directory on disk.
char * GNUNET_STRINGS_filename_expand(const char *fil)
Complete filename (a la shell) from abbrevition.
Configure write end to block when writing if set.
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.
enum GNUNET_GenericReturnValue GNUNET_DISK_handle_invalid(const struct GNUNET_DISK_FileHandle *h)
Checks whether a handle is invalid.
enum GNUNET_GenericReturnValue GNUNET_DISK_internal_file_handle_(const struct GNUNET_DISK_FileHandle *fh, void *dst, size_t dst_len)
Retrieve OS file handle.
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).
#define LOG_STRERROR_FILE(kind, syscall, filename)
struct GNUNET_DISK_FileHandle * GNUNET_DISK_get_handle_from_int_fd(int fno)
Get a handle from a native integer FD.
enum GNUNET_GenericReturnValue GNUNET_DISK_file_sync(const struct GNUNET_DISK_FileHandle *h)
Write file changes to disk.
enum GNUNET_GenericReturnValue(* GNUNET_FileNameCallback)(void *cls, const char *filename)
Function called with a filename.
#define GNUNET_log(kind,...)
GNUNET_DISK_OpenFlags
Specifies how a file should be opened.
Open the file for both reading and writing.
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.
static char * mktemp_name(const char *t)
Create the name for a temporary file or directory from a template.
int fd
File handle on Unix-like systems.
Fail if file already exists.
enum GNUNET_GenericReturnValue GNUNET_DISK_directory_remove(const char *filename)
Remove all files in a directory (rm -rf).
ssize_t GNUNET_DISK_file_read_non_blocking(const struct GNUNET_DISK_FileHandle *h, void *result, size_t len)
Read the contents of a binary file into a buffer.
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.
struct GNUNET_DISK_FileHandle * GNUNET_DISK_file_open(const char *fn, enum GNUNET_DISK_OpenFlags flags, enum GNUNET_DISK_AccessPermissions perm)
Open a file.
GNUNET_DISK_PipeEnd
Enumeration identifying the two ends of a pipe.
Handle used to access files (and pipes).
enum GNUNET_GenericReturnValue GNUNET_DISK_directory_test(const char *fil, int is_readable)
Test if fil is a directory and listable.
Handle used to manage a pipe.
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)...
#define GNUNET_malloc(size)
Wrapper around malloc.
ssize_t GNUNET_DISK_fn_read(const char *fn, void *result, size_t len)
Read the contents of a binary file into a buffer.
void GNUNET_DISK_filename_canonicalize(char *fn)
Removes special characters as ':' from a filename.
Handle for a memory-mapping operation.
Internal DISK related helper functions.
#define GNUNET_free(ptr)
Wrapper around free.
uint16_t len
length of data (which is always a uint32_t, but presumably this can be used to specify that fewer byt...
Configure read end to block when reading if set.
enum GNUNET_GenericReturnValue GNUNET_CONFIGURATION_parse_and_run(const char *filename, GNUNET_CONFIGURATION_Callback cb, void *cb_cls)
Parse a configuration file filename and run the function cb with the resulting configuration object...