1
0
mirror of https://github.com/tmate-io/tmate-ssh-server.git synced 2020-11-18 19:53:51 -08:00

Allow clients to extract the ssh connection strings from cmd line

This commit is contained in:
Nicolas Viennot 2014-10-31 00:05:44 -04:00
parent 6e4adcc140
commit 2f43ed93b7
6 changed files with 112 additions and 3 deletions

View File

@ -178,6 +178,7 @@ dist_tmate_SOURCES = \
tmate-ssh-client.c \
tmate-encoder.c \
tmate-decoder.c \
tmate-env.c \
tmate-msg.c \
tmate-session.c \
tmux.c \

View File

@ -23,6 +23,7 @@
#include <string.h>
#include "tmux.h"
#include "tmate.h"
/*
* Block or wake a client on a named wait channel.
@ -116,10 +117,44 @@ cmd_wait_for_signal(struct cmd_q *cmdq, const char *name,
return (CMD_RETURN_NORMAL);
}
#ifdef TMATE
void signal_waiting_clients(const char *name)
{
struct wait_channel *wc, wc0;
struct cmd_q *wq, *wq1;
wc0.name = name;
wc = RB_FIND(wait_channels, &wait_channels, &wc0);
if (wc == NULL || TAILQ_EMPTY(&wc->waiters)) {
return;
}
TAILQ_FOREACH_SAFE(wq, &wc->waiters, waitentry, wq1) {
TAILQ_REMOVE(&wc->waiters, wq, waitentry);
if (!cmdq_free(wq))
cmdq_continue(wq);
}
if (!wc->locked) {
RB_REMOVE(wait_channels, &wait_channels, wc);
free((void*) wc->name);
free(wc);
}
}
#endif
enum cmd_retval
cmd_wait_for_wait(struct cmd_q *cmdq, const char *name,
struct wait_channel *wc)
{
#ifdef TMATE
if (!strcmp(name, "tmate-ready") && tmate_session.decoder.ready)
return (CMD_RETURN_NORMAL);
#endif
if (cmdq->client == NULL || cmdq->client->session != NULL) {
cmdq_error(cmdq, "not able to wait");
return (CMD_RETURN_ERROR);

View File

@ -26,6 +26,7 @@
#include <unistd.h>
#include "tmux.h"
#include "tmate.h"
/*
* Build a list of key-value pairs and use them to expand #{key} entries in a
@ -214,6 +215,10 @@ format_expand(struct format_tree *ft, const char *fmt)
size_t off, len, n;
int ch;
#ifdef TMATE
tmate_format(ft);
#endif
len = 64;
buf = xmalloc(len);
off = 0;

View File

@ -148,7 +148,27 @@ out:
free(cmd_str);
}
static void handle_message(msgpack_object obj)
static void tmate_client_env(struct tmate_unpacker *uk)
{
char *name = unpack_string(uk);
char *value = unpack_string(uk);
tmate_set_env(name, value);
free(name);
free(value);
}
extern void signal_waiting_clients(const char *name);
static void tmate_client_ready(struct tmate_decoder *decoder,
struct tmate_unpacker *uk)
{
decoder->ready = 1;
signal_waiting_clients("tmate-ready");
}
static void handle_message(struct tmate_decoder *decoder, msgpack_object obj)
{
struct tmate_unpacker _uk;
struct tmate_unpacker *uk = &_uk;
@ -160,6 +180,8 @@ static void handle_message(msgpack_object obj)
case TMATE_CLIENT_PANE_KEY: tmate_client_pane_key(uk); break;
case TMATE_CLIENT_RESIZE: tmate_client_resize(uk); break;
case TMATE_CLIENT_EXEC_CMD: tmate_client_exec_cmd(uk); break;
case TMATE_CLIENT_ENV: tmate_client_env(uk); break;
case TMATE_CLIENT_READY: tmate_client_ready(decoder, uk); break;
default: decoder_error();
}
}
@ -172,7 +194,7 @@ void tmate_decoder_commit(struct tmate_decoder *decoder, size_t len)
msgpack_unpacked_init(&result);
while (msgpack_unpacker_next(&decoder->unpacker, &result)) {
handle_message(result.data);
handle_message(decoder, result.data);
}
msgpack_unpacked_destroy(&result);
@ -199,4 +221,5 @@ void tmate_decoder_init(struct tmate_decoder *decoder)
{
if (!msgpack_unpacker_init(&decoder->unpacker, 2*TMATE_MAX_MESSAGE_SIZE))
tmate_fatal("cannot initialize the unpacker");
decoder->ready = 0;
}

36
tmate-env.c Normal file
View File

@ -0,0 +1,36 @@
#include "tmate.h"
struct tmate_env {
TAILQ_ENTRY(tmate_env) entry;
char *name;
char *value;
};
TAILQ_HEAD(, tmate_env) tmate_env_list;
void tmate_set_env(const char *name, const char *value)
{
struct tmate_env *tmate_env;
TAILQ_FOREACH(tmate_env, &tmate_env_list, entry) {
if (!strcmp(tmate_env->name, name)) {
free(tmate_env->value);
tmate_env->value = xstrdup(value);
return;
}
}
tmate_env = xmalloc(sizeof(*tmate_env));
tmate_env->name = xstrdup(name);
tmate_env->value = xstrdup(value);
TAILQ_INSERT_HEAD(&tmate_env_list, tmate_env, entry);
}
void tmate_format(struct format_tree *ft)
{
struct tmate_env *tmate_env;
TAILQ_FOREACH(tmate_env, &tmate_env_list, entry) {
format_add(ft, tmate_env->name, "%s", tmate_env->value);
}
}

11
tmate.h
View File

@ -18,7 +18,7 @@
#define TMATE_MAX_MESSAGE_SIZE (16*1024)
#define TMATE_PROTOCOL_VERSION 3
#define TMATE_PROTOCOL_VERSION 4
enum tmate_commands {
TMATE_HEADER,
@ -56,10 +56,13 @@ enum tmate_client_commands {
TMATE_CLIENT_PANE_KEY,
TMATE_CLIENT_RESIZE,
TMATE_CLIENT_EXEC_CMD,
TMATE_CLIENT_ENV,
TMATE_CLIENT_READY,
};
struct tmate_decoder {
struct msgpack_unpacker unpacker;
int ready;
};
extern int tmate_sx;
@ -147,4 +150,10 @@ extern void tmate_catch_sigsegv(void);
extern void __tmate_status_message(const char *fmt, va_list ap);
extern void printflike1 tmate_status_message(const char *fmt, ...);
/* tmate-env.c */
extern int tmate_has_received_env(void);
extern void tmate_set_env(const char *name, const char *value);
extern void tmate_format(struct format_tree *ft);
#endif