+ uint8_t buf[BUFSIZ];
+ size_t len;
+
+ _SysDebug("Client %p", Client);
+ len = _SysRead(Client->Socket, buf, BUFSIZ);
+ _SysDebug("%i bytes for %p", len, Client);
+ if( len == 0 ) return ;
+ if( len == -1 ) {
+ return ;
+ }
+ // handle options
+ // int last_flush = 0;
+ for( int i = 0; i < len; i ++ )
+ {
+ switch(Client->Mode)
+ {
+ case MODE_IAC:
+ Client->Mode = MODE_DATA;
+ switch(buf[i])
+ {
+ case 240: // End of subnegotiation parameters
+ _SysDebug("End Subnegotiation");
+ break;
+ case 241: // Nop
+ break;
+ case 242: // SYNCH
+ case 243: // NVT Break
+ case 244: // Function 'IP' (Ctrl-C)
+
+ break;
+ case 245: // Function 'AO'
+ case 246: // Function 'AYT'
+ case 247: // Function 'EC'
+ case 248: // Function 'EL'
+ case 249: // GA Signal
+ break;
+ case 250: // Subnegotation
+ _SysDebug("Subnegotiation");
+ // TODO: Get option ID, and then cache until 'END SB' (240)
+ Client->Mode = MODE_SUBNEG_OPTION;
+ break;
+ case 251: // WILL
+ Client->Mode = MODE_WILL;
+ break;
+ case 252: // WONT
+ Client->Mode = MODE_WONT;
+ break;
+ case 253: // DO
+ Client->Mode = MODE_DO;
+ break;
+ case 254: // DONT
+ Client->Mode = MODE_DONT;
+ break;
+ case 255: // Literal 255
+ _SysWrite(Client->pty, buf+i, 1);
+ break;
+ }
+ break;
+ case MODE_WILL:
+ _SysDebug("Option %i WILL", buf[i]);
+ HandleOptionRequest(Client, buf[i], true, false);
+ Client->Mode = MODE_DATA;
+ break;
+ case MODE_WONT:
+ _SysDebug("Option %i WONT", buf[i]);
+ HandleOptionRequest(Client, buf[i], false, false);
+ Client->Mode = MODE_DATA;
+ break;
+ case MODE_DO:
+ _SysDebug("Option %i DO", buf[i]);
+ HandleOptionRequest(Client, buf[i], true, true);
+ Client->Mode = MODE_DATA;
+ break;
+ case MODE_DONT:
+ _SysDebug("Option %i DONT", buf[i]);
+ HandleOptionRequest(Client, buf[i], false, true);
+ Client->Mode = MODE_DATA;
+ break;
+ case MODE_SUBNEG_OPTION:
+ _SysDebug("Option %i subnegotation", buf[i]);
+ Client->Mode = MODE_SUBNEG_DATA;
+ break;
+ case MODE_SUBNEG_IAC:
+ switch(buf[i])
+ {
+ case 240: // End subnegotation
+ // TODO: Handle subnegotation data
+ Client->Mode = MODE_DATA;
+ break;
+ case 255:
+ // TODO: Literal 255
+ Client->Mode = MODE_SUBNEG_DATA;
+ break;
+ default:
+ _SysDebug("Unexpected %i in SUBNEG IAC", buf[i]);
+ Client->Mode = MODE_SUBNEG_DATA;
+ break;
+ }
+ case MODE_SUBNEG_DATA:
+ if( buf[i] == 255 )
+ Client->Mode = MODE_SUBNEG_IAC;
+ else
+ ;//_SysWrite(Client->pty, buf+i, 1);
+ break;
+
+ case MODE_DATA:
+ if( buf[i] == 255 )
+ Client->Mode = MODE_IAC;
+ else
+ _SysWrite(Client->pty, buf+i, 1);
+ break;
+ }
+ }