From: John Hodge (sonata) Date: Thu, 1 Aug 2013 04:07:43 +0000 (+0800) Subject: Merge branch 'master' of git://cadel.mutabah.net/acess2 X-Git-Tag: rel0.15~292^2 X-Git-Url: https://git.ucc.asn.au/?p=tpg%2Facess2.git;a=commitdiff_plain;h=e7a76b0d8a0cc6aa77966509780973a6f8216ef7;hp=-c Merge branch 'master' of git://cadel.mutabah.net/acess2 Conflicts: Usermode/Applications/telnetd_src/main.c Usermode/Libraries/libc.so_src/perror.c --- e7a76b0d8a0cc6aa77966509780973a6f8216ef7 diff --combined Usermode/Applications/telnetd_src/main.c index 6ef832f3,05268011..7fac367b --- a/Usermode/Applications/telnetd_src/main.c +++ b/Usermode/Applications/telnetd_src/main.c @@@ -10,23 -10,14 +10,26 @@@ #include #include #include + #include // === 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! @@@ -107,7 -98,7 +110,7 @@@ // 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]); @@@ -118,7 -109,7 +121,7 @@@ void Server_NewClient(int FD) { - tClient *clt; + tClient *clt = NULL; // TODO: Is this done in the IPStack? if( giNumClients == giConfig_MaxClients ) @@@ -136,113 -127,32 +139,109 @@@ 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) @@@ -250,7 -160,7 +249,7 @@@ 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); } diff --combined Usermode/Libraries/ld-acess.so_src/include_exp/acess/devices/pty.h index 13dbdb8d,9c243ce0..137b86fb --- a/Usermode/Libraries/ld-acess.so_src/include_exp/acess/devices/pty.h +++ b/Usermode/Libraries/ld-acess.so_src/include_exp/acess/devices/pty.h @@@ -11,12 -11,9 +11,12 @@@ #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 diff --combined Usermode/Libraries/libc.so_src/Makefile index 2c2e62d6,7b345871..6dba912e --- a/Usermode/Libraries/libc.so_src/Makefile +++ b/Usermode/Libraries/libc.so_src/Makefile @@@ -4,20 -4,22 +4,22 @@@ -include ../Makefile.cfg CPPFLAGS += - CFLAGS += -Werror -Wextra + CFLAGS += -Wall -Werror -Wextra ASFLAGS += LDFLAGS += -Map map.txt INCFILES := stdio.h stdlib.h OBJ = stub.o heap.o stdlib.o env.o stdio.o string.o rand.o -OBJ += perror.o scanf.o signals.o strtoi.o strtof.o +OBJ += scanf.o signals.o strtoi.o strtof.o OBJ += printf.o time.o errno.o OBJ += arch/$(ARCHDIR).ao # signals.o DEPFILES := $(OBJ:%.o=%.d) BIN = libc.so ifeq ($(ARCHDIR),native) + OBJ := $(filter-out heap.o,$(OBJ)) + #LDFLAGS += -l c BIN = libc_acess.so endif diff --combined Usermode/Libraries/libc.so_src/errno.c index b4a4f019,a2d78909..7e1905cd --- a/Usermode/Libraries/libc.so_src/errno.c +++ b/Usermode/Libraries/libc.so_src/errno.c @@@ -6,39 -6,59 +6,73 @@@ * - errno and strerror */ #include "lib.h" +#include #include #include + #include 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); +} +