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