window change hack in telnetd
This commit is contained in:
parent
f0cc130f18
commit
b2bb27eda1
@ -12,24 +12,32 @@
|
|||||||
#include <sys/types.h>
|
#include <sys/types.h>
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
#include <fcntl.h>
|
#include <fcntl.h>
|
||||||
|
#include <errno.h>
|
||||||
#include <unistd.h>
|
#include <unistd.h>
|
||||||
|
#include <termios.h>
|
||||||
#include "telnetd.h"
|
#include "telnetd.h"
|
||||||
#include "telnet.h"
|
#include "telnet.h"
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
|
#include <sys/ioctl.h>
|
||||||
|
|
||||||
|
|
||||||
#define IN_DATA 0
|
#define IN_DATA 0
|
||||||
#define IN_CR 1
|
#define IN_CR 1
|
||||||
#define IN_IAC 2
|
#define IN_IAC 2
|
||||||
#define IN_IAC2 3
|
#define IN_IAC2 3
|
||||||
|
#define IN_SB 4
|
||||||
|
|
||||||
_PROTOTYPE(static void dowill, (int c));
|
_PROTOTYPE(static void dowill, (int c));
|
||||||
_PROTOTYPE(static void dowont, (int c));
|
_PROTOTYPE(static void dowont, (int c));
|
||||||
_PROTOTYPE(static void dodo, (int c));
|
_PROTOTYPE(static void dodo, (int c));
|
||||||
_PROTOTYPE(static void dodont, (int c));
|
_PROTOTYPE(static void dodont, (int c));
|
||||||
_PROTOTYPE(static void respond, (int ack, int option));
|
_PROTOTYPE(static void respond, (int ack, int option));
|
||||||
|
_PROTOTYPE(static void respond_really, (int ack, int option));
|
||||||
|
|
||||||
#define LASTTELOPT TELOPT_SGA
|
#define LASTTELOPT TELOPT_SGA
|
||||||
|
|
||||||
|
static int r_winch = 0;
|
||||||
|
|
||||||
static int TelROpts[LASTTELOPT+1];
|
static int TelROpts[LASTTELOPT+1];
|
||||||
static int TelLOpts[LASTTELOPT+1];
|
static int TelLOpts[LASTTELOPT+1];
|
||||||
|
|
||||||
@ -63,7 +71,7 @@ int len;
|
|||||||
if(option <= LASTTELOPT) {
|
if(option <= LASTTELOPT) {
|
||||||
TelROpts[option] = 1;
|
TelROpts[option] = 1;
|
||||||
len = 3;
|
len = 3;
|
||||||
}
|
} else if(option == TELOPT_WINCH && !r_winch) { r_winch = 1; len = 3; }
|
||||||
break;
|
break;
|
||||||
case DONT:
|
case DONT:
|
||||||
if(option <= LASTTELOPT) {
|
if(option <= LASTTELOPT) {
|
||||||
@ -88,6 +96,15 @@ int len;
|
|||||||
(void) write(fdout, buf, 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 tel_in(fdout, telout, buffer, len)
|
||||||
int fdout;
|
int fdout;
|
||||||
int telout;
|
int telout;
|
||||||
@ -134,6 +151,9 @@ int c;
|
|||||||
InState = IN_IAC2;
|
InState = IN_IAC2;
|
||||||
ThisOpt = c;
|
ThisOpt = c;
|
||||||
break;
|
break;
|
||||||
|
case SB:
|
||||||
|
InState = IN_SB;
|
||||||
|
break;
|
||||||
case EOR:
|
case EOR:
|
||||||
case SE:
|
case SE:
|
||||||
case NOP:
|
case NOP:
|
||||||
@ -144,7 +164,6 @@ int c;
|
|||||||
case EC:
|
case EC:
|
||||||
case EL:
|
case EL:
|
||||||
case GA:
|
case GA:
|
||||||
case SB:
|
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
break;
|
break;
|
||||||
@ -164,6 +183,43 @@ int c;
|
|||||||
case DONT: dodont(c); break;
|
case DONT: dodont(c); break;
|
||||||
}
|
}
|
||||||
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;
|
TelROpts[c] = 1;
|
||||||
ack = DO;
|
ack = DO;
|
||||||
break;
|
break;
|
||||||
|
case TELOPT_WINCH:
|
||||||
|
if(r_winch) return;
|
||||||
|
r_winch = 1;
|
||||||
|
ack = DO;
|
||||||
|
respond_really(ack, c);
|
||||||
|
return;
|
||||||
default:
|
default:
|
||||||
ack = DONT;
|
ack = DONT;
|
||||||
}
|
}
|
||||||
|
|
||||||
respond(ack, c);
|
respond(ack, c);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -259,5 +322,16 @@ unsigned char c[3];
|
|||||||
c[0] = IAC;
|
c[0] = IAC;
|
||||||
c[1] = ack;
|
c[1] = ack;
|
||||||
c[2] = option;
|
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_SNDLOC 23 /* send location */
|
||||||
#define TELOPT_TTYPE 24 /* terminal type */
|
#define TELOPT_TTYPE 24 /* terminal type */
|
||||||
#define TELOPT_EOR 25 /* end or record */
|
#define TELOPT_EOR 25 /* end or record */
|
||||||
|
#define TELOPT_WINCH 31 /* window size */
|
||||||
#define TELOPT_EXOPL 255 /* extended-options-list */
|
#define TELOPT_EXOPL 255 /* extended-options-list */
|
||||||
|
|
||||||
/* Sub-option qualifiers. */
|
/* Sub-option qualifiers. */
|
||||||
|
@ -38,6 +38,7 @@ void term_init()
|
|||||||
telopt(1, WILL, TELOPT_BINARY);
|
telopt(1, WILL, TELOPT_BINARY);
|
||||||
telopt(1, DO, TELOPT_BINARY);
|
telopt(1, DO, TELOPT_BINARY);
|
||||||
telopt(1, WILL, TELOPT_ECHO);
|
telopt(1, WILL, TELOPT_ECHO);
|
||||||
|
telopt(1, DO, TELOPT_WINCH);
|
||||||
}
|
}
|
||||||
|
|
||||||
static int io_done = 0;
|
static int io_done = 0;
|
||||||
|
Loading…
x
Reference in New Issue
Block a user