diff options
author | Nicholas Marriott <nicm@cvs.openbsd.org> | 2009-07-13 18:49:37 +0000 |
---|---|---|
committer | Nicholas Marriott <nicm@cvs.openbsd.org> | 2009-07-13 18:49:37 +0000 |
commit | 63269139e75a3b46a125a5c6d8b948f8ee6c3134 (patch) | |
tree | 29cf8bdcdf27da29634efe85350113032f367628 /usr.bin/tmux | |
parent | 9887258f29a81d66f4dcd7c64eb0d6f767c4d63f (diff) |
Expand leading tildes in arguments, from Tiage Cunha.
Diffstat (limited to 'usr.bin/tmux')
-rw-r--r-- | usr.bin/tmux/cmd-string.c | 44 |
1 files changed, 43 insertions, 1 deletions
diff --git a/usr.bin/tmux/cmd-string.c b/usr.bin/tmux/cmd-string.c index 671a86aa6b2..1c1435f5956 100644 --- a/usr.bin/tmux/cmd-string.c +++ b/usr.bin/tmux/cmd-string.c @@ -1,4 +1,4 @@ -/* $OpenBSD: cmd-string.c,v 1.3 2009/07/08 16:04:56 nicm Exp $ */ +/* $OpenBSD: cmd-string.c,v 1.4 2009/07/13 18:49:36 nicm Exp $ */ /* * Copyright (c) 2008 Nicholas Marriott <nicm@users.sourceforge.net> @@ -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); +} |