📄 telnet.cc
字号:
for (spcp = &spc_data[1]; spcp < &spc_data[NSLC+1]; spcp++) { if (spcp->valp && spcp->val != *spcp->valp) { spcp->val = *spcp->valp; if (spcp->val == (cc_t)(_POSIX_VDISABLE)) spcp->flags = SLC_NOSUPPORT; else spcp->flags = spcp->mylevel; slc_add_reply(spcp - spc_data, spcp->flags, spcp->val); } } slc_end_reply(); setconnmode(1);}unsigned char slc_reply[128];unsigned char *slc_replyp;void slc_start_reply(void) { slc_replyp = slc_reply; *slc_replyp++ = IAC; *slc_replyp++ = SB; *slc_replyp++ = TELOPT_LINEMODE; *slc_replyp++ = LM_SLC;}void slc_add_reply(int func, int flags, int value) { if ((*slc_replyp++ = func) == IAC) *slc_replyp++ = IAC; if ((*slc_replyp++ = flags) == IAC) *slc_replyp++ = IAC; if ((*slc_replyp++ = value) == IAC) *slc_replyp++ = IAC;}void slc_end_reply(void) { register int len; *slc_replyp++ = IAC; *slc_replyp++ = SE; len = slc_replyp - slc_reply; if (len <= 6) return; printsub('>', &slc_reply[2], len - 2); netoring.write((char *)slc_reply, len);}int slc_update(void) { struct spc *spcp; int need_update = 0; for (spcp = &spc_data[1]; spcp < &spc_data[NSLC+1]; spcp++) { if (!(spcp->flags&SLC_ACK)) continue; spcp->flags &= ~SLC_ACK; if (spcp->valp && (*spcp->valp != spcp->val)) { *spcp->valp = spcp->val; need_update = 1; } } return(need_update);}void env_opt(unsigned char *buf, int len) { unsigned char *ep = 0, *epc = 0; int i; switch(buf[0]) { case TELQUAL_SEND: env_opt_start(); if (len == 1) { env_opt_add(NULL); } else for (i = 1; i < len; i++) { switch (buf[i]) { case ENV_VALUE: if (ep) { *epc = 0; env_opt_add((const char *)ep); } ep = epc = &buf[i+1]; break; case ENV_ESC: i++; /*FALL THROUGH*/ default: if (epc) *epc++ = buf[i]; break; } if (ep) { *epc = 0; env_opt_add((const char *)ep); } } env_opt_end(1); break; case TELQUAL_IS: case TELQUAL_INFO: /* Ignore for now. We shouldn't get it anyway. */ break; default: break; }}#define OPT_REPLY_SIZE 256unsigned char *opt_reply;unsigned char *opt_replyp;unsigned char *opt_replyend;void env_opt_start(void) { if (opt_reply) opt_reply = (unsigned char *)realloc(opt_reply, OPT_REPLY_SIZE); else opt_reply = (unsigned char *)malloc(OPT_REPLY_SIZE); if (opt_reply == NULL) { /*@*/ printf("env_opt_start: malloc()/realloc() failed!!!\n"); opt_reply = opt_replyp = opt_replyend = NULL; return; } opt_replyp = opt_reply; opt_replyend = opt_reply + OPT_REPLY_SIZE; *opt_replyp++ = IAC; *opt_replyp++ = SB; *opt_replyp++ = TELOPT_ENVIRON; *opt_replyp++ = TELQUAL_IS;}void env_opt_start_info(void) { env_opt_start(); if (opt_replyp) opt_replyp[-1] = TELQUAL_INFO;}void env_opt_add(const char *ep) { const char *vp; unsigned char c; if (opt_reply == NULL) /*XXX*/ return; /*XXX*/ if (ep == NULL || *ep == '\0') { int i; env_iterate(&i, 1); for (ep = env_next(&i,1); ep; ep = env_next(&i,1)) env_opt_add(ep); return; } vp = env_getvalue(ep, 1); if (opt_replyp + (vp ? strlen(vp) : 0) + strlen(ep) + 6 > opt_replyend) { register int len; opt_replyend += OPT_REPLY_SIZE; len = opt_replyend - opt_reply; opt_reply = (unsigned char *)realloc(opt_reply, len); if (opt_reply == NULL) { /*@*/ printf("env_opt_add: realloc() failed!!!\n"); opt_reply = opt_replyp = opt_replyend = NULL; return; } opt_replyp = opt_reply + len - (opt_replyend - opt_replyp); opt_replyend = opt_reply + len; } *opt_replyp++ = ENV_VAR; for (;;) { while ((c = *ep++)!=0) { switch(c) { case IAC: *opt_replyp++ = IAC; break; case ENV_VALUE: case ENV_VAR: case ENV_ESC: *opt_replyp++ = ENV_ESC; break; } *opt_replyp++ = c; } if ((ep = vp)!=NULL) { *opt_replyp++ = ENV_VALUE; vp = NULL; } else break; }}void env_opt_end(int emptyok) { register int len; len = opt_replyp - opt_reply + 2; if (emptyok || len > 6) { *opt_replyp++ = IAC; *opt_replyp++ = SE; printsub('>', &opt_reply[2], len - 2); netoring.write((char *)opt_reply, len); } if (opt_reply) { free(opt_reply); opt_reply = opt_replyp = opt_replyend = NULL; }}int telrcv(void) { int c; int returnValue = 0; while (TTYROOM() > 2) { if (!netiring.getch(&c)) { /* No more data coming in */ break; } returnValue = 1; switch (telrcv_state) { case TS_CR: telrcv_state = TS_DATA; if (c == '\0') { break; /* Ignore \0 after CR */ } else if ((c == '\n') && my_want_state_is_dont(TELOPT_ECHO) && !crmod) { TTYADD(c); break; } /* Else, fall through */ case TS_DATA: if (c == IAC) { telrcv_state = TS_IAC; break; }#if defined(TN3270) if (In3270) { *Ifrontp++ = c; while (netiring.getch(&c)) { if (c == IAC) { telrcv_state = TS_IAC; break; } *Ifrontp++ = c; } } else#endif /* defined(TN3270) */ /* * The 'crmod' hack (see following) is needed * since we can't * set CRMOD on output only. * Machines like MULTICS like to send \r without * \n; since we must turn off CRMOD to get proper * input, the mapping is done here (sigh). */ if ((c == '\r') && my_want_state_is_dont(TELOPT_BINARY)) { if (netiring.getch(&c)) { if (c == 0) { /* a "true" CR */ TTYADD('\r'); } else if (my_want_state_is_dont(TELOPT_ECHO) && (c == '\n')) { TTYADD('\n'); } else { netiring.ungetch(c); TTYADD('\r'); if (crmod) TTYADD('\n'); } } else { telrcv_state = TS_CR; TTYADD('\r'); if (crmod) TTYADD('\n'); } } else { TTYADD(c); } continue; case TS_IAC: process_iac: switch (c) { case WILL: telrcv_state = TS_WILL; continue; case WONT: telrcv_state = TS_WONT; continue; case DO: telrcv_state = TS_DO; continue; case DONT: telrcv_state = TS_DONT; continue; case DM: /* * We may have missed an urgent notification, * so make sure we flush whatever is in the * buffer currently. */ printoption("RCVD", IAC, DM); SYNCHing = 1; ttyflush(1); SYNCHing = nlink.stilloob(); settimer(gotDM); break; case SB: SB_CLEAR(); telrcv_state = TS_SB; continue; #if defined(TN3270) case EOR: if (In3270) { if (Ibackp == Ifrontp) { Ibackp = Ifrontp = Ibuf; ISend = 0; /* should have been! */ } else { Ibackp += DataFromNetwork(Ibackp, Ifrontp-Ibackp, 1); ISend = 1; } } printoption("RCVD", IAC, EOR); break;#endif /* defined(TN3270) */ case IAC:#if !defined(TN3270) TTYADD(IAC);#else /* !defined(TN3270) */ if (In3270) { *Ifrontp++ = IAC; } else { TTYADD(IAC); }#endif /* !defined(TN3270) */ break; case NOP: case GA: default: printoption("RCVD", IAC, c); break; } telrcv_state = TS_DATA; continue; case TS_WILL: printoption("RCVD", WILL, c); willoption(c); SetIn3270(); telrcv_state = TS_DATA; continue; case TS_WONT: printoption("RCVD", WONT, c); wontoption(c); SetIn3270(); telrcv_state = TS_DATA; continue; case TS_DO: printoption("RCVD", DO, c); dooption(c); SetIn3270(); if (c == TELOPT_NAWS) { sendnaws(); } else if (c == TELOPT_LFLOW) { localflow = 1; setcommandmode(); setconnmode(0); } telrcv_state = TS_DATA; continue; case TS_DONT: printoption("RCVD", DONT, c); dontoption(c); flushline = 1; setconnmode(0); /* set new tty mode (maybe) */ SetIn3270(); telrcv_state = TS_DATA; continue; case TS_SB: if (c == IAC) { telrcv_state = TS_SE; } else { SB_ACCUM(c); } continue; case TS_SE: if (c != SE) { if (c != IAC) { /* * This is an error. We only expect to get * "IAC IAC" or "IAC SE". Several things may * have happend. An IAC was not doubled, the * IAC SE was left off, or another option got * inserted into the suboption are all possibilities. * If we assume that the IAC was not doubled, * and really the IAC SE was left off, we could * get into an infinate loop here. So, instead, * we terminate the suboption, and process the * partial suboption if we can. */ SB_ACCUM(IAC); SB_ACCUM(c); subpointer -= 2; SB_TERM(); printoption("In SUBOPTION processing, RCVD", IAC, c); suboption(); /* handle sub-option */ SetIn3270(); telrcv_state = TS_IAC; goto process_iac; } SB_ACCUM(c); telrcv_state = TS_SB; } else { SB_ACCUM(IAC); SB_ACCUM(SE); subpointer -= 2; SB_TERM(); suboption(); /* handle sub-option */ SetIn3270(); telrcv_state = TS_DATA; } } } return returnValue;}static int bol = 1, local = 0;int rlogin_susp(void) { if (local) { local = 0; bol = 1; command(0, "z\n", 2); return(1); } return(0);}static int telsnd(void) { // int tcc; // int count; int returnValue = 0; // const char *tbp = NULL; // tcc = 0; // count = 0; while (netoring.empty_count() > 2) { int c, sc; if (!ttyiring.getch(&c)) { break; } returnValue = 1; sc = strip(c); if (rlogin != _POSIX_VDISABLE) { if (bol) { bol = 0; if (sc == rlogin) { local = 1; continue; } } else if (local) { local = 0; if (sc == '.' || c == termEofChar) { bol = 1; command(0, "close\n", 6); continue; } if (sc == termSuspChar) { bol = 1; command(0, "z\n", 2); continue; } if (sc == escapechar && escapechar !=_POSIX_VDISABLE) { int l; char buf[128]; l = ttyiring.gets(buf, sizeof(buf)); command(0, buf, l); bol = 1; flushline = 1; break; } if (sc != rlogin) { ttyiring.ungetch(c); c = sc = rlogin; } } if ((sc == '\n') || (sc == '\r')) bol = 1; } else if (sc == escapechar && escapechar != _POSIX_VDISABLE) { int ignore = 0; /* * Double escape is a pass through of a single escape character. */ if (ttyiring.getch(&c)) { if (strip(c) != escapechar) ttyiring.ungetch(c); else {
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -