Merge branch 'obsd-master'

This commit is contained in:
Thomas Adam 2017-01-24 22:01:13 +00:00
commit 418ab1a553
15 changed files with 303 additions and 226 deletions

View File

@ -251,16 +251,13 @@ client_main(struct event_base *base, int argc, char **argv, int flags,
* flag.
*/
cmdlist = cmd_list_parse(argc, argv, NULL, 0, &cause);
if (cmdlist == NULL) {
fprintf(stderr, "%s\n", cause);
return (1);
if (cmdlist != NULL) {
TAILQ_FOREACH(cmd, &cmdlist->list, qentry) {
if (cmd->entry->flags & CMD_STARTSERVER)
cmdflags |= CMD_STARTSERVER;
}
cmd_list_free(cmdlist);
}
cmdflags &= ~CMD_STARTSERVER;
TAILQ_FOREACH(cmd, &cmdlist->list, qentry) {
if (cmd->entry->flags & CMD_STARTSERVER)
cmdflags |= CMD_STARTSERVER;
}
cmd_list_free(cmdlist);
}
/* Create client process structure (starts logging). */

View File

@ -54,7 +54,6 @@ cmd_attach_session(struct cmdq_item *item, int dflag, int rflag,
struct client *c = item->client, *c_loop;
struct winlink *wl = item->state.tflag.wl;
struct window_pane *wp = item->state.tflag.wp;
const char *update;
char *cause, *cwd;
struct format_tree *ft;
@ -95,12 +94,8 @@ cmd_attach_session(struct cmdq_item *item, int dflag, int rflag,
server_client_detach(c_loop, MSG_DETACH);
}
}
if (!Eflag) {
update = options_get_string(s->options,
"update-environment");
environ_update(update, c->environ, s->environ);
}
if (!Eflag)
environ_update(s->options, c->environ, s->environ);
c->session = s;
server_client_set_key_table(c, NULL);
@ -116,7 +111,6 @@ cmd_attach_session(struct cmdq_item *item, int dflag, int rflag,
free(cause);
return (CMD_RETURN_ERROR);
}
if (rflag)
c->flags |= CLIENT_READONLY;
@ -127,12 +121,8 @@ cmd_attach_session(struct cmdq_item *item, int dflag, int rflag,
server_client_detach(c_loop, MSG_DETACH);
}
}
if (!Eflag) {
update = options_get_string(s->options,
"update-environment");
environ_update(update, c->environ, s->environ);
}
if (!Eflag)
environ_update(s->options, c->environ, s->environ);
c->session = s;
server_client_set_key_table(c, NULL);

View File

@ -73,7 +73,7 @@ cmd_new_session_exec(struct cmd *self, struct cmdq_item *item)
struct window *w;
struct environ *env;
struct termios tio, *tiop;
const char *newname, *target, *update, *errstr, *template;
const char *newname, *target, *errstr, *template;
const char *path, *cmd, *cwd, *to_free = NULL;
char **argv, *cause, *cp;
int detached, already_attached, idx, argc;
@ -234,11 +234,8 @@ cmd_new_session_exec(struct cmd *self, struct cmdq_item *item)
/* Construct the environment. */
env = environ_create();
if (c != NULL && !args_has(args, 'E')) {
update = options_get_string(global_s_options,
"update-environment");
environ_update(update, c->environ, env);
}
if (c != NULL && !args_has(args, 'E'))
environ_update(global_s_options, c->environ, env);
/* Create the new session. */
idx = -1 - options_get_number(global_s_options, "base-index");

View File

@ -68,6 +68,7 @@ static enum cmd_retval
cmd_set_option_exec(struct cmd *self, struct cmdq_item *item)
{
struct args *args = self->args;
int append = args_has(args, 'a');
struct cmd_find_state *fs = &item->state.tflag;
struct session *s = fs->s;
struct winlink *wl = fs->wl;
@ -160,17 +161,6 @@ cmd_set_option_exec(struct cmd *self, struct cmdq_item *item)
cmdq_error(item, "not an array: %s", args->argv[0]);
return (CMD_RETURN_ERROR);
}
} else if (*name != '@' && options_array_size(parent, NULL) != -1) {
if (value == NULL) {
cmdq_error(item, "empty value");
return (-1);
}
if (o == NULL)
o = options_empty(oo, options_table_entry(parent));
if (!args_has(args, 'a'))
options_array_clear(o);
options_array_assign(o, value);
return (CMD_RETURN_NORMAL);
}
/* With -o, check this option is not already set. */
@ -204,16 +194,26 @@ cmd_set_option_exec(struct cmd *self, struct cmdq_item *item)
options_remove(o);
} else
options_array_set(o, idx, NULL, 0);
} else if (*name == '@')
options_set_string(oo, name, args_has(args, 'a'), "%s", value);
else if (idx == -1) {
} else if (*name == '@') {
if (value == NULL) {
cmdq_error(item, "empty value");
return (CMD_RETURN_ERROR);
}
options_set_string(oo, name, append, "%s", value);
} else if (idx == -1 && options_array_size(parent, NULL) == -1) {
error = cmd_set_option_set(self, item, oo, parent, value);
if (error != 0)
return (CMD_RETURN_ERROR);
} else {
if (value == NULL) {
cmdq_error(item, "empty value");
return (CMD_RETURN_ERROR);
}
if (o == NULL)
o = options_empty(oo, options_table_entry(parent));
if (options_array_set(o, idx, value, 1) != 0) {
if (idx == -1)
options_array_assign(o, value);
else if (options_array_set(o, idx, value, append) != 0) {
cmdq_error(item, "invalid index: %s", args->argv[0]);
return (CMD_RETURN_ERROR);
}

View File

@ -44,17 +44,6 @@ const struct cmd_entry cmd_show_messages_entry = {
.exec = cmd_show_messages_exec
};
const struct cmd_entry cmd_server_info_entry = {
.name = "server-info",
.alias = "info",
.args = { "", 0, 0 },
.usage = "",
.flags = CMD_AFTERHOOK,
.exec = cmd_show_messages_exec
};
static int cmd_show_messages_terminals(struct cmdq_item *, int);
static int cmd_show_messages_jobs(struct cmdq_item *, int);
@ -108,11 +97,11 @@ cmd_show_messages_exec(struct cmd *self, struct cmdq_item *item)
int done, blank;
done = blank = 0;
if (args_has(args, 'T') || self->entry == &cmd_server_info_entry) {
if (args_has(args, 'T')) {
blank = cmd_show_messages_terminals(item, blank);
done = 1;
}
if (args_has(args, 'J') || self->entry == &cmd_server_info_entry) {
if (args_has(args, 'J')) {
cmd_show_messages_jobs(item, blank);
done = 1;
}

View File

@ -54,17 +54,15 @@ cmd_string_ungetc(size_t *p)
(*p)--;
}
struct cmd_list *
cmd_string_parse(const char *s, const char *file, u_int line, char **cause)
int
cmd_string_split(const char *s, int *rargc, char ***rargv)
{
size_t p = 0;
int ch, i, argc = 0;
char **argv = NULL, *buf = NULL, *t;
const char *whitespace, *equals;
size_t len = 0;
struct cmd_list *cmdlist = NULL;
size_t p = 0;
int ch, argc = 0, append = 0;
char **argv = NULL, *buf = NULL, *t;
const char *whitespace, *equals;
size_t len = 0;
*cause = NULL;
for (;;) {
ch = cmd_string_getc(s, &p);
switch (ch) {
@ -115,43 +113,67 @@ cmd_string_parse(const char *s, const char *file, u_int line, char **cause)
argc--;
memmove(argv, argv + 1, argc * (sizeof *argv));
}
if (argc == 0)
goto out;
cmdlist = cmd_list_parse(argc, argv, file, line, cause);
goto out;
goto done;
case '~':
if (buf == NULL) {
t = cmd_string_expand_tilde(s, &p);
if (t == NULL)
goto error;
cmd_string_copy(&buf, t, &len);
if (buf != NULL) {
append = 1;
break;
}
/* FALLTHROUGH */
default:
if (len >= SIZE_MAX - 2)
t = cmd_string_expand_tilde(s, &p);
if (t == NULL)
goto error;
buf = xrealloc(buf, len + 1);
buf[len++] = ch;
cmd_string_copy(&buf, t, &len);
break;
default:
append = 1;
break;
}
if (append) {
if (len >= SIZE_MAX - 2)
goto error;
buf = xrealloc(buf, len + 1);
buf[len++] = ch;
}
append = 0;
}
done:
*rargc = argc;
*rargv = argv;
free(buf);
return (0);
error:
if (argv != NULL)
cmd_free_argv(argc, argv);
free(buf);
return (-1);
}
struct cmd_list *
cmd_string_parse(const char *s, const char *file, u_int line, char **cause)
{
struct cmd_list *cmdlist = NULL;
int argc;
char **argv;
*cause = NULL;
if (cmd_string_split(s, &argc, &argv) != 0)
goto error;
if (argc != 0) {
cmdlist = cmd_list_parse(argc, argv, file, line, cause);
if (cmdlist == NULL) {
cmd_free_argv(argc, argv);
goto error;
}
}
cmd_free_argv(argc, argv);
return (cmdlist);
error:
xasprintf(cause, "invalid or unknown command: %s", s);
out:
free(buf);
if (argv != NULL) {
for (i = 0; i < argc; i++)
free(argv[i]);
free(argv);
}
return (cmdlist);
return (NULL);
}
static void

View File

@ -53,7 +53,7 @@ cmd_switch_client_exec(struct cmd *self, struct cmdq_item *item)
struct client *c = state->c;
struct session *s = item->state.tflag.s;
struct window_pane *wp;
const char *tablename, *update;
const char *tablename;
struct key_table *table;
if (args_has(args, 'r'))
@ -102,10 +102,8 @@ cmd_switch_client_exec(struct cmd *self, struct cmdq_item *item)
}
}
if (!args_has(args, 'E')) {
update = options_get_string(s->options, "update-environment");
environ_update(update, c->environ, s->environ);
}
if (!args_has(args, 'E'))
environ_update(s->options, c->environ, s->environ);
if (c->session != NULL && c->session != s)
c->last_session = c->session;

70
cmd.c
View File

@ -92,7 +92,6 @@ extern const struct cmd_entry cmd_select_pane_entry;
extern const struct cmd_entry cmd_select_window_entry;
extern const struct cmd_entry cmd_send_keys_entry;
extern const struct cmd_entry cmd_send_prefix_entry;
extern const struct cmd_entry cmd_server_info_entry;
extern const struct cmd_entry cmd_set_buffer_entry;
extern const struct cmd_entry cmd_set_environment_entry;
extern const struct cmd_entry cmd_set_hook_entry;
@ -181,7 +180,6 @@ const struct cmd_entry *cmd_table[] = {
&cmd_select_window_entry,
&cmd_send_keys_entry,
&cmd_send_prefix_entry,
&cmd_server_info_entry,
&cmd_set_buffer_entry,
&cmd_set_environment_entry,
&cmd_set_hook_entry,
@ -307,21 +305,74 @@ cmd_stringify_argv(int argc, char **argv)
return (buf);
}
static int
cmd_try_alias(int *argc, char ***argv)
{
struct options_entry *o;
int old_argc = *argc, new_argc;
char **old_argv = *argv, **new_argv;
u_int size, idx;
int i;
size_t wanted;
const char *s, *cp = NULL;
o = options_get_only(global_options, "command-alias");
if (o == NULL || options_array_size(o, &size) == -1 || size == 0)
return (-1);
wanted = strlen(old_argv[0]);
for (idx = 0; idx < size; idx++) {
s = options_array_get(o, idx);
if (s == NULL)
continue;
cp = strchr(s, '=');
if (cp == NULL || (size_t)(cp - s) != wanted)
continue;
if (strncmp(old_argv[0], s, wanted) == 0)
break;
}
if (idx == size)
return (-1);
if (cmd_string_split(cp + 1, &new_argc, &new_argv) != 0)
return (-1);
*argc = new_argc + old_argc - 1;
*argv = xcalloc((*argc) + 1, sizeof **argv);
for (i = 0; i < new_argc; i++)
(*argv)[i] = xstrdup(new_argv[i]);
for (i = 1; i < old_argc; i++)
(*argv)[new_argc + i - 1] = xstrdup(old_argv[i]);
log_debug("alias: %s=%s", old_argv[0], cp + 1);
for (i = 0; i < *argc; i++)
log_debug("alias: argv[%d] = %s", i, (*argv)[i]);
cmd_free_argv(new_argc, new_argv);
return (0);
}
struct cmd *
cmd_parse(int argc, char **argv, const char *file, u_int line, char **cause)
{
const char *name;
const struct cmd_entry **entryp, *entry;
struct cmd *cmd;
struct args *args;
char s[BUFSIZ];
int ambiguous = 0;
int ambiguous, allocated = 0;
*cause = NULL;
if (argc == 0) {
xasprintf(cause, "no command");
return (NULL);
}
name = argv[0];
retry:
ambiguous = 0;
entry = NULL;
for (entryp = cmd_table; *entryp != NULL; entryp++) {
if ((*entryp)->alias != NULL &&
@ -341,10 +392,17 @@ cmd_parse(int argc, char **argv, const char *file, u_int line, char **cause)
if (strcmp(entry->name, argv[0]) == 0)
break;
}
if ((ambiguous || entry == NULL) &&
server_proc != NULL &&
!allocated &&
cmd_try_alias(&argc, &argv) == 0) {
allocated = 1;
goto retry;
}
if (ambiguous)
goto ambiguous;
if (entry == NULL) {
xasprintf(cause, "unknown command: %s", argv[0]);
xasprintf(cause, "unknown command: %s", name);
return (NULL);
}
@ -364,6 +422,8 @@ cmd_parse(int argc, char **argv, const char *file, u_int line, char **cause)
cmd->file = xstrdup(file);
cmd->line = line;
if (allocated)
cmd_free_argv(argc, argv);
return (cmd);
ambiguous:
@ -377,7 +437,7 @@ ambiguous:
break;
}
s[strlen(s) - 2] = '\0';
xasprintf(cause, "ambiguous command: %s, could be: %s", argv[0], s);
xasprintf(cause, "ambiguous command: %s, could be: %s", name, s);
return (NULL);
usage:

View File

@ -169,25 +169,27 @@ environ_unset(struct environ *env, const char *name)
free(envent);
}
/*
* Copy a space-separated list of variables from a destination into a source
* environment.
*/
/* Copy variables from a destination into a source * environment. */
void
environ_update(const char *vars, struct environ *srcenv,
struct environ *dstenv)
environ_update(struct options *oo, struct environ *src, struct environ *dst)
{
struct environ_entry *envent;
char *copyvars, *var, *next;
struct options_entry *o;
u_int size, idx;
const char *value;
copyvars = next = xstrdup(vars);
while ((var = strsep(&next, " ")) != NULL) {
if ((envent = environ_find(srcenv, var)) == NULL)
environ_clear(dstenv, var);
o = options_get(oo, "update-environment");
if (o == NULL || options_array_size(o, &size) == -1)
return;
for (idx = 0; idx < size; idx++) {
value = options_array_get(o, idx);
if (value == NULL)
continue;
if ((envent = environ_find(src, value)) == NULL)
environ_clear(dst, value);
else
environ_set(dstenv, envent->name, "%s", envent->value);
environ_set(dst, envent->name, "%s", envent->value);
}
free(copyvars);
}
/* Push environment into the real environment - use after fork(). */

View File

@ -383,7 +383,7 @@ key_bindings_init(void)
for (i = 0; i < nitems(defaults); i++) {
cmdlist = cmd_string_parse(defaults[i], "<default>", i, &cause);
if (cmdlist == NULL)
fatalx("bad default key");
fatalx("bad default key: %s", defaults[i]);
cmdq_append(NULL, cmdq_get_command(cmdlist, NULL, NULL, 0));
cmd_list_free(cmdlist);
}

View File

@ -64,6 +64,16 @@ const struct options_table_entry options_table[] = {
.default_num = 20
},
{ .name = "command-alias",
.type = OPTIONS_TABLE_ARRAY,
.scope = OPTIONS_TABLE_SERVER,
.default_str = "split-pane=split-window,"
"splitp=split-window,"
"server-info=show-messages -JT,"
"info=show-messages -JT",
.separator = ","
},
{ .name = "default-terminal",
.type = OPTIONS_TABLE_STRING,
.scope = OPTIONS_TABLE_SERVER,
@ -111,11 +121,12 @@ const struct options_table_entry options_table[] = {
},
{ .name = "terminal-overrides",
.type = OPTIONS_TABLE_STRING,
.type = OPTIONS_TABLE_ARRAY,
.scope = OPTIONS_TABLE_SERVER,
.default_str = "xterm*:XT:Ms=\\E]52;%p1%s;%p2%s\\007"
":Cs=\\E]12;%p1%s\\007:Cr=\\E]112\\007"
":Ss=\\E[%p1%d q:Se=\\E[2 q,screen*:XT"
":Ss=\\E[%p1%d q:Se=\\E[2 q,screen*:XT",
.separator = ","
},
{ .name = "assume-paste-time",
@ -470,11 +481,10 @@ const struct options_table_entry options_table[] = {
},
{ .name = "update-environment",
.type = OPTIONS_TABLE_STRING,
.type = OPTIONS_TABLE_ARRAY,
.scope = OPTIONS_TABLE_SESSION,
.default_str = "DISPLAY SSH_ASKPASS SSH_AUTH_SOCK SSH_AGENT_PID "
"SSH_CONNECTION WINDOWID XAUTHORITY"
},
{ .name = "visual-activity",

2
pty.c
View File

@ -53,7 +53,7 @@ pty_fork(int ptmfd, int *fd, char *name, size_t namelen, struct winsize *ws)
struct ptmget ptm;
pid_t pid;
if ((ioctl(ptmfd, PTMGET, &ptm) == -1))
if (ioctl(ptmfd, PTMGET, &ptm) == -1)
return (-1);
strlcpy(name, ptm.sn, namelen);

66
tmux.1
View File

@ -2414,6 +2414,30 @@ Available server options are:
Set the number of buffers; as new buffers are added to the top of the stack,
old ones are removed from the bottom if necessary to maintain this maximum
length.
.It Xo Ic command-alias[]
.Ar name=value
.Xc
This is an array of custom aliases for commands.
If an unknown command matches
.Ar name ,
it is replaced with
.Ar value .
For example, after:
.Pp
.Dl set -s command-alias[2] zoom='resize-pane -Z'
.Pp
Using:
.Pp
.Dl zoom -t:.1
.Pp
Is equivalent to:
.Pp
.Dl resize-pane -Z -t:.1
.Pp
Note that aliases are expanded when a command is parsed rather than when it is
executed, so binding an alias with
.Ic bind-key
will bind the expanded form.
.It Ic default-terminal Ar terminal
Set the default terminal for new windows created in this session - the
default value of the
@ -2475,12 +2499,12 @@ disallowedWindowOps: 20,21,SetXprop
Or changing this property from the
.Xr xterm 1
interactive menu when required.
.It Ic terminal-overrides Ar string
Contains a list of entries which override terminal descriptions read using
.Xr terminfo 5 .
.Ar string
is a comma-separated list of items each a colon-separated string made up of a
terminal type pattern (matched using
.It Ic terminal-overrides[] Ar string
Allow terminal descriptions read using
.Xr terminfo 5
to be overriden.
Each entry is a colon-separated string made up of a terminal type pattern
(matched using
.Xr fnmatch 3 )
and a set of
.Em name=value
@ -2491,26 +2515,14 @@ For example, to set the
.Xr terminfo 5
entry to
.Ql \ee[H\ee[2J
for all terminal types and the
.Ql dch1
entry to
.Ql \ee[P
for the
.Ql rxvt
terminal type, the option could be set to the string:
.Bd -literal -offset indent
"*:clear=\ee[H\ee[2J,rxvt:dch1=\ee[P"
.Ed
for all terminal types matching
.Ql rxvt* :
.Pp
.Dl "rxvt*:clear=\ee[H\ee[2J"
.Pp
The terminal entry value is passed through
.Xr strunvis 3
before interpretation.
The default value forcibly corrects the
.Ql colors
entry for terminals which support 256 colours:
.Bd -literal -offset indent
"*256col*:colors=256,xterm*:XT"
.Ed
.El
.Pp
Available session options are:
@ -2861,19 +2873,15 @@ For how to specify
see the
.Ic message-command-style
option.
.It Ic update-environment Ar variables
Set a space-separated string containing a list of environment variables to be
copied into the session environment when a new session is created or an
existing session is attached.
.It Ic update-environment[] Ar variable
Set list of environment variables to be copied into the session environment
when a new session is created or an existing session is attached.
Any variables that do not exist in the source environment are set to be
removed from the session environment (as if
.Fl r
was given to the
.Ic set-environment
command).
The default is
"DISPLAY SSH_ASKPASS SSH_AUTH_SOCK SSH_AGENT_PID SSH_CONNECTION WINDOWID
XAUTHORITY".
.It Xo Ic visual-activity
.Op Ic on | off
.Xc

3
tmux.h
View File

@ -1671,7 +1671,7 @@ void printflike(3, 4) environ_set(struct environ *, const char *, const char *,
void environ_clear(struct environ *, const char *);
void environ_put(struct environ *, const char *);
void environ_unset(struct environ *, const char *);
void environ_update(const char *, struct environ *, struct environ *);
void environ_update(struct options *, struct environ *, struct environ *);
void environ_push(struct environ *);
void environ_log(struct environ *, const char *);
@ -1830,6 +1830,7 @@ void printflike(2, 3) cmdq_print(struct cmdq_item *, const char *, ...);
void printflike(2, 3) cmdq_error(struct cmdq_item *, const char *, ...);
/* cmd-string.c */
int cmd_string_split(const char *, int *, char ***);
struct cmd_list *cmd_string_parse(const char *, const char *, u_int, char **);
/* cmd-wait-for.c */

View File

@ -297,86 +297,82 @@ tty_term_strip(const char *s)
}
static void
tty_term_override(struct tty_term *term, const char *overrides)
tty_term_override(struct tty_term *term, const char *override)
{
const struct tty_term_code_entry *ent;
struct tty_code *code;
char *termnext, *termstr;
char *entnext, *entstr;
char *s, *ptr, *val;
char *next, *s, *copy, *cp, *value;
const char *errstr;
u_int i;
int n, removeflag;
int n, remove;
s = xstrdup(overrides);
copy = next = xstrdup(override);
termnext = s;
while ((termstr = strsep(&termnext, ",")) != NULL) {
entnext = termstr;
entstr = strsep(&entnext, ":");
if (entstr == NULL || entnext == NULL)
continue;
if (fnmatch(entstr, term->name, 0) != 0)
continue;
while ((entstr = strsep(&entnext, ":")) != NULL) {
if (*entstr == '\0')
continue;
val = NULL;
removeflag = 0;
if ((ptr = strchr(entstr, '=')) != NULL) {
*ptr++ = '\0';
val = xstrdup(ptr);
if (strunvis(val, ptr) == -1) {
free(val);
val = xstrdup(ptr);
}
} else if (entstr[strlen(entstr) - 1] == '@') {
entstr[strlen(entstr) - 1] = '\0';
removeflag = 1;
} else
val = xstrdup("");
log_debug("%s override: %s %s",
term->name, entstr, removeflag ? "@" : val);
for (i = 0; i < tty_term_ncodes(); i++) {
ent = &tty_term_codes[i];
if (strcmp(entstr, ent->name) != 0)
continue;
code = &term->codes[i];
if (removeflag) {
code->type = TTYCODE_NONE;
continue;
}
switch (ent->type) {
case TTYCODE_NONE:
break;
case TTYCODE_STRING:
if (code->type == TTYCODE_STRING)
free(code->value.string);
code->value.string = xstrdup(val);
code->type = ent->type;
break;
case TTYCODE_NUMBER:
n = strtonum(val, 0, INT_MAX, &errstr);
if (errstr != NULL)
break;
code->value.number = n;
code->type = ent->type;
break;
case TTYCODE_FLAG:
code->value.flag = 1;
code->type = ent->type;
break;
}
}
free(val);
}
s = strsep(&next, ":");
if (s == NULL || next == NULL || fnmatch(s, term->name, 0) != 0) {
free(copy);
return;
}
while ((s = strsep(&next, ":")) != NULL) {
if (*s == '\0')
continue;
value = NULL;
remove = 0;
if ((cp = strchr(s, '=')) != NULL) {
*cp++ = '\0';
value = xstrdup(cp);
if (strunvis(value, cp) == -1) {
free(value);
value = xstrdup(cp);
}
} else if (s[strlen(s) - 1] == '@') {
s[strlen(s) - 1] = '\0';
remove = 1;
} else
value = xstrdup("");
if (remove)
log_debug("%s override: %s@", term->name, s);
else
log_debug("%s override: %s=%s", term->name, s, value);
for (i = 0; i < tty_term_ncodes(); i++) {
ent = &tty_term_codes[i];
if (strcmp(s, ent->name) != 0)
continue;
code = &term->codes[i];
if (remove) {
code->type = TTYCODE_NONE;
continue;
}
switch (ent->type) {
case TTYCODE_NONE:
break;
case TTYCODE_STRING:
if (code->type == TTYCODE_STRING)
free(code->value.string);
code->value.string = xstrdup(value);
code->type = ent->type;
break;
case TTYCODE_NUMBER:
n = strtonum(value, 0, INT_MAX, &errstr);
if (errstr != NULL)
break;
code->value.number = n;
code->type = ent->type;
break;
case TTYCODE_FLAG:
code->value.flag = 1;
code->type = ent->type;
break;
}
}
free(value);
}
free(s);
}
@ -386,7 +382,8 @@ tty_term_find(char *name, int fd, char **cause)
struct tty_term *term;
const struct tty_term_code_entry *ent;
struct tty_code *code;
u_int i;
struct options_entry *o;
u_int size, i;
int n, error;
const char *s, *acs;
@ -460,8 +457,14 @@ tty_term_find(char *name, int fd, char **cause)
}
/* Apply terminal overrides. */
s = options_get_string(global_options, "terminal-overrides");
tty_term_override(term, s);
o = options_get_only(global_options, "terminal-overrides");
if (options_array_size(o, &size) != -1) {
for (i = 0; i < size; i++) {
s = options_array_get(o, i);
if (s != NULL)
tty_term_override(term, s);
}
}
/* Delete curses data. */
#if !defined(NCURSES_VERSION_MAJOR) || NCURSES_VERSION_MAJOR > 5 || \