📄 ckctel.c
字号:
/* tn_flui() -- Processes all waiting data for Telnet commands. All non-Telnet data is to be stored into the Telnet Wait Buffer. Returns 1 on success.*/inttn_flui() { extern int ckxech; int x = 0; /* Wait up to 5 sec for responses to outstanding telnet negotiations */ while (x >= 0 && ttchk() > 0 && tn_wait_idx < TN_WAIT_BUF_SZ) { x = ttinc(1); switch (x) { case IAC: x = tn_doop((CHAR)(x & 0xff),inserver?ckxech:duplex,ttinc); debug(F101,"tn_flui tn_doop","",x); switch (x) { case 1: /* Turn on echoing */ duplex = 1; if (inserver) ckxech = 1; break; case 2: /* Turn off echoing */ duplex = 0; if (inserver) ckxech = 0; break; case 3: tn_wait_buf[tn_wait_idx++] = IAC; break; case 4: /* IKS event */ case 6: /* Logout */ break; } break; default: if (x >= 0) tn_wait_buf[tn_wait_idx++] = x; } } return(1);}#ifdef CK_FORWARD_Xint#ifdef CK_ANSICfwdx_tn_sb( unsigned char * sb, int n )#elsefwdx_tn_sb( sb, n ) unsigned char * sb; int n;#endif /* CK_ANSIC */{ unsigned short hchannel, nchannel; unsigned char * p; int rc = -1; /* as a security precaution should add a test here to check to make sure */ /* we have negotiated FORWARD_X with the peer. */ switch (sb[0]) { case FWDX_SCREEN: if (sstelnet && n == 4) rc = fwdx_create_listen_socket(sb[1]); break; case FWDX_OPEN: if ( !sstelnet && n == 5 ) { p = (unsigned char *) &nchannel; p[0] = sb[1]; p[1] = sb[2]; hchannel = ntohs(nchannel); rc = fwdx_open_client_channel(hchannel); if ( rc < 0 ) { /* Failed; Send CLOSE channel */ fwdx_send_close(hchannel); }#ifdef NT if ( !TELOPT_SB(TELOPT_FORWARD_X).forward_x.thread_started ) { ckThreadBegin( &fwdx_thread,32655, 0, FALSE, 0 ) ; TELOPT_SB(TELOPT_FORWARD_X).forward_x.thread_started = 1; }#endif /* NT */ } break; case FWDX_CLOSE: p = (unsigned char *) &nchannel; p[0] = sb[1]; p[1] = sb[2]; hchannel = ntohs(nchannel); rc = fwdx_close_channel(hchannel); break; case FWDX_DATA: p = (unsigned char *) &nchannel; p[0] = sb[1]; p[1] = sb[2]; hchannel = ntohs(nchannel); rc = fwdx_write_data_to_channel(hchannel,(char *)&sb[3],n-5); break; } if ( rc < 0 ) { if ( sstelnet ) { if (tn_sopt(WONT,TELOPT_FORWARD_X) < 0) return(-1); TELOPT_UNANSWERED_WONT(TELOPT_FORWARD_X) = 1; return(-1); } else { if (tn_sopt(DONT,TELOPT_FORWARD_X) < 0) return(-1); TELOPT_UNANSWERED_DONT(TELOPT_FORWARD_X) = 1; return(-1); } } return(0);}intfwdx_send_close(channel) int channel; { int nchannel; CHAR * p; nchannel = htons(channel); p = (unsigned char *) &nchannel; sb[0] = (CHAR) IAC; /* I Am a Command */ sb[1] = (CHAR) SB; /* Subnegotiation */ sb[2] = TELOPT_FORWARD_X; /* Forward X */ sb[3] = FWDX_CLOSE; /* Open */ sb[4] = p[0]; sb[5] = p[1]; sb[6] = (CHAR) IAC; /* End of Subnegotiation */ sb[7] = (CHAR) SE; /* marked by IAC SE */ if (ttol((CHAR *)sb,8) < 0) { /* Send it. */ return(-1); }#ifdef DEBUG if (deblog || tn_deb || debses) { sprintf(tn_msg,"TELNET SENT SB %s CLOSE %02x %02x IAC SE", TELOPT(TELOPT_FORWARD_X),p[0],p[1]); debug(F100,tn_msg,"",0); if (tn_deb || debses) tn_debug(tn_msg); }#endif /* DEBUG */ return(0);}intfwdx_send_open(channel) int channel; { int nchannel; CHAR * p; nchannel = htons(channel); p = (unsigned char *) &nchannel; sb[0] = (CHAR) IAC; /* I Am a Command */ sb[1] = (CHAR) SB; /* Subnegotiation */ sb[2] = TELOPT_FORWARD_X; /* Forward X */ sb[3] = FWDX_OPEN; /* Open */ sb[4] = p[0]; sb[5] = p[1]; sb[6] = (CHAR) IAC; /* End of Subnegotiation */ sb[7] = (CHAR) SE; /* marked by IAC SE */ if (ttol((CHAR *)sb,8) < 0) { /* Send it. */ return(-1); }#ifdef DEBUG if (deblog || tn_deb || debses) { sprintf(tn_msg,"TELNET SENT SB %s OPEN %02x %02x IAC SE", TELOPT(TELOPT_FORWARD_X),p[0],p[1]); debug(F100,tn_msg,"",0); if (tn_deb || debses) tn_debug(tn_msg); }#endif /* DEBUG */ return(0);}#endif /* CK_FORWARD_X */#ifdef IKS_OPTION/* iks_wait() -- Wait for an IKS subnegotiation response. sb - is either KERMIT_REQ_START or KERMIT_REQ_STOP depending on the desired state of the peer's Kermit server. flushok - specifies whether it is ok to throw away non-Telnet data if so, then we call ttflui() instead of tn_flui(). Returns: 1 if the desired state is achieved or if it is unknown. 0 if the desired state is not achieved.*/int#ifdef CK_ANSICiks_wait(int sb, int flushok)#else /* CK_ANSIC */iks_wait(sb,flushok) int sb; int flushok;#endif /* CK_ANSIC */{ int tn_wait_save = tn_wait_flg; int x; if (TELOPT_U(TELOPT_KERMIT)) { switch (sb) { case KERMIT_REQ_START: debug(F111, "iks_wait KERMIT_REQ_START", "u_start", TELOPT_SB(TELOPT_KERMIT).kermit.u_start ); tn_siks(KERMIT_REQ_START); tn_wait_flg = 1; /* Kermit Option MUST wait */ do { if (flushok) tn_wait_idx = 0; x = tn_wait("iks_wait() me_iks_req_start"); } while (x == 0 && flushok && tn_wait_idx == TN_WAIT_BUF_SZ); tn_wait_flg = tn_wait_save; if (flushok) tn_wait_idx = 0; if (tn_wait_idx == TN_WAIT_BUF_SZ) { /* * We are attempting to start a kermit server on the peer * the most likely reason is because we want to perform a * file transfer. But there is a huge amount of non telnet * negotiation data coming in and so we have not been able * to find the response. So we will lie and assume that * response is 'yes'. The worse that will happen is that * a RESP_STOP is received after we enter protocol mode. * And the protocol operation will be canceled. */ tn_push(); return(1); } else { tn_push(); return(TELOPT_SB(TELOPT_KERMIT).kermit.u_start); } case KERMIT_REQ_STOP: debug(F111, "iks_wait KERMIT_REQ_STOP", "u_start", TELOPT_SB(TELOPT_KERMIT).kermit.u_start ); tn_siks(KERMIT_REQ_STOP); tn_wait_flg = 1; /* Kermit Option MUST wait */ do { if (flushok) tn_wait_idx = 0; x = tn_wait("iks_wait() me_iks_req_stop"); } while (x == 0 && flushok && tn_wait_idx == TN_WAIT_BUF_SZ); tn_wait_flg = tn_wait_save; if (flushok) tn_wait_idx = 0; if (tn_wait_idx == TN_WAIT_BUF_SZ) { /* * We are attempting to stop a kermit server on the peer * the most likely reason being that we want to enter * CONNECT mode. But there is a huge amount of non telnet * negotiation data coming in and so we have not been able * to find the response. So we will lie and assume that * the answer is 'yes' and allow the CONNECT command to * succeed. The worst that happens is that CONNECT mode * swallows the incoming data displaying it to the user * and then it resumes Kermit client mode. */ tn_push(); return(1); } else { tn_push(); return(!TELOPT_SB(TELOPT_KERMIT).kermit.u_start); } } tn_push(); } return(1);}int#ifdef CK_ANSICiks_tn_sb( char * sb, int n )#elseiks_tn_sb( sb, n ) char * sb; int n;#endif /* CK_ANSIC */{#ifndef NOXFER extern int server;#ifdef NOICP extern int autodl; int inautodl = 0, cmdadl = 1; extern int local;#else#ifdef CK_AUTODL extern int autodl, inautodl, cmdadl; extern int local;#endif /* CK_AUTODL */#endif /* NOICP */ switch (sb[0]) { case KERMIT_START: /* START */ TELOPT_SB(TELOPT_KERMIT).kermit.u_start = 1; return(4); case KERMIT_STOP: /* STOP */ TELOPT_SB(TELOPT_KERMIT).kermit.u_start = 0; return(4); case KERMIT_REQ_START: /* REQ-START */ if (inserver) {#ifdef CK_AUTODL cmdadl = 1; /* Turn on packet detection */#endif /* CK_AUTODL */ TELOPT_SB(TELOPT_KERMIT).kermit.me_start = 1; tn_siks(KERMIT_RESP_START); } else if (TELOPT_SB(TELOPT_KERMIT).kermit.me_start) { tn_siks(KERMIT_RESP_START); } else {#ifdef CK_AUTODL if ((local && what == W_CONNECT && autodl) || (local && what != W_CONNECT && inautodl) ) tn_siks(KERMIT_RESP_START); /* STOP */ else#endif /* CK_AUTODL */ tn_siks(KERMIT_RESP_STOP); } return(4); case KERMIT_REQ_STOP: /* REQ-STOP */ /* The protocol requires that the request be responded to */ /* either by changing states or by reporting the current */ /* state. */ /* We need to provide the user some way of dictating what */ /* the policies should be. For instance, if we are in */ /* CONNECT mode with autodownload ON and we get a REQ-STOP*/ /* what should the proper response be? */ if (inserver#ifdef CK_AUTODL || !local && cmdadl#endif /* CK_AUTODL */ ) {#ifdef CK_AUTODL cmdadl = 0; /* Turn off packet detection */#endif /* CK_AUTODL */ tn_siks(KERMIT_RESP_STOP); } else if (server) { extern int en_fin; if (en_fin) { /* If the server is allowed to stop */ tn_siks(KERMIT_RESP_STOP); } else { /* We are not allowed to stop */ tn_siks(KERMIT_RESP_START); }#ifdef CK_AUTODL } else if ((local && what == W_CONNECT && autodl) || (local && what != W_CONNECT && inautodl) ) { /* If we are a pseudo-server and the other side requests */ /* that we stop, tell then that we have even though we */ /* have not. Otherwise, the other side might refuse to */ /* enter SERVER mode. */ tn_siks(KERMIT_RESP_STOP); /* STOP */#endif /* CK_AUTODL */ } else { /* If we are not currently in any mode that accepts */ /* Kermit packets then of course report that we are */ /* not being a Kermit server. */ tn_siks(KERMIT_RESP_STOP); /* STOP */ } return(4); case KERMIT_SOP: { /* SOP */ extern CHAR stchr; /* Incoming SOP character */ stchr = sb[1]; TELOPT_SB(TELOPT_KERMIT).kermit.sop = 1; return(4); } case KERMIT_RESP_START: /* START */ TELOPT_SB(TELOPT_KERMIT).kermit.u_start = 1; if (TELOPT_SB(TELOPT_KERMIT).kermit.me_req_start) { TELOPT_SB(TELOPT_KERMIT).kermit.me_req_start = 0; } else if (TELOPT_SB(TELOPT_KERMIT).kermit.me_req_stop) { /* If we have issued a request to stop a Kermit Server */ /* and the response is Start, then we must report this */ /* to the caller. */ TELOPT_SB(TELOPT_KERMIT).kermit.me_req_stop = 0; } return(4); case KERMIT_RESP_STOP: /* STOP */ TELOPT_SB(TELOPT_KERMIT).kermit.u_start = 0; if (TELOPT_SB(TELOPT_KERMIT).kermit.me_req_start) { TELOPT_SB(TELOPT_KERMIT).kermit.me_req_start = 0; /* If we have issued a request to start a Kermit Server */ /* and the response is Stop, then we must report this */ /* to the caller. */ } else if (TELOPT_SB(TELOPT_KERMIT).kermit.me_req_stop) { TELOPT_SB(TELOPT_KERMIT).kermit.me_req_stop = 0; } return(4);
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -