📄 ckucns.c
字号:
#endif /* CK_FORWARD_X */ /* Wait till the first one of the above is ready for i/o */ /* NOTE: here we could implement idle timeouts */ debug(F100,"CONNECT select() waiting...","",0); c = select(16, &in, &out, &err, 0); debug(F101,"CONNECT select()","",c); if (c < 1) {#ifdef EINTR if (c == -1) { if (errno == EINTR) { continue; } }#endif /* EINTR */ sleep(1); continue; }#ifndef BEBOX if (FD_ISSET(scrnout, &out)) { debug(F100,"CONNECT SELECT scrnout","",0); }#endif /* BEBOX */#ifdef CK_FORWARD_X fwdx_check_sockets(&in);#endif /* CK_FORWARD_X */ if (FD_ISSET(ttyfd, &in)) { /* Read from net? */ debug(F110,"CONNECT SELECT ttyfd","in",0); FD_CLR(ttyfd, &in); gotnet = 1; /* Net is ready */ } if (FD_ISSET(kbin, &in)) { /* Read from keyboard? */ debug(F100,"CONNECT SELECT kbin","",0); FD_CLR(kbin, &in); gotkbd = 1; /* Keyboard is ready */ } if (FD_ISSET(ttyfd, &err)) { debug(F110,"CONNECT SELECT ttyfd","err",0); FD_CLR(ttyfd, &err);#ifdef NETPTY#ifdef HAVE_PTYTRAP /* Special handling for HP-UX pty i/o */ if (ttpty) { if (pty_trap_handler(ttyfd) > 0) { ttclos(0); goto conret1; } continue; }#endif /* HAVE_PTYTRAP */#endif /* NETPTY */ gotnet = 1; /* Net is ready (don't set if pty) */ } } debug(F101,"CONNECT gotkbd","",gotkbd); debug(F101,"CONNECT kbc","",kbc);#ifndef NOSETKEY debug(F101,"CONNECT kmptr","",kmptr);#endif /* NOSETKEY */ while (gotkbd || kbc > 0 /* If we have keyboard chars */#ifndef NOSETKEY || kmptr#endif /* NOSETKEY */ ) {#ifndef NOSETKEY if (kmptr) { /* Have current macro? */ debug(F100,"CONNECT kmptr non NULL","",0); if ((c = (CHAR) *kmptr++) == NUL) { /* Get char from it */ kmptr = NULL; /* If no more chars, */ debug(F100,"CONNECT macro empty, continuing","",0); continue; /* reset pointer and continue */ } debug(F000,"CONNECT char from macro","",c); } else { /* No macro... */#endif /* NOSETKEY */#ifdef BEBOX { int rc = 0; if ((rc = recv(kbin,buf,1,0)) > 0) c = buf[0]; else c = -1; debug(F111,"recv","rc",rc); printf("\r\nrecv: %c rc=%d\r\n",buf[0],rc); }#else /* BEBOX */ c = CONGKS(); /* Yes, read from keyboard */#endif /* BEBOX */ gotkbd = 0; /* Turn off select() result flag */#ifndef NOSETKEY }#endif /* NOSETKEY */ if (c == -1) {#ifdef EINTR if (errno == EINTR) continue;#endif /* EINTR */ conoc(BEL); goto conret0; } c &= cmdmsk; /* Do any requested masking */#ifndef NOSETKEY/* Note: kmptr is NULL if we got character c from the keyboard, and it is not NULL if it came from a macro. In the latter case, we must avoid expanding it again.*/ if (!kmptr && macrotab[c]) { /* Macro definition for c? */ debug(F000,"CONNECT macro key",macrotab[c],c); kmptr = macrotab[c]; /* Yes, set up macro pointer */ continue; /* and restart the loop, */ } else c = keymap[c]; /* else use single-char keymap */#endif /* NOSETKEY */ if (#ifndef NOSETKEY !kmptr &&#endif /* NOSETKEY */ (tt_escape && (c & 0x7f) == escape)) { /* Escape char? */ debug(F000,"CONNECT got escape","",c);#ifdef BEBOX if (recv(kbin,buf,1,0)>=0) c = buf[0]; else c = -1;#else /* BEBOX */ c = CONGKS() & 0177; /* Read argument */#endif /* BEBOX */ doesc((char) c); /* Handle it */ continue; /* Back to loop */ } csave = c; /* Save it before translation */ /* for local echoing. */#ifndef NOCSETS if (inesc[1] == ES_NORMAL) { /* If not inside escape seq.. */ /* Translate character sets */#ifdef UNICODE int x; if (unicode == 1) { /* Remote is UTF-8 */ outxcount = b_to_u((CHAR)c,outxbuf,OUTXBUFSIZ,tcssize); outxbuf[outxcount] = NUL; } else if (unicode == 2) { /* Local is UTF-8 */ x = u_to_b((CHAR)c); if (x < 0) continue; outxbuf[0] = (unsigned)(x & 0xff); outxcount = 1; outxbuf[outxcount] = NUL; } else {#endif /* UNICODE */ if (sxo) c = (*sxo)((char)c); /* Local-intermediate */ if (rxo) c = (*rxo)((char)c); /* Intermediate-remote */ outxbuf[0] = c; outxcount = 1; outxbuf[outxcount] = NUL;#ifdef UNICODE }#endif /* UNICODE */ } else { outxbuf[0] = c; outxcount = 1; outxbuf[outxcount] = NUL; } if (escseq) 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 */ (ttnproto == NP_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 && (ttnproto == NP_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) { 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"); active = 0; break; } } } if (FD_ISSET(ttyfd, &out)) { FD_CLR(ttyfd, &out); } while (gotnet > 0 || ibc > 0) { gotnet = 0; 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 */ tthang(); /* Hang up the connection */ debug(F111,"CONNECT i/o error 1",ck_errstr(),errno); goto conret0; }#ifdef TNCODE tx = 0; if ((c == IAC) && network && (ttnproto == NP_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 */ debug(F111,"CONNECT i/o error 2",ck_errstr(),errno); goto conret0; } else if (tx == -2) { /* I/O error */ if (msgflg) printf("\r\nConnection closed by peer");#ifdef NOSETBUF fflush(stdout);#endif /* NOSETBUF */ debug(F111,"CONNECT i/o error 3",ck_errstr(),errno); 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 */ debug(F111,"CONNECT i/o error 4",ck_errstr(),errno); 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. */ 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); 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 */ 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; k = kstart((CHAR)c); /* Kermit S or I packet? */#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++)
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -