1
0
mirror of https://github.com/tmate-io/tmate-ssh-server.git synced 2020-11-18 19:53:51 -08:00

Merge branch 'obsd-master'

This commit is contained in:
Thomas Adam 2014-12-03 08:41:08 +00:00
commit ccbe2545d9
7 changed files with 123 additions and 72 deletions

View File

@ -37,8 +37,8 @@ void cmd_if_shell_free(void *);
const struct cmd_entry cmd_if_shell_entry = { const struct cmd_entry cmd_if_shell_entry = {
"if-shell", "if", "if-shell", "if",
"bt:", 2, 3, "bFt:", 2, 3,
"[-b] " CMD_TARGET_PANE_USAGE " shell-command command [command]", "[-bF] " CMD_TARGET_PANE_USAGE " shell-command command [command]",
0, 0,
cmd_if_shell_exec cmd_if_shell_exec
}; };
@ -56,7 +56,8 @@ cmd_if_shell_exec(struct cmd *self, struct cmd_q *cmdq)
{ {
struct args *args = self->args; struct args *args = self->args;
struct cmd_if_shell_data *cdata; struct cmd_if_shell_data *cdata;
char *shellcmd; char *shellcmd, *cmd, *cause;
struct cmd_list *cmdlist;
struct client *c; struct client *c;
struct session *s = NULL; struct session *s = NULL;
struct winlink *wl = NULL; struct winlink *wl = NULL;
@ -84,6 +85,26 @@ cmd_if_shell_exec(struct cmd *self, struct cmd_q *cmdq)
shellcmd = format_expand(ft, args->argv[0]); shellcmd = format_expand(ft, args->argv[0]);
format_free(ft); format_free(ft);
if (args_has(args, 'F')) {
cmd = NULL;
if (*shellcmd != '0' && *shellcmd != '\0')
cmd = args->argv[1];
else if (args->argc == 3)
cmd = args->argv[2];
if (cmd == NULL)
return (CMD_RETURN_NORMAL);
if (cmd_string_parse(cmd, &cmdlist, NULL, 0, &cause) != 0) {
if (cause != NULL) {
cmdq_error(cmdq, "%s", cause);
free(cause);
}
return (CMD_RETURN_ERROR);
}
cmdq_run(cmdq, cmdlist);
cmd_list_free(cmdlist);
return (CMD_RETURN_NORMAL);
}
cdata = xmalloc(sizeof *cdata); cdata = xmalloc(sizeof *cdata);
cdata->cmd_if = xstrdup(args->argv[1]); cdata->cmd_if = xstrdup(args->argv[1]);
if (args->argc == 3) if (args->argc == 3)

View File

@ -40,8 +40,26 @@ int format_replace(struct format_tree *, const char *, size_t, char **,
char *format_get_command(struct window_pane *); char *format_get_command(struct window_pane *);
void format_window_pane_tabs(struct format_tree *, struct window_pane *); void format_window_pane_tabs(struct format_tree *, struct window_pane *);
/* Entry in format tree. */
struct format_entry {
char *key;
char *value;
RB_ENTRY(format_entry) entry;
};
/* Tree of format entries. */
struct format_tree {
struct window *w;
struct session *s;
RB_HEAD(format_rb_tree, format_entry) tree;
};
/* Format key-value replacement entry. */ /* Format key-value replacement entry. */
RB_GENERATE(format_tree, format_entry, entry, format_cmp); int format_cmp(struct format_entry *, struct format_entry *);
RB_PROTOTYPE(format_rb_tree, format_entry, entry, format_cmp);
RB_GENERATE(format_rb_tree, format_entry, entry, format_cmp);
/* Format tree comparison function. */ /* Format tree comparison function. */
int int
@ -117,8 +135,8 @@ format_create(void)
struct format_tree *ft; struct format_tree *ft;
char host[MAXHOSTNAMELEN], *ptr; char host[MAXHOSTNAMELEN], *ptr;
ft = xmalloc(sizeof *ft); ft = xcalloc(1, sizeof *ft);
RB_INIT(ft); RB_INIT(&ft->tree);
if (gethostname(host, sizeof host) == 0) { if (gethostname(host, sizeof host) == 0) {
format_add(ft, "host", "%s", host); format_add(ft, "host", "%s", host);
@ -134,14 +152,10 @@ format_create(void)
void void
format_free(struct format_tree *ft) format_free(struct format_tree *ft)
{ {
struct format_entry *fe, *fe_next; struct format_entry *fe, *fe1;
fe_next = RB_MIN(format_tree, ft); RB_FOREACH_SAFE(fe, format_rb_tree, &ft->tree, fe1) {
while (fe_next != NULL) { RB_REMOVE(format_rb_tree, &ft->tree, fe);
fe = fe_next;
fe_next = RB_NEXT(format_tree, ft, fe);
RB_REMOVE(format_tree, ft, fe);
free(fe->value); free(fe->value);
free(fe->key); free(fe->key);
free(fe); free(fe);
@ -165,7 +179,7 @@ format_add(struct format_tree *ft, const char *key, const char *fmt, ...)
xvasprintf(&fe->value, fmt, ap); xvasprintf(&fe->value, fmt, ap);
va_end(ap); va_end(ap);
fe_now = RB_INSERT(format_tree, ft, fe); fe_now = RB_INSERT(format_rb_tree, &ft->tree, fe);
if (fe_now != NULL) { if (fe_now != NULL) {
free(fe_now->value); free(fe_now->value);
fe_now->value = fe->value; fe_now->value = fe->value;
@ -179,9 +193,32 @@ const char *
format_find(struct format_tree *ft, const char *key) format_find(struct format_tree *ft, const char *key)
{ {
struct format_entry *fe, fe_find; struct format_entry *fe, fe_find;
struct options_entry *o;
static char s[16];
o = options_find(&global_options, key);
if (o == NULL && ft->w != NULL)
o = options_find(&ft->w->options, key);
if (o == NULL)
o = options_find(&global_w_options, key);
if (o == NULL && ft->s != NULL)
o = options_find(&ft->s->options, key);
if (o == NULL)
o = options_find(&global_s_options, key);
if (o != NULL) {
switch (o->type) {
case OPTIONS_STRING:
return (o->str);
case OPTIONS_NUMBER:
snprintf(s, sizeof s, "%lld", o->num);
return (s);
case OPTIONS_STYLE:
return (style_tostring(&o->style));
}
}
fe_find.key = (char *) key; fe_find.key = (char *) key;
fe = RB_FIND(format_tree, ft, &fe_find); fe = RB_FIND(format_rb_tree, &ft->tree, &fe_find);
if (fe == NULL) if (fe == NULL)
return (NULL); return (NULL);
return (fe->value); return (fe->value);
@ -206,7 +243,7 @@ format_replace(struct format_tree *ft, const char *key, size_t keylen,
copy[keylen] = '\0'; copy[keylen] = '\0';
/* Is there a length limit or whatnot? */ /* Is there a length limit or whatnot? */
if (!islower((u_char) *copy) && *copy != '?') { if (!islower((u_char) *copy) && *copy != '@' && *copy != '?') {
while (*copy != ':' && *copy != '\0') { while (*copy != ':' && *copy != '\0') {
switch (*copy) { switch (*copy) {
case '=': case '=':
@ -389,6 +426,8 @@ format_session(struct format_tree *ft, struct session *s)
char *tim; char *tim;
time_t t; time_t t;
ft->s = s;
format_add(ft, "session_name", "%s", s->name); format_add(ft, "session_name", "%s", s->name);
format_add(ft, "session_windows", "%u", winlink_count(&s->windows)); format_add(ft, "session_windows", "%u", winlink_count(&s->windows));
format_add(ft, "session_width", "%u", s->sx); format_add(ft, "session_width", "%u", s->sx);
@ -418,6 +457,9 @@ format_client(struct format_tree *ft, struct client *c)
time_t t; time_t t;
struct session *s; struct session *s;
if (ft->s == NULL)
ft->s = c->session;
format_add(ft, "client_height", "%u", c->tty.sy); format_add(ft, "client_height", "%u", c->tty.sy);
format_add(ft, "client_width", "%u", c->tty.sx); format_add(ft, "client_width", "%u", c->tty.sx);
if (c->tty.path != NULL) if (c->tty.path != NULL)
@ -463,6 +505,8 @@ format_window(struct format_tree *ft, struct window *w)
{ {
char *layout; char *layout;
ft->w = w;
layout = layout_dump(w); layout = layout_dump(w);
format_add(ft, "window_id", "@%u", w->id); format_add(ft, "window_id", "@%u", w->id);
@ -471,6 +515,8 @@ format_window(struct format_tree *ft, struct window *w)
format_add(ft, "window_height", "%u", w->sy); format_add(ft, "window_height", "%u", w->sy);
format_add(ft, "window_layout", "%s", layout); format_add(ft, "window_layout", "%s", layout);
format_add(ft, "window_panes", "%u", window_count_panes(w)); format_add(ft, "window_panes", "%u", window_count_panes(w));
format_add(ft, "window_zoomed_flag", "%u",
!!(w->flags & WINDOW_ZOOMED));
free(layout); free(layout);
} }
@ -482,6 +528,9 @@ format_winlink(struct format_tree *ft, struct session *s, struct winlink *wl)
struct window *w = wl->window; struct window *w = wl->window;
char *flags; char *flags;
if (ft->w == NULL)
ft->w = wl->window;
flags = window_printable_flags(s, wl); flags = window_printable_flags(s, wl);
format_window(ft, w); format_window(ft, w);
@ -498,8 +547,6 @@ format_winlink(struct format_tree *ft, struct session *s, struct winlink *wl)
!!(wl->flags & WINLINK_SILENCE)); !!(wl->flags & WINLINK_SILENCE));
format_add(ft, "window_last_flag", "%u", format_add(ft, "window_last_flag", "%u",
!!(wl == TAILQ_FIRST(&s->lastw))); !!(wl == TAILQ_FIRST(&s->lastw)));
format_add(ft, "window_zoomed_flag", "%u",
!!(wl->flags & WINDOW_ZOOMED));
free(flags); free(flags);
} }
@ -536,6 +583,9 @@ format_window_pane(struct format_tree *ft, struct window_pane *wp)
u_int i, idx; u_int i, idx;
char *cmd, *cwd; char *cmd, *cwd;
if (ft->w == NULL)
ft->w = wp->window;
size = 0; size = 0;
for (i = 0; i < gd->hsize; i++) { for (i = 0; i < gd->hsize; i++) {
gl = &gd->linedata[i]; gl = &gd->linedata[i];

View File

@ -184,9 +184,10 @@ grid_view_insert_cells(struct grid *gd, u_int px, u_int py, u_int nx)
px = grid_view_x(gd, px); px = grid_view_x(gd, px);
py = grid_view_y(gd, py); py = grid_view_y(gd, py);
sx = grid_view_x(gd, gd->linedata[py].cellsize); if (gd->linedata[py].cellsize + nx < gd->sx)
if (sx < px + nx) sx = grid_view_x(gd, gd->linedata[py].cellsize + nx);
sx = px + nx; else
sx = grid_view_x(gd, gd->sx);
if (px == sx - 1) if (px == sx - 1)
grid_clear(gd, px, py, 1, 1); grid_clear(gd, px, py, 1, 1);

2
log.c
View File

@ -46,7 +46,7 @@ log_open(const char *path)
if (log_file == NULL) if (log_file == NULL)
return; return;
setlinebuf(log_file); setvbuf(log_file, NULL, _IOLBF, 0);
event_set_log_callback(log_event_cb); event_set_log_callback(log_event_cb);
tzset(); tzset();

34
tmux.1
View File

@ -3043,12 +3043,17 @@ and
.Ql } , .Ql } ,
for example for example
.Ql #{session_name} . .Ql #{session_name} .
Some variables also have an shorter alias such as The possible variables are listed in the table below, or the name of a
.Ql #S . .Nm
option may be used for an option's value.
Some variables have a shorter alias such as
.Ql #S ,
and
.Ql ## .Ql ##
is replaced by a single is replaced by a single
.Ql # . .Ql # .
Conditionals are also accepted by prefixing with .Pp
Conditionals are available by prefixing with
.Ql \&? .Ql \&?
and separating two alternatives with a comma; and separating two alternatives with a comma;
if the specified variable exists and is not zero, the first alternative if the specified variable exists and is not zero, the first alternative
@ -3059,7 +3064,15 @@ will include the string
.Ql attached .Ql attached
if the session is attached and the string if the session is attached and the string
.Ql not attached .Ql not attached
if it is unattached. if it is unattached, or
.Ql #{?automatic-rename,yes,no}
will include
.Ql yes
if
.Ic automatic-rename
is enabled, or
.Ql no
if not.
A limit may be placed on the length of the resultant string by prefixing it A limit may be placed on the length of the resultant string by prefixing it
by an by an
.Ql = , .Ql = ,
@ -3581,7 +3594,7 @@ Miscellaneous commands are as follows:
.It Ic clock-mode Op Fl t Ar target-pane .It Ic clock-mode Op Fl t Ar target-pane
Display a large clock. Display a large clock.
.It Xo Ic if-shell .It Xo Ic if-shell
.Op Fl b .Op Fl bF
.Op Fl t Ar target-pane .Op Fl t Ar target-pane
.Ar shell-command command .Ar shell-command command
.Op Ar command .Op Ar command
@ -3594,7 +3607,9 @@ if
returns success or the second returns success or the second
.Ar command .Ar command
otherwise. otherwise.
Before being executed, shell-command is expanded using the rules specified in the Before being executed,
.Ar shell-command
is expanded using the rules specified in the
.Sx FORMATS .Sx FORMATS
section, including those relevant to section, including those relevant to
.Ar target-pane . .Ar target-pane .
@ -3602,6 +3617,13 @@ With
.Fl b , .Fl b ,
.Ar shell-command .Ar shell-command
is run in the background. is run in the background.
.Pp
If
.Fl F
is given,
.Ar shell-command
is not executed but considered success if neither empty nor zero (after formats
are expanded).
.It Ic lock-server .It Ic lock-server
.D1 (alias: Ic lock ) .D1 (alias: Ic lock )
Lock each client individually by running the command specified by the Lock each client individually by running the command specified by the

15
tmux.h
View File

@ -1459,15 +1459,6 @@ struct options_table_entry {
const char *style; const char *style;
}; };
/* Tree of format entries. */
struct format_entry {
char *key;
char *value;
RB_ENTRY(format_entry) entry;
};
RB_HEAD(format_tree, format_entry);
/* Common command usages. */ /* Common command usages. */
#define CMD_TARGET_PANE_USAGE "[-t target-pane]" #define CMD_TARGET_PANE_USAGE "[-t target-pane]"
#define CMD_TARGET_WINDOW_USAGE "[-t target-window]" #define CMD_TARGET_WINDOW_USAGE "[-t target-window]"
@ -1511,8 +1502,7 @@ void cfg_print_causes(struct cmd_q *);
void cfg_show_causes(struct session *); void cfg_show_causes(struct session *);
/* format.c */ /* format.c */
int format_cmp(struct format_entry *, struct format_entry *); struct format_tree;
RB_PROTOTYPE(format_tree, format_entry, entry, format_cmp);
struct format_tree *format_create(void); struct format_tree *format_create(void);
void format_free(struct format_tree *); void format_free(struct format_tree *);
void printflike(3, 4) format_add(struct format_tree *, const char *, void printflike(3, 4) format_add(struct format_tree *, const char *,
@ -2234,9 +2224,6 @@ struct window_choose_data *window_choose_add_window(struct window_pane *,
struct window_choose_data *window_choose_add_session(struct window_pane *, struct window_choose_data *window_choose_add_session(struct window_pane *,
struct client *, struct session *, const char *, struct client *, struct session *, const char *,
const char *, u_int); const char *, u_int);
struct window_choose_data *window_choose_add_item(struct window_pane *,
struct client *, struct winlink *, const char *,
const char *, u_int);
void window_choose_expand_all(struct window_pane *); void window_choose_expand_all(struct window_pane *);
void window_choose_collapse_all(struct window_pane *); void window_choose_collapse_all(struct window_pane *);
void window_choose_set_current(struct window_pane *, u_int); void window_choose_set_current(struct window_pane *, u_int);

View File

@ -931,36 +931,6 @@ window_choose_add_session(struct window_pane *wp, struct client *c,
return (wcd); return (wcd);
} }
struct window_choose_data *
window_choose_add_item(struct window_pane *wp, struct client *c,
struct winlink *wl, const char *template, const char *action, u_int idx)
{
struct window_choose_data *wcd;
char *expanded;
wcd = window_choose_data_create(TREE_OTHER, c, c->session);
wcd->idx = wl->idx;
wcd->ft_template = xstrdup(template);
format_add(wcd->ft, "line", "%u", idx);
format_session(wcd->ft, wcd->start_session);
format_winlink(wcd->ft, wcd->start_session, wl);
format_window_pane(wcd->ft, wl->window->active);
/*
* Interpolate action here, since the data we pass back is the expanded
* template itself.
*/
xasprintf(&expanded, "%s", format_expand(wcd->ft, wcd->ft_template));
wcd->command = cmd_template_replace(action, expanded, 1);
free(expanded);
window_choose_add(wp, wcd);
return (wcd);
}
struct window_choose_data * struct window_choose_data *
window_choose_add_window(struct window_pane *wp, struct client *c, window_choose_add_window(struct window_pane *wp, struct client *c,
struct session *s, struct winlink *wl, const char *template, struct session *s, struct winlink *wl, const char *template,