diff --git a/Usermode/Applications/telnetd_src/main.c b/Usermode/Applications/telnetd_src/main.c
index c7f1978c6c9f67af547abc862664d39567273731..fa852506a155637f88c54dbb3d41449922005523 100644
--- a/Usermode/Applications/telnetd_src/main.c
+++ b/Usermode/Applications/telnetd_src/main.c
@@ -13,6 +13,7 @@
 #include <assert.h>
 #include <errno.h>
 #include <acess/devices/pty.h>
+#include <stdbool.h>
 
 // === TYPES ===
 enum eTelnetMode
@@ -22,7 +23,10 @@ enum eTelnetMode
 	MODE_WILL,
 	MODE_WONT,
 	MODE_DO,
-	MODE_DONT
+	MODE_DONT,
+	MODE_SUBNEG_OPTION,
+	MODE_SUBNEG_DATA,
+	MODE_SUBNEG_IAC,
 };
 
 typedef struct sClient
@@ -37,6 +41,7 @@ void	EventLoop(void);
 void	Server_NewClient(int FD);
 void	HandleServerBoundData(tClient *Client);
 void	HandleClientBoundData(tClient *Client);
+void	HandleOptionRequest(tClient *Client, int Option, bool Value, bool IsRequest);
 
 // === GLOBALS ===
 // --- Configuration ---
@@ -94,7 +99,8 @@ void EventLoop(void)
 		}
 		
 		// Select!
-		_SysSelect( maxfd+1, &fds, NULL, NULL, NULL, 0 );
+		int rv = _SysSelect( maxfd+1, &fds, NULL, NULL, NULL, 0 );
+		_SysDebug("Select return %i", rv);
 		
 		// Check events
 		if( FD_ISSET(giServerFD, &fds) )
@@ -154,7 +160,7 @@ void Server_NewClient(int FD)
 	}
 	// - Initialise
 	{
-		_SysIOCtl(clt->pty, PTY_IOCTL_SETID, "telnetd0");
+		_SysIOCtl(clt->pty, PTY_IOCTL_SETID, "telnetd#");
 		struct ptymode	mode = {.InputMode = 0, .OutputMode=0};
 		struct ptydims	dims = {.W = 80, .H = 25};
 		_SysIOCtl(clt->pty, PTY_IOCTL_SETMODE, &mode);
@@ -163,7 +169,9 @@ void Server_NewClient(int FD)
 	
 	// TODO: Arguments and envp
 	{
-		 int	clientfd = _SysOpen("/Devices/pts/telnetd0", OPENFLAG_READ|OPENFLAG_WRITE);
+		char pty_path[] = "/Devices/pts/telnetd000";
+		_SysIOCtl(clt->pty, PTY_IOCTL_GETID, pty_path+13);
+		 int	clientfd = _SysOpen(pty_path, OPENFLAG_READ|OPENFLAG_WRITE);
 		if(clientfd < 0) {
 			perror("Unable to open login PTY");
 			_SysClose(clt->Socket);
@@ -171,9 +179,11 @@ void Server_NewClient(int FD)
 			clt->Socket = 0;
 			return ;
 		}
+		_SysDebug("Using client PTY %s", pty_path);
 		int fds[3] = {clientfd, clientfd, clientfd};
 		const char	*argv[] = {"login", NULL};
 		_SysSpawn("/Acess/SBin/login", argv, argv, 3, fds, NULL);
+		_SysClose(clientfd);
 	}
 }
 
@@ -181,14 +191,16 @@ void HandleServerBoundData(tClient *Client)
 {
 	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;
+	// int	last_flush = 0;
 	for( int i = 0; i < len; i ++ )
 	{
 		switch(Client->Mode)
@@ -215,6 +227,8 @@ void HandleServerBoundData(tClient *Client)
 				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;
@@ -229,27 +243,57 @@ void HandleServerBoundData(tClient *Client)
 				Client->Mode = MODE_DONT;
 				break;
 			case 255:	// Literal 255
-				Client->Mode = MODE_DATA;
-				i --;	// hacky!
+				_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;
@@ -270,3 +314,13 @@ void HandleClientBoundData(tClient *Client)
 	_SysWrite(Client->Socket, buf, len);
 }
 
+void HandleOptionRequest(tClient *Client, int Option, bool Value, bool IsRequest)
+{
+	switch(Option)
+	{
+	default:
+		_SysDebug("Unknown option %i", Option);
+		break;
+	}
+}
+