summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorNicolas Viennot <nicolas@viennot.biz>2013-06-11 22:07:04 -0400
committerNicolas Viennot <nicolas@viennot.biz>2013-06-11 22:32:49 -0400
commit839c4e3dd9b7d5ebfaacbc5a446bcb9ef6f9b63b (patch)
tree3462fc582d32fdde9f49f0615f8dfb65dd3bb1d8
parentb7371802bf2e2c51ff9fff6915e646471c782ff7 (diff)
Replicate remote client commands
-rw-r--r--tmate-decoder.c88
-rw-r--r--tmate.h3
2 files changed, 81 insertions, 10 deletions
diff --git a/tmate-decoder.c b/tmate-decoder.c
index 476077af..774c8c0d 100644
--- a/tmate-decoder.c
+++ b/tmate-decoder.c
@@ -10,6 +10,7 @@ struct tmate_unpacker {
static void decoder_error(void)
{
+ /* TODO Don't kill the session, disconnect */
tmate_fatal("Received a bad message");
}
@@ -42,22 +43,64 @@ static int64_t unpack_int(struct tmate_unpacker *uk)
return val;
}
-static void tmate_client_key(struct tmate_unpacker *uk)
+static void unpack_raw(struct tmate_unpacker *uk,
+ const char **buf, size_t *len)
{
- struct client *c;
+ if (uk->argc == 0)
+ decoder_error();
+
+ if (uk->argv[0].type != MSGPACK_OBJECT_RAW)
+ decoder_error();
+
+ *len = uk->argv[0].via.raw.size;
+ *buf = uk->argv[0].via.raw.ptr;
+
+ uk->argv++;
+ uk->argc--;
+}
+
+static char *unpack_string(struct tmate_unpacker *uk)
+{
+ const char *buf;
+ char *alloc_buf;
+ size_t len;
+
+ unpack_raw(uk, &buf, &len);
+
+ alloc_buf = xmalloc(len + 1);
+ memcpy(alloc_buf, buf, len);
+ alloc_buf[len] = '\0';
+
+ return alloc_buf;
+}
+
+
+static void tmate_client_pane_key(struct tmate_unpacker *uk)
+{
+ struct session *s;
+ struct window *w;
+ struct window_pane *wp;
+
int key = unpack_int(uk);
- /* Very gross. other clients cannot even detach */
+ s = RB_MIN(sessions, &sessions);
+ if (!s)
+ return;
- if (ARRAY_LENGTH(&clients) > 0) {
- c = ARRAY_ITEM(&clients, 0);
- server_client_handle_key(c, key);
- }
+ w = s->curw->window;
+ if (!w)
+ return;
+
+ wp = w->active;
+ if (!wp)
+ return;
+
+ window_pane_key(wp, s, key);
}
static void tmate_client_resize(struct tmate_unpacker *uk)
{
- /* A bit gross as well */
+ /* TODO This is sad, we might want our own client. */
tmate_sx = unpack_int(uk);
tmate_sy = unpack_int(uk);
recalculate_sizes();
@@ -65,6 +108,32 @@ static void tmate_client_resize(struct tmate_unpacker *uk)
/* TODO Handle reconnection cases */
}
+static void tmate_client_cmd(struct tmate_unpacker *uk)
+{
+ struct cmd_q *cmd_q;
+ struct cmd_list *cmdlist;
+ unsigned int argc = 0;
+ char *argv[1024];
+ char *cmd_str;
+ char *cause;
+ int i;
+
+ cmd_str = unpack_string(uk);
+ tmate_debug("received command from remote client: %s", cmd_str);
+
+ if (cmd_string_parse(cmd_str, &cmdlist, NULL, 0, &cause) != 0) {
+ free(cause);
+ goto out;
+ }
+
+ cmd_q = cmdq_new(NULL);
+ cmdq_run(cmd_q, cmdlist);
+ cmd_list_free(cmdlist);
+ cmdq_free(cmd_q);
+out:
+ free(cmd_str);
+}
+
static void handle_message(msgpack_object obj)
{
struct tmate_unpacker _uk;
@@ -74,8 +143,9 @@ static void handle_message(msgpack_object obj)
init_unpacker(uk, obj);
switch (unpack_int(uk)) {
- case TMATE_CLIENT_KEY: tmate_client_key(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;
default: decoder_error();
}
}
diff --git a/tmate.h b/tmate.h
index ed3f847b..a9caf337 100644
--- a/tmate.h
+++ b/tmate.h
@@ -39,8 +39,9 @@ extern void tmate_pty_data(struct window_pane *wp, const char *buf, size_t len);
/* tmate-decoder.c */
enum tmate_notifications {
- TMATE_CLIENT_KEY,
+ TMATE_CLIENT_PANE_KEY,
TMATE_CLIENT_RESIZE,
+ TMATE_CLIENT_CMD,
};
struct tmate_decoder {