Sophie

Sophie

distrib > Scientific%20Linux > 5x > x86_64 > by-pkgid > 130701790bf2d95e902edf16031ff596 > files > 144

autofs-5.0.1-0.rc2.164.el5_8.src.rpm

diff --git a/CHANGELOG b/CHANGELOG
index 6007086..04d8159 100644
--- a/CHANGELOG
+++ b/CHANGELOG
@@ -26,6 +26,7 @@
 - fix get_query_dn not looking in subtree for LDAP search (missed second
   occurance).
 - allow additional common LDAP attributes in map dn.
+- deal with changed semantics of mkdir in 2.6.19.
 
 1/9/2006 autofs-5.0.1 rc2
 -------------------------
diff --git a/daemon/automount.c b/daemon/automount.c
index 343fd68..ccb8021 100644
--- a/daemon/automount.c
+++ b/daemon/automount.c
@@ -72,33 +72,70 @@ static int umount_all(struct autofs_poin
 extern pthread_mutex_t master_mutex;
 extern struct master *master_list;
 
+static int do_mkdir(const char *parent, const char *path, mode_t mode)
+{
+	int status;
+	struct stat st;
+	struct statfs fs;
+
+	/* If path exists we're done */
+	status = stat(path, &st);
+	if (status == 0) {
+		if (!S_ISDIR(st.st_mode)) {
+			errno = ENOTDIR;
+			return 0;
+		}
+		return 1;
+	}
+
+	/*
+	 * If we're trying to create a directory within an autofs fs
+	 * of the path is contained in a localy mounted fs go ahead.
+	 */
+	status = -1;
+	if (*parent)
+		status = statfs(parent, &fs);
+	if ((status != -1 && fs.f_type == AUTOFS_SUPER_MAGIC) ||
+	    contained_in_local_fs(path)) {
+		if (mkdir(path, mode) == -1) {
+			if (errno == EEXIST)
+				return 1;
+			return 0;
+		}
+		return 1;
+	}
+
+	return 0;
+}
+
 int mkdir_path(const char *path, mode_t mode)
 {
 	char *buf = alloca(strlen(path) + 1);
+	char *parent = alloca(strlen(path) + 1);
 	const char *cp = path, *lcp = path;
-	char *bp = buf;
+	char *bp = buf, *pp = parent;
+
+	*parent = '\0';
 
 	do {
 		if (cp != path && (*cp == '/' || *cp == '\0')) {
 			memcpy(bp, lcp, cp - lcp);
 			bp += cp - lcp;
-			lcp = cp;
 			*bp = '\0';
-			if (mkdir(buf, mode) == -1) {
-				/* If it already exists, make sure it's a directory */
-				if (errno == EEXIST) {
-					struct stat st;
-
-					if (stat(buf, &st) == 0 && !S_ISDIR(st.st_mode))
-						errno = ENOTDIR;
-					else {
-						/* last component, return -1 */
-						if (*cp != '\0')
-							continue;
-					}
+			if (!do_mkdir(parent, buf, mode)) {
+				if (*cp != '\0') {
+					memcpy(pp, lcp, cp - lcp);
+					pp += cp - lcp;
+					*pp = '\0';
+					lcp = cp;
+					continue;
 				}
 				return -1;
 			}
+			memcpy(pp, lcp, cp - lcp);
+			pp += cp - lcp;
+			*pp = '\0';
+			lcp = cp;
 		}
 	} while (*cp++ != '\0');
 
diff --git a/daemon/indirect.c b/daemon/indirect.c
index 608f37b..492cbbb 100644
--- a/daemon/indirect.c
+++ b/daemon/indirect.c
@@ -171,7 +171,7 @@ static int do_mount_autofs_indirect(stru
 	if (mkdir_path(ap->path, 0555) < 0) {
 		if (errno != EEXIST && errno != EROFS) {
 			crit(ap->logopt,
-			     "failed to create iautofs directory %s",
+			     "failed to create autofs directory %s",
 			     ap->path);
 			goto out_err;
 		}
diff --git a/include/automount.h b/include/automount.h
index 9c2de00..798cc50 100644
--- a/include/automount.h
+++ b/include/automount.h
@@ -322,6 +322,7 @@ #define MNTS_AUTOFS	0x0004
 
 struct mnt_list {
 	char *path;
+	char *fs_name;
 	char *fs_type;
 	char *opts;
 	pid_t owner;
@@ -350,6 +351,7 @@ char *make_mnt_name_string(char *path);
 struct mnt_list *get_mnt_list(const char *table, const char *path, int include);
 struct mnt_list *reverse_mnt_list(struct mnt_list *list);
 void free_mnt_list(struct mnt_list *list);
+int contained_in_local_fs(const char *path);
 int is_mounted(const char *table, const char *path, unsigned int type);
 int has_fstab_option(const char *opt);
 char *find_mnt_ino(const char *table, dev_t dev, ino_t ino);
diff --git a/lib/mounts.c b/lib/mounts.c
index 46131cd..1e92ca5 100644
--- a/lib/mounts.c
+++ b/lib/mounts.c
@@ -170,9 +170,16 @@ struct mnt_list *get_mnt_list(const char
 		}
 		strcpy(ent->path, mnt->mnt_dir);
 
+		ent->fs_name = malloc(strlen(mnt->mnt_fsname) + 1);
+		if (!ent->fs_name) {
+			endmntent(tab);
+			free_mnt_list(list);
+			return NULL;
+		}
+		strcpy(ent->fs_name, mnt->mnt_fsname);
+
 		ent->fs_type = malloc(strlen(mnt->mnt_type) + 1);
 		if (!ent->fs_type) {
-			free(ent->path);
 			endmntent(tab);
 			free_mnt_list(list);
 			return NULL;
@@ -181,8 +188,6 @@ struct mnt_list *get_mnt_list(const char
 
 		ent->opts = malloc(strlen(mnt->mnt_opts) + 1);
 		if (!ent->opts) {
-			free(ent->fs_type);
-			free(ent->path);
 			endmntent(tab);
 			free_mnt_list(list);
 			return NULL;
@@ -240,6 +245,9 @@ void free_mnt_list(struct mnt_list *list
 		if (this->path)
 			free(this->path);
 
+		if (this->fs_name)
+			free(this->fs_name);
+
 		if (this->fs_type)
 			free(this->fs_type);
 
@@ -250,6 +258,43 @@ void free_mnt_list(struct mnt_list *list
 	}
 }
 
+int contained_in_local_fs(const char *path)
+{
+	struct mnt_list *mnts, *this;
+	size_t pathlen = strlen(path);
+	int ret;
+
+	if (!path || !pathlen || pathlen > PATH_MAX)
+		return 0;
+
+	mnts = get_mnt_list(_PATH_MOUNTED, "/", 1);
+	if (!mnts)
+		return 0;
+
+	ret = 0;
+
+	for (this = mnts; this != NULL; this = this->next) {
+		size_t len = strlen(this->path);
+
+		if (!strncmp(path, this->path, len)) {
+			if (len > 1 && pathlen > len && path[len] != '/')
+				continue;
+			else if (this->fs_name[0] == '/') {
+				if (strlen(this->fs_name) > 1) {
+					if (this->fs_name[1] != '/')
+						ret = 1;
+				} else
+					ret = 1;
+			}
+			break;
+		}
+	}
+
+	free_mnt_list(mnts);
+
+	return ret;
+}
+
 int is_mounted(const char *table, const char *path, unsigned int type)
 {
 	struct mntent *mnt;
@@ -497,6 +542,7 @@ void tree_free_mnt_tree(struct mnt_list 
 		list_del(&this->self);
 
 		free(this->path);
+		free(this->fs_name);
 		free(this->fs_type);
 
 		if (this->opts)
@@ -506,6 +552,7 @@ void tree_free_mnt_tree(struct mnt_list 
 	}
 
 	free(tree->path);
+	free(tree->fs_name);
 	free(tree->fs_type);
 
 	if (tree->opts)
@@ -570,9 +617,21 @@ struct mnt_list *tree_make_mnt_tree(cons
 		}
 		strcpy(ent->path, mnt->mnt_dir);
 
+		ent->fs_name = malloc(strlen(mnt->mnt_fsname) + 1);
+		if (!ent->fs_name) {
+			free(ent->path);
+			free(ent);
+			endmntent(tab);
+			tree_free_mnt_tree(tree);
+			return NULL;
+		}
+		strcpy(ent->fs_name, mnt->mnt_fsname);
+
 		ent->fs_type = malloc(strlen(mnt->mnt_type) + 1);
 		if (!ent->fs_type) {
+			free(ent->fs_name);
 			free(ent->path);
+			free(ent);
 			endmntent(tab);
 			tree_free_mnt_tree(tree);
 			return NULL;
@@ -582,7 +641,9 @@ struct mnt_list *tree_make_mnt_tree(cons
 		ent->opts = malloc(strlen(mnt->mnt_opts) + 1);
 		if (!ent->opts) {
 			free(ent->fs_type);
+			free(ent->fs_name);
 			free(ent->path);
+			free(ent);
 			endmntent(tab);
 			tree_free_mnt_tree(tree);
 			return NULL;