24RCSID(
"$Id: 3f8b7bc786dee6703308a2e0b3e3c7624ccc7844 $")
 
   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;
 
 
  437        struct stat stat_buf;
 
  442        if (
try[0] == 
'.') 
return false;
 
  453                if (!len) 
return false;
 
  483        if (!len) 
return false;
 
  488        if ((len > 10) && (strncmp(&
try[len - 10], 
".dpkg-dist", 10) == 0)) 
return false;
 
  489        if ((len > 9) && (strncmp(&
try[len - 9], 
".dpkg-old", 9) == 0)) 
return false;
 
  490        if ((len > 7) && (strncmp(&
try[len - 7], 
".rpmnew", 9) == 0)) 
return false;
 
  491        if ((len > 8) && (strncmp(&
try[len - 8], 
".rpmsave", 10) == 0)) 
return false;
 
  502        room = (iter->
path + PATH_MAX) - filename;
 
  504        if (
strlcpy(filename, 
try, room) >= room) 
return false;
 
  509        if (stat(iter->
path, &stat_buf) != 0) {
 
  513        if (S_ISREG(stat_buf.st_mode)) {
 
  514                if ((stat_buf.st_mode & (S_IXUSR | S_IXGRP | S_IXOTH)) != 0) {
 
  517        } 
else if (!S_ISLNK(stat_buf.st_mode)) { 
 
 
  540                dp = readdir(iter->dir);
 
  542                        if (errno != 0) 
return -1;
 
  573        iter->
path = malloc(PATH_MAX);
 
  593                        while (*p == 
'/') p++;
 
  599                if ((
size_t) (q - iter->
path) >= PATH_MAX) {
 
  620                if ((
size_t) (q - iter->
path) >= PATH_MAX) {
 
  639                        if (!slash) 
continue;
 
  646                while (*p == 
'/') p++;
 
  667                if ((p[1] == 
'.') && (p[2] == 
'/')) {
 
 
  709        for (p = pattern; *p != 
'\0'; p++) {
 
  717                        iter->
type = FR_GLOBDIR_DIR;
 
  735                if ((*p == 
'*') || (*p == 
'?') || (*p == 
'[')) {
 
  740                        if ((pattern[0] != 
'/') && (dir[0] != 
'/')) {
 
  745                        iter->
type = FR_GLOBDIR_GLOB;
 
  757        if (pattern[0] == 
'/') {
 
  780                to_open = iter->
path;
 
  787        switch (iter->
type) {
 
  794                *filename = iter->
path;
 
  802                iter->dir = opendir(to_open);
 
  808                if (fr_globdir_dir_next(filename, iter) < 0) {
 
  816        case FR_GLOBDIR_GLOB:
 
  817                if (glob(to_open, GLOB_NOESCAPE | GLOB_ERR, NULL, &iter->glob) < 0) {
 
  822                if (iter->glob.gl_pathc == 0) {
 
  825                        iter->gl_current = 0;
 
  830                        *filename = iter->glob.gl_pathv[iter->gl_current];
 
  836        return 0 + (*filename != NULL);
 
 
  854        switch (iter->
type) {
 
  864                if (fr_globdir_dir_next(filename, iter) < 0) 
return -1;
 
  866                return 0 + (*filename != NULL);
 
  870        case FR_GLOBDIR_GLOB:
 
  872                if (iter->gl_current >= iter->glob.gl_pathc) {
 
  876                *filename = iter->glob.gl_pathv[iter->gl_current];
 
 
  893        switch (iter->
type) {
 
  902                if (!iter->dir) 
return 0;
 
  904                return closedir(iter->dir);
 
  908        case FR_GLOBDIR_GLOB:
 
  909                globfree(&iter->glob);
 
 
#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_globdir_iter_init(char const **filename, char const *dir, char const *pattern, fr_globdir_iter_t *iter)
Initialize an iterator over filenames.
static int fr_globdir_get_path(char const *dir, char const *pattern, fr_globdir_iter_t *iter)
Create a full path from dir + pattern.
int fr_mkdir_chown(int fd, char const *path, void *uctx)
Callback for the common case of chown() of the directory.
static bool fr_globdir_file_ok(char const *try, fr_globdir_iter_t *iter)
ssize_t fr_touch(int *fd_out, char const *filename, mode_t mode, bool mkdir, mode_t dir_mode)
Create an empty file.
int fr_globdir_iter_next(char const **filename, fr_globdir_iter_t *iter)
Get the next filename.
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.
int fr_globdir_iter_free(fr_globdir_iter_t *iter)
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.
size_t fr_utf8_char(uint8_t const *str, ssize_t inlen)
Checks for utf-8, taken from http://www.w3.org/International/questions/qa-forms-utf-8.
size_t strlcpy(char *dst, char const *src, size_t siz)
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)