1
0
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:
Nicolas Viennot 2013-06-12 19:40:30 -04:00
parent a1d7bf7dc0
commit 844451c6ce
10 changed files with 168 additions and 28 deletions

View File

@ -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 \

View File

@ -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,

View File

@ -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 &&

View File

@ -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 {

View File

@ -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);

View File

@ -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
View 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);
}

View File

@ -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

View File

@ -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

3
tmux.h
View File

@ -1332,6 +1332,9 @@ struct client {
#define CLIENT_REDRAWWINDOW 0x1000
#define CLIENT_CONTROL 0x2000
#define CLIENT_FOCUSED 0x4000
#ifdef TMATE
#define CLIENT_FORCE_STATUS 0x800000
#endif
int flags;
struct event identify_timer;