dovecot-1.2: Added mkdir_parents_chown().
dovecot at dovecot.org
dovecot at dovecot.org
Sun Jul 20 23:20:23 EEST 2008
details: http://hg.dovecot.org/dovecot-1.2/rev/ed12eee73357
changeset: 8035:ed12eee73357
user: Timo Sirainen <tss at iki.fi>
date: Sun Jul 20 23:19:25 2008 +0300
description:
Added mkdir_parents_chown().
diffstat:
2 files changed, 46 insertions(+), 15 deletions(-)
src/lib/mkdir-parents.c | 57 ++++++++++++++++++++++++++++++++++-------------
src/lib/mkdir-parents.h | 4 +++
diffs (96 lines):
diff -r b3efdd9dc293 -r ed12eee73357 src/lib/mkdir-parents.c
--- 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);
+}
diff -r b3efdd9dc293 -r ed12eee73357 src/lib/mkdir-parents.h
--- 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
More information about the dovecot-cvs
mailing list