BBN-Vax-TCP/src/telnet/process.c

Compare this file to the similar file:
Show the results in this format:

#include "stdio.h"
#include "tnio.h"
#include "globdefs.h"
#include "ttyctl.h"

/* -------------------------- P R O C E S S ------------------------- */
/*
 * Read from input buffer and put in command buffer cline (contained in
 * this routine) or output buffer via telwrite.
 * This routine identifies and executes the user's commands.
 * If the user types the escape char twice, that sends the escape char.
 * If the user types the escape char followed by a newline, the modes are
 * changed to normal. If the user types the escape char
 * followed by anything else, it is just executed without changing tty modes.
 */
process(buf, cnt, connp)
    char * buf;
    int cnt;
    NETCONN * connp;
{
    register char *p;	  /* Points into inbuf */
    static char outbuf[WNETSIZE];     /* Static just to keep stack size down */
    register char *op;	  /* Points into outbuf */
    int c;	      /* Unsigned char */
    int tflags;
    static TTYMODE *oldmode = NULL;
    static int cmdstate = 0;
#	define SENDING 0
#	define GOTESC  1
#	define INCMD   2

    static char cline[256];
    static char *clinep;

    static trunc;
    extern int escape;
    extern int udone;
    extern int termfd;
    extern int inputfd;
    extern int usercr;
    extern int needprompt;

    if (cnt == -1 || cnt == 0)
    {
	udone++;
	return(0);
    }

    op = outbuf;
    for (p = buf; cnt > 0; p++, cnt--)
    {
	int type;
#	    define ORDINARY 10
#	    define CMDBEGIN 20
#	    define CMDEND 30

	if (connp == NULL && cmdstate == SENDING)
	{
	    cmdstate = GOTESC;
	    needprompt = 1;
	}

	c = *p & 0377;

	if ((c&0177) == escape)
	    type = CMDBEGIN;
	else if ((c&0177) == '\n' || (c&0177) == '\r')
	    type = CMDEND;
	else
	    type = ORDINARY;

	switch(type + cmdstate)
	{
	case SENDING + ORDINARY:    /* Send it */
	case SENDING + CMDEND:	    /* Send it */
    xmit:
	    *op++ = c;
	    if (c == '\r' && usercr) {	/* Follow CR with LF */
		*op++ = '\n';
		tflags = GetFlags(CurMode());
		if (tflags&ECHO)	
			echo('\r');
	    }
	    cmdstate = SENDING;
	    break;
	case SENDING + CMDBEGIN:    /* Start of command? */
	    echo(c);
	    cmdstate = GOTESC;
	    break;
	case GOTESC + CMDBEGIN:     /* Doubled command char, send it */
	    if (connp != NULL)
		goto xmit;
	    break;
	case GOTESC + CMDEND:	    /* Line ended with escape, enter cmd mode */
	    echo(c);
	    if (oldmode == NULL)
		oldmode = ChgMode(OrigMode());
	    needprompt = 1;
	    break;
	case GOTESC + ORDINARY:     /* Start of command */
	    clinep = cline;
	    trunc = 0;
	case INCMD + ORDINARY:	    /* Collect command */
	case INCMD + CMDBEGIN:	    /* Collect command */
	    echo(c);
	    if (clinep < &cline[sizeof(cline)])
		*clinep++ = c;
	    else
		trunc = 1;  /* Remember we are losing chars */
	    cmdstate = INCMD;
	    break;
	case INCMD + CMDEND:
	    echo(c);
	    if (oldmode != NULL)
	    {
		ChgMode(oldmode);
		oldmode = NULL;
	    }
	    if (trunc)
		fprintf(stderr, "Command line too long -- ignored.\r\n");
	    else
	    {
/* Flush what we have in case command involves it */
		if (connp != 0 && op - outbuf > 0)
		    telwrite(connp, outbuf, op - outbuf);
		op = outbuf;
/* Ignore initial escape char */
		if (cline[0] == escape)
		    cline[0] = ' ';
/* Execute command */
		cline[clinep-cline] = '\0';
		callcmd(cline);
	    }
	    cmdstate = SENDING;
	    break;
	}
    }
    if (connp != 0 && op - outbuf > 0) 
	telwrite(connp, outbuf, op - outbuf);
    return(0);
}