diff options
author | Anderson Toshiyuki Sasaki <ansasaki@redhat.com> | 2019-07-31 15:15:22 +0200 |
---|---|---|
committer | Andreas Schneider <asn@cryptomilk.org> | 2019-08-06 16:53:22 +0200 |
commit | 742918cb1cf99b711538dc9c21e3850fd487dfd6 (patch) | |
tree | 619949906f7b29d5346aac920fbbcba11b638ba6 /src | |
parent | 7857cd1aa5e8979175b2f68df8cbe70921156e18 (diff) | |
download | libssh-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')
-rw-r--r-- | src/misc.c | 75 |
1 files changed, 70 insertions, 5 deletions
@@ -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; } /** |