⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 telnetdlib.c

📁 VXWORKS源代码
💻 C
📖 第 1 页 / 共 4 页
字号:
             * REMOTE_STOP if the connection is ever broken.             */            pSlot->loggedIn = TRUE;             }        }    }/********************************************************************************* telnetOutTask - relay output to remote user** This routine transfers data from the registered input/output task to* the remote user. It is the entry point for the output task which is* deleted when the client disconnects.** INTERNAL* * This routine blocks within the read() call until the command interpreter* sends a response. When the telnet server creates all input/output tasks* during startup (i.e. telnetdTaskFlag is TRUE), this routine cannot send* any data to the socket until the primary server task (telnetd) awakens * the input routine.** NOMANUAL* but not LOCAL for i()*/void telnetOutTask    (    TELNETD_SESSION_DATA *pSlot  /* pointer to the connection information */    )    {    FAST int n;    char buf [STDOUT_BUF_SIZE];    int sock;     /* Socket for individual telnet session */    int outputFd; /* Output from command interpreter */    /*     * Wait for a connection if the server creates this task in advance.      */    if (telnetdTaskFlag)  /* static task creation  */        semTake (pSlot->startOutput, WAIT_FOREVER);    sock = pSlot->socket;    outputFd = pSlot->outputFd;    /*     * In the default configuration, the following read loop exits after     * the connection between the client and server ends because closing     * the socket to the remote client causes the input task to close the     * output file descriptor.     *     * When the server creates the input and output tasks in advance, that     * operation does not occur. To prevent writing to a non-existent     * socket, the input task restarts the output task after using the     * FIOFLUSH ioctl to prevent stale data from reaching the next session.     */    while ((n = read (outputFd, buf, sizeof (buf))) > 0)        {        /* XXX should scan for IAC and double 'em to escape 'em */        write (sock, buf, n);        }    return; /* This point is never reached */    }/********************************************************************************* telnetInTask - relay input from remote user** This routine transfers data from the remote user to the registered* input/output task. It is deleted when the client disconnects. The* <slot> argument has two possible meanings. In the default setup,* it provides access to the session data which includes two file* descriptors: one for a socket (to the remote client) and another* provided by the command interpreter for the connection. That* information is not available when the server creates the input/output* tasks in advance. ** RETURNS: N/A.** NOMANUAL* but not LOCAL for i()*/void telnetInTask    (    TELNETD_SESSION_DATA * pSlot    )    {    int n;    int state = TS_DATA;    char buf [STDIN_BUF_SIZE];    int sock;    /* Socket for individual telnet session */    int inputFd; /* Input to command interpreter */    int slaveFd; /* Command interpreter stdin */    FOREVER        {        /* Wait for a connection if the server creates this task in advance. */        if (telnetdTaskFlag)  /* static creation */            semTake (pSlot->startInput, WAIT_FOREVER);        /*         * Transfer data from the socket to the command interpreter, after         * filtering out the telnet commands and options.         */        sock = pSlot->socket;        inputFd = pSlot->inputFd;        slaveFd = pSlot->slaveFd;        while ((n = read (sock, buf, sizeof (buf))) > 0)            state = tnInput (state, slaveFd, sock, inputFd, buf, n);        /*         * Terminate the session.  This is done as a seperate job because          *  the function telnetdSessionDisconnectFromRemote() deletes          *  the inTask before completion and that is our context (in this case)!         */        excJobAdd (telnetdSessionDisconnectFromRemote,                    (int)pSlot,                    0, 0, 0, 0, 0);        taskSuspend (0); /* Wait to be deleted by telnetdSessionDisconnect */        }    return;    }/********************************************************************************* tnInput - process input from remote user** This routine transfers input data from a telnet client's <clientSock>* socket to the command interpreter through the <inputFd> file descriptor.* The <state> parameter triggers interpretation of the input as raw data or* as part of a command sequence or telnet option.** RETURNS: state value for next data bytes** NOMANUAL*/LOCAL int tnInput    (    FAST int state,         /* state of telnet session's input handler */    FAST int slaveFd,       /* local fd, some options adjust it via ioctl */    FAST int clientSock,    /* socket connected to telnet client */    FAST int inputFd,       /* input to command interpreter */    FAST char *buf,         /* buffer containing client data */    FAST int n              /* amount of client data in buffer */    )    {    char cc;    int ci;    while (--n >= 0)    {        cc = *buf++;               /* get next character */        ci = (unsigned char) cc;   /* convert to int since many values                                    * are negative characters */    switch (state)        {        case TS_CR: 	/* doing crmod; ignore add'l linefeed */		state = TS_DATA;		if ((cc != EOS) && (cc != '\n'))		    write (inputFd, &cc, 1);	/* forward char */		break;	case TS_DATA:	/* just pass data */		if (ci == IAC)		    state = TS_IAC;		else		    {		    write (inputFd, &cc, 1);	/* forward char */		    if (!myOpts [TELOPT_BINARY] && (cc == '\r'))			state = TS_CR;		    }		break;	    case TS_IAC:		switch (ci)		    {		    case BREAK:		/* interrupt from remote */		    case IP:			/* XXX interrupt (); */			state = TS_DATA;			break;		    case AYT:		/* Are You There? */			{			static char aytAnswer [] = "\r\n[yes]\r\n";			write (clientSock, aytAnswer, sizeof (aytAnswer) - 1);			state = TS_DATA;			break;			}		    case EC:		/* erase character */			write (inputFd, "\b", 1);			state = TS_DATA;			break;		    case EL:		/* erase line */			write (inputFd, "\025", 1);			state = TS_DATA;			break;		    case DM:		/* data mark */			state = TS_DATA;			break;		    case SB:		/* sub-option negotiation begin */			state = TS_BEGINNEG;			break;		    case WILL: state = TS_WILL;	break;	/* remote will do opt */		    case WONT: state = TS_WONT;	break;	/* remote wont do opt */		    case DO:   state = TS_DO;	break;	/* req we do opt */		    case DONT: state = TS_DONT;	break;	/* req we dont do opt */		    case IAC:			write (inputFd, &cc, 1);	/* forward char */			state = TS_DATA;			break;		    }		break;	    case TS_BEGINNEG:		/* ignore sub-option stuff for now */		if (ci == IAC)		    state = TS_ENDNEG;		break;	    case TS_ENDNEG:		state = (ci == SE) ? TS_DATA : TS_BEGINNEG;		break;	    case TS_WILL:		/* remote side said it will do opt */		(void)remDoOpt (slaveFd, ci, TRUE, clientSock, TRUE);		state = TS_DATA;		break;	    case TS_WONT:		/* remote side said it wont do opt */		(void)remDoOpt (slaveFd, ci, FALSE, clientSock, TRUE);		state = TS_DATA;		break;	    case TS_DO:			/* remote wants us to do opt */		(void)localDoOpt (slaveFd, ci, TRUE, clientSock, TRUE);		state = TS_DATA;		break;	    case TS_DONT:		/* remote wants us to not do opt */		(void)localDoOpt (slaveFd, ci, FALSE, clientSock, TRUE);		state = TS_DATA;		break;	    default:		TELNETD_DEBUG ("telnetd: invalid state = %d\n", state,                                1, 2, 3, 4, 5);		break;	    }	}    return (state);    }/********************************************************************************* remDoOpt - request/acknowledge remote enable/disable of option** This routine will try to accept the remote's enable or disable,* as specified by "will", of the remote's support for the specified option.* If the request is to disable the option, the option will always be disabled.* If the request is to enable the option, the option will be enabled, IF we* are capable of supporting it.  The remote is notified to DO/DONT support* the option.** RETURNS: OK or ERROR.*/LOCAL STATUS remDoOpt    (    FAST int slaveFd,/* slave fd */    FAST int opt,    /* option to be enabled/disabled */    BOOL enable,     /* TRUE = enable option, FALSE = disable */    int clientSock,  /* socket connection to telnet client */    BOOL remFlag     /* TRUE = request is from remote */    )    {    BOOL doOpt = enable;    if (remOpts [opt] == enable)	return (OK);    switch (opt)	{	case TELOPT_BINARY:	case TELOPT_ECHO:	    setMode (slaveFd, opt, enable);	    break;	case TELOPT_SGA:	    break;	default:	    doOpt = FALSE;	    break;	}    if ((remOpts [opt] != doOpt) || remFlag)	{	char msg[3];	msg[0] = IAC;	msg[1] = doOpt ? DO : DONT;	msg[2] = opt;	write (clientSock, msg, 3);	remOpts [opt] = doOpt;	}    return ((enable == doOpt) ? OK : ERROR);    }/********************************************************************************* localDoOpt - offer/acknowledge local support of option** This routine will try to enable or disable local support for the specified* option.  If local support of the option is already in the desired mode, no* action is taken.  If the request is to disable the option, the option will* always be disabled.  If the request is to enable the option, the option* will be enabled, IF we are capable of supporting it.  The remote is* notified that we WILL/WONT support the option.** NOMANUAL** RETURNS: OK or ERROR.*/LOCAL STATUS localDoOpt    (    FAST int slaveFd,     /* slave fd */    FAST int opt,    /* option to be enabled/disabled */    BOOL enable,        /* TRUE = enable option, FALSE = disable */    int clientSock,     /* socket connection to telnet client */    BOOL remFlag     /* TRUE = request is from remote */    )    {    BOOL will = enable;    if (myOpts [opt] == enable)	return (OK);    switch (opt)	{	case TELOPT_BINARY:	case TELOPT_ECHO:	    setMode (slaveFd, opt, enable);	    break;	case TELOPT_SGA:	    break;	default:	    will = FALSE;	    break;	}    if ((myOpts [opt] != will) || remFlag)	{	char msg[3];	msg[0] = IAC;	msg[1] = will ? WILL : WONT;	msg[2] = opt;	write (clientSock, msg, 3);	myOpts [opt] = will;	}    return ((will == enable) ? OK : ERROR);    }/********************************************************************************* setMode - set telnet option** RETURNS: N/A.** NOMANUAL**/LOCAL void setMode    (    int fd,    int telnetOption,    BOOL enable    )    {    FAST int ioOptions;    switch (telnetOption)        {        case TELOPT_BINARY: raw  = enable; break;        case TELOPT_ECHO:   echo = enable; break;        }    if (raw)        ioOptions = 0;    else        {        ioOptions = OPT_7_BIT | OPT_ABORT | OPT_TANDEM | OPT_LINE;        if (echo)            {            ioOptions |= (OPT_ECHO | OPT_CRMOD);            }    }    (void) ioctl (fd, FIOOPTIONS, ioOptions);    }/********************************************************************************* telnetdStaticTaskInitializationGet - report whether tasks were pre-started by telnetd** This function is called by a custom shell parser library to determine if a shell * is to be spawned at the time a connection is requested.** RETURNS  ** TRUE, if all tasks are pre-spawned; FALSE, if tasks are spawned at the * time a connection is requested.** SEE ALSO: telnetdInit(), telnetdParserSet()** INTERNAL* This routine is used by custom shells and is demonstrated in the * unsupported user shell echoShell.c**/BOOL telnetdStaticTaskInitializationGet()    {    return (telnetdTaskFlag);    } 

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -