From 160053bc3912bd204156c229ceed836795b1959b Mon Sep 17 00:00:00 2001 From: Andreas Schneider Date: Wed, 26 Aug 2009 09:47:20 +0200 Subject: Added ssh_basename() and ssh_dirname(). --- include/libssh/libssh.h | 3 ++ libssh/misc.c | 109 ++++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 112 insertions(+) diff --git a/include/libssh/libssh.h b/include/libssh/libssh.h index 6c6d5157..ad8f20ce 100644 --- a/include/libssh/libssh.h +++ b/include/libssh/libssh.h @@ -373,6 +373,9 @@ const char *ssh_userauth_kbdint_getprompt(SSH_SESSION *session, unsigned int i, int ssh_userauth_kbdint_setanswer(SSH_SESSION *session, unsigned int i, const char *answer); +/* misc.c */ +char *ssh_dirname (const char *path); +char *ssh_basename (const char *path); /* init.c */ int ssh_init(void); diff --git a/libssh/misc.c b/libssh/misc.c index bd926298..1359c156 100644 --- a/libssh/misc.c +++ b/libssh/misc.c @@ -149,5 +149,114 @@ const char *ssh_version(int req_version) { return NULL; } +/** + * @brief Parse directory component. + * + * dirname breaks a null-terminated pathname string into a directory component. + * In the usual case, ssh_dirname() returns the string up to, but not including, + * the final '/'. Trailing '/' characters are not counted as part of the + * pathname. The caller must free the memory. + * + * @param path The path to parse. + * + * @return The dirname of path or NULL if we can't allocate memory. If path + * does not contain a slash, c_dirname() returns the string ".". If + * path is the string "/", it returns the string "/". If path is + * NULL or an empty string, "." is returned. + */ +char *ssh_dirname (const char *path) { + char *new = NULL; + unsigned int len; + + if (path == NULL || *path == '\0') { + return strdup("."); + } + + len = strlen(path); + + /* Remove trailing slashes */ + while(len > 0 && path[len - 1] == '/') --len; + + /* We have only slashes */ + if (len == 0) { + return strdup("/"); + } + + /* goto next slash */ + while(len > 0 && path[len - 1] != '/') --len; + + if (len == 0) { + return strdup("."); + } else if (len == 1) { + return strdup("/"); + } + + /* Remove slashes again */ + while(len > 0 && path[len - 1] == '/') --len; + + new = malloc(len + 1); + if (new == NULL) { + return NULL; + } + + strncpy(new, path, len); + new[len] = '\0'; + + return new; +} + +/** + * @brief basename - parse filename component. + * + * basename breaks a null-terminated pathname string into a filename component. + * ssh_basename() returns the component following the final '/'. Trailing '/' + * characters are not counted as part of the pathname. + * + * @param path The path to parse. + * + * @return The filename of path or NULL if we can't allocate memory. If path + * is a the string "/", basename returns the string "/". If path is + * NULL or an empty string, "." is returned. + */ +char *ssh_basename (const char *path) { + char *new = NULL; + const char *s; + unsigned int len; + + if (path == NULL || *path == '\0') { + return strdup("."); + } + + len = strlen(path); + /* Remove trailing slashes */ + while(len > 0 && path[len - 1] == '/') --len; + + /* We have only slashes */ + if (len == 0) { + return strdup("/"); + } + + while(len > 0 && path[len - 1] != '/') --len; + + if (len > 0) { + s = path + len; + len = strlen(s); + + while(len > 0 && s[len - 1] == '/') --len; + } else { + return strdup(path); + } + + new = malloc(len + 1); + if (new == NULL) { + return NULL; + } + + strncpy(new, s, len); + new[len] = '\0'; + + return new; +} + /** @} */ /* vim: set ts=2 sw=2 et cindent: */ -- cgit v1.2.3