www.pudn.com > watsock.zip > WINSK.C
#include "winsock.h" /* Must be included before TCPSTREAM definition */
/* TCP input buffer -- must be large enough to prevent overflow */
#define BUFLEN 512
#define NIL 0 /* convenient name */
/* TCP I/O stream (must be before osdep.h is included) */
#define TCPSTREAM struct tcp_stream
TCPSTREAM {
char *host; /* host name */
char *localhost; /* local host name */
SOCKET tcps; /* tcp socket */
long ictr; /* input counter */
char *iptr; /* input pointer */
char ibuf[BUFLEN]; /* input buffer */
};
#define __XVT__ /* To avoid "ERROR redifinition" problem */
/* Private function prototypes */
#include "mail.h"
#include
#include
#include
#include
#include
#include
#include
#include "debug.h"
#define MEM_SAFETY_DEBUG
// #include
/**** EXTERNALS */
extern void ecs_error(char *);
char *local_hostname = "isa386-15" ;
/* PROTOTYPES of win_* routines */
SOCKET win_socket(int domain, int type, int protocol);
int win_connect(SOCKET s, unsigned long address, unsigned short s_port);
int win_close(SOCKET s);
int win_select(int width, fd_set *readfds,
fd_set *writefds, fd_set *exceptfds, long timeout);
int win_read(SOCKET s, char *buf, int nbyte);
int win_write(SOCKET s, char *buf, int nbyte);
unsigned long win_rhost(char **name);
unsigned long win_htonl(unsigned long hostlong);
unsigned long win_ntohl(unsigned long netlong);
unsigned short win_htons(unsigned short hostshort);
unsigned short win_ntohs(unsigned short netshort);
unsigned long win_inet_addr(char *cp);
void fatal (char *string);
void *fs_get (size_t size);
/* Holds the addresses of the socket routines in the socket dll */
#define SOCKDLL struct SockDll
SOCKDLL {
SOCKET (PASCAL FAR * socket)(int af, int type, int protocol);
int (PASCAL FAR * connect)(SOCKET s, struct sockaddr FAR *name, int namelen);
int (PASCAL FAR *closesocket)(SOCKET s);
int (PASCAL FAR *select)(int nfds, fd_set FAR *readfds, fd_set FAR *writefds, fd_set FAR *exceptfds, struct timeval FAR *timeout);
int (PASCAL FAR *recv)(SOCKET s, char FAR *buf, int len, int flags);
int (PASCAL FAR *send)(SOCKET s, char FAR *buf, int len, int flags);
struct hostent * (PASCAL FAR *gethostbyname)(char FAR *name);
int (PASCAL FAR *gethostname)(char FAR *name, int namelen);
unsigned long (PASCAL FAR *inet_addr)(char FAR *cp);
unsigned long (PASCAL FAR *so_rhost)(char **cp);
u_long (PASCAL FAR *htonl)(u_long hostlong);
u_short (PASCAL FAR *htons)(u_short hostshort);
u_long (PASCAL FAR *ntohl)(u_long netlong);
u_short (PASCAL FAR *ntohs)(u_short hostshort);
};
/****** STATIC DATA ******/
static SOCKDLL *sockdll = NULL; /* Global to this file */
static HANDLE hLibrary = 0; /* Used to free library */
/* END STATIC DATA ***/
int TCP_init_libs(char *global_dir);
void TCP_free_libs(void);
void TCP_test(char *buf) ;
void tcp_close(TCPSTREAM *stream);
TCPSTREAM *tcp_open (char *host,long port);
long tcp_soutr (TCPSTREAM *stream,char *string);
char *tcp_getline (TCPSTREAM *stream);
long tcp_getbuffer (TCPSTREAM *stream,unsigned long size,char *buffer);
#ifdef MSDOS
int netshut() {};
#endif
/* Global data */
unsigned long rndm = 0xfeed; /* initial `random' number */
/* Write current time in RFC 822 format
* Accepts: destination string
*/
char *days[] = {"Sun", "Mon", "Tue", "Wed", "Thu", "Fri", "Sat"};
/* Copy string to free storage
* Accepts: source string
* Returns: free storage copy of string
*/
char *cpystr (char *string)
{
if (string) { /* make sure argument specified */
char *dst = (char *) fs_get (1+strlen (string));
strcpy (dst,string);
return (dst);
}
else return NIL;
}
/************************************************************************/
/* Get a block of free storage
* Accepts: size of desired block
* Returns: free storage block
*/
void *fs_get (size_t size)
{
void *block = NULL;
/* Make sure "size" is within the 64K limit */
if(size > (size_t)0xffff){
fatal("Cannot allocate more than 64K memory");
return(NULL); /* Should have already quit */
}
block = (void *)malloc(size); /* Would use smartheap */
if (!block)
fatal ("Out of free storage");
/* Set to zero */
memset(block, 0, size);
return (block);
}
/* Resize a block of free storage
* Accepts: ** pointer to current block
* new size
*/
void fs_resize (void **block,size_t size)
{
if(size > (size_t)0xffff)
fatal("Can't resize to more than 64k");
if (!(*block = realloc ((char *)*block,size)))
fatal ("Can't resize free storage");
}
/* Return a block of free storage
* Accepts: ** pointer to free storage block
*/
void fs_give (void **block)
{
if(block && *block)
free ((char *)*block); /* Would use smartheap */
if(block)
*block = NIL;
}
/* Report a fatal error
* Accepts: string to output
*/
void fatal (char *string)
{
debug_trace (string); /* pass the string */
debug_trace ("\n");
abort (); /* die horribly */
}
/* Copy string with CRLF newlines
* Accepts: destination string
* pointer to size of destination string
* source string
* length of source string
*/
char *strcrlfcpy (char **dst,unsigned long *dstl,char *src,unsigned long srcl)
{
if (srcl > *dstl) { /* resize if not enough space */
fs_give ((void **) dst); /* fs_resize does an unnecessary copy */
*dst = (char *) fs_get ((*dstl = srcl) + 1);
}
/* copy strings */
if (srcl) memcpy (*dst,src,srcl);
*(*dst + srcl) = '\0'; /* tie off destination */
return *dst; /* return destination */
}
/* Length of string after strcrlfcpy applied
* Accepts: source string
* length of source string
*/
unsigned long strcrlflen (STRING *s)
{
return SIZE (s); /* no-brainer on DOS! */
}
/* Server log in (dummy place holder)
* Accepts: user name string
* password string
* optional place to return home directory
* Returns: T if password validated, NIL otherwise
*/
long server_login (char *user,char *pass,char **home)
{
return NIL;
}
/***************************************************************************
****************************************************************************/
void TCP_test(char *buf)
{
TCPSTREAM *stream ;
char *string = " " ;
long port = 143 ; /* imapd */
long retval ;
stream = tcp_open("isasun-1", port);
retval = tcp_soutr (stream, string);
string = tcp_getline (stream);
movmem(string,buf,strlen(string));
tcp_close(stream);
}
/***************************************************************************
****************************************************************************/
/* TCP/IP send string as record
* Accepts: TCP/IP stream
* Returns: T if success else NIL
*/
long tcp_soutr (TCPSTREAM *stream,char *string)
{
int a ;
long i;
unsigned long size = strlen (string);
fd_set fds;
FD_ZERO (&fds); /* initialize selection vector */
if (stream->tcps == INVALID_SOCKET) return NIL;
FD_SET (stream->tcps,&fds);/* set bit in selection vector */
while (size > 0) { /* until request satisfied */
if( (win_select (stream->tcps+1,0,&fds,0,0) < 0) ||
((i = win_write (stream->tcps,string,size)) < 1) )
{
win_close (stream->tcps); /* nuke the socket */
stream->tcps = INVALID_SOCKET;
return NIL;
}
size -= i; /* count this size */
string += i;
}
return T; /* all done */
}
/* TCP/IP send string (Not NULL terminated).
* Accepts: TCP/IP stream
* Returns: T if success else NIL
*/
long tcp_sout (TCPSTREAM *stream,char *string,unsigned long size)
{
size_t i;
fd_set fds;
size_t len, MAXLEN = 8192; /* send no more than this at a time */
FD_ZERO (&fds); /* initialize selection vector */
if (stream->tcps == INVALID_SOCKET) return NIL;
FD_SET (stream->tcps,&fds); /* set bit in selection vector */
len = (size_t)min(size, MAXLEN);
while (size > 0) { /* until request satisfied */
if ((win_select (stream->tcps+1,0,&fds,0,0) < 0) ||
((i = win_write (stream->tcps,string,len)) < 0)) { /* Send len at a time */
win_close (stream->tcps); /* nuke the socket */
stream->tcps = INVALID_SOCKET;
return NIL;
}
size -= i; /* count this size */
string += i;
}
/* Append a "\n" */
if ((win_select (stream->tcps+1,0,&fds,0,0) < 0) ||
((i = win_write (stream->tcps,"\n",1)) < 0)) {
win_close (stream->tcps); /* nuke the socket */
stream->tcps = INVALID_SOCKET;
return NIL;
}
return T; /* all done */
}
/* TCP/IP receive line
* Accepts: TCP/IP stream
* Returns: text line string or NIL if failure
*/
char *tcp_getline (TCPSTREAM *stream)
{
int a;
long n, m;
char *st;
char *ret;
char *stp;
char tmp[2];
fd_set fds;
FD_ZERO (&fds); /* initialize selection vector */
if (stream->tcps == INVALID_SOCKET) return NIL;
FD_SET (stream->tcps, &fds); /* set bit in selection vector */
while (stream->ictr < 1) { /* if nothing in the buffer */
/* block and read */
if( (win_select (stream->tcps+1,&fds,0,0,0) < 0) ||
((stream->ictr = win_read (stream->tcps,stream->ibuf,BUFLEN)) < 1))
{
win_close (stream->tcps); /* nuke the socket */
stream->tcps = INVALID_SOCKET;
return NIL;
}
stream->iptr = stream->ibuf;/* point at TCP buffer */
}
st = stream->iptr; /* save start of string */
n = 0; /* init string count */
while (stream->ictr--) { /* look for end of line */
/* saw the trailing CR? */
if (stream->iptr++[0] == '\015') {
ret = (char *) fs_get (n+1);
memcpy (ret,st,n); /* copy into a free storage string */
ret[n] = '\0'; /* tie off string with null */
/* eat the line feed */
tcp_getbuffer (stream,(unsigned long) 1,tmp);
return ret; /* return it to caller */
}
++n; /* else count and try next character */
}
stp = (char *) fs_get (n); /* copy first part of string */
memcpy (stp,st,n);
/* recurse to get remainder */
if (st = tcp_getline (stream)) {
/* build total string */
ret = (char *) fs_get (n+1+(m = strlen (st)));
memcpy (ret,stp,n); /* copy first part */
memcpy (ret+n,st,m); /* and second part */
ret[n+m] = '\0'; /* tie off string with null */
fs_give ((void **) &st); /* flush partial string */
fs_give ((void **) &stp); /* flush initial fragment */
}
else ret = stp; /* return the fragment */
return ret;
}
/* TCP/IP receive buffer
* Accepts: TCP/IP stream
* size in bytes
* buffer to read into
* Returns: T if success, NIL otherwise
*/
long tcp_getbuffer (TCPSTREAM *stream,unsigned long size,char *buffer)
{
int a;
int retval ;
unsigned long n;
char *bufptr = buffer;
fd_set fds ;
FD_ZERO (&fds); /* initialize selection vector */
if (stream->tcps == INVALID_SOCKET) return NIL;
FD_SET (stream->tcps, &fds); /* set bit in selection vector */
while (size > 0) { /* until request satisfied */
while (stream->ictr < 1) { /* if nothing in the buffer */
/* block and read */
if( (win_select(stream->tcps+1,&fds,0,0,0) < 0) ||
((stream->ictr = win_read(stream->tcps,stream->ibuf,BUFLEN)) < 1))
{
win_close (stream->tcps); /* nuke the socket */
stream->tcps = INVALID_SOCKET;
return NIL;
}
/* point at TCP buffer */
stream->iptr = stream->ibuf;
} /* inner while */
n = min (size,stream->ictr);/* number of bytes to transfer */
/* do the copy */
memcpy (bufptr,stream->iptr,n);
bufptr += n; /* update pointer */
stream->iptr +=n;
size -= n; /* update # of bytes to do */
stream->ictr -=n;
bufptr[0] = '\0'; /* tie off string */
} /* outer while */
return T;
}
/* TCP/IP close
* Accepts: TCP/IP stream
*/
void tcp_close (TCPSTREAM *stream)
{
/* nuke the socket */
if (stream->tcps != INVALID_SOCKET) win_close (stream->tcps);
stream->tcps = INVALID_SOCKET;
/* flush host names */
fs_give ((void **) &stream->host);
fs_give ((void **) &stream->localhost);
fs_give ((void **) &stream); /* flush the stream */
}
/* TCP/IP open
* Accepts: host name
* contact port number
* Returns: TCP/IP stream if success else NIL
*/
TCPSTREAM *tcp_open (char *host,long port)
{
TCPSTREAM *stream = NIL;
SOCKET sock;
unsigned long address;
unsigned short s_port;
char *s;
char tmp[MAILTMPLEN];
char *hostname = cpystr (host);
/* set default gets routine */
// if (!mailgets) mailgets = mm_gets
/* The domain literal form is used (rather than simply the dotted decimal
as with other Unix programs) because it has to be a valid "host name"
in mailsystem terminology.
*/
if (host[0] == '[' && host[(strlen (host))-1] == ']') {
strcpy (tmp,host+1); /* yes, copy number part */
tmp[strlen (tmp)-1] = '\0';
if ((address = win_inet_addr (tmp)) == -1) {
sprintf (tmp,"Invalid post office: \"%s\" ",host);
ecs_error(tmp);
fs_give ((void **)&hostname);
return NIL;
}
}
else { /* lookup host name */
if ((address = win_rhost (&hostname)) == 0) {
sprintf (tmp,"Post office not found: \"%s\" ",host);
ecs_error(tmp);
fs_give ((void **)&hostname);
return NIL;
}
}
/* copy port number in network format */
if (!(s_port = win_htons (port)))
fatal ("Bad port argument to tcp_open");
/* get a TCP stream */
sock = win_socket(AF_INET, SOCK_STREAM, 0);
if (sock < 0) {
sprintf(tmp, "Cannot connect to post office: \"%s\" - Unable to create TCP socket", host);
ecs_error(tmp);
return NIL;
}
/* The local PC's hostname MUST be in the external "local_hostname", else
* return an error.
*/
if(local_hostname == NULL){
ecs_error("Could not get the name or IP address of your PC");
return NIL;
}
/* open connection */
if ((errno = win_connect (sock, address, s_port)) > 10000) {
switch (errno) { /* analyze error */
case WSAENETUNREACH: s = "tcp_open failed"; break;
case WSAETIMEDOUT: s = "Timed out"; break;
default: s = "Unknown error"; break;
}
sprintf(tmp,"Connect fail to \"%s\" [%ld] at port %ld. %s\n",hostname,address,port,s);
ecs_error(tmp);
fs_give ((void **)&hostname);
win_close (sock);
return NIL;
}
/* create TCP/IP stream */
stream = (TCPSTREAM *) fs_get (sizeof (TCPSTREAM));
stream->host = hostname; /* official host name */
stream->localhost = cpystr (local_hostname);
stream->tcps = sock; /* init socket */
stream->ictr = 0; /* init input counter */
return stream; /* return success */
}
/* TCP/IP authenticated open
* Accepts: host name
* service name
* Returns: TCP/IP stream if success else NIL
*/
TCPSTREAM *tcp_aopen (char *host,char *service)
{
return NIL; /* always NIL on DOS */
}
char *tcp_host (TCPSTREAM *stream)
{
return stream->host; /* return host name */
}
/* TCP/IP get local host name
* Accepts: TCP/IP stream
* Returns: local host name
*/
char *tcp_localhost (TCPSTREAM *stream)
{
return stream->localhost; /* return local host name */
}
/* These functions are only used by rfc822.c for calculating cookies. So this
* is good enough. If anything better is needed fancier functions will be
* needed.
*/
/* Return host ID
*/
#ifndef PCTCP
unsigned long gethostid ()
{
return (unsigned long) 0;
}
#endif
/* Return `process ID'
*/
long getpid ()
{
return 1;
}
/* These two are used for pattern matching in misc.c, but are actually never
* called in DOS.
*/
/* Dummy re_comp -- always return NIL */
char *re_comp (char *s)
{
return NIL;
}
/* Dummy re_exec -- always return T */
long re_exec (char *s)
{
return T;
}
/* Fill in the function pointers in the sockdll structure. The
* functions to be filled into the "sockdll" structure are:
- socket,
- connect,
- closesocket,
- select,
- recv,
- send,
- gethostbyname,
- net_addr,
- htonl,
- htons,
- ntohl,
- ntohs,
**/
/* Looks for the file "winsock.dll", loads it and extracts the addresses.
* The returned instance of the library is stored in the static "hLibraray"
* so it can be free by "TCP_free_libs()"
*/
int TCP_init_libs(char *global_dir)
{
int (PASCAL FAR *WSAStartup)(WORD wVersionRequired, LPWSADATA lpWSAData);
WSADATA *lpwsadata;
int retval;
WORD our_wsock_version = 257; /* Version 1.1 of winsock */
WSAStartup = NULL;
lpwsadata = NULL;
if((hLibrary = LoadLibrary("winsock.dll")) <= 32)
return(-1);
/* Do this for debuggindg */
{
char *path = fs_get(256);
path[0] = '\0';
/* Get library's path */
GetModuleFileName(hLibrary, path, 255);
fs_give((void **)&path);
}
if((WSAStartup = (int (FAR PASCAL *)())GetProcAddress(hLibrary, "WSAStartup")) == NULL)
return(-1);
/* Allocate */
lpwsadata = fs_get(sizeof(WSADATA));
/* Initialize the application */
lpwsadata->wHighVersion = our_wsock_version; /* In case */
retval = (*WSAStartup)(lpwsadata->wHighVersion, lpwsadata);
if(retval != 0) /* DLL hopefully filled this in!! */
retval = (*WSAStartup)(lpwsadata->wHighVersion, lpwsadata);
if(retval != 0){ /* Still no success */
char *path = fs_get(256);
char *mess = fs_get(256);
path[0] = '\0';
mess[0] = '\0';
/* Get library's path */
if(GetModuleFileName(hLibrary, path, 255) == 0)
path[0] == '\0';
switch(retval){
case 0: /* All's well */
break;
case WSASYSNOTREADY:
sprintf(mess, "Error iniitalizing \"%s\": system not ready",
path);
ecs_error(mess);
break;
case WSAVERNOTSUPPORTED:
case WSAEINVAL:
sprintf(mess, "\"%s\" does not support the winsock version \
required by ECS Mail", path);
ecs_error(mess);
break;
}
fs_give((void **)&path);
fs_give((void **)&mess);
goto error;
}
/* Don't need lpwsadata anymore */
fs_give((void **)&lpwsadata);
lpwsadata = NULL;
/* Ok. All's well */
/* Allocate space */
if(sockdll == NULL) /* Should be */
sockdll = (SOCKDLL *)fs_get(sizeof(SOCKDLL));
/* so_rhost accomodates our B&W shim */
sockdll->so_rhost = NULL; /* Set this explicitly */
/* Get addresses of routines */
sockdll->so_rhost = (unsigned long (FAR PASCAL *)())
GetProcAddress(hLibrary, "so_rhost"); /* Could be NULL */
if((sockdll->socket = (int (FAR PASCAL *)())
GetProcAddress(hLibrary, "socket")) == NULL)
goto error;
if((sockdll->connect = (int (FAR PASCAL *)())GetProcAddress(hLibrary, "connect")) == NULL)
goto error;
if((sockdll->closesocket = (int (FAR PASCAL *)())GetProcAddress(hLibrary, "closesocket")) == NULL)
goto error;
if((sockdll->select = (int (FAR PASCAL *)())GetProcAddress(hLibrary, "select")) == NULL)
goto error;
if((sockdll->recv = (int (FAR PASCAL *)())GetProcAddress(hLibrary, "recv")) == NULL)
goto error;
if((sockdll->send = (int (FAR PASCAL *)())GetProcAddress(hLibrary, "send")) == NULL)
goto error;
if((sockdll->gethostbyname = (struct hostent * (PASCAL FAR *)())GetProcAddress(hLibrary, "gethostbyname")) == NULL)
goto error;
if((sockdll->gethostname = (int (PASCAL FAR *)())GetProcAddress(hLibrary, "gethostname")) == NULL)
goto error;
if((sockdll->inet_addr = (unsigned long (FAR PASCAL *)())GetProcAddress(hLibrary, "inet_addr")) == NULL)
goto error;
if((sockdll->htonl = (unsigned long (FAR PASCAL *)())GetProcAddress(hLibrary, "htonl")) == NULL)
goto error;
if((sockdll->ntohl = (unsigned long (FAR PASCAL *)())GetProcAddress(hLibrary, "ntohl")) == NULL)
goto error;
if((sockdll->htons = (unsigned short (FAR PASCAL *)())GetProcAddress(hLibrary, "htons")) == NULL)
goto error;
if((sockdll->ntohs = (unsigned short (FAR PASCAL *)())GetProcAddress(hLibrary, "ntohs")) == NULL)
goto error;
return(0);
error:
if(sockdll)
fs_give((void **)&sockdll);
sockdll = NULL;
if(lpwsadata)
fs_give((void **)&lpwsadata);
return(-1);
}
/* Free the socket library */
void TCP_free_libs(void)
{
int (PASCAL FAR *WSACleanup)(void);
WSACleanup = NULL;
if(hLibrary <= 0)
return;
/* Call WSACleanup now */
if((WSACleanup = (int (FAR PASCAL *)())GetProcAddress(hLibrary, "WSACleanup")) != NULL)
(*WSACleanup)();
/* Free sockdll*/
if(sockdll)
fs_give((void **)&sockdll);
sockdll = NULL;
}
/* These routines simply call the address of socket(), etc. */
SOCKET win_socket(int domain, int type, int protocol)
{
if(sockdll && sockdll->socket)
return((*sockdll->socket)(domain, type, protocol));
}
/* NOTE: s_port already in network order */
int win_connect(SOCKET s, unsigned long address, unsigned short s_port)
{
struct sockaddr_in sin;
sin.sin_family = AF_INET;
sin.sin_port = s_port;
sin.sin_addr.s_addr = address;
if(sockdll && sockdll->connect)
return((*sockdll->connect)(s, (struct sockaddr *)&sin, sizeof(sin)));
return(-1);
}
int win_close(SOCKET s)
{
if(sockdll && sockdll->closesocket)
return((*sockdll->closesocket)(s));
return(-1);
}
/* timwout of 0 means non-blocking */
int win_select(int width, fd_set *readfds, fd_set *writefds, fd_set *exceptfds, long timeout)
{
struct timeval tval;
int result ;
tval.tv_sec = timeout;
if(tval.tv_sec < 2)
tval.tv_sec = 2;
tval.tv_usec = 0;
if(sockdll && sockdll->select)
result = (*sockdll->select)(width, readfds, writefds, exceptfds, &tval);
if( (result > WSABASEERR) || (result == 0) )
return(-1);
return(result) ;
}
int win_read(SOCKET s, char *buf, int nbyte)
{
if(sockdll && sockdll->recv)
return((*sockdll->recv)(s, buf, nbyte, 0));
return(-1);
}
int win_write(SOCKET s, char *buf, int nbyte)
{
if(sockdll && sockdll->send)
return((*sockdll->send)(s, buf, nbyte, 0));
return(-1);
}
/* rhost - a short-cut for gethostbyname.
* Return 0 on error.
*/
unsigned long win_rhost(char **name)
{
unsigned long addr;
struct hostent *h;
struct in_addr sin_addr;
if(!(name && *name))
return(0L);
addr = 0L;
/* If a so_rhost() is provided by the winsock.dll, use it */
if(sockdll && sockdll->so_rhost) /* Use rhost */
addr = (*sockdll->so_rhost)(name);
if(addr > 0L)
return(addr);
/* If so_rhost failed, try below */
if(!(sockdll && sockdll->inet_addr && sockdll->gethostbyname))
return(0L);
addr = 0L;
addr = (*sockdll->inet_addr)(*name);
if (addr == INADDR_NONE)
{
addr = 0L;
h = (*sockdll->gethostbyname)(*name);
if(h != NULL){
memcpy((char *)&sin_addr, h->h_addr, h->h_length);
addr = sin_addr.s_addr;
}
}
return(addr);
}
unsigned long win_htonl(unsigned long hostlong)
{
if(sockdll && sockdll->htonl)
return((*sockdll->htonl)(hostlong));
return(0L);
}
unsigned long win_ntohl(unsigned long netlong)
{
if(sockdll && sockdll->ntohl)
return((*sockdll->ntohl)(netlong));
return(0L);
}
unsigned short win_htons(unsigned short hostshort)
{
if(sockdll && sockdll->htons)
return((*sockdll->htons)(hostshort));
return(0);
}
unsigned short win_ntohs(unsigned short netshort)
{
if(sockdll && sockdll->ntohs)
return((*sockdll->ntohs)(netshort));
return(0);
}
unsigned long win_inet_addr(char *cp)
{
if(sockdll && sockdll->inet_addr)
return((*sockdll->inet_addr)(cp));
return(0L);
}
/** Get local host name or IP address. Use "gethostname".
* "buf" must be supplied, of length "buflen".
* These are simply passed to winsock's gethostname().
* Returns 0 if found, -1 on error.
*/
int ECS_get_local_hostname(char *buf, int buflen)
{
if(sockdll && sockdll->gethostname)
return((*sockdll->gethostname)(buf, buflen));
return(-1);
}