aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--include/libssh/libssh.h3
-rw-r--r--libssh/misc.c109
2 files changed, 112 insertions, 0 deletions
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: */