summaryrefslogtreecommitdiffstats
path: root/cmd-string.c
diff options
context:
space:
mode:
authorNicholas Marriott <nicm@openbsd.org>2009-07-13 18:49:36 +0000
committerNicholas Marriott <nicm@openbsd.org>2009-07-13 18:49:36 +0000
commitcba885a67c654a5546cb5d077f15aea8c4e7ed3a (patch)
tree9a5b1f3315e804559da0c31fe98d9fc9cbc75b1a /cmd-string.c
parentcf411053c7773bbf9f7bdb8e6004ae10d006f05a (diff)
Expand leading tildes in arguments, from Tiage Cunha.
Diffstat (limited to 'cmd-string.c')
-rw-r--r--cmd-string.c42
1 files changed, 42 insertions, 0 deletions
diff --git a/cmd-string.c b/cmd-string.c
index c6ef61b0..9ba399b2 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);
+}