24 RCSID(
"$Id: 3cd094bcda33609a2ebb71ae3f93804ea74b261c $")
26 #include <sys/param.h>
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>
52 ret = mkdir(path, 0700);
54 fd = open(path, O_DIRECTORY);
59 p = strrchr(path, FR_DIR_SEP);
60 if (!p)
return start - path;
65 if (fchmod(fd, mode) < 0) {
85 if (errno == EEXIST) {
86 fd = open(path, O_DIRECTORY);
100 if (errno != ENOENT) {
112 p = strrchr(path, FR_DIR_SEP);
113 if (!p || (p == path))
return start - path;
116 if (
_fr_mkdir(fd_out, start, path, mode, func, uctx) <= 0)
return start - p;
118 fr_assert_msg((*fd_out) >= 0,
"Logic error - Bad FD %i", *fd_out);
127 if (mkdirat(*fd_out, p + 1, 0700) < 0) {
133 if (errno == EEXIST) {
134 fd = openat(*fd_out, p + 1, O_DIRECTORY);
152 fd = openat(*fd_out, p + 1, O_DIRECTORY);
159 if (fchmod(fd, mode) < 0) {
170 if (func && (func(fd, path, uctx) < 0)) {
183 return strlen(start);
206 if (len < 0) len = strlen(path);
207 if (len == 0)
return 0;
215 fd = open(path, O_DIRECTORY);
216 if (fd >= 0)
goto done;
235 slen =
_fr_mkdir(&fd, our_path, our_path, mode, func, uctx);
237 if (slen <= 0)
return slen;
267 char *tmp_path = NULL, *abs_path, *talloc_abs_path;
269 if (len > 0) path = tmp_path =
talloc_bstrndup(NULL, path, (
size_t)len);
271 abs_path = realpath(path, NULL);
281 talloc_abs_path = talloc_strdup(ctx, abs_path);
283 if (!talloc_abs_path) {
288 return talloc_abs_path;
307 fd = open(filename, O_WRONLY | O_CREAT, mode);
312 if (mkdir && (errno == ENOENT) && (q = strrchr(filename, FR_DIR_SEP))) {
315 slen =
fr_mkdir(&dir_fd, filename, q - filename, dir_mode, NULL, NULL);
316 if (slen <= 0)
return slen;
318 fd = openat(dir_fd, q + 1, O_WRONLY | O_CREAT, mode);
322 return strlen(filename);
325 slen = -(q - filename);
337 return strlen(filename);
349 if (unlink(filename) == 0)
return 0;
351 if (errno == ENOENT)
return 1;
367 static char our_wd[MAXPATHLEN];
370 if (!getcwd(our_wd,
sizeof(our_wd)))
return filename;
372 found = strstr(filename, our_wd);
373 if (found && (found == our_wd)) {
374 filename += strlen(our_wd);
375 while (*filename ==
'/') filename++;
393 int fr_dirfd(
int *dirfd,
char const **filename,
char const *pathname)
395 char const *last_slash = strrchr(pathname,
'/');
397 if (last_slash == NULL) {
398 *filename = pathname;
403 char dirpath[(last_slash - pathname) + 1];
405 memcpy(dirpath, pathname, last_slash - pathname);
406 dirpath[last_slash - pathname] =
'\0';
407 *filename = last_slash + 1;
408 *dirfd = open(dirpath, O_DIRECTORY);
409 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.
ssize_t fr_touch(int *fd_out, char const *filename, mode_t mode, bool mkdir, mode_t dir_mode)
Create an empty file.
char * fr_realpath(TALLOC_CTX *ctx, char const *path, ssize_t len)
Convenience wrapper around realpath.
int fr_dirfd(int *dirfd, char const **filename, char const *pathname)
From a pathname, return fd and filename needed for *at() functions.
char const * fr_cwd_strip(char const *filename)
Intended to be used in logging functions to make output more readable.
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)