diff options
author | Andreas Schneider <mail@cynapses.org> | 2010-05-10 23:18:09 +0200 |
---|---|---|
committer | Andreas Schneider <mail@cynapses.org> | 2010-05-11 09:44:29 +0200 |
commit | b8bc3a658248692a3d4548fca54201f34713927c (patch) | |
tree | 45a978d1970cf1b76012abcccfa34ed552fb1759 | |
parent | 07e8d8f1f25518bae8789534e3bdff90e116a774 (diff) | |
download | libssh-b8bc3a658248692a3d4548fca54201f34713927c.tar.gz libssh-b8bc3a658248692a3d4548fca54201f34713927c.tar.xz libssh-b8bc3a658248692a3d4548fca54201f34713927c.zip |
Added a function to expand an escaped string.
-rw-r--r-- | include/libssh/misc.h | 1 | ||||
-rw-r--r-- | libssh/misc.c | 84 |
2 files changed, 85 insertions, 0 deletions
diff --git a/include/libssh/misc.h b/include/libssh/misc.h index 0150cf61..be741fbc 100644 --- a/include/libssh/misc.h +++ b/include/libssh/misc.h @@ -29,6 +29,7 @@ char *ssh_get_local_username(ssh_session session); int ssh_file_readaccess_ok(const char *file); char *ssh_path_expand_tilde(const char *d); +char *ssh_path_expand_escape(ssh_session session, const char *s); /* macro for byte ordering */ uint64_t ntohll(uint64_t); diff --git a/libssh/misc.c b/libssh/misc.c index 7a3de7b4..c3ebfd27 100644 --- a/libssh/misc.c +++ b/libssh/misc.c @@ -46,6 +46,7 @@ #include "libssh/priv.h" #include "libssh/misc.h" +#include "libssh/session.h" #ifdef HAVE_LIBGCRYPT #define GCRYPT_STRING "/gnutls" @@ -552,6 +553,89 @@ char *ssh_path_expand_tilde(const char *d) { return r; } +char *ssh_path_expand_escape(ssh_session session, const char *s) { +#define MAX_BUF_SIZE 4096 + char host[NI_MAXHOST]; + char buf[MAX_BUF_SIZE]; + char *r, *x = NULL; + const char *p; + size_t i, l; + + if (strlen(s) > MAX_BUF_SIZE) { + ssh_set_error(session, SSH_FATAL, "string to expand too long"); + return NULL; + } + + r = ssh_path_expand_tilde(s); + if (r == NULL) { + ssh_set_error_oom(session); + return NULL; + } + + p = r; + buf[0] = '\0'; + + for (i = 0; *p != '\0'; p++) { + if (*p != '%') { + buf[i] = *p; + i++; + if (i > MAX_BUF_SIZE) { + return NULL; + } + buf[i] = '\0'; + continue; + } + + p++; + if (*p == '\0') { + break; + } + + switch (*p) { + case 'd': + x = strdup(session->sshdir); + break; + case 'u': + x = ssh_get_local_username(session); + break; + case 'l': + if (gethostname(host, sizeof(host) == 0)) { + x = strdup(host); + } + break; + case 'h': + x = strdup(session->host); + break; + case 'r': + x = strdup(session->username); + break; + default: + ssh_set_error(session, SSH_FATAL, + "Wrong escape sequence detected"); + return NULL; + } + + if (x == NULL) { + ssh_set_error_oom(session); + return NULL; + } + + i += strlen(x); + if (i > MAX_BUF_SIZE) { + ssh_set_error(session, SSH_FATAL, + "String too long"); + return NULL; + } + l = strlen(buf); + strcat(buf + l, x); + SAFE_FREE(x); + } + + free(r); + return strdup(buf); +#undef MAX_BUF_SIZE +} + /* @} */ /* vim: set ts=4 sw=4 et cindent: */ |