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

📄 telnetlib.c

📁 vxworks源码源码解读是学习vxworks的最佳途径
💻 C
📖 第 1 页 / 共 2 页
字号:
	    if (telnetOutTaskId != ERROR)		taskDelete (telnetOutTaskId);	    telnetdExit (FALSE);	/* try to do a tidy clean-up */	    }	}    }/********************************************************************************* telnetOutTask - stdout to socket process** This routine gets spawned by the telnet daemon to move data between the* client socket and the pseudo-terminal.  The created task is deleted* when the client disconnects.** NOMANUAL* but not LOCAL for i()*/void telnetOutTask    (    FAST int sock,      /* socket to copy output to */    FAST int ptyMfd     /* pty Master fd */    )    {    FAST int n;    char buf [STDOUT_BUF_SIZE];    while ((n = read (ptyMfd, buf, sizeof (buf))) > 0)	{	/* XXX should scan for IAC and double 'em to escape 'em */	write (sock, buf, n);	}    }/********************************************************************************* telnetInTask - socket to stdin process** This routine gets spawned by the telnet daemon to move data between the* pseudo-terminal and the client socket.  The task exits, calling* telnetdExit(), when the client disconnects.** RETURNS: N/A.** NOMANUAL* but not LOCAL for i()*/void telnetInTask    (    FAST int sock,      /* socket to copy input from */    int ptyMfd          /* pty Master fd */    )    {    int n;    int state = TS_DATA;    char buf [STDIN_BUF_SIZE];    cleanupFlag = FALSE;	/* exit cleanup has not been done... */    /* Loop, reading from the socket and writing to the pty. */    while ((n = read (sock, buf, sizeof (buf))) > 0)        state = tnInput (state, sock, ptyMfd, buf, n);    /* Exit and cleanup.  The above loop will exit when the socket is     * closed.  The socket can be closed as a result of the connection     * terminating from the remote host, or as a result of the logout()     * command issued to our shell.  When the logout() command is used,     * the telnetdExit() routine below is called and the socket is explicitly     * closed.  In this case, there is no need to call telnetdExit() again.     * We use the cleanupFlag to determine this case.  To summarize, if the     * cleanupFlag is set, we are here because the connection was terminated     * remotely and cleanup is required.     */    if (!cleanupFlag)        telnetdExit (FALSE);    }/********************************************************************************* telnetdExit - exit and cleanup routine for telnetd()** This is the support routine for logout().  The client socket is closed,* shell standard I/O is redirected back to the console, and the shell is* restarted by sending an EOF.** RETURNS: N/A.*/LOCAL void telnetdExit    (    BOOL usedLogout    /* true if called from logout() */    )    {    /* This routine is called either as a result of the logout() command     * being issued from the shell, or from the telnetInTask above.  It is     * therefore run in the context of the shell or telnetInTask.  The     * caller indicates itself to us by the usedLogout argument.  The     * state of this argument affects our behavior, as explained below.     */    cleanupFlag = TRUE;                 /* release telnetInTask() from duty */    shellLogoutInstall ((FUNCPTR) NULL, 0);     /* uninstall logout function */    if (logFdFromRlogin != NONE)        {        logFdDelete (logFdFromRlogin);		/* cancel extra log device */        logFdFromRlogin = NONE;			/* reset fd */        }    shellOrigStdSet (STD_IN,  shellInFd);       /* restore shell's stnd I/O */    shellOrigStdSet (STD_OUT, shellOutFd);    shellOrigStdSet (STD_ERR, shellErrFd);    shellLock (FALSE);                          /* unlock shell */    write (telnetdSocket, "\n", 1);    close (telnetdSocket);                      /* close the socket */    /* For typical remote sessions, there is no need to restart the shell.     * If we are in shell context, simply restoring the standard I/O     * descriptors is enough to get the shell back on track upon return     * from this function.  If we are in telnetInTask context, the closing     * of the pty device will cause the shell to unblock from its read()     * and do subsequent I/O from the restored descriptors.     * However, problems can occur upon logout if the remote user has     * disabled the line editor and/or put the pty device in raw mode.     * The problem caused is that the shell does not resume properly.     * It is therefore deemed prudent to always restart the shell, thereby     * avoiding any funny business.     *     * The previous version attempted to send a ctrl-D up the pty device     * to wakeup and restart the shell.  Unfortunately, ctrl-D only has     * special meaning when the device is in line mode, and hence did     * not work in raw mode.     *     * The pty device is closed after the shell is restarted, when called     * from telnetInTask, to avoid waking the existing shell and causing an     * additional prompt to appear on the console.     */    if (usedLogout)                             /* called from shell */        {        close (telnetdM);        close (telnetdS);        activeFlag = FALSE;			/* allow new connection */        taskRestart (0);                        /* never returns */        }    else                                        /* called from telnetInTask */        {        excJobAdd (shellRestart, FALSE, 0, 0, 0, 0, 0);        close (telnetdM);        close (telnetdS);        activeFlag = FALSE;			/* allow new connection */        }    }/********************************************************************************* tnInput - process input from remote** RETURNS: state*/LOCAL int tnInput    (    FAST int state,     /* state of input stream */    FAST int remFd,     /* fd of socket to otherside */    FAST int ptyFd,     /* fd of pty to this side */    FAST char *buf,     /* ptr to input chars */    FAST int n          /* number of chars input */    )    {    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'))		    sendToPty (ptyFd, &cc, 1);	/* forward char */		break;	    case TS_DATA:	/* just pass data */		if (ci == IAC)		    state = TS_IAC;		else		    {		    sendToPty (ptyFd, &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 (); */			logMsg ("telnetInTask: interrupt\n", 0, 0, 0, 0, 0, 0);			state = TS_DATA;			break;		    case AYT:		/* Are You There? */			{			static char aytAnswer [] = "\r\n[yes]\r\n";			sendToRem (remFd, aytAnswer, sizeof (aytAnswer) - 1);			state = TS_DATA;			break;			}		    case EC:		/* erase character */			sendToPty (ptyFd, "\b", 1);			state = TS_DATA;			break;		    case EL:		/* erase line */			sendToPty (ptyFd, "\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:			sendToPty (ptyFd, &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 (ci, TRUE, remFd, ptyFd, TRUE);		state = TS_DATA;		break;	    case TS_WONT:		/* remote side said it wont do opt */		(void)remDoOpt (ci, FALSE, remFd, ptyFd, TRUE);		state = TS_DATA;		break;	    case TS_DO:			/* remote wants us to do opt */		(void)localDoOpt (ci, TRUE, remFd, ptyFd, TRUE);		state = TS_DATA;		break;	    case TS_DONT:		/* remote wants us to not do opt */		(void)localDoOpt (ci, FALSE, remFd, ptyFd, TRUE);		state = TS_DATA;		break;	    default:		printErr ("telnetd: invalid state = %d\n", state);		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 option,    /* option to be enabled/disabled */    BOOL enable,        /* TRUE = enable option, FALSE = disable */    int remFd,          /* fd to remote */    int ptyFd,          /* fd to local pseudo-terminal */    BOOL reqFromRem     /* TRUE = request is from remote */    )    {    BOOL doOpt = enable;    if (remOpts [option] == enable)	return (OK);    switch (option)	{	case TELOPT_BINARY:	case TELOPT_ECHO:	    setMode (option, enable);	    break;	case TELOPT_SGA:	    break;	default:	    doOpt = FALSE;	    break;	}    if ((remOpts [option] != doOpt) || reqFromRem)	{	char msg[3];	msg[0] = IAC;	msg[1] = doOpt ? DO : DONT;	msg[2] = option;	sendToRem (remFd, msg, 3);	remOpts [option] = 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.** RETURNS: OK or ERROR.*/LOCAL STATUS localDoOpt    (    FAST int option,    /* option to be enabled/disabled */    BOOL enable,        /* TRUE = enable option, FALSE = disable */    int remFd,          /* fd to remote */    int ptyFd,          /* fd to local pseudo-terminal */    BOOL reqFromRem     /* TRUE = request is from remote */    )    {    BOOL will = enable;    if (myOpts [option] == enable)	return (OK);    switch (option)	{	case TELOPT_BINARY:	case TELOPT_ECHO:	    setMode (option, enable);	    break;	case TELOPT_SGA:	    break;	default:	    will = FALSE;	    break;	}    if ((myOpts [option] != will) || reqFromRem)	{	char msg[3];	msg[0] = IAC;	msg[1] = will ? WILL : WONT;	msg[2] = option;	sendToRem (remFd, msg, 3);	myOpts [option] = will;	}    return ((will == enable) ? OK : ERROR);    }/********************************************************************************* setMode -** RETURNS: N/A.*/LOCAL void setMode    (    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 (STD_IN, FIOOPTIONS, ioOptions);    }

⌨️ 快捷键说明

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