Merge branch 'master' of git://cadel.mutabah.net/acess2
authorJohn Hodge (sonata) <[email protected]>
Thu, 1 Aug 2013 04:07:43 +0000 (12:07 +0800)
committerJohn Hodge (sonata) <[email protected]>
Thu, 1 Aug 2013 04:07:43 +0000 (12:07 +0800)
Conflicts:
Usermode/Applications/telnetd_src/main.c
Usermode/Libraries/libc.so_src/perror.c

1  2 
Usermode/Applications/telnetd_src/main.c
Usermode/Libraries/ld-acess.so_src/include_exp/acess/devices/pty.h
Usermode/Libraries/libc.so_src/Makefile
Usermode/Libraries/libc.so_src/errno.c

  #include <stdio.h>
  #include <stdlib.h>
  #include <acess/sys.h>
+ #include <assert.h>
  
  // === TYPES ===
 +enum eTelnetMode
 +{
 +      MODE_DATA,
 +      MODE_IAC,
 +      MODE_WILL,
 +      MODE_WONT,
 +      MODE_DO,
 +      MODE_DONT
 +};
 +
  typedef struct sClient
  {
 +      enum eTelnetMode        Mode;
         int    Socket;
 -       int    stdout;
 +       int    pty;
+        int    stdin;
++       int    stdout;
  } tClient;
  
  // === PROTOTYPES ===
@@@ -86,10 -77,10 +89,10 @@@ void EventLoop(void
                for( int i = 0; i < giConfig_MaxClients; i ++ )
                {
                        if( gaClients[i].Socket == 0 )  continue ;
 -                      _SysDebug("Socket = %i, stdout = %i",
 -                              gaClients[i].Socket, gaClients[i].stdout);
 +                      _SysDebug("Socket = %i, pty = %i",
 +                              gaClients[i].Socket, gaClients[i].pty);
                        FD_SET_MAX(&fds, gaClients[i].Socket, &maxfd);
 -                      FD_SET_MAX(&fds, gaClients[i].stdout,  &maxfd);
 +                      FD_SET_MAX(&fds, gaClients[i].pty,  &maxfd);
                }
                
                // Select!
                                // Handle client data
                                HandleServerBoundData(&gaClients[i]);
                        }
 -                      if( FD_ISSET(gaClients[i].stdout, &fds) )
 +                      if( FD_ISSET(gaClients[i].pty, &fds) )
                        {
                                // Handle output from terminal
                                HandleClientBoundData(&gaClients[i]);
  
  void Server_NewClient(int FD)
  {
-       tClient *clt;
+       tClient *clt = NULL;
        
        // TODO: Is this done in the IPStack?
        if( giNumClients == giConfig_MaxClients )
                        break;
                }
        }
+       assert(clt);
        // Accept the connection
        clt->Socket = _SysOpenChild(FD, "", OPENFLAG_READ|OPENFLAG_WRITE);
        giNumClients ++;
        
        // Create stdin/stdout
-       // - Current PTY code is strange with mknod
-       clt->pty = _SysOpen("/Devices/pts/telnetd0", OPENFLAG_CREATE|OPENFLAG_READ|OPENFLAG_WRITE);
-       if( clt->pty < 0 ) {
-               perror("Unable to open server PTY");
-               _SysClose(clt->Socket);
-               clt->Socket = 0;
-               return ;
-       }
+       // TODO: Use PTYs
+       clt->stdin = _SysOpen("/Devices/fifo/anon", OPENFLAG_READ|OPENFLAG_WRITE);
+       clt->stdout = _SysOpen("/Devices/fifo/anon", OPENFLAG_READ|OPENFLAG_WRITE);
        
        // TODO: Arguments and envp
        {
 -              int fds[3] = {clt->stdin, clt->stdout, clt->stdout};
 -              const char      *argv[] = {NULL};
 +               int    clientfd = _SysOpen("/Devices/pts/telnetd0c", OPENFLAG_READ|OPENFLAG_WRITE);
 +              if(clientfd < 0) {
 +                      perror("Unable to open login PTY");
 +                      _SysClose(clt->Socket);
 +                      _SysClose(clt->pty);
 +                      clt->Socket = 0;
 +                      return ;
 +              }
 +              int fds[3] = {clientfd, clientfd, clientfd};
 +              const char      *argv[] = {"login", NULL};
                _SysSpawn("/Acess/SBin/login", argv, argv, 3, fds, NULL);
        }
  }
  
  void HandleServerBoundData(tClient *Client)
  {
 -      char    buf[BUFSIZ];
 -       int    len;
 +      uint8_t buf[BUFSIZ];
 +      size_t  len;
        
        len = _SysRead(Client->Socket, buf, BUFSIZ);
 -      if( len <= 0 )  return ;
 -      _SysWrite(Client->stdin, buf, len);
 +      if( len == 0 )  return ;
 +      if( len == -1 ) {
 +              return ;
 +      }
 +      // handle options
 +       int    last_flush = 0;
 +      for( int i = 0; i < len; i ++ )
 +      {
 +              switch(Client->Mode)
 +              {
 +              case MODE_IAC:
 +                      Client->Mode = MODE_DATA;
 +                      switch(buf[i])
 +                      {
 +                      case 240:       // End of subnegotiation parameters
 +                      case 241:       // Nop
 +                              break;
 +                      case 242:       // SYNCH
 +                      case 243:       // NVT Break
 +                      case 244:       // Function 'IP' (Ctrl-C)
 +                              
 +                              break;
 +                      case 245:       // Function 'AO'
 +                      case 246:       // Function 'AYT'
 +                      case 247:       // Function 'EC'
 +                      case 248:       // Function 'EL'
 +                      case 249:       // GA Signal
 +                      case 250:       // Subnegotation
 +                              break;
 +                      case 251:       // WILL
 +                              Client->Mode = MODE_WILL;
 +                              break;
 +                      case 252:       // WONT
 +                              Client->Mode = MODE_WILL;
 +                              break;
 +                      case 253:       // DO
 +                              Client->Mode = MODE_WILL;
 +                              break;
 +                      case 254:       // DONT
 +                              Client->Mode = MODE_WILL;
 +                              break;
 +                      case 255:       // Literal 255
 +                              Client->Mode = MODE_DATA;
 +                              i --;   // hacky!
 +                              break;
 +                      }
 +                      break;
 +              case MODE_WILL:
 +                      _SysDebug("Option %i WILL", buf[i]);
 +                      Client->Mode = MODE_DATA;
 +                      break;
 +              case MODE_WONT:
 +                      _SysDebug("Option %i WONT", buf[i]);
 +                      Client->Mode = MODE_DATA;
 +                      break;
 +              case MODE_DO:
 +                      _SysDebug("Option %i DO", buf[i]);
 +                      Client->Mode = MODE_DATA;
 +                      break;
 +              case MODE_DONT:
 +                      _SysDebug("Option %i DONT", buf[i]);
 +                      Client->Mode = MODE_DATA;
 +                      break;
 +              case MODE_DATA:
 +                      if( buf[i] == 255 )
 +                              Client->Mode = MODE_IAC;
 +                      else
 +                              _SysWrite(Client->pty, buf+i, 1);
 +                      break;
 +              }
 +      }
  }
  
  void HandleClientBoundData(tClient *Client)
        char    buf[BUFSIZ];
         int    len;
        
 -      len = _SysRead(Client->stdout, buf, BUFSIZ);
 +      len = _SysRead(Client->pty, buf, BUFSIZ);
        if( len <= 0 )  return ;
        _SysWrite(Client->Socket, buf, len);
  }
  
  #include "../devices.h"
  
 -#define PTYIMODE_CANON        0x001
 -#define PTYIMODE_ECHO 0x002
 -#define PTYIMODE_RAW  0x004
 +#define PTYSFLAG_ILOCAL       0x001   //!< Input modes are handled in the server process
 +#define PTYSFLAG_SMODE        0x002   //!< Inform server of mode changes by the user
 +
 +#define PTYIMODE_CANON        0x001   //!< Line-buffered input
 +#define PTYIMODE_ECHO 0x002   //!< Echo input characters
 +#define PTYIMODE_RAW  0x004   //!< Disable all input processing
  
  #define PTYOMODE_BUFFMT       0x003
  #define PTYBUFFMT_TEXT         0x000
@@@ -48,6 -45,7 +48,7 @@@ enu
        PTY_IOCTL_GETDIMS,
        PTY_IOCTL_SETDIMS,
        PTY_IOCTL_GETID,
+       PTY_IOCTL_SETID,
  };
  
  #endif
@@@ -4,20 -4,22 +4,22 @@@
  -include ../Makefile.cfg\r
  \r
  CPPFLAGS += \r
- CFLAGS   += -Werror -Wextra\r
+ CFLAGS   += -Wall -Werror -Wextra\r
  ASFLAGS  +=\r
  LDFLAGS  += -Map map.txt\r
  \r
  INCFILES := stdio.h stdlib.h\r
  \r
  OBJ  = stub.o heap.o stdlib.o env.o stdio.o string.o rand.o\r
 -OBJ += perror.o scanf.o signals.o strtoi.o strtof.o\r
 +OBJ += scanf.o signals.o strtoi.o strtof.o\r
  OBJ += printf.o time.o errno.o\r
  OBJ += arch/$(ARCHDIR).ao\r
  # signals.o\r
  DEPFILES := $(OBJ:%.o=%.d)\r
  BIN = libc.so\r
  ifeq ($(ARCHDIR),native)\r
+  OBJ := $(filter-out heap.o,$(OBJ))\r
+  #LDFLAGS += -l c\r
   BIN = libc_acess.so\r
  endif\r
  \r
@@@ -6,39 -6,59 +6,73 @@@
   * - errno and strerror
   */
  #include "lib.h"
 +#include <stdio.h>
  #include <errno.h>
  #include <acess/sys.h>
+ #include <string.h>
  
  EXPORT int *libc_geterrno()
  {
        return &_errno;
  }
  
- EXPORT const char *strerror(int errnum)
+ EXPORT char *strerror(int errnum)
  {
-       switch(errnum)
+       switch((enum libc_eErrorNumbers)errnum)
        {
+       case EOK:       return "Success";
        case ENOSYS:    return "Invalid instruction/syscall";
+       case EINVAL:    return "Bad argument(s)";
+       case EBADF:     return "Invalid file";
+       case ENOMEM:    return "No free memory";
+       case EACCES:    return "Not permitted";
+       case EBUSY:     return "Resource is busy";
+       case ERANGE:    return "Value out of range";
+       case ENOTFOUND: return "Item not found";
+       case EROFS:     return "Read only filesystem";
+       case ENOTIMPL:  return "Not implimented";
        case ENOENT:    return "No such file or directory";
-       case EINVAL:    return "Bad arguments";
-       case EPERM:     return "Permissions error";
-       default:
-               _SysDebug("strerror: errnum=%i unk", errnum);
-               return "unknown error";
+       case EEXIST:    return "Already exists";
+       case ENFILE:    return "Too many open files";
+       case ENOTDIR:   return "Not a directory";
+       case EISDIR:    return "Is a directory";
+       case EIO:       return "IO Error";
+       case EINTR:     return "Interrupted";
+       case EWOULDBLOCK:       return "Operation would have blocked";
+       case ENODEV:    return "No such device";
+       case EADDRNOTAVAIL:     return "Address not avaliable";
+       case EINPROGRESS:       return "Operation in process";
+       case EPERM:     return "Operation not permitted";
+       case ENOTTY:    return "Not a TTY";
+       case EAGAIN:    return "Try again";
+       case EALREADY:  return "Operation was no-op";
+       case EINTERNAL: return "Internal error";
        }
+       _SysDebug("strerror: errnum=%i unk", errnum);
+       errno = EINVAL;
+       return "unknown error";
+ }
+ EXPORT int strerror_r(int errnum, char *buf, size_t bufsiz)
+ {
+       const char *str = strerror(errnum);
+       if(!str)
+               return -1;
+       
+       strncpy(buf, str, bufsiz);
+       return 0;
  }
  
 +// stdio.h
 +EXPORT void perror(const char *s)
 +{
 +      int err = errno;
 +      if( s && s[0] ) {
 +              fprintf(stderr, "%s: (%i) %s\n", s, err, strerror(err));
 +      }
 +      else {
 +              fprintf(stderr, "(%i) %s\n", err, strerror(err));
 +      }
 +      _SysDebug("perror('%s'): %s (%i)", s, strerror(err), err);
 +}
 +

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