tmate/tmate-decoder.c

212 lines
4.4 KiB
C
Raw Normal View History

2013-06-02 05:16:06 +02:00
#include "tmate.h"
2016-01-01 22:44:01 +01:00
#include "tmate-protocol.h"
2013-06-02 05:16:06 +02:00
2016-01-01 22:44:01 +01:00
static void handle_notify(__unused struct tmate_session *session,
struct tmate_unpacker *uk)
2013-06-13 01:40:30 +02:00
{
2013-06-13 10:31:25 +02:00
char *msg = unpack_string(uk);
tmate_status_message("%s", msg);
free(msg);
2013-06-13 01:40:30 +02:00
}
2013-06-12 04:07:04 +02:00
2016-01-01 22:44:01 +01:00
static void handle_legacy_pane_key(__unused struct tmate_session *_session,
struct tmate_unpacker *uk)
2013-06-12 04:07:04 +02:00
{
struct session *s;
struct window *w;
struct window_pane *wp;
2013-06-02 05:16:06 +02:00
int key = unpack_int(uk);
2013-06-12 04:07:04 +02:00
s = RB_MIN(sessions, &sessions);
if (!s)
return;
2013-06-02 05:16:06 +02:00
2013-06-12 04:07:04 +02:00
w = s->curw->window;
if (!w)
return;
wp = w->active;
if (!wp)
return;
2015-12-23 11:41:41 +01:00
window_pane_key(wp, NULL, s, key, NULL);
2013-06-02 05:16:06 +02:00
}
2015-12-31 17:35:36 +01:00
static struct window_pane *find_window_pane(struct session *s, int pane_id)
2015-12-30 19:40:18 +01:00
{
struct window *w;
2016-01-05 16:53:28 +01:00
if (pane_id != -1)
return window_pane_find_by_id(pane_id);
2015-12-30 19:40:18 +01:00
w = s->curw->window;
if (!w)
2015-12-31 17:35:36 +01:00
return NULL;
2016-01-05 16:53:28 +01:00
return w->active;
2015-12-30 19:40:18 +01:00
}
2016-01-01 22:44:01 +01:00
static void handle_pane_key(__unused struct tmate_session *_session,
struct tmate_unpacker *uk)
2015-12-30 19:40:18 +01:00
{
struct session *s;
struct window_pane *wp;
int pane_id = unpack_int(uk);
key_code key = unpack_int(uk);
s = RB_MIN(sessions, &sessions);
if (!s)
return;
wp = find_window_pane(s, pane_id);
if (!wp)
return;
window_pane_key(wp, NULL, s, key, NULL);
}
2016-01-01 22:44:01 +01:00
static void handle_resize(struct tmate_session *session,
struct tmate_unpacker *uk)
2013-06-02 05:16:06 +02:00
{
2016-01-01 22:44:01 +01:00
session->min_sx = unpack_int(uk);
session->min_sy = unpack_int(uk);
2013-06-02 05:16:06 +02:00
recalculate_sizes();
}
2015-12-23 11:41:41 +01:00
extern char **cfg_causes;
extern u_int cfg_ncauses;
static void handle_exec_cmd_str(__unused struct tmate_session *session,
struct tmate_unpacker *uk)
2013-06-12 04:07:04 +02:00
{
struct cmd_q *cmd_q;
struct cmd_list *cmdlist;
char *cause;
2015-12-23 11:41:41 +01:00
u_int i;
2013-06-12 04:07:04 +02:00
int client_id = unpack_int(uk);
char *cmd_str = unpack_string(uk);
2013-06-12 04:07:04 +02:00
if (cmd_string_parse(cmd_str, &cmdlist, NULL, 0, &cause) != 0) {
tmate_failed_cmd(client_id, cause);
2013-06-12 04:07:04 +02:00
free(cause);
goto out;
}
cmd_q = cmdq_new(NULL);
2015-12-23 11:41:41 +01:00
cmdq_run(cmd_q, cmdlist, NULL);
2013-06-12 04:07:04 +02:00
cmd_list_free(cmdlist);
cmdq_free(cmd_q);
2015-12-23 11:41:41 +01:00
/* error messages land in cfg_causes */
for (i = 0; i < cfg_ncauses; i++) {
tmate_failed_cmd(client_id, cfg_causes[i]);
free(cfg_causes[i]);
}
2015-12-23 11:41:41 +01:00
free(cfg_causes);
cfg_causes = NULL;
cfg_ncauses = 0;
2013-06-12 04:07:04 +02:00
out:
free(cmd_str);
}
static void handle_exec_cmd(__unused struct tmate_session *session,
struct tmate_unpacker *uk)
{
struct cmd_q *cmd_q;
struct cmd_list *cmdlist;
struct cmd *cmd;
char *cause;
u_int i;
unsigned int argc;
char **argv;
int client_id = unpack_int(uk);
argc = uk->argc;
argv = xmalloc(sizeof(char *) * argc);
for (i = 0; i < argc; i++)
argv[i] = unpack_string(uk);
cmd = cmd_parse(argc, argv, NULL, 0, &cause);
if (!cmd) {
tmate_failed_cmd(client_id, cause);
free(cause);
goto out;
}
cmdlist = xcalloc(1, sizeof *cmdlist);
cmdlist->references = 1;
TAILQ_INIT(&cmdlist->list);
TAILQ_INSERT_TAIL(&cmdlist->list, cmd, qentry);
cmd_q = cmdq_new(NULL);
cmdq_run(cmd_q, cmdlist, NULL);
cmd_list_free(cmdlist);
cmdq_free(cmd_q);
/* error messages land in cfg_causes */
for (i = 0; i < cfg_ncauses; i++) {
tmate_failed_cmd(client_id, cfg_causes[i]);
free(cfg_causes[i]);
}
free(cfg_causes);
cfg_causes = NULL;
cfg_ncauses = 0;
out:
cmd_free_argv(argc, argv);
}
2016-03-27 00:00:16 +01:00
static void maybe_save_reconnection_data(struct tmate_session *session,
const char *name, const char *value)
{
if (!strcmp(name, "tmate_reconnection_data")) {
free(session->reconnection_data);
session->reconnection_data = xstrdup(value);
}
}
static void handle_set_env(struct tmate_session *session,
2016-01-01 22:44:01 +01:00
struct tmate_unpacker *uk)
{
char *name = unpack_string(uk);
char *value = unpack_string(uk);
tmate_set_env(name, value);
2016-03-27 00:00:16 +01:00
maybe_save_reconnection_data(session, name, value);
free(name);
free(value);
}
2016-03-27 00:00:16 +01:00
static void handle_ready(struct tmate_session *session,
2016-01-01 22:44:01 +01:00
__unused struct tmate_unpacker *uk)
{
2016-01-01 22:44:01 +01:00
session->tmate_env_ready = 1;
signal_waiting_clients("tmate-ready");
}
2016-01-01 22:44:01 +01:00
void tmate_dispatch_slave_message(struct tmate_session *session,
struct tmate_unpacker *uk)
{
int cmd = unpack_int(uk);
switch (cmd) {
#define dispatch(c, f) case c: f(session, uk); break
dispatch(TMATE_IN_NOTIFY, handle_notify);
dispatch(TMATE_IN_LEGACY_PANE_KEY, handle_legacy_pane_key);
dispatch(TMATE_IN_RESIZE, handle_resize);
dispatch(TMATE_IN_EXEC_CMD_STR, handle_exec_cmd_str);
2016-01-01 22:44:01 +01:00
dispatch(TMATE_IN_SET_ENV, handle_set_env);
dispatch(TMATE_IN_READY, handle_ready);
dispatch(TMATE_IN_PANE_KEY, handle_pane_key);
dispatch(TMATE_IN_EXEC_CMD, handle_exec_cmd);
2016-01-23 07:07:25 +01:00
default: tmate_info("Bad message type: %d", cmd);
2013-06-02 05:16:06 +02:00
}
}