Mercurial > dovecot > original-hg > dovecot-1.2
changeset 8035:ed12eee73357 HEAD
Added mkdir_parents_chown().
author | Timo Sirainen <tss@iki.fi> |
---|---|
date | Sun, 20 Jul 2008 23:19:25 +0300 |
parents | b3efdd9dc293 |
children | b3303b65c3f2 |
files | src/lib/mkdir-parents.c src/lib/mkdir-parents.h |
diffstat | 2 files changed, 46 insertions(+), 15 deletions(-) [+] |
line wrap: on
line diff
--- a/src/lib/mkdir-parents.c Sun Jul 20 23:03:09 2008 +0300 +++ b/src/lib/mkdir-parents.c Sun Jul 20 23:19:25 2008 +0300 @@ -4,38 +4,65 @@ #include "mkdir-parents.h" #include <sys/stat.h> +#include <unistd.h> -int mkdir_parents(const char *path, mode_t mode) +static int mkdir_chown(const char *path, mode_t mode, uid_t uid, gid_t gid) +{ + mode_t old_mask; + int ret; + + old_mask = umask(0); + ret = mkdir(path, mode); + umask(old_mask); + + if (ret < 0) { + if (errno == EISDIR || errno == ENOSYS) { + /* EISDIR check is for BSD/OS which returns it if path + contains '/' at the end and it exists. + + ENOSYS check is for NFS mount points. */ + errno = EEXIST; + } + return -1; + } + if (chown(path, uid, gid) < 0) { + i_error("chown(%s, %ld, %ld) failed: %m", path, + uid == (uid_t)-1 ? -1L : (long)uid, + gid == (gid_t)-1 ? -1L : (long)gid); + return -1; + } + return 0; +} + +int mkdir_parents_chown(const char *path, mode_t mode, uid_t uid, gid_t gid) { const char *p; int ret; - if (mkdir(path, mode) == 0) { - /* success */ - } else if (errno != ENOENT) { - /* EISDIR check is for BSD/OS which returns it if path - contains '/' at the end and it exists. + if (mkdir_chown(path, mode, uid, gid) < 0) { + if (errno != ENOENT) + return -1; - ENOSYS check is for NFS mount points. - */ - if (errno == EISDIR && errno == ENOSYS) - errno = EEXIST; - return -1; - } else { + /* doesn't exist, try recursively creating our parent dir */ p = strrchr(path, '/'); if (p == NULL || p == path) return -1; /* shouldn't happen */ T_BEGIN { - ret = mkdir_parents(t_strdup_until(path, p), mode); + ret = mkdir_parents_chown(t_strdup_until(path, p), + mode, uid, gid); } T_END; if (ret < 0) return -1; /* should work now */ - if (mkdir(path, mode) < 0 && errno != EEXIST && errno != EISDIR) + if (mkdir_chown(path, mode, uid, gid) < 0) return -1; } - return 0; } + +int mkdir_parents(const char *path, mode_t mode) +{ + return mkdir_parents_chown(path, mode, (uid_t)-1, (gid_t)-1); +}
--- a/src/lib/mkdir-parents.h Sun Jul 20 23:03:09 2008 +0300 +++ b/src/lib/mkdir-parents.h Sun Jul 20 23:19:25 2008 +0300 @@ -6,4 +6,8 @@ exists, returns -1 with errno=EXIST. */ int mkdir_parents(const char *path, mode_t mode); +/* Like mkdir_parents(), but use the given uid/gid for newly created + directories. */ +int mkdir_parents_chown(const char *path, mode_t mode, uid_t uid, gid_t gid); + #endif