tmate.h 6.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215
  1. #ifndef TMATE_H
  2. #define TMATE_H
  3. #include <sys/types.h>
  4. #include <msgpack.h>
  5. #include <libssh/libssh.h>
  6. #include <libssh/callbacks.h>
  7. #include <event.h>
  8. #include "tmux.h"
  9. #define tmate_debug(...) log_debug("[tmate] D " __VA_ARGS__)
  10. #define tmate_warn(...) log_debug("[tmate] W " __VA_ARGS__)
  11. #define tmate_info(...) log_debug("[tmate] I " __VA_ARGS__)
  12. #define tmate_fatal(...) fatalx("[tmate] " __VA_ARGS__)
  13. /* tmate-msgpack.c */
  14. typedef void tmate_encoder_write_cb(void *userdata, struct evbuffer *buffer);
  15. struct tmate_encoder {
  16. msgpack_packer pk;
  17. tmate_encoder_write_cb *ready_callback;
  18. void *userdata;
  19. struct evbuffer *buffer;
  20. struct event ev_buffer;
  21. bool ev_active;
  22. };
  23. extern void tmate_encoder_init(struct tmate_encoder *encoder,
  24. tmate_encoder_write_cb *callback,
  25. void *userdata);
  26. extern void tmate_encoder_destroy(struct tmate_encoder *encoder);
  27. extern void tmate_encoder_set_ready_callback(struct tmate_encoder *encoder,
  28. tmate_encoder_write_cb *callback,
  29. void *userdata);
  30. extern void msgpack_pack_string(msgpack_packer *pk, const char *str);
  31. extern void msgpack_pack_boolean(msgpack_packer *pk, bool value);
  32. #define _pack(enc, what, ...) msgpack_pack_##what(&(enc)->pk, ##__VA_ARGS__)
  33. struct tmate_unpacker;
  34. struct tmate_decoder;
  35. typedef void tmate_decoder_reader(void *userdata, struct tmate_unpacker *uk);
  36. struct tmate_decoder {
  37. struct msgpack_unpacker unpacker;
  38. tmate_decoder_reader *reader;
  39. void *userdata;
  40. };
  41. extern void tmate_decoder_init(struct tmate_decoder *decoder, tmate_decoder_reader *reader, void *userdata);
  42. extern void tmate_decoder_destroy(struct tmate_decoder *decoder);
  43. extern void tmate_decoder_get_buffer(struct tmate_decoder *decoder, char **buf, size_t *len);
  44. extern void tmate_decoder_commit(struct tmate_decoder *decoder, size_t len);
  45. struct tmate_unpacker {
  46. int argc;
  47. msgpack_object *argv;
  48. };
  49. extern void init_unpacker(struct tmate_unpacker *uk, msgpack_object obj);
  50. extern void tmate_decoder_error(void);
  51. extern int64_t unpack_int(struct tmate_unpacker *uk);
  52. extern bool unpack_bool(struct tmate_unpacker *uk);
  53. extern void unpack_buffer(struct tmate_unpacker *uk, const char **buf, size_t *len);
  54. extern char *unpack_string(struct tmate_unpacker *uk);
  55. extern void unpack_array(struct tmate_unpacker *uk, struct tmate_unpacker *nested);
  56. #define unpack_each(nested_uk, tmp_uk, uk) \
  57. for (unpack_array(uk, tmp_uk); \
  58. (tmp_uk)->argc > 0 && (init_unpacker(nested_uk, (tmp_uk)->argv[0]), 1); \
  59. (tmp_uk)->argv++, (tmp_uk)->argc--)
  60. /* tmate-encoder.c */
  61. #define TMATE_PROTOCOL_VERSION 6
  62. struct tmate_session;
  63. extern void tmate_write_header(void);
  64. extern void tmate_write_ready(void);
  65. extern void tmate_sync_layout(void);
  66. extern void tmate_pty_data(struct window_pane *wp, const char *buf, size_t len);
  67. extern int tmate_should_replicate_cmd(const struct cmd_entry *cmd);
  68. extern void tmate_exec_cmd_args(int argc, const char **argv);
  69. extern void tmate_exec_cmd(struct cmd *cmd);
  70. extern void tmate_failed_cmd(int client_id, const char *cause);
  71. extern void tmate_status(const char *left, const char *right);
  72. extern void tmate_sync_copy_mode(struct window_pane *wp);
  73. extern void tmate_write_copy_mode(struct window_pane *wp, const char *str);
  74. extern void tmate_write_fin(void);
  75. extern void tmate_send_reconnection_state(struct tmate_session *session);
  76. /* tmate-decoder.c */
  77. struct tmate_session;
  78. extern void tmate_dispatch_slave_message(struct tmate_session *session,
  79. struct tmate_unpacker *uk);
  80. /* tmate-ssh-client.c */
  81. enum tmate_ssh_client_state_types {
  82. SSH_NONE,
  83. SSH_INIT,
  84. SSH_CONNECT,
  85. SSH_AUTH_SERVER,
  86. SSH_AUTH_CLIENT,
  87. SSH_OPEN_CHANNEL,
  88. SSH_BOOTSTRAP,
  89. SSH_READY,
  90. };
  91. struct tmate_ssh_client {
  92. /* XXX The "session" word is used for three things:
  93. * - the ssh session
  94. * - the tmate sesssion
  95. * - the tmux session
  96. * A tmux session is associated 1:1 with a tmate session.
  97. * An ssh session belongs to a tmate session, and a tmate session
  98. * has one ssh session, except during bootstrapping where
  99. * there is one ssh session per tmate server, and the first one wins.
  100. */
  101. struct tmate_session *tmate_session;
  102. TAILQ_ENTRY(tmate_ssh_client) node;
  103. char *server_ip;
  104. int has_encoder;
  105. int state;
  106. /*
  107. * ssh_callbacks is allocated because the libssh API sucks (userdata
  108. * has to be in the struct itself).
  109. */
  110. struct ssh_callbacks_struct ssh_callbacks;
  111. char *tried_passphrase;
  112. ssh_session session;
  113. ssh_channel channel;
  114. bool has_init_conn_fd;
  115. struct event ev_ssh;
  116. };
  117. TAILQ_HEAD(tmate_ssh_clients, tmate_ssh_client);
  118. extern struct tmate_ssh_client *tmate_ssh_client_alloc(struct tmate_session *session,
  119. const char *server_ip);
  120. /* tmate-session.c */
  121. struct tmate_session {
  122. struct event_base *ev_base;
  123. struct evdns_base *ev_dnsbase;
  124. struct event ev_dns_retry;
  125. struct tmate_encoder encoder;
  126. struct tmate_decoder decoder;
  127. /* True when the slave has sent all the environment variables */
  128. int tmate_env_ready;
  129. int min_sx;
  130. int min_sy;
  131. /*
  132. * This list contains one connection per IP. The first connected
  133. * client wins, and saved in *client. When we have a winner, the
  134. * losers are disconnected and killed.
  135. */
  136. struct tmate_ssh_clients clients;
  137. int need_passphrase;
  138. char *passphrase;
  139. bool reconnected;
  140. struct event ev_connection_retry;
  141. char *last_server_ip;
  142. char *reconnection_data;
  143. /*
  144. * When we reconnect, instead of serializing the key bindings and
  145. * options, we replay all the tmux commands we replicated.
  146. * It may be a little innacurate to replicate the state, but
  147. * it's much easier.
  148. */
  149. struct {
  150. unsigned int capacity;
  151. unsigned int tail;
  152. struct {
  153. int argc;
  154. char **argv;
  155. } *cmds;
  156. } saved_tmux_cmds;
  157. };
  158. extern struct tmate_session tmate_session;
  159. extern void tmate_session_init(struct event_base *base);
  160. extern void tmate_session_start(void);
  161. extern void tmate_reconnect_session(struct tmate_session *session, const char *message);
  162. /* tmate-debug.c */
  163. extern void tmate_print_stack_trace(void);
  164. extern void tmate_catch_sigsegv(void);
  165. /* tmate-msg.c */
  166. extern void __tmate_status_message(const char *fmt, va_list ap);
  167. extern void printflike(1, 2) tmate_status_message(const char *fmt, ...);
  168. /* tmate-env.c */
  169. extern int tmate_has_received_env(void);
  170. extern void tmate_set_env(const char *name, const char *value);
  171. extern void tmate_format(struct format_tree *ft);
  172. #endif