Ejemplo n.º 1
0
void AxWin3_int_SendIPCMessage(tAxWin_IPCMessage *Msg)
{
	 int	size = sizeof(tAxWin_IPCMessage) + Msg->Size;
	switch(giConnectionType)
	{
	case CONNTYPE_SENDMESSAGE:
		_SysSendMessage(giConnectionNum, size, Msg);
		break;
	case CONNTYPE_UDP: {
		// Create UDP header
		char	tmpbuf[giAxWin3_int_UDPHeaderLen + size];
		memcpy(tmpbuf, gaAxWin3_int_UDPHeader, giAxWin3_int_UDPHeaderLen);
		memcpy(tmpbuf + giAxWin3_int_UDPHeaderLen, Msg, size);
		size_t rv = _SysWrite(giConnectionNum, tmpbuf, sizeof(tmpbuf));
		if( rv == -1 ) {
			_SysDebug("AxWin3 SendIPCMessage: UDP Write Failed %s", strerror(errno));
			exit(1);
		}
		}
		break;
	case CONNTYPE_IPCPIPE:
	case CONNTYPE_TCP: {
		size_t rv = _SysWrite(giConnectionNum, Msg, size);
		if( rv != size ) {
			_SysDebug("AxWin3 SendIPCMessage: Write Failed %s - sent %i want %i",
				strerror(errno), rv, size);
			exit(1);
		}
		}
		break;
	default:
		break;
	}
}
Ejemplo n.º 2
0
int _fflush_int(FILE *fp)
{
	 int	ret = 0;
	size_t	len;
	
	// Check the buffer contains data
	if( fp->BufferPos == 0 )
		return 0;
	
	switch(fp->Flags & FILE_FLAG_MODE_MASK)
	{
	// Read - Flush input buffer
	case FILE_FLAG_MODE_READ:
		fp->BufferPos = 0;
		break;
	
	// Append - Seek to end and write
	case FILE_FLAG_MODE_APPEND:
		_SysSeek(fp->FD, fp->BufferOfs, SEEK_SET);
		len = _SysWrite(fp->FD, fp->Buffer, fp->BufferPos);
		if( len != fp->BufferPos )
			ret = 1;
		if( len <= fp->BufferPos )
		{
			fp->BufferPos -= len;
		}
		fp->BufferOfs = _SysTell(fp->FD);
		break;
		
	// Write - Write buffer
	case FILE_FLAG_MODE_WRITE:
		//_SysDebug("Flushing to %i '%.*s'", fp->FD, fp->BufferPos, fp->Buffer);
		len = _SysWrite(fp->FD, fp->Buffer, fp->BufferPos);
		if( len != fp->BufferPos )
			ret = 1;
		if( len <= fp->BufferPos )
		{
			fp->BufferPos -= len;
		}
		//else {
		//	_SysDebug("Flush of %i failed, %s", fp->FD, strerror(errno));
		//}
		break;
	default:
		break;
	}
	return ret;
}
Ejemplo n.º 3
0
bool ACurses_GetDims_SerialTermHack(void)
{
	_SysDebug("ACurses_GetDims_SerialTermHack: Trying");
	// Set cursor to 1000,1000 , request cursor position, reset cursor to 0,0
	static const char req[] = "\033[1000;1000H\033[6n\033[H";
	fflush(stdin);
	_SysWrite(1, req, sizeof(req));
	int64_t timeout = 1000;
	fd_set fds;
	FD_ZERO(&fds);
	FD_SET(0, &fds);
	_SysSelect(1, &fds, NULL, NULL, &timeout, 0);
	if( !FD_ISSET(0, &fds) )
		return false;
	
	if( fgetc(stdin) != '\x1b' )
		return false;
	if( fgetc(stdin) != '[' )
		return false;
	if( fscanf(stdin, "%i;%i", &giTerminal_Width, &giTerminal_Height) != 2 )
		return false;
	if( fgetc(stdin) != 'R' )
		return false;
	
	return true;
}
Ejemplo n.º 4
0
size_t _fwrite_unbuffered(FILE *fp, size_t size, size_t num, const void *data)
{
	size_t	ret = 0, bytes;
	while( num -- )
	{
		bytes = _SysWrite(fp->FD, data, size);
		if( bytes == (size_t)-1 ) {
			// Oops.
			// TODO: Set error flag
			break;
		}
		if( bytes != size ) {
			_SysDebug("_fwrite_unbuffered: Oops, rollback %i/%i bytes!", bytes, size);
			_SysSeek(fp->FD, -bytes, SEEK_CUR);
			break;
		}
		data = (char*)data + size;
	}
	fp->Pos += ret * size;
	return ret;
}
Ejemplo n.º 5
0
// === CODE ===
int main(int argc, char *argv[], const char **envp)
{
    AxWin3_Connect(NULL);

    // --- Build up window
    gMainWindow = AxWin3_RichText_CreateWindow(NULL, AXWIN3_RICHTEXT_READONLY);
    AxWin3_SetWindowTitle(gMainWindow, "Terminal");	// TODO: Update title with other info

    gMenuWindow = AxWin3_Menu_Create(gMainWindow);
    AxWin3_Menu_AddItem(gMenuWindow, "Copy\tWin+C", NULL, NULL, 0, NULL);
    AxWin3_Menu_AddItem(gMenuWindow, "Paste\tWin+V", NULL, NULL, 0, NULL);
    // TODO: Populate menu


    // TODO: Tabs?

    AxWin3_RichText_SetKeyHandler	(gMainWindow, Term_KeyHandler);
    AxWin3_RichText_SetMouseHandler	(gMainWindow, Term_MouseHandler);
    AxWin3_RichText_SetDefaultColour(gMainWindow, 0xFFFFFF);
    AxWin3_RichText_SetBackground   (gMainWindow, 0x000000);
    AxWin3_RichText_SetFont		(gMainWindow, "#monospace", 10);
    AxWin3_RichText_SetCursorPos	(gMainWindow, 0, 0);
    AxWin3_RichText_SetCursorType	(gMainWindow, AXWIN3_RICHTEXT_CURSOR_INV);
    AxWin3_RichText_SetCursorBlink	(gMainWindow, 1);

    tTerminal *term = Display_Init(80, 25, 100);
    AxWin3_ResizeWindow(gMainWindow, 80*8, 25*16);
    AxWin3_MoveWindow(gMainWindow, 20, 50);
    AxWin3_ShowWindow(gMainWindow, 1);
    AxWin3_FocusWindow(gMainWindow);

    // Create PTY
    giPTYHandle = _SysOpen("/Devices/pts/ptmx", OPENFLAG_READ|OPENFLAG_WRITE);
    if( giPTYHandle < 0 ) {
        perror("Unable to create/open PTY");
        _SysDebug("Unable to create/open PTY: %s", strerror(errno));
        return -1;
    }
    // - Initialise
    {
        _SysIOCtl(giPTYHandle, PTY_IOCTL_SETID, "gui0");
        struct ptymode	mode = {.InputMode = PTYIMODE_CANON|PTYIMODE_ECHO, .OutputMode=0};
        struct ptydims	dims = {.W = 80, .H = 25};
        _SysIOCtl(giPTYHandle, PTY_IOCTL_SETMODE, &mode);
        _SysIOCtl(giPTYHandle, PTY_IOCTL_SETDIMS, &dims);
    }

    // Spawn shell
    {
        int	fd = _SysOpen("/Devices/pts/gui0", OPENFLAG_READ|OPENFLAG_WRITE);
        int	fds[] = {fd, fd, fd};
        const char	*argv[] = {"CLIShell", NULL};
        int pid = _SysSpawn("/Acess/Bin/CLIShell", argv, envp, 3, fds, NULL);
        if( pid < 0 )
            _SysDebug("ERROR: Shell spawn failed: %s", strerror(errno));
        _SysIOCtl(fd, PTY_IOCTL_SETPGRP, &pid);
        _SysClose(fd);
    }

    // Main loop
    for( ;; )
    {
        fd_set	fds;

        FD_ZERO(&fds);
        FD_SET(giPTYHandle, &fds);
        AxWin3_MessageSelect(giPTYHandle + 1, &fds);

        if( FD_ISSET(giPTYHandle, &fds) )
        {
            _SysDebug("Activity on child stdout");
            // Read and update screen
            char	buf[512];
            int len = _SysRead(giPTYHandle, buf, sizeof(buf));
            if( len <= 0 )	break;

            Term_HandleOutput(term, len, buf);
        }
    }

    return 0;
}

int Term_KeyHandler(tHWND Window, int bPress, uint32_t KeySym, uint32_t Translated)
{
    static int	ctrl_state = 0;

    // Handle modifiers
#define _bitset(var,bit,set) do{if(set)var|=1<<(bit);else var&=~(1<<(bit));}while(0)
    switch(KeySym)
    {
    case KEYSYM_LEFTCTRL:
        _bitset(ctrl_state, 0, bPress!=0);
        return 0;
    case KEYSYM_RIGHTCTRL:
        _bitset(ctrl_state, 1, bPress!=0);
        return 0;
    }
#undef _bitset

    // Handle shortcuts
    // - Ctrl-A -- Ctrl-Z
    if( ctrl_state && KeySym >= KEYSYM_a && KeySym <= KEYSYM_z )
    {
        Translated = KeySym - KEYSYM_a + 1;
        _SysDebug("Ctrl-%c: KS %x => Trans %x", 'A'+(KeySym-KEYSYM_a), KeySym, Translated);
    }

    // == 2 :: FIRE
    if( bPress == 2 )
    {
        if( Translated )
        {
            char	buf[6];
            int	len;

            // Encode and send
            len = WriteUTF8(buf, Translated);

            _SysDebug("Keystroke %x:%x translated to '%.*s'", KeySym, Translated, len, buf);
            _SysWrite(giPTYHandle, buf, len);

            return 0;
        }

        // No translation, look for escape sequences to send
        const char *str = NULL;
        switch(KeySym)
        {
        case KEYSYM_LEFTARROW:
            str = "\x1b[D";
            break;
        case KEYSYM_RIGHTARROW:
            str = "\x1b[C";
            break;
        case KEYSYM_UPARROW:
            str = "\x1b[A";
            break;
        case KEYSYM_DOWNARROW:
            str = "\x1b[B";
            break;
        }
        if( str )
        {
            _SysWrite(giPTYHandle, str, strlen(str));
        }
    }
    return 0;
}

int Term_MouseHandler(tHWND Window, int bPress, int Button, int Row, int Col)
{
    return 0;
}

void Term_HandleOutput(tTerminal *Term, int Len, const char *Buf)
{
    // TODO: Handle graphical / accelerated modes

    //_SysDebug("Term_HandleOutput: %i \"%.*s\"", Len, Len, Buf);

    int	ofs = 0;
    int	esc_len = 0;

    while( ofs < Len )
    {
        esc_len = Term_HandleVT100(Term, Len - ofs, Buf + ofs);
        if( esc_len < 0 ) {
            Display_AddText(Term, -esc_len, Buf + ofs);
            esc_len = -esc_len;
        }
        ofs += esc_len;
        //_SysDebug("Len = %i, ofs = %i", Len, ofs);
    }

    Display_Flush(Term);
}
Ejemplo n.º 6
0
void Server_NewClient(int FD)
{
	tClient	*clt = NULL;
	
	// TODO: Is this done in the IPStack?
	if( giNumClients == giConfig_MaxClients )
	{
		// Open, reject
		_SysClose( _SysOpenChild(FD, "", OPENFLAG_READ) );
		return ;
	}
	
	// Allocate client structure and open socket
	for( int i = 0; i < giConfig_MaxClients; i ++ )
	{
		if( gaClients[i].Socket == 0 ) {
			clt = &gaClients[i];
			break;
		}
	}
	assert(clt);
	// Accept the connection
	clt->Socket = _SysOpenChild(FD, "", OPENFLAG_READ|OPENFLAG_WRITE);
	giNumClients ++;
	
	// Create PTY
	// TODO: Use PTYs
	clt->pty = _SysOpen("/Devices/pts/ptmx", OPENFLAG_READ|OPENFLAG_WRITE);
	if( clt->pty < 0 ) {
		perror("Unable to create/open PTY");
		_SysDebug("Unable to create/open PTY: %s", strerror(errno));
		_SysClose(clt->Socket);
		clt->Socket = 0;
		return ;
	}
	// - Initialise
	{
		_SysIOCtl(clt->pty, PTY_IOCTL_SETID, "telnetd#");
		struct ptymode	mode = {.InputMode = 0, .OutputMode=0};
		struct ptydims	dims = {.W = 80, .H = 25};
		_SysIOCtl(clt->pty, PTY_IOCTL_SETMODE, &mode);
		_SysIOCtl(clt->pty, PTY_IOCTL_SETDIMS, &dims);
	}
	
	// TODO: Arguments and envp
	{
		char pty_path[] = "/Devices/pts/telnetd000";
		_SysIOCtl(clt->pty, PTY_IOCTL_GETID, pty_path+13);
		 int	clientfd = _SysOpen(pty_path, OPENFLAG_READ|OPENFLAG_WRITE);
		if(clientfd < 0) {
			perror("Unable to open login PTY");
			_SysClose(clt->Socket);
			_SysClose(clt->pty);
			clt->Socket = 0;
			return ;
		}
		_SysDebug("Using client PTY %s", pty_path);
		int fds[3] = {clientfd, clientfd, clientfd};
		const char	*argv[] = {"login", NULL};
		_SysSpawn("/Acess/SBin/login", argv, argv, 3, fds, NULL);
		_SysClose(clientfd);
	}
}

void HandleServerBoundData(tClient *Client)
{
	uint8_t	buf[BUFSIZ];
	size_t	len;

	_SysDebug("Client %p", Client);	
	len = _SysRead(Client->Socket, buf, BUFSIZ);
	_SysDebug("%i bytes for %p", len, Client);
	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
				_SysDebug("End Subnegotiation");
				break;
			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
				break;
			case 250:	// Subnegotation
				_SysDebug("Subnegotiation");
				// TODO: Get option ID, and then cache until 'END SB' (240)
				Client->Mode = MODE_SUBNEG_OPTION;
				break;
			case 251:	// WILL
				Client->Mode = MODE_WILL;
				break;
			case 252:	// WONT
				Client->Mode = MODE_WONT;
				break;
			case 253:	// DO
				Client->Mode = MODE_DO;
				break;
			case 254:	// DONT
				Client->Mode = MODE_DONT;
				break;
			case 255:	// Literal 255
				_SysWrite(Client->pty, buf+i, 1);
				break;
			}
			break;
		case MODE_WILL:
			_SysDebug("Option %i WILL", buf[i]);
			HandleOptionRequest(Client, buf[i], true, false);
			Client->Mode = MODE_DATA;
			break;
		case MODE_WONT:
			_SysDebug("Option %i WONT", buf[i]);
			HandleOptionRequest(Client, buf[i], false, false);
			Client->Mode = MODE_DATA;
			break;
		case MODE_DO:
			_SysDebug("Option %i DO", buf[i]);
			HandleOptionRequest(Client, buf[i], true, true);
			Client->Mode = MODE_DATA;
			break;
		case MODE_DONT:
			_SysDebug("Option %i DONT", buf[i]);
			HandleOptionRequest(Client, buf[i], false, true);
			Client->Mode = MODE_DATA;
			break;
		case MODE_SUBNEG_OPTION:
			_SysDebug("Option %i subnegotation", buf[i]);
			Client->Mode = MODE_SUBNEG_DATA;
			break;
		case MODE_SUBNEG_IAC:
			switch(buf[i])
			{
			case 240:	// End subnegotation
				// TODO: Handle subnegotation data
				Client->Mode = MODE_DATA;
				break;
			case 255:
				// TODO: Literal 255
				Client->Mode = MODE_SUBNEG_DATA;
				break;
			default:
				_SysDebug("Unexpected %i in SUBNEG IAC", buf[i]);
				Client->Mode = MODE_SUBNEG_DATA;
				break;
			}
		case MODE_SUBNEG_DATA:
			if( buf[i] == 255 )
				Client->Mode = MODE_SUBNEG_IAC;
			else
				;//_SysWrite(Client->pty, buf+i, 1);
			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->pty, buf, BUFSIZ);
	if( len <= 0 )	return ;
	_SysWrite(Client->Socket, buf, len);
}
Ejemplo n.º 7
0
Archivo: main.c Proyecto: berkus/acess2
int Readline_int_ParseCharacter(tReadline *Info, char *Input)
{
	 int	ofs = 0;
	char	ch;
	
	if( Input[ofs] == 0 )	return 0;
	
	// Read In Command Line
	ch = Input[ofs++];
	
	if(ch == '\n')
	{
//		printf("\n");
		if(Info->CurBuffer)
		{	
			// Cap String
			Info->CurBuffer[Info->BufferUsed] = '\0';
			
			if( Info->UseHistory )
				Readline_int_AddToHistory(Info, Info->CurBuffer);
			Info->OutputValue = strdup(Info->CurBuffer);
		}
		else
			Info->OutputValue = strdup("");
		
		// Save and reset
		Info->BufferSize = 0;
		Info->BufferUsed = 0;
		Info->BufferWritePos = 0;
		Info->CurBuffer = 0;
		Info->HistoryPos = Info->NumHistory - 1;
		
		return 1;
	}
	
	switch(ch)
	{
	// Control characters
	case '\x1B':
		ch = Input[ofs++];	// Read control character
		switch(ch)
		{
		//case 'D':	if(pos)	pos--;	break;
		//case 'C':	if(pos<len)	pos++;	break;
		case '[':
			ch = Input[ofs++];	// Read control character
			switch(ch)
			{
			case 'A':	// Up
				{
					 int	oldLen = Info->BufferUsed;
					 int	pos;
					if( Info->HistoryPos <= 0 )	break;
					
					// Move to the beginning of the line
					pos = oldLen;
					while(pos--)	_SysWrite(STDOUT_FD, "\x1B[D", 3);
					
					// Update state
					Info->CurBuffer = Info->History[--Info->HistoryPos];
					Info->BufferSize = Info->BufferUsed = strlen(Info->CurBuffer);
					
					_SysWrite(STDOUT_FD, Info->CurBuffer, Info->BufferUsed);
					Info->BufferWritePos = Info->BufferUsed;
					
					// Clear old characters (if needed)
					if( oldLen > Info->BufferWritePos ) {
						pos = oldLen - Info->BufferWritePos;
						while(pos--)	_SysWrite(STDOUT_FD, " ", 1);
						pos = oldLen - Info->BufferWritePos;
						while(pos--)	_SysWrite(STDOUT_FD, "\x1B[D", 3);
					}
				}
				break;
			case 'B':	// Down
				{
					 int	oldLen = Info->BufferUsed;
					 int	pos;
					if( Info->HistoryPos >= Info->NumHistory - 1 )	break;
					
					// Move to the beginning of the line
					pos = oldLen;
					while(pos--)	_SysWrite(STDOUT_FD, "\x1B[D", 3);
					
					// Update state
					Info->CurBuffer = Info->History[Info->HistoryPos++];
					Info->BufferSize = Info->BufferUsed = strlen(Info->CurBuffer);
					
					// Write new line
					_SysWrite(STDOUT_FD, Info->CurBuffer, Info->BufferUsed);
					Info->BufferWritePos = Info->BufferUsed;
					
					// Clear old characters (if needed)
					if( oldLen > Info->BufferWritePos ) {
						pos = oldLen - Info->BufferWritePos;
						while(pos--)	_SysWrite(STDOUT_FD, " ", 1);
						pos = oldLen - Info->BufferWritePos;
						while(pos--)	_SysWrite(STDOUT_FD, "\x1B[D", 3);
					}
				}
				break;
			case 'D':	// Left
				if(Info->BufferWritePos == 0)	break;
				Info->BufferWritePos --;
				_SysWrite(STDOUT_FD, "\x1B[D", 3);
				break;
			case 'C':	// Right
				if(Info->BufferWritePos == Info->BufferUsed)	break;
				Info->BufferWritePos ++;
				_SysWrite(STDOUT_FD, "\x1B[C", 3);
				break;
			}
			break;
		case '\0':
			ofs --;
			break;
		}
		break;
	
	// Backspace
	case '\b':
		if(Info->BufferWritePos <= 0)	break;	// Protect against underflows
		// Write the backsapce
		_SysWrite(STDOUT_FD, &ch, 1);
		if(Info->BufferWritePos == Info->BufferUsed)	// Simple case: End of string
		{
			Info->BufferUsed --;
			Info->BufferWritePos --;
		}
		else
		{
			// Have to delete the character, and reposition the text
			char	buf[7] = "\x1B[000D";
			 int	delta = Info->BufferUsed - Info->BufferWritePos + 1;
			buf[2] += (delta/100) % 10;
			buf[3] += (delta/10) % 10;
			buf[4] += (delta) % 10;
			// Write everything save for the deleted character
			_SysWrite(STDOUT_FD,
				&Info->CurBuffer[Info->BufferWritePos],
				Info->BufferUsed - Info->BufferWritePos
				);
			ch = ' ';	_SysWrite(STDOUT_FD, &ch, 1);	ch = '\b';	// Clear old last character
			_SysWrite(STDOUT_FD, buf, 7);	// Update Cursor
			// Alter Buffer
			memmove(&Info->CurBuffer[Info->BufferWritePos-1],
				&Info->CurBuffer[Info->BufferWritePos],
				Info->BufferUsed-Info->BufferWritePos
				);
			Info->BufferWritePos --;
			Info->BufferUsed --;
		}
		break;
	
	// Tab
	case '\t':
		//TODO: Implement Tab-Completion
		//Currently just ignore tabs
		break;
	
	default:		
		// Expand Buffer
		if(Info->BufferUsed + 1 > Info->BufferSize)
		{
			Info->BufferSize += 256;
			Info->CurBuffer = Info->History[Info->HistoryPos]
				= realloc(Info->CurBuffer, Info->BufferSize);
			if(!Info->CurBuffer)	return 0;
		}
		
		// Editing inside the buffer
		if(Info->BufferWritePos < Info->BufferUsed) {
			char	buf[7] = "\x1B[000D";
			 int	delta = Info->BufferUsed - Info->BufferWritePos;
			buf[2] += (delta/100) % 10;
			buf[3] += (delta/10) % 10;
			buf[4] += (delta) % 10;
			_SysWrite(STDOUT_FD, &ch, 1);	// Print new character
			_SysWrite(STDOUT_FD,
				&Info->CurBuffer[Info->BufferWritePos],
				Info->BufferUsed - Info->BufferWritePos
				);
			_SysWrite(STDOUT_FD, buf, 7);	// Update Cursor
			// Move buffer right
			memmove(
				&Info->CurBuffer[Info->BufferWritePos+1],
				&Info->CurBuffer[Info->BufferWritePos],
				Info->BufferUsed - Info->BufferWritePos
				);
		}
		// Simple append
		else {
			_SysWrite(STDOUT_FD, &ch, 1);
		}
		Info->CurBuffer[ Info->BufferWritePos ++ ] = ch;
		Info->BufferUsed ++;
		break;
	}
	
	return ofs;
}