2013-06-02 05:16:06 +02:00
|
|
|
#ifndef TMATE_H
|
|
|
|
#define TMATE_H
|
|
|
|
|
|
|
|
#include <sys/types.h>
|
|
|
|
#include <msgpack.h>
|
2013-06-17 23:34:34 +02:00
|
|
|
#include <libssh/libssh.h>
|
2013-07-22 23:06:28 +02:00
|
|
|
#include <libssh/callbacks.h>
|
2013-06-02 05:16:06 +02:00
|
|
|
#include <event.h>
|
|
|
|
|
|
|
|
#include "tmux.h"
|
|
|
|
|
2019-11-03 11:11:37 +01:00
|
|
|
#define tmate_debug(...) log_emit(LOG_DEBUG, __VA_ARGS__)
|
|
|
|
#define tmate_info(...) log_emit(LOG_INFO, __VA_ARGS__)
|
|
|
|
#define tmate_fatal(...) fatalx( __VA_ARGS__)
|
2013-06-02 05:16:06 +02:00
|
|
|
|
2016-01-01 22:44:01 +01:00
|
|
|
/* tmate-msgpack.c */
|
2013-06-02 05:16:06 +02:00
|
|
|
|
2016-01-01 22:44:01 +01:00
|
|
|
typedef void tmate_encoder_write_cb(void *userdata, struct evbuffer *buffer);
|
2013-06-02 05:16:06 +02:00
|
|
|
|
|
|
|
struct tmate_encoder {
|
|
|
|
msgpack_packer pk;
|
2016-01-01 22:44:01 +01:00
|
|
|
tmate_encoder_write_cb *ready_callback;
|
|
|
|
void *userdata;
|
2013-06-02 05:16:06 +02:00
|
|
|
struct evbuffer *buffer;
|
2016-01-01 22:44:01 +01:00
|
|
|
struct event ev_buffer;
|
|
|
|
bool ev_active;
|
|
|
|
};
|
|
|
|
|
|
|
|
extern void tmate_encoder_init(struct tmate_encoder *encoder,
|
|
|
|
tmate_encoder_write_cb *callback,
|
|
|
|
void *userdata);
|
2016-03-27 00:00:16 +01:00
|
|
|
extern void tmate_encoder_destroy(struct tmate_encoder *encoder);
|
2016-01-01 22:44:01 +01:00
|
|
|
extern void tmate_encoder_set_ready_callback(struct tmate_encoder *encoder,
|
|
|
|
tmate_encoder_write_cb *callback,
|
|
|
|
void *userdata);
|
|
|
|
|
|
|
|
extern void msgpack_pack_string(msgpack_packer *pk, const char *str);
|
|
|
|
extern void msgpack_pack_boolean(msgpack_packer *pk, bool value);
|
|
|
|
|
2016-03-27 06:30:20 +02:00
|
|
|
#define _pack(enc, what, ...) msgpack_pack_##what(&(enc)->pk, ##__VA_ARGS__)
|
2016-01-01 22:44:01 +01:00
|
|
|
|
|
|
|
struct tmate_unpacker;
|
|
|
|
struct tmate_decoder;
|
|
|
|
typedef void tmate_decoder_reader(void *userdata, struct tmate_unpacker *uk);
|
|
|
|
|
|
|
|
struct tmate_decoder {
|
|
|
|
struct msgpack_unpacker unpacker;
|
|
|
|
tmate_decoder_reader *reader;
|
|
|
|
void *userdata;
|
|
|
|
};
|
|
|
|
|
|
|
|
extern void tmate_decoder_init(struct tmate_decoder *decoder, tmate_decoder_reader *reader, void *userdata);
|
2016-03-27 00:00:16 +01:00
|
|
|
extern void tmate_decoder_destroy(struct tmate_decoder *decoder);
|
2016-01-01 22:44:01 +01:00
|
|
|
extern void tmate_decoder_get_buffer(struct tmate_decoder *decoder, char **buf, size_t *len);
|
|
|
|
extern void tmate_decoder_commit(struct tmate_decoder *decoder, size_t len);
|
|
|
|
|
|
|
|
struct tmate_unpacker {
|
|
|
|
int argc;
|
|
|
|
msgpack_object *argv;
|
2013-06-02 05:16:06 +02:00
|
|
|
};
|
|
|
|
|
2016-01-01 22:44:01 +01:00
|
|
|
extern void init_unpacker(struct tmate_unpacker *uk, msgpack_object obj);
|
|
|
|
extern void tmate_decoder_error(void);
|
|
|
|
extern int64_t unpack_int(struct tmate_unpacker *uk);
|
|
|
|
extern bool unpack_bool(struct tmate_unpacker *uk);
|
|
|
|
extern void unpack_buffer(struct tmate_unpacker *uk, const char **buf, size_t *len);
|
|
|
|
extern char *unpack_string(struct tmate_unpacker *uk);
|
|
|
|
extern void unpack_array(struct tmate_unpacker *uk, struct tmate_unpacker *nested);
|
|
|
|
|
|
|
|
#define unpack_each(nested_uk, tmp_uk, uk) \
|
|
|
|
for (unpack_array(uk, tmp_uk); \
|
|
|
|
(tmp_uk)->argc > 0 && (init_unpacker(nested_uk, (tmp_uk)->argv[0]), 1); \
|
|
|
|
(tmp_uk)->argv++, (tmp_uk)->argc--)
|
|
|
|
|
|
|
|
/* tmate-encoder.c */
|
|
|
|
|
2016-03-11 20:11:28 +01:00
|
|
|
#define TMATE_PROTOCOL_VERSION 6
|
2013-06-02 05:16:06 +02:00
|
|
|
|
2016-03-27 00:00:16 +01:00
|
|
|
struct tmate_session;
|
|
|
|
|
2013-06-02 05:16:06 +02:00
|
|
|
extern void tmate_write_header(void);
|
2016-03-11 20:11:28 +01:00
|
|
|
extern void tmate_write_ready(void);
|
2013-06-12 08:53:44 +02:00
|
|
|
extern void tmate_sync_layout(void);
|
2013-06-02 05:16:06 +02:00
|
|
|
extern void tmate_pty_data(struct window_pane *wp, const char *buf, size_t len);
|
2013-06-12 04:45:33 +02:00
|
|
|
extern int tmate_should_replicate_cmd(const struct cmd_entry *cmd);
|
2016-03-28 05:32:32 +02:00
|
|
|
extern void tmate_exec_cmd_args(int argc, const char **argv);
|
|
|
|
extern void tmate_exec_cmd(struct cmd *cmd);
|
2013-06-13 02:09:43 +02:00
|
|
|
extern void tmate_failed_cmd(int client_id, const char *cause);
|
2013-06-12 05:50:16 +02:00
|
|
|
extern void tmate_status(const char *left, const char *right);
|
2013-06-13 04:38:41 +02:00
|
|
|
extern void tmate_sync_copy_mode(struct window_pane *wp);
|
2013-06-26 08:05:13 +02:00
|
|
|
extern void tmate_write_copy_mode(struct window_pane *wp, const char *str);
|
2016-01-02 17:03:04 +01:00
|
|
|
extern void tmate_write_fin(void);
|
2016-03-27 00:00:16 +01:00
|
|
|
extern void tmate_send_reconnection_state(struct tmate_session *session);
|
2013-06-02 05:16:06 +02:00
|
|
|
|
|
|
|
/* tmate-decoder.c */
|
|
|
|
|
2016-01-01 22:44:01 +01:00
|
|
|
struct tmate_session;
|
|
|
|
extern void tmate_dispatch_slave_message(struct tmate_session *session,
|
|
|
|
struct tmate_unpacker *uk);
|
2013-06-02 05:16:06 +02:00
|
|
|
|
|
|
|
/* tmate-ssh-client.c */
|
|
|
|
|
|
|
|
enum tmate_ssh_client_state_types {
|
|
|
|
SSH_NONE,
|
|
|
|
SSH_INIT,
|
|
|
|
SSH_CONNECT,
|
2013-06-12 07:28:01 +02:00
|
|
|
SSH_AUTH_SERVER,
|
2019-10-15 09:04:24 +02:00
|
|
|
SSH_AUTH_CLIENT_NONE,
|
|
|
|
SSH_AUTH_CLIENT_PUBKEY,
|
|
|
|
SSH_NEW_CHANNEL,
|
2013-06-02 05:16:06 +02:00
|
|
|
SSH_OPEN_CHANNEL,
|
|
|
|
SSH_BOOTSTRAP,
|
|
|
|
SSH_READY,
|
|
|
|
};
|
|
|
|
|
|
|
|
struct tmate_ssh_client {
|
2013-07-22 23:06:28 +02:00
|
|
|
/* XXX The "session" word is used for three things:
|
|
|
|
* - the ssh session
|
|
|
|
* - the tmate sesssion
|
|
|
|
* - the tmux session
|
|
|
|
* A tmux session is associated 1:1 with a tmate session.
|
|
|
|
* An ssh session belongs to a tmate session, and a tmate session
|
|
|
|
* has one ssh session, except during bootstrapping where
|
|
|
|
* there is one ssh session per tmate server, and the first one wins.
|
|
|
|
*/
|
|
|
|
struct tmate_session *tmate_session;
|
|
|
|
TAILQ_ENTRY(tmate_ssh_client) node;
|
|
|
|
|
|
|
|
char *server_ip;
|
|
|
|
|
|
|
|
int has_encoder;
|
2013-06-02 05:16:06 +02:00
|
|
|
int state;
|
2013-07-22 23:06:28 +02:00
|
|
|
|
|
|
|
/*
|
|
|
|
* ssh_callbacks is allocated because the libssh API sucks (userdata
|
|
|
|
* has to be in the struct itself).
|
|
|
|
*/
|
|
|
|
struct ssh_callbacks_struct ssh_callbacks;
|
2013-07-23 01:45:34 +02:00
|
|
|
char *tried_passphrase;
|
2013-06-02 05:16:06 +02:00
|
|
|
ssh_session session;
|
|
|
|
ssh_channel channel;
|
|
|
|
|
2016-01-15 22:02:42 +01:00
|
|
|
bool has_init_conn_fd;
|
2013-06-02 05:16:06 +02:00
|
|
|
struct event ev_ssh;
|
|
|
|
};
|
2013-07-22 23:06:28 +02:00
|
|
|
TAILQ_HEAD(tmate_ssh_clients, tmate_ssh_client);
|
|
|
|
|
|
|
|
extern struct tmate_ssh_client *tmate_ssh_client_alloc(struct tmate_session *session,
|
|
|
|
const char *server_ip);
|
2013-06-02 05:16:06 +02:00
|
|
|
|
2013-07-22 23:06:28 +02:00
|
|
|
/* tmate-session.c */
|
2013-06-02 05:16:06 +02:00
|
|
|
|
2013-07-22 23:06:28 +02:00
|
|
|
struct tmate_session {
|
2015-12-23 11:41:41 +01:00
|
|
|
struct event_base *ev_base;
|
|
|
|
struct evdns_base *ev_dnsbase;
|
|
|
|
struct event ev_dns_retry;
|
|
|
|
|
2013-07-22 23:06:28 +02:00
|
|
|
struct tmate_encoder encoder;
|
|
|
|
struct tmate_decoder decoder;
|
|
|
|
|
2016-01-01 22:44:01 +01:00
|
|
|
/* True when the slave has sent all the environment variables */
|
|
|
|
int tmate_env_ready;
|
|
|
|
|
|
|
|
int min_sx;
|
|
|
|
int min_sy;
|
|
|
|
|
2013-07-22 23:06:28 +02:00
|
|
|
/*
|
|
|
|
* This list contains one connection per IP. The first connected
|
|
|
|
* client wins, and saved in *client. When we have a winner, the
|
|
|
|
* losers are disconnected and killed.
|
|
|
|
*/
|
|
|
|
struct tmate_ssh_clients clients;
|
2013-07-23 01:45:34 +02:00
|
|
|
int need_passphrase;
|
|
|
|
char *passphrase;
|
2016-03-27 00:00:16 +01:00
|
|
|
|
|
|
|
bool reconnected;
|
|
|
|
struct event ev_connection_retry;
|
|
|
|
char *last_server_ip;
|
|
|
|
char *reconnection_data;
|
2016-03-27 07:10:23 +02:00
|
|
|
/*
|
|
|
|
* When we reconnect, instead of serializing the key bindings and
|
|
|
|
* options, we replay all the tmux commands we replicated.
|
|
|
|
* It may be a little innacurate to replicate the state, but
|
|
|
|
* it's much easier.
|
|
|
|
*/
|
|
|
|
struct {
|
|
|
|
unsigned int capacity;
|
|
|
|
unsigned int tail;
|
2016-03-28 05:32:32 +02:00
|
|
|
struct {
|
|
|
|
int argc;
|
|
|
|
char **argv;
|
|
|
|
} *cmds;
|
2016-03-27 07:10:23 +02:00
|
|
|
} saved_tmux_cmds;
|
2013-07-22 23:06:28 +02:00
|
|
|
};
|
2013-06-02 05:16:06 +02:00
|
|
|
|
2013-07-22 23:06:28 +02:00
|
|
|
extern struct tmate_session tmate_session;
|
2015-12-23 11:41:41 +01:00
|
|
|
extern void tmate_session_init(struct event_base *base);
|
2013-07-22 23:06:28 +02:00
|
|
|
extern void tmate_session_start(void);
|
2016-03-29 05:29:49 +02:00
|
|
|
extern void tmate_reconnect_session(struct tmate_session *session, const char *message);
|
2013-06-02 05:16:06 +02:00
|
|
|
|
2013-06-12 23:57:53 +02:00
|
|
|
/* tmate-debug.c */
|
2016-01-01 22:44:01 +01:00
|
|
|
extern void tmate_print_stack_trace(void);
|
2013-07-22 23:06:28 +02:00
|
|
|
extern void tmate_catch_sigsegv(void);
|
2013-06-12 23:57:53 +02:00
|
|
|
|
2013-06-13 01:40:30 +02:00
|
|
|
/* tmate-msg.c */
|
|
|
|
|
|
|
|
extern void __tmate_status_message(const char *fmt, va_list ap);
|
2015-12-23 11:41:41 +01:00
|
|
|
extern void printflike(1, 2) tmate_status_message(const char *fmt, ...);
|
2013-06-13 01:40:30 +02:00
|
|
|
|
2014-10-31 05:05:44 +01:00
|
|
|
/* 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);
|
|
|
|
|
2013-06-02 05:16:06 +02:00
|
|
|
#endif
|