📄 ckucon.c
字号:
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 SUNX25 if (network && (nettype == NET_SX25)) { bzero(x25ibuf,sizeof(x25ibuf)) ; if ((ibufl = ttxin(MAXIX25,(CHAR *)x25ibuf)) < 0) { if (ibufl == -2) { /* PAD parms changes */ pipemsg(CEV_PAD); write(xpipe[1],padparms,MAXPADPARMS); ck_sndmsg(); } else { if (!quiet) printf("\r\nCommunications disconnect "); pipemsg(CEV_HUP); ck_sndmsg(); /* Wait to be killed */ /* NOTREACHED */ } /* 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 (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#ifdef NOESCSEQ /* Translate character sets */ /* From local to intermediate. */ if (sxo) c = (*sxo)(c); /* From intermediate to remote. */ if (rxo) c = (*rxo)(c);#else /* If not inside escape sequence... */ if (inesc == ES_NORMAL) { /* Translate character sets */ if (sxo) c = (*sxo)(c); if (rxo) c = (*rxo)(c); } if (escseq) apcrc = chkaes(c);#endif /* NOESCSEQ */#endif /* NOCSETS */ c &= cmdmsk; /* Apply command mask. */ conoc(c); /* Output to screen */ logchar(c); /* and session log */ } } 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 /* SUNX25 *//* Get the next communication line character from our internal buffer. If the buffer is empty, refill it.*/ 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 "); 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"); }#ifdef NOSETBUF fflush(stdout);#endif /* NOSETBUF */ tthang(); /* Hang up the connection */ pipemsg(CEV_HUP); ck_sndmsg(); /* Wait to be killed */ } debug(F101,"** PORT","",c); /* Got character c OK. */#ifdef TNCODE /* Handle TELNET negotiations... */ if (c == IAC && network && ttnproto == NP_TELNET) { int me_bin = me_binary; int u_bin = u_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 != me_binary) { debug(F101,"CONNECT TELNET me_bin","",me_binary); pipemsg(CEV_MEBIN); /* Tell parent */ write(xpipe[1], &me_binary, sizeof(me_binary)); ck_sndmsg(); /* Tell the parent fork */ } else if (u_bin != u_binary) { debug(F101,"CONNECT TELNET u_bin","",u_binary); pipemsg(CEV_UBIN); /* Tell parent */ write(xpipe[1], &u_binary, sizeof(u_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 */ 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; } else continue; /* Negotiation OK, get next char. */ } else if (parity) c &= 0x7f;#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 */#ifdef CK_APC/* 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? */ 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) { extern CHAR mystch, seol; CHAR buf[6]; int ksign = 0; 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 */ ) { /* Temporarily switch protocol */ sprintf(apcbuf, "set proto %s, %s, set proto %s", ptab[k].p_name, ksign ? "server" : "receive", ptab[protocol].p_name ); apclength = strlen(apcbuf); debug(F110,"autodownload",apcbuf,0); apcactive = APC_LOCAL; if (k == PROTO_K) { /* Kermit */ /* Send a NAK to make them resend S pkt */ sprintf((char *)buf, "%c%s%c", mystch, "# N3", seol ); ttol(buf,6); } ckcputf(); /* Force screen update */ /* Notify parent */ pipemsg(justone ? CEV_AUL : CEV_ADL); /* Write buffer including trailing NUL byte */ write(xpipe[1], (char *)&apclength, sizeof(apclength) ); write(xpipe[1], apcbuf, apclength+1); /* Copy our input buffer to the parent fork */ debug(F101,"autodownload complete ibc","",ibc); debug(F101,"autodownload complete obc","",obc); write(xpipe[1], (char *)&ibc, sizeof(ibc)); if (ibc > 0) { write(xpipe[1], (char *)&ibp, sizeof(ibp)); write(xpipe[1], ibp, ibc); } debug(F101,"autodownload justone","",justone); ck_sndmsg(); /* Wait to be killed */ /* NOTREACHED */ } } }#ifdef NOSERVER noserver:#endif /* NOSERVER */#endif /* CK_APC */ 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; }#ifndef NOCSETS if (#ifndef NOESCSEQ inesc == ES_NORMAL /* If not in an escape sequence */#else 1#endif /* NOESCSEQ */ ) { /* Translate character sets */ if (sxi) c = (*sxi)((CHAR)c); if (rxi) c = (*rxi)((CHAR)c); }#endif /* NOCSETS */#ifndef NOESCSEQ if (escseq) /* If handling escape sequences */ apcrc = chkaes((char)c); /* update our state */#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_OFF) { if (inesc == ES_GOTESC) /* Don't write ESC yet */ continue; else if (oldesc == ES_GOTESC && !apcactive) { ckcputc(ESC); /* Write saved ESC */ if (seslog) logchar((char)ESC); } else if (apcrc) { /* We have an APC */ debug(F111,"APC complete",apcbuf,apclength); ckcputf(); /* Force screen update */ pipemsg(CEV_APC); /* Notify parent */ write(xpipe[1], (char *)&apclength, sizeof(apclength) ); /* Write buffer including trailing NUL byte */ write(xpipe[1], apcbuf, apclength+1); /* Copy our input buffer to the parent fork */ debug(F101,"APC complete ibc","",ibc); debug(F101,"APC complete obc","",obc); write(xpipe[1], (char *)&ibc, sizeof(ibc)); if (ibc > 0) { write(xpipe[1], (char *)&ibp, sizeof(ibp)); write(xpipe[1], ibp, ibc); } ck_sndmsg(); /* Wait to be killed */ /* NOTREACHED */ } }#endif /* CK_APC */#endif /* NOESCSEQ */ if (#ifdef CK_APC !apcactive /* Ignore APC sequences */#else 1#endif /* CK_APC */ ) { c &= cmdmsk; /* Apply command mask. */ if (c == CR && tt_crd) { /* SET TERM CR-DISPLA CRLF? */ ckcputc(c); /* Yes, output CR */ if (seslog) logchar((char)c); c = LF; /* and insert a linefeed */ } ckcputc(c); /* Write character to screen */ } if (seslog) logchar((char)c); /* Handle session log */ }#ifdef SUNX25 } #endif /* SUNX25 */ }}/* C O N E C T -- Interactive terminal connection */intconect() { int n; /* General purpose counter */ int c; /* 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 c2; /* A copy of c */ int csave; /* Another copy of c */#ifdef SUNX25 int i; /* Worker for X.25 code */#endif /* SUNX25 */#ifdef NETCONN#endif /* NETCONN */#ifndef NOESCSEQ int apcrc;#endif /* NOESCSEQ */ int conret = 0; /* Return value from conect() */ /* jbchksum = -1L; */ jbset = 0; /* jmp_buf not set yet, don't use it */ debug(F101,"CONNECT fork signal","",CK_FORK_SIG); signal(CK_FORK_SIG, SIG_IGN); /* Initial CK_FORK_SIG handling, *//* The following ttimoff() call should not be necessary, but evidently there are cases where a timer is left active and then goes off, taking a longjmp to nowhere after the program's stack has changed. In any case, this is safe because the CONNECT module uses no timer of any kind, and no other timer should be armed while Kermit is in CONNECT mode.*/ ttimoff(); /* Turn off any timer interrupts */ if (!local) {#ifdef NETCONN printf("Sorry, you must SET LINE or SET HOST first\n");#else printf("Sorry, you must SET LINE first\n");#endif /* NETCONN */ goto conret0; } if (speed < 0L && network == 0 && ttfdflg == 0) { printf("Sorry, you must SET SPEED first\n"); goto conret0; }#ifdef TCPSOCKET if (network && (nettype != NET_TCPB)#ifdef SUNX25 && (nettype != NET_SX25)#endif /* SUNX25 */ ) { printf("Sorry, network type not supported\n"); goto conret0; }#endif /* TCPSOCKET */#ifdef DYNAMIC if (!ibuf) { if (!(ibuf = malloc(IBUFL+1))) { /* Allocate input line buffer */ printf("Sorry, CONNECT input buffer can't be allocated\n"); goto conret0; } else { ibp = ibuf; ibc = 0; } }
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -