📄 ckcnet.c
字号:
#ifdef TCPIPLIB/* For buffered network reads... *//* If the buffering code is written right, it shouldn't matter how long this buffer is.*/#ifdef OS2#ifdef NT#define TTIBUFL 64240 /* 44 * 1460 (MSS) */#else#define TTIBUFL 32120 /* 22 * 1460 (MSS) */#endif /* NT */#else /* OS2 */#define TTIBUFL 8191 /* Let's use 8K. */#endif /* OS2 */CHAR ttibuf[TTIBUFL+1];/* select() is used in preference to alarm()/signal(), but different systems use different forms of select()...*/#ifndef NOSELECT /* Option to override BSDSELECT */#ifdef BELLV10/* Note: Although BELLV10 does have TCP/IP support, and does use the unique form of select() that is evident in this module (and in ckutio.c), it does not have a sockets library and so we can't build Kermit TCP/IP support for it. For this, somebody would have to write TCP/IP streams code.*/#define BELLSELECT#ifndef FD_SETSIZE#define FD_SETSIZE 128#endif /* FD_SETSIZE */#else#ifdef WINTCP /* VMS with Wollongong WIN/TCP */#ifndef OLD_TWG /* TWG 3.2 has only select(read) */#define BSDSELECT#endif /* OLD_TWG */#else#ifdef CMU_TCPIP /* LIBCMU can do select */#define BSDSELECT#else#ifdef DEC_TCPIP#define BSDSELECT#else#ifdef OS2 /* OS/2 with TCP/IP */#ifdef NT#define BSDSELECT#else /* NT */#define IBMSELECT#endif /* NT */#endif /* OS2 */#endif /* DEC_TCPIP */#endif /* CMU_TCPIP */#endif /* WINTCP */#endif /* BELLV10 */#endif /* NOSELECT *//* Others (TGV, TCPware, ...) use alarm()/signal(). The BSDSELECT case does not compile at all; the IBMSELECT case compiles and links but crashes at runtime. NOTE: If any of these can be converted to select(), they should be for two reasons: (1) It's a lot faster; (2) certain sockets libraries do not like their socket_read() calls to be interrupted; subsequent socket_read()'s tend to fail with EBUSY. This happened in the UCX case before it was converted to use select().*/#ifndef OS2#ifndef VMSstatic /* These are used in CKVTIO.C */#endif /* VMS */ /* And in CKONET.C */#endif /* OS2 */int ttibp = 0, ttibn = 0;/* Read bytes from network into internal buffer ttibuf[]. To be called when input buffer is empty, i.e. when ttibn == 0. Other network reading routines, like ttinc, ttinl, ttxin, should check the internal buffer first, and call this routine for a refill if necessary. Returns -1 on error, 0 if nothing happens. When data is read successfully, returns number of bytes read, and sets global ttibn to that number and ttibp (the buffer pointer) to zero.*/_PROTOTYP( int ttbufr, ( VOID ) );intttbufr() { /* TT Buffer Read */ int count; if (ttnet != NET_TCPB) /* First make sure current net is */ return(-1); /* TCP/IP; if not, do nothing. */ if (ttibn > 0) /* Our internal buffer is not empty, */ return(ttibn); /* so keep using it. */ ttibp = 0; /* Else reset pointer to beginning */ if (ttyfd == -1) /* No connection, error */ return(-2);#ifdef WINTCP count = 512; /* This works for WIN/TCP */#else#ifdef DEC_TCPIP count = 512; /* UCX */#else#ifdef OS2 count = TTIBUFL;#else /* Multinet, etc. */ count = ttchk(); /* Check network input buffer, */ if (ttibn > 0) { /* which can put a char there! */ debug(F111,"ttbufr","ttchk() returns",count); return(ttibn); } if (count < 0) /* Read error - connection closed */ return(-2); else if (count > TTIBUFL) /* Too many to read */ count = TTIBUFL; else if (count == 0) /* None, so force blocking read */ count = 1;#endif /* OS2 */#endif /* DEC_TCPIP */#endif /* WINTCP */ debug(F101,"ttbufr count 1","",count);#ifdef CK_SSL if (ssl_active_flag || tls_active_flag) { int error; if (ssl_active_flag) count = SSL_read(ssl_con, ttibuf, count); else count = SSL_read(tls_con, ttibuf, count); switch (SSL_get_error(ssl_active_flag?ssl_con:tls_con,count)) { case SSL_ERROR_NONE: debug(F111,"ttbufr SSL_ERROR_NONE","count",count); if (count > 0) { ttibp = 0; /* Reset buffer pointer. */ ttibn = count; return(ttibn); /* Return buffer count. */ } else if (count < 0) { return(-1); } else { netclos(); return(-2); } case SSL_ERROR_WANT_WRITE: debug(F100,"ttbufr SSL_ERROR_WANT_WRITE","",0); return(-1); case SSL_ERROR_WANT_READ: debug(F100,"ttbufr SSL_ERROR_WANT_READ","",0); return(-1); case SSL_ERROR_SYSCALL:#ifdef NT debug(F111,"ttbufr SSL_ERROR_SYSCALL", "GetLastError()",GetLastError());#endif /* NT */ netclos(); return(-2); case SSL_ERROR_WANT_X509_LOOKUP: debug(F100,"ttbufr SSL_ERROR_WANT_X509_LOOKUP","",0); netclos(); return(-2); case SSL_ERROR_SSL: debug(F100,"ttbufr SSL_ERROR_SSL","",0); netclos(); return(-2); case SSL_ERROR_ZERO_RETURN: debug(F100,"ttbufr SSL_ERROR_ZERO_RETURN","",0); netclos(); return(-2); default: debug(F100,"ttbufr SSL_ERROR_?????","",0); netclos(); return(-2); } }#endif /* CK_SSL */#ifdef COMMENT/* This is for nonblocking reads, which we don't do any more. This code didn't work anyway, in the sense that a broken connection was never sensed.*/ if ((count = socket_read(ttyfd,&ttibuf[ttibp+ttibn],count)) < 1) { if (count == -1 && socket_errno == EWOULDBLOCK) { debug(F100,"ttbufr finds nothing","",0); return(0); } else { debug(F101,"ttbufr socket_read error","",socket_errno); return(-1); } } else if (count == 0) { debug(F100,"ttbufr socket eof","",0); return(-1); }#else /* COMMENT *//* This is for blocking reads */#ifndef VMS#ifdef SO_OOBINLINE { int outofband = 0;#ifdef BELLSELECT if (select(128, NULL, NULL, efds, 0) > 0 && FD_ISSET(ttyfd, efds)) outofband = 1;#else#ifdef BSDSELECT fd_set efds; struct timeval tv; FD_ZERO(&efds); FD_SET(ttyfd, &efds); tv.tv_sec = tv.tv_usec = 0L; debug(F100,"Out-of-Band BSDSELECT","",0);#ifdef NT WSASafeToCancel = 1;#endif /* NT */ if (select(FD_SETSIZE, NULL, NULL, &efds, &tv) > 0 && FD_ISSET(ttyfd, &efds)) outofband = 1;#ifdef NT WSASafeToCancel = 0;#endif /* NT */#else /* !BSDSELECT */#ifdef IBMSELECT/* Was used by OS/2, currently not used, but might come in handy some day... *//* ... and it came in handy! For our TCP/IP layer, it avoids all the fd_set *//* and timeval stuff since this is the only place where it is used. */ int socket = ttyfd; debug(F100,"Out-of-Band IBMSELECT","",0); if ((select(&socket, 0, 0, 1, 0L) == 1) && (socket == ttyfd)) outofband = 1;#else /* !IBMSELECT *//* If we can't use select(), then we use the regular alarm()/signal() timeout mechanism.*/ debug(F101,"Out-of-Band data not supported","",0); outofband = 0;#endif /* IBMSELECT */#endif /* BSDSELECT */#endif /* BELLSELECT */ if (outofband) { /* Get the Urgent Data */ /* if OOBINLINE is disabled this should be only a single byte */ /* MS Winsock has a bug in Windows 95. Extra bytes are delivered */ /* That were never sent. */#ifdef OS2 RequestTCPIPMutex(SEM_INDEFINITE_WAIT);#endif /* OS2 */ count = socket_recv(ttyfd,&ttibuf[ttibp+ttibn],count,MSG_OOB);#ifdef OS2 ReleaseTCPIPMutex();#endif /* OS2 */ if (count <= 0) { int s_errno = socket_errno; debug(F101, "ttbufr socket_recv MSG_OOB","",count); debug(F101, "ttbufr socket_errno","",s_errno);#ifdef OS2ONLY if (count < 0 && (s_errno == 0 || s_errno == 23)) { /* These appear in OS/2 - don't know why */ /* ignore it and read as normal data */ /* and break, then we will attempt to read */ /* the port using normal read() techniques */ debug(F100,"ttbufr handing as in-band data","",0); count = 1; } else { netclos(); /* *** *** */ return(-2); }#else /* OS2ONLY */ netclos(); /* *** *** */ return(-2);#endif /* OS2ONLY */ } else { /* we got out-of-band data */ hexdump("ttbufr out-of-band chars",&ttibuf[ttibp+ttibn],count);#ifdef BETATEST bleep(BP_NOTE);#endif /* BETATEST */#ifdef RLOGCODE /* blah */ if (ttnproto == NP_RLOGIN || ttnproto == NP_K4LOGIN || ttnproto == NP_EK4LOGIN || ttnproto == NP_K5LOGIN || ttnproto == NP_EK5LOGIN ) { /* When urgent data is read with MSG_OOB and not OOBINLINE then urgent data and normal data are not mixed. So treat the entire buffer as urgent data. */ rlog_oob(&ttibuf[ttibp+ttibn], count); return ttbufr(); } else#endif /* RLOGCODE */ /* blah */#ifdef COMMENT /* I haven't written this yet, nor do I know what it should do */ if (ttnproto == NP_TELNET) { tn_oob(); return 0; } else#endif /* COMMENT */ { /* For any protocols we don't have a special out-of-band */ /* handler for, just put the bytes in the normal buffer */ /* and return */#ifdef OS2 RequestTCPIPMutex(SEM_INDEFINITE_WAIT);#endif /* OS2 */ ttibp += 0; /* Reset buffer pointer. */ ttibn += count;#ifdef OS2 ReleaseTCPIPMutex();#endif /* OS2 */#ifdef DEBUG /* Got some bytes. */ debug(F101,"ttbufr count 2","",count); if (count > 0) ttibuf[ttibp+ttibn] = '\0'; debug(F111,"ttbufr ttibuf",ttibuf,ttibp);#endif /* DEBUG */ return(ttibn); /* Return buffer count. */ } } } }#endif /* SO_OOBINLINE */#endif /* VMS */#ifdef OS2 RequestTCPIPMutex(SEM_INDEFINITE_WAIT);#endif /* OS2 */ count = socket_read(ttyfd,&ttibuf[ttibp+ttibn],count);#ifdef OS2 ReleaseTCPIPMutex();#endif /* OS2 */ if (count <= 0) { int s_errno = socket_errno; debug(F101,"ttbufr socket_read","",count); debug(F101,"ttbufr socket_errno","",s_errno);#ifdef OS2 if (count == 0 || os2socketerror(s_errno) < 0) { netclos(); return(-2); } return(-1);#else /* OS2 */ netclos(); /* *** *** */ return(-2);#endif /* OS2 */ }#endif /* COMMENT */ /* (blocking vs nonblock reads...) */ else {#ifdef OS2 RequestTCPIPMutex(SEM_INDEFINITE_WAIT);#endif /* OS2 */ ttibp = 0; /* Reset buffer pointer. */ ttibn += count;#ifdef OS2 ReleaseTCPIPMutex();#endif /* OS2 */#ifdef DEBUG debug(F101,"ttbufr count 2","",count); /* Got some bytes. */ if (count > 0) ttibuf[ttibp+ttibn] = '\0'; debug(F111,"ttbufr ttibuf",&ttibuf[ttibp],ttibn);#endif /* DEBUG */ return(ttibn); /* Return buffer count. */ }}#endif /* TCPIPLIB */#ifndef IBMSELECT#ifndef BELLSELECT#ifndef BSDSELECT /* Non-TCPIPLIB case */#ifdef SELECT#define BSDSELECT#endif /* SELECT */#endif /* BSDSELECT */#endif /* BELLSELECT */#endif /* IBMSELECT */#define TELNET_PORT 23 /* Should do lookup, but it won't change */#define RLOGIN_PORT 513#define KERMIT_PORT 1649#define KLOGIN_PORT 543#define EKLOGIN_PORT 2105/* Type needed as 5th argument (length) to get/setsockopt() */#ifndef SOCKOPT_T#define SOCKOPT_T int#ifdef AIX42#undef SOCKOPT_T#define SOCKOPT_T unsigned long#else#ifdef PTX#undef SOCKOPT_T#define SOCKOPT_T size_t#else#ifdef NT#undef SOCKOPT_T#define SOCKOPT_T int#else /* NT */#ifdef UNIXWARE#undef SOCKOPT_T#define SOCKOPT_T size_t#else /* UNIXWARE */#ifdef VMS#ifdef DEC_TCPIP#ifdef __DECC_VER#undef SOCKOPT_T#define SOCKOPT_T size_t#endif /* __DECC_VER */#endif /* DEC_TCPIP */#endif /* VMS */#endif /* UNIXWARE */
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -