This commit is contained in:
prasad%netscape.com 1998-08-24 21:19:49 +00:00
Родитель 8eee69e40a
Коммит 5fb25dd9c6
12 изменённых файлов: 2556 добавлений и 0 удалений

Просмотреть файл

@ -0,0 +1,45 @@
/*
* The contents of this file are subject to the Netscape Public License
* Version 1.0 (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)
*/
#ifndef LINKLIST_H
#define LINKLIST_H
/*
* linklist.h
* @author derekt@netscape.com
* @version 1.0
*/
typedef struct LinkedList
{
void * pData;
struct LinkedList * next;
} LinkedList_t;
int AddElement( LinkedList_t ** in_ppLinkedList, void * in_pData );
void RemoveAllElements( LinkedList_t ** in_ppLinkedList );
int size( LinkedList_t * in_pLinkedList );
#endif /* LINKLIST_H */

143
msgsdk/C/include/nsStream.h Normal file
Просмотреть файл

@ -0,0 +1,143 @@
/*
* The contents of this file are subject to the Netscape Public License
* Version 1.0 (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)
*/
/* input output stream utilities
* nsStream.h
* @author prasad@netscape.com
* @version 1.0
*/
#ifndef NSIOSTREAM_H
#define NSIOSTREAM_H
#include "nsmail.h"
#ifdef __cplusplus
extern "C" {
#endif
/*
* Creates an input-stream from a file that can be passed to all messaging
* SDK API calls that require a parameter of type nsmail_inputstream_t.
* Implements the stream and the associated internal functions for read(),
* rewind() and close().
*
* Params:
* =======
*
* in_fileName: Full path name of the file to create the input-stream on.
* The file must exist.
* out_ppRetInputStream: The created input-stream is returned here.
* RETURN Value: 0 on success < 0 on failure. See nsmail.h for possible err codes.
*
* USAGE:
* ======
* nsmail_inputstream_t * pInputStream;
*
* ret_value = file_inputStream_create (<file-name>, &pInputStream);
*
* ret_value = mime_basicPart_setDataStream (<other-params>, pInputStream);
*
* When done close and free the stream.
* ----------------------------------
* pInputStream->close (pInputStream->rock);
* nsStream_free (pInputStream); pInputStream = NULL;
*
*/
int file_inputStream_create (char * in_fileName,
nsmail_inputstream_t ** out_ppRetInputStream);
/*
* Creates an input-stream from a buffer that can be passed to all messaging
* SDK API calls that require a parameter of type nsmail_inputstream_t.
* Implements the stream and the associated internal functions for read(),
* rewind() and close().
*
* Params:
* =======
*
* in_pDataBuf: Data buf to base the input-stream on. Should not be NULL.
* A reference to the buffer is stored in the stream. Hence
* The buffer should not be freed until the stream is closed.
* in_data_size Size of data in in_pDataBuf.
* out_ppRetInputStream: The created input-stream is returned here.
* RETURN Value: 0 on success < 0 on failure. See nsmail.h for possible err codes.
*
*
* USAGE:
* ======
*
* Same as file_inputStream above.
*
*/
int buf_inputStream_create (char * in_pDataBuf,
long in_data_size,
nsmail_inputstream_t ** out_ppRetInputStream);
/*
* Creates an output-stream from a file that can be passed to all messaging
* SDK API calls that require a parameter of type nsmail_outputstream_t.
*
* Params:
* =======
*
* in_fileName: Full path name of the file to create the output-stream on.
* Creates the file if needed. Blows away any previous data in the file.
* out_ppRetInputStream: The created output-stream is returned here.
* RETURN Value: 0 on success < 0 on failure. See nsmail.h for possible err codes.
*
* USAGE:
* ======
* nsmail_outputstream_t * pOutputStream;
*
* ret_value = file_outputStream_create (<file-name>, &pOutputStream);
*
* ret_value = mime_message_putByteStream (<other-params>, pOutputStream);
*
* When done close and free the stream.
* ----------------------------------
* pOutputStream->close (pOutputStream->rock);
* nsStream_free (pOutputStream); pOutputStream = NULL;
*
* NOTE: The file under the stream needs to be removed separately.
*/
int file_outputStream_create (char * in_fileName,
nsmail_outputstream_t ** out_ppRetOutputStream);
/* free the memory allocated for the (input/output) stream */
void nsStream_free (void * pMem);
#ifdef __cplusplus
}
#endif
#endif /* NSIOSTREAM_H */

105
msgsdk/C/include/nsio.h Normal file
Просмотреть файл

@ -0,0 +1,105 @@
/*
* The contents of this file are subject to the Netscape Public License
* Version 1.0 (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)
*/
#ifndef NSIO_H
#define NSIO_H
/*
* nsio.h
* @author derekt@netscape.com
* @version 1.0
*/
#include "nsmail.h"
#include "nssocket.h"
#define DEFAULT_BUFFER_LENGTH 1024
const static char eoline[] = "\r\n";
/*IO structure.*/
typedef struct IO
{
int socket;
struct timeval timeout;
nsmail_io_fns_t ioFunctions;
unsigned int readBufferLimit;
unsigned int writeBufferLimit;
unsigned int readBufferSize;
unsigned int writeBufferSize;
char * readBuffer;
char * writeBuffer;
} IO_t;
/*Initialize the IO structure.*/
/*You must make sure that in_bufferSize is at least large
enough to hold an entire line including CRLF*/
int IO_initialize( IO_t * in_pIO,
unsigned int in_readBufferLimit,
unsigned int in_writeBufferLimit );
/*Free the all members of the IO structure.*/
void IO_free( IO_t * in_pIO );
/*Connect to the specified server at the specified port.*/
int IO_connect( IO_t * in_pIO, const char * in_szServer, unsigned short in_nPort );
/*Disconnect from the server.*/
int IO_disconnect( IO_t * in_pIO );
/*Send a byte of data to the server.*/
int IO_writeByte( IO_t * in_pIO, const char in_byte );
/*Send data to the server.*/
int IO_write( IO_t * in_pIO, const char * in_data, unsigned int in_length );
/*Send data to the server appending the \r\n and optionally flushing.*/
int IO_send( IO_t * in_pIO, const char * in_data, boolean in_bufferData );
/*Send a byte of data to the server.*/
int IO_flush( IO_t * in_pIO );
/*Read size number of bytes directly from the socket.*/
int IO_read( IO_t * in_pIO, char * out_response, int in_size, int * out_bytesRead );
/*Reads a line of data from the socket.*/
int IO_readLine( IO_t * in_pIO, char * out_response, int in_maxLength );
/*Reads a line of data from the socket and allocates the proper amount of space for out_ppResponse.*/
int IO_readDLine( IO_t * in_pIO, char** out_ppResponse );
/*Frees the line dynamically allocated by IO_readDLine.*/
int IO_freeDLine( char ** out_ppResponse );
/*Set the timeout for reading data from the socket.*/
int IO_setTimeout( IO_t * in_pIO, double in_timeout );
/* Function to set IO functions.*/
void IO_setFunctions( IO_t * in_pIO, nsmail_io_fns_t * in_pIOFunctions );
/* Functions to get IO functions.*/
void IO_getFunctions( IO_t * in_pIO, nsmail_io_fns_t * in_pIOFunctions );
#endif /* NSIO_H */

159
msgsdk/C/include/nsmail.h Normal file
Просмотреть файл

@ -0,0 +1,159 @@
/*
* The contents of this file are subject to the Netscape Public License
* Version 1.0 (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)
*/
#ifndef NSMAIL_H
#define NSMAIL_H
/*
* nsio.h
* @author prasad
* @version 1.0
*/
#ifdef XP_UNIX
#include <sys/time.h>
#endif /* XP_UNIX */
#ifdef AIX
#include <sys/select.h>
#endif /* AIX */
#ifdef WIN32
#include <winsock.h>
#endif /* WIN32 */
#define FALSE 0
#define TRUE 1
typedef unsigned char boolean;
#ifdef XP_UNIX
#define BOOLEAN int
#endif
/*
Definitions for various options that might want to be set.
*/
typedef enum NSMAIL_Options
{
NSMAIL_OPT_IO_FN_PTRS
} NSMAIL_Options_t;
/*
Error codes.
*/
#define NSMAIL_OK 0
#define NSMAIL_ERR_UNINITIALIZED -1
#define NSMAIL_ERR_INVALIDPARAM -2
#define NSMAIL_ERR_OUTOFMEMORY -3
#define NSMAIL_ERR_UNEXPECTED -4
#define NSMAIL_ERR_IO -5
#define NSMAIL_ERR_IO_READ -6
#define NSMAIL_ERR_IO_WRITE -7
#define NSMAIL_ERR_IO_SOCKET -8
#define NSMAIL_ERR_IO_SELECT -9
#define NSMAIL_ERR_IO_CONNECT -10
#define NSMAIL_ERR_IO_CLOSE -11
#define NSMAIL_ERR_PARSE -12
#define NSMAIL_ERR_TIMEOUT -13
#define NSMAIL_ERR_INVALID_INDEX -14
#define NSMAIL_ERR_CANTOPENFILE -15
#define NSMAIL_ERR_CANT_SET -16
#define NSMAIL_ERR_ALREADY_SET -17
#define NSMAIL_ERR_CANT_DELETE -18
#define NSMAIL_ERR_CANT_ADD -19
#define NSMAIL_ERR_SENDDATA -20
#define NSMAIL_ERR_MUSTPROCESSRESPONSES -21
#define NSMAIL_ERR_PIPELININGNOTSUPPORTED -22
#define NSMAIL_ERR_ALREADYCONNECTED -23
#define NSMAIL_ERR_NOTCONNECTED -24
#define NSMAIL_ERR_EOF -1
#define NSMAIL_ERR_NOTIMPL -99
#define ERRORLOG /* turn on error log */
struct sockaddr;
/*
Definition for a structure to plug in specific io functionality.
*/
typedef struct nsmail_io_fns
{
int (*liof_read)( int, char *, int );
int (*liof_write)( int, char *, int );
int (*liof_socket)( int, int, int );
int (*liof_select)( int, fd_set *, fd_set *, fd_set *, struct timeval * );
int (*liof_connect)( int, const struct sockaddr *, int );
int (*liof_close)( int );
} nsmail_io_fns_t;
typedef struct nsmail_inputstream
{
void *rock; /* opaque client data */
/* Returns the number of bytes actually read and -1 on eof on the stream and
* may return an NSMAIL_ERR* (int value < 0) in case of any other error.
* Can be invoked multiple times. Each read returns the next sequence of bytes
* in the stream, starting past the last byte returned by previous read.
* The buf space allocated and freed by the caller. The size parameter
* specifies the maximum number of bytes to be returned by read. If the number
* of bytes actually returned by read is less than size, an eof on the stream
* is assumed.
*/
int (*read) (void *rock, char *buf, int size);
/* Reset the stream to the beginning. A subsequent read returns data from the
start of the stream.
*/
void (*rewind) (void *rock);
/* Closes the stream, freeing any internal buffers and rock etc.
Once a stream is closed it is illegal to attempt read() or rewind()
or close() on the stream. After close(), the nsmail_inputstream structure
corresponding to the stream needs to be freed by the user of the stream.
*/
void (*close) (void *rock);
} nsmail_inputstream_t;
typedef struct nsmail_outputstream
{
void *rock; /* opaque client data */
/* write (CRLF-separated) output in 'buf', of size 'size'. May be called multiple times */
void (*write) (void *rock, const char *buf, int size);
void (*close) (void *rock);
/* Closes the stream, freeing any internal buffers and rock etc.
Once a stream is closed it is illegal to attempt write() or close()
on the stream. After close(), the nsmail_outputstream structure
corresponding to the stream needs to be freed by the user of the stream.
*/
} nsmail_outputstream_t;
#endif /* NSMAIL_H */

106
msgsdk/C/include/nssocket.h Normal file
Просмотреть файл

@ -0,0 +1,106 @@
/*
* The contents of this file are subject to the Netscape Public License
* Version 1.0 (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)
*/
#ifndef NSSOCKET_H
#define NSSOCKET_H
/*
* nssocket.h
* @author derekt@netscape.com
* @version 1.0
*/
#include "linklist.h"
#include <stdio.h>
#ifdef XP_UNIX
#include <sys/time.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <netdb.h>
#endif /* XP_UNIX */
#ifdef AIX
#include <sys/select.h>
#endif /* AIX */
#ifdef WIN32
#include <winsock.h>
#endif /* WIN32 */
#ifdef __cplusplus
extern "C" {
#endif /* __cplusplus */
/* Functions used to initialize and terminate socket IO. */
void NSSock_Initialize();
/* Functions used to initialize and terminate socket IO. */
void NSSock_Terminate();
/* Close the socket connection. */
int NSSock_Close( int in_socket );
/* Connect to the specified host. */
int NSSock_Connect( int in_socket,
const struct sockaddr * in_pHostInetAddr,
int in_port );
/* Read data from the socket. */
int NSSock_Read( int in_socket, char * io_buffer, int in_length );
/*
* Select to determine the status of one or more sockets.
* We use this to simulate timeouts.
*/
int NSSock_Select( int in_nfds,
fd_set * in_readfds,
fd_set * in_writefds,
fd_set * in_exceptfds,
struct timeval * in_timeout );
/* Create a new socket descriptor. */
int NSSock_Socket ( int in_af, int in_type, int in_protocol );
/* Write data to the socket. */
int NSSock_Write( int in_socket, char * in_buffer, int in_length );
/* Call the platform specific getHostbyName(). */
int NSSock_GetHostName( char * out_hostName, int in_maxLength );
LinkedList_t * NSSock_GetHostByName( const char * in_hostName );
/*
int Flush( NSMAIL_Socket_t * in_socket );
char * GetHostByAddr( char * in_dottedDecimal );
char * GetHostByName( const char * in_hostName );
*/
#ifdef __cplusplus
}
#endif /* __cplusplus */
#endif /* NSSOCKET_H */

75
msgsdk/C/src/Makefile Normal file
Просмотреть файл

@ -0,0 +1,75 @@
# GNU Makefile for pop3
#
MSGSDK_ROOT = ../../C
CONFIG_ROOT = ../../CONFIG
BUILD_ROOT = ../
MKDIR = mkdir -p
LIBDIR = $(OBJDIR)/lib
OBJDEST = $(LIBDIR)/libcomm
LIBNAME = libcomm
include $(CONFIG_ROOT)/msgsdk.mk
LOCAL_INCDIR = ../include
CFLAGS += -I$(LOCAL_INCDIR) -D_REENTRANT -D_THREAD_SAFE
ifeq ($(ARCH), AIX)
LIBNAME = libcomm_shr
DLL_SUFFIX = a
endif
#
# Build full target library file and path
#
LIBTARGET = $(addsuffix .$(DLL_SUFFIX), \
$(addprefix $(LIBDIR)/, $(LIBNAME)))
COMMON_OBJS= nsio.o nssocket.o linklist.o nsStream.o
OBJS = $(addprefix $(OBJDEST)/, $(COMMON_OBJS))
all: $(OBJDEST) $(LIBDIR) $(LIBTARGET)
clean:
rm -rf $(OBJDEST)*
rm -rf $(OBJDEST)/*
$(LIBDIR):
echo OBJDEST = $(OBJDEST)
echo LIBDIR = $(LIBDIR)
echo LIBTARGET = $(LIBTARGET)
echo creating $(LIBDIR)
$(MKDIR) $(LIBDIR)
$(OBJDEST):
echo creating $(OBJDEST)
$(MKDIR) $(OBJDEST)
ifeq ($(ARCH), WINNT)
$(LIBTARGET): $(OBJS)
$(PURIFY) $(LINK_DLL) /DEF:comm.def /DEFAULTLIB:WSOCK32.LIB $(OBJS)
else
ifeq ($(ARCH), AIX)
$(LIBTARGET): $(OBJS)
$(LD) $(DLL_LDFLAGS) -bnoentry -o $(LIBTARGET) $(OBJS) -bE:comm.exp -lc_r -lc
else
ifeq ($(ARCH), IRIX)
$(LIBTARGET): $(OBJS)
$(LD) $(DLL_LDFLAGS) -soname $(LIBNAME).so -o $(LIBTARGET) $(OBJS)
else
ifeq ($(ARCH), IRIX64)
$(LIBTARGET): $(OBJS)
$(LD) $(DLL_LDFLAGS) -soname $(LIBNAME).so -o $(LIBTARGET) $(OBJS)
else
$(LIBTARGET): $(OBJS)
echo LIBDIR = $(LIBDIR)
echo LIBTARGET = $(LIBTARGET)
$(LD) $(DLL_LDFLAGS) -o $(LIBTARGET) $(OBJS)
endif
endif
endif
endif

24
msgsdk/C/src/comm.def Normal file
Просмотреть файл

@ -0,0 +1,24 @@
LIBRARY LIBCOMM
DESCRIPTION "COMMON Client exported functions."
EXPORTS
IO_initialize @1
file_inputStream_create @2
buf_inputStream_create @3
file_outputStream_create @4
RemoveAllElements @5
IO_free @6
AddElement @7
IO_write @8
IO_connect @9
IO_send @10
IO_disconnect @11
IO_writeByte @12
IO_flush @13
IO_setTimeout @14
IO_setFunctions @15
IO_getFunctions @16
IO_readLine @17
IO_readDLine @18
IO_read @19
IO_freeDLine @20
nsStream_free @21

21
msgsdk/C/src/comm.exp Normal file
Просмотреть файл

@ -0,0 +1,21 @@
IO_initialize
file_inputStream_create
buf_inputStream_create
file_outputStream_create
RemoveAllElements
IO_free
AddElement
IO_write
IO_connect
IO_send
IO_disconnect
IO_writeByte
IO_flush
IO_setTimeout
IO_setFunctions
IO_getFunctions
IO_readLine
IO_readDLine
IO_read
IO_freeDLine
nsStream_free

108
msgsdk/C/src/linklist.c Normal file
Просмотреть файл

@ -0,0 +1,108 @@
/*
* The contents of this file are subject to the Netscape Public License
* Version 1.0 (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)
*/
/*
* linklist.c
* @author derekt@netscape.com
* @version 1.0
*/
#include "nsmail.h"
#include "linklist.h"
#include <malloc.h>
#include <string.h>
int AddElement( LinkedList_t ** in_ppLinkedList, void * in_pData )
{
LinkedList_t * l_node;
LinkedList_t * l_temp;
if ( in_pData == NULL || in_ppLinkedList == NULL )
{
return NSMAIL_ERR_INVALIDPARAM;
}
l_node = (LinkedList_t*)malloc( sizeof( LinkedList_t ) );
if ( l_node == NULL )
{
return NSMAIL_ERR_OUTOFMEMORY;
}
l_node->next = NULL;
l_node->pData = in_pData;
if ( *in_ppLinkedList == NULL )
{
*in_ppLinkedList = l_node;
}
else
{
l_temp = *in_ppLinkedList;
while ( l_temp->next != NULL )
{
l_temp = l_temp->next;
}
l_temp->next = l_node;
}
return NSMAIL_OK;
}
void RemoveAllElements( LinkedList_t ** in_ppLinkedList )
{
LinkedList_t * l_prevListPtr = *in_ppLinkedList;
LinkedList_t * l_currListPtr = l_prevListPtr;
while ( l_currListPtr != NULL )
{
l_currListPtr = l_currListPtr->next;
free( l_prevListPtr );
l_prevListPtr = l_currListPtr;
}
*in_ppLinkedList = NULL;
}
int size( LinkedList_t * in_ppLinkedList )
{
int l_nCount = 0;
while ( in_ppLinkedList != NULL )
{
l_nCount++;
in_ppLinkedList = in_ppLinkedList->next;
}
return l_nCount;
}

549
msgsdk/C/src/nsStream.c Normal file
Просмотреть файл

@ -0,0 +1,549 @@
/*
* The contents of this file are subject to the Netscape Public License
* Version 1.0 (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)
*/
/*
* nsStream.c
* prasad@netscape.com, Jan 1998.
*/
#include "nsStream.h"
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <malloc.h>
#include <ctype.h>
#include <memory.h>
#define MAX_BUFSIZE 1024
/* Internal structures */
typedef struct buf_inputStream_tracker
{
char * pDataBuf; /* data buffer */
long total_size; /* totoal buffer size */
long bytes_read; /* number of bytes read */
char * pNext;
} buf_inputStream_tracker_t;
typedef struct file_inputStream_tracker
{
FILE * fp;
char * file_name;
long bytes_read;
} file_inputStream_tracker_t;
typedef struct file_outputStream_tracker
{
FILE * fp;
char * file_name;
long bytes_written;
} file_outputStream_tracker_t;
/* ========================= STREAM UTILITIES =============================*/
/*
* Prasad, jan 8,98
* Reader function for a buffer based inputstream
* Note buf space is allocated/freed by the caller.
*
* parameter :
*
* return :
*/
int buf_inputStream_read (void * rock, char *buf, int size)
{
buf_inputStream_tracker_t * pStream;
int bytes_to_read = 0, bytes_left;
if (rock == NULL || buf == NULL || size <= 0)
{
return NSMAIL_ERR_INVALIDPARAM;
}
pStream = (buf_inputStream_tracker_t *) rock;
if (pStream->pDataBuf == NULL)
{
return NSMAIL_ERR_INVALIDPARAM;
}
bytes_left = pStream->total_size - pStream->bytes_read;
if (bytes_left <= 0)
{
return NSMAIL_ERR_EOF;
}
if (bytes_left >= size)
bytes_to_read = size;
else
bytes_to_read = bytes_left;
memcpy( buf, pStream->pNext, bytes_to_read );
if (bytes_to_read < size)
buf [bytes_to_read] = NULL; /* NULL terminate it */
if (bytes_to_read == size)
{
/* we still have data to read on the stream */
pStream->bytes_read += bytes_to_read;
if (pStream->bytes_read < pStream->total_size)
pStream->pNext += bytes_to_read;
else
pStream->pNext = pStream->pDataBuf + pStream->total_size -1; /* on last byte */
}
else
{
/* We returned less than what was asked. So we are at EOF */
pStream->bytes_read = pStream->total_size;
pStream->pNext = pStream->pDataBuf + pStream->total_size -1; /* on last byte */
}
return bytes_to_read;
}
/*
* Prasad, jan 8,98
* Rewind function for a buffer based inputstream
*
* parameter : rock
*
* return : nothing
*/
void buf_inputStream_rewind (void * rock)
{
buf_inputStream_tracker_t * pStream;
if (rock == NULL)
return;
pStream = (buf_inputStream_tracker_t *) rock;
pStream->bytes_read = 0;
pStream->pNext = pStream->pDataBuf;
}
/*
* Prasad, jan 8,98
* Close function for a buffer based inputstream
* The client must free the stream after return from close.
*
* parameter : rock
*
* return : nothing
*/
void buf_inputStream_close (void * rock)
{
buf_inputStream_tracker_t * pStream;
if (rock == NULL)
{
return;
}
pStream = (buf_inputStream_tracker_t *) rock;
free (pStream->pDataBuf);
pStream->pDataBuf = NULL;
pStream->pNext = NULL;
pStream->total_size = 0;
pStream->bytes_read = 0;
free (rock);
/* rock = NULL; */
}
/*
* Prasad, jan 8,98
* Makes and returns an input stream out of the databuffer Passed.
* Uses the passed buffer as is. That is, data is not copied.
* data_size must be identical to actual size of data in pDataBuf.
*
* parameter :
*
* return :
*/
int buf_inputStream_create (char * pDataBuf, long data_size, nsmail_inputstream_t ** ppRetInputStream)
{
nsmail_inputstream_t * pNewStream;
buf_inputStream_tracker_t * pTracker;
if (pDataBuf == NULL || data_size <= 0)
{
return NSMAIL_ERR_INVALIDPARAM;
}
pNewStream = (nsmail_inputstream_t *) malloc (sizeof (nsmail_inputstream_t));
if (pNewStream == NULL)
{
return NSMAIL_ERR_OUTOFMEMORY;
}
pTracker = (buf_inputStream_tracker_t *) malloc (sizeof (buf_inputStream_tracker_t));
if (pTracker == NULL)
{
return NSMAIL_ERR_OUTOFMEMORY;
}
pTracker->pDataBuf = pDataBuf;
pTracker->pNext = pDataBuf;
pTracker->total_size = data_size;
pTracker->bytes_read = 0;
pNewStream->rock = (void *) pTracker;
pNewStream->read = buf_inputStream_read;
pNewStream->rewind = buf_inputStream_rewind;
pNewStream->close = buf_inputStream_close;
*ppRetInputStream = pNewStream;
return NSMAIL_OK;
}
/*
* Prasad, jan 8,98
* Reader function for a file based inputstream
* Note: buf space is allocated/freed by the caller.
*
* parameter :
*
* return :
*/
int file_inputStream_read (void * rock, char *buf, int size)
{
file_inputStream_tracker_t * pStream;
int read_len = 0;
if (rock == NULL)
{
return -1;
}
if (buf == NULL)
NSMAIL_ERR_INVALIDPARAM;
pStream = (file_inputStream_tracker_t *) rock;
if (pStream->fp == NULL)
{
return -1;
}
read_len = fread (buf, sizeof (char), size, pStream->fp);
if (read_len < size)
buf [read_len] = NULL; /* NULL terminate it */
if (read_len > 0)
(pStream->bytes_read += read_len);
else
read_len = -1;
return read_len;
}
/*
* Prasad, jan 8,98
* Rewind function for a file based inputstream
*
* parameter : rock
*
* return : nothing
*/
void file_inputStream_rewind (void * rock)
{
file_inputStream_tracker_t * pStream;
if (rock == NULL)
{
return;
}
pStream = (file_inputStream_tracker_t *) rock;
if (pStream->fp == NULL)
{
return;
}
rewind (pStream->fp);
pStream->bytes_read = 0;
}
/*
* Prasad, jan 8,98
* Close function for a file based inputstream
* The client must free the stream after return from close.
*
* parameter : rock
*
* return : nothing
*/
void file_inputStream_close (void * rock)
{
file_inputStream_tracker_t * pStream;
if (rock == NULL)
{
return;
}
pStream = (file_inputStream_tracker_t *) rock;
if (pStream->fp == NULL)
{
free (rock);
return;
}
fclose (pStream->fp);
free (pStream->file_name);
free (rock);
/* rock = NULL; */
}
/*
* Prasad, jan 8,98
* Makes and returns an input stream out of the fileName Passed.
* NOTE: fileName must be that of an existing file since this is an inputStream.
*
* parameter :
*
* return :
*/
int file_inputStream_create (char * fileName, nsmail_inputstream_t ** ppRetInputStream)
{
FILE * fp;
nsmail_inputstream_t * pNewStream;
file_inputStream_tracker_t * pTracker;
if (fileName == NULL || ppRetInputStream == NULL)
{
return NSMAIL_ERR_INVALIDPARAM;
}
if ((fp = fopen(fileName, "rb")) == (FILE *) NULL)
{
return NSMAIL_ERR_CANTOPENFILE;
}
pNewStream = (nsmail_inputstream_t *) malloc (sizeof (nsmail_inputstream_t));
if (pNewStream == NULL)
{
return NSMAIL_ERR_OUTOFMEMORY;
}
pTracker = (file_inputStream_tracker_t *) malloc (sizeof (file_inputStream_tracker_t));
if (pTracker == NULL)
{
return NSMAIL_ERR_OUTOFMEMORY;
}
pTracker->file_name = (char *) strdup (fileName);
pTracker->fp = fp;
pTracker->bytes_read = 0;
pNewStream->rock = (void *) pTracker;
pNewStream->read = file_inputStream_read;
pNewStream->rewind = file_inputStream_rewind;
pNewStream->close = file_inputStream_close;
*ppRetInputStream = pNewStream;
return 0;
}
/*
* Prasad, jan 8,98
* Returns the size of data that is available on the inputstream. -1 on an error.
*
* parameter :
*
* return :
*/
static long get_inputstream_size (nsmail_inputstream_t * pTheStream)
{
static char * pLocalBuf; /* allocated only once */
long stream_size = 0;
long read_size = 0;
if (pLocalBuf == NULL)
pLocalBuf = (char *) malloc (MAX_BUFSIZE+1); /* allocated only once */
if (pLocalBuf == NULL)
{
return NSMAIL_ERR_OUTOFMEMORY;
}
while (TRUE)
{
read_size = pTheStream->read (pTheStream->rock, pLocalBuf, MAX_BUFSIZE);
if (read_size > 0)
{
stream_size += read_size;
read_size = 0;
}
else
break;
} /* while */
if (stream_size > 0)
{
pTheStream->rewind (pTheStream->rock);
return (stream_size);
}
else
return (-1);
} /* get_inputstream_size */
void file_outputStream_write (void * rock, const char *buf, int size)
{
file_outputStream_tracker_t * pStream;
int write_len = 0;
if (rock == NULL)
{
return;
}
pStream = (file_outputStream_tracker_t *) rock;
if (pStream->fp == NULL)
{
return;
}
write_len = fwrite (buf, sizeof (char), size, pStream->fp);
if (write_len > 0)
(pStream->bytes_written += write_len);
return;
}
void file_outputStream_close (void * rock)
{
file_outputStream_tracker_t * pStream;
if (rock == NULL)
{
return;
}
pStream = (file_outputStream_tracker_t *) rock;
if (pStream->fp == NULL)
{
free (rock);
return;
}
fclose (pStream->fp);
free (pStream->file_name);
free (rock);
/* rock = NULL; */
}
int file_outputStream_create (char * fileName, nsmail_outputstream_t ** ppRetOutputStream)
{
FILE * fp;
nsmail_outputstream_t * pNewStream;
file_outputStream_tracker_t * pTracker;
if (fileName == NULL || ppRetOutputStream == NULL)
{
return NSMAIL_ERR_INVALIDPARAM;
}
if ((fp = fopen(fileName, "wb")) == (FILE *) NULL)
{
return NSMAIL_ERR_CANTOPENFILE;
}
pNewStream = (nsmail_outputstream_t *) malloc (sizeof (nsmail_outputstream_t));
if (pNewStream == NULL)
{
return NSMAIL_ERR_OUTOFMEMORY;
}
pTracker = (file_outputStream_tracker_t *) malloc (sizeof (file_outputStream_tracker_t));
if (pTracker == NULL)
{
return NSMAIL_ERR_OUTOFMEMORY;
}
pTracker->file_name = (char *) strdup (fileName);
pTracker->fp = fp;
pTracker->bytes_written = 0;
pNewStream->rock = (void *) pTracker;
pNewStream->write = file_outputStream_write;
/* pNewStream->rewind = file_inputStream_rewind; */
pNewStream->close = file_outputStream_close;
*ppRetOutputStream = pNewStream;
return 0;
}
void nsStream_free (void * pMem)
{
free (pMem);
}

839
msgsdk/C/src/nsio.c Normal file
Просмотреть файл

@ -0,0 +1,839 @@
/*
* The contents of this file are subject to the Netscape Public License
* Version 1.0 (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)
*/
/*
* nsio.c
* @author derekt@netscape.com
* @version 1.0
*/
#include "nsmail.h"
#include "nsio.h"
#include "nssocket.h"
#include <string.h>
#include <malloc.h>
#include <ctype.h>
#include <stdio.h>
/* Internal functions not to be used directly. */
int IO_checkTimeout( IO_t * in_pIO );
void IO_resetFunctions( IO_t * in_pIO );
int UpdateBuffer( IO_t * in_pIO );
/* Initalize the IO structure. */
int IO_initialize( IO_t * in_pIO,
unsigned int in_readBufferLimit,
unsigned int in_writeBufferLimit )
{
/*
* Parameter validation.
*/
if ( in_pIO == NULL ||
in_pIO->readBuffer != NULL ||
in_pIO->writeBuffer != NULL )
{
return NSMAIL_ERR_INVALIDPARAM;
}
if ( in_readBufferLimit == 0 )
{
in_pIO->readBufferLimit = DEFAULT_BUFFER_LENGTH;
}
else
{
in_pIO->readBufferLimit = in_readBufferLimit;
}
if ( in_writeBufferLimit == 0 )
{
in_pIO->writeBufferLimit = DEFAULT_BUFFER_LENGTH;
}
else
{
in_pIO->writeBufferLimit = in_writeBufferLimit;
}
/*
* Set the socket descriptor to an invalid value to identify a
* disconnected state.
*/
in_pIO->socket = -1;
/*
* Initialize the read buffer.
*/
in_pIO->readBuffer = (char*)malloc( in_pIO->readBufferLimit * sizeof( char ) );
if ( in_pIO->readBuffer == NULL )
{
return NSMAIL_ERR_OUTOFMEMORY;
}
memset(in_pIO->readBuffer, 0, in_pIO->readBufferLimit * sizeof( char ) );
/*
* Initialize the write buffer.
*/
in_pIO->writeBuffer = (char*)malloc( in_pIO->writeBufferLimit * sizeof( char ) );
if ( in_pIO->writeBuffer == NULL )
{
return NSMAIL_ERR_OUTOFMEMORY;
}
memset(in_pIO->writeBuffer, 0, in_pIO->writeBufferLimit * sizeof( char ) );
/* Set the current size of the write buffer. */
in_pIO->writeBufferSize = 0;
/* Set the current size of the read buffer. */
in_pIO->readBufferSize = 0;
/* Set the IO function pointers. */
IO_resetFunctions( in_pIO );
/* Set the default timeout value. */
return IO_setTimeout( in_pIO, -1 );
}
/* Free the IO structure. */
void IO_free( IO_t * in_pIO )
{
if ( in_pIO == NULL )
{
return;
}
/*
* Reset the data members.
*/
if ( in_pIO->readBuffer != NULL )
{
free( in_pIO->readBuffer );
in_pIO->readBuffer = NULL;
}
if ( in_pIO->writeBuffer != NULL )
{
free( in_pIO->writeBuffer );
in_pIO->writeBuffer = NULL;
}
/*
* Terminate the socket session.
*/
NSSock_Terminate();
}
/* Connect to the specified server with the specified port. */
int IO_connect( IO_t * in_pIO, const char * in_szServer, unsigned short in_nPort )
{
struct sockaddr_in l_hostInetAddr;
LinkedList_t * l_addressList;
LinkedList_t * l_tempList;
int fHostIsIPAddr;
int dotCount = 0;
int i;
/*
* Parameter validation.
*/
if ( in_pIO == NULL || in_szServer == NULL )
{
return NSMAIL_ERR_INVALIDPARAM;
}
if ( in_pIO->socket > 0 )
{
return NSMAIL_ERR_ALREADYCONNECTED;
}
/*
* Initialize the socket session.
*/
NSSock_Initialize();
/*
* Create a handle to the new socket.
*/
in_pIO->socket = in_pIO->ioFunctions.liof_socket( AF_INET, SOCK_STREAM, 0 );
if ( in_pIO->socket < 0 )
{
return NSMAIL_ERR_IO_SOCKET;
}
/* initialize the address structures */
memset (&l_hostInetAddr, 0, sizeof(l_hostInetAddr));
l_hostInetAddr.sin_family = AF_INET;
l_hostInetAddr.sin_port = htons(in_nPort);
/*
* Determine if a host name or IP address was specified. Assume
* it is, then see if we can find something that means it isn't.
* (The test below is not very careful, it should verify there
* are numbers between the dots, and the numbers are less than 256.)
*/
fHostIsIPAddr = 1;
for (i=0; i<strlen(in_szServer); ++i) {
if (in_szServer[i] == '.') {
++dotCount;
}
else if (!isdigit(in_szServer[i])) {
fHostIsIPAddr = 0;
break;
}
}
if (dotCount != 3) {
fHostIsIPAddr = 0;
}
if ( fHostIsIPAddr )
{
l_hostInetAddr.sin_addr.s_addr = inet_addr( (char *)in_szServer );
if ( in_pIO->ioFunctions.liof_connect(
in_pIO->socket,
(const struct sockaddr *)&l_hostInetAddr,
in_nPort ) != FALSE )
{
return NSMAIL_OK;
}
}
else
{
l_addressList = NSSock_GetHostByName( in_szServer );
while ( l_addressList != NULL )
{
if ( ( l_hostInetAddr.sin_addr.s_addr = inet_addr(l_addressList->pData) ) != 0 )
{
if ( in_pIO->ioFunctions.liof_connect(
in_pIO->socket,
(const struct sockaddr *)&l_hostInetAddr,
in_nPort ) != FALSE )
{
while ( l_addressList != NULL )
{
free( l_addressList->pData );
l_tempList = l_addressList;
l_addressList = l_tempList->next;
free( l_tempList );
}
return NSMAIL_OK;
}
}
free( l_addressList->pData );
l_tempList = l_addressList;
l_addressList = l_tempList->next;
free( l_tempList );
}
}
in_pIO->socket = -1;
return NSMAIL_ERR_IO_CONNECT;
}
/* Disconnect from the server. */
int IO_disconnect( IO_t * in_pIO )
{
/*
* Parameter validation.
*/
if ( in_pIO == NULL )
{
return NSMAIL_ERR_INVALIDPARAM;
}
if ( in_pIO->socket < 0 )
{
return NSMAIL_ERR_NOTCONNECTED;
}
/*
* Close the socket.
*/
if ( in_pIO->ioFunctions.liof_close( in_pIO->socket ) == FALSE )
{
in_pIO->socket = -1;
return NSMAIL_ERR_IO_CLOSE;
}
in_pIO->socket = -1;
return NSMAIL_OK;
}
/*Send data to the server appending the \r\n and optionally flushing.*/
int IO_send( IO_t * in_pIO, const char * in_data, boolean in_bufferData )
{
int l_nReturn;
l_nReturn = IO_write( in_pIO, in_data, strlen(in_data) );
if ( l_nReturn != NSMAIL_OK )
{
return l_nReturn;
}
l_nReturn = IO_write( in_pIO, eoline, 2 );
if ( l_nReturn != NSMAIL_OK )
{
return l_nReturn;
}
if ( in_bufferData == FALSE )
{
l_nReturn = IO_flush( in_pIO );
if ( l_nReturn != NSMAIL_OK )
{
return l_nReturn;
}
}
return NSMAIL_OK;
}
/* Write operation to the buffered socket. */
int IO_write( IO_t * in_pIO, const char * in_data, unsigned int in_length )
{
int l_nReturn;
/* Parameter validation.*/
if ( in_pIO == NULL || in_data == NULL )
{
return NSMAIL_ERR_INVALIDPARAM;
}
if ( in_pIO->socket < 0 )
{
return NSMAIL_ERR_NOTCONNECTED;
}
/* Fill the buffer and send the data if it is full. */
if ( in_pIO->writeBufferSize + in_length < in_pIO->writeBufferLimit )
{
memcpy( &(in_pIO->writeBuffer[in_pIO->writeBufferSize]),
in_data,
in_length );
in_pIO->writeBufferSize += in_length;
}
else
{
l_nReturn = IO_flush( in_pIO );
if ( l_nReturn != NSMAIL_OK )
{
return l_nReturn;
}
if ( in_length < in_pIO->writeBufferLimit )
{
memcpy( in_pIO->writeBuffer, in_data, in_length );
in_pIO->writeBufferSize = in_length;
}
else
{
if ( in_pIO->ioFunctions.liof_write( in_pIO->socket,
(char*)in_data,
in_length ) == FALSE )
{
return NSMAIL_ERR_IO_WRITE;
}
}
}
return NSMAIL_OK;
}
int IO_writeByte( IO_t * in_pIO, const char in_byte )
{
int l_nReturn;
/* Parameter validation */
if ( in_pIO == NULL )
{
return NSMAIL_ERR_INVALIDPARAM;
}
if ( in_pIO->socket < 0 )
{
return NSMAIL_ERR_NOTCONNECTED;
}
/*
* Fill the buffer and send the data if it is full.
*/
if ( in_pIO->writeBufferSize + 1 < in_pIO->writeBufferLimit )
{
in_pIO->writeBuffer[(in_pIO->writeBufferSize)++] = in_byte;
}
else
{
l_nReturn = IO_flush( in_pIO );
if ( l_nReturn != NSMAIL_OK )
{
return l_nReturn;
}
in_pIO->writeBuffer[(in_pIO->writeBufferSize)++] = in_byte;
}
return NSMAIL_OK;
}
int IO_flush( IO_t * in_pIO )
{
/* Parameter validation */
if ( in_pIO == NULL || in_pIO->writeBuffer == NULL )
{
return NSMAIL_ERR_INVALIDPARAM;
}
if ( in_pIO->socket < 0 )
{
return NSMAIL_ERR_NOTCONNECTED;
}
/* Send the data and verify that it was sent ok. */
if ( in_pIO->writeBufferSize > 0 )
{
if ( in_pIO->ioFunctions.liof_write( in_pIO->socket,
(char*)in_pIO->writeBuffer,
in_pIO->writeBufferSize ) == FALSE )
{
return NSMAIL_ERR_IO_WRITE;
}
memset( in_pIO->writeBuffer, 0, in_pIO->writeBufferLimit );
in_pIO->writeBufferSize = 0;
}
return NSMAIL_OK;
}
/**
* Read in in_size bytes into out_response
* @param in_pIO The IO structure
* @param out_ppResponse The memory to store the data in
* @param in_size The amount of data requested
& @param out_bytesRead The total number of bytes read
*/
int IO_read( IO_t * in_pIO, char * out_response, int in_size, int * out_bytesRead )
{
int l_returnCode;
int l_bytesRead = 0;
int l_bytesToRead = 0;
int l_offset = 0;
/* Parameter validation. */
if ((in_pIO == NULL) || (out_response == NULL) ||
(in_size < 1) || (out_bytesRead == NULL))
{
return NSMAIL_ERR_INVALIDPARAM;
}
/* Make sure the IO buffer is not empty */
if ( in_pIO->readBufferSize == 0 )
{
l_returnCode = UpdateBuffer( in_pIO );
if ( l_returnCode != NSMAIL_OK )
{
return l_returnCode;
}
}
/* Read in_size bytes */
while ( l_bytesRead < in_size )
{
/* Determine amount of data to read in from the IO buffer */
if( (in_pIO->readBufferSize + l_bytesRead) <= in_size)
{
l_bytesToRead = in_pIO->readBufferSize;
}
else
{
l_bytesToRead = in_size - l_bytesRead;
}
memcpy(out_response + l_bytesRead, in_pIO->readBuffer, l_bytesToRead);
in_pIO->readBufferSize -= l_bytesToRead;
l_bytesRead += l_bytesToRead;
l_offset += l_bytesToRead;
/* Make sure the IO buffer is not empty */
if ( in_pIO->readBufferSize == 0 )
{
l_returnCode = UpdateBuffer( in_pIO );
if ( l_returnCode != NSMAIL_OK )
{
return l_returnCode;
}
l_offset = 0;
}
}
/* Move the rest of the buffer to the beginning of the buffer. */
memcpy( in_pIO->readBuffer, (&in_pIO->readBuffer[l_offset]), in_pIO->readBufferSize );
(*out_bytesRead) = l_bytesRead;
return NSMAIL_OK;;
}
/* Reads a line from the socket. */
int IO_readLine( IO_t * in_pIO, char * out_response, int in_maxLength )
{
int l_returnCode;
unsigned int offset = 0;
/* Parameter validation. */
if ( in_pIO == NULL || out_response == NULL || out_response == NULL )
{
return NSMAIL_ERR_INVALIDPARAM;
}
if ( in_pIO->socket < 0 )
{
return NSMAIL_ERR_NOTCONNECTED;
}
if ( in_pIO->readBufferSize == 0 )
{
l_returnCode = UpdateBuffer( in_pIO );
if ( l_returnCode != NSMAIL_OK )
{
return l_returnCode;
}
}
/* Read byte by byte looking for the newline character. */
while ( in_pIO->readBuffer[offset] != '\n' )
{
offset++;
if ( offset == in_pIO->readBufferSize )
{
if ( offset == in_pIO->readBufferLimit )
{
return NSMAIL_ERR_UNEXPECTED;
}
l_returnCode = UpdateBuffer( in_pIO );
if ( l_returnCode != NSMAIL_OK )
{
return l_returnCode;
}
}
}
if ( offset > in_maxLength )
{
return NSMAIL_ERR_UNEXPECTED;
}
/* Copy the line into the buffer. */
memcpy( out_response, in_pIO->readBuffer, offset + 1 );
in_pIO->readBufferSize -= (offset + 1);
/* Move the rest of the buffer to the beginning of the buffer. */
memcpy( in_pIO->readBuffer,
(&in_pIO->readBuffer[offset+1]),
in_pIO->readBufferSize );
/*
* Look for the carriage return character.
* If it is there, place the null character there,
* else put the null character in the location of the linefeed character.
*/
if ( out_response[offset-1] == '\r' )
{
out_response[offset-1] = '\0';
}
else
{
out_response[offset] = '\0';
}
return NSMAIL_OK;;
}
/* Reads a line from the socket and dynamically allocates the necessary space for the response */
int IO_readDLine( IO_t * in_pIO, char** out_ppResponse )
{
int l_returnCode;
unsigned int offset = 0;
char* l_tempBuffer = NULL;
int l_bufferlength = 0;
/* Parameter validation. */
if ( in_pIO == NULL || (*out_ppResponse) != NULL )
{
return NSMAIL_ERR_INVALIDPARAM;
}
if ( in_pIO->socket < 0 )
{
return NSMAIL_ERR_NOTCONNECTED;
}
/* Make sure the IO buffer is not empty */
while( in_pIO->readBufferSize == 0 )
{
l_returnCode = UpdateBuffer( in_pIO );
if ( l_returnCode != NSMAIL_OK )
{
return l_returnCode;
}
}
/* Read byte by byte looking for the newline character. */
while(in_pIO->readBuffer[offset] != '\n')
{
offset++;
if(offset >= in_pIO->readBufferSize)
{
if(offset == in_pIO->readBufferLimit)
{
/*Grow the size of the read buffer*/
l_bufferlength = in_pIO->readBufferLimit + DEFAULT_BUFFER_LENGTH;
l_tempBuffer = in_pIO->readBuffer;
in_pIO->readBuffer = (char*)malloc(l_bufferlength*sizeof(char));
if(in_pIO->readBuffer == NULL)
{
return NSMAIL_ERR_OUTOFMEMORY;
}
memset(in_pIO->readBuffer, 0, l_bufferlength*sizeof(char));
in_pIO->readBufferLimit = l_bufferlength;
memcpy( in_pIO->readBuffer,
l_tempBuffer,
in_pIO->readBufferSize );
free(l_tempBuffer);
l_tempBuffer = NULL;
}
while(offset >= in_pIO->readBufferSize)
{
/* Put more data in the buffer. */
l_returnCode = UpdateBuffer( in_pIO );
if ( l_returnCode != NSMAIL_OK )
{
return l_returnCode;
}
}
}
}
(*out_ppResponse) = (char*)malloc((offset + 2)*sizeof(char));
if((*out_ppResponse) == NULL)
{
return NSMAIL_ERR_OUTOFMEMORY;
}
memset((*out_ppResponse), 0, (offset + 2)*sizeof(char));
memcpy((*out_ppResponse), in_pIO->readBuffer, offset + 1);
in_pIO->readBufferSize -= (offset + 1);
/* Move the rest of the buffer to the beginning of the buffer. */
memcpy( in_pIO->readBuffer,
(&in_pIO->readBuffer[offset + 1]),
in_pIO->readBufferSize );
memset((&in_pIO->readBuffer[in_pIO->readBufferSize]), 0, in_pIO->readBufferLimit - in_pIO->readBufferSize);
return NSMAIL_OK;
}
int IO_freeDLine( char ** out_ppResponse )
{
if ( out_ppResponse == NULL || (*out_ppResponse) == NULL )
{
return NSMAIL_ERR_INVALIDPARAM;
}
free( (*out_ppResponse) );
(*out_ppResponse) = NULL;
return NSMAIL_OK;
}
/* Updates the read buffer. */
int UpdateBuffer( IO_t * in_pIO )
{
int l_nByteCount;
int l_nSelectResponse;
/* Determine if there is any data to be read in. */
l_nSelectResponse = IO_checkTimeout( in_pIO );
if ( l_nSelectResponse == 0 )
{
return NSMAIL_ERR_TIMEOUT;
}
/* Determine if there was an error. */
if ( l_nSelectResponse < 0 )
{
return NSMAIL_ERR_IO_SELECT;
}
/* Read in as much data as possible up to the max. size from the socket. */
l_nByteCount = in_pIO->ioFunctions.liof_read(
in_pIO->socket,
in_pIO->readBuffer + in_pIO->readBufferSize,
in_pIO->readBufferLimit - in_pIO->readBufferSize );
if ( l_nByteCount <= 0 )
{
return NSMAIL_ERR_IO_READ;
}
/* Set the new size of the read buffer. */
in_pIO->readBufferSize += l_nByteCount;
return NSMAIL_OK;
}
/* Set the timeout value. */
int IO_setTimeout( IO_t * in_pIO, double in_timeout )
{
if ( in_pIO == NULL )
{
return NSMAIL_ERR_INVALIDPARAM;
}
/* represents infinite blocking, not timeout */
if ( in_timeout == -1 )
{
in_pIO->timeout.tv_sec = (long)in_timeout;
return NSMAIL_OK;
}
if (in_timeout < 0.0) in_timeout = 0.0;
if (in_timeout > 1.0e8) in_timeout = 1.0e8;
in_pIO->timeout.tv_sec = (long) in_timeout;
in_pIO->timeout.tv_usec = (long) (1.0e6 * (in_timeout-(double)(long)in_timeout));
if (in_pIO->timeout.tv_usec >= 1000000)
{
in_pIO->timeout.tv_sec++;
in_pIO->timeout.tv_usec = 0;
}
return NSMAIL_OK;
}
/* Check for a timeout using select() */
int IO_checkTimeout( IO_t * in_pIO )
{
fd_set * l_fdSet;
int l_nSelectResponse;
int l_nSock = in_pIO->socket + 1;
/*
* Create the fd_set structure to be used in select().
*/
l_fdSet = (fd_set *)malloc( sizeof(fd_set) );
FD_ZERO( l_fdSet );
FD_SET( in_pIO->socket, l_fdSet );
/*
* Determine if the timeout value is infinite or not.
*/
if ( in_pIO->timeout.tv_sec == -1 )
{
l_nSelectResponse = in_pIO->ioFunctions.liof_select( l_nSock, l_fdSet, NULL, NULL, NULL );
}
else
{
l_nSelectResponse = in_pIO->ioFunctions.liof_select( l_nSock, l_fdSet, NULL, NULL, &(in_pIO->timeout) );
}
/*
* Free the fd_set structure.
*/
free( l_fdSet );
/*
* Return the result.
*/
return l_nSelectResponse;
}
/* Reset the IO functions. */
void IO_resetFunctions( IO_t * in_pIO )
{
in_pIO->ioFunctions.liof_read = NSSock_Read;
in_pIO->ioFunctions.liof_write = NSSock_Write;
in_pIO->ioFunctions.liof_socket = NSSock_Socket;
in_pIO->ioFunctions.liof_select = NSSock_Select;
in_pIO->ioFunctions.liof_connect = NSSock_Connect;
in_pIO->ioFunctions.liof_close = NSSock_Close;
}
/* Get a structure to the IO functions. */
void IO_getFunctions( IO_t * in_pIO, nsmail_io_fns_t * in_pIOFunctions )
{
in_pIOFunctions->liof_read = in_pIO->ioFunctions.liof_read;
in_pIOFunctions->liof_write = in_pIO->ioFunctions.liof_write;
in_pIOFunctions->liof_socket = in_pIO->ioFunctions.liof_socket;
in_pIOFunctions->liof_select = in_pIO->ioFunctions.liof_select;
in_pIOFunctions->liof_connect = in_pIO->ioFunctions.liof_connect;
in_pIOFunctions->liof_close = in_pIO->ioFunctions.liof_close;
}
/* Set the IO functions. */
void IO_setFunctions( IO_t * in_pIO, nsmail_io_fns_t * in_pIOFunctions )
{
in_pIO->ioFunctions.liof_read = in_pIOFunctions->liof_read;
in_pIO->ioFunctions.liof_write = in_pIOFunctions->liof_write;
in_pIO->ioFunctions.liof_socket = in_pIOFunctions->liof_socket;
in_pIO->ioFunctions.liof_select = in_pIOFunctions->liof_select;
in_pIO->ioFunctions.liof_connect = in_pIOFunctions->liof_connect;
in_pIO->ioFunctions.liof_close = in_pIOFunctions->liof_close;
}

382
msgsdk/C/src/nssocket.c Normal file
Просмотреть файл

@ -0,0 +1,382 @@
/*
* The contents of this file are subject to the Netscape Public License
* Version 1.0 (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;
}