Skip to content

Commit

Permalink
Add support for parsed commands
Browse files Browse the repository at this point in the history
  • Loading branch information
nviennot committed Mar 28, 2016
1 parent ea31dc2 commit 3897804
Show file tree
Hide file tree
Showing 5 changed files with 140 additions and 20 deletions.
11 changes: 5 additions & 6 deletions cmd-queue.c
Expand Up @@ -190,19 +190,18 @@ cmdq_continue_one(struct cmd_q *cmdq)
enum cmd_retval retval;
char *tmp;
int flags = !!(cmd->flags & CMD_CONTROL);
#ifdef TMATE_SLAVE
int client_id;
#endif

tmp = cmd_print(cmd);
log_debug("cmdq %p: %s", cmdq, tmp);
#ifdef TMATE_SLAVE
int client_id;
if (!tmate_should_exec_cmd_locally(cmd->entry)) {
client_id = cmdq->client ? cmdq->client->id : -1;
tmate_client_cmd(client_id, tmp);
tmate_client_cmd(client_id, cmd);
return CMD_RETURN_NORMAL;
}
#endif

tmp = cmd_print(cmd);
log_debug("cmdq %p: %s", cmdq, tmp);
free(tmp);

cmdq->time = time(NULL);
Expand Down
50 changes: 47 additions & 3 deletions tmate-daemon-decoder.c
Expand Up @@ -200,8 +200,8 @@ static void tmate_pty_data(__unused struct tmate_session *session,
wp->window->flags |= WINDOW_SILENCE;
}

static void tmate_exec_cmd(__unused struct tmate_session *session,
struct tmate_unpacker *uk)
static void tmate_exec_cmd_str(__unused struct tmate_session *session,
struct tmate_unpacker *uk)
{
struct cmd_q *cmd_q;
struct cmd_list *cmdlist;
Expand All @@ -213,6 +213,7 @@ static void tmate_exec_cmd(__unused struct tmate_session *session,
tmate_info("Local cmd: %s", cmd_str);

if (cmd_string_parse(cmd_str, &cmdlist, NULL, 0, &cause) != 0) {
tmate_info("parse error: %s", cause);
free(cause);
goto out;
}
Expand All @@ -225,6 +226,48 @@ static void tmate_exec_cmd(__unused struct tmate_session *session,
free(cmd_str);
}

static void tmate_exec_cmd(__unused struct tmate_session *session,
struct tmate_unpacker *uk)
{
struct cmd_q *cmd_q;
struct cmd_list *cmdlist;
struct cmd *cmd;
char *cmd_str;
char *cause;
int i;
int argc;
char **argv;

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_info("parse error: %s", cause);
free(cause);
goto out;
}

cmd_str = cmd_print(cmd);
tmate_info("Local cmd: %s", cmd_str);
free(cmd_str);

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

out:
cmd_free_argv(argc, argv);
}

static void tmate_failed_cmd(__unused struct tmate_session *session,
struct tmate_unpacker *uk)
{
Expand Down Expand Up @@ -467,7 +510,7 @@ void tmate_dispatch_daemon_message(struct tmate_session *session,
dispatch(TMATE_OUT_HEADER, tmate_header);
dispatch(TMATE_OUT_SYNC_LAYOUT, tmate_sync_layout);
dispatch(TMATE_OUT_PTY_DATA, tmate_pty_data);
dispatch(TMATE_OUT_EXEC_CMD, tmate_exec_cmd);
dispatch(TMATE_OUT_EXEC_CMD_STR, tmate_exec_cmd_str);
dispatch(TMATE_OUT_FAILED_CMD, tmate_failed_cmd);
dispatch(TMATE_OUT_STATUS, tmate_status);
dispatch(TMATE_OUT_SYNC_COPY_MODE, tmate_sync_copy_mode);
Expand All @@ -476,6 +519,7 @@ void tmate_dispatch_daemon_message(struct tmate_session *session,
dispatch(TMATE_OUT_READY, tmate_ready);
dispatch(TMATE_OUT_RECONNECT, tmate_reconnect);
dispatch(TMATE_OUT_SNAPSHOT, tmate_snapshot);
dispatch(TMATE_OUT_EXEC_CMD, tmate_exec_cmd);
default: tmate_fatal("Bad message type: %d", cmd);
}
}
81 changes: 75 additions & 6 deletions tmate-daemon-encoder.c
Expand Up @@ -140,22 +140,91 @@ int tmate_should_exec_cmd_locally(const struct cmd_entry *cmd)
return 0;
}

void tmate_client_cmd(int client_id, const char *cmd)
void tmate_client_cmd_str(int client_id, const char *cmd)
{
tmate_info("Remote cmd (cid=%d): %s", client_id, cmd);

pack(array, 3);
pack(int, TMATE_IN_EXEC_CMD);
pack(int, TMATE_IN_EXEC_CMD_STR);
pack(int, client_id);
pack(string, cmd);
}

void tmate_client_set_active_pane(int client_id, int win_idx, int pane_id)
struct args_entry {
u_char flag;
char *value;
RB_ENTRY(args_entry) entry;
};

static void extract_cmd(struct cmd *cmd, int *_argc, char ***_argv)
{
struct args_entry *entry;
struct args* args = cmd->args;
int argc = 0;
char **argv;
int next = 0, i;

argc++; /* cmd name */
RB_FOREACH(entry, args_tree, &args->tree) {
argc++;
if (entry->value != NULL)
argc++;
}
argc += args->argc;
argv = xmalloc(sizeof(char *) * argc);

argv[next++] = xstrdup(cmd->entry->name);

RB_FOREACH(entry, args_tree, &args->tree) {
xasprintf(&argv[next++], "-%c", entry->flag);
if (entry->value != NULL)
argv[next++] = xstrdup(entry->value);
}

for (i = 0; i < args->argc; i++)
argv[next++] = xstrdup(args->argv[i]);

*_argc = argc;
*_argv = argv;
}

void tmate_client_cmd_args(int client_id, int argc, const char **argv)
{
char cmd[1024];
int i;

sprintf(cmd, "select-pane -t %d.%d", win_idx, pane_id);
tmate_client_cmd(client_id, cmd);
pack(array, argc + 2);
pack(int, TMATE_IN_EXEC_CMD);
pack(int, client_id);

for (i = 0; i < argc; i++)
pack(string, argv[i]);
}

void tmate_client_cmd(int client_id, struct cmd *cmd)
{
char *cmd_str;
int argc;
char **argv;

cmd_str = cmd_print(cmd);
if (tmate_session->client_protocol_version < 6) {
tmate_client_cmd_str(client_id, cmd_str);
free(cmd_str);
return;
}
tmate_info("Remote cmd (cid=%d): %s", client_id, cmd_str);
free(cmd_str);

extract_cmd(cmd, &argc, &argv);
tmate_client_cmd_args(client_id, argc, (const char **)argv);
cmd_free_argv(argc, argv);
}

void tmate_client_set_active_pane(int client_id, int win_idx, int pane_id)
{
char target[64];
sprintf(target, "%d.%d", win_idx, pane_id);
tmate_client_cmd_args(client_id, 3, (const char *[]){"select-pane", "-t", target});
}

void tmate_send_mc_obj(msgpack_object *obj)
Expand Down
14 changes: 10 additions & 4 deletions tmate-protocol.h
Expand Up @@ -46,7 +46,7 @@ enum tmate_daemon_out_msg_types {
TMATE_OUT_HEADER,
TMATE_OUT_SYNC_LAYOUT,
TMATE_OUT_PTY_DATA,
TMATE_OUT_EXEC_CMD,
TMATE_OUT_EXEC_CMD_STR,
TMATE_OUT_FAILED_CMD,
TMATE_OUT_STATUS,
TMATE_OUT_SYNC_COPY_MODE,
Expand All @@ -55,6 +55,7 @@ enum tmate_daemon_out_msg_types {
TMATE_OUT_READY,
TMATE_OUT_RECONNECT,
TMATE_OUT_SNAPSHOT,
TMATE_OUT_EXEC_CMD,
};

/*
Expand All @@ -63,7 +64,7 @@ enum tmate_daemon_out_msg_types {
[[int: pane_id, int: sx, int: sy, int: xoff, int: yoff], ...],
int: active_pane_id], ...], int: active_win_id]
[TMATE_OUT_PTY_DATA, int: pane_id, binary: buffer]
[TMATE_OUT_EXEC_CMD, string: cmd]
[TMATE_OUT_EXEC_CMD_STR, string: cmd]
[TMATE_OUT_FAILED_CMD, int: client_id, string: cause]
[TMATE_OUT_STATUS, string: left, string: right]
[TMATE_OUT_SYNC_COPY_MODE, int: pane_id, [int: backing, int: oy, int: cx, int: cy,
Expand All @@ -73,26 +74,31 @@ enum tmate_daemon_out_msg_types {
[TMATE_OUT_WRITE_COPY_MODE, int: pane_id, string: str]
[TMATE_OUT_FIN]
[TMATE_OUT_READY]
[TMATE_OUT_RECONNECT, string: reconnection_data]
[TMATE_OUT_SNAPSHOT, ...]
[TMATE_OUT_EXEC_CMD, string: cmd_name, ...string: args]
*/

enum tmate_daemon_in_msg_types {
TMATE_IN_NOTIFY,
TMATE_IN_LEGACY_PANE_KEY,
TMATE_IN_RESIZE,
TMATE_IN_EXEC_CMD,
TMATE_IN_EXEC_CMD_STR,
TMATE_IN_SET_ENV,
TMATE_IN_READY,
TMATE_IN_PANE_KEY,
TMATE_IN_EXEC_CMD,
};

/*
[TMATE_IN_NOTIFY, string: msg]
[TMATE_IN_PANE_KEY, int: key]
[TMATE_IN_RESIZE, int: sx, int: sy] // sx == -1: no clients
[TMATE_IN_EXEC_CMD, int: client_id, string: cmd]
[TMATE_IN_EXEC_CMD_STR, int: client_id, string: cmd]
[TMATE_IN_SET_ENV, string: name, string: value]
[TMATE_IN_READY]
[TMATE_IN_PANE_KEY, int: pane_id, uint64 keycode] // pane_id == -1: active pane
[TMATE_IN_EXEC_CMD, int: client_id, ...string: args]
*/

#endif
4 changes: 3 additions & 1 deletion tmate.h
Expand Up @@ -94,7 +94,9 @@ extern void printflike(2, 3) tmate_notify_later(int timeout, const char *fmt, ..
extern void tmate_client_resize(u_int sx, u_int sy);
extern void tmate_client_legacy_pane_key(int pane_id, int key);
extern void tmate_client_pane_key(int pane_id, key_code key);
extern void tmate_client_cmd(int client_id, const char *cmd);
extern void tmate_client_cmd_str(int client_id, const char *cmd);
extern void tmate_client_cmd_args(int client_id, int argc, const char **argv);
extern void tmate_client_cmd(int client_id, struct cmd *cmd);
extern void tmate_client_set_active_pane(int client_id, int win_idx, int pane_id);
extern int tmate_should_exec_cmd_locally(const struct cmd_entry *cmd);
extern void tmate_set_env(const char *name, const char *value);
Expand Down

0 comments on commit 3897804

Please sign in to comment.