Usermode/automounter - Added automounter
[tpg/acess2.git] / Usermode / Applications / telnetd_src / main.c
1 /*
2  * Acess2 Telnet Server (TCP server test case)
3  * - By John Hodge (thePowersGang)
4  *
5  * main.c
6  * - All
7  */
8 #include <stddef.h>
9 #include <net.h>
10 #include <stdio.h>
11 #include <stdlib.h>
12 #include <acess/sys.h>
13
14 // === TYPES ===
15 typedef struct sClient
16 {
17          int    Socket;
18          int    stdout;
19          int    stdin;
20 } tClient;
21
22 // === PROTOTYPES ===
23 void    EventLoop(void);
24 void    Server_NewClient(int FD);
25 void    HandleServerBoundData(tClient *Client);
26 void    HandleClientBoundData(tClient *Client);
27
28 // === GLOBALS ===
29 // --- Configuration ---
30  int    giConfig_MaxClients = 5;
31 // --- State ---
32  int    giServerFD;
33 tClient *gaClients;
34  int    giNumClients;
35
36 // === CODE ===
37 int main(int argc, char *argv[])
38 {
39         // TODO: Configure
40
41         // Initialise
42         gaClients = calloc(giConfig_MaxClients, sizeof(tClient));
43
44         // Open server
45         {
46                 uint8_t data[16];
47                  int    addrtype = Net_ParseAddress("10.0.2.10", data);
48                  int    port = 23;
49                 giServerFD = Net_OpenSocket(addrtype, data, "tcps");
50                 _SysIOCtl(giServerFD, 4, &port);        // Set port and start listening
51         }
52
53         // Event loop
54         EventLoop();
55         
56         return 0;
57 }
58
59 static void FD_SET_MAX(fd_set *set, int fd, int *maxfd)
60 {
61         FD_SET(fd, set);
62         if(*maxfd < fd) *maxfd = fd;
63 }
64
65 void EventLoop(void)
66 {
67         fd_set  fds;
68          int    maxfd;
69
70         for( ;; )
71         {
72                 FD_ZERO(&fds);
73                 maxfd = 0;
74                 // Fill select
75                 FD_SET_MAX(&fds, giServerFD, &maxfd);
76                 for( int i = 0; i < giConfig_MaxClients; i ++ )
77                 {
78                         if( gaClients[i].Socket == 0 )  continue ;
79                         _SysDebug("Socket = %i, stdout = %i",
80                                 gaClients[i].Socket, gaClients[i].stdout);
81                         FD_SET_MAX(&fds, gaClients[i].Socket, &maxfd);
82                         FD_SET_MAX(&fds, gaClients[i].stdout,  &maxfd);
83                 }
84                 
85                 // Select!
86                 _SysSelect( maxfd+1, &fds, NULL, NULL, NULL, 0 );
87                 
88                 // Check events
89                 if( FD_ISSET(giServerFD, &fds) )
90                 {
91                         Server_NewClient(giServerFD);
92                 }
93                 for( int i = 0; i < giConfig_MaxClients; i ++ )
94                 {
95                         if( FD_ISSET(gaClients[i].Socket, &fds) )
96                         {
97                                 // Handle client data
98                                 HandleServerBoundData(&gaClients[i]);
99                         }
100                         if( FD_ISSET(gaClients[i].stdout, &fds) )
101                         {
102                                 // Handle output from terminal
103                                 HandleClientBoundData(&gaClients[i]);
104                         }
105                 }
106         }
107 }
108
109 void Server_NewClient(int FD)
110 {
111         tClient *clt;
112         
113         // TODO: Is this done in the IPStack?
114         if( giNumClients == giConfig_MaxClients )
115         {
116                 // Open, reject
117                 _SysClose( _SysOpenChild(FD, "", OPENFLAG_READ) );
118                 return ;
119         }
120         
121         // Allocate client structure and open socket
122         for( int i = 0; i < giConfig_MaxClients; i ++ )
123         {
124                 if( gaClients[i].Socket == 0 ) {
125                         clt = &gaClients[i];
126                         break;
127                 }
128         }
129         // Accept the connection
130         clt->Socket = _SysOpenChild(FD, "", OPENFLAG_READ|OPENFLAG_WRITE);
131         giNumClients ++;
132         
133         // Create stdin/stdout
134         clt->stdin = _SysOpen("/Devices/fifo/anon", OPENFLAG_READ|OPENFLAG_WRITE);
135         clt->stdout = _SysOpen("/Devices/fifo/anon", OPENFLAG_READ|OPENFLAG_WRITE);
136         
137         // TODO: Arguments and envp
138         {
139                 int fds[3] = {clt->stdin, clt->stdout, clt->stdout};
140                 const char      *argv[] = {NULL};
141                 _SysSpawn("/Acess/SBin/login", argv, argv, 3, fds, NULL);
142         }
143 }
144
145 void HandleServerBoundData(tClient *Client)
146 {
147         char    buf[BUFSIZ];
148          int    len;
149         
150         len = _SysRead(Client->Socket, buf, BUFSIZ);
151         if( len <= 0 )  return ;
152         _SysWrite(Client->stdin, buf, len);
153 }
154
155 void HandleClientBoundData(tClient *Client)
156 {
157         char    buf[BUFSIZ];
158          int    len;
159         
160         len = _SysRead(Client->stdout, buf, BUFSIZ);
161         if( len <= 0 )  return ;
162         _SysWrite(Client->Socket, buf, len);
163 }
164

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