elks-enhanced
public
Read
Owner: themaster
Branch: master
Commits: 6893
Updated: 2026-04-19 00:15
Git CLI clone URL
git clone https://www.xt-emporium.com/git/elks-enhanced.git
Fullscreen desktop URL
Code
Commits
History
Branches
Bug Reports
Discussions
Compare
Settings
elks-enhanced
/
elkscmd
/
inet
/
telopt.c
File editor
/* * telopt.c - Telnet options processing for telnetd.c * * TNET A server program for MINIX which implements the TCP/IP suite * of networking protocols. It is based on the TCP/IP code written by Phil * Karn et al, as found in his NET package for Packet Radio communications. * * This module handles telnet option processing. * * Author: Michael Temari, <temari@temari.ae.ge.com> 01/13/93 */ #include <stdio.h> #include <string.h> #include <fcntl.h> #include <unistd.h> #include <termios.h> #include <sys/ioctl.h> #include "telopt.h" #define IN_DATA 0 #define IN_CR 1 #define IN_IAC 2 #define IN_IAC2 3 #define IN_SB 4 #define LASTTELOPT TELOPT_SGA static int r_winch = 0; static int telfdout; static int TelROpts[LASTTELOPT + 1]; static int TelLOpts[LASTTELOPT + 1]; static void dowill(int c); static void dowont(int c); static void dodo(int c); static void dodont(int c); static void respond_really(int ack, int option); #define respond(ack, option) /* reduce code size with null procedure */ //static void respond(int ack, int option); void tel_init(void) { int i; for (i = 0; i <= LASTTELOPT; i++) { TelROpts[i] = 0; TelLOpts[i] = 0; } } void tel_opt(int fdout, int what, int option) { int len; char buf[3]; buf[0] = IAC; buf[1] = what; buf[2] = option; len = 0; switch (what) { case DO: 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) { TelROpts[option] = 1; len = 3; } break; case WILL: if (option <= LASTTELOPT) { TelLOpts[option] = 1; len = 3; } break; case WONT: if (option <= LASTTELOPT) { TelLOpts[option] = 1; len = 3; } break; } if (len > 0) write(fdout, buf, len); } static void setwinsize(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); } void tel_in(int fdout, int telout, char *buffer, int len) { static int InState = IN_DATA; static int ThisOpt = 0; char *p; char *p2; int size; int c; telfdout = telout; p = p2 = buffer; size = 0; while (len > 0) { c = (unsigned char)*p++; len--; switch (InState) { case IN_CR: InState = IN_DATA; if (c == 0 || c == '\n') break; /* fall through */ case IN_DATA: if (c == IAC) { InState = IN_IAC; break; } *p2++ = c; size++; if (c == '\r') InState = IN_CR; break; case IN_IAC: switch (c) { case IAC: *p2++ = c; size++; InState = IN_DATA; break; case WILL: case WONT: case DO: case DONT: InState = IN_IAC2; ThisOpt = c; break; case SB: InState = IN_SB; break; case IP: InState = IN_DATA; *p2++ = '\003'; size++; break; case AO: InState = IN_DATA; /* no action for Abort Output */ break; case EOR: case SE: case NOP: case BREAK: case AYT: case EC: case EL: case GA: break; default: break; } break; case IN_IAC2: if (size > 0) { write(fdout, buffer, size); p2 = buffer; size = 0; } InState = IN_DATA; switch (ThisOpt) { case WILL: dowill(c); break; case WONT: dowont(c); break; case DO: dodo(c); break; 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. */ setwinsize(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; } } } if (size > 0) write(fdout, buffer, size); } void tel_out(int fdout, char *buf, int size) { char *p; int got_iac, len; p = buf; while (size > 0) { buf = p; got_iac = 0; if ((p = memchr(buf, IAC, size)) != NULL) { got_iac = 1; p++; } else p = buf + size; len = p - buf; if (len > 0) write(fdout, buf, len); if (got_iac) write(fdout, p - 1, 1); size = size - len; } } static void dowill(int c) { int ack; switch (c) { case TELOPT_BINARY: case TELOPT_ECHO: case TELOPT_SGA: if (TelROpts[c] == 1) return; 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); } static void dowont(int c) { if (c <= LASTTELOPT) { if (TelROpts[c] == 0) return; TelROpts[c] = 0; } respond(DONT, c); } static void dodo(int c) { #ifndef respond int ack; switch (c) { default: ack = WONT; } respond(ack, c); #endif } static void dodont(int c) { if (c <= LASTTELOPT) { if (TelLOpts[c] == 0) return; TelLOpts[c] = 0; } respond(WONT, c); } #ifndef respond static void respond(int ack, int option) { /**unsigned char c[3]; c[0] = IAC; c[1] = ack; c[2] = option; write(telfdout, c, 3);**/ } #endif static void respond_really(int ack, int option) { unsigned char c[3]; c[0] = IAC; c[1] = ack; c[2] = option; write(telfdout, c, 3); }
Commit message
This repository is read-only for this account.
Repository snapshot
Current branch
master
Visibility
public
Your access
Read
Remote
Configured
File activity
View file history