2 * Acess2 Telnet Server (TCP server test case)
3 * - By John Hodge (thePowersGang)
12 #include <acess/sys.h>
25 typedef struct sClient
27 enum eTelnetMode Mode;
34 void Server_NewClient(int FD);
35 void HandleServerBoundData(tClient *Client);
36 void HandleClientBoundData(tClient *Client);
39 // --- Configuration ---
40 int giConfig_MaxClients = 5;
47 int main(int argc, char *argv[])
52 gaClients = calloc(giConfig_MaxClients, sizeof(tClient));
57 int addrtype = Net_ParseAddress("10.0.2.10", data);
59 giServerFD = Net_OpenSocket(addrtype, data, "tcps");
60 _SysIOCtl(giServerFD, 4, &port); // Set port and start listening
69 static void FD_SET_MAX(fd_set *set, int fd, int *maxfd)
72 if(*maxfd < fd) *maxfd = fd;
85 FD_SET_MAX(&fds, giServerFD, &maxfd);
86 for( int i = 0; i < giConfig_MaxClients; i ++ )
88 if( gaClients[i].Socket == 0 ) continue ;
89 _SysDebug("Socket = %i, pty = %i",
90 gaClients[i].Socket, gaClients[i].pty);
91 FD_SET_MAX(&fds, gaClients[i].Socket, &maxfd);
92 FD_SET_MAX(&fds, gaClients[i].pty, &maxfd);
96 _SysSelect( maxfd+1, &fds, NULL, NULL, NULL, 0 );
99 if( FD_ISSET(giServerFD, &fds) )
101 Server_NewClient(giServerFD);
103 for( int i = 0; i < giConfig_MaxClients; i ++ )
105 if( FD_ISSET(gaClients[i].Socket, &fds) )
107 // Handle client data
108 HandleServerBoundData(&gaClients[i]);
110 if( FD_ISSET(gaClients[i].pty, &fds) )
112 // Handle output from terminal
113 HandleClientBoundData(&gaClients[i]);
119 void Server_NewClient(int FD)
123 // TODO: Is this done in the IPStack?
124 if( giNumClients == giConfig_MaxClients )
127 _SysClose( _SysOpenChild(FD, "", OPENFLAG_READ) );
131 // Allocate client structure and open socket
132 for( int i = 0; i < giConfig_MaxClients; i ++ )
134 if( gaClients[i].Socket == 0 ) {
139 // Accept the connection
140 clt->Socket = _SysOpenChild(FD, "", OPENFLAG_READ|OPENFLAG_WRITE);
143 // Create stdin/stdout
144 // - Current PTY code is strange with mknod
145 clt->pty = _SysOpen("/Devices/pts/telnetd0", OPENFLAG_CREATE|OPENFLAG_READ|OPENFLAG_WRITE);
147 perror("Unable to open server PTY");
148 _SysClose(clt->Socket);
153 // TODO: Arguments and envp
155 int clientfd = _SysOpen("/Devices/pts/telnetd0c", OPENFLAG_READ|OPENFLAG_WRITE);
157 perror("Unable to open login PTY");
158 _SysClose(clt->Socket);
163 int fds[3] = {clientfd, clientfd, clientfd};
164 const char *argv[] = {"login", NULL};
165 _SysSpawn("/Acess/SBin/login", argv, argv, 3, fds, NULL);
169 void HandleServerBoundData(tClient *Client)
174 len = _SysRead(Client->Socket, buf, BUFSIZ);
175 if( len == 0 ) return ;
181 for( int i = 0; i < len; i ++ )
186 Client->Mode = MODE_DATA;
189 case 240: // End of subnegotiation parameters
193 case 243: // NVT Break
194 case 244: // Function 'IP' (Ctrl-C)
197 case 245: // Function 'AO'
198 case 246: // Function 'AYT'
199 case 247: // Function 'EC'
200 case 248: // Function 'EL'
201 case 249: // GA Signal
202 case 250: // Subnegotation
205 Client->Mode = MODE_WILL;
208 Client->Mode = MODE_WILL;
211 Client->Mode = MODE_WILL;
214 Client->Mode = MODE_WILL;
216 case 255: // Literal 255
217 Client->Mode = MODE_DATA;
223 _SysDebug("Option %i WILL", buf[i]);
224 Client->Mode = MODE_DATA;
227 _SysDebug("Option %i WONT", buf[i]);
228 Client->Mode = MODE_DATA;
231 _SysDebug("Option %i DO", buf[i]);
232 Client->Mode = MODE_DATA;
235 _SysDebug("Option %i DONT", buf[i]);
236 Client->Mode = MODE_DATA;
240 Client->Mode = MODE_IAC;
242 _SysWrite(Client->pty, buf+i, 1);
248 void HandleClientBoundData(tClient *Client)
253 len = _SysRead(Client->pty, buf, BUFSIZ);
254 if( len <= 0 ) return ;
255 _SysWrite(Client->Socket, buf, len);