mirror of
https://github.com/tmate-io/tmate-ssh-server.git
synced 2020-11-18 19:53:51 -08:00
Show tmate messages in the status bar
This commit is contained in:
parent
a1d7bf7dc0
commit
844451c6ce
@ -181,6 +181,7 @@ dist_tmate_SOURCES = \
|
||||
tmate-ssh-client.c \
|
||||
tmate-encoder.c \
|
||||
tmate-decoder.c \
|
||||
tmate-msg.c \
|
||||
tmate.c \
|
||||
tmux.c \
|
||||
tty-acs.c \
|
||||
|
@ -169,6 +169,13 @@ const struct options_table_entry session_options_table[] = {
|
||||
.default_num = 750
|
||||
},
|
||||
|
||||
{ .name = "tmate-display-time",
|
||||
.type = OPTIONS_TABLE_NUMBER,
|
||||
.minimum = 1,
|
||||
.maximum = INT_MAX,
|
||||
.default_num = 30000
|
||||
},
|
||||
|
||||
{ .name = "history-limit",
|
||||
.type = OPTIONS_TABLE_NUMBER,
|
||||
.minimum = 0,
|
||||
|
4
resize.c
4
resize.c
@ -62,6 +62,10 @@ recalculate_sizes(void)
|
||||
if (c == NULL || c->flags & CLIENT_SUSPENDED)
|
||||
continue;
|
||||
if (c->session == s) {
|
||||
#ifdef TMATE
|
||||
if (c->flags & CLIENT_FORCE_STATUS)
|
||||
has_status = 1;
|
||||
#endif
|
||||
if (c->tty.sx < ssx)
|
||||
ssx = c->tty.sx;
|
||||
if (has_status &&
|
||||
|
@ -271,6 +271,9 @@ server_client_status_timer(void)
|
||||
s = c->session;
|
||||
|
||||
if (!options_get_number(&s->options, "status"))
|
||||
#ifdef TMATE
|
||||
if (!(c->flags & CLIENT_FORCE_STATUS))
|
||||
#endif
|
||||
continue;
|
||||
interval = options_get_number(&s->options, "status-interval");
|
||||
|
||||
@ -395,6 +398,9 @@ server_client_handle_key(struct client *c, int key)
|
||||
|
||||
/* Handle status line. */
|
||||
if (!(c->flags & CLIENT_READONLY)) {
|
||||
#ifdef TMATE
|
||||
if (!(c->flags & CLIENT_FORCE_STATUS))
|
||||
#endif
|
||||
status_message_clear(c);
|
||||
server_clear_identify(c);
|
||||
}
|
||||
@ -635,6 +641,10 @@ server_client_reset_state(struct client *c)
|
||||
tty_region(&c->tty, 0, c->tty.sy - 1);
|
||||
|
||||
status = options_get_number(oo, "status");
|
||||
#ifdef TMATE
|
||||
if (c->flags & CLIENT_FORCE_STATUS)
|
||||
status = 1;
|
||||
#endif
|
||||
if (!window_pane_visible(wp) || wp->yoff + s->cy >= c->tty.sy - status)
|
||||
tty_cursor(&c->tty, 0, 0);
|
||||
else {
|
||||
|
10
status.c
10
status.c
@ -171,6 +171,9 @@ status_redraw(struct client *c)
|
||||
|
||||
/* No status line? */
|
||||
if (c->tty.sy == 0 || !options_get_number(&s->options, "status"))
|
||||
#ifdef TMATE
|
||||
if (c->tty.sy == 0 || !(c->flags & CLIENT_FORCE_STATUS))
|
||||
#endif
|
||||
return (1);
|
||||
left = right = NULL;
|
||||
larrow = rarrow = 0;
|
||||
@ -802,6 +805,7 @@ status_message_set(struct client *c, const char *fmt, ...)
|
||||
}
|
||||
}
|
||||
|
||||
/* FIXME tmux: session can be NULL */
|
||||
delay = options_get_number(&c->session->options, "display-time");
|
||||
tv.tv_sec = delay / 1000;
|
||||
tv.tv_usec = (delay % 1000) * 1000L;
|
||||
@ -826,6 +830,12 @@ status_message_clear(struct client *c)
|
||||
c->message_string = NULL;
|
||||
|
||||
c->tty.flags &= ~(TTY_NOCURSOR|TTY_FREEZE);
|
||||
#ifdef TMATE
|
||||
if (c->flags & CLIENT_FORCE_STATUS) {
|
||||
c->flags &= ~CLIENT_FORCE_STATUS;
|
||||
recalculate_sizes();
|
||||
}
|
||||
#endif
|
||||
c->flags |= CLIENT_REDRAW; /* screen was frozen and may have changed */
|
||||
|
||||
screen_reinit(&c->status);
|
||||
|
@ -74,6 +74,13 @@ static char *unpack_string(struct tmate_unpacker *uk)
|
||||
return alloc_buf;
|
||||
}
|
||||
|
||||
static void tmate_reply_header(struct tmate_unpacker *uk)
|
||||
{
|
||||
unsigned long flags = unpack_int(uk);
|
||||
char *remote_session = unpack_string(uk);
|
||||
|
||||
tmate_status_message("Remote session: %s", remote_session);
|
||||
}
|
||||
|
||||
static void tmate_client_pane_key(struct tmate_unpacker *uk)
|
||||
{
|
||||
@ -138,6 +145,7 @@ static void handle_message(msgpack_object obj)
|
||||
init_unpacker(uk, obj);
|
||||
|
||||
switch (unpack_int(uk)) {
|
||||
case TMATE_REPLY_HEADER: tmate_reply_header(uk); break;
|
||||
case TMATE_CLIENT_PANE_KEY: tmate_client_pane_key(uk); break;
|
||||
case TMATE_CLIENT_RESIZE: tmate_client_resize(uk); break;
|
||||
case TMATE_CLIENT_CMD: tmate_client_cmd(uk); break;
|
||||
|
78
tmate-msg.c
Normal file
78
tmate-msg.c
Normal file
@ -0,0 +1,78 @@
|
||||
#include <time.h>
|
||||
#include "tmate.h"
|
||||
|
||||
void status_message_callback(int, short, void *);
|
||||
|
||||
/* Very similar to status.c:status_message_set */
|
||||
|
||||
static void tmate_status_message_client(struct client *c, const char *message)
|
||||
{
|
||||
struct timeval tv;
|
||||
struct session *s = c->session;
|
||||
struct message_entry *msg;
|
||||
int delay;
|
||||
u_int i, limit;
|
||||
|
||||
status_prompt_clear(c);
|
||||
status_message_clear(c);
|
||||
|
||||
xasprintf(&c->message_string, "tmate: %s", message);
|
||||
|
||||
ARRAY_EXPAND(&c->message_log, 1);
|
||||
msg = &ARRAY_LAST(&c->message_log);
|
||||
msg->msg_time = time(NULL);
|
||||
msg->msg = xstrdup(c->message_string);
|
||||
|
||||
if (!s)
|
||||
return;
|
||||
|
||||
limit = options_get_number(&s->options, "message-limit");
|
||||
if (ARRAY_LENGTH(&c->message_log) > limit) {
|
||||
limit = ARRAY_LENGTH(&c->message_log) - limit;
|
||||
for (i = 0; i < limit; i++) {
|
||||
msg = &ARRAY_FIRST(&c->message_log);
|
||||
free(msg->msg);
|
||||
ARRAY_REMOVE(&c->message_log, 0);
|
||||
}
|
||||
}
|
||||
|
||||
delay = options_get_number(&c->session->options, "tmate-display-time");
|
||||
tv.tv_sec = delay / 1000;
|
||||
tv.tv_usec = (delay % 1000) * 1000L;
|
||||
|
||||
if (event_initialized (&c->message_timer))
|
||||
evtimer_del(&c->message_timer);
|
||||
evtimer_set(&c->message_timer, status_message_callback, c);
|
||||
evtimer_add(&c->message_timer, &tv);
|
||||
|
||||
c->flags |= CLIENT_STATUS | CLIENT_FORCE_STATUS;
|
||||
|
||||
recalculate_sizes();
|
||||
}
|
||||
|
||||
void __tmate_status_message(const char *fmt, va_list ap)
|
||||
{
|
||||
struct client *c;
|
||||
unsigned int i;
|
||||
char *message;
|
||||
|
||||
xvasprintf(&message, fmt, ap);
|
||||
tmate_debug("%s", message);
|
||||
|
||||
for (i = 0; i < ARRAY_LENGTH(&clients); i++) {
|
||||
c = ARRAY_ITEM(&clients, i);
|
||||
if (c && !(c->flags & CLIENT_READONLY))
|
||||
tmate_status_message_client(c, message);
|
||||
}
|
||||
|
||||
free(message);
|
||||
}
|
||||
|
||||
void printflike1 tmate_status_message(const char *fmt, ...)
|
||||
{
|
||||
va_list ap;
|
||||
|
||||
va_start(ap, fmt);
|
||||
__tmate_status_message(fmt, ap);
|
||||
va_end(ap);
|
||||
}
|
@ -11,8 +11,10 @@ static void consume_channel(struct tmate_ssh_client *client);
|
||||
static void flush_input_stream(struct tmate_ssh_client *client);
|
||||
static void __flush_input_stream(evutil_socket_t fd, short what, void *arg);
|
||||
static void __on_session_event(evutil_socket_t fd, short what, void *arg);
|
||||
static void disconnect_session(struct tmate_ssh_client *client);
|
||||
static void reconnect_session(struct tmate_ssh_client *client);
|
||||
static void printflike2 disconnect_session(struct tmate_ssh_client *client,
|
||||
const char *fmt, ...);
|
||||
static void printflike2 reconnect_session(struct tmate_ssh_client *client,
|
||||
const char *fmt, ...);
|
||||
|
||||
static void log_function(ssh_session session, int priority,
|
||||
const char *message, void *userdata)
|
||||
@ -56,9 +58,8 @@ static void consume_channel(struct tmate_ssh_client *client)
|
||||
tmate_decoder_get_buffer(client->decoder, &buf, &len);
|
||||
len = ssh_channel_read_nonblocking(client->channel, buf, len, 0);
|
||||
if (len < 0) {
|
||||
tmate_debug("Error reading from channel: %s",
|
||||
ssh_get_error(client->session));
|
||||
reconnect_session(client);
|
||||
reconnect_session(client, "Error reading from channel: %s",
|
||||
ssh_get_error(client->session));
|
||||
break;
|
||||
}
|
||||
|
||||
@ -107,7 +108,7 @@ static void on_session_event(struct tmate_ssh_client *client)
|
||||
ssh_options_set(session, SSH_OPTIONS_USER, "tmate");
|
||||
ssh_options_set(session, SSH_OPTIONS_COMPRESSION, "yes");
|
||||
|
||||
tmate_debug("Connecting...");
|
||||
tmate_status_message("Connecting to %s...", TMATE_HOST);
|
||||
client->state = SSH_CONNECT;
|
||||
/* fall through */
|
||||
|
||||
@ -117,8 +118,8 @@ static void on_session_event(struct tmate_ssh_client *client)
|
||||
register_session_fd_event(client);
|
||||
return;
|
||||
case SSH_ERROR:
|
||||
tmate_debug("Error connecting: %s", ssh_get_error(session));
|
||||
reconnect_session(client);
|
||||
reconnect_session(client, "Error connecting: %s",
|
||||
ssh_get_error(session));
|
||||
return;
|
||||
case SSH_OK:
|
||||
register_session_fd_event(client);
|
||||
@ -129,8 +130,7 @@ static void on_session_event(struct tmate_ssh_client *client)
|
||||
|
||||
case SSH_AUTH_SERVER:
|
||||
if ((hash_len = ssh_get_pubkey_hash(session, &hash)) < 0) {
|
||||
tmate_debug("Cannnot authenticate server");
|
||||
disconnect_session(client);
|
||||
disconnect_session(client, "Cannnot authenticate server");
|
||||
return;
|
||||
}
|
||||
|
||||
@ -165,8 +165,7 @@ static void on_session_event(struct tmate_ssh_client *client)
|
||||
free(hash_str);
|
||||
|
||||
if (!match) {
|
||||
tmate_debug("Cannnot authenticate server");
|
||||
disconnect_session(client);
|
||||
disconnect_session(client, "Cannnot authenticate server");
|
||||
return;
|
||||
}
|
||||
|
||||
@ -180,12 +179,11 @@ static void on_session_event(struct tmate_ssh_client *client)
|
||||
case SSH_AUTH_PARTIAL:
|
||||
case SSH_AUTH_INFO:
|
||||
case SSH_AUTH_DENIED:
|
||||
tmate_debug("Access denied. Try again later.");
|
||||
disconnect_session(client);
|
||||
disconnect_session(client, "Access denied. Try again later.");
|
||||
return;
|
||||
case SSH_AUTH_ERROR:
|
||||
tmate_debug("Auth error: %s", ssh_get_error(session));
|
||||
reconnect_session(client);
|
||||
reconnect_session(client, "Auth error: %s",
|
||||
ssh_get_error(session));
|
||||
return;
|
||||
case SSH_AUTH_SUCCESS:
|
||||
tmate_debug("Auth successful");
|
||||
@ -198,8 +196,8 @@ static void on_session_event(struct tmate_ssh_client *client)
|
||||
case SSH_AGAIN:
|
||||
return;
|
||||
case SSH_ERROR:
|
||||
tmate_debug("Error opening channel: %s", ssh_get_error(session));
|
||||
reconnect_session(client);
|
||||
reconnect_session(client, "Error opening channel: %s",
|
||||
ssh_get_error(session));
|
||||
return;
|
||||
case SSH_OK:
|
||||
tmate_debug("Session opened, initalizing tmate");
|
||||
@ -212,8 +210,8 @@ static void on_session_event(struct tmate_ssh_client *client)
|
||||
case SSH_AGAIN:
|
||||
return;
|
||||
case SSH_ERROR:
|
||||
tmate_debug("Error initializing tmate: %s", ssh_get_error(session));
|
||||
reconnect_session(client);
|
||||
reconnect_session(client, "Error initializing tmate: %s",
|
||||
ssh_get_error(session));
|
||||
return;
|
||||
case SSH_OK:
|
||||
tmate_debug("Ready");
|
||||
@ -230,8 +228,7 @@ static void on_session_event(struct tmate_ssh_client *client)
|
||||
case SSH_READY:
|
||||
consume_channel(client);
|
||||
if (!ssh_is_connected(session)) {
|
||||
tmate_debug("Disconnected");
|
||||
reconnect_session(client);
|
||||
reconnect_session(client, "Disconnected");
|
||||
return;
|
||||
}
|
||||
}
|
||||
@ -255,9 +252,8 @@ static void flush_input_stream(struct tmate_ssh_client *client)
|
||||
|
||||
written = ssh_channel_write(client->channel, buf, len);
|
||||
if (written < 0) {
|
||||
tmate_debug("Error writing to channel: %s",
|
||||
ssh_get_error(client->session));
|
||||
reconnect_session(client);
|
||||
reconnect_session(client, "Error writing to channel: %s",
|
||||
ssh_get_error(client->session));
|
||||
return;
|
||||
}
|
||||
|
||||
@ -275,8 +271,11 @@ static void __on_session_event(evutil_socket_t fd, short what, void *arg)
|
||||
on_session_event(arg);
|
||||
}
|
||||
|
||||
static void disconnect_session(struct tmate_ssh_client *client)
|
||||
static void __disconnect_session(struct tmate_ssh_client *client,
|
||||
const char *fmt, va_list va)
|
||||
{
|
||||
__tmate_status_message(fmt, va);
|
||||
|
||||
if (event_initialized(&client->ev_ssh)) {
|
||||
event_del(&client->ev_ssh);
|
||||
client->ev_ssh.ev_flags = 0;
|
||||
@ -297,6 +296,16 @@ static void disconnect_session(struct tmate_ssh_client *client)
|
||||
client->state = SSH_NONE;
|
||||
}
|
||||
|
||||
static void printflike2 disconnect_session(struct tmate_ssh_client *client,
|
||||
const char *fmt, ...)
|
||||
{
|
||||
va_list ap;
|
||||
|
||||
va_start(ap, fmt);
|
||||
__disconnect_session(client, fmt, ap);
|
||||
va_end(ap);
|
||||
}
|
||||
|
||||
static void connect_session(struct tmate_ssh_client *client)
|
||||
{
|
||||
if (!client->session) {
|
||||
@ -310,11 +319,15 @@ static void on_reconnect_timer(evutil_socket_t fd, short what, void *arg)
|
||||
connect_session(arg);
|
||||
}
|
||||
|
||||
static void reconnect_session(struct tmate_ssh_client *client)
|
||||
static void printflike2 reconnect_session(struct tmate_ssh_client *client,
|
||||
const char *fmt, ...)
|
||||
{
|
||||
struct timeval tv;
|
||||
va_list ap;
|
||||
|
||||
disconnect_session(client);
|
||||
va_start(ap, fmt);
|
||||
__disconnect_session(client, fmt, ap);
|
||||
va_end(ap);
|
||||
|
||||
/* Not yet implemented... */
|
||||
#if 0
|
||||
|
6
tmate.h
6
tmate.h
@ -44,6 +44,7 @@ extern void tmate_status(const char *left, const char *right);
|
||||
/* tmate-decoder.c */
|
||||
|
||||
enum tmate_client_commands {
|
||||
TMATE_REPLY_HEADER,
|
||||
TMATE_CLIENT_PANE_KEY,
|
||||
TMATE_CLIENT_RESIZE,
|
||||
TMATE_CLIENT_CMD,
|
||||
@ -112,4 +113,9 @@ extern void tmate_client_start(void);
|
||||
/* tmate-debug.c */
|
||||
extern void tmate_print_trace (void);
|
||||
|
||||
/* tmate-msg.c */
|
||||
|
||||
extern void __tmate_status_message(const char *fmt, va_list ap);
|
||||
extern void printflike1 tmate_status_message(const char *fmt, ...);
|
||||
|
||||
#endif
|
||||
|
Loading…
x
Reference in New Issue
Block a user