📄 telnet.cc
字号:
bol = 0; ignore = 1; } } if (!ignore) { int l; char buf[128]; l = ttyiring.gets(buf, sizeof(buf)); command(0, buf, l); bol = 1; flushline = 1; break; } } else { bol = 0; }#ifdef KLUDGELINEMODE if (kludgelinemode && (globalmode&MODE_EDIT) && (sc == echoc)) { int ignore=0; if (ttyiring.getch(&c) > 0) { if (strip(c) != echoc) ttyiring.ungetch(c); else ignore=1; } if (!ignore) { dontlecho = !dontlecho; settimer(echotoggle); setconnmode(0); flushline = 1; break; } }#endif if (MODE_LOCAL_CHARS(globalmode)) { if (TerminalSpecialChars(sc) == 0) { bol = 1; break; } } if (my_want_state_is_wont(TELOPT_BINARY)) { switch (c) { case '\n': /* * If we are in CRMOD mode (\r ==> \n) * on our local machine, then probably * a newline (unix) is CRLF (TELNET). */ if (MODE_LOCAL_CHARS(globalmode)) { NETADD('\r'); } NETADD('\n'); bol = flushline = 1; break; case '\r': if (!crlf) { NET2ADD('\r', '\0'); } else { NET2ADD('\r', '\n'); } bol = flushline = 1; break; case IAC: NET2ADD(IAC, IAC); break; default: NETADD(c); break; } } else if (c == IAC) { NET2ADD(IAC, IAC); } else { NETADD(c); } } return returnValue; /* Non-zero if we did anything */}/* * Scheduler() * * Try to do something. * * If we do something useful, return 1; else return 0. * *//* block: should we block in the select ? */int Scheduler(int block) { /* One wants to be a bit careful about setting returnValue * to one, since a one implies we did some useful work, * and therefore probably won't be called to block next * time (TN3270 mode only). */ int returnValue; int netin, netout, netex, ttyin, ttyout; /* Decide which rings should be processed */ netout = netoring.full_count() && (flushline || (my_want_state_is_wont(TELOPT_LINEMODE)#ifdef KLUDGELINEMODE && (!kludgelinemode || my_want_state_is_do(TELOPT_SGA))#endif ) || my_want_state_is_will(TELOPT_BINARY)); ttyout = ttyoring.full_count(); #if defined(TN3270) ttyin = ttyiring.empty_count() && (shell_active == 0);#else /* defined(TN3270) */ ttyin = ttyiring.empty_count();#endif /* defined(TN3270) */ #if defined(TN3270) netin = netiring.empty_count();#else /* !defined(TN3270) */ netin = !ISend && netiring.empty_count();#endif /* !defined(TN3270) */ netex = !SYNCHing; /* If we have seen a signal recently, reset things */#ifdef TN3270 if (HaveInput) { HaveInput = 0; (void) signal(SIGIO, inputAvailable); }#endif /* TN3270 */ /* Call to system code to process rings */ returnValue = process_rings(netin, netout, netex, ttyin, ttyout, !block); /* Now, look at the input rings, looking for work to do. */ if (ttyiring.full_count()) {#if defined(TN3270) if (In3270) { int c; c = DataFromTerminal(ttyiring.consume, ring_full_consecutive(&ttyiring)); if (c) { returnValue = 1; ring_consumed(&ttyiring, c); } } else {#endif /* defined(TN3270) */ returnValue |= telsnd();#if defined(TN3270) }#endif /* defined(TN3270) */ } if (netiring.full_count()) {# if !defined(TN3270) returnValue |= telrcv();# else /* !defined(TN3270) */ returnValue = Push3270();# endif /* !defined(TN3270) */ } return returnValue;}/* * Select from tty and network... */void telnet(const char * /*user*/) { sys_telnet_init(); #if !defined(TN3270) if (telnetport) { send_do(TELOPT_SGA, 1); send_will(TELOPT_TTYPE, 1); send_will(TELOPT_NAWS, 1); send_will(TELOPT_TSPEED, 1); send_will(TELOPT_LFLOW, 1); send_will(TELOPT_LINEMODE, 1); send_will(TELOPT_ENVIRON, 1); send_do(TELOPT_STATUS, 1); if (env_getvalue("DISPLAY", 0)) send_will(TELOPT_XDISPLOC, 1); if (eight) tel_enter_binary(eight); }#endif /* !defined(TN3270) */ #if !defined(TN3270) for (;;) { int schedValue; while ((schedValue = Scheduler(0)) != 0) { if (schedValue == -1) { setcommandmode(); return; } } if (Scheduler(1) == -1) { setcommandmode(); return; } }#else /* !defined(TN3270) */ for (;;) { int schedValue; while (!In3270 && !shell_active) { if (Scheduler(1) == -1) { setcommandmode(); return; } } while ((schedValue = Scheduler(0)) != 0) { if (schedValue == -1) { setcommandmode(); return; } } /* If there is data waiting to go out to terminal, don't * schedule any more data for the terminal. */ if (ring_full_count(&ttyoring)) { schedValue = 1; } else { if (shell_active) { if (shell_continue() == 0) { ConnectScreen(); } } else if (In3270) { schedValue = DoTerminalOutput(); } } if (schedValue && (shell_active == 0)) { if (Scheduler(1) == -1) { setcommandmode(); return; } } }#endif /* !defined(TN3270) */}#if 0 /* XXX - this not being in is a bug *//* * nextitem() * * Return the address of the next "item" in the TELNET data * stream. This will be the address of the next character if * the current address is a user data character, or it will * be the address of the character following the TELNET command * if the current address is a TELNET IAC ("I Am a Command") * character. */static unsigned char *nextitem(unsigned char *current) { if (*current != IAC) { return current+1; } switch (current[1]) { case DO: case DONT: case WILL: case WONT: return current+3; case SB: /* loop forever looking for the SE */ { unsigned char *look = current+2; for (;;) { if (*look++ == IAC) { if (*look++ == SE) { return look; } } } } default: return current+2; }}#endif /* 0 *//* * netclear() * * We are about to do a TELNET SYNCH operation. Clear * the path to the network. * * Things are a bit tricky since we may have sent the first * byte or so of a previous TELNET command into the network. * So, we have to scan the network buffer from the beginning * until we are up to where we want to be. * * A side effect of what we do, just to keep things * simple, is to clear the urgent data pointer. The principal * caller should be setting the urgent data pointer AFTER calling * us in any case. */static void netclear(void) {#if 0 /* XXX */ register char *thisitem, *next; char *good;#define wewant(p) ((nfrontp > p) && (*p == IAC) && \ (p[1] != EC) && (p[1] != EL)) thisitem = netobuf; while ((next = nextitem(thisitem)) <= netobuf.send) { thisitem = next; } /* Now, thisitem is first before/at boundary. */ good = netobuf; /* where the good bytes go */ while (netoring.add > thisitem) { if (wewant(thisitem)) { int length; next = thisitem; do { next = nextitem(next); } while (wewant(next) && (nfrontp > next)); length = next-thisitem; memcpy(good, thisitem, length); good += length; thisitem = next; } else { thisitem = nextitem(thisitem); } } #endif /* 0 */}/* * These routines add various telnet commands to the data stream. */static void doflush(void) { NET2ADD(IAC, DO); NETADD(TELOPT_TM); flushline = 1; flushout = 1; (void) ttyflush(1); /* Flush/drop output */ /* do printoption AFTER flush, otherwise the output gets tossed... */ printoption("SENT", DO, TELOPT_TM);}void xmitAO(void) { NET2ADD(IAC, AO); printoption("SENT", IAC, AO); if (autoflush) { doflush(); }}void xmitEL(void) { NET2ADD(IAC, EL); printoption("SENT", IAC, EL);}void xmitEC(void) { NET2ADD(IAC, EC); printoption("SENT", IAC, EC);}int dosynch(void) { netclear(); /* clear the path to the network */ NETADD(IAC); netoring.set_mark(); NETADD(DM); printoption("SENT", IAC, DM); return 1;}int want_status_response = 0;int get_status(const char *, const char *) { unsigned char tmp[16]; unsigned char *cp; if (my_want_state_is_dont(TELOPT_STATUS)) { printf("Remote side does not support STATUS option\n"); return 0; } cp = tmp; *cp++ = IAC; *cp++ = SB; *cp++ = TELOPT_STATUS; *cp++ = TELQUAL_SEND; *cp++ = IAC; *cp++ = SE; printsub('>', tmp+2, cp - tmp - 2); netoring.write((char *)tmp, cp-tmp); ++want_status_response; return 1;}void intp(void) { NET2ADD(IAC, IP); printoption("SENT", IAC, IP); flushline = 1; if (autoflush) { doflush(); } if (autosynch) { dosynch(); }}void sendbrk(void) { NET2ADD(IAC, BREAK); printoption("SENT", IAC, BREAK); flushline = 1; if (autoflush) { doflush(); } if (autosynch) { dosynch(); }}void sendabort(void) { NET2ADD(IAC, ABORT); printoption("SENT", IAC, ABORT); flushline = 1; if (autoflush) { doflush(); } if (autosynch) { dosynch(); }}void sendsusp(void) { NET2ADD(IAC, SUSP); printoption("SENT", IAC, SUSP); flushline = 1; if (autoflush) { doflush(); } if (autosynch) { dosynch(); }}void sendeof(void) { NET2ADD(IAC, xEOF); printoption("SENT", IAC, xEOF);}void sendayt(void) { NET2ADD(IAC, AYT); printoption("SENT", IAC, AYT);}/* * Send a window size update to the remote system. */void sendnaws(void) { long rows, cols; unsigned char tmp[16]; unsigned char *cp; if (my_state_is_wont(TELOPT_NAWS)) return; #define PUTSHORT(cp, x) { if ((*cp++ = ((x)>>8)&0xff) == IAC) *cp++ = IAC; \ if ((*cp++ = ((x))&0xff) == IAC) *cp++ = IAC; } if (TerminalWindowSize(&rows, &cols) == 0) { /* Failed */ return; } cp = tmp; *cp++ = IAC; *cp++ = SB; *cp++ = TELOPT_NAWS; PUTSHORT(cp, cols); PUTSHORT(cp, rows); *cp++ = IAC; *cp++ = SE; printsub('>', tmp+2, cp - tmp - 2); netoring.write((char *)tmp, cp-tmp);}void tel_enter_binary(int rw) { if (rw&1) send_do(TELOPT_BINARY, 1); if (rw&2) send_will(TELOPT_BINARY, 1);}void tel_leave_binary(int rw) { if (rw&1) send_dont(TELOPT_BINARY, 1); if (rw&2) send_wont(TELOPT_BINARY, 1);}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -