📄 ckucns.c
字号:
apcrc = chkaes((char)c,1);#else outxbuf[0] = c; outxcount = 1; outxbuf[outxcount] = NUL;#endif /* NOCSETS */ debug(F111,"OUTXBUF",outxbuf,outxcount); for (i = 0; i < outxcount; i++) { c = outxbuf[i];/* If Shift-In/Shift-Out is selected and we have a 7-bit connection, handle shifting here.*/ if (sosi) { /* Shift-In/Out selected? */ if (cmask == 0177) { /* In 7-bit environment? */ if (c & 0200) { /* 8-bit character? */ if (outshift == 0) { /* If not shifted, */ ttoc(dopar(SO)); /* shift. */ outshift = 1; } } else { if (outshift == 1) { /* 7-bit character */ ttoc(dopar(SI)); /* If shifted, */ outshift = 0; /* unshift. */ } } } if (c == SO) outshift = 1; /* User typed SO */ if (c == SI) outshift = 0; /* User typed SI */ } c &= cmask; /* Apply Kermit-to-host mask now. */ if (c == '\015') { /* Carriage Return */ int stuff = -1; if (tnlm) { /* TERMINAL NEWLINE ON */ stuff = LF; /* Stuff LF */#ifdef TNCODE } else if (network && /* TELNET NEWLINE ON/OFF/RAW */ IS_TELNET()) { switch (!TELOPT_ME(TELOPT_BINARY) ? tn_nlm : tn_b_nlm){ case TNL_CRLF: stuff = LF; break; case TNL_CRNUL: stuff = NUL; break; }#endif /* TNCODE */ } if (stuff > -1) { ttoc(dopar('\015')); /* Send CR */ if (duplex) conoc('\015'); /* Maybe echo CR */ c = stuff; /* Char to stuff */ csave = c; } }#ifdef TNCODE/* If user types the 0xff character (TELNET IAC), it must be doubled. */ else /* Not CR */ if ((dopar((CHAR) c) == IAC) && /* IAC (0xff) */ network && IS_TELNET()) { /* Send one now */ ttoc((char)IAC); /* and the other one just below. */ }#endif /* TNCODE */ /* Send the character */ x = ttoc((char)dopar((CHAR) c)); if (x > -1) {#ifdef CKLEARN if (learning) { /* Learned script active */ if (crflag) { /* User typed CR */ learnchar(CR); /* Handle CR */ learnst = 0; /* Shift to Neutral */ } else { learnchar(c); /* Not CR */ learnst = 2; /* Change state to Keyboard */ } }#endif /* CKLEARN */ if (duplex) { /* If half duplex, must echo */ if (debses) conol(dbchr(csave)); /* the original char */ else /* not the translated one */ conoc((char)csave); if (seslog) { /* And maybe log it too */ c2 = csave; if (sessft == 0 && csave == '\r') c2 = '\n'; logchar((char)c2); } } } else { perror("\r\nCan't send character"); cx_status = CSX_IOERROR; active = 0; break; } } } if (FD_ISSET(ttyfd, &out)) { FD_CLR(ttyfd, &out); } while (gotnet > 0 || ibc > 0) { gotnet = 0; prev = c; c = ckcgetc(0); /* Get next character */ /* debug(F101,"CONNECT c","",c); */ if (c < 0) { /* Failed... */ ckcputf(); /* Flush CONNECT output buffer */ if (msgflg) { printf("\r\nCommunications disconnect ");#ifdef COMMENT if (c == -3#ifdef ultrix/* This happens on Ultrix if there's no carrier */ && errno != EIO#endif /* ultrix */#ifdef UTEK/* This happens on UTEK if there's no carrier */ && errno != EWOULDBLOCK#endif /* UTEK */ ) perror("\r\nCan't read character");#endif /* COMMENT */ }#ifdef NOSETBUF fflush(stdout);#endif /* NOSETBUF */ dologend(); tthang(); /* Hang up the connection */ debug(F111,"CONNECT i/o error 1",ck_errstr(),errno); cx_status = CSX_HOSTDISC; goto conret0; }#ifdef TNCODE tx = 0; if ((c == NUL) && network && IS_TELNET()) { if (prev == CR) { /* Discard <NUL> of <CR><NUL> if peer */ if (!TELOPT_U(TELOPT_BINARY)) { /* not in binary mode */ debug(F111,"CONNECT NUL",ckitoa(prev),c); ckcputf(); /* Flush screen output buffer */ break; } } } debug(F111,"CONNECT","c",c); debug(F111,"CONNECT","network",network); debug(F111,"CONNECT","IS_TELNET",IS_TELNET()); if ((c == IAC) && network && IS_TELNET()) {#ifdef CK_ENCRYPTION int x_auth = TELOPT_ME(TELOPT_AUTHENTICATION);#else int x_auth = 0;#endif /* CK_ENCRYPTION */ int me_bin = TELOPT_ME(TELOPT_BINARY); int u_bin = TELOPT_U(TELOPT_BINARY); debug(F100,"CONNECT got IAC","",0); ckcputf(); /* Dump screen-output buffer */ if ((tx = tn_doop((CHAR)(c & 0xff),duplex,ckcgetc)) == 0) { if (me_bin != TELOPT_ME(TELOPT_BINARY)) { me_bin = TELOPT_ME(TELOPT_BINARY); } else if (u_bin != TELOPT_U(TELOPT_BINARY)) { u_bin = TELOPT_U(TELOPT_BINARY);#ifdef CK_ENCRYPTION/* Here we have to push back any bytes we have read using block reads, so we can read them again using single-character reads, so they can be decrypted in case there was a switch to encryption in the block. Note that we can't handle switches in the encryption state itself this way -- which would be nice, since it would eliminate the need for single-character reads. Why? Because if a series of characters has already been decrypted that shouldn't have been, then (a) it's ruined, and (b) so is the state of the decryption machine. Too bad.*/ } else if (TELOPT_ME(TELOPT_AUTHENTICATION) != 0 && TELOPT_ME(TELOPT_AUTHENTICATION) != x_auth ) { if (ttpushback((CHAR *)ibp,ibc) > -1) { ibc = 0; ibp = ibuf; }#endif /* CK_ENCRYPTION */ } continue; } else if (tx == -1) { /* I/O error */ if (msgflg) printf("\r\nCommunications disconnect ");#ifdef NOSETBUF fflush(stdout);#endif /* NOSETBUF */ dologend(); debug(F111,"CONNECT i/o error 2",ck_errstr(),errno); cx_status = CSX_IOERROR; goto conret0; } else if (tx == -2) { /* I/O error */ if (msgflg) printf("\r\nConnection closed by peer");#ifdef NOSETBUF fflush(stdout);#endif /* NOSETBUF */ dologend(); debug(F111,"CONNECT i/o error 3",ck_errstr(),errno); cx_status = CSX_IOERROR; goto conret0; } else if (tx == -3) { /* I/O error */ if (msgflg) printf("\r\nConnection closed due to telnet policy");#ifdef NOSETBUF fflush(stdout);#endif /* NOSETBUF */ dologend(); debug(F111,"CONNECT i/o error 4",ck_errstr(),errno); cx_status = CSX_IOERROR; goto conret0; } else if ((tx == 1) && (!duplex)) { /* ECHO change */ duplex = 1; /* Turn on local echo */ continue; } else if ((tx == 2) && (duplex)) { /* ECHO change */ duplex = 0; continue; } else if (tx == 3) { /* Quoted IAC */ c = parity ? 127 : 255; }#ifdef IKS_OPTION else if (tx == 4) { /* IKS State Change */ if (TELOPT_SB(TELOPT_KERMIT).kermit.u_start && !tcp_incoming ) { /* here we need to print a msg that the other */ /* side is in SERVER mode and that REMOTE */ /* commands should be used. And CONNECT mode */ /* should be ended. */ cx_status = CSX_IKSD; active = 0; } }#endif /* IKS_OPTION */ else if (tx == 6) { /* DO LOGOUT was received */ if (msgflg) printf("\r\nRemote Logout ");#ifdef NOSETBUF fflush(stdout);#endif /* NOSETBUF */ debug(F100,"CONNECT Remote Logout","",0); cx_status = CSX_TRIGGER; goto conret0; } else continue; /* Negotiation OK, get next char. */ } else if (parity) c &= 0x7f; /* I'm echoing for the remote */ if (TELOPT_ME(TELOPT_ECHO) && tn_rem_echo) ttoc((char)c);#endif /* TNCODE */#ifdef CKLEARN /* Learned script: Record incoming chars if not in Keyboard state */ if (learning && learnst != 2) { /* Learned script active */ learnbuf[learnbp++] = c; /* Save for INPUT command */ if (learnbp >= LEARNBUFSIZ) /* in circular buffer */ learnbp = 0; /* wrapping if at end. */ learnbc++; /* Count this byte. */ learnst = 1; /* State is Net. */ }#endif /* CKLEARN */ if (debses) { /* Output character to screen */ char *s; /* Debugging display... */ s = dbchr(c); while (*s) ckcputc(*s++); } else { /* Regular display ... */ c &= cmask; /* Apply Kermit-to-remote mask */ if (seslog && sessft) /* If binary session log */ logchar((char)c); /* log the character now. */#ifndef NOXFER#ifdef CK_AUTODL/* Autodownload. Check for Kermit S packet prior to translation, since that can change the packet and make it unrecognizable (as when the terminal character set is an ISO 646 one)... Ditto for Zmodem start packet.*/ if (autodl /* Autodownload enabled? */#ifdef IKS_OPTION || TELOPT_SB(TELOPT_KERMIT).kermit.me_start#endif /* IKS_OPTION */ ) { int k = 0; if (kstartactive || c == stchr /* Kermit S or I packet? */#ifdef COMMENT || adl_kmode == ADLSTR /* Not used in C-Kermit */#endif /* COMMENT */ ) k = kstart((CHAR)c);#ifdef CK_XYZ if (!k && zmdlok) /* Or an "sz" start? */ k = zstart((CHAR)c);#endif /* CK_XYZ */ if (k) { int ksign = 0; debug(F101,"CONNECT autodownload k","",k); if (k < 0) { /* Minus-Protocol? */#ifdef NOSERVER goto noserver; /* Need server mode for this */#else ksign = 1; /* Remember */ k = 0 - k; /* Convert to actual protocol */ justone = 1; /* Flag for protocol module */#endif /* NOSERVER */ } else justone = 0; k--; /* Adjust [kz]start's return value */ if (k == PROTO_K#ifdef CK_XYZ || k == PROTO_Z#endif /* CK_XYZ */ ) { /* Damage the packet so that it doesn't trigger */ /* autodownload detection downstream. */ if (k == PROTO_K) { int i, len = strlen((char *)ksbuf); for (i = 0; i < len; i++) ckcputc(BS); }#ifdef CK_XYZ else { int i; for (i = 0; i < 3; i++) ckcputc(CAN); }#endif /* CK_XYZ */#ifndef NOICP /* sprintf is safe here (builtin keywords) */ sprintf(apcbuf, "set proto %s, %s, set proto %s", ptab[k].p_name, ksign ? "server" : "receive", ptab[protocol].p_name ); apclength = strlen(apcbuf); debug(F111,"CONNECT ksbuf",ksbuf,k); debug(F110,"CONNECT autodownload",apcbuf,0); apcactive = APC_LOCAL; ckcputf(); /* Force screen update */ cx_status = CSX_APC; goto conret1;#else/* Here's another way that doesn't require APC, but then we'll have to change all the other CONNECT modules, and then the mainline code that calls them.*/ { extern char sstate; sstate = ksign ? 'x' : 'v'; proto(); }#endif /* NOICP */ } } }#ifdef NOSERVER noserver:#endif /* NOSERVER */#endif /* CK_AUTODL */#endif /* NOXFER */ if (sosi) { /* Handle SI/SO */ if (c == SO) { /* Shift Out */ inshift = 1; continue; } else if (c == SI) { /* Shift In */ inshift = 0; continue; } if (inshift) c |= 0200; } inxbuf[0] = c; /* In case there is no translation */ inxcount = 1; /* ... */#ifndef NOCSETS if (inesc[0] == ES_NORMAL /* If not in an escape sequence */ && !printing /* and not in transparent print */ ) { /* Translate character sets */#ifdef UNICODE int x; if (unicode == 1) { /* Remote is UTF-8 */ x = u_to_b((CHAR)c); if (x == -1) continue; else if (x == -2) { /* LS or PS */ inxbuf[0] = CR; inxbuf[1] = LF; inxcount = 2; } else if (x == -9) { /* UTF-8 error */ inxbuf[0] = '?'; inxbuf[1] = u_to_b2(); inxcount = 2; } else { inxbuf[0] = (unsigned)(x & 0xff); } c = inxbuf[0]; } else if (unicode == 2) { /* Local is UTF-8 */ inxcount = b_to_u((CHAR)c,inxbuf,OUTXBUFSIZ,tcssize); c = inxbuf[0]; } else {#endif /* UNICODE */ if (sxi) c = (*sxi)((CHAR)c); if (rxi) c = (*rxi)((CHAR)c); inxbuf[0] = c;#ifdef UNICODE }#endif /* UNICODE */ }#endif /* NOCSETS */#ifndef NOESCSEQ if (escseq) { /* If handling escape sequences */ oldprt = printing; /* remember printer state */ apcrc = chkaes((char)c,0); /* and update escseq state. */ if (printing && !oldprt) /* If printer was turned on */ continue; /* don't print final char of escseq */ }#ifdef CK_APC/* If we are handling APCs, we have several possibilities at this point: 1. Ordinary character to be written to the screen. 2. An Esc; we can't write it because it might be the beginning of an APC. 3. The character following an Esc, in which case we write Esc, then char, but only if we have not just entered an APC sequence.*/ if (escseq && (apcstatus & APC_ON)) { if (inesc[0] == ES_GOTESC) /* Don't write ESC yet */ continue; else if (oldesc[0] == ES_GOTESC && !apcactive) { ckcputc(ESC); /* Write saved ESC */ if (seslog && !sessft) logchar((char)ESC); } else if (apcrc) { /* We have an APC */ debug(F111,"CONNECT APC complete",apcbuf,apclength); ckcputf(); /* Force s
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -