diff options
author | Nicholas Marriott <nicm@cvs.openbsd.org> | 2017-02-14 18:13:06 +0000 |
---|---|---|
committer | Nicholas Marriott <nicm@cvs.openbsd.org> | 2017-02-14 18:13:06 +0000 |
commit | 9ff5dae92ef837b083712f4dec05aa8f9ae1dab7 (patch) | |
tree | aadb5eadf0fc03d856c095683f3cbe761914ce8e | |
parent | c354b31d48263e4d8dba4af52f82bb9202a4728b (diff) |
Make source-file look for files relative to the client working directory
(like load-buffer and save-buffer), from Chris Pickel. Also break the
where-is-this-file code out into its own function for loadb and saveb.
-rw-r--r-- | usr.bin/tmux/cmd-load-buffer.c | 32 | ||||
-rw-r--r-- | usr.bin/tmux/cmd-save-buffer.c | 34 | ||||
-rw-r--r-- | usr.bin/tmux/cmd-source-file.c | 30 | ||||
-rw-r--r-- | usr.bin/tmux/server-client.c | 31 | ||||
-rw-r--r-- | usr.bin/tmux/tmux.h | 4 |
5 files changed, 73 insertions, 58 deletions
diff --git a/usr.bin/tmux/cmd-load-buffer.c b/usr.bin/tmux/cmd-load-buffer.c index 639bfaa7248..969f779889b 100644 --- a/usr.bin/tmux/cmd-load-buffer.c +++ b/usr.bin/tmux/cmd-load-buffer.c @@ -1,4 +1,4 @@ -/* $OpenBSD: cmd-load-buffer.c,v 1.48 2017/01/06 13:26:09 nicm Exp $ */ +/* $OpenBSD: cmd-load-buffer.c,v 1.49 2017/02/14 18:13:05 nicm Exp $ */ /* * Copyright (c) 2009 Tiago Cunha <me@tiagocunha.org> @@ -57,11 +57,9 @@ cmd_load_buffer_exec(struct cmd *self, struct cmdq_item *item) struct args *args = self->args; struct cmd_load_buffer_data *cdata; struct client *c = item->client; - struct session *s; FILE *f; - const char *path, *bufname, *cwd; + const char *path, *bufname; char *pdata, *new_pdata, *cause, *file; - char resolved[PATH_MAX]; size_t psize; int ch, error; @@ -87,26 +85,11 @@ cmd_load_buffer_exec(struct cmd *self, struct cmdq_item *item) return (CMD_RETURN_WAIT); } - if (c != NULL && c->session == NULL && c->cwd != NULL) - cwd = c->cwd; - else if (c != NULL && (s = c->session) != NULL && s->cwd != NULL) - cwd = s->cwd; - else - cwd = "."; - - if (*path == '/') - file = xstrdup(path); - else - xasprintf(&file, "%s/%s", cwd, path); - if (realpath(file, resolved) == NULL && - strlcpy(resolved, file, sizeof resolved) >= sizeof resolved) { - cmdq_error(item, "%s: %s", file, strerror(ENAMETOOLONG)); - return (CMD_RETURN_ERROR); - } - f = fopen(resolved, "rb"); - free(file); + file = server_client_get_path(c, path); + f = fopen(file, "rb"); if (f == NULL) { - cmdq_error(item, "%s: %s", resolved, strerror(errno)); + cmdq_error(item, "%s: %s", file, strerror(errno)); + free(file); return (CMD_RETURN_ERROR); } @@ -122,13 +105,14 @@ cmd_load_buffer_exec(struct cmd *self, struct cmdq_item *item) pdata[psize++] = ch; } if (ferror(f)) { - cmdq_error(item, "%s: read error", resolved); + cmdq_error(item, "%s: read error", file); goto error; } if (pdata != NULL) pdata[psize] = '\0'; fclose(f); + free(file); if (paste_set(pdata, psize, bufname, &cause) != 0) { cmdq_error(item, "%s", cause); diff --git a/usr.bin/tmux/cmd-save-buffer.c b/usr.bin/tmux/cmd-save-buffer.c index 640e1a41a1f..419f1ae29f6 100644 --- a/usr.bin/tmux/cmd-save-buffer.c +++ b/usr.bin/tmux/cmd-save-buffer.c @@ -1,4 +1,4 @@ -/* $OpenBSD: cmd-save-buffer.c,v 1.41 2017/01/06 13:26:09 nicm Exp $ */ +/* $OpenBSD: cmd-save-buffer.c,v 1.42 2017/02/14 18:13:05 nicm Exp $ */ /* * Copyright (c) 2009 Tiago Cunha <me@tiagocunha.org> @@ -61,11 +61,10 @@ cmd_save_buffer_exec(struct cmd *self, struct cmdq_item *item) { struct args *args = self->args; struct client *c = item->client; - struct session *s; struct paste_buffer *pb; - const char *path, *bufname, *bufdata, *start, *end, *cwd; + const char *path, *bufname, *bufdata, *start, *end; const char *flags; - char *msg, *file, resolved[PATH_MAX]; + char *msg, *file; size_t size, used, msglen, bufsize; FILE *f; @@ -98,39 +97,26 @@ cmd_save_buffer_exec(struct cmd *self, struct cmdq_item *item) goto do_print; } - if (c != NULL && c->session == NULL && c->cwd != NULL) - cwd = c->cwd; - else if (c != NULL && (s = c->session) != NULL && s->cwd != NULL) - cwd = s->cwd; - else - cwd = "."; - flags = "wb"; if (args_has(self->args, 'a')) flags = "ab"; - if (*path == '/') - file = xstrdup(path); - else - xasprintf(&file, "%s/%s", cwd, path); - if (realpath(file, resolved) == NULL && - strlcpy(resolved, file, sizeof resolved) >= sizeof resolved) { - cmdq_error(item, "%s: %s", file, strerror(ENAMETOOLONG)); - return (CMD_RETURN_ERROR); - } - f = fopen(resolved, flags); - free(file); + file = server_client_get_path(c, path); + f = fopen(file, flags); if (f == NULL) { - cmdq_error(item, "%s: %s", resolved, strerror(errno)); + cmdq_error(item, "%s: %s", file, strerror(errno)); + free(file); return (CMD_RETURN_ERROR); } if (fwrite(bufdata, 1, bufsize, f) != bufsize) { - cmdq_error(item, "%s: write error", resolved); + cmdq_error(item, "%s: write error", file); fclose(f); return (CMD_RETURN_ERROR); } + fclose(f); + free(file); return (CMD_RETURN_NORMAL); diff --git a/usr.bin/tmux/cmd-source-file.c b/usr.bin/tmux/cmd-source-file.c index d24f7b68a30..b497f860348 100644 --- a/usr.bin/tmux/cmd-source-file.c +++ b/usr.bin/tmux/cmd-source-file.c @@ -1,4 +1,4 @@ -/* $OpenBSD: cmd-source-file.c,v 1.33 2017/01/29 22:10:55 nicm Exp $ */ +/* $OpenBSD: cmd-source-file.c,v 1.34 2017/02/14 18:13:05 nicm Exp $ */ /* * Copyright (c) 2008 Tiago Cunha <me@tiagocunha.org> @@ -22,6 +22,7 @@ #include <glob.h> #include <stdlib.h> #include <string.h> +#include <vis.h> #include "tmux.h" @@ -48,22 +49,35 @@ static enum cmd_retval cmd_source_file_exec(struct cmd *self, struct cmdq_item *item) { struct args *args = self->args; + int quiet = args_has(args, 'q'); struct client *c = item->client; - int quiet; struct cmdq_item *new_item; enum cmd_retval retval; + char *pattern, *tmp; + const char *path = args->argv[0]; glob_t g; u_int i; - quiet = args_has(args, 'q'); - if (glob(args->argv[0], 0, NULL, &g) != 0) { - if (quiet && errno == ENOENT) - return (CMD_RETURN_NORMAL); - cmdq_error(item, "%s: %s", args->argv[0], strerror(errno)); - return (CMD_RETURN_ERROR); + if (*path == '/') + pattern = xstrdup(path); + else { + utf8_stravis(&tmp, server_client_get_cwd(c), VIS_GLOB); + xasprintf(&pattern, "%s/%s", tmp, path); + free(tmp); } + log_debug("%s: %s", __func__, pattern); retval = CMD_RETURN_NORMAL; + if (glob(pattern, 0, NULL, &g) != 0) { + if (!quiet || errno != ENOENT) { + cmdq_error(item, "%s: %s", path, strerror(errno)); + retval = CMD_RETURN_ERROR; + } + free(pattern); + return (retval); + } + free(pattern); + for (i = 0; i < (u_int)g.gl_pathc; i++) { if (load_cfg(g.gl_pathv[i], c, item, quiet) != 0) retval = CMD_RETURN_ERROR; diff --git a/usr.bin/tmux/server-client.c b/usr.bin/tmux/server-client.c index 90eae6956dc..adaa332991b 100644 --- a/usr.bin/tmux/server-client.c +++ b/usr.bin/tmux/server-client.c @@ -1,4 +1,4 @@ -/* $OpenBSD: server-client.c,v 1.212 2017/02/09 12:09:33 nicm Exp $ */ +/* $OpenBSD: server-client.c,v 1.213 2017/02/14 18:13:05 nicm Exp $ */ /* * Copyright (c) 2009 Nicholas Marriott <nicholas.marriott@gmail.com> @@ -1655,3 +1655,32 @@ server_client_add_message(struct client *c, const char *fmt, ...) free(msg); } } + +/* Get client working directory. */ +const char * +server_client_get_cwd(struct client *c) +{ + struct session *s; + + if (c != NULL && c->session == NULL && c->cwd != NULL) + return (c->cwd); + if (c != NULL && (s = c->session) != NULL && s->cwd != NULL) + return (s->cwd); + return ("."); +} + +/* Resolve an absolute path or relative to client working directory. */ +char * +server_client_get_path(struct client *c, const char *file) +{ + char *path, resolved[PATH_MAX]; + + if (*file == '/') + path = xstrdup(file); + else + xasprintf(&path, "%s/%s", server_client_get_cwd(c), file); + if (realpath(path, resolved) == NULL) + return (path); + free(path); + return (xstrdup(resolved)); +} diff --git a/usr.bin/tmux/tmux.h b/usr.bin/tmux/tmux.h index 59cedcd9b96..4dff98d2a95 100644 --- a/usr.bin/tmux/tmux.h +++ b/usr.bin/tmux/tmux.h @@ -1,4 +1,4 @@ -/* $OpenBSD: tmux.h,v 1.726 2017/02/10 12:59:18 nicm Exp $ */ +/* $OpenBSD: tmux.h,v 1.727 2017/02/14 18:13:05 nicm Exp $ */ /* * Copyright (c) 2007 Nicholas Marriott <nicholas.marriott@gmail.com> @@ -1834,6 +1834,8 @@ void server_client_push_stdout(struct client *); void server_client_push_stderr(struct client *); void printflike(2, 3) server_client_add_message(struct client *, const char *, ...); +char *server_client_get_path(struct client *, const char *); +const char *server_client_get_cwd(struct client *); /* server-fn.c */ void server_fill_environ(struct session *, struct environ *); |