Commit d1667f0dbbdff5755402fbb72c95b6940d78ad3e

Stefan Sperling 2019-03-11T20:22:28

introduce got_path_dirname()

diff --git a/lib/got_lib_path.h b/lib/got_lib_path.h
index f28495f..d796646 100644
--- a/lib/got_lib_path.h
+++ b/lib/got_lib_path.h
@@ -89,3 +89,6 @@ void got_pathlist_free(struct got_pathlist_head *);
 
 /* Attempt to create a directory at a given path. */
 const struct got_error *got_path_mkdir(const char *);
+
+/* dirname(3) with error handling and dynamically allocated result. */
+const struct got_error *got_path_dirname(char **, const char *);
diff --git a/lib/path.c b/lib/path.c
index 0e002c4..5da704b 100644
--- a/lib/path.c
+++ b/lib/path.c
@@ -273,14 +273,11 @@ static const struct got_error *
 make_parent_dirs(const char *abspath)
 {
 	const struct got_error *err = NULL;
-	char *p, *parent;
+	char *parent;
 
-	p = dirname(abspath);
-	if (p == NULL)
-		return got_error_from_errno();
-	parent = strdup(p);
-	if (parent == NULL)
-		return got_error_from_errno();
+	err = got_path_dirname(&parent, abspath);
+	if (err)
+		return err;
 
 	if (mkdir(parent, GOT_DEFAULT_DIR_MODE) == -1) {
 		if (errno == ENOENT) {
@@ -318,3 +315,22 @@ got_path_mkdir(const char *abspath)
 done:
 	return err;
 }
+
+const struct got_error *
+got_path_dirname(char **parent, const char *path)
+{
+	char *p;
+
+	p = dirname(path);
+	if (p == NULL)
+		return got_error_from_errno();
+
+	if (p[0] == '.' && p[1] == '\0')
+		return got_error(GOT_ERR_BAD_PATH);
+
+	*parent = strdup(p);
+	if (*parent == NULL)
+		return got_error_from_errno();
+
+	return NULL;
+}
diff --git a/lib/reference.c b/lib/reference.c
index 66e4588..d2d3fe0 100644
--- a/lib/reference.c
+++ b/lib/reference.c
@@ -742,19 +742,12 @@ got_ref_write(struct got_reference *ref, struct got_repository *repo)
 
 	err = got_opentemp_named(&tmppath, &f, path);
 	if (err) {
-		char *p, *parent;
+		char *parent;
 		if (!(err->code == GOT_ERR_ERRNO && errno == ENOENT))
 			goto done;
-		p = dirname(path);
-		if (p == NULL) {
-			err = got_error_from_errno();
-			goto done;
-		}
-		parent = strdup(p);
-		if (parent == NULL) {
-			err = got_error_from_errno();
+		err = got_path_dirname(&parent, path);
+		if (err)
 			goto done;
-		}
 		err = got_path_mkdir(parent);
 		free(parent);
 		if (err)