24RCSID(
"$Id: 2ac616577d4367233b5c8a828bad0f6d5731e743 $")
31#include <freeradius-devel/util/file.h>
32#include <freeradius-devel/util/strerror.h>
33#include <freeradius-devel/util/syserror.h>
34#include <freeradius-devel/util/value.h>
43 if ((ctx->
uid == (uid_t) -1) && (ctx->
gid == (gid_t) -1))
return 0;
45 if (fchown(fd, ctx->
uid, ctx->
gid) < 0) {
71 ret = mkdir(path, 0700);
73 fd = open(path, O_DIRECTORY);
78 p = strrchr(path, FR_DIR_SEP);
79 if (!p)
return start - path;
84 if (fchmod(fd, mode) < 0) {
104 if (errno == EEXIST) {
105 fd = open(path, O_DIRECTORY);
111 return strlen(start);
119 if (errno != ENOENT) {
131 p = strrchr(path, FR_DIR_SEP);
132 if (!p || (p == path))
return start - path;
135 if (
_fr_mkdir(fd_out, start, path, mode, func, uctx) <= 0)
return start - p;
137 fr_assert_msg((*fd_out) >= 0,
"Logic error - Bad FD %i", *fd_out);
146 if (mkdirat(*fd_out, p + 1, 0700) < 0) {
152 if (errno == EEXIST) {
153 fd = openat(*fd_out, p + 1, O_DIRECTORY);
171 fd = openat(*fd_out, p + 1, O_DIRECTORY);
178 if (fchmod(fd, mode) < 0) {
189 if (func && (func(fd, path, uctx) < 0)) {
202 return strlen(start);
225 if (len < 0) len = strlen(path);
226 if (len == 0)
return 0;
234 fd = open(path, O_DIRECTORY);
235 if (fd >= 0)
goto done;
254 slen =
_fr_mkdir(&fd, our_path, our_path, mode, func, uctx);
256 if (slen <= 0)
return slen;
286 char *tmp_path = NULL, *abs_path, *talloc_abs_path;
288 if (len > 0) path = tmp_path =
talloc_bstrndup(NULL, path, (
size_t)len);
290 abs_path = realpath(path, NULL);
300 talloc_abs_path = talloc_strdup(ctx, abs_path);
302 if (!talloc_abs_path) {
307 return talloc_abs_path;
326 fd = open(filename, O_WRONLY | O_CREAT, mode);
331 if (mkdir && (errno == ENOENT) && (q = strrchr(filename, FR_DIR_SEP))) {
334 slen =
fr_mkdir(&dir_fd, filename, q - filename, dir_mode, NULL, NULL);
335 if((slen <= 0) || (dir_fd < 0))
return slen;
337 fd = openat(dir_fd, q + 1, O_WRONLY | O_CREAT, mode);
341 return strlen(filename);
344 slen = -(q - filename);
356 return strlen(filename);
368 if (unlink(filename) == 0)
return 0;
370 if (errno == ENOENT)
return 1;
386 static char our_wd[MAXPATHLEN];
389 if (!getcwd(our_wd,
sizeof(our_wd)))
return filename;
391 found = strstr(filename, our_wd);
392 if (found && (found == our_wd)) {
393 filename += strlen(our_wd);
394 while (*filename ==
'/') filename++;
412int fr_dirfd(
int *dirfd,
char const **filename,
char const *pathname)
414 char const *last_slash = strrchr(pathname,
'/');
416 if (last_slash == NULL) {
417 *filename = pathname;
422 char dirpath[(last_slash - pathname) + 1];
424 memcpy(dirpath, pathname, last_slash - pathname);
425 dirpath[last_slash - pathname] =
'\0';
426 *filename = last_slash + 1;
427 *dirfd = open(dirpath, O_DIRECTORY);
428 return (*dirfd < 0) ? -1 : 0;
#define fr_assert_msg(_x, _msg,...)
Calls panic_action ifndef NDEBUG, else logs error and causes the server to exit immediately with code...
ssize_t fr_mkdir(int *fd_out, char const *path, ssize_t len, mode_t mode, fr_mkdir_func_t func, void *uctx)
Create directories that are missing in the specified path.
int fr_unlink(char const *filename)
Remove a regular file from the filesystem.
int fr_mkdir_chown(int fd, char const *path, void *uctx)
Callback for the common case of chown() of the directory.
ssize_t fr_touch(int *fd_out, char const *filename, mode_t mode, bool mkdir, mode_t dir_mode)
Create an empty file.
char const * fr_cwd_strip(char const *filename)
Intended to be used in logging functions to make output more readable.
int fr_dirfd(int *dirfd, char const **filename, char const *pathname)
From a pathname, return fd and filename needed for *at() functions.
char * fr_realpath(TALLOC_CTX *ctx, char const *path, ssize_t len)
Convenience wrapper around realpath.
static ssize_t _fr_mkdir(int *fd_out, char *start, char *path, mode_t mode, fr_mkdir_func_t func, void *uctx)
int(* fr_mkdir_func_t)(int fd, char const *path, void *uctx)
Callback for allowing additional operations on newly created directories.
char const * fr_syserror(int num)
Guaranteed to be thread-safe version of strerror.
char * talloc_bstrndup(TALLOC_CTX *ctx, char const *in, size_t inlen)
Binary safe strndup function.
void fr_strerror_clear(void)
Clears all pending messages from the talloc pools.
#define fr_strerror_printf(_fmt,...)
Log to thread local error buffer.
#define fr_strerror_printf_push(_fmt,...)
Add a message to an existing stack of messages at the tail.
#define fr_strerror_const(_msg)
#define fr_box_strvalue_buffer(_val)