384 lines
9.7 KiB
C
384 lines
9.7 KiB
C
/*
|
|
* The contents of this file are subject to the Netscape Public
|
|
* License Version 1.1 (the "License"); you may not use this file
|
|
* except in compliance with the License. You may obtain a copy of
|
|
* the License at http://www.mozilla.org/NPL/
|
|
*
|
|
* Software distributed under the License is distributed on an "AS
|
|
* IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or
|
|
* implied. See the License for the specific language governing
|
|
* rights and limitations under the License.
|
|
*
|
|
* The Original Code is the Netscape Messaging Access SDK Version 3.5 code,
|
|
* released on or about June 15, 1998. *
|
|
* The Initial Developer of the Original Code is Netscape Communications
|
|
* Corporation. Portions created by Netscape are
|
|
* Copyright (C) 1998 Netscape Communications Corporation. All
|
|
* Rights Reserved.
|
|
*
|
|
* Contributor(s): ______________________________________.
|
|
*/
|
|
|
|
/*
|
|
* Copyright (c) 1997 and 1998 Netscape Communications Corporation
|
|
* (http://home.netscape.com/misc/trademarks.html)
|
|
*/
|
|
|
|
/*
|
|
* nssocket.c
|
|
* @author derekt@netscape.com
|
|
* @version 1.0
|
|
*/
|
|
|
|
/* our includes */
|
|
#include "nssocket.h"
|
|
|
|
/* system includes */
|
|
#include <string.h>
|
|
|
|
#ifdef XP_UNIX
|
|
#include <unistd.h>
|
|
#include <fcntl.h>
|
|
#include <errno.h>
|
|
#endif /* XP_UNIX */
|
|
|
|
#ifdef WIN32
|
|
#include <winsock.h>
|
|
#endif /* WIN32 */
|
|
|
|
/* constants */
|
|
const int kn_DefaultMTU = (32*1024); /* 64kBytes, was 4 kBytes */
|
|
const double defaultTimeout = 1800.0;
|
|
|
|
void NSSock_Initialize()
|
|
{
|
|
#ifdef WIN32
|
|
const WORD kWS_VERSION_REQUIRED = 0x0101;
|
|
WSADATA wsaData;
|
|
|
|
/* Initialize Windows Sockets */
|
|
WSAStartup(kWS_VERSION_REQUIRED,&wsaData);
|
|
#endif /* WIN32 */
|
|
}
|
|
|
|
void NSSock_Terminate()
|
|
{
|
|
#ifdef WIN32
|
|
WSACleanup();
|
|
#endif /* WIN32 */
|
|
}
|
|
|
|
/* Creates a socket. */
|
|
int NSSock_Socket ( int in_af, int in_type, int in_protocol )
|
|
{
|
|
return socket( in_af, in_type, in_protocol );
|
|
}
|
|
|
|
|
|
/* Connect to the specified ip address with the specified port. */
|
|
int NSSock_Connect( int in_socket,
|
|
const struct sockaddr * in_pHostInetAddr,
|
|
int in_port )
|
|
{
|
|
struct sockaddr_in ThisInetAddr; /* our address */
|
|
|
|
/* initialize the address structures */
|
|
memset (&ThisInetAddr, 0, sizeof(ThisInetAddr));
|
|
|
|
ThisInetAddr.sin_family = AF_INET;
|
|
ThisInetAddr.sin_addr.s_addr = htonl(INADDR_ANY);
|
|
ThisInetAddr.sin_port = htons(0);
|
|
|
|
|
|
if ( bind( in_socket, (struct sockaddr *)&ThisInetAddr, sizeof (ThisInetAddr)) < 0 )
|
|
{
|
|
return 0;
|
|
}
|
|
|
|
if ( connect( in_socket, (struct sockaddr *)in_pHostInetAddr, sizeof (*in_pHostInetAddr)) < 0)
|
|
{
|
|
return 0;
|
|
}
|
|
|
|
return 1;
|
|
}
|
|
|
|
/* Write the supplied buffer out to the socket. */
|
|
int NSSock_Write( int in_socket, char * in_buffer, int in_length )
|
|
{
|
|
int nRet;
|
|
int nSent = 0;
|
|
|
|
/* send all the data in the output buffer */
|
|
while ( nSent < in_length )
|
|
{
|
|
nRet = send ( in_socket, &(in_buffer[nSent]), in_length-nSent, 0 );
|
|
if ( nRet < 0 )
|
|
{
|
|
return 0;
|
|
}
|
|
nSent += nRet;
|
|
}
|
|
|
|
return (nSent == in_length);
|
|
}
|
|
|
|
/* Read data from the socket into the buffer. */
|
|
int NSSock_Read( int in_socket, char * io_buffer, int in_length )
|
|
{
|
|
int nRet;
|
|
|
|
/* read data from the socket */
|
|
nRet = recv ( in_socket, io_buffer, in_length, 0 );
|
|
|
|
/* fail if an error occurred */
|
|
if (nRet <= 0)
|
|
{
|
|
return 0;
|
|
}
|
|
|
|
return( nRet );
|
|
}
|
|
|
|
/* Close the socket. */
|
|
int NSSock_Close( int in_socket )
|
|
{
|
|
/* disable further operations */
|
|
shutdown (in_socket, 0);
|
|
#ifdef WIN32
|
|
return ( closesocket( in_socket ) == 0 );
|
|
#endif /* WIN32 */
|
|
|
|
#ifdef XP_UNIX
|
|
return ( close( in_socket ) == 0 );
|
|
#endif /* XP_UNIX */
|
|
}
|
|
|
|
/* Select used to simulate timeouts. */
|
|
int NSSock_Select( int nfds,
|
|
fd_set * readfds,
|
|
fd_set * writefds,
|
|
fd_set * exceptfds,
|
|
struct timeval * timeout)
|
|
{
|
|
int l_retCode = select( nfds, readfds, writefds, exceptfds, timeout );
|
|
|
|
if ( l_retCode <= 0 )
|
|
{
|
|
return 0;
|
|
}
|
|
|
|
return l_retCode;
|
|
}
|
|
|
|
/* Get the host name. */
|
|
int NSSock_GetHostName( char * out_hostName, int in_maxLength )
|
|
{
|
|
if ( gethostname( out_hostName, in_maxLength ) != 0 )
|
|
{
|
|
return 0;
|
|
}
|
|
|
|
return 1;
|
|
}
|
|
|
|
/* Get the host by name. */
|
|
LinkedList_t * NSSock_GetHostByName( const char * in_hostName )
|
|
{
|
|
#ifdef HPUX
|
|
int l_nReturn;
|
|
struct hostent_data * l_hostent_data;
|
|
#endif /* HPUX */
|
|
#ifdef AIX
|
|
int l_nReturn;
|
|
struct hostent_data * l_hostent_data;
|
|
#endif /* AIX */
|
|
#ifdef SOLARIS
|
|
int l_nReturn;
|
|
int l_nBufferLength;
|
|
int l_nIter = 1;
|
|
char * l_buffer;
|
|
#endif /* SOLARIS */
|
|
struct hostent * l_hostent;
|
|
char ** l_ppAddressList;
|
|
char * l_pAddress;
|
|
char * l_pTempAddress;
|
|
LinkedList_t * l_list = 0;
|
|
|
|
#ifdef WIN32
|
|
l_hostent = gethostbyname( in_hostName );
|
|
|
|
if ( l_hostent == 0 )
|
|
{
|
|
return 0;
|
|
}
|
|
|
|
for( l_ppAddressList = l_hostent->h_addr_list; *l_ppAddressList != 0; l_ppAddressList++ )
|
|
{
|
|
struct in_addr in;
|
|
|
|
memcpy( &in.s_addr, *l_ppAddressList, sizeof(in.s_addr));
|
|
l_pTempAddress = inet_ntoa(in);
|
|
l_pAddress = (char*)malloc( (strlen( l_pTempAddress ) +1) * sizeof(char) );
|
|
strcpy( l_pAddress, l_pTempAddress );
|
|
AddElement( &l_list, l_pAddress );
|
|
}
|
|
#endif /* WIN32 */
|
|
|
|
#ifdef AIX
|
|
l_hostent = (struct hostent*)malloc( sizeof(struct hostent) );
|
|
l_hostent_data = (struct hostent_data*)malloc( sizeof(struct hostent_data) );
|
|
|
|
/* initialize the address structures */
|
|
memset(l_hostent_data, 0, sizeof(struct hostent_data));
|
|
|
|
/* derekt:check for an error here */
|
|
l_nReturn = gethostbyname_r( in_hostName, l_hostent, l_hostent_data );
|
|
|
|
for( l_ppAddressList = l_hostent->h_addr_list; *l_ppAddressList != 0; l_ppAddressList++ )
|
|
{
|
|
struct in_addr in;
|
|
|
|
memcpy( &in.s_addr, *l_ppAddressList, sizeof(in.s_addr));
|
|
l_pTempAddress = inet_ntoa(in);
|
|
l_pAddress = (char*)malloc( (strlen( l_pTempAddress ) +1) * sizeof(char) );
|
|
strcpy( l_pAddress, l_pTempAddress );
|
|
AddElement( &l_list, l_pAddress );
|
|
}
|
|
|
|
free( l_hostent_data );
|
|
free( l_hostent );
|
|
#endif /* AIX */
|
|
|
|
#ifdef HPUX
|
|
/* derekt:check for an error here */
|
|
if ( (l_hostent = gethostbyname( in_hostName )) == NULL )
|
|
{
|
|
return 0;
|
|
}
|
|
|
|
for( l_ppAddressList = l_hostent->h_addr_list; *l_ppAddressList != 0; l_ppAddressList++ )
|
|
{
|
|
struct in_addr in;
|
|
|
|
memcpy( &in.s_addr, *l_ppAddressList, sizeof(in.s_addr));
|
|
l_pTempAddress = inet_ntoa(in);
|
|
l_pAddress = (char*)malloc( (strlen( l_pTempAddress ) +1) * sizeof(char) );
|
|
strcpy( l_pAddress, l_pTempAddress );
|
|
AddElement( &l_list, l_pAddress );
|
|
}
|
|
|
|
#ifdef OLDHPUX
|
|
l_hostent = (struct hostent*)malloc( sizeof(struct hostent) );
|
|
l_hostent_data = (struct hostent_data*)malloc( sizeof(struct hostent_data) );
|
|
|
|
/* initialize the address structures */
|
|
l_hostent_data->current = 0;
|
|
|
|
/* derekt:check for an error here */
|
|
l_nReturn = gethostbyname_r( in_hostName, l_hostent, l_hostent_data );
|
|
|
|
for( l_ppAddressList = l_hostent->h_addr_list; *l_ppAddressList != 0; l_ppAddressList++ )
|
|
{
|
|
struct in_addr in;
|
|
|
|
memcpy( &in.s_addr, *l_ppAddressList, sizeof(in.s_addr));
|
|
l_pTempAddress = inet_ntoa(in);
|
|
l_pAddress = (char*)malloc( (strlen( l_pTempAddress ) +1) * sizeof(char) );
|
|
strcpy( l_pAddress, l_pTempAddress );
|
|
AddElement( &l_list, l_pAddress );
|
|
}
|
|
|
|
free( l_hostent_data );
|
|
free( l_hostent );
|
|
#endif /* OLDHPUX */
|
|
#endif /* HPUX */
|
|
|
|
#ifdef SOLARIS
|
|
l_hostent = (struct hostent*)malloc( sizeof(struct hostent) );
|
|
l_nBufferLength = 2048;
|
|
l_buffer = (char*)malloc( l_nBufferLength * sizeof(char) * l_nIter );
|
|
|
|
while( gethostbyname_r( in_hostName,
|
|
l_hostent,
|
|
l_buffer,
|
|
l_nBufferLength,
|
|
&l_nReturn ) == 0 )
|
|
{
|
|
free( l_buffer );
|
|
if ( l_nReturn == ERANGE )
|
|
{
|
|
l_buffer = (char*)malloc( l_nBufferLength * sizeof(char) * ++l_nIter );
|
|
}
|
|
else
|
|
{
|
|
free( l_hostent );
|
|
return 0;
|
|
}
|
|
}
|
|
|
|
for( l_ppAddressList = l_hostent->h_addr_list; *l_ppAddressList != 0; l_ppAddressList++ )
|
|
{
|
|
struct in_addr in;
|
|
|
|
memcpy( &in.s_addr, *l_ppAddressList, sizeof(in.s_addr));
|
|
l_pTempAddress = inet_ntoa(in);
|
|
l_pAddress = (char*)malloc( (strlen( l_pTempAddress ) +1) * sizeof(char) );
|
|
strcpy( l_pAddress, l_pTempAddress );
|
|
AddElement( &l_list, l_pAddress );
|
|
}
|
|
|
|
free( l_buffer );
|
|
free( l_hostent );
|
|
#endif /* SOLARIS */
|
|
|
|
#if defined (IRIX) || defined (IRIX64)
|
|
l_hostent = gethostbyname( in_hostName );
|
|
|
|
if ( l_hostent == 0 )
|
|
{
|
|
return 0;
|
|
}
|
|
|
|
for( l_ppAddressList = l_hostent->h_addr_list; *l_ppAddressList != 0; l_ppAddressList++ )
|
|
{
|
|
struct in_addr in;
|
|
|
|
memcpy( &in.s_addr, *l_ppAddressList, sizeof(in.s_addr));
|
|
l_pTempAddress = inet_ntoa(in);
|
|
l_pAddress = (char*)malloc( (strlen( l_pTempAddress ) +1) * sizeof(char) );
|
|
strcpy( l_pAddress, l_pTempAddress );
|
|
AddElement( &l_list, l_pAddress );
|
|
}
|
|
|
|
#endif /* IRIX */
|
|
|
|
#ifdef OSF1
|
|
l_hostent = gethostbyname( in_hostName );
|
|
|
|
if ( l_hostent == 0 )
|
|
{
|
|
return 0;
|
|
}
|
|
|
|
for( l_ppAddressList = l_hostent->h_addr_list; *l_ppAddressList != 0; l_ppAddressList++ )
|
|
{
|
|
struct in_addr in;
|
|
|
|
memcpy( &in.s_addr, *l_ppAddressList, sizeof(in.s_addr));
|
|
l_pTempAddress = inet_ntoa(in);
|
|
l_pAddress = (char*)malloc( (strlen( l_pTempAddress ) +1) * sizeof(char) );
|
|
strcpy( l_pAddress, l_pTempAddress );
|
|
AddElement( &l_list, l_pAddress );
|
|
}
|
|
#endif /* OSF1 */
|
|
|
|
/*
|
|
* Add any addional platforms here
|
|
*/
|
|
|
|
return l_list;
|
|
}
|
|
|
|
|