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

merge complete

This commit is contained in:
Nicolas Viennot 2015-12-29 20:01:15 -05:00
parent 8284dd910c
commit 1a48abd0be
26 changed files with 301 additions and 308 deletions

View File

@ -1,7 +1,7 @@
# Makefile.am
# Obvious program stuff.
bin_PROGRAMS = tmate
bin_PROGRAMS = tmate-slave
CLEANFILES = tmate.1.mdoc tmate.1.man
# Distribution tarball options.
@ -185,7 +185,7 @@ dist_tmate_slave_SOURCES = \
tmate-ssh-daemon.c \
tmate-ssh-exec.c \
tmate-ssh-server.c \
tmux-bare.c \
tmux.c \
tty-acs.c \
tty-keys.c \
tty-term.c \
@ -228,7 +228,7 @@ if NO_FGETLN
nodist_tmate_slave_SOURCES += compat/fgetln.c
endif
if NO_FPARSELN
nodist_tmux_SOURCES += compat/fparseln.c
nodist_tmate_slave_SOURCES += compat/fparseln.c
endif
if NO_GETOPT
nodist_tmate_slave_SOURCES += compat/getopt.c
@ -249,11 +249,11 @@ if NO_B64_NTOP
nodist_tmate_slave_SOURCES += compat/b64_ntop.c
endif
if NO_CFMAKERAW
nodist_tmate_SOURCES += compat/cfmakeraw.c
nodist_tmate_slave_SOURCES += compat/cfmakeraw.c
endif
if NO_OPENAT
nodist_tmate_SOURCES += compat/openat.c
nodist_tmate_slave_SOURCES += compat/openat.c
endif
if NO_REALLOCARRAY
nodist_tmate_SOURCES += compat/reallocarray.c
nodist_tmate_slave_SOURCES += compat/reallocarray.c
endif

View File

@ -227,8 +227,10 @@ client_main(struct event_base *base, int argc, char **argv, int flags,
struct termios tio, saved_tio;
size_t size;
#ifndef TMATE_SLAVE
/* Ignore SIGCHLD now or daemon() in the server will leave a zombie. */
signal(SIGCHLD, SIG_IGN);
#endif
/* Save the flags. */
client_flags = flags;
@ -264,10 +266,10 @@ client_main(struct event_base *base, int argc, char **argv, int flags,
#ifdef TMATE_SLAVE
fd = tmate_session->tmux_socket_fd;
#else
/* Create client process structure (starts logging). */
client_proc = proc_start("client", base, 0, client_signal);
#else
/* Initialize the client socket and start the server. */
fd = client_connect(base, socket_path, cmdflags & CMD_STARTSERVER);
if (fd == -1) {
@ -306,11 +308,13 @@ client_main(struct event_base *base, int argc, char **argv, int flags,
fatal("pledge failed");
#endif
#ifndef TMATE_SLAVE
/* Free stuff that is not used in the client. */
options_free(global_options);
options_free(global_s_options);
options_free(global_w_options);
environ_free(global_environ);
#endif
/* Create stdin handler. */
setblocking(STDIN_FILENO, 0);
@ -524,11 +528,9 @@ client_signal(int sig)
client_exitval = 1;
proc_send(client_peer, MSG_EXITING, -1, NULL, 0);
break;
#ifndef TMATE_SLAVE
case SIGWINCH:
proc_send(client_peer, MSG_RESIZE, -1, NULL, 0);
break;
#endif
case SIGCONT:
memset(&sigact, 0, sizeof sigact);
sigemptyset(&sigact.sa_mask);
@ -642,10 +644,10 @@ client_dispatch_wait(struct imsg *imsg, const char *shellcmd)
if (datalen == 0 || data[datalen - 1] != '\0')
fatalx("bad MSG_SHELL string");
clear_signals(0);
#ifdef TMATE_SLAVE
exit(1);
#else
clear_signals(0);
client_exec(data, shellcmd);
#endif
/* NOTREACHED */

View File

@ -125,7 +125,6 @@ cmd_resize_pane_exec(struct cmd *self, struct cmd_q *cmdq)
server_redraw_window(wl->window);
return (CMD_RETURN_NORMAL);
#endif
}
void
@ -173,4 +172,5 @@ cmd_resize_pane_mouse_update(struct client *c, struct mouse_event *m)
server_redraw_window(wl->window);
else
c->tty.mouse_drag_update = NULL;
#endif
}

View File

@ -380,9 +380,14 @@ format_cb_window_visible_layout(struct format_tree *ft, struct format_entry *fe)
if (w == NULL)
return;
#ifdef TMATE_SLAVE
fe->value = xstrdup("no layout");
#else
fe->value = layout_dump(w->layout_root);
#endif
}
#ifndef TMATE_SLAVE
/* Callback for pane_start_command. */
void
format_cb_start_command(struct format_tree *ft, struct format_entry *fe)
@ -432,6 +437,7 @@ format_cb_current_path(struct format_tree *ft, struct format_entry *fe)
if (cwd != NULL)
fe->value = xstrdup(cwd);
}
#endif
/* Callback for history_bytes. */
void

2
job.c
View File

@ -65,7 +65,9 @@ job_run(const char *cmd, struct session *s, const char *cwd,
close(out[1]);
return (NULL);
case 0: /* child */
#ifndef TMATE_SLAVE
clear_signals(1);
#endif
if (cwd == NULL || chdir(cwd) != 0) {
if ((home = find_home()) == NULL || chdir(home) != 0)

10
log.c
View File

@ -43,7 +43,7 @@ static void log_event_cb(int, const char *);
static void log_vwrite(int, const char *, va_list);
static void
log_event_cb(unused int severity, const char *msg)
log_event_cb(__unused int severity, const char *msg)
{
log_debug("%s", msg);
}
@ -52,14 +52,14 @@ log_event_cb(unused int severity, const char *msg)
void
log_add_level(void)
{
logging_settings.log_level++;
log_settings.log_level++;
}
/* Get log level. */
int
log_get_level(void)
{
return (logging_settings.log_level);
return (log_settings.log_level);
}
void init_logging(const char *program_name, bool use_syslog, int log_level)
@ -130,7 +130,7 @@ fatal(const char *msg, ...)
va_start(ap, msg);
if (asprintf(&fmt, "fatal: %s: %s", msg, strerror(errno)) == -1)
exit(1);
log_vwrite(fmt, ap);
log_vwrite(LOG_CRIT, fmt, ap);
exit(1);
}
@ -144,7 +144,7 @@ fatalx(const char *msg, ...)
va_start(ap, msg);
if (asprintf(&fmt, "fatal: %s", msg) == -1)
exit(1);
log_vwrite(fmt, ap);
log_vwrite(LOG_CRIT, fmt, ap);
exit(1);
}

8
proc.c
View File

@ -172,6 +172,10 @@ proc_start(const char *name, struct event_base *base, int forkflag,
struct tmuxproc *tp;
struct utsname u;
#ifdef TMATE_SLAVE
if (forkflag)
fatal("can't fork");
#else
if (forkflag) {
switch (fork()) {
case -1:
@ -188,8 +192,8 @@ proc_start(const char *name, struct event_base *base, int forkflag,
if (event_reinit(base) != 0)
fatalx("event_reinit failed");
}
log_open(name);
#endif
#ifdef HAVE_SETPROCTITLE
setproctitle("%s (%s)", name, socket_path);
@ -206,8 +210,10 @@ proc_start(const char *name, struct event_base *base, int forkflag,
tp = xcalloc(1, sizeof *tp);
tp->name = xstrdup(name);
#ifndef TMATE_SLAVE
tp->signalcb = signalcb;
set_signals(proc_signal_cb, tp);
#endif
return (tp);
}

View File

@ -313,10 +313,6 @@ server_client_detach(struct client *c, enum msgtype msgtype)
key_code
server_client_check_mouse(struct client *c)
{
#ifdef TMATE_SLAVE
/* TODO Support mouse */
return;
#else
struct session *s = c->session;
struct mouse_event *m = &c->tty.mouse;
struct window *w;
@ -539,7 +535,6 @@ server_client_check_mouse(struct client *c)
key |= KEYC_SHIFT;
return (key);
#endif
}
/* Is this fast enough to probably be a paste? */

View File

@ -332,11 +332,11 @@ server_destroy_pane(struct window_pane *wp, int hooks)
server_unzoom_window(w);
#ifndef TMATE_SLAVE
layout_close_pane(wp);
#endif
window_remove_pane(w, wp);
if (hooks && cmd_find_from_window(&fs, w) == 0)
hooks_run(hooks_get(fs.s), NULL, &fs, "pane-exited");
#endif
if (TAILQ_EMPTY(&w->panes))
server_kill_window(w);

View File

@ -135,7 +135,9 @@ server_create_socket(void)
int
server_start(struct event_base *base, int lockfd, char *lockfile)
{
#ifndef TMATE_SLAVE
#ifdef TMATE_SLAVE
server_proc = proc_start("server", base, 0, server_signal);
#else
int pair[2];
if (socketpair(AF_UNIX, SOCK_STREAM, PF_UNSPEC, pair) != 0)
@ -186,15 +188,23 @@ server_start(struct event_base *base, int lockfd, char *lockfile)
start_cfg();
#ifndef TMATE_SLAVE
status_prompt_load_history();
#endif
server_add_accept(0);
proc_loop(server_proc, server_loop);
#ifndef TMATE_SLAVE
status_prompt_save_history();
#endif
exit(0);
}
#ifdef TMATE_SLAVE
static int tmate_server_request_exit;
#endif
/* Server loop callback. */
int
server_loop(void)
@ -203,10 +213,15 @@ server_loop(void)
server_client_loop();
#ifdef TMATE_SLAVE
if (!tmate_server_request_exit)
return 0;
#else
if (!options_get_number(global_options, "exit-unattached")) {
if (!RB_EMPTY(&sessions))
return (0);
}
#endif
TAILQ_FOREACH(c, &clients, entry) {
if (c->session != NULL)
@ -221,11 +236,7 @@ server_loop(void)
if (!TAILQ_EMPTY(&clients))
return (0);
#ifdef TMATE_SLAVE
return server_shutdown;
#else
return (1);
#endif
}
/* Exit the server by killing all clients and windows. */
@ -235,6 +246,10 @@ server_send_exit(void)
struct client *c, *c1;
struct session *s, *s1;
#ifdef TMATE_SLAVE
tmate_server_request_exit = 1;
#endif
cmd_wait_for_flush();
TAILQ_FOREACH_SAFE(c, &clients, entry, c1) {
@ -353,7 +368,6 @@ server_signal(int sig)
server_child_signal();
break;
case SIGUSR1:
#ifndef TMATE_SLAVE
event_del(&server_ev_accept);
fd = server_create_socket();
if (fd != -1) {
@ -362,7 +376,6 @@ server_signal(int sig)
server_update_socket();
}
server_add_accept(0);
#endif
break;
}
}

View File

@ -25,6 +25,7 @@
#include <time.h>
#include "tmux.h"
#include "tmate.h"
struct sessions sessions;
u_int next_session_id;
@ -343,6 +344,9 @@ session_new(struct session *s, const char *name, int argc, char **argv,
shell = _PATH_BSHELL;
hlimit = options_get_number(s->options, "history-limit");
#ifdef TMATE_SLAVE
hlimit = hlimit > TMATE_HLIMIT ? TMATE_HLIMIT : hlimit;
#endif
w = window_create(name, argc, argv, path, shell, cwd, env, s->tio,
s->sx, s->sy, hlimit, cause);
if (w == NULL) {

View File

@ -24,6 +24,8 @@
#include "tmux.h"
#ifndef TMATE_SLAVE
struct event ev_sighup;
struct event ev_sigchld;
struct event ev_sigcont;
@ -103,3 +105,5 @@ clear_signals(int after_fork)
event_del(&ev_sigwinch);
}
}
#endif

View File

@ -2,11 +2,10 @@
#include <unistd.h>
#include "tmate.h"
#include "tmate-protocol.h"
#include "window-copy.h"
char *tmate_left_status, *tmate_right_status;
static struct session *main_session;
static void tmate_header(struct tmate_session *session,
struct tmate_unpacker *uk)
{
@ -24,8 +23,8 @@ static void tmate_header(struct tmate_session *session,
client_version = unpack_string(uk);
}
tmate_debug("new master, client version: %s, protocol version: %d",
client_version, session->client_protocol_version);
tmate_notice("new master, client version: %s, protocol version: %d",
client_version, session->client_protocol_version);
#if 0
if (strcmp(client_version, TMATE_LATEST_VERSION))
@ -113,10 +112,7 @@ static void tmate_sync_windows(struct session *s,
wl = winlink_find_by_index(&s->windows, idx);
if (!wl) {
/* Avoid memory bloats with the scroll buffer */
options_set_number(&s->options,
"history-limit", TMATE_HLIMIT);
wl = session_new(s, name, "", NULL, idx, &cause);
wl = session_new(s, name, 0, NULL, NULL, NULL, idx, &cause);
if (!wl)
tmate_fatal("can't create window idx=%d", idx);
}
@ -146,7 +142,7 @@ static void tmate_sync_windows(struct session *s,
server_redraw_window(wl->window);
}
static void tmate_sync_layout(struct tmate_session *session,
static void tmate_sync_layout(__unused struct tmate_session *session,
struct tmate_unpacker *uk)
{
struct session *s;
@ -157,8 +153,8 @@ static void tmate_sync_layout(struct tmate_session *session,
s = RB_MIN(sessions, &sessions);
if (!s) {
s = session_create("default", NULL, "default", NULL,
NULL, 0, sx, sy, &cause);
s = session_create("default", 0, NULL, "/", "/",
NULL, NULL, 0, sx, sy, &cause);
if (!s)
tmate_fatal("can't create main session");
}
@ -169,7 +165,7 @@ static void tmate_sync_layout(struct tmate_session *session,
tmate_sync_windows(s, uk);
}
static void tmate_pty_data(struct tmate_session *session,
static void tmate_pty_data(__unused struct tmate_session *session,
struct tmate_unpacker *uk)
{
struct window_pane *wp;
@ -190,7 +186,7 @@ static void tmate_pty_data(struct tmate_session *session,
wp->window->flags |= WINDOW_SILENCE;
}
static void tmate_exec_cmd(struct tmate_session *session,
static void tmate_exec_cmd(__unused struct tmate_session *session,
struct tmate_unpacker *uk)
{
struct cmd_q *cmd_q;
@ -205,26 +201,24 @@ static void tmate_exec_cmd(struct tmate_session *session,
}
cmd_q = cmdq_new(NULL);
cmdq_run(cmd_q, cmdlist);
cmdq_run(cmd_q, cmdlist, NULL);
cmd_list_free(cmdlist);
cmdq_free(cmd_q);
out:
free(cmd_str);
}
static void tmate_failed_cmd(struct tmate_session *session,
static void tmate_failed_cmd(__unused struct tmate_session *session,
struct tmate_unpacker *uk)
{
struct client *c;
unsigned int i;
int client_id;
char *cause;
client_id = unpack_int(uk);
cause = unpack_string(uk);
for (i = 0; i < ARRAY_LENGTH(&clients); i++) {
c = ARRAY_ITEM(&clients, i);
TAILQ_FOREACH(c, &clients, entry) {
if (c && c->id == client_id) {
*cause = toupper((u_char) *cause);
status_message_set(c, "%s", cause);
@ -235,34 +229,25 @@ static void tmate_failed_cmd(struct tmate_session *session,
free(cause);
}
static void tmate_status(struct tmate_session *session,
static void tmate_status(__unused struct tmate_session *session,
struct tmate_unpacker *uk)
{
struct client *c;
unsigned int i;
free(tmate_left_status);
free(tmate_right_status);
tmate_left_status = unpack_string(uk);
tmate_right_status = unpack_string(uk);
for (i = 0; i < ARRAY_LENGTH(&clients); i++) {
c = ARRAY_ITEM(&clients, i);
if (c)
c->flags |= CLIENT_STATUS;
}
TAILQ_FOREACH(c, &clients, entry)
c->flags |= CLIENT_STATUS;
}
extern void window_copy_redraw_screen(struct window_pane *);
extern int window_copy_update_selection(struct window_pane *);
extern void window_copy_init_for_output(struct window_pane *);
static void tmate_sync_copy_mode(struct tmate_session *session,
struct tmate_unpacker *uk)
{
struct tmate_unpacker cm_uk, sel_uk, input_uk;
struct window_copy_mode_data *data;
struct screen_write_ctx ctx;
struct window_pane *wp;
int pane_id;
int base_backing = 1;
@ -288,7 +273,7 @@ static void tmate_sync_copy_mode(struct tmate_session *session,
if (window_pane_set_mode(wp, &window_copy_mode) == 0) {
if (base_backing)
window_copy_init_from_pane(wp);
window_copy_init_from_pane(wp, 0);
else
window_copy_init_for_output(wp);
}
@ -335,11 +320,11 @@ static void tmate_sync_copy_mode(struct tmate_session *session,
data->inputprompt = NULL;
}
window_copy_update_selection(wp);
window_copy_update_selection(wp, 1);
window_copy_redraw_screen(wp);
}
static void tmate_write_copy_mode(struct tmate_session *session,
static void tmate_write_copy_mode(__unused struct tmate_session *session,
struct tmate_unpacker *uk)
{
struct window_pane *wp;

View File

@ -10,7 +10,7 @@ static void __tmate_notify(const char *msg)
pack(string, msg);
}
void printflike1 tmate_notify(const char *fmt, ...)
void tmate_notify(const char *fmt, ...)
{
va_list ap;
char msg[1024];
@ -22,13 +22,14 @@ void printflike1 tmate_notify(const char *fmt, ...)
__tmate_notify(msg);
}
static void __tmate_notify_later(evutil_socket_t fd, short what, void *arg)
static void __tmate_notify_later(__unused evutil_socket_t fd,
__unused short what, void *arg)
{
char *msg = arg;
__tmate_notify(msg);
}
void printflike2 tmate_notify_later(int timeout, const char *fmt, ...)
void tmate_notify_later(int timeout, const char *fmt, ...)
{
struct timeval tv;
va_list ap;
@ -42,12 +43,12 @@ void printflike2 tmate_notify_later(int timeout, const char *fmt, ...)
va_end(ap);
/*
* FIXME leaks like crazy when calling tmate_notify_later()
* FIXME leaks when calling tmate_notify_later()
* multiple times.
*/
evtimer_assign(&tmate_session->ev_notify_timer, ev_base,
__tmate_notify_later, msg);
evtimer_set(&tmate_session->ev_notify_timer,
__tmate_notify_later, msg);
evtimer_add(&tmate_session->ev_notify_timer, &tv);
}
@ -92,6 +93,13 @@ void tmate_client_pane_key(int pane_id, int key)
pack(int, key);
}
extern const struct cmd_entry cmd_bind_key_entry;
extern const struct cmd_entry cmd_unbind_key_entry;
extern const struct cmd_entry cmd_set_option_entry;
extern const struct cmd_entry cmd_set_window_option_entry;
extern const struct cmd_entry cmd_detach_client_entry;
extern const struct cmd_entry cmd_attach_session_entry;
static const struct cmd_entry *local_cmds[] = {
&cmd_bind_key_entry,
&cmd_unbind_key_entry,

View File

@ -1,7 +1,8 @@
#include "tmate.h"
#include "tmate-protocol.h"
static void on_encoder_buffer_ready(evutil_socket_t fd, short what, void *arg)
static void on_encoder_buffer_ready(__unused evutil_socket_t fd,
__unused short what, void *arg)
{
struct tmate_encoder *encoder = arg;
@ -161,8 +162,8 @@ void tmate_encoder_init(struct tmate_encoder *encoder,
if (!encoder->buffer)
tmate_fatal("Can't allocate buffer");
event_assign(&encoder->ev_buffer, ev_base, -1,
EV_READ | EV_PERSIST, on_encoder_buffer_ready, encoder);
event_set(&encoder->ev_buffer, -1,
EV_READ | EV_PERSIST, on_encoder_buffer_ready, encoder);
event_add(&encoder->ev_buffer, NULL);

View File

@ -10,7 +10,7 @@
#define pack(what, ...) _pack(&tmate_session->proxy_encoder, what, __VA_ARGS__)
static void ctl_daemon_fwd_msg(struct tmate_session *session,
static void ctl_daemon_fwd_msg(__unused struct tmate_session *session,
struct tmate_unpacker *uk)
{
if (uk->argc != 1)
@ -18,15 +18,14 @@ static void ctl_daemon_fwd_msg(struct tmate_session *session,
tmate_send_mc_obj(&uk->argv[0]);
}
static void do_snapshot(struct tmate_unpacker *uk,
static void do_snapshot(__unused struct tmate_unpacker *uk,
unsigned int max_history_lines,
struct window_pane *pane)
{
struct screen *screen;
struct grid *grid;
struct grid_line *line;
struct grid_cell *cell;
struct utf8_data utf8;
struct grid_cell gc;
unsigned int line_i, i;
unsigned int max_lines;
size_t str_len;
@ -59,30 +58,28 @@ static void do_snapshot(struct tmate_unpacker *uk,
pack(array, 2);
str_len = 0;
for (i = 0; i < line->cellsize; i++) {
cell = &line->celldata[i];
grid_cell_get(cell, &utf8);
str_len += utf8.size;
grid_get_cell(grid, line_i, i, &gc);
str_len += gc.data.size;
}
pack(str, str_len);
for (i = 0; i < line->cellsize; i++) {
cell = &line->celldata[i];
grid_cell_get(cell, &utf8);
pack(str_body, utf8.data, utf8.size);
grid_get_cell(grid, line_i, i, &gc);
pack(str_body, gc.data.data, gc.data.size);
}
pack(array, line->cellsize);
for (i = 0; i < line->cellsize; i++) {
cell = &line->celldata[i];
pack(unsigned_int, ((cell->flags << 24) |
(cell->attr << 16) |
(cell->bg << 8) |
cell->fg ));
grid_get_cell(grid, line_i, i, &gc);
pack(unsigned_int, ((gc.flags << 24) |
(gc.attr << 16) |
(gc.bg << 8) |
gc.fg ));
}
}
}
static void ctl_daemon_request_snapshot(struct tmate_session *session,
static void ctl_daemon_request_snapshot(__unused struct tmate_session *session,
struct tmate_unpacker *uk)
{
struct session *s;
@ -122,7 +119,7 @@ static void ctl_daemon_request_snapshot(struct tmate_session *session,
}
}
static void ctl_pane_keys(struct tmate_session *session,
static void ctl_pane_keys(__unused struct tmate_session *session,
struct tmate_unpacker *uk)
{
int i;
@ -191,7 +188,7 @@ void tmate_proxy_exec(struct tmate_session *session, const char *command)
pack(string, command);
}
void tmate_notify_client_join(struct tmate_session *session,
void tmate_notify_client_join(__unused struct tmate_session *session,
struct client *c)
{
if (!tmate_has_proxy())
@ -205,7 +202,7 @@ void tmate_notify_client_join(struct tmate_session *session,
pack(boolean, c->readonly);
}
void tmate_notify_client_left(struct tmate_session *session,
void tmate_notify_client_left(__unused struct tmate_session *session,
struct client *c)
{
if (!tmate_has_proxy())
@ -216,10 +213,9 @@ void tmate_notify_client_left(struct tmate_session *session,
pack(int, c->id);
}
void tmate_send_proxy_daemon_msg(struct tmate_session *session,
void tmate_send_proxy_daemon_msg(__unused struct tmate_session *session,
struct tmate_unpacker *uk)
{
struct timespec time_diff, current_time;
int i;
if (!tmate_has_proxy())
@ -253,7 +249,7 @@ static void on_proxy_decoder_read(void *userdata, struct tmate_unpacker *uk)
tmate_dispatch_proxy_message(session, uk);
}
static void on_proxy_read(struct bufferevent *bev, void *_session)
static void on_proxy_read(__unused struct bufferevent *bev, void *_session)
{
struct tmate_session *session = _session;
struct evbuffer *proxy_in;
@ -281,7 +277,6 @@ static void on_proxy_encoder_write(void *userdata, struct evbuffer *buffer)
{
struct tmate_session *session = userdata;
struct evbuffer *proxy_out;
size_t len;
proxy_out = bufferevent_get_output(session->bev_proxy);
@ -289,7 +284,7 @@ static void on_proxy_encoder_write(void *userdata, struct evbuffer *buffer)
tmate_fatal("Cannot write to proxy buffer");
}
static void on_proxy_event_default(struct tmate_session *session, short events)
static void on_proxy_event_default(__unused struct tmate_session *session, short events)
{
if (events & BEV_EVENT_EOF)
tmate_fatal("Connection to proxy closed");
@ -299,7 +294,7 @@ static void on_proxy_event_default(struct tmate_session *session, short events)
evutil_socket_error_to_string(EVUTIL_SOCKET_ERROR()));
}
static void on_proxy_event(struct bufferevent *bev, short events, void *_session)
static void on_proxy_event(__unused struct bufferevent *bev, short events, void *_session)
{
struct tmate_session *session = _session;
session->on_proxy_error(session, events);
@ -315,8 +310,8 @@ void tmate_init_proxy(struct tmate_session *session,
session->proxy_sy = -1;
/* session->proxy_fd is already connected */
session->bev_proxy = bufferevent_socket_new(ev_base, session->proxy_fd,
BEV_OPT_CLOSE_ON_FREE);
session->bev_proxy = bufferevent_socket_new(session->ev_base, session->proxy_fd,
BEV_OPT_CLOSE_ON_FREE);
if (!session->bev_proxy)
tmate_fatal("Cannot setup socket bufferevent");

View File

@ -3,6 +3,7 @@
#include <unistd.h>
#include <libssh/libssh.h>
#include <sys/stat.h>
#include <sys/param.h>
#include <errno.h>
#include <grp.h>
#include <pwd.h>
@ -28,7 +29,7 @@ static char *cmdline_end;
static int dev_urandom_fd;
extern int server_create_socket(void);
extern int client_connect(char *path, int start_server);
extern int client_connect(struct event_base *base, const char *path, int start_server);
struct tmate_settings _tmate_settings = {
.keys_dir = TMATE_SSH_DEFAULT_KEYS_DIR,
@ -60,14 +61,12 @@ long tmate_get_random_long(void)
return val;
}
extern int server_shutdown;
extern int server_fd;
extern void server_send_shutdown(void);
extern void server_send_exit(void);
void request_server_termination(void)
{
if (server_fd) {
server_shutdown = 1;
server_send_shutdown();
server_send_exit();
} else
exit(1);
}
@ -154,9 +153,10 @@ static char *get_random_token(void)
static void set_session_token(struct tmate_session *session,
const char *token)
{
char *path;
session->session_token = xstrdup(token);
strcpy(socket_path, TMATE_WORKDIR "/sessions/");
strcat(socket_path, token);
xasprintf(&path, TMATE_WORKDIR "/sessions/%s", token);
socket_path = path;
memset(cmdline, 0, cmdline_end - cmdline);
sprintf(cmdline, "tmate-slave [%s] %s %s",
@ -164,6 +164,7 @@ static void set_session_token(struct tmate_session *session,
session->ssh_client.role == TMATE_ROLE_DAEMON ? "(daemon)" : "(pty client)",
session->ssh_client.ip_address);
}
static void create_session_ro_symlink(struct tmate_session *session)
{
char session_ro_path[MAXPATHLEN];
@ -271,7 +272,7 @@ static void jail(void)
if (chdir("/") < 0)
tmate_fatal("Cannot chdir()");
#if IS_LINUX
#ifdef IS_LINUX
if (unshare(CLONE_NEWPID | CLONE_NEWIPC | CLONE_NEWNS | CLONE_NEWNET) < 0)
tmate_fatal("Cannot create new namespace");
#endif
@ -279,10 +280,10 @@ static void jail(void)
if (setgroups(1, (gid_t[]){gid}) < 0)
tmate_fatal("Cannot setgroups()");
#if HAVE_SETRESGID
#if defined(HAVE_SETRESGID)
if (setresgid(gid, gid, gid) < 0)
tmate_fatal("Cannot setresgid() %d", gid);
#elif HAVE_SETREGID
#elif defined(HAVE_SETREGID)
if (setregid(gid, gid) < 0)
tmate_fatal("Cannot setregid()");
#else
@ -290,10 +291,10 @@ static void jail(void)
tmate_fatal("Cannot setgid()");
#endif
#if HAVE_SETRESUID
#if defined(HAVE_SETRESUID)
if (setresuid(uid, uid, uid) < 0)
tmate_fatal("Cannot setresuid()");
#elif HAVE_SETREUID
#elif defined(HAVE_SETREUID)
if (setreuid(uid, uid) < 0)
tmate_fatal("Cannot setreuid()");
#else
@ -304,8 +305,8 @@ static void jail(void)
if (nice(1) < 0)
tmate_fatal("Cannot nice()");
tmate_debug("Dropped priviledges to %s (%d,%d), jailed in %s",
TMATE_JAIL_USER, uid, gid, TMATE_WORKDIR "/jail");
tmate_info("Dropped priviledges to %s (%d,%d), jailed in %s",
TMATE_JAIL_USER, uid, gid, TMATE_WORKDIR "/jail");
}
static void setup_ncurse(int fd, const char *name)
@ -318,10 +319,7 @@ static void setup_ncurse(int fd, const char *name)
static void tmate_spawn_slave_daemon(struct tmate_session *session)
{
struct tmate_ssh_client *client = &session->ssh_client;
char *token;
struct tmate_encoder encoder;
struct tmate_decoder decoder;
token = get_random_token();
#ifdef DEVENV
@ -331,8 +329,8 @@ static void tmate_spawn_slave_daemon(struct tmate_session *session)
set_session_token(session, token);
free(token);
tmate_debug("Spawning slave server for %s at %s (%s)",
client->username, client->ip_address, client->pubkey);
tmate_notice("Spawning slave server for %s at %s (%s)",
client->username, client->ip_address, client->pubkey);
session->tmux_socket_fd = server_create_socket();
if (session->tmux_socket_fd < 0)
@ -354,9 +352,10 @@ static void tmate_spawn_slave_daemon(struct tmate_session *session)
session->proxy_fd}, 4);
jail();
event_reinit(ev_base);
event_reinit(session->ev_base);
tmux_server_init(IDENTIFY_UTF8 | IDENTIFY_256COLOURS);
tmux_server_init();
server_start(session->ev_base, -1, NULL);
/* never reached */
}
@ -383,10 +382,10 @@ static void tmate_spawn_slave_pty_client(struct tmate_session *session)
set_session_token(session, token);
tmate_debug("Spawning slave client for %s (%s)",
client->ip_address, client->pubkey);
tmate_notice("Spawning slave client for %s (%s)",
client->ip_address, client->pubkey);
session->tmux_socket_fd = client_connect(socket_path, 0);
session->tmux_socket_fd = client_connect(session->ev_base, socket_path, 0);
if (session->tmux_socket_fd < 0) {
random_sleep(); /* for making timing attacks harder */
ssh_echo(client, EXPIRED_TOKEN_ERROR_STR);
@ -427,9 +426,10 @@ static void tmate_spawn_slave_pty_client(struct tmate_session *session)
ssh_get_fd(session->ssh_client.session),
session->pty, log_file ? fileno(log_file) : -1}, 7);
jail();
event_reinit(ev_base);
event_reinit(session->ev_base);
ret = client_main(argc, argv, IDENTIFY_UTF8 | IDENTIFY_256COLOURS);
ret = client_main(session->ev_base, argc, argv,
CLIENT_UTF8 | CLIENT_256COLOURS, NULL);
tmate_flush_pty(session);
exit(ret);
}
@ -440,11 +440,11 @@ static void tmate_spawn_slave_exec(struct tmate_session *session)
log_file ? fileno(log_file) : -1,
session->proxy_fd}, 3);
jail();
event_reinit(ev_base);
event_reinit(session->ev_base);
tmate_client_exec_init(session);
if (event_base_dispatch(ev_base) < 0)
if (event_base_dispatch(session->ev_base) < 0)
tmate_fatal("Cannot run event loop");
exit(0);
}

View File

@ -3,11 +3,12 @@
#include <sys/ioctl.h>
#include "tmate.h"
extern void client_write_server(enum msgtype type, void *buf, size_t len);
extern void client_signal(int sig);
static int on_ssh_channel_read(ssh_session _session, ssh_channel channel,
static int on_ssh_channel_read(__unused ssh_session _session,
__unused ssh_channel channel,
void *_data, uint32_t total_len,
int is_stderr, void *userdata)
__unused int is_stderr, void *userdata)
{
struct tmate_session *session = userdata;
char *data = _data;
@ -32,7 +33,8 @@ static int on_ssh_channel_read(ssh_session _session, ssh_channel channel,
return written;
}
static int on_ssh_message_callback(ssh_session _session, ssh_message msg, void *arg)
static int on_ssh_message_callback(__unused ssh_session _session,
ssh_message msg, void *arg)
{
struct tmate_session *session = arg;
@ -44,7 +46,7 @@ static int on_ssh_message_callback(ssh_session _session, ssh_message msg, void *
ws.ws_row = ssh_message_channel_request_pty_height(msg);
ioctl(session->pty, TIOCSWINSZ, &ws);
client_write_server(MSG_RESIZE, NULL, 0);
client_signal(SIGWINCH);
return 1;
}
@ -77,7 +79,7 @@ static void on_pty_event(struct tmate_session *session)
}
}
static void __on_pty_event(evutil_socket_t fd, short what, void *arg)
static void __on_pty_event(__unused evutil_socket_t fd, __unused short what, void *arg)
{
on_pty_event(arg);
}
@ -104,7 +106,7 @@ void tmate_client_pty_init(struct tmate_session *session)
on_ssh_message_callback, session);
setblocking(session->pty, 0);
event_assign(&session->ev_pty, ev_base, session->pty,
EV_READ | EV_PERSIST, __on_pty_event, session);
event_set(&session->ev_pty, session->pty,
EV_READ | EV_PERSIST, __on_pty_event, session);
event_add(&session->ev_pty, NULL);
}

View File

@ -13,11 +13,11 @@ void tmate_dump_exec_response(struct tmate_session *session,
ssh_channel_send_eof(client->channel);
ssh_channel_close(client->channel);
if (event_base_loopexit(ev_base, NULL) < 0)
if (event_base_loopexit(session->ev_base, NULL) < 0)
tmate_fatal("cannot stop event loop");
}
static void on_proxy_error(struct tmate_session *session, short events)
static void on_proxy_error(struct tmate_session *session, __unused short events)
{
tmate_warn("Lost proxy connection");
tmate_dump_exec_response(session, 1, "Internal Error\r\n");

View File

@ -11,7 +11,8 @@
#include "tmate.h"
static void start_keepalive_timer(struct tmate_ssh_client *client);
static void on_keepalive_timer(evutil_socket_t fd, short what, void *arg)
static void on_keepalive_timer(__unused evutil_socket_t fd,
__unused short what, void *arg)
{
struct tmate_ssh_client *client = arg;
@ -23,14 +24,17 @@ static void start_keepalive_timer(struct tmate_ssh_client *client)
{
struct timeval tv = { TMATE_SSH_KEEPALIVE, 0 };
evtimer_assign(&client->ev_keepalive_timer, ev_base,
on_keepalive_timer, client);
evtimer_set(&client->ev_keepalive_timer,
on_keepalive_timer, client);
evtimer_add(&client->ev_keepalive_timer, &tv);
}
static int pty_request(ssh_session session, ssh_channel channel,
const char *term, int width, int height,
int pxwidth, int pwheight, void *userdata)
static int pty_request(__unused ssh_session session,
__unused ssh_channel channel,
__unused const char *term,
int width, int height,
__unused int pxwidth, __unused int pwheight,
void *userdata)
{
struct tmate_ssh_client *client = userdata;
@ -40,7 +44,8 @@ static int pty_request(ssh_session session, ssh_channel channel,
return 0;
}
static int shell_request(ssh_session session, ssh_channel channel,
static int shell_request(__unused ssh_session session,
__unused ssh_channel channel,
void *userdata)
{
struct tmate_ssh_client *client = userdata;
@ -53,7 +58,8 @@ static int shell_request(ssh_session session, ssh_channel channel,
return 0;
}
static int subsystem_request(ssh_session session, ssh_channel channel,
static int subsystem_request(__unused ssh_session session,
__unused ssh_channel channel,
const char *subsystem, void *userdata)
{
struct tmate_ssh_client *client = userdata;
@ -67,7 +73,8 @@ static int subsystem_request(ssh_session session, ssh_channel channel,
return 0;
}
static int exec_request(ssh_session session, ssh_channel channel,
static int exec_request(__unused ssh_session session,
__unused ssh_channel channel,
const char *command, void *userdata)
{
struct tmate_ssh_client *client = userdata;
@ -114,7 +121,8 @@ static ssh_channel channel_open_request_cb(ssh_session session, void *userdata)
return client->channel;
}
static int auth_pubkey_cb(ssh_session session, const char *user,
static int auth_pubkey_cb(__unused ssh_session session,
const char *user,
struct ssh_key_struct *pubkey,
char signature_state, void *userdata)
{
@ -139,7 +147,7 @@ static struct ssh_server_callbacks_struct ssh_server_cb = {
.channel_open_request_session_function = channel_open_request_cb,
};
static void on_ssh_read(evutil_socket_t fd, short what, void *arg)
static void on_ssh_read(__unused evutil_socket_t fd, __unused short what, void *arg)
{
struct tmate_ssh_client *client = arg;
ssh_execute_message_callbacks(client->session);
@ -156,23 +164,21 @@ static void on_ssh_read(evutil_socket_t fd, short what, void *arg)
static void register_on_ssh_read(struct tmate_ssh_client *client)
{
event_assign(&client->ev_ssh, ev_base, ssh_get_fd(client->session),
EV_READ | EV_PERSIST, on_ssh_read, client);
event_set(&client->ev_ssh, ssh_get_fd(client->session),
EV_READ | EV_PERSIST, on_ssh_read, client);
event_add(&client->ev_ssh, NULL);
}
static void client_bootstrap(struct tmate_session *_session)
{
struct tmate_ssh_client *client = &_session->ssh_client;
int auth = 0;
int grace_period = TMATE_SSH_GRACE_PERIOD;
ssh_event mainloop;
ssh_session session = client->session;
ssh_message msg;
tmate_notice("Bootstrapping ssh client ip=%s", client->ip_address);
ev_base = osdep_event_init();
_session->ev_base = osdep_event_init();
/* new process group, we don't want to die with our parent (upstart) */
setpgid(0, 0);
@ -200,7 +206,7 @@ static void client_bootstrap(struct tmate_session *_session)
ssh_set_auth_methods(client->session, SSH_AUTH_METHOD_PUBLICKEY);
tmate_debug("Exchanging DH keys");
tmate_info("Exchanging DH keys");
if (ssh_handle_key_exchange(session) < 0)
tmate_fatal("Error doing the key exchange: %s",
ssh_get_error(session));
@ -248,10 +254,15 @@ static void handle_sigsegv(void)
tmate_print_stack_trace();
tmate_fatal("CRASHED");
}
static void handle_sigterm(void)
{
request_server_termination();
}
static void signal_handler(int sig)
{
switch (sig) {
case SIGTERM: handle_sigterm(); break;
case SIGCHLD: handle_sigchld(); break;
case SIGALRM: handle_sigalrm(); break;
case SIGSEGV: handle_sigsegv(); break;
@ -260,6 +271,7 @@ static void signal_handler(int sig)
static void setup_signals(void)
{
signal(SIGTERM, signal_handler);
signal(SIGCHLD, signal_handler);
signal(SIGALRM, signal_handler);
signal(SIGSEGV, signal_handler);
@ -293,9 +305,9 @@ static int get_ip(int fd, char *dst, size_t len)
}
static void ssh_log_function(int priority, const char *function,
const char *buffer, void *userdata)
const char *buffer, __unused void *userdata)
{
tmate_debug("[%d] [%s] %s", priority, function, buffer);
tmate_info("[%d] [%s] %s", priority, function, buffer);
}
static ssh_bind prepare_ssh(const char *keys_dir, int port)

11
tmate.h
View File

@ -14,7 +14,7 @@ struct tmate_session;
/* log.c */
extern void init_logging(const char *program_name, bool use_syslog, int log_level);
extern void printflike2 tmate_log(int level, const char *msg, ...);
extern void printflike(2, 3) tmate_log(int level, const char *msg, ...);
#define tmate_debug(str, ...) tmate_log(LOG_DEBUG, str, ##__VA_ARGS__)
#define tmate_info(str, ...) tmate_log(LOG_INFO, str, ##__VA_ARGS__)
@ -88,8 +88,8 @@ extern void unpack_array(struct tmate_unpacker *uk, struct tmate_unpacker *neste
#define TMATE_LATEST_VERSION "1.8.10"
extern void printflike1 tmate_notify(const char *fmt, ...);
extern void printflike2 tmate_notify_later(int timeout, const char *fmt, ...);
extern void printflike(1, 2) tmate_notify(const char *fmt, ...);
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_pane_key(int pane_id, int key);
@ -195,6 +195,7 @@ extern struct tmate_settings *tmate_settings;
typedef void on_proxy_error_cb(struct tmate_session *session, short events);
struct tmate_session {
struct event_base *ev_base;
struct tmate_ssh_client ssh_client;
int tmux_socket_fd;
@ -259,8 +260,8 @@ extern unsigned long long timespec_to_millisec(struct timespec *ts);
extern void tmate_preload_trace_lib(void);
extern void tmate_print_stack_trace(void);
/* tmux-bare.c */
/* tmux.c */
extern void tmux_server_init(int flags);
extern void tmux_server_init(void);
#endif

View File

@ -1,78 +0,0 @@
#include <stdlib.h>
#include <fcntl.h>
#include <unistd.h>
#include "tmux.h"
#include "tmate.h"
struct event_base *ev_base;
struct options global_options; /* server options */
struct options global_s_options; /* session options */
struct options global_w_options; /* window options */
struct environ global_environ;
char *cfg_file;
char *shell_cmd;
int debug_level;
time_t start_time;
char socket_path[MAXPATHLEN];
int login_shell;
char *environ_path;
pid_t environ_pid = -1;
int environ_session_id = -1;
void
setblocking(int fd, int state)
{
int mode;
if ((mode = fcntl(fd, F_GETFL)) != -1) {
if (!state)
mode |= O_NONBLOCK;
else
mode &= ~O_NONBLOCK;
fcntl(fd, F_SETFL, mode);
}
}
const char*
get_full_path(const char *wd, const char *path)
{
static char newpath[MAXPATHLEN];
char oldpath[MAXPATHLEN];
if (getcwd(oldpath, sizeof oldpath) == NULL)
return (NULL);
if (chdir(wd) != 0)
return (NULL);
if (realpath(path, newpath) != 0)
return (NULL);
chdir(oldpath);
return (newpath);
}
void tmux_server_init(int flags)
{
int quiet = 0;
environ_init(&global_environ);
options_init(&global_options, NULL);
options_table_populate_tree(server_options_table, &global_options);
options_set_number(&global_options, "quiet", quiet);
options_init(&global_s_options, NULL);
options_table_populate_tree(session_options_table, &global_s_options);
options_init(&global_w_options, NULL);
options_table_populate_tree(window_options_table, &global_w_options);
if (flags & IDENTIFY_UTF8) {
options_set_number(&global_s_options, "status-utf8", 1);
options_set_number(&global_s_options, "mouse-utf8", 1);
options_set_number(&global_w_options, "utf8", 1);
}
server_start(0, NULL);
}

31
tmux.c
View File

@ -31,6 +31,7 @@
#include <unistd.h>
#include "tmux.h"
#include "tmate.h"
#if defined(DEBUG) && defined(__OpenBSD__)
extern char *malloc_options;
@ -45,6 +46,7 @@ struct hooks *global_hooks;
struct timeval start_time;
const char *socket_path;
#ifndef TMATE_SLAVE
__dead void usage(void);
static char *make_label(const char *);
@ -151,6 +153,7 @@ fail:
errno = saved_errno;
return (NULL);
}
#endif
void
setblocking(int fd, int state)
@ -166,6 +169,11 @@ setblocking(int fd, int state)
}
}
#ifdef TMATE_SLAVE
const char * find_home(void) { return NULL; }
int areshell(__unused const char *shell) { return 0; }
#else
const char *
find_home(void)
{
@ -337,3 +345,26 @@ main(int argc, char **argv)
/* Pass control to the client. */
exit(client_main(event_init(), argc, argv, flags, shellcmd));
}
#endif
#ifdef TMATE_SLAVE
void tmux_server_init(void)
{
global_hooks = hooks_create(NULL);
global_environ = environ_create();
global_options = options_create(NULL);
options_table_populate_tree(OPTIONS_TABLE_SERVER, global_options);
global_s_options = options_create(NULL);
options_table_populate_tree(OPTIONS_TABLE_SESSION, global_s_options);
options_set_string(global_s_options, "default-shell", "%s", "/bin/false");
global_w_options = options_create(NULL);
options_table_populate_tree(OPTIONS_TABLE_WINDOW, global_w_options);
options_set_number(global_s_options, "status-keys", MODEKEY_VI);
options_set_number(global_w_options, "mode-keys", MODEKEY_VI);
}
#endif

8
tmux.h
View File

@ -409,6 +409,12 @@ enum msgtype {
MSG_IDENTIFY_CLIENTPID,
MSG_IDENTIFY_CWD,
#ifdef TMATE_SLAVE
MSG_IDENTIFY_TMATE_IP_ADDRESS,
MSG_IDENTIFY_TMATE_PUBKEY,
MSG_IDENTIFY_TMATE_READONLY,
#endif
MSG_COMMAND = 200,
MSG_DETACH,
MSG_DETACHKILL,
@ -879,8 +885,8 @@ struct window_pane {
#else
int fd;
struct bufferevent *event;
struct event timer;
#endif
struct event timer;
struct input_ctx *ictx;

View File

@ -24,67 +24,7 @@
#include "tmux.h"
struct screen *window_copy_init(struct window_pane *);
void window_copy_free(struct window_pane *);
void window_copy_resize(struct window_pane *, u_int, u_int);
void window_copy_key(struct window_pane *, struct client *, struct session *,
key_code, struct mouse_event *);
int window_copy_key_input(struct window_pane *, key_code);
int window_copy_key_numeric_prefix(struct window_pane *, key_code);
void window_copy_redraw_selection(struct window_pane *, u_int);
void window_copy_redraw_lines(struct window_pane *, u_int, u_int);
void window_copy_redraw_screen(struct window_pane *);
void window_copy_write_line(struct window_pane *, struct screen_write_ctx *,
u_int);
void window_copy_write_lines(struct window_pane *,
struct screen_write_ctx *, u_int, u_int);
void window_copy_scroll_to(struct window_pane *, u_int, u_int);
int window_copy_search_compare(struct grid *, u_int, u_int, struct grid *,
u_int, int);
int window_copy_search_lr(struct grid *, struct grid *, u_int *, u_int,
u_int, u_int, int);
int window_copy_search_rl(struct grid *, struct grid *, u_int *, u_int,
u_int, u_int, int);
void window_copy_search_up(struct window_pane *, const char *);
void window_copy_search_down(struct window_pane *, const char *);
void window_copy_goto_line(struct window_pane *, const char *);
void window_copy_update_cursor(struct window_pane *, u_int, u_int);
void window_copy_start_selection(struct window_pane *);
int window_copy_update_selection(struct window_pane *, int);
void *window_copy_get_selection(struct window_pane *, size_t *);
void window_copy_copy_buffer(struct window_pane *, const char *, void *,
size_t);
void window_copy_copy_pipe(struct window_pane *, struct session *,
const char *, const char *);
void window_copy_copy_selection(struct window_pane *, const char *);
void window_copy_append_selection(struct window_pane *, const char *);
void window_copy_clear_selection(struct window_pane *);
void window_copy_copy_line(struct window_pane *, char **, size_t *, u_int,
u_int, u_int);
int window_copy_in_set(struct window_pane *, u_int, u_int, const char *);
u_int window_copy_find_length(struct window_pane *, u_int);
void window_copy_cursor_start_of_line(struct window_pane *);
void window_copy_cursor_back_to_indentation(struct window_pane *);
void window_copy_cursor_end_of_line(struct window_pane *);
void window_copy_other_end(struct window_pane *);
void window_copy_cursor_left(struct window_pane *);
void window_copy_cursor_right(struct window_pane *);
void window_copy_cursor_up(struct window_pane *, int);
void window_copy_cursor_down(struct window_pane *, int);
void window_copy_cursor_jump(struct window_pane *);
void window_copy_cursor_jump_back(struct window_pane *);
void window_copy_cursor_jump_to(struct window_pane *, int);
void window_copy_cursor_jump_to_back(struct window_pane *, int);
void window_copy_cursor_next_word(struct window_pane *, const char *);
void window_copy_cursor_next_word_end(struct window_pane *, const char *);
void window_copy_cursor_previous_word(struct window_pane *, const char *);
void window_copy_scroll_up(struct window_pane *, u_int);
void window_copy_scroll_down(struct window_pane *, u_int);
void window_copy_rectangle_toggle(struct window_pane *);
void window_copy_drag_update(struct client *, struct mouse_event *);
void window_copy_drag_release(struct client *, struct mouse_event *);
#include "window-copy.h"
const struct window_mode window_copy_mode = {
window_copy_init,
@ -93,8 +33,6 @@ const struct window_mode window_copy_mode = {
window_copy_key,
};
#include "window-copy.h"
struct screen *
window_copy_init(struct window_pane *wp)
{

View File

@ -3,6 +3,70 @@
#include "tmux.h"
struct screen *window_copy_init(struct window_pane *);
void window_copy_free(struct window_pane *);
void window_copy_resize(struct window_pane *, u_int, u_int);
void window_copy_key(struct window_pane *, struct client *, struct session *,
key_code, struct mouse_event *);
int window_copy_key_input(struct window_pane *, key_code);
int window_copy_key_numeric_prefix(struct window_pane *, key_code);
void window_copy_redraw_selection(struct window_pane *, u_int);
void window_copy_redraw_lines(struct window_pane *, u_int, u_int);
void window_copy_redraw_screen(struct window_pane *);
void window_copy_write_line(struct window_pane *, struct screen_write_ctx *,
u_int);
void window_copy_write_lines(struct window_pane *,
struct screen_write_ctx *, u_int, u_int);
void window_copy_scroll_to(struct window_pane *, u_int, u_int);
int window_copy_search_compare(struct grid *, u_int, u_int, struct grid *,
u_int, int);
int window_copy_search_lr(struct grid *, struct grid *, u_int *, u_int,
u_int, u_int, int);
int window_copy_search_rl(struct grid *, struct grid *, u_int *, u_int,
u_int, u_int, int);
void window_copy_search_up(struct window_pane *, const char *);
void window_copy_search_down(struct window_pane *, const char *);
void window_copy_goto_line(struct window_pane *, const char *);
void window_copy_update_cursor(struct window_pane *, u_int, u_int);
void window_copy_start_selection(struct window_pane *);
int window_copy_update_selection(struct window_pane *, int);
void *window_copy_get_selection(struct window_pane *, size_t *);
void window_copy_copy_buffer(struct window_pane *, const char *, void *,
size_t);
void window_copy_copy_pipe(struct window_pane *, struct session *,
const char *, const char *);
void window_copy_copy_selection(struct window_pane *, const char *);
void window_copy_append_selection(struct window_pane *, const char *);
void window_copy_clear_selection(struct window_pane *);
void window_copy_copy_line(struct window_pane *, char **, size_t *, u_int,
u_int, u_int);
int window_copy_in_set(struct window_pane *, u_int, u_int, const char *);
u_int window_copy_find_length(struct window_pane *, u_int);
void window_copy_cursor_start_of_line(struct window_pane *);
void window_copy_cursor_back_to_indentation(struct window_pane *);
void window_copy_cursor_end_of_line(struct window_pane *);
void window_copy_other_end(struct window_pane *);
void window_copy_cursor_left(struct window_pane *);
void window_copy_cursor_right(struct window_pane *);
void window_copy_cursor_up(struct window_pane *, int);
void window_copy_cursor_down(struct window_pane *, int);
void window_copy_cursor_jump(struct window_pane *);
void window_copy_cursor_jump_back(struct window_pane *);
void window_copy_cursor_jump_to(struct window_pane *, int);
void window_copy_cursor_jump_to_back(struct window_pane *, int);
void window_copy_cursor_next_word(struct window_pane *, const char *);
void window_copy_cursor_next_word_end(struct window_pane *, const char *);
void window_copy_cursor_previous_word(struct window_pane *, const char *);
void window_copy_scroll_up(struct window_pane *, u_int);
void window_copy_scroll_down(struct window_pane *, u_int);
void window_copy_rectangle_toggle(struct window_pane *);
void window_copy_drag_update(struct client *, struct mouse_event *);
void window_copy_drag_release(struct client *, struct mouse_event *);
extern const struct window_mode window_copy_mode;
enum window_copy_input_type {
WINDOW_COPY_OFF,
WINDOW_COPY_NAMEDBUFFER,
@ -33,10 +97,6 @@ enum window_copy_input_type {
* mode ends).
*/
#ifdef TMATE
typedef void (*copy_password_callback)(const char *password, void *private);
#endif
struct window_copy_mode_data {
struct screen screen;