From 0d3fdae7b623bd992b1fd2058e59920b2efd47da Mon Sep 17 00:00:00 2001 From: Nicholas Marriott Date: Thu, 23 Apr 2020 17:56:45 +0100 Subject: [PATCH] Build list of paths and weed out duplicates before loading configs. --- cfg.c | 55 ++++++-------------------------------- input.c | 1 - tmux.c | 71 ++++++++++++++++++++++++++++++++++++++++++++++++++ tmux.h | 4 ++- tty-features.c | 2 +- 5 files changed, 83 insertions(+), 50 deletions(-) diff --git a/cfg.c b/cfg.c index 312775eb..84be3967 100644 --- a/cfg.c +++ b/cfg.c @@ -66,45 +66,12 @@ set_cfg_file(const char *path) cfg_file = xstrdup(path); } -static char * -expand_cfg_file(const char *path, const char *home) -{ - char *expanded, *name; - const char *end; - struct environ_entry *value; - - if (strncmp(path, "~/", 2) == 0) { - if (home == NULL) - return (NULL); - xasprintf(&expanded, "%s%s", home, path + 1); - return (expanded); - } - - if (*path == '$') { - end = strchr(path, '/'); - if (end == NULL) - name = xstrdup(path + 1); - else - name = xstrndup(path + 1, end - path - 1); - value = environ_find(global_environ, name); - free(name); - if (value == NULL) - return (NULL); - if (end == NULL) - end = ""; - xasprintf(&expanded, "%s%s", value->value, end); - return (expanded); - } - - return (xstrdup(path)); -} - void start_cfg(void) { - const char *home = find_home(); - struct client *c; - char *path, *copy, *next, *expanded; + struct client *c; + char **paths; + u_int i, n; /* * Configuration files are loaded without a client, so commands are run @@ -123,18 +90,12 @@ start_cfg(void) } if (cfg_file == NULL) { - path = copy = xstrdup(TMUX_CONF); - while ((next = strsep(&path, ":")) != NULL) { - expanded = expand_cfg_file(next, home); - if (expanded == NULL) { - log_debug("couldn't expand %s", next); - continue; - } - log_debug("expanded %s to %s", next, expanded); - load_cfg(expanded, c, NULL, CMD_PARSE_QUIET, NULL); - free(expanded); + expand_paths(TMUX_CONF, &paths, &n); + for (i = 0; i < n; i++) { + load_cfg(paths[i], c, NULL, CMD_PARSE_QUIET, NULL); + free(paths[i]); } - free(copy); + free(paths); } else load_cfg(cfg_file, c, NULL, 0, NULL); diff --git a/input.c b/input.c index b9acfbef..1b1be485 100644 --- a/input.c +++ b/input.c @@ -1326,7 +1326,6 @@ input_csi_dispatch(struct input_ctx *ictx) struct input_table_entry *entry; int i, n, m; u_int cx, bg = ictx->cell.cell.bg; - char *copy, *cp; if (ictx->flags & INPUT_DISCARD) return (0); diff --git a/tmux.c b/tmux.c index 32b04bd1..727c9b99 100644 --- a/tmux.c +++ b/tmux.c @@ -106,6 +106,77 @@ areshell(const char *shell) return (0); } +static char * +expand_path(const char *path, const char *home) +{ + char *expanded, *name; + const char *end; + struct environ_entry *value; + + if (strncmp(path, "~/", 2) == 0) { + if (home == NULL) + return (NULL); + xasprintf(&expanded, "%s%s", home, path + 1); + return (expanded); + } + + if (*path == '$') { + end = strchr(path, '/'); + if (end == NULL) + name = xstrdup(path + 1); + else + name = xstrndup(path + 1, end - path - 1); + value = environ_find(global_environ, name); + free(name); + if (value == NULL) + return (NULL); + if (end == NULL) + end = ""; + xasprintf(&expanded, "%s%s", value->value, end); + return (expanded); + } + + return (xstrdup(path)); +} + +void +expand_paths(const char *s, char ***paths, u_int *n) +{ + const char *home = find_home(); + char *copy, *next, *tmp, resolved[PATH_MAX], *expanded; + u_int i; + + *paths = NULL; + *n = 0; + + copy = tmp = xstrdup(s); + while ((next = strsep(&tmp, ":")) != NULL) { + expanded = expand_path(next, home); + if (expanded == NULL) { + log_debug("%s: invalid path: %s", __func__, next); + continue; + } + if (realpath(expanded, resolved) == NULL) { + log_debug("%s: realpath(\"%s\") failed: %s", __func__, + expanded, strerror(errno)); + free(expanded); + continue; + } + free(expanded); + for (i = 0; i < *n; i++) { + if (strcmp(resolved, (*paths)[i]) == 0) + break; + } + if (i != *n) { + log_debug("%s: duplicate path: %s", __func__, resolved); + continue; + } + *paths = xreallocarray(*paths, (*n) + 1, sizeof *paths); + (*paths)[(*n)++] = xstrdup(resolved); + } + free(copy); +} + static char * make_label(const char *label, char **cause) { diff --git a/tmux.h b/tmux.h index a020ac6a..f1652b68 100644 --- a/tmux.h +++ b/tmux.h @@ -65,7 +65,7 @@ struct winlink; /* Client-server protocol version. */ #define PROTOCOL_VERSION 8 -/* Default configuration files. */ +/* Default configuration file. */ #ifndef TMUX_CONF #define TMUX_CONF "/etc/tmux.conf:~/.tmux.conf" #endif @@ -1748,6 +1748,8 @@ const char *sig2name(int); const char *find_cwd(void); const char *find_home(void); const char *getversion(void); +void expand_paths(const char *, char ***, u_int *); + /* proc.c */ struct imsg; diff --git a/tty-features.c b/tty-features.c index 9eb446d4..7505c96b 100644 --- a/tty-features.c +++ b/tty-features.c @@ -27,7 +27,7 @@ * Still hardcoded: * - bracket paste (sent if application asks for it); * - mouse (under kmous capability); - * - focus events (under focus-events option); + * - focus events (under XT and focus-events option); * - default colours (under AX or op capabilities); * - AIX colours (under colors >= 16); * - alternate escape (under XT).