Usermode/telnetd - Hacking it up :) Needs _SysSpawn implemented to work
authorJohn Hodge <[email protected]>
Thu, 26 Jan 2012 06:23:12 +0000 (14:23 +0800)
committerJohn Hodge <[email protected]>
Thu, 26 Jan 2012 06:23:12 +0000 (14:23 +0800)
- A related change in TCP server code to reduce expense of accepting a connection

Modules/IPStack/tcp.c
Usermode/Applications/telnetd_src/Makefile [new file with mode: 0644]
Usermode/Applications/telnetd_src/main.c [new file with mode: 0644]
Usermode/include/acess/sys.h

index 7ba2556..1415dea 100644 (file)
@@ -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 (file)
index 0000000..a85a071
--- /dev/null
@@ -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 (file)
index 0000000..198ddaa
--- /dev/null
@@ -0,0 +1,145 @@
+/*
+ */
+#include <stddef.h>
+#include <net.h>
+#include <unistd.h>
+#include <stdio.h>
+
+// === 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);
+}
+
index e1a78a7..2d2b429 100644 (file)
@@ -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));

UCC git Repository :: git.ucc.asn.au