From: John Hodge Date: Thu, 26 Jan 2012 06:23:12 +0000 (+0800) Subject: Usermode/telnetd - Hacking it up :) Needs _SysSpawn implemented to work X-Git-Tag: rel0.15~792^2~13 X-Git-Url: https://git.ucc.asn.au/?a=commitdiff_plain;h=31ca692f6ad721a25a48ef121534e02f6900efaf;p=tpg%2Facess2.git Usermode/telnetd - Hacking it up :) Needs _SysSpawn implemented to work - A related change in TCP server code to reduce expense of accepting a connection --- diff --git a/Modules/IPStack/tcp.c b/Modules/IPStack/tcp.c index 7ba25565..1415deaa 100644 --- a/Modules/IPStack/tcp.c +++ b/Modules/IPStack/tcp.c @@ -914,30 +914,43 @@ tVFS_Node *TCP_Server_FindDir(tVFS_Node *Node, const char *Name) int id = atoi(Name); ENTER("pNode sName", Node, Name); - - // Sanity Check - itoa(tmp, id, 16, 8, '0'); - if(strcmp(tmp, Name) != 0) { - LOG("'%s' != '%s' (%08x)", Name, tmp, id); - LEAVE('n'); - return NULL; + + // Check for a non-empty name + if( Name[0] ) + { + // Sanity Check + itoa(tmp, id, 16, 8, '0'); + if(strcmp(tmp, Name) != 0) { + LOG("'%s' != '%s' (%08x)", Name, tmp, id); + LEAVE('n'); + return NULL; + } + + Log_Debug("TCP", "srv->Connections = %p", srv->Connections); + Log_Debug("TCP", "srv->NewConnections = %p", srv->NewConnections); + Log_Debug("TCP", "srv->ConnectionsTail = %p", srv->ConnectionsTail); + + // Search + SHORTLOCK( &srv->lConnections ); + for(conn = srv->Connections; + conn; + conn = conn->Next) + { + LOG("conn->Node.ImplInt = %i", conn->Node.ImplInt); + if(conn->Node.ImplInt == id) break; + } + SHORTREL( &srv->lConnections ); } - - Log_Debug("TCP", "srv->Connections = %p", srv->Connections); - Log_Debug("TCP", "srv->NewConnections = %p", srv->NewConnections); - Log_Debug("TCP", "srv->ConnectionsTail = %p", srv->ConnectionsTail); - - // Search - SHORTLOCK( &srv->lConnections ); - for(conn = srv->Connections; - conn; - conn = conn->Next) + // Empty Name - Check for a new connection and if it's there, open it + else { - LOG("conn->Node.ImplInt = %i", conn->Node.ImplInt); - if(conn->Node.ImplInt == id) break; + SHORTLOCK( &srv->lConnections ); + conn = srv->NewConnections; + if( conn != NULL ) + srv->NewConnections = conn->Next; + SHORTREL( &srv->lConnections ); } - SHORTREL( &srv->lConnections ); - + // If not found, ret NULL if(!conn) { LOG("Connection %i not found", id); diff --git a/Usermode/Applications/telnetd_src/Makefile b/Usermode/Applications/telnetd_src/Makefile new file mode 100644 index 00000000..a85a0712 --- /dev/null +++ b/Usermode/Applications/telnetd_src/Makefile @@ -0,0 +1,12 @@ +# Project: telnetd + +-include ../Makefile.cfg + +LDFLAGS += -lnet + +OBJ = main.o +BIN = telnetd +DIR = SBin +CFLAGS += -std=c99 + +-include ../Makefile.tpl diff --git a/Usermode/Applications/telnetd_src/main.c b/Usermode/Applications/telnetd_src/main.c new file mode 100644 index 00000000..198ddaaf --- /dev/null +++ b/Usermode/Applications/telnetd_src/main.c @@ -0,0 +1,145 @@ +/* + */ +#include +#include +#include +#include + +// === TYPES === +typedef struct sClient +{ + int Socket; + int stdout; + int stdin; +} tClient; + +// === PROTOTYPES === +void EventLoop(void); +void Server_NewClient(int FD); +void HandleServerBoundData(tClient *Client); +void HandleClientBoundData(tClient *Client); + +// === GLOBALS === +// --- Configuration --- + int giConfig_MaxClients = 5; +// --- State --- + int giServerFD; +tClient *gaClients; + int giNumClients; + +// === CODE === +int main(int argc, char *argv[]) +{ + // TODO: Configure + + // Initialise + gaClients = calloc(giConfig_MaxClients, sizeof(tClient)); + + // Open server + giServerFD = Net_OpenSocket(0, NULL, "tcps"); + + // Event loop + EventLoop(); + + return 0; +} + +void EventLoop(void) +{ + fd_set fds; + int maxfd; + + void FD_SET_MAX(fd_set *set, int fd, int *maxfd) + { + FD_SET(fd, set); + if(*maxfd < fd) *maxfd = fd; + } + + for( ;; ) + { + maxfd = 0; + // Fill select + FD_SET_MAX(&fds, giServerFD, &maxfd); + for( int i = 0; i < giConfig_MaxClients; i ++ ) + { + FD_SET_MAX(&fds, gaClients[i].Socket, &maxfd); + FD_SET_MAX(&fds, gaClients[i].stdout, &maxfd); + } + + // Select! + select( maxfd+1, &fds, NULL, NULL, NULL ); + + // Check events + if( FD_ISSET(giServerFD, &fds) ) + { + Server_NewClient(giServerFD); + } + for( int i = 0; i < giConfig_MaxClients; i ++ ) + { + if( FD_ISSET(gaClients[i].Socket, &fds) ) + { + // Handle client data + HandleServerBoundData(&gaClients[i]); + } + if( FD_ISSET(gaClients[i].stdout, &fds) ) + { + // Handle output from terminal + HandleClientBoundData(&gaClients[i]); + } + } + } +} + +void Server_NewClient(int FD) +{ + tClient *clt; + + // TODO: Is this done in the IPStack? + if( giNumClients == giConfig_MaxClients ) + { + // Open, reject + close( _SysOpenChild(FD, "", O_RDWR) ); + return ; + } + + // Allocate client structure and open socket + for( int i = 0; i < giConfig_MaxClients; i ++ ) + { + if( gaClients[i].Socket == 0 ) { + clt = &gaClients[i]; + break; + } + } + // Accept the connection + clt->Socket = _SysOpenChild(FD, "", O_RDWR); + giNumClients ++; + + // Create stdin/stdout + clt->stdin = open("/Devices/fifo", O_RDWR); + clt->stdout = open("/Devices/fifo", O_RDWR); + + // TODO: Arguments and envp + { + int fds[3] = {clt->stdin, clt->stdout, clt->stdout}; + _SysSpawn("/Acess/SBin/login", NULL, NULL, 3, fds); + } +} + +void HandleServerBoundData(tClient *Client) +{ + char buf[BUFSIZ]; + int len; + + len = read(Client->Socket, buf, BUFSIZ); + write(Client->stdin, buf, len); +} + +void HandleClientBoundData(tClient *Client) +{ + char buf[BUFSIZ]; + int len; + + len = read(Client->stdout, buf, BUFSIZ); + write(Client->Socket, buf, len); +} + diff --git a/Usermode/include/acess/sys.h b/Usermode/include/acess/sys.h index e1a78a7f..2d2b4291 100644 --- a/Usermode/include/acess/sys.h +++ b/Usermode/include/acess/sys.h @@ -47,6 +47,7 @@ extern int _SysWaitEvent(int EventMask); extern int waittid(int id, int *status); extern int clone(int flags, void *stack); extern int execve(char *path, char **argv, char **envp); +extern int _SysSpawn(const char *Path, const char **argv, const char **envp, int nFDs, int *FDs); extern int gettid(void); extern int getpid(void); extern int _SysSetFaultHandler(int (*Handler)(int));