diff options
author | Andreas Schneider <mail@cynapses.org> | 2010-05-10 22:47:00 +0200 |
---|---|---|
committer | Andreas Schneider <mail@cynapses.org> | 2010-05-11 09:44:13 +0200 |
commit | 07e8d8f1f25518bae8789534e3bdff90e116a774 (patch) | |
tree | d5dee8dec954d85da9ff1dce2b1617bdd9b3e901 | |
parent | 34a927716a37a533719c3473dd0007be35307883 (diff) | |
download | libssh-07e8d8f1f25518bae8789534e3bdff90e116a774.tar.gz libssh-07e8d8f1f25518bae8789534e3bdff90e116a774.tar.xz libssh-07e8d8f1f25518bae8789534e3bdff90e116a774.zip |
Added a function to expand the tilde from a path.
-rw-r--r-- | include/libssh/misc.h | 2 | ||||
-rw-r--r-- | libssh/misc.c | 65 |
2 files changed, 65 insertions, 2 deletions
diff --git a/include/libssh/misc.h b/include/libssh/misc.h index 666b0782..0150cf61 100644 --- a/include/libssh/misc.h +++ b/include/libssh/misc.h @@ -28,6 +28,8 @@ char *ssh_get_user_home_dir(void); char *ssh_get_local_username(ssh_session session); int ssh_file_readaccess_ok(const char *file); +char *ssh_path_expand_tilde(const char *d); + /* macro for byte ordering */ uint64_t ntohll(uint64_t); #define htonll(x) ntohll(x) diff --git a/libssh/misc.c b/libssh/misc.c index 3ba88fc7..7a3de7b4 100644 --- a/libssh/misc.c +++ b/libssh/misc.c @@ -492,5 +492,66 @@ int ssh_mkdir(const char *pathname, mode_t mode) { return r; } -/** @} */ -/* vim: set ts=2 sw=2 et cindent: */ +/** + * @brief Expand a directory starting with a tilde '~' + * + * @param[in] session The ssh session to use. + * + * @param[in] d The directory to expand. + * + * @return The expanded directory, NULL on error. + */ +char *ssh_path_expand_tilde(const char *d) { + char *h, *r, *p; + size_t ld; + size_t lh = 0; + + if (d[0] != '~') { + return strdup(d); + } + d++; + + /* handle ~user/path */ + p = strchr(d, '/'); + if (p != NULL && p > d) { + struct passwd *pw; + size_t s = p - d; + char u[128]; + + if (s > sizeof(u)) { + return NULL; + } + memcpy(u, d, s); + u[s] = '\0'; + pw = getpwnam(u); + if (pw == NULL) { + return NULL; + } + ld = strlen(p); + h = strdup(pw->pw_dir); + } else { + ld = strlen(d); + p = (char *) d; + h = ssh_get_user_home_dir(); + } + if (h == NULL) { + return NULL; + } + lh = strlen(h); + + r = malloc(ld + lh + 1); + if (r == NULL) { + return NULL; + } + + if (lh > 0) { + memcpy(r, h, lh); + } + memcpy(r + lh, p, ld); + + return r; +} + +/* @} */ + +/* vim: set ts=4 sw=4 et cindent: */ |