Remove the internal tmux locking and instead detach each client and run the

command specified by a new option "lock-command" (by default "lock -np") in
each client.

This means each terminal has to be unlocked individually but simplifies the
code and allows the system password to be used to unlock.

Note that the set-password command is gone, so it will need to be removed from
configuration files, and the -U command line flag has been removed.

This is the third protocol version change so again it is best to stop the tmux
server before upgrading.
pull/1/head
Nicholas Marriott 2009-09-23 06:18:47 +00:00
parent 962fa20b36
commit b01dcd7971
13 changed files with 55 additions and 449 deletions

View File

@ -20,7 +20,7 @@ SRCS= attributes.c buffer-poll.c buffer.c cfg.c client-fn.c \
cmd-scroll-mode.c cmd-select-layout.c cmd-select-pane.c \
cmd-select-prompt.c cmd-select-window.c cmd-send-keys.c \
cmd-send-prefix.c cmd-server-info.c cmd-set-buffer.c cmd-set-option.c \
cmd-set-password.c cmd-set-window-option.c cmd-show-buffer.c \
cmd-set-window-option.c cmd-show-buffer.c \
cmd-show-options.c cmd-show-window-options.c cmd-source-file.c \
cmd-split-window.c cmd-start-server.c cmd-string.c cmd-if-shell.c \
cmd-run-shell.c cmd-suspend-client.c cmd-swap-pane.c cmd-swap-window.c \

View File

@ -242,6 +242,7 @@ client_msg_dispatch(struct client_ctx *cctx)
{
struct imsg imsg;
struct msg_print_data printdata;
struct msg_lock_data lockdata;
ssize_t n, datalen;
for (;;) {
@ -295,6 +296,15 @@ client_msg_dispatch(struct client_ctx *cctx)
client_suspend();
break;
case MSG_LOCK:
if (datalen != sizeof lockdata)
fatalx("bad MSG_LOCK size");
memcpy(&lockdata, imsg.data, sizeof lockdata);
lockdata.cmd[(sizeof lockdata.cmd) - 1] = '\0';
system(lockdata.cmd);
client_write_server(cctx, MSG_UNLOCK, NULL, 0);
break;
default:
fatalx("unexpected message");
}

View File

@ -62,6 +62,7 @@ const struct set_option_entry set_option_table[] = {
{ "display-time", SET_OPTION_NUMBER, 1, INT_MAX, NULL },
{ "history-limit", SET_OPTION_NUMBER, 0, INT_MAX, NULL },
{ "lock-after-time", SET_OPTION_NUMBER, 0, INT_MAX, NULL },
{ "lock-command", SET_OPTION_STRING, 0, 0, NULL },
{ "message-attr", SET_OPTION_ATTRIBUTES, 0, 0, NULL },
{ "message-bg", SET_OPTION_COLOUR, 0, 0, NULL },
{ "message-fg", SET_OPTION_COLOUR, 0, 0, NULL },

View File

@ -1,145 +0,0 @@
/* $OpenBSD$ */
/*
* Copyright (c) 2009 Nicholas Marriott <nicm@users.sourceforge.net>
*
* Permission to use, copy, modify, and distribute this software for any
* purpose with or without fee is hereby granted, provided that the above
* copyright notice and this permission notice appear in all copies.
*
* THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
* WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
* MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
* ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
* WHATSOEVER RESULTING FROM LOSS OF MIND, USE, DATA OR PROFITS, WHETHER
* IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING
* OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
*/
#include <sys/types.h>
#include <pwd.h>
#include <unistd.h>
#include "tmux.h"
/*
* Set server password.
*/
int cmd_set_password_parse(struct cmd *, int, char **, char **);
int cmd_set_password_exec(struct cmd *, struct cmd_ctx *);
void cmd_set_password_free(struct cmd *);
void cmd_set_password_init(struct cmd *, int);
size_t cmd_set_password_print(struct cmd *, char *, size_t);
struct cmd_set_password_data {
char *password;
int flag_encrypted;
};
const struct cmd_entry cmd_set_password_entry = {
"set-password", "pass",
"[-c] password",
0, 0,
cmd_set_password_init,
cmd_set_password_parse,
cmd_set_password_exec,
cmd_set_password_free,
cmd_set_password_print
};
void
cmd_set_password_init(struct cmd *self, unused int arg)
{
struct cmd_set_password_data *data;
self->data = data = xmalloc(sizeof *data);
data->password = NULL;
data->flag_encrypted = 0;
}
int
cmd_set_password_parse(struct cmd *self, int argc, char **argv, char **cause)
{
struct cmd_set_password_data *data;
int opt;
char *out;
self->entry->init(self, KEYC_NONE);
data = self->data;
while ((opt = getopt(argc, argv, "c")) != -1) {
switch (opt) {
case 'c':
data->flag_encrypted = 1;
break;
default:
goto usage;
}
}
argc -= optind;
argv += optind;
if (argc != 1)
goto usage;
if (!data->flag_encrypted) {
if ((out = crypt(argv[0], "$1")) != NULL)
data->password = xstrdup(out);
} else
data->password = xstrdup(argv[0]);
return (0);
usage:
xasprintf(cause, "usage: %s %s", self->entry->name, self->entry->usage);
self->entry->free(self);
return (-1);
}
int
cmd_set_password_exec(struct cmd *self, struct cmd_ctx *ctx)
{
struct cmd_set_password_data *data = self->data;
if (data->password == NULL) {
ctx->error(ctx, "failed to encrypt password");
return (-1);
}
if (server_password != NULL)
xfree(server_password);
if (*data->password == '\0')
server_password = NULL;
else
server_password = xstrdup(data->password);
return (0);
}
void
cmd_set_password_free(struct cmd *self)
{
struct cmd_set_password_data *data = self->data;
if (data->password != NULL)
xfree(data->password);
xfree(data);
}
size_t
cmd_set_password_print(struct cmd *self, char *buf, size_t len)
{
struct cmd_set_password_data *data = self->data;
size_t off = 0;
off += xsnprintf(buf, len, "%s", self->entry->name);
if (data == NULL)
return (off);
if (off < len && data->flag_encrypted)
off += xsnprintf(buf + off, len - off, " -c");
if (off < len && data->password != NULL)
off += xsnprintf(buf + off, len - off, " password");
return (off);
}

5
cmd.c
View File

@ -89,7 +89,6 @@ const struct cmd_entry *cmd_table[] = {
&cmd_set_buffer_entry,
&cmd_set_environment_entry,
&cmd_set_option_entry,
&cmd_set_password_entry,
&cmd_set_window_option_entry,
&cmd_show_buffer_entry,
&cmd_show_environment_entry,
@ -260,10 +259,6 @@ usage:
int
cmd_exec(struct cmd *cmd, struct cmd_ctx *ctx)
{
if (server_locked) {
ctx->error(ctx, "server is locked");
return (-1);
}
return (cmd->entry->exec(cmd, ctx));
}

View File

@ -18,16 +18,12 @@
#include <sys/types.h>
#include <login_cap.h>
#include <pwd.h>
#include <string.h>
#include <time.h>
#include <unistd.h>
#include "tmux.h"
int server_lock_callback(void *, const char *);
void
server_fill_environ(struct session *s, struct environ *env)
{
@ -161,110 +157,30 @@ server_status_window(struct window *w)
void
server_lock(void)
{
struct client *c;
static struct passwd *pw, pwstore;
static char pwbuf[_PW_BUF_LEN];
u_int i;
if (server_locked)
return;
if (getpwuid_r(getuid(), &pwstore, pwbuf, sizeof pwbuf, &pw) != 0) {
server_locked_pw = NULL;
return;
}
server_locked_pw = pw;
struct client *c;
const char *cmd;
struct msg_lock_data lockdata;
u_int i;
for (i = 0; i < ARRAY_LENGTH(&clients); i++) {
c = ARRAY_ITEM(&clients, i);
if (c == NULL || c->session == NULL)
continue;
status_prompt_clear(c);
status_prompt_set(c,
"Password:", server_lock_callback, NULL, c, PROMPT_HIDDEN);
server_redraw_client(c);
}
server_locked = 1;
}
int
server_lock_callback(unused void *data, const char *s)
{
return (server_unlock(s));
}
int
server_unlock(const char *s)
{
struct client *c;
login_cap_t *lc;
u_int i;
char *out;
u_int failures, tries, backoff;
if (!server_locked || server_locked_pw == NULL)
return (0);
server_activity = time(NULL);
if (server_activity < password_backoff)
return (-2);
if (server_password != NULL) {
if (s == NULL)
return (-1);
out = crypt(s, server_password);
if (strcmp(out, server_password) != 0)
goto wrong;
}
for (i = 0; i < ARRAY_LENGTH(&clients); i++) {
c = ARRAY_ITEM(&clients, i);
if (c == NULL)
if (c->flags & CLIENT_SUSPENDED)
continue;
status_prompt_clear(c);
server_redraw_client(c);
}
server_locked = 0;
password_failures = 0;
password_backoff = 0;
return (0);
wrong:
password_failures++;
password_backoff = 0;
for (i = 0; i < ARRAY_LENGTH(&clients); i++) {
c = ARRAY_ITEM(&clients, i);
if (c == NULL || c->prompt_buffer == NULL)
cmd = options_get_string(&c->session->options, "lock-command");
if (strlcpy(lockdata.cmd,
cmd, sizeof lockdata.cmd) >= sizeof lockdata.cmd)
continue;
*c->prompt_buffer = '\0';
c->prompt_index = 0;
server_redraw_client(c);
}
tty_stop_tty(&c->tty);
tty_raw(&c->tty, tty_term_string(c->tty.term, TTYC_SMCUP));
tty_raw(&c->tty, tty_term_string(c->tty.term, TTYC_CLEAR));
/*
* Start slowing down after "login-backoff" attempts and reset every
* "login-tries" attempts.
*/
lc = login_getclass(server_locked_pw->pw_class);
if (lc != NULL) {
tries = login_getcapnum(lc, (char *) "login-tries", 10, 10);
backoff = login_getcapnum(lc, (char *) "login-backoff", 3, 3);
} else {
tries = 10;
backoff = 3;
c->flags |= CLIENT_SUSPENDED;
server_write_client(c, MSG_LOCK, &lockdata, sizeof lockdata);
}
failures = password_failures % tries;
if (failures > backoff) {
password_backoff =
server_activity + ((failures - backoff) * tries / 2);
return (-2);
}
return (-1);
}
void

View File

@ -40,7 +40,6 @@ server_msg_dispatch(struct client *c)
struct imsg imsg;
struct msg_command_data commanddata;
struct msg_identify_data identifydata;
struct msg_unlock_data unlockdata;
struct msg_environ_data environdata;
ssize_t n, datalen;
@ -95,31 +94,15 @@ server_msg_dispatch(struct client *c)
tty_close(&c->tty);
server_write_client(c, MSG_EXITED, NULL, 0);
break;
case MSG_UNLOCK:
if (datalen != sizeof unlockdata)
fatalx("bad MSG_UNLOCK size");
memcpy(&unlockdata, imsg.data, sizeof unlockdata);
unlockdata.pass[(sizeof unlockdata.pass) - 1] = '\0';
switch (server_unlock(unlockdata.pass)) {
case -1:
server_write_error(c, "bad password");
break;
case -2:
server_write_error(c,
"too many bad passwords, sleeping");
break;
}
memset(&unlockdata, 0, sizeof unlockdata);
server_write_client(c, MSG_EXIT, NULL, 0);
break;
case MSG_WAKEUP:
case MSG_UNLOCK:
if (datalen != 0)
fatalx("bad MSG_WAKEUP size");
c->flags &= ~CLIENT_SUSPENDED;
tty_start_tty(&c->tty);
server_redraw_client(c);
server_activity = time(NULL);
break;
case MSG_ENVIRON:
if (datalen != sizeof environdata)

View File

@ -67,7 +67,6 @@ void server_lost_client(struct client *);
void server_check_window(struct window *);
void server_check_redraw(struct client *);
void server_set_title(struct client *);
void server_redraw_locked(struct client *);
void server_check_timers(struct client *);
void server_second_timers(void);
int server_update_socket(void);
@ -160,8 +159,6 @@ server_start(char *path)
key_bindings_init();
utf8_build();
server_locked = 0;
server_password = NULL;
server_activity = time(NULL);
start_time = time(NULL);
@ -382,8 +379,6 @@ server_main(int srv_fd)
options_free(&global_s_options);
options_free(&global_w_options);
if (server_password != NULL)
xfree(server_password);
return (0);
}
@ -541,10 +536,7 @@ server_check_redraw(struct client *c)
}
if (c->flags & CLIENT_REDRAW) {
if (server_locked)
server_redraw_locked(c);
else
screen_redraw_screen(c, 0);
screen_redraw_screen(c, 0);
c->flags &= ~CLIENT_STATUS;
} else {
TAILQ_FOREACH(wp, &c->session->curw->window->panes, entry) {
@ -581,49 +573,6 @@ server_set_title(struct client *c)
xfree(title);
}
/* Redraw client when locked. */
void
server_redraw_locked(struct client *c)
{
struct screen_write_ctx ctx;
struct screen screen;
struct grid_cell gc;
u_int colour, xx, yy, i;
int style;
xx = c->tty.sx;
yy = c->tty.sy - 1;
if (xx == 0 || yy == 0)
return;
colour = options_get_number(&global_w_options, "clock-mode-colour");
style = options_get_number(&global_w_options, "clock-mode-style");
memcpy(&gc, &grid_default_cell, sizeof gc);
colour_set_fg(&gc, colour);
gc.attr |= GRID_ATTR_BRIGHT;
screen_init(&screen, xx, yy, 0);
screen_write_start(&ctx, NULL, &screen);
clock_draw(&ctx, colour, style);
if (password_failures != 0) {
screen_write_cursormove(&ctx, 0, 0);
screen_write_puts(
&ctx, &gc, "%u failed attempts", password_failures);
if (time(NULL) < password_backoff)
screen_write_puts(&ctx, &gc, "; sleeping");
}
screen_write_stop(&ctx);
for (i = 0; i < screen_size_y(&screen); i++)
tty_draw_line(&c->tty, &screen, i, 0, 0);
screen_redraw_screen(c, 1);
screen_free(&screen);
}
/* Check for timers on client. */
void
server_check_timers(struct client *c)
@ -836,8 +785,6 @@ server_handle_client(struct client *c)
status_prompt_key(c, key);
continue;
}
if (server_locked)
continue;
/* Check for mouse keys. */
if (key == KEYC_MOUSE) {
@ -929,8 +876,6 @@ server_handle_client(struct client *c)
tty_cursor(&c->tty, s->cx, s->cy, wp->xoff, wp->yoff);
mode = s->mode;
if (server_locked)
mode &= ~TTY_NOCURSOR;
tty_update_mode(&c->tty, mode);
tty_reset(&c->tty);
}
@ -1235,12 +1180,9 @@ void
server_second_timers(void)
{
struct window *w;
struct client *c;
struct window_pane *wp;
u_int i;
int xtimeout;
struct tm now, then;
static time_t last_t = 0;
time_t t;
t = time(NULL);
@ -1259,29 +1201,6 @@ server_second_timers(void)
wp->mode->timer(wp);
}
}
if (password_backoff != 0 && t >= password_backoff) {
for (i = 0; i < ARRAY_LENGTH(&clients); i++) {
if ((c = ARRAY_ITEM(&clients, i)) != NULL)
server_redraw_client(c);
}
password_backoff = 0;
}
/* Check for a minute having passed. */
gmtime_r(&t, &now);
gmtime_r(&last_t, &then);
if (now.tm_min == then.tm_min)
return;
last_t = t;
/* If locked, redraw all clients. */
if (server_locked) {
for (i = 0; i < ARRAY_LENGTH(&clients); i++) {
if ((c = ARRAY_ITEM(&clients, i)) != NULL)
server_redraw_client(c);
}
}
}
/* Update socket execute permissions based on whether sessions are attached. */

View File

@ -890,9 +890,6 @@ status_prompt_key(struct client *c, int key)
}
break;
case MODEKEYEDIT_HISTORYUP:
if (server_locked)
break;
if (ARRAY_LENGTH(&c->prompt_hdata) == 0)
break;
if (c->prompt_flags & PROMPT_HIDDEN)
@ -908,9 +905,6 @@ status_prompt_key(struct client *c, int key)
c->flags |= CLIENT_STATUS;
break;
case MODEKEYEDIT_HISTORYDOWN:
if (server_locked)
break;
if (c->prompt_flags & PROMPT_HIDDEN)
memset(c->prompt_buffer, 0, strlen(c->prompt_buffer));
xfree(c->prompt_buffer);
@ -1003,9 +997,6 @@ status_prompt_key(struct client *c, int key)
void
status_prompt_add_history(struct client *c)
{
if (server_locked)
return;
if (ARRAY_LENGTH(&c->prompt_hdata) > 0 &&
strcmp(ARRAY_LAST(&c->prompt_hdata), c->prompt_buffer) == 0)
return;

40
tmux.1
View File

@ -23,7 +23,7 @@
.Sh SYNOPSIS
.Nm tmux
.Bk -words
.Op Fl 28dlqUuv
.Op Fl 28dlquv
.Op Fl f Ar file
.Op Fl L Ar socket-name
.Op Fl S Ar socket-path
@ -154,8 +154,6 @@ If
is specified, the default socket directory is not used and any
.Fl L
flag is ignored.
.It Fl U
Unlock the server.
.It Fl u
.Nm
attempts to guess if the terminal is likely to support UTF-8 by checking the
@ -337,8 +335,6 @@ rename-session -tfirst newname
set-window-option -t:0 monitor-activity on
new-window ; split-window -d
bind-key D detach-client \e\; lock-server
.Ed
.Sh CLIENTS AND SESSIONS
The following commands are available:
@ -1213,17 +1209,20 @@ Set the maximum number of lines held in window history.
This setting applies only to new windows - existing window histories are not
resized and retain the limit at the point they were created.
.It Ic lock-after-time Ar number
Lock the server after
Lock the server (like the
.Ic lock-server
command) after
.Ar number
seconds of inactivity.
The default is off (set to 0).
This has no effect as a session option; it must be set as a global option using
.Fl g .
When passwords are entered incorrectly,
.Nm
follows the behaviour of
.Xr login 1
and ignores further password attempts for an increasing timeout.
.It Ic lock-command Ar command
Command to run when locking each client.
The default is to run
.Xr lock 1
with
.Fl np .
.It Ic message-attr Ar attributes
Set status line message attributes, where
.Ar attributes
@ -1962,7 +1961,9 @@ if
returns success.
.It Ic lock-server
.D1 (alias: Ic lock )
Lock the server until a password is entered.
Lock each client individually by running the command specified by the
.Ic lock-command
option.
.It Ic run-shell Ar command
.D1 (alias: Ic run )
Execute
@ -1975,21 +1976,6 @@ doesn't return success, the exit status is also displayed.
.It Ic server-info
.D1 (alias: Ic info )
Show server information and terminal details.
.It Xo Ic set-password
.Op Fl c
.Ar password
.Xc
.D1 (alias: Ic pass )
Set the server password.
If the
.Fl c
option is given, a pre-encrypted password may be specified.
By default, the password is blank, thus any entered password will be accepted
when unlocking the server (see the
.Ic lock-server
command).
To prevent variable expansion when an encrypted password is read from a
configuration file, enclose it in single quotes (').
.El
.Sh FILES
.Bl -tag -width "/etc/tmux.confXXX" -compact

58
tmux.c
View File

@ -46,11 +46,6 @@ struct options global_s_options; /* session options */
struct options global_w_options; /* window options */
struct environ global_environ;
int server_locked;
struct passwd *server_locked_pw;
u_int password_failures;
time_t password_backoff;
char *server_password;
time_t server_activity;
int debug_level;
@ -61,7 +56,6 @@ int login_shell;
__dead void usage(void);
char *makesockpath(const char *);
int prepare_unlock(enum msgtype *, void **, size_t *, int);
int prepare_cmd(enum msgtype *, void **, size_t *, int, char **);
int dispatch_imsg(struct client_ctx *, int *);
@ -69,7 +63,7 @@ __dead void
usage(void)
{
fprintf(stderr,
"usage: %s [-28dlqUuv] [-f file] [-L socket-name]\n"
"usage: %s [-28dlquv] [-f file] [-L socket-name]\n"
" [-S socket-path] [command [flags]]\n",
__progname);
exit(1);
@ -250,35 +244,6 @@ makesockpath(const char *label)
return (path);
}
int
prepare_unlock(enum msgtype *msg, void **buf, size_t *len, int argc)
{
static struct msg_unlock_data unlockdata;
char *pass;
if (argc != 0) {
log_warnx("can't specify a command when unlocking");
return (-1);
}
if ((pass = getpass("Password:")) == NULL)
return (-1);
if (strlen(pass) >= sizeof unlockdata.pass) {
log_warnx("password too long");
return (-1);
}
strlcpy(unlockdata.pass, pass, sizeof unlockdata.pass);
memset(pass, 0, strlen(pass));
*buf = &unlockdata;
*len = sizeof unlockdata;
*msg = MSG_UNLOCK;
return (0);
}
int
prepare_cmd(enum msgtype *msg, void **buf, size_t *len, int argc, char **argv)
{
@ -314,10 +279,10 @@ main(int argc, char **argv)
char cwd[MAXPATHLEN];
void *buf;
size_t len;
int retcode, opt, flags, unlock, cmdflags = 0;
int retcode, opt, flags, cmdflags = 0;
int nfds;
unlock = flags = 0;
flags = 0;
label = path = NULL;
login_shell = (**argv == '-');
while ((opt = getopt(argc, argv, "28df:lL:qS:uUv")) != -1) {
@ -357,9 +322,6 @@ main(int argc, char **argv)
case 'u':
flags |= IDENTIFY_UTF8;
break;
case 'U':
unlock = 1;
break;
case 'v':
debug_level++;
break;
@ -407,6 +369,7 @@ main(int argc, char **argv)
options_set_number(so, "display-time", 750);
options_set_number(so, "history-limit", 2000);
options_set_number(so, "lock-after-time", 0);
options_set_string(so, "lock-command", "lock -np");
options_set_number(so, "message-attr", 0);
options_set_number(so, "message-bg", 3);
options_set_number(so, "message-fg", 0);
@ -514,17 +477,10 @@ main(int argc, char **argv)
}
xfree(label);
if (unlock) {
if (prepare_unlock(&msg, &buf, &len, argc) != 0)
exit(1);
} else {
if (prepare_cmd(&msg, &buf, &len, argc, argv) != 0)
exit(1);
}
if (prepare_cmd(&msg, &buf, &len, argc, argv) != 0)
exit(1);
if (unlock)
cmdflags &= ~CMD_STARTSERVER;
else if (argc == 0) /* new-session is the default */
if (argc == 0) /* new-session is the default */
cmdflags |= CMD_STARTSERVER|CMD_SENDENVIRON;
else {
/*

18
tmux.h
View File

@ -19,7 +19,7 @@
#ifndef TMUX_H
#define TMUX_H
#define PROTOCOL_VERSION 3
#define PROTOCOL_VERSION 4
#include <sys/param.h>
#include <sys/time.h>
@ -304,10 +304,11 @@ enum msgtype {
MSG_RESIZE,
MSG_SHUTDOWN,
MSG_SUSPEND,
MSG_UNLOCK,
MSG_VERSION,
MSG_WAKEUP,
MSG_ENVIRON
MSG_ENVIRON,
MSG_UNLOCK,
MSG_LOCK
};
/*
@ -339,8 +340,8 @@ struct msg_identify_data {
int flags;
};
struct msg_unlock_data {
char pass[PASS_MAX];
struct msg_lock_data {
char cmd[COMMAND_LENGTH];
};
struct msg_environ_data {
@ -1108,11 +1109,6 @@ extern struct options global_s_options;
extern struct options global_w_options;
extern struct environ global_environ;
extern char *cfg_file;
extern int server_locked;
extern struct passwd *server_locked_pw;
extern u_int password_failures;
extern time_t password_backoff;
extern char *server_password;
extern time_t server_activity;
extern int debug_level;
extern int be_quiet;
@ -1179,6 +1175,7 @@ void environ_unset(struct environ *, const char *);
void environ_update(const char *, struct environ *, struct environ *);
/* tty.c */
void tty_raw(struct tty *, const char *);
u_char tty_get_acs(struct tty *, u_char);
void tty_attributes(struct tty *, const struct grid_cell *);
void tty_reset(struct tty *);
@ -1352,7 +1349,6 @@ extern const struct cmd_entry cmd_server_info_entry;
extern const struct cmd_entry cmd_set_buffer_entry;
extern const struct cmd_entry cmd_set_environment_entry;
extern const struct cmd_entry cmd_set_option_entry;
extern const struct cmd_entry cmd_set_password_entry;
extern const struct cmd_entry cmd_set_window_option_entry;
extern const struct cmd_entry cmd_show_buffer_entry;
extern const struct cmd_entry cmd_show_environment_entry;

2
tty.c
View File

@ -29,8 +29,6 @@
void tty_fill_acs(struct tty *);
void tty_raw(struct tty *, const char *);
int tty_try_256(struct tty *, u_char, const char *);
int tty_try_88(struct tty *, u_char, const char *);