summaryrefslogtreecommitdiffstats
path: root/cmd-string.c
authortcunha <tcunha>2009-07-13 18:03:18 (GMT)
committer tcunha <tcunha>2009-07-13 18:03:18 (GMT)
commit24efec1ca1a64f5a1b4821983dbf75b8105b9039 (patch) (side-by-side diff)
treec84a281858d58b4e0ffe0ded9afc76c1d9df6e2e /cmd-string.c
parentee7bae5751214f7ae300642cf2aa6ef4ac2a7a63 (diff)
downloadtmux-old-24efec1ca1a64f5a1b4821983dbf75b8105b9039.zip
tmux-old-24efec1ca1a64f5a1b4821983dbf75b8105b9039.tar.gz
tmux-old-24efec1ca1a64f5a1b4821983dbf75b8105b9039.tar.bz2
Expand leading tilde on commands which expect a filename.
Diffstat (limited to 'cmd-string.c') (more/less context) (ignore whitespace changes)
-rw-r--r--cmd-string.c42
1 files changed, 42 insertions, 0 deletions
diff --git a/cmd-string.c b/cmd-string.c
index 8da781d..818e25e 100644
--- a/cmd-string.c
+++ b/cmd-string.c
@@ -19,9 +19,11 @@
#include <sys/types.h>
#include <errno.h>
+#include <pwd.h>
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
+#include <unistd.h>
#include "tmux.h"
@@ -33,6 +35,7 @@ int cmd_string_getc(const char *, size_t *);
void cmd_string_ungetc(const char *, size_t *);
char *cmd_string_string(const char *, size_t *, char, int);
char *cmd_string_variable(const char *, size_t *);
+char *cmd_string_expand_tilde(const char *, size_t *);
int
cmd_string_getc(const char *s, size_t *p)
@@ -154,6 +157,17 @@ cmd_string_parse(const char *s, struct cmd_list **cmdlist, char **cause)
rval = 0;
goto out;
+ case '~':
+ if (have_arg == 0) {
+ if ((t = cmd_string_expand_tilde(s, &p)) == NULL)
+ goto error;
+ buf = xrealloc(buf, 1, len + strlen(t) + 1);
+ strlcpy(buf + len, t, strlen(t) + 1);
+ len += strlen(t);
+ xfree(t);
+ break;
+ }
+ /* FALLTHROUGH */
default:
if (len >= SIZE_MAX - 2)
goto error;
@@ -309,3 +323,31 @@ error:
xfree(buf);
return (NULL);
}
+
+char *
+cmd_string_expand_tilde(const char *s, size_t *p)
+{
+ struct passwd *pw;
+ char *home, *path, *username;
+
+ home = NULL;
+ if (cmd_string_getc(s, p) == '/') {
+ if ((home = getenv("HOME")) == NULL) {
+ if ((pw = getpwuid(getuid())) != NULL)
+ home = pw->pw_dir;
+ }
+ } else {
+ cmd_string_ungetc(s, p);
+ if ((username = cmd_string_string(s, p, '/', 0)) == NULL)
+ return (NULL);
+ if ((pw = getpwnam(username)) != NULL)
+ home = pw->pw_dir;
+ if (username != NULL)
+ xfree(username);
+ }
+ if (home == NULL)
+ return (NULL);
+
+ xasprintf(&path, "%s/", home);
+ return (path);
+}