/* ckoftp.c * * TCP/IP interface DLL between C-Kermit and FTP PC/TCP * */ /* Author: Jeffrey Altman (jaltman@secure-endpoints.com) Secure Endpoints Inc., New York City Copyright (C) 1985, 2004, Trustees of Columbia University in the City of New York. */ /* PCTCP include file */ #define INCL_DOSEXCEPTIONS #include /* BSD include files */ #include #include #include #include #ifndef __IBMC__ #include #include #endif #define CK_DLL #include "ckotcp.h" int ENTRY ck_sockinit(void) { /* no sock_init() in ftp pc/tcp */ return 0; } /* socket calls */ int ENTRY ck_connect(int socket, struct ck_sockaddr *name, int namelen) { struct sockaddr_in addr; memset(&addr, 0, sizeof(addr)); addr.sin_port = ((struct ck_sockaddr_in *) name) -> sin_port; addr.sin_family = ((struct ck_sockaddr_in *) name) -> sin_family; addr.sin_addr.s_addr = ((struct ck_sockaddr_in *) name) -> sin_addr.s_addr; return connect(socket, (struct sockaddr *) &addr, sizeof(addr)); } int ENTRY ck_bind(int socket, struct ck_sockaddr *name, int namelen) { struct sockaddr_in addr; memset(&addr, 0, sizeof(addr)); addr.sin_port = ((struct ck_sockaddr_in *) name) -> sin_port; addr.sin_family = ((struct ck_sockaddr_in *) name) -> sin_family; addr.sin_addr.s_addr = ((struct ck_sockaddr_in *) name) -> sin_addr.s_addr; return bind(socket, (struct sockaddr *) &addr, sizeof(addr)); } int ENTRY ck_listen(int socket, int backlog) { return listen( socket, backlog ); } int ENTRY ck_accept(int socket, struct ck_sockaddr *name, int * namelen) { struct sockaddr_in addr; int rc = 0 ; short len = sizeof(addr); memset(&addr, 0, sizeof(addr)); addr.sin_port = ((struct ck_sockaddr_in *) name) -> sin_port; addr.sin_family = ((struct ck_sockaddr_in *) name) -> sin_family; addr.sin_addr.s_addr = ((struct ck_sockaddr_in *) name) -> sin_addr.s_addr; rc = accept(socket, (struct sockaddr *) &addr, &len); *namelen = len ; ((struct ck_sockaddr_in *) name) -> sin_port = addr.sin_port ; ((struct ck_sockaddr_in *) name) -> sin_family = addr.sin_family ; ((struct ck_sockaddr_in *) name) -> sin_addr.s_addr = addr.sin_addr.s_addr; return rc ; } int ENTRY ck_ioctl(int socket, int cmd, long *data) { long dat = *data ; int rc = 0 ; switch (cmd) { case CK_FIONREAD: cmd = FIONREAD; break; case CK_FIONBIO: cmd = FIONBIO; break; case CK_SIOCATMARK: cmd = SIOCATMARK; break; default: return -1; } rc = ioctl(socket, cmd, (char *)&dat); *data = dat ; return rc; } int ENTRY ck_recv(int socket, char *buffer, int length, int flags) { return recv(socket, buffer, length,flags); } int ENTRY ck_select(int *fds, int read, int write, int except, long timeout) { /* Warning: if the called select is 16-bit but the calling code is * 32-bit, only one fd can be pointed to by fds! However, calling * with one "read" socket is the only use of select() in * C-Kermit. Might change in the future, so this must be checked. */ int rc ; ULONG nestings ; /* MustComplete sections */ fd_set rfds; struct timeval tv; int socket = *fds; if ((read + write + except) != 1) return -1; FD_ZERO(&rfds); FD_SET(socket, &rfds); tv.tv_sec = tv.tv_usec = 0L; if (timeout < 1000) tv.tv_usec = (long) timeout * 1000L; else tv.tv_sec = timeout / 1000L ; rc = (read ? select(FD_SETSIZE, &rfds, NULL, NULL, &tv) : 1) && (write ? select(FD_SETSIZE, NULL, &rfds, NULL, &tv) : 1) && (except ? select(FD_SETSIZE, NULL, NULL, &rfds, &tv) : 1) && FD_ISSET(socket, &rfds); return rc ; } int ENTRY ck_send(int socket, char *buffer, int length, int flags) { return send(socket, buffer, length,flags); } int ENTRY ck_setsockopt(int socket, int level, int optname, char *optvalue, int optlength) { int rc=0; short optname16; char * optvalue16; short optlength16; short optval16; if (level == CK_SOL_SOCKET) level = SOL_SOCKET; else return -1; switch ( optname ) { case CK_SO_OOBINLINE: optname16 = SO_OOBINLINE ; optval16 = (short)*((int *)optvalue); rc = setsockopt(socket, level, optname16, &optval16, optlength); break; case CK_SO_REUSEADDR: optname16 = SO_REUSEADDR ; break; case CK_SO_LINGER: optname16 = SO_LINGER ; break; case CK_SO_KEEPALIVE: optname16 = SO_KEEPALIVE ; break; case CK_SO_SNDBUF: optname16 = SO_SNDBUF ; break; case CK_SO_RCVBUF: optname16 = SO_RCVBUF ; break; default: return -1; } return rc; } int ENTRY ck_getsockopt(int socket, int level, int optname, char *optvalue, int * optlength) { short len = *optlength ; int rc = 0 ; if (level == CK_SOL_SOCKET) level = SOL_SOCKET; else return -1; switch ( optname ) { case CK_SO_OOBINLINE: optname = SO_OOBINLINE ; break; case CK_SO_REUSEADDR: optname = SO_REUSEADDR ; break; case CK_SO_LINGER: optname = SO_LINGER ; break; case CK_SO_KEEPALIVE: optname = SO_KEEPALIVE ; break; case CK_SO_SNDBUF: optname = SO_SNDBUF ; break; case CK_SO_RCVBUF: optname = SO_RCVBUF ; break; default: return -1; } rc = getsockopt(socket, level, optname, optvalue, &len); *optlength = len ; return rc ; } int ENTRY ck_socket(int domain, int type, int protocol) { if (domain == CK_AF_INET) domain = AF_INET; else return -1; if (type == CK_SOCK_STREAM) type = SOCK_STREAM; else return -1; if (protocol != 0) return -1; return socket(domain, type, protocol); } int ENTRY ck_soclose(int socket) { return closesocket(socket); } /* utility calls */ struct ck_hostent * ENTRY ck_gethostbyname(char *name) { struct hostent *host = gethostbyname(name); static struct ck_hostent ckhost; if (host == NULL) return NULL; ckhost.h_name = host -> h_name; ckhost.h_aliases = NULL; ckhost.h_addrtype = host -> h_addrtype; ckhost.h_length = host -> h_length; ckhost.h_addr_list = host -> h_addr_list; return &ckhost; } struct ck_servent * ENTRY ck_getservbyname(char *name, char *protocol) { struct servent *serv = getservbyname(name, protocol); static struct ck_servent ckserv; if (serv == NULL) return NULL; ckserv.s_name = serv -> s_name; ckserv.s_aliases = NULL; ckserv.s_port = serv -> s_port; ckserv.s_proto = serv -> s_proto; return &ckserv; } struct ck_hostent * ENTRY ck_gethostbyaddr(char *addr, int len, int net) { struct hostent *host = gethostbyaddr(addr, len, net); static struct ck_hostent ckhost; if (host == NULL) return NULL; ckhost.h_name = host -> h_name; ckhost.h_aliases = NULL; ckhost.h_addrtype = host -> h_addrtype; ckhost.h_length = host -> h_length; ckhost.h_addr_list = host -> h_addr_list; return &ckhost; } struct ck_servent * ENTRY ck_getservbyport(int port, char *name) { struct servent *serv = getservbyport(port, name); static struct ck_servent ckserv; if (serv == NULL) return NULL; ckserv.s_name = serv -> s_name; ckserv.s_aliases = NULL; ckserv.s_port = serv -> s_port; ckserv.s_proto = serv -> s_proto; return &ckserv; } unsigned long ENTRY ck_inet_addr(char *cp) { return inet_addr(cp); } char * ENTRY ck_inet_ntoa(struct ck_in_addr in) { struct in_addr addr; addr.s_addr = in.s_addr; return inet_ntoa(addr); } int ENTRY ck_getpeername( int socket, struct ck_sockaddr * name, int * namelen ) { int rc ; short len = (short) *namelen ; rc = getpeername( socket, (struct sockaddr *) name, &len ) ; *namelen = len ; return rc; } int ENTRY ck_getsockname( int socket, struct ck_sockaddr * name, int * namelen ) { int rc ; short len = (short) *namelen ; rc = getsockname( socket, (struct sockaddr *) name, &len ) ; *namelen = len ; return rc; } int ENTRY ck_gethostname( char * buf, int len ) { int rc ; short slen = (short) len ; rc = gethostname( buf, slen ) ; return rc; } /* end of ckotcp.c */ .