📄 ckcnet.c
字号:
#endif /* NT */#endif /* PTX */#endif /* AIX42 */#endif /* SOCKOPT_T *//* Ditto for getsockname() */#ifndef GSOCKNAME_T#define GSOCKNAME_T int#ifdef PTX#undef GSOCKNAME_T#define GSOCKNAME_T size_t#else#ifdef AIX42 /* size_t in 4.2++, int in 4.1-- */#undef GSOCKNAME_T#define GSOCKNAME_T size_t#else#ifdef UNIXWARE#undef GSOCKNAME_T#define GSOCKNAME_T size_t#else#ifdef VMS#ifdef DEC_TCPIP#ifdef __DECC_VER#undef GSOCKNAME_T#define GSOCKNAME_T size_t#endif /* __DECC_VER */#endif /* DEC_TCPIP */#endif /* VMS */#endif /* UNIXWARE */#endif /* AIX41 */#endif /* PTX */#endif /* GSOCKNAME_T */#ifndef NOLOCAL/* C-Kermit network open/close functions for BSD-sockets. Much of this code shared by SunLink X.25, which also uses the socket library.*//* N E T O P N -- Open a network connection. *//* Call with: name of host (or host:service), lcl - local-mode flag to be set if this function succeeds, network type - value defined in ckunet.h.*/#ifdef TCPSOCKET#ifdef EXCELAN/* Most other BSD sockets implementations define these in header files and libraries.*/struct servent { unsigned short s_port;};struct hostent { short h_addrtype; struct in_addr h_addr; int h_length;};struct servent *getservbyname(service, connection) char *service,*connection; { static struct servent servrec; int port; port = 0; if (strcmp(service, "telnet") == 0) port = 23; else if (strcmp(service, "smtp") == 0) port = 25; else port = atoi(service); debug(F101,"getservbyname return port ","",port); if (port > 0) { servrec.s_port = htons(port); return(&servrec); } return((struct servent *) NULL);}struct hostent *gethostbyname(hostname) char *hostname; { return((struct hostent *) NULL);}unsigned longinet_addr(name) char *name; { unsigned long addr; addr = rhost(&name); debug(F111,"inet_addr ",name,(int)addr); return(addr);}char *inet_ntoa(in) struct in_addr in; { static char name[80]; sprintf(name, "%d.%d.%d.%d", in.s_net, in.s_host, in.s_lh, in.s_impno); return(name);}#else#ifdef DEC_TCPIP /* UCX */int ucx_port_bug = 0; /* Explained below */#ifndef __DECC /* VAXC or GCC */#define getservbyname my_getservbyname#ifdef CK_ANSICglobalref int (*C$$GA_UCX_GETSERVBYNAME)();extern void C$$TRANSLATE();extern void C$$SOCK_TRANSLATE();#elseglobalref int (*C$$GA_UCX_GETSERVBYNAME)();extern VOID C$$TRANSLATE();extern VOID C$$SOCK_TRANSLATE();#endif /* CK_ANSIC */struct servent *my_getservbyname (service, proto) char *service, *proto; { static struct servent sent; struct iosb { union { unsigned long status; unsigned short st[2]; } sb; unsigned long spare; } s; struct { struct iosb *s; char *serv; char *prot; } par; unsigned long e; char sbuf[30], pbuf[30]; char *p; debug(F111,"UCX getservbyname",service,(int)C$$GA_UCX_GETSERVBYNAME); p = sbuf; ckstrncpy(p, service, 29); while (*p = toupper(*p), *p++) {} p = pbuf; ckstrncpy(p, proto, 29); while (*p = toupper(*p), *p++) {} par.s = &s; par.serv = ""; par.prot = ""; /* reset file pointer or something like that!?!? */ e = (*C$$GA_UCX_GETSERVBYNAME)(&par, &sent, par.s); par.serv = sbuf; par.prot = pbuf; /* that is don't care */ e = (*C$$GA_UCX_GETSERVBYNAME)(&par, &sent, par.s); if ((long)e == -1L) return NULL; if ((e & 1) == 0L) { C$$TRANSLATE(e); return NULL; } if ((s.sb.st[0] & 1) == 0) { C$$SOCK_TRANSLATE(&s.sb.st[0]); return NULL; }/* sent.s_port is supposed to be returned by UCX in network byte order. However, UCX 2.0 through 2.0C did not do this; 2.0D and later do it. But there is no way of knowing which UCX version, so we have a user-settable runtime variable. Note: UCX 2.0 was only for the VAX.*/ debug(F101,"UCX getservbyname port","",sent.s_port); debug(F101,"UCX getservbyname ntohs(port)","",ntohs(sent.s_port)); if (ucx_port_bug) { sent.s_port = htons(sent.s_port); debug(F100,"UCX-PORT-BUG ON: swapping bytes","",0); debug(F101,"UCX swapped port","",sent.s_port); debug(F101,"UCX swapped ntohs(port)","",ntohs(sent.s_port)); } return &sent;}#endif /* __DECC */#endif /* DEC_TCPIP */#endif /* EXCELAN */#endif /* TCPSOCKET */#ifndef NOTCPOPTS#ifndef datageneralintck_linger(onoff, timo) int onoff; int timo; {/* The following, from William Bader, turns off the socket linger parameter, which makes a close() block until all data is sent. "I don't think that disabling linger can ever cause kermit to lose data, but you telnet to a flaky server (or to our modem server when the modem is in use), disabling linger prevents kermit from hanging on the close if you try to exit." Modified by Jeff Altman to be generally useful.*/#ifdef SOL_SOCKET#ifdef SO_LINGER struct linger set_linger_opt; struct linger get_linger_opt; SOCKOPT_T x; if (ttyfd == -1 || nettype != NET_TCPA && nettype != NET_TCPB || ttmdm >= 0) { tcp_linger = onoff; tcp_linger_tmo = timo; return(1); } x = sizeof(get_linger_opt); if (getsockopt(ttyfd, SOL_SOCKET, SO_LINGER, (char *)&get_linger_opt, &x)) { debug(F111,"TCP ck_linger can't get SO_LINGER",ck_errstr(),errno); } else if (x != sizeof(get_linger_opt)) {#ifdef OS2 struct _linger16 { short s_linger; short s_onoff; } get_linger_opt16, set_linger_opt16; if ( x == sizeof(get_linger_opt16) ) { debug(F111,"TCP setlinger warning: SO_LINGER","len is 16-bit",x); if (getsockopt(ttyfd, SOL_SOCKET, SO_LINGER, (char *)&get_linger_opt16, &x) ) { debug(F111, "TCP ck_linger can't get SO_LINGER",ck_errstr(),errno); } else if (get_linger_opt16.s_onoff != onoff || get_linger_opt16.s_linger != timo) { set_linger_opt16.s_onoff = onoff; set_linger_opt16.s_linger = timo; if (setsockopt(ttyfd, SOL_SOCKET, SO_LINGER, (char *)&set_linger_opt16, sizeof(set_linger_opt16)) ) { debug(F111, "TCP ck_linger can't set SO_LINGER", ck_errstr(), errno ); tcp_linger = get_linger_opt16.s_onoff; tcp_linger_tmo = get_linger_opt16.s_linger; } else { debug(F101, "TCP ck_linger new SO_LINGER","", set_linger_opt16.s_onoff); tcp_linger = set_linger_opt16.s_onoff; tcp_linger_tmo = set_linger_opt16.s_linger; return 1; } } else { debug(F101,"TCP ck_linger SO_LINGER unchanged","", get_linger_opt16.s_onoff); tcp_linger = get_linger_opt16.s_onoff; tcp_linger_tmo = get_linger_opt16.s_linger; return 1; } return(0); }#endif /* OS2 */ debug(F111,"TCP ck_linger error: SO_LINGER","len",x); debug(F111,"TCP ck_linger SO_LINGER", "expected len",sizeof(get_linger_opt)); debug(F111,"TCP ck_linger SO_LINGER","linger_opt.l_onoff", get_linger_opt.l_onoff); debug(F111,"TCP linger SO_LINGER","linger_opt.l_linger", get_linger_opt.l_linger); } else if (get_linger_opt.l_onoff != onoff || get_linger_opt.l_linger != timo) { set_linger_opt.l_onoff = onoff; set_linger_opt.l_linger = timo; if (setsockopt(ttyfd, SOL_SOCKET, SO_LINGER, (char *)&set_linger_opt, sizeof(set_linger_opt))) { debug(F111,"TCP ck_linger can't set SO_LINGER",ck_errstr(),errno); tcp_linger = get_linger_opt.l_onoff; tcp_linger_tmo = get_linger_opt.l_linger; } else { debug(F101, "TCP ck_linger new SO_LINGER", "", set_linger_opt.l_onoff ); tcp_linger = set_linger_opt.l_onoff; tcp_linger_tmo = set_linger_opt.l_linger; return 1; } } else { debug(F101,"TCP ck_linger SO_LINGER unchanged","", get_linger_opt.l_onoff); tcp_linger = get_linger_opt.l_onoff; tcp_linger_tmo = get_linger_opt.l_linger; return 1; }#else debug(F100,"TCP ck_linger SO_LINGER not defined","",0);#endif /* SO_LINGER */#else debug(F100,"TCP ck_linger SO_SOCKET not defined","",0);#endif /* SOL_SOCKET */ return(0);}intsendbuf(size) int size; {/* The following, from William Bader, allows changing of socket buffer sizes, in case that might affect performance. Modified by Jeff Altman to be generally useful.*/#ifdef SOL_SOCKET#ifdef SO_SNDBUF int i, j, rc = 0; SOCKOPT_T x; if (ttyfd == -1 || nettype != NET_TCPA && nettype != NET_TCPB || ttmdm >= 0) { tcp_sendbuf = size; return 1; } x = sizeof(i); if (getsockopt(ttyfd, SOL_SOCKET, SO_SNDBUF, (char *)&i, &x)) { debug(F111,"TCP sendbuf can't get SO_SNDBUF",ck_errstr(),errno); } else if (x != sizeof(i)) {#ifdef OS2 short i16,j16; if (x == sizeof(i16)) { debug(F111,"TCP sendbuf warning: SO_SNDBUF","len is 16-bit",x); if (getsockopt(ttyfd, SOL_SOCKET, SO_SNDBUF, (char *)&i16, &x) ) { debug(F111,"TCP sendbuf can't get SO_SNDBUF", ck_errstr(),errno); } else if (size <= 0) { tcp_sendbuf = i16; debug(F101,"TCP sendbuf SO_SNDBUF retrieved","",i16); return 1; } else if (i16 != size) { j16 = size; if (setsockopt(ttyfd, SOL_SOCKET, SO_SNDBUF, (char *)&j16, sizeof(j16)) ) { debug(F111,"TCP sendbuf can't set SO_SNDBUF", ck_errstr(),errno); } else { debug(F101,"TCP sendbuf old SO_SNDBUF","",i16); debug(F101,"TCP sendbuf new SO_SNDBUF","",j16); tcp_sendbuf = size; return 1; } } else { debug(F101,"TCP sendbuf SO_SNDBUF unchanged","",i16); tcp_sendbuf = size; return 1; } return(0); }#endif /* OS2 */ debug(F111,"TCP sendbuf error: SO_SNDBUF","len",x); debug(F111,"TCP sendbuf SO_SNDBUF","expected len",sizeof(i)); debug(F111,"TCP sendbuf SO_SNDBUF","i",i); } else if (size <= 0) { tcp_sendbuf = i; debug(F101,"TCP sendbuf SO_SNDBUF retrieved","",i); return 1; } else if (i != size) { j = size; if (setsockopt(ttyfd, SOL_SOCKET, SO_SNDBUF, (char *)&j, sizeof(j))) { debug(F111,"TCP sendbuf can't set SO_SNDBUF",ck_errstr(),errno); tcp_sendbuf = i; } else { debug(F101,"TCP sendbuf old SO_SNDBUF","",i); debug(F101,"TCP sendbuf new SO_SNDBUF","",j); tcp_sendbuf = size; return 1; } } else { debug(F101,"TCP sendbuf SO_SNDBUF unchanged","",i); tcp_sendbuf = size; return 1; }#else debug(F100,"TCP sendbuf SO_SNDBUF not defined","",0);#endif /* SO_SNDBUF */#else debug(F100,"TCP sendbuf SO_SOCKET not defined","",0);#endif /* SOL_SOCKET */ return(0);}intrecvbuf(size) int size; {/* The following, from William Bader, allows changing of socket buffer sizes, in case that might affect performance. Modified by Jeff Altman to be generally useful.*/#ifdef SOL_SOCKET#ifdef SO_RCVBUF int i, j, rc = 0; SOCKOPT_T x; if (ttyfd == -1 || nettype != NET_TCPA && nettype != NET_TCPB || ttmdm >= 0) { tcp_recvbuf = size; return(1); } x = sizeof(i);
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -