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

📄 raw.c

📁 dtelent是开源的开发项目
💻 C
📖 第 1 页 / 共 2 页
字号:
	    break;

	case TELOPT_ECHO:
	    switch (cmd) {
	    case DO: /* Server has told us to ECHO - reject */
		     /* Note: netkit-telnetd sends "DO ECHO" */
		     /* just to detect broken clients */
                     /* but we are not (so) broken */
		rawCmd(WONT, TELOPT_ECHO);
		break;
	    case DONT:
		/* Server told us not to ECHO - ignore */
		break;
	    case WILL:
		/* Server told us it WILL ECHO, tell it to ECHO */
		rawCmd(DO, TELOPT_ECHO);
		emulSetEcho(FALSE);
		break;
	    case WONT:
		/* Server has told us it WONT ECHO, tell it not to */
		rawCmd(DONT, TELOPT_ECHO);
		emulSetEcho(TRUE);
		break;
	    }
	    break;

	case TELOPT_SGA:
	    switch (cmd) {
	    case DO:
		/* Server told us to SGA, tell it we WILL SGA
		 */
		rawCmd(WILL, TELOPT_SGA);
		break;
	    case WILL:
		/* Server told us it WILL SGA, tell it to SGA
		 */
		if (!fDoSgaSent) {
		    rawCmd(DO, TELOPT_SGA);
		    fDoSgaSent = TRUE;
		}
		break;
	    }
	    doneSGA = TRUE;
	    break;

	case TELOPT_TTYPE:
	    switch (cmd) {
	    case DO:
		/* Server told us to TTYPE, tell it we WILL TTYPE
		 */
		rawCmd(WILL, TELOPT_TTYPE);
		break;
	    }
	    break;

	case TELOPT_LFLOW:
	    switch (cmd) {
	    case DO:
		/* Server told us DO LFLOW, tell it we will LFLOW
		 */
		if (!socketLocalFlowControl()) {
		    rawCmd(WILL, TELOPT_LFLOW);
		    socketSetLocalFlowControl(TRUE);
		}
		break;
	    case DONT:
		/* Server told us not to LFLOW, tell it we WONT LFLOW
		 */
		rawCmd(WONT, TELOPT_LFLOW);
		socketSetLocalFlowControl(FALSE);
		break;
	    }
	    doneLFLOW = TRUE;
	    break;

	case TELOPT_XDISPLOC:

	    switch (cmd) {
	    case WILL: /* Server should never send me his DISPLAY ! */
		rawCmd(DONT, TELOPT_XDISPLOC);
		break;
	    case WONT: /* No reply required */
		break;

	    case DO:
	    case DONT:
	        rawTLOMachine (TELOPT_XDISPLOC, &toXdisploc, cmd);
		break;
	    }
	    break;

	default:
	    switch (cmd) {
	    case DO:
	    case DONT:
		/* For all other commands, say we WONT do them
		 */
		rawCmd(WONT, opt);
		break;
	    case WILL:
	    case WONT:
		/* For all other commands tell the server not to do them
		 */
		rawCmd(DONT, opt);
		break;
	    }
	    break;
	}
	cmdUpto = 0;
	return FALSE;		/* Not in command any more */

    case SB:
	/* Server wants to negotiate something we agreed to do
	 */
	if (cmdUpto < 3)
	    return TRUE;

	opt = cmdBuff[2];
	switch (opt) {
	case TELOPT_TTYPE:
	    /* IAC SB TERMINAL-TYPE SEND IAC SE
	     * Server wants us to send our terminal type
	     */
	    if (cmdUpto < 6)
		return TRUE;
	    if (cmdBuff[3] == 1 && cmdBuff[4] == IAC && cmdBuff[5] == SE) {
		logProtocol("recv SB TERMINAL-TYPE SEND IAC SE\n");
		rawSetTerm();
	    }
	    break;
	case TELOPT_LFLOW:
	    /* IAC SB TOGGLE-FLOW-CONTROL ? IAC SE
	     * Server is telling us to modify local flow control
	     */
	    if (cmdUpto < 6 || cmdBuff[cmdUpto - 1] != SE)
		return TRUE;
	    switch (cmdBuff[3]) {
	    case LFLOW_OFF:
		socketSetLocalFlowControl(FALSE);
		logProtocol("recv SB LFLOW OFF IAC SE\n");
		break;
	    case LFLOW_ON:
		socketSetLocalFlowControl(TRUE);
		logProtocol("recv SB LFLOW ON IAC SE\n");
		break;
	    case LFLOW_RESTART_ANY:
		emulLocalFlowAny(TRUE);
		logProtocol("recv SB LFLOW RESTART-ANY IAC SE\n");
		break;
	    case LFLOW_RESTART_XON:
		emulLocalFlowAny(FALSE);
		logProtocol("recv SB LFLOW RESTART-XON IAC SE\n");
		break;
	    }
	case TELOPT_XDISPLOC:
	    if (cmdUpto < 6 || cmdBuff[cmdUpto - 1] != SE)
		return TRUE;
	    if (cmdBuff[3] == TELNET_SEND && 
                cmdBuff[4] == IAC && 
                cmdBuff[5] == SE) {
		logProtocol("recv SB XDISPLOC SEND IAC SE\n");
		sprintf (display, "%s:0", socketGetLocalIP());
		msglen  = sprintf (msg, "%c%c%c%c%s%c%c",
				   IAC, SB, TELOPT_XDISPLOC, 0,
				   display, IAC, SE);
		socketWrite(msg, msglen);
		logProtocol("send SB XDISPLOC IS %s IAC SE\n",
			    display);
	    }
	}
	cmdUpto = 0;
	return FALSE;		/* Not in command any more */

    case DM:	/* Data mark--for connect. cleaning */
    case GA:	/* You may reverse the line */
    case EL:	/* Erase the current line */
    case EC:	/* Erase the current character */
    case BRK:	/* Break */
    case NOP:	/* NOP */
    case AYT:	/* Are you there */
    case AO:	/* Abort output--but let prog finish */
    case IP:	/* Interrupt process--permanently */
    case SE:	/* End sub negotiation */
	cmdUpto = 0;
	return FALSE;		/* Not in command any more */
    }

    return TRUE;
}

/* Set the protocol to interpret in the session
 *
 * Args:
 * proto - the protocol to interpret
 */
void rawEnableProtocol(RawProtocol proto)
{
    rawProtocol = proto;

    switch (proto) {
    case protoNone:
	/* When not doing any protocol, echo all characters
	 */
	emulSetEcho(TRUE);
	logProtocol("no protocol\n");
	break;
    case protoTelnet:
	/* When doing telnet, start by not echoing characters
	 */
	emulSetEcho(TRUE);  /* Changed to TRUE by LZS on 2001.04.02 */
	logProtocol("telnet protocol enabled\n");
	break;
    case protoRlogin:
	/* When doing rlogin, start by not echoing characters
	 */
	emulSetEcho(FALSE);
	logProtocol("rlogin protocol enabled\n");
	break;
    }
}

/* Return the protocol that we are interpreting
 */
RawProtocol rawGetProtocol()
{
    return rawProtocol;
}

/* Interpret some data from the telnet server
 *
 * Args:
 * text - the text received from the server
 * len -  the amount of text received
 */
static int rawProcessTelnet(unsigned char* text, int len)
{
    int numChars = 0;		/* number of consecutive session
				 * characters found */
    int idx;			/* iterate over text */

    ASSERT(text != NULL);
    ASSERT(len > 0);

    if (startSession) {
	/* This is the first data received from the telnet server
	 */
	logProtocol("Server initiated options\n");
	startSession = FALSE;
    }

    /* Process the text received
     */
    for (idx = 0; idx < len; idx++) {
	if (inCommand) {
	    /* If we are in a command, process the command one
	     * character at a time.
	     */
	    inCommand = parseTelnetCommand(text[idx]);
	} else {
	    /* Scan over text until we hit a command
	     */
	    if (text[idx] != IAC) {
		/* Normal text, just count it for now
		 */
		if (ignoreTextUntilDM && text[idx] == DM) {
		    /* Server has told us to ignore text until we see DM
		     */
		    ignoreTextUntilDM = FALSE;
		    numChars = 0;
		} else
		    numChars++;
	    } else {
		/* Some kind of command
		 */
		if (numChars > 0) {
		    /* If we scanned any text, pass this text to the
		     * text receive processing.
		     */
		    if (!ignoreTextUntilDM)
			emulAddText(text + idx - numChars, numChars, FALSE);
		    numChars = 0;
		}
		/* Pass the IAC into the command parser
		 */
		inCommand = parseTelnetCommand(text[idx]);
	    }
	}
    }

    if (numChars > 0 && !ignoreTextUntilDM)
	/* We finished the loop with scanned text, pass this text to
	 * the text receive processing.
	 */
	emulAddText(text + idx - numChars, numChars, FALSE);

    return len;
}

/* Interpret some data from the rlogin server
 *
 * Args:
 * text - text received from the server
 * len -  the amount of text received
 */
static int rawProcessRlogin(unsigned char* text, int len)
{
    int idx = 0;		/* index to process from */

    ASSERT(text != NULL);
    ASSERT(len > 0);
    if (startSession) {
	/* The server might send a nul as the very first character,
	 * skip over it
	 */
	if (*text == '\0')
	    idx = 1;
	startSession = FALSE;
    }

    /* Send the rest of the text to the terminal emulator
     */
    if (idx < len)
	emulAddText(text + idx, len - idx, FALSE);

    return len;
}

/* Process some data received from the server
 *
 * Args:
 * text - text received from the server
 * len -  amount of text received
 */
int rawProcessData(unsigned char* text, int len)
{
    ASSERT(text != NULL);
    ASSERT(len > 0);
    switch (rawProtocol) {
    case protoNone:
	/* No protocol - send text directly to terminal
	 */
	emulAddText(text, len, FALSE);
	return len;
    case protoTelnet:
	return rawProcessTelnet(text, len);
    case protoRlogin:
	return rawProcessRlogin(text, len);
    }
    /* Just in case...
     */
    return len;
}

/* Process some out-of-band data from the server
 *
 * Args:
 * text - text received from server
 * len  - length of text received
 */
void rawProcessOob(unsigned char* text, int len)
{
#if 0
    /* Display the text via OutputDebugString
     */
    int idx;

    ods("OOB:\n");
    for (idx = 0; idx < len; idx += 16) {
	int off;
	for (off = 0; idx + off < len && off < 16; ++off)
	    ods("%02x ", text[idx + off]);
	while (off++ < 16)
	    ods("   ");
	for (off = 0; idx + off < len && off < 16; ++off)
	    if (isprint(text[idx + off]))
		ods("%c", text[idx + off]);
	    else
		ods(".");
	ods("\n");
    }
#endif
    ASSERT(text != NULL);
    ASSERT(len > 0);
    switch (rawProtocol) {
    case protoTelnet:
	switch (*text) {
	case 0xff:
	    logProtocol("recv TELNET Synch\n");
	    ignoreTextUntilDM = TRUE;
	    break;
	}
	break;
    case protoRlogin:
	switch (*text) {
	case 0x02:		/* discard buffered data from server */
	    break;
	case 0x10:		/* raw mode - send ^S/^Q to server */
	    socketSetLocalFlowControl(FALSE);
	    break;
	case 0x20:		/* handle ^S/^Q locally */
	    socketSetLocalFlowControl(TRUE);
	    break;
	case 0x80:
	    dontNAWS = FALSE;
	    rawSetWindowSize();
	    break;
	}
	break;
    }
}

/* Find the protocol appropriate for the specified port
 */
RawProtocol findPortProtocol(char* portName)
{
    int idx;

    for (idx = 0; idx < numElem(protocols); idx++)
	if (stricmp(portName, protocols[idx].name) == 0
	    || atoi(portName) == protocols[idx].port)
	    return protocols[idx].proto;
    return protoNone;
}

void rawTLOMachine (unsigned char option, TelnetLocalOption *state,
                    int input /* DO or DONT */)
{
    if (*state==toIDontWant) { /* never change this state */
	if (input==DO) {
	    rawCmd (WONT, option);
	}

    } else if (input==DO) {
	if (*state == toIWDisabled) {
	    rawCmd (WILL, option);
	}
	*state = toIWEnabled;

    } else { /* input==DONT */
	if (*state == toIWEnabled) {
	    rawCmd (WONT, option);
	}
	*state = toIWDisabled;
    }
}

⌨️ 快捷键说明

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