summaryrefslogtreecommitdiff
path: root/src/misc.c
diff options
context:
space:
mode:
authorAnderson Toshiyuki Sasaki <ansasaki@redhat.com>2019-07-31 15:15:22 +0200
committerAndreas Schneider <asn@cryptomilk.org>2019-08-06 16:53:22 +0200
commit742918cb1cf99b711538dc9c21e3850fd487dfd6 (patch)
tree619949906f7b29d5346aac920fbbcba11b638ba6 /src/misc.c
parent7857cd1aa5e8979175b2f68df8cbe70921156e18 (diff)
downloadlibssh-742918cb1cf99b711538dc9c21e3850fd487dfd6.tar.gz
libssh-742918cb1cf99b711538dc9c21e3850fd487dfd6.tar.xz
libssh-742918cb1cf99b711538dc9c21e3850fd487dfd6.zip
misc: Introduce internal function ssh_mkdirs()
If the given path includes missing directories, ssh_mkdirs() tries to create them recursively. Signed-off-by: Anderson Toshiyuki Sasaki <ansasaki@redhat.com> Reviewed-by: Andreas Schneider <asn@cryptomilk.org>
Diffstat (limited to 'src/misc.c')
-rw-r--r--src/misc.c75
1 files changed, 70 insertions, 5 deletions
diff --git a/src/misc.c b/src/misc.c
index 19bf28c9..8bd378f3 100644
--- a/src/misc.c
+++ b/src/misc.c
@@ -950,16 +950,81 @@ char *ssh_basename (const char *path) {
*
* @return 0 on success, < 0 on error with errno set.
*/
-int ssh_mkdir(const char *pathname, mode_t mode) {
- int r;
+int ssh_mkdir(const char *pathname, mode_t mode)
+{
+ int r;
+#ifdef _WIN32
+ r = _mkdir(pathname);
+#else
+ r = mkdir(pathname, mode);
+#endif
+ return r;
+}
+
+/**
+ * @brief Attempts to create a directory with the given pathname. The missing
+ * directories in the given pathname are created recursively.
+ *
+ * @param[in] pathname The path name to create the directory.
+ *
+ * @param[in] mode The permissions to use.
+ *
+ * @return 0 on success, < 0 on error with errno set.
+ *
+ * @note mode is ignored on Windows systems.
+ */
+int ssh_mkdirs(const char *pathname, mode_t mode)
+{
+ int rc = 0;
+ char *parent = NULL;
+
+ if (pathname == NULL ||
+ pathname[0] == '\0' ||
+ !strcmp(pathname, "/") ||
+ !strcmp(pathname, "."))
+ {
+ errno = EINVAL;
+ return -1;
+ }
+
+ errno = 0;
+
+#ifdef _WIN32
+ rc = _mkdir(pathname);
+#else
+ rc = mkdir(pathname, mode);
+#endif
+
+ if (rc < 0) {
+ /* If a directory was missing, try to create the parent */
+ if (errno == ENOENT) {
+ parent = ssh_dirname(pathname);
+ if (parent == NULL) {
+ errno = ENOMEM;
+ return -1;
+ }
+
+ rc = ssh_mkdirs(parent, mode);
+ if (rc < 0) {
+ /* We could not create the parent */
+ SAFE_FREE(parent);
+ return -1;
+ }
+
+ SAFE_FREE(parent);
+
+ /* Try again */
+ errno = 0;
#ifdef _WIN32
- r = _mkdir(pathname);
+ rc = _mkdir(pathname);
#else
- r = mkdir(pathname, mode);
+ rc = mkdir(pathname, mode);
#endif
+ }
+ }
- return r;
+ return rc;
}
/**