📄 ckucon.c
字号:
*ibp++ = c; /* Advance buffer pointer */ ibc++; /* and count. */ } if ((n = ttchk()) > 0) { /* Any more waiting? */ if (n > (IBUFL - ibc)) /* Get them all at once. */ n = IBUFL - ibc; /* Don't overflow buffer */ if ((n = ttxin(n,(CHAR *)ibp)) > 0) {#ifdef CK_ENCRYPTION if (TELOPT_U(TELOPT_ENCRYPTION)) ck_tn_decrypt(ibp,n);#endif /* CK_ENCRYPTION */ ibc += n; /* Advance counter */ } } else if (n < 0) { /* Error? */ return(n); /* Return the error code */ } debug(F101,"CONNECT CKCGETC 2 ibc","",ibc); /* Log how many */ ibp = ibuf; /* Point to beginning of buffer */ } c = *ibp++ & 0xff; /* Get next character from buffer */ ibc--; /* Reduce buffer count */ return(c); /* Return the character */}/* Keyboard handling, buffered for speed, which is needed when C-Kermit is in CONNECT mode between two other computers that are transferring data.*/static char *kbp; /* Keyboard input buffer pointer */static int kbc; /* Keyboard input buffer count */#ifdef CK_SMALL /* Keyboard input buffer length */#define KBUFL 32 /* Small for PDP-11 UNIX */#else#define KBUFL 257 /* Regular kernel size for others */#endif /* CK_SMALL */#ifdef DYNAMICstatic char *kbuf = NULL;#elsestatic char kbuf[KBUFL];#endif /* DYNAMIC *//* Macro for reading keystrokes. */#define CONGKS() (((--kbc)>=0) ? ((int)(*kbp++) & 0377) : kbget())/* Note that we call read() directly here, normally a no-no, but in this case we know it's UNIX and we're only doing what coninc(0) would have done, except we're reading a block of characters rather than just one. There is, at present, no conxin() analog to ttxin() for chunk reads, and instituting one would only add function-call overhead as it would only be a wrapper for a read() call anyway.*//* Another note: We stick in this read() till the user types something. But the other (lower) fork is running too, and on TELNET connections, it will signal us to indicate echo-change negotiations, and this can interrupt the read(). Some UNIXes automatically restart the interrupted system call, others return from it with errno == EINTR.*/static int /* Keyboard buffer filler */kbget() {#ifdef EINTR int tries = 10; /* If read() is interrupted, */ int ok = 0; while (tries-- > 0) { /* try a few times... */#endif /* EINTR */ if ((kbc = conchk()) < 1) /* How many chars waiting? */ kbc = 1; /* If none or dunno, wait for one. */ else if (kbc > KBUFL) /* If too many, */ kbc = KBUFL; /* only read this many. */ if ((kbc = read(0, kbuf, kbc)) < 1) { /* Now read it/them. */ debug(F101,"CONNECT kbget errno","",errno); /* Got an error. */#ifdef EINTR if (errno == EINTR) /* Interrupted system call. */ continue; /* Try again, up to limit. */ else /* Something else. */#endif /* EINTR */ return(-1); /* Pass along read() error. */ }#ifdef EINTR else { ok = 1; break; } } if (!ok) return(-1);#endif /* EINTR */ kbp = kbuf; /* Adjust buffer pointer, */ kbc--; /* count, */ return((int)(*kbp++) & 0377); /* and return first character. */}/* C O N C L D -- Interactive terminal connection child function */static#ifdef BEOSORBEBOXlong#elseVOID#endif /* BEOSORBEBOX */concld (#ifdef BEOSORBEBOX void *bevoid#endif /* BEOSORBEBOX */ ) { int n; /* General purpose counter */ int i; /* For loops... */ int c = -1; /* c is a character, but must be signed integer to pass thru -1, which is the modem disconnection signal, and is different from the character 0377 */ int prev;#ifdef TNCODE int tx; /* tn_doop() return code */#endif /* TNCODE */#ifdef CK_TRIGGER int ix; /* Trigger index */#endif /* CK_TRIGGER */#ifndef NOESCSEQ int apcrc;#endif /* NOESCSEQ */#ifdef COMMENT int conret = 0; /* Return value from conect() */ jbchksum = -1L;#endif /* COMMENT */ jbset = 0; /* jmp_buf not set yet, don't use it */ debug(F101,"CONNECT concld entry","",CK_FORK_SIG); /* *** */ /* Inferior reads, prints port input */ if (priv_can()) { /* Cancel all privs */ printf("?setuid error - fatal\n"); doexit(BAD_EXIT,-1); } signal(SIGINT, SIG_IGN); /* In case these haven't been */ signal(SIGQUIT, SIG_IGN); /* inherited from above... */ signal(CK_FORK_SIG, SIG_IGN); /* CK_FORK_SIG not expected yet */ inshift = outshift = 0; /* Initial SO/SI shift state. */ { /* Wait for parent's setup */ int i; while ((i = read(xpipe[0], &c, 1)) <= 0) { if (i < 0) { debug(F101,"CONNECT concld setup error","",i); debug(F111,"CONNECT concld setup error",ck_errstr(),errno); pipemsg(CEV_HUP); /* Read error - hangup */ ck_sndmsg(); /* Send and wait to be killed */ /* NOTREACHED */ } /* Restart interrupted read() */ } } close(xpipe[0]); xpipe[0] = -1; /* Child - prevent future reads */#ifdef DEBUG if (deblog) { debug(F100,"CONNECT starting port fork","",0); debug(F101,"CONNECT port fork ibc","",ibc); debug(F101,"CONNECT port fork obc","",obc); }#endif /* DEBUG */ what = W_CONNECT; while (1) { /* Fresh read, wait for a character. */#ifdef ANYX25 if (network && (nettype == NET_SX25)) { bzero(x25ibuf,sizeof(x25ibuf)) ; if ((ibufl = ttxin(MAXIX25,(CHAR *)x25ibuf)) < 0) {#ifndef IBMX25 if (ibufl == -2) { /* PAD parms changes */ pipemsg(CEV_PAD); write(xpipe[1],padparms,MAXPADPARMS); ck_sndmsg(); } else {#endif /* IBMX25 */ if (!quiet) printf("\r\nCommunications disconnect "); dologend(); pipemsg(CEV_HUP); ck_sndmsg(); /* Wait to be killed */ /* NOTREACHED */#ifndef IBMX25 }#endif /* IBMX25 */ /* pause(); <--- SHOULD BE OBSOLETE NOW! */ /* BECAUSE pause() is done inside of ck_sndmsg() */ } if (debses) { /* Debugging output */ p = x25ibuf ; while (ibufl--) { c = *p++; conol(dbchr(c)); } } else { if (seslog && sessft) /* Binary session log */ logchar((char)c); /* Log char before translation */ if (sosi#ifndef NOCSETS || tcsl != tcsr#endif /* NOCSETS */ ) { /* Character at a time */ for (i = 1; i < ibufl; i++) { c = x25ibuf[i] & cmask; if (sosi) { /* Handle SI/SO */ if (c == SO) { inshift = 1; continue; } else if (c == SI) { inshift = 0; continue; } if (inshift) c |= 0200; }#ifndef NOCSETS if (inesc == ES_NORMAL) {#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 { 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 */ c &= cmdmsk; /* Apply command mask. */ conoc(c); /* Output to screen */ if (seslog && !sessft) /* and session log */ logchar(c); } } else { /* All at once */ for (i = 1; i < ibufl; i++) x25ibuf[i] &= (cmask & cmdmsk); conxo(ibufl,x25ibuf); if (seslog) zsoutx(ZSFILE,x25ibuf,ibufl); } } continue; } else { /* Not X.25... */#endif /* ANYX25 *//* Get the next communication line character from our internal buffer. If the buffer is empty, refill it.*/ prev = c; /* Remember previous character */ c = ckcgetc(0); /* Get next character */ /* debug(F101,"CONNECT c","",c); */ if (c < 0) { /* Failed... */ debug(F101,"CONNECT disconnect ibc","",ibc); debug(F101,"CONNECT disconnect obc","",obc); ckcputf(); /* Flush CONNECT output buffer */ if (!quiet) { 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 concld i/o error",ck_errstr(),errno); pipemsg(CEV_HUP); ck_sndmsg(); /* Wait to be killed */ }#ifdef COMMENT/* too much... */ debug(F101,"CONNECT ** PORT","",c); /* Got character c OK. */#endif /* COMMENT */#ifdef TNCODE /* Handle TELNET negotiations... */ if ((c == NUL) && network && IS_TELNET()) { if (prev == CR) /* Discard <NUL> of <CR><NUL> */ if (!TELOPT_U(TELOPT_BINARY)) continue; } if ((c == IAC) && network && IS_TELNET()) { 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)) { debug(F101, "CONNECT TELNET me_bin", "", TELOPT_ME(TELOPT_BINARY) ); pipemsg(CEV_MEBIN); /* Tell parent */ write(xpipe[1], &TELOPT_ME(TELOPT_BINARY), sizeof(TELOPT_ME(TELOPT_BINARY)) ); ck_sndmsg(); /* Tell the parent fork */ } else if (u_bin != TELOPT_U(TELOPT_BINARY)) { debug(F101, "CONNECT TELNET u_bin", "", TELOPT_U(TELOPT_BINARY) ); pipemsg(CEV_UBIN); /* Tell parent */ write(xpipe[1], &TELOPT_U(TELOPT_BINARY), sizeof(TELOPT_U(TELOPT_BINARY)) ); ck_sndmsg(); /* Tell the parent fork */ } continue; } else if (tx == -1) { /* I/O error */ if (!quiet) printf("\r\nCommunications disconnect ");#ifdef NOSETBUF fflush(stdout);#endif /* NOSETBUF */ dologend(); debug(F111,"CONNECT concld i/o error 2",ck_errstr(),errno); pipemsg(CEV_HUP); ck_sndmsg(); /* Wait to be killed */ /* NOTREACHED */ } else if (tx == -3) { /* I/O error */ if (!quiet) printf("\r\nConnection closed due to telnet policy ");#ifdef NOSETBUF fflush(stdout);#endif /* NOSETBUF */ dologend(); debug(F111,"CONNECT concld i/o error 2",ck_errstr(),errno); pipemsg(CEV_HUP); ck_sndmsg(); /* Wait to be killed */ /* NOTREACHED */ } else if (tx == -2) { /* I/O error */ if (!quiet) printf("\r\nConnection closed by peer ");#ifdef NOSETBUF fflush(stdout);#endif /* NOSETBUF */ dologend(); debug(F111,"CONNECT concld i/o error 2",ck_errstr(),errno); pipemsg(CEV_HUP); ck_sndmsg(); /* Wait to be killed */ /* NOTREACHED */ } else if ((tx == 1) && (!duplex)) { /* ECHO change */ duplex = 1; /* Turn on local echo */ debug(F101,"CONNECT TELNET duplex change","",duplex); pipemsg(CEV_DUP); /* Tell parent */ write(xpipe[1], &duplex, sizeof(duplex)); ck_sndmsg(); /* Tell the parent fork */ continue; } else if ((tx == 2) && (duplex)) { /* ECHO change */ duplex = 0; debug(F101,"CONNECT TELNET duplex change","",duplex); pipemsg(CEV_DUP); write(xpipe[1], &duplex, sizeof(duplex)); ck_sndmsg(); 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 received */ if (!quiet) printf("\r\nRemote Logout ");#ifdef NOSETBUF fflush(stdout);#endif /* NOSETBUF */ debug(F100,"CONNECT Remote Logout","",0); pipemsg(CEV_HUP); ck_sndmsg(); /* Wait to be killed */
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -