window change hack in telnetd
This commit is contained in:
parent
f0cc130f18
commit
b2bb27eda1
3 changed files with 79 additions and 3 deletions
|
@ -12,24 +12,32 @@
|
|||
#include <sys/types.h>
|
||||
#include <string.h>
|
||||
#include <fcntl.h>
|
||||
#include <errno.h>
|
||||
#include <unistd.h>
|
||||
#include <termios.h>
|
||||
#include "telnetd.h"
|
||||
#include "telnet.h"
|
||||
#include <stdio.h>
|
||||
#include <sys/ioctl.h>
|
||||
|
||||
|
||||
#define IN_DATA 0
|
||||
#define IN_CR 1
|
||||
#define IN_IAC 2
|
||||
#define IN_IAC2 3
|
||||
#define IN_SB 4
|
||||
|
||||
_PROTOTYPE(static void dowill, (int c));
|
||||
_PROTOTYPE(static void dowont, (int c));
|
||||
_PROTOTYPE(static void dodo, (int c));
|
||||
_PROTOTYPE(static void dodont, (int c));
|
||||
_PROTOTYPE(static void respond, (int ack, int option));
|
||||
_PROTOTYPE(static void respond_really, (int ack, int option));
|
||||
|
||||
#define LASTTELOPT TELOPT_SGA
|
||||
|
||||
static int r_winch = 0;
|
||||
|
||||
static int TelROpts[LASTTELOPT+1];
|
||||
static int TelLOpts[LASTTELOPT+1];
|
||||
|
||||
|
@ -63,7 +71,7 @@ int len;
|
|||
if(option <= LASTTELOPT) {
|
||||
TelROpts[option] = 1;
|
||||
len = 3;
|
||||
}
|
||||
} else if(option == TELOPT_WINCH && !r_winch) { r_winch = 1; len = 3; }
|
||||
break;
|
||||
case DONT:
|
||||
if(option <= LASTTELOPT) {
|
||||
|
@ -88,6 +96,15 @@ int len;
|
|||
(void) write(fdout, buf, len);
|
||||
}
|
||||
|
||||
int set_winsize(int fd, unsigned int cols, unsigned int rows)
|
||||
{
|
||||
struct winsize w;
|
||||
memset(&w, 0, sizeof(w));
|
||||
w.ws_col = cols;
|
||||
w.ws_row = rows;
|
||||
ioctl(fd, TIOCSWINSZ, (char *) &w);
|
||||
}
|
||||
|
||||
int tel_in(fdout, telout, buffer, len)
|
||||
int fdout;
|
||||
int telout;
|
||||
|
@ -134,6 +151,9 @@ int c;
|
|||
InState = IN_IAC2;
|
||||
ThisOpt = c;
|
||||
break;
|
||||
case SB:
|
||||
InState = IN_SB;
|
||||
break;
|
||||
case EOR:
|
||||
case SE:
|
||||
case NOP:
|
||||
|
@ -144,7 +164,6 @@ int c;
|
|||
case EC:
|
||||
case EL:
|
||||
case GA:
|
||||
case SB:
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
|
@ -164,6 +183,43 @@ int c;
|
|||
case DONT: dodont(c); break;
|
||||
}
|
||||
break;
|
||||
case IN_SB:
|
||||
{
|
||||
static int winchpos = -1;
|
||||
/* Subnegotiation. */
|
||||
if(winchpos >= 0) {
|
||||
static unsigned int winchbuf[5], iacs = 0;
|
||||
winchbuf[winchpos] = c;
|
||||
/* IAC is escaped - unescape it. */
|
||||
if(c == IAC) iacs++; else { iacs = 0; winchpos++; }
|
||||
if(iacs == 2) { winchpos++; iacs = 0; }
|
||||
if(winchpos >= 4) {
|
||||
/* End of WINCH data. */
|
||||
set_winsize(fdout,
|
||||
(winchbuf[0] << 8) | winchbuf[1],
|
||||
(winchbuf[2] << 8) | winchbuf[3]);
|
||||
winchpos = -1;
|
||||
}
|
||||
} else {
|
||||
static int lastiac = 0;
|
||||
switch(c) {
|
||||
case TELOPT_WINCH:
|
||||
/* Start listening. */
|
||||
winchpos = 0;
|
||||
break;
|
||||
case SE:
|
||||
if(lastiac) InState = IN_DATA;
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
if(c == IAC) lastiac = 1;
|
||||
else lastiac = 0;
|
||||
|
||||
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -211,9 +267,16 @@ int ack;
|
|||
TelROpts[c] = 1;
|
||||
ack = DO;
|
||||
break;
|
||||
case TELOPT_WINCH:
|
||||
if(r_winch) return;
|
||||
r_winch = 1;
|
||||
ack = DO;
|
||||
respond_really(ack, c);
|
||||
return;
|
||||
default:
|
||||
ack = DONT;
|
||||
}
|
||||
|
||||
respond(ack, c);
|
||||
}
|
||||
|
||||
|
@ -259,5 +322,16 @@ unsigned char c[3];
|
|||
c[0] = IAC;
|
||||
c[1] = ack;
|
||||
c[2] = option;
|
||||
/* write(telfdout, c, 3); */
|
||||
/* write(telfdout, c, 3); */
|
||||
}
|
||||
|
||||
static void respond_really(ack, option)
|
||||
int ack, option;
|
||||
{
|
||||
unsigned char c[3];
|
||||
|
||||
c[0] = IAC;
|
||||
c[1] = ack;
|
||||
c[2] = option;
|
||||
write(telfdout, c, 3);
|
||||
}
|
||||
|
|
|
@ -61,6 +61,7 @@
|
|||
#define TELOPT_SNDLOC 23 /* send location */
|
||||
#define TELOPT_TTYPE 24 /* terminal type */
|
||||
#define TELOPT_EOR 25 /* end or record */
|
||||
#define TELOPT_WINCH 31 /* window size */
|
||||
#define TELOPT_EXOPL 255 /* extended-options-list */
|
||||
|
||||
/* Sub-option qualifiers. */
|
||||
|
|
|
@ -38,6 +38,7 @@ void term_init()
|
|||
telopt(1, WILL, TELOPT_BINARY);
|
||||
telopt(1, DO, TELOPT_BINARY);
|
||||
telopt(1, WILL, TELOPT_ECHO);
|
||||
telopt(1, DO, TELOPT_WINCH);
|
||||
}
|
||||
|
||||
static int io_done = 0;
|
||||
|
|
Loading…
Reference in a new issue