2058 lines
53 KiB
C
2058 lines
53 KiB
C
|
/* c4com.c (c)Copyright Sequiter Software Inc., 1988-1996. All rights reserved. */
|
||
|
|
||
|
/* CONNECTION4::connectionFailure indicates an irrecoverable connection error.
|
||
|
In the case of only a CODE4::errorCode condition, communications will still
|
||
|
operate normally */
|
||
|
|
||
|
#include "d4all.h"
|
||
|
#ifndef S4UNIX
|
||
|
#ifdef __TURBOC__
|
||
|
#pragma hdrstop
|
||
|
#endif /* __TUROBC__ */
|
||
|
#endif /* S4UNIX */
|
||
|
|
||
|
/* cannot be inline due to DLL CODE4 structure potential mismatches */
|
||
|
/* available whether or not communications are available */
|
||
|
long S4FUNCTION code4timeout( CODE4 *c4 )
|
||
|
{
|
||
|
#ifdef E4PARM_LOW
|
||
|
if ( c4 == 0 )
|
||
|
return error4( 0, e4parm_null, E91006 ) ;
|
||
|
#endif
|
||
|
return c4->timeout ;
|
||
|
}
|
||
|
|
||
|
/* available whether or not communications are available */
|
||
|
void S4FUNCTION code4timeoutSet( CODE4 *c4, long val )
|
||
|
{
|
||
|
#ifdef E4PARM_LOW
|
||
|
if ( c4 == 0 )
|
||
|
{
|
||
|
error4( 0, e4parm_null, E91007 ) ;
|
||
|
return ;
|
||
|
}
|
||
|
#endif
|
||
|
c4->timeout = val ;
|
||
|
}
|
||
|
|
||
|
#ifndef S4OFF_COMMUNICATIONS
|
||
|
|
||
|
/*#include <conio.h>*/
|
||
|
#ifndef S4SERVER
|
||
|
#ifndef S4UNIX
|
||
|
#include <sys\timeb.h>
|
||
|
#else
|
||
|
#ifndef S4NO_FTIME
|
||
|
#include <sys/timeb.h>
|
||
|
#else
|
||
|
#include <sys/time.h>
|
||
|
#endif
|
||
|
#endif
|
||
|
#endif
|
||
|
|
||
|
#ifdef S4COM_PRINT
|
||
|
static void s4connectionPrint( const int ) ;
|
||
|
#endif
|
||
|
|
||
|
#ifndef E4OFF_STRING
|
||
|
extern long error4seek( long ) ;
|
||
|
#endif
|
||
|
|
||
|
#ifdef E4PARM_LOW
|
||
|
static long packet4len( const PACKET4 *packet )
|
||
|
{
|
||
|
if ( packet == 0 )
|
||
|
return error4( 0, e4parm_null, E90159 ) ;
|
||
|
|
||
|
return packet->dataLen ;
|
||
|
}
|
||
|
|
||
|
static int packet4setLen( PACKET4 *packet, const long int dataLen )
|
||
|
{
|
||
|
if ( packet == 0 )
|
||
|
return error4( 0, e4parm_null, E90159 ) ;
|
||
|
|
||
|
packet->dataLen = dataLen ;
|
||
|
|
||
|
return 0 ;
|
||
|
}
|
||
|
|
||
|
static void packet4setStatus( PACKET4 *packet, int status )
|
||
|
{
|
||
|
if ( packet == 0 )
|
||
|
{
|
||
|
error4( 0, e4parm_null, E90159 ) ;
|
||
|
return ;
|
||
|
}
|
||
|
|
||
|
packet->status = status ;
|
||
|
}
|
||
|
|
||
|
static void packet4setType( PACKET4 *packet, const int type )
|
||
|
{
|
||
|
if ( packet == 0 )
|
||
|
{
|
||
|
error4( 0, e4parm_null, E90159 ) ;
|
||
|
return ;
|
||
|
}
|
||
|
|
||
|
packet->type = type ;
|
||
|
}
|
||
|
|
||
|
static int packet4status( const PACKET4 *packet )
|
||
|
{
|
||
|
if ( packet == 0 )
|
||
|
return error4( 0, e4parm_null, E90159 ) ;
|
||
|
|
||
|
return packet->status ;
|
||
|
}
|
||
|
|
||
|
static long packet4errCode2( const PACKET4 *packet )
|
||
|
{
|
||
|
if ( packet == 0 )
|
||
|
return error4( 0, e4parm_null, E90159 ) ;
|
||
|
|
||
|
return packet->errCode2 ;
|
||
|
}
|
||
|
|
||
|
static int packet4setErrCode2( PACKET4 *packet, const long code2 )
|
||
|
{
|
||
|
if ( packet == 0 )
|
||
|
return error4( 0, e4parm_null, E90159 ) ;
|
||
|
|
||
|
packet->errCode2 = code2 ;
|
||
|
return 0 ;
|
||
|
}
|
||
|
|
||
|
static int packet4type( const PACKET4 *packet )
|
||
|
{
|
||
|
if ( packet == 0 )
|
||
|
return error4( 0, e4parm_null, E90159 ) ;
|
||
|
|
||
|
return packet->type ;
|
||
|
}
|
||
|
|
||
|
static long packet4serverId( const PACKET4 *packet )
|
||
|
{
|
||
|
if ( packet == 0 )
|
||
|
{
|
||
|
error4( 0, e4parm_null, E90159 ) ;
|
||
|
return 0 ;
|
||
|
}
|
||
|
return packet->serverDataId ;
|
||
|
}
|
||
|
|
||
|
static long packet4clientId( const PACKET4 *packet )
|
||
|
{
|
||
|
if ( packet == 0 )
|
||
|
{
|
||
|
error4( 0, e4parm_null, E90159 ) ;
|
||
|
return 0 ;
|
||
|
}
|
||
|
|
||
|
return packet->clientDataId ;
|
||
|
}
|
||
|
|
||
|
static int packet4didUnlock( const PACKET4 *packet )
|
||
|
{
|
||
|
if ( packet == 0 )
|
||
|
return error4( 0, e4parm_null, E90159 ) ;
|
||
|
|
||
|
return packet->didUnlock ;
|
||
|
}
|
||
|
|
||
|
static int packet4readLock( const PACKET4 *packet )
|
||
|
{
|
||
|
if ( packet == 0 )
|
||
|
return error4( 0, e4parm_null, E90159 ) ;
|
||
|
|
||
|
return packet->readLock ;
|
||
|
}
|
||
|
|
||
|
static int packet4unlockAuto( const PACKET4 *packet )
|
||
|
{
|
||
|
if ( packet == 0 )
|
||
|
return error4( 0, e4parm_null, E90159 ) ;
|
||
|
|
||
|
return packet->unlockAuto ;
|
||
|
}
|
||
|
|
||
|
static void packet4setClientId( PACKET4 *packet, const long id )
|
||
|
{
|
||
|
if ( packet == 0 )
|
||
|
{
|
||
|
error4( 0, e4parm_null, E90159 ) ;
|
||
|
return ;
|
||
|
}
|
||
|
|
||
|
packet->clientDataId = id ;
|
||
|
}
|
||
|
|
||
|
static void packet4setServerId( PACKET4 *packet, const long id )
|
||
|
{
|
||
|
if ( packet == 0 )
|
||
|
{
|
||
|
error4( 0, e4parm_null, E90159 ) ;
|
||
|
return ;
|
||
|
}
|
||
|
|
||
|
packet->serverDataId = id ;
|
||
|
}
|
||
|
|
||
|
static void packet4setReadLock( PACKET4 *packet, const int readLock )
|
||
|
{
|
||
|
if ( packet == 0 )
|
||
|
{
|
||
|
error4( 0, e4parm_null, E90159 ) ;
|
||
|
return ;
|
||
|
}
|
||
|
|
||
|
packet->readLock = readLock ;
|
||
|
}
|
||
|
|
||
|
static void packet4setRequestLockedInfo( PACKET4 *packet, const int val )
|
||
|
{
|
||
|
if ( packet == 0 )
|
||
|
{
|
||
|
error4( 0, e4parm_null, E90159 ) ;
|
||
|
return ;
|
||
|
}
|
||
|
|
||
|
packet->requestLockedInfo = val ;
|
||
|
}
|
||
|
|
||
|
int packet4requestLockedInfo( const PACKET4 *packet )
|
||
|
{
|
||
|
if ( packet == 0 )
|
||
|
return error4( 0, e4parm_null, E90159 ) ;
|
||
|
|
||
|
return packet->requestLockedInfo ;
|
||
|
}
|
||
|
|
||
|
void packet4setDidUnlock( PACKET4 *packet, const int didUnlock )
|
||
|
{
|
||
|
if ( packet == 0 )
|
||
|
{
|
||
|
error4( 0, e4parm_null, E90159 ) ;
|
||
|
return ;
|
||
|
}
|
||
|
|
||
|
packet->didUnlock = didUnlock ;
|
||
|
}
|
||
|
|
||
|
static void packet4setUnlockAuto( PACKET4 *packet, const int unlockAuto )
|
||
|
{
|
||
|
if ( packet == 0 )
|
||
|
{
|
||
|
error4( 0, e4parm_null, E90159 ) ;
|
||
|
return ;
|
||
|
}
|
||
|
|
||
|
packet->unlockAuto = unlockAuto ;
|
||
|
}
|
||
|
|
||
|
static int packet4partNo( const PACKET4 *packet )
|
||
|
{
|
||
|
if ( packet == 0 )
|
||
|
return error4( 0, e4parm_null, E90159 ) ;
|
||
|
|
||
|
return packet->partNo ;
|
||
|
}
|
||
|
|
||
|
static int packet4numParts( const PACKET4 *packet )
|
||
|
{
|
||
|
if ( packet == 0 )
|
||
|
return error4( 0, e4parm_null, E90159 ) ;
|
||
|
|
||
|
return packet->numParts ;
|
||
|
}
|
||
|
|
||
|
long connection4clientId( const CONNECTION4 *connection )
|
||
|
{
|
||
|
#ifdef E4PARM_LOW
|
||
|
if ( connection == 0 )
|
||
|
{
|
||
|
error4( 0, e4parm_null, E90160 ) ;
|
||
|
return 0 ;
|
||
|
}
|
||
|
#endif
|
||
|
|
||
|
if ( connection->message == 0 )
|
||
|
return 0 ;
|
||
|
|
||
|
return packet4clientId( connection->message->packet ) ;
|
||
|
}
|
||
|
|
||
|
S4CONST char * connection4data( const CONNECTION4 *connection )
|
||
|
{
|
||
|
return connection4dataOffset( connection, 0 ) ;
|
||
|
}
|
||
|
#endif
|
||
|
|
||
|
/* if a single linked message only (case of a receive), then can return parts */
|
||
|
#ifdef S4UTILS
|
||
|
S4CONST char * S4FUNCTION connection4dataOffset( const CONNECTION4 *connection, const unsigned int offset )
|
||
|
#else
|
||
|
S4CONST char *connection4dataOffset( const CONNECTION4 *connection, const unsigned int offset )
|
||
|
#endif
|
||
|
{
|
||
|
MESSAGE4DATA *data ;
|
||
|
|
||
|
#ifdef E4PARM_LOW
|
||
|
if ( connection == 0 )
|
||
|
{
|
||
|
error4( 0, e4parm_null, E90160 ) ;
|
||
|
return 0 ;
|
||
|
}
|
||
|
#endif
|
||
|
|
||
|
if ( connection->messageData.nLink != 1 )
|
||
|
{
|
||
|
#ifdef E4ANALYZE
|
||
|
error4( connection->cb, e4info, E90160 ) ;
|
||
|
#endif
|
||
|
return 0 ;
|
||
|
}
|
||
|
data = (MESSAGE4DATA *)l4first( &connection->messageData ) ;
|
||
|
if ( data == 0 )
|
||
|
return 0 ;
|
||
|
return data->data + offset + connection->adjustForLocked ;
|
||
|
}
|
||
|
|
||
|
int connection4disconnect( CONNECTION4 *connection )
|
||
|
{
|
||
|
int rc ;
|
||
|
|
||
|
#ifdef E4PARM_LOW
|
||
|
if ( connection == 0 )
|
||
|
return error4( 0, e4parm_null, E90160 ) ;
|
||
|
#endif
|
||
|
|
||
|
if ( connection->connected != 0 )
|
||
|
{
|
||
|
#ifdef E4ANALYZE
|
||
|
if ( connection->net == 0 )
|
||
|
return error4( connection->cb, e4struct, E90160 ) ;
|
||
|
#endif
|
||
|
rc = connection4netDisconnect( connection->net ) ;
|
||
|
if ( rc < 0 )
|
||
|
return error4stack( connection->cb, (short)rc, E90160 ) ;
|
||
|
connection->connected = 0 ;
|
||
|
rc = connection4netFree( connection->net ) ;
|
||
|
connection->net = 0 ;
|
||
|
#ifdef S4SERVER
|
||
|
l4remove( &connection->socket->connections, connection ) ;
|
||
|
#endif
|
||
|
return rc ;
|
||
|
}
|
||
|
else
|
||
|
return 0 ;
|
||
|
}
|
||
|
|
||
|
int connection4init( CONNECTION4 *connection, SOCKET4 *socket )
|
||
|
{
|
||
|
#ifdef E4PARM_LOW
|
||
|
if ( socket == 0 || connection == 0 )
|
||
|
return error4( 0, e4parm_null, E90160 ) ;
|
||
|
#endif
|
||
|
|
||
|
memset( connection, 0, sizeof( CONNECTION4 ) ) ;
|
||
|
connection->cb = socket->cb ;
|
||
|
connection->socket = socket ;
|
||
|
|
||
|
return 0 ;
|
||
|
}
|
||
|
|
||
|
int connection4initUndo( CONNECTION4 *connection )
|
||
|
{
|
||
|
int rc ;
|
||
|
|
||
|
#ifdef E4PARM_LOW
|
||
|
if ( connection == 0 )
|
||
|
return error4( 0, e4parm_null, E90160 ) ;
|
||
|
#endif
|
||
|
|
||
|
#ifdef E4ANALYZE
|
||
|
connection->initUndone = 1 ;
|
||
|
#endif
|
||
|
|
||
|
rc = connection4disconnect( connection ) ;
|
||
|
|
||
|
connection4clear( connection ) ;
|
||
|
|
||
|
if ( connection->net != 0 )
|
||
|
{
|
||
|
connection4netInitUndo( connection->net ) ;
|
||
|
connection4netFree( connection->net ) ;
|
||
|
connection->net = 0 ;
|
||
|
}
|
||
|
|
||
|
if ( connection->message != 0 )
|
||
|
{
|
||
|
message4free( connection->cb, connection->message ) ;
|
||
|
connection->message = 0 ;
|
||
|
}
|
||
|
|
||
|
return rc ;
|
||
|
}
|
||
|
|
||
|
#ifdef E4PARM_LOW
|
||
|
int connection4free( CONNECTION4 *connection )
|
||
|
{
|
||
|
if ( connection == 0 )
|
||
|
return 0 ;
|
||
|
|
||
|
#ifdef E4ANALYZE
|
||
|
if ( connection->initUndone != 1 )
|
||
|
return error4( connection->cb, e4info, E90160 ) ;
|
||
|
#endif
|
||
|
|
||
|
mem4free( connection->cb->connectionMemory, connection ) ;
|
||
|
return 0 ;
|
||
|
}
|
||
|
|
||
|
/* if connection is null, it means dealing with a system file, so return 0L */
|
||
|
long connection4id( const CONNECTION4 *connection )
|
||
|
{
|
||
|
if ( connection == 0 )
|
||
|
return 0L ;
|
||
|
return connection4netId( connection->net ) ;
|
||
|
}
|
||
|
|
||
|
int connection4didUnlock( const CONNECTION4 *connection )
|
||
|
{
|
||
|
if ( connection == 0 )
|
||
|
return error4( 0, e4parm_null, E90160 ) ;
|
||
|
if ( connection->message == 0 )
|
||
|
return error4( 0, e4struct, E90160 ) ;
|
||
|
|
||
|
return packet4didUnlock( connection->message->packet ) ;
|
||
|
}
|
||
|
|
||
|
int connection4readLock( const CONNECTION4 *connection )
|
||
|
{
|
||
|
if ( connection == 0 )
|
||
|
return error4( 0, e4parm_null, E90160 ) ;
|
||
|
if ( connection->message == 0 )
|
||
|
return error4( 0, e4struct, E90160 ) ;
|
||
|
|
||
|
return packet4readLock( connection->message->packet ) ;
|
||
|
}
|
||
|
|
||
|
int connection4unlockAuto( const CONNECTION4 *connection )
|
||
|
{
|
||
|
if ( connection == 0 )
|
||
|
return error4( 0, e4parm_null, E90160 ) ;
|
||
|
if ( connection->message == 0 )
|
||
|
return error4( 0, e4struct, E90160 ) ;
|
||
|
|
||
|
return packet4unlockAuto( connection->message->packet ) ;
|
||
|
}
|
||
|
#endif /* E4PARM_LOW -- i.e. inline */
|
||
|
|
||
|
static int connection4messageAlloc( CONNECTION4 *connection )
|
||
|
{
|
||
|
if ( connection->message == 0 )
|
||
|
{
|
||
|
connection->message = message4alloc( connection->cb, (unsigned int)connection4netMessageLen( connection->net ) ) ;
|
||
|
if ( connection->message == 0 )
|
||
|
return error4( connection->cb, e4memory, E90160 ) ;
|
||
|
}
|
||
|
return 0 ;
|
||
|
}
|
||
|
|
||
|
static MESSAGE4DATA *connection4allocateData( CONNECTION4 *connection, const unsigned allocLen, const int doAlloc, const int insert )
|
||
|
{
|
||
|
CODE4 *c4 ;
|
||
|
int rc ;
|
||
|
MESSAGE4DATA *messageLink ;
|
||
|
|
||
|
c4 = connection->cb ;
|
||
|
|
||
|
rc = connection4messageAlloc( connection ) ;
|
||
|
if ( rc != 0 )
|
||
|
{
|
||
|
#ifdef E4STACK
|
||
|
error4stack( c4, (short)rc, E90160 ) ;
|
||
|
#endif
|
||
|
return 0 ;
|
||
|
}
|
||
|
|
||
|
if ( c4->messageLinkMemory == 0 )
|
||
|
{
|
||
|
c4->messageLinkMemory = mem4create( c4, 20, sizeof( MESSAGE4DATA ), 10, 0 ) ;
|
||
|
if ( c4->messageLinkMemory == 0 )
|
||
|
{
|
||
|
#ifdef E4STACK
|
||
|
error4stack( c4, e4memory, E90160 ) ;
|
||
|
#endif
|
||
|
return 0 ;
|
||
|
}
|
||
|
}
|
||
|
|
||
|
messageLink = 0 ;
|
||
|
|
||
|
if ( doAlloc == 1 ) /* check with local list first */
|
||
|
if ( allocLen <= COM4DEFAULT_MESSAGE_LEN ) /* if <= 512, try to get from local list to avoid allocate/deallocate sequence */
|
||
|
messageLink = (MESSAGE4DATA *)l4pop( &c4->availDataMessages ) ;
|
||
|
|
||
|
if ( messageLink == 0 )
|
||
|
{
|
||
|
messageLink = (MESSAGE4DATA *)mem4alloc( c4->messageLinkMemory ) ;
|
||
|
if ( messageLink == 0 )
|
||
|
{
|
||
|
#ifdef E4STACK
|
||
|
error4stack( c4, e4memory, E90160 ) ;
|
||
|
#endif
|
||
|
return 0 ;
|
||
|
}
|
||
|
}
|
||
|
|
||
|
if ( doAlloc == 1 )
|
||
|
{
|
||
|
if ( messageLink->allocLen == 0 )
|
||
|
{
|
||
|
if ( allocLen <= COM4DEFAULT_MESSAGE_LEN )
|
||
|
{
|
||
|
messageLink->allocatedData = (char *)u4allocEr( c4, (long)COM4DEFAULT_MESSAGE_LEN ) ;
|
||
|
if ( messageLink->allocatedData != 0 )
|
||
|
messageLink->allocLen = COM4DEFAULT_MESSAGE_LEN ;
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
messageLink->allocatedData = (char *)u4allocEr( c4, (long)allocLen ) ;
|
||
|
}
|
||
|
if ( messageLink->allocatedData == 0 )
|
||
|
{
|
||
|
#ifdef E4STACK
|
||
|
error4stack( c4, e4memory, E90160 ) ;
|
||
|
#endif
|
||
|
return 0 ;
|
||
|
}
|
||
|
messageLink->data = messageLink->allocatedData ;
|
||
|
messageLink->didAlloc = 1 ;
|
||
|
}
|
||
|
}
|
||
|
else
|
||
|
messageLink->didAlloc = 0 ;
|
||
|
|
||
|
messageLink->len = allocLen ;
|
||
|
if ( insert == 1 )
|
||
|
l4addBefore( &connection->messageData, l4first( &connection->messageData ), messageLink ) ;
|
||
|
else
|
||
|
l4add( &connection->messageData, messageLink ) ;
|
||
|
connection->totalDataLen += allocLen ;
|
||
|
|
||
|
return messageLink ;
|
||
|
}
|
||
|
|
||
|
/* a null data paramater means that the space should be allocated but none inserted */
|
||
|
/* a return code of '1' means that the data was repositioned */
|
||
|
int connection4insertData( CONNECTION4 *connection, const void *data, const unsigned dataLen, const int doAlloc, const int insert )
|
||
|
{
|
||
|
MESSAGE4DATA *messageLink ;
|
||
|
|
||
|
#ifdef E4PARM_LOW
|
||
|
if ( connection == 0 )
|
||
|
return error4( 0, e4parm_null, E90160 ) ;
|
||
|
#endif
|
||
|
|
||
|
if ( connection->connectionFailure < 0 )
|
||
|
return connection->connectionFailure ;
|
||
|
|
||
|
if ( dataLen == 0 )
|
||
|
return 0 ;
|
||
|
|
||
|
messageLink = connection4allocateData( connection, dataLen, doAlloc, insert ) ;
|
||
|
if ( messageLink == 0 )
|
||
|
return error4stack( connection->c4, e4memory, E90160 ) ;
|
||
|
|
||
|
if ( doAlloc == 1 )
|
||
|
memcpy( messageLink->allocatedData, data, dataLen ) ;
|
||
|
else
|
||
|
messageLink->data = (char *)data ;
|
||
|
|
||
|
return 0 ;
|
||
|
}
|
||
|
|
||
|
CONNECTION4 *connection4alloc( SOCKET4 *socket )
|
||
|
{
|
||
|
int rc ;
|
||
|
CONNECTION4 *connection ;
|
||
|
CODE4 *c4 ;
|
||
|
|
||
|
#ifdef E4PARM_LOW
|
||
|
if ( socket == 0 )
|
||
|
{
|
||
|
error4( 0, e4parm_null, E90160 ) ;
|
||
|
return 0 ;
|
||
|
}
|
||
|
#endif
|
||
|
|
||
|
c4 = socket->cb ;
|
||
|
|
||
|
if ( c4->connectionMemory == 0 )
|
||
|
{
|
||
|
#ifdef S4SERVER
|
||
|
c4->connectionMemory = mem4create( c4, 10, sizeof( CONNECTION4 ), 5, 0 ) ;
|
||
|
#else
|
||
|
c4->connectionMemory = mem4create( c4, 2, sizeof( CONNECTION4 ), 1, 0 ) ;
|
||
|
#endif
|
||
|
if ( c4->connectionMemory == 0 )
|
||
|
return 0 ;
|
||
|
}
|
||
|
connection = (CONNECTION4 *)mem4alloc( c4->connectionMemory ) ;
|
||
|
if ( connection == 0 )
|
||
|
{
|
||
|
#ifdef E4STACK
|
||
|
error4stack( c4, e4memory, E90160 ) ;
|
||
|
#endif
|
||
|
return 0 ;
|
||
|
}
|
||
|
|
||
|
connection->cb = c4 ;
|
||
|
rc = connection4init( connection, socket ) ;
|
||
|
if ( rc < 0 )
|
||
|
{
|
||
|
#ifdef E4STACK
|
||
|
error4stack( c4, (short)rc, E90160 ) ;
|
||
|
#endif
|
||
|
return 0 ;
|
||
|
}
|
||
|
|
||
|
return connection ;
|
||
|
}
|
||
|
|
||
|
/* sets up basic required info, and clears the data connectionmunication set */
|
||
|
#ifdef S4UTILS
|
||
|
int S4FUNCTION connection4assign( CONNECTION4 *connection, const int type, const long clientId, const long serverId )
|
||
|
#else
|
||
|
int connection4assign( CONNECTION4 *connection, const int type, const long clientId, const long serverId )
|
||
|
#endif
|
||
|
{
|
||
|
int rc ;
|
||
|
|
||
|
#ifdef E4PARM_LOW
|
||
|
if ( connection == 0 )
|
||
|
return error4( 0, e4parm_null, E90160 ) ;
|
||
|
#endif
|
||
|
|
||
|
if ( connection->connectionFailure < 0 )
|
||
|
return connection->connectionFailure ;
|
||
|
|
||
|
if ( connection->net != 0 ) /* the default server will have a null net */
|
||
|
{
|
||
|
rc = connection4messageAlloc( connection ) ;
|
||
|
if ( rc < 0 )
|
||
|
{
|
||
|
connection->connectionFailure = rc ;
|
||
|
return error4stack( connection->cb, (short)rc, E90160 ) ;
|
||
|
}
|
||
|
}
|
||
|
|
||
|
#ifdef E4ANALYZE
|
||
|
if ( connection->message == 0 )
|
||
|
{
|
||
|
connection->connectionFailure = e4struct ;
|
||
|
return error4( connection->cb, e4struct, E90160 ) ;
|
||
|
}
|
||
|
#endif
|
||
|
|
||
|
#ifndef S4SERVER
|
||
|
connection->cb->lockedLockItem = -2L ;
|
||
|
connection->cb->lockedFileName = 0 ;
|
||
|
connection->cb->lockedUserId = 0 ;
|
||
|
connection->cb->lockedNetId = 0 ;
|
||
|
connection->adjustForLocked = 0 ;
|
||
|
|
||
|
if ( connection->message != 0 )
|
||
|
connection4setRequestLockedInfo( connection, 0 ) ;
|
||
|
#endif
|
||
|
|
||
|
packet4setType( connection->message->packet, type ) ;
|
||
|
packet4setStatus( connection->message->packet, 0 ) ;
|
||
|
packet4setClientId( connection->message->packet, clientId ) ;
|
||
|
packet4setServerId( connection->message->packet, serverId ) ;
|
||
|
#ifndef S4SERVER
|
||
|
packet4setReadLock( connection->message->packet, connection->cb->readLock ) ;
|
||
|
packet4setUnlockAuto( connection->message->packet, code4unlockAuto( connection->cb ) ) ;
|
||
|
#endif
|
||
|
|
||
|
return connection4clear( connection ) ;
|
||
|
}
|
||
|
|
||
|
int connection4clear( CONNECTION4 *connection )
|
||
|
{
|
||
|
MESSAGE4DATA *link ;
|
||
|
|
||
|
#ifdef E4PARM_LOW
|
||
|
if ( connection == 0 )
|
||
|
return error4( 0, e4parm_null, E90160 ) ;
|
||
|
if ( connection->cb == 0 )
|
||
|
{
|
||
|
#ifdef S4SERVER
|
||
|
if ( connection->messageData.nLink != 0 )
|
||
|
#endif
|
||
|
return error4( 0, e4parm, E90160 ) ;
|
||
|
}
|
||
|
#endif
|
||
|
|
||
|
/* WARNING: do not modify this function without making appropriate changes
|
||
|
to connection4repeat() which emulates portions of this function */
|
||
|
connection->totalDataLen = 0L ;
|
||
|
|
||
|
for ( ;; )
|
||
|
{
|
||
|
link = (MESSAGE4DATA *)l4first( &connection->messageData ) ;
|
||
|
if ( link == 0 )
|
||
|
break ;
|
||
|
l4remove( &connection->messageData, link ) ;
|
||
|
if ( link->didAlloc == 1 )
|
||
|
{
|
||
|
if ( link->allocLen == COM4DEFAULT_MESSAGE_LEN )
|
||
|
l4add( &connection->cb->availDataMessages, link ) ;
|
||
|
else
|
||
|
{
|
||
|
u4free( link->allocatedData ) ;
|
||
|
link->didAlloc = 0 ;
|
||
|
mem4free( connection->cb->messageLinkMemory, link ) ;
|
||
|
}
|
||
|
}
|
||
|
else
|
||
|
mem4free( connection->cb->messageLinkMemory, link ) ;
|
||
|
}
|
||
|
|
||
|
return 0 ;
|
||
|
}
|
||
|
|
||
|
#define packet4connectionId( p ) ( (p)->connectionId )
|
||
|
|
||
|
static MESSAGE4 *connection4returnMessage( CONNECTION4 *connection, const CONNECTION4ID id, const int partNo )
|
||
|
{
|
||
|
MESSAGE4 *message ;
|
||
|
|
||
|
for ( message = 0 ;; )
|
||
|
{
|
||
|
message = (MESSAGE4 *)l4next( &connection->receivedMessages, message ) ;
|
||
|
if ( message == 0 )
|
||
|
return 0 ;
|
||
|
if ( packet4connectionId( message->packet ) == id && packet4partNo( message->packet ) == partNo )
|
||
|
{
|
||
|
l4remove( &connection->receivedMessages, message ) ;
|
||
|
return message ;
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
|
||
|
#ifndef S4SERVER
|
||
|
static int code4unlockSet( CODE4 *c4 )
|
||
|
{
|
||
|
DATA4FILE *data ;
|
||
|
LOCK4LINK *lock ;
|
||
|
|
||
|
#ifdef E4PARM_LOW
|
||
|
if ( c4 == 0 )
|
||
|
return error4( 0, e4parm_null, E90155 ) ;
|
||
|
#endif
|
||
|
|
||
|
for( data = 0 ;; )
|
||
|
{
|
||
|
data = (DATA4FILE *)l4next( &c4->dataFileList, data ) ;
|
||
|
if ( data == 0 )
|
||
|
return 0 ;
|
||
|
data->numRecs = -1 ;
|
||
|
#ifdef S4CLIENT
|
||
|
data->appendLock = 0 ;
|
||
|
data->fileLock = 0 ;
|
||
|
#endif
|
||
|
for( ;; )
|
||
|
{
|
||
|
lock = (LOCK4LINK *)l4first( &data->lockedRecords ) ;
|
||
|
if ( lock == 0 )
|
||
|
break ;
|
||
|
l4remove( &data->lockedRecords, lock ) ;
|
||
|
mem4free( c4->lockLinkMemory, lock ) ;
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
#endif
|
||
|
|
||
|
#ifndef S4SERVER
|
||
|
#ifdef S4UTILS
|
||
|
int S4FUNCTION connection4receive( CONNECTION4 *connection )
|
||
|
#else
|
||
|
int connection4receive( CONNECTION4 *connection )
|
||
|
#endif
|
||
|
{
|
||
|
int rc, len, totLen, conLen; /*, hundredths ;*/
|
||
|
long totalHundredths, countHundredths ;
|
||
|
const char *ptr ;
|
||
|
CODE4 *c4 ;
|
||
|
CONNECTION4 *messageConnection ;
|
||
|
#ifdef S4NO_FTIME
|
||
|
struct timeval oldTime, newTime ;
|
||
|
#else
|
||
|
struct timeb oldTime, newTime ;
|
||
|
#endif
|
||
|
#ifdef S4TIMEOUT_HOOK
|
||
|
int count, elapsedHundredths ;
|
||
|
struct timeb origTime ;
|
||
|
#endif
|
||
|
|
||
|
#ifdef E4PARM_LOW
|
||
|
if ( connection == 0 )
|
||
|
return error4( 0, e4parm_null, E90160 ) ;
|
||
|
#endif
|
||
|
|
||
|
c4 = connection->cb ;
|
||
|
|
||
|
#ifdef E4ANALYZE
|
||
|
if ( c4 == 0 )
|
||
|
return error4( 0, e4struct, E90160 ) ;
|
||
|
#endif
|
||
|
|
||
|
if ( connection->connectionFailure < 0 )
|
||
|
return connection->connectionFailure ;
|
||
|
|
||
|
if ( connection->message != 0 )
|
||
|
{
|
||
|
connection4clear( connection ) ;
|
||
|
message4free( c4, connection->message ) ;
|
||
|
connection->message = 0 ;
|
||
|
}
|
||
|
|
||
|
connection->totalDataLen = 0 ;
|
||
|
#ifndef S4NO_FTIME
|
||
|
ftime( &oldTime) ;
|
||
|
#else
|
||
|
gettimeofday(&oldTime, NULL ) ;
|
||
|
#endif
|
||
|
totalHundredths = code4timeout( c4 ) ;
|
||
|
if ( totalHundredths > 0 )
|
||
|
totalHundredths *= 100 ;
|
||
|
#ifdef S4TIMEOUT_HOOK
|
||
|
ftime( &origTime) ;
|
||
|
for( count = 0 ;; )
|
||
|
#else
|
||
|
for( ;; )
|
||
|
#endif
|
||
|
{
|
||
|
messageConnection = socket4receiveMessage( connection->socket ) ;
|
||
|
if ( messageConnection != 0 )
|
||
|
{
|
||
|
if ( connection4didUnlock( connection ) == 1 )
|
||
|
rc = code4unlockSet( c4 ) ;
|
||
|
else
|
||
|
{
|
||
|
rc = 0 ;
|
||
|
if ( connection4type( connection ) == CON4DISCONNECT )
|
||
|
{
|
||
|
connection->connectionFailure = e4connection ;
|
||
|
return error4( c4, e4connection, E80220 ) ;
|
||
|
}
|
||
|
}
|
||
|
|
||
|
connection->adjustForLocked = 0 ;
|
||
|
if ( connection4requestLockedInfo( connection ) == 1 )
|
||
|
if ( connection4status( connection ) == r4locked )
|
||
|
{
|
||
|
conLen = (int)connection4len( connection ) ;
|
||
|
totLen = sizeof( c4->lockedLockItem ) ;
|
||
|
if ( conLen < totLen + 3 )
|
||
|
return error4( c4, e4packetLen, E90160 ) ;
|
||
|
ptr = connection4data( connection ) ;
|
||
|
c4->lockedLockItem = *((long *)ptr ) ;
|
||
|
ptr += sizeof( c4->lockedLockItem ) ;
|
||
|
len = strlen( ptr ) ;
|
||
|
totLen += len + 1 ;
|
||
|
if ( conLen < totLen )
|
||
|
return error4( c4, e4packetLen, E90160 ) ;
|
||
|
c4->lockedFileName = ptr ;
|
||
|
ptr += (len + 1) ;
|
||
|
len = strlen( ptr ) ;
|
||
|
totLen += len + 1 ;
|
||
|
if ( conLen < totLen )
|
||
|
return error4( c4, e4packetLen, E90160 ) ;
|
||
|
c4->lockedUserId = ptr ;
|
||
|
ptr += (len + 1) ;
|
||
|
len = strlen( ptr ) ;
|
||
|
totLen += len + 1 ;
|
||
|
if ( conLen < totLen )
|
||
|
return error4( c4, e4packetLen, E90160 ) ;
|
||
|
c4->lockedNetId = ptr ;
|
||
|
connection->adjustForLocked = totLen ;
|
||
|
}
|
||
|
|
||
|
return rc ;
|
||
|
}
|
||
|
|
||
|
if ( error4code( c4 ) < 0 )
|
||
|
return error4stack( c4, error4code( c4 ), E90160 ) ;
|
||
|
|
||
|
if ( totalHundredths != -1 )
|
||
|
{
|
||
|
#ifndef S4NO_FTIME
|
||
|
ftime( &newTime ) ;
|
||
|
countHundredths = ((newTime.time - oldTime.time)*100 ) + (( (int)newTime.millitm - (int)oldTime.millitm ) / 10 ) ;
|
||
|
#else
|
||
|
gettimeofday(&newTime, NULL ) ;
|
||
|
countHundredths = ((newTime.tv_sec-oldTime.tv_sec)*100) + (( (int)newTime.tv_usec - (int)oldTime.tv_usec ) / 10000 ) ;
|
||
|
#endif
|
||
|
if ( countHundredths > totalHundredths )
|
||
|
{
|
||
|
#ifdef S4TIMEOUT_HOOK
|
||
|
elapsedHundredths = (int)( ((newTime.time - origTime.time)*100 ) + (( (int)newTime.millitm - (int)origTime.millitm ) / 10 ) ) ;
|
||
|
rc = code4timeoutHook( c4, count, elapsedHundredths ) ;
|
||
|
if ( rc != 0 )
|
||
|
return rc ;
|
||
|
count++ ;
|
||
|
ftime( &oldTime ) ;
|
||
|
#else
|
||
|
return error4( c4, e4timeOut, E81006 ) ;
|
||
|
#endif
|
||
|
}
|
||
|
}
|
||
|
|
||
|
connection4yield( connection ) ;
|
||
|
}
|
||
|
}
|
||
|
#endif /* S4SERVER */
|
||
|
|
||
|
CONNECTION4 * socket4receiveMessage( SOCKET4 *socket )
|
||
|
{
|
||
|
MESSAGE4 *message, *partialMessage, *returnMessage ;
|
||
|
MESSAGE4DATA *messageData = 0 ;
|
||
|
CONNECTION4ID connectionId ;
|
||
|
int partNo ;
|
||
|
int offset = 0 ;
|
||
|
unsigned int numParts, i ;
|
||
|
CONNECTION4 *connection ;
|
||
|
CODE4 *c4 ;
|
||
|
#ifdef S4SERVER
|
||
|
SERVER4CLIENT *client ;
|
||
|
#endif
|
||
|
|
||
|
#ifdef E4PARM_LOW
|
||
|
if ( socket == 0 )
|
||
|
{
|
||
|
error4( 0, e4parm_null, E90161 ) ;
|
||
|
return 0 ;
|
||
|
}
|
||
|
#endif
|
||
|
|
||
|
#ifdef E4ANALYZE
|
||
|
if ( socket->cb == 0 )
|
||
|
{
|
||
|
error4( 0, e4struct, E90161 ) ;
|
||
|
return 0 ;
|
||
|
}
|
||
|
#endif
|
||
|
|
||
|
c4 = socket->cb ;
|
||
|
|
||
|
#ifndef S4SERVER
|
||
|
connection = socket->connect ;
|
||
|
#endif
|
||
|
|
||
|
for( ;; )
|
||
|
{
|
||
|
message = socket4receive( socket ) ;
|
||
|
if ( message == 0 )
|
||
|
return 0 ;
|
||
|
|
||
|
#ifdef S4SERVER
|
||
|
client = server4client( c4->server, message->packet->connectionId ) ;
|
||
|
if ( client == 0 ) /* could be a crashed client, so just delete message */
|
||
|
{
|
||
|
message4free( c4, message ) ;
|
||
|
return 0 ;
|
||
|
}
|
||
|
|
||
|
connection = client->connection ;
|
||
|
#endif
|
||
|
|
||
|
if ( message != 0 ) /* is this the complete message? */
|
||
|
{
|
||
|
/* if a disconnect message received, any pending messages for the client are deleted
|
||
|
and the disconnect message is forwarded */
|
||
|
|
||
|
if ( packet4type( message->packet ) == CON4DISCONNECT )
|
||
|
{
|
||
|
for ( ;; )
|
||
|
{
|
||
|
partialMessage = (MESSAGE4 *)l4first( &connection->receivedMessages ) ;
|
||
|
if ( partialMessage == 0 )
|
||
|
break ;
|
||
|
l4remove( &connection->receivedMessages, partialMessage ) ;
|
||
|
message4free( c4, partialMessage ) ;
|
||
|
}
|
||
|
if ( connection->message != 0 )
|
||
|
{
|
||
|
message4free( c4, connection->message ) ;
|
||
|
connection->message = 0 ;
|
||
|
}
|
||
|
#ifdef E4ANALYZE
|
||
|
if ( packet4numParts( message->packet ) != 1 ) /* disconnect cannot span parts */
|
||
|
{
|
||
|
error4( c4, e4info, E90160 ) ;
|
||
|
return 0 ;
|
||
|
}
|
||
|
#endif
|
||
|
}
|
||
|
|
||
|
#ifdef E4ANALYZE
|
||
|
if ( connection->message != 0 )
|
||
|
{
|
||
|
error4( c4, e4info, E90160 ) ;
|
||
|
return 0 ;
|
||
|
}
|
||
|
#endif
|
||
|
|
||
|
#ifdef S4DISTRIBUTED
|
||
|
if ( packet4connectionId( message->packet ) != connection4netSourceId( connection->net ) )
|
||
|
{
|
||
|
/* message from another server, maybe a disconnect. */
|
||
|
/* error for now */
|
||
|
error4( c4, e4connection, "connection4receive() - invalid message received" ) ;
|
||
|
return 0 ;
|
||
|
}
|
||
|
#endif
|
||
|
|
||
|
numParts = (unsigned int)packet4numParts( message->packet ) ;
|
||
|
if ( numParts == 1 )
|
||
|
{
|
||
|
connection->message = message ;
|
||
|
connection4addData( connection, (char *)(((char *)message->packet) + message->packet->packetDataOffset), message->packet->packetDataLen, 0 ) ;
|
||
|
return connection ;
|
||
|
}
|
||
|
|
||
|
connectionId = packet4connectionId( message->packet ) ;
|
||
|
numParts-- ;
|
||
|
|
||
|
/* check if we can complete a message with available parts */
|
||
|
if ( connection->receivedMessages.nLink < numParts ) /* insufficient supply of parts */
|
||
|
{
|
||
|
l4add( &connection->receivedMessages, message ) ;
|
||
|
partialMessage = 0 ;
|
||
|
}
|
||
|
else
|
||
|
for ( partialMessage = 0 ;; )
|
||
|
{
|
||
|
partialMessage = (MESSAGE4 *)l4next( &connection->receivedMessages, partialMessage ) ;
|
||
|
if ( partialMessage == 0 ) /* can't complete... */
|
||
|
{
|
||
|
l4add( &connection->receivedMessages, message ) ;
|
||
|
break ;
|
||
|
}
|
||
|
if ( packet4connectionId( partialMessage->packet ) == connectionId )
|
||
|
{
|
||
|
numParts-- ;
|
||
|
if ( numParts == 0 ) /* should be able to create a complete message */
|
||
|
break ;
|
||
|
}
|
||
|
}
|
||
|
|
||
|
if ( partialMessage == 0 ) /* get an additional message */
|
||
|
continue ;
|
||
|
|
||
|
numParts = packet4numParts( message->packet ) ;
|
||
|
partNo = packet4partNo( message->packet ) ;
|
||
|
returnMessage = 0 ;
|
||
|
|
||
|
for ( i = 1 ; i <= numParts ; i++ )
|
||
|
{
|
||
|
if ( (unsigned int)partNo == i )
|
||
|
partialMessage = message ;
|
||
|
else /* need to get the message */
|
||
|
partialMessage = connection4returnMessage( connection, connectionId, i ) ;
|
||
|
|
||
|
if ( partialMessage == 0 )
|
||
|
{
|
||
|
if ( returnMessage != 0 && message != returnMessage )
|
||
|
message4free( c4, returnMessage ) ;
|
||
|
if ( message != 0 )
|
||
|
message4free( c4, message ) ;
|
||
|
connection->message = 0 ;
|
||
|
error4( c4, e4message, E90160 ) ;
|
||
|
return 0 ;
|
||
|
}
|
||
|
|
||
|
if ( i == 1 )
|
||
|
{
|
||
|
connection->message = partialMessage ;
|
||
|
returnMessage = partialMessage ;
|
||
|
#ifdef E4ANALYZE
|
||
|
if ( connection4len( connection ) > UINT_MAX )
|
||
|
{
|
||
|
error4( c4, e4info, E90160 ) ;
|
||
|
return 0 ;
|
||
|
}
|
||
|
#endif
|
||
|
messageData = connection4allocateData( connection, (unsigned int)connection4len( connection ), 1, 0 ) ;
|
||
|
if ( messageData == 0 )
|
||
|
{
|
||
|
#ifdef E4STACK
|
||
|
error4stack( c4, e4memory, E90160 ) ;
|
||
|
#endif
|
||
|
return 0 ;
|
||
|
}
|
||
|
#ifdef E4ANALYZE
|
||
|
if ( messageData->len < partialMessage->packet->packetDataLen )
|
||
|
{
|
||
|
error4( c4, e4info, E90160 ) ;
|
||
|
return 0 ;
|
||
|
}
|
||
|
#endif
|
||
|
memcpy( messageData->allocatedData, (char *)(((char *)partialMessage->packet) + partialMessage->packet->packetDataOffset), partialMessage->packet->packetDataLen ) ;
|
||
|
offset = partialMessage->packet->packetDataLen ;
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
#ifdef E4ANALYZE
|
||
|
if ( messageData->len < partialMessage->packet->packetDataLen + offset )
|
||
|
{
|
||
|
error4( c4, e4info, E90160 ) ;
|
||
|
return 0 ;
|
||
|
}
|
||
|
#endif
|
||
|
memcpy( messageData->allocatedData + offset, (char *)(((char *)partialMessage->packet) + partialMessage->packet->packetDataOffset), partialMessage->packet->packetDataLen ) ;
|
||
|
offset += partialMessage->packet->packetDataLen ;
|
||
|
}
|
||
|
|
||
|
if ( i != 1 )
|
||
|
{
|
||
|
if ( message == partialMessage )
|
||
|
message = 0 ;
|
||
|
message4free( c4, partialMessage ) ;
|
||
|
}
|
||
|
}
|
||
|
|
||
|
#ifdef S4COM_PRINT
|
||
|
if ( partNo == 1 && returnMessage != 0 )
|
||
|
{
|
||
|
printf( "Received Message: " ) ;
|
||
|
s4connectionPrint( packet4type( returnMessage->packet ) ) ;
|
||
|
}
|
||
|
#endif
|
||
|
|
||
|
return connection ;
|
||
|
}
|
||
|
|
||
|
return 0 ;
|
||
|
}
|
||
|
}
|
||
|
|
||
|
/* return code of 1 means done. input len is amount available for writing, startPos is where to start writing */
|
||
|
static int connection4placeData( CONNECTION4 *connection, unsigned short int *dataPos, unsigned short int len, unsigned short int startLen, MESSAGE4DATA **dataIn )
|
||
|
{
|
||
|
MESSAGE4DATA *data ;
|
||
|
|
||
|
data = *dataIn ;
|
||
|
|
||
|
if ( data == 0 )
|
||
|
data = (MESSAGE4DATA *)l4first( &connection->messageData ) ;
|
||
|
if ( data == 0 )
|
||
|
return 1 ;
|
||
|
|
||
|
while ( ( data->len - *dataPos ) <= len )
|
||
|
{
|
||
|
memcpy( ((char *)connection->message->packet) + startLen, data->data + *dataPos, data->len - (long)*dataPos ) ;
|
||
|
len -= (unsigned short)( data->len - *dataPos ) ;
|
||
|
startLen += (unsigned short)( data->len - *dataPos ) ;
|
||
|
data = (MESSAGE4DATA *)l4next( &connection->messageData, data ) ;
|
||
|
*dataPos = 0 ;
|
||
|
if ( data == 0 )
|
||
|
{
|
||
|
*dataIn = data ; /* changed */
|
||
|
return 1 ;
|
||
|
}
|
||
|
if ( len == 0 )
|
||
|
{
|
||
|
*dataIn = data ;
|
||
|
return 0 ;
|
||
|
}
|
||
|
}
|
||
|
|
||
|
memcpy( ((char *)connection->message->packet) + startLen, data->data + *dataPos, len ) ;
|
||
|
*dataPos += len ;
|
||
|
|
||
|
*dataIn = data ;
|
||
|
return 0 ;
|
||
|
}
|
||
|
|
||
|
#ifndef S4SERVER
|
||
|
/* performs a send/receive loop as long as return code is loopCode numRepeat times (or
|
||
|
forever if numRepeat == - 1 )
|
||
|
assigning -2 to numRepeat, or -1 to delayHundredths or loopCode results in their taking
|
||
|
default appropriate CODE4 values */
|
||
|
int connection4repeat( CONNECTION4 *connection, const int numRepeat, const int loopCodeIn, const int delayHundredthsIn, DATA4 *d4 )
|
||
|
{
|
||
|
int rc, loop, delayHundredths, loopCode, saveAdjustedLen ;
|
||
|
MESSAGE4 *saveMessage, *saveMessage2 ;
|
||
|
PACKET4 savePacketInfo ;
|
||
|
LIST4 saveData, saveData2 ;
|
||
|
unsigned long int saveTotal, saveTotal2 ;
|
||
|
CODE4 *c4 ;
|
||
|
#ifdef S4LOCK_HOOK
|
||
|
int count ;
|
||
|
#endif
|
||
|
|
||
|
#ifdef E4PARM_LOW
|
||
|
if ( connection == 0 || numRepeat < -2 )
|
||
|
return error4( 0, e4parm, E90160 ) ;
|
||
|
#endif
|
||
|
|
||
|
c4 = connection->cb ;
|
||
|
|
||
|
loop = numRepeat ;
|
||
|
if ( loop == 0 )
|
||
|
loop = 1 ;
|
||
|
if ( loop == -2 )
|
||
|
loop = c4->lockAttempts ;
|
||
|
if ( loopCodeIn == -1 )
|
||
|
loopCode = r4locked ;
|
||
|
else
|
||
|
loopCode = loopCodeIn ;
|
||
|
if ( delayHundredthsIn == -1 )
|
||
|
delayHundredths = c4->lockDelay ;
|
||
|
else
|
||
|
delayHundredths = delayHundredthsIn ;
|
||
|
|
||
|
saveMessage = connection->message ;
|
||
|
memcpy( &saveData, &connection->messageData, sizeof( LIST4 ) ) ;
|
||
|
memcpy( &savePacketInfo, connection->message->packet, sizeof( PACKET4 ) ) ;
|
||
|
saveTotal = connection->totalDataLen ;
|
||
|
#ifdef S4LOCK_HOOK
|
||
|
for ( count = 0 ;; count++ )
|
||
|
#else
|
||
|
for ( ;; )
|
||
|
#endif
|
||
|
{
|
||
|
if ( loop != numRepeat )
|
||
|
{
|
||
|
connection->message = saveMessage ;
|
||
|
memcpy( &connection->messageData, &saveData, sizeof( LIST4 ) ) ;
|
||
|
memcpy( connection->message->packet, &savePacketInfo, sizeof( PACKET4 ) );
|
||
|
}
|
||
|
if ( loop > 0 )
|
||
|
loop-- ;
|
||
|
c4->lockedLockItem = -2L ;
|
||
|
c4->lockedFileName = 0 ;
|
||
|
c4->lockedUserId = 0 ;
|
||
|
c4->lockedNetId = 0 ;
|
||
|
connection->adjustForLocked = 0 ;
|
||
|
connection->totalDataLen = saveTotal ;
|
||
|
#ifndef S4LOCK_HOOK
|
||
|
/* in the case of lock hook, always set, otherwise only set just before return */
|
||
|
if ( loop == 0 ) /* will return next call, so get lock info if r4locked */
|
||
|
#endif
|
||
|
connection4setRequestLockedInfo( connection, 1 ) ;
|
||
|
connection4send( connection ) ;
|
||
|
connection->message = 0 ;
|
||
|
memset( &connection->messageData, 0, sizeof( LIST4 ) ) ;
|
||
|
connection->totalDataLen = 0 ;
|
||
|
rc = connection4receive( connection ) ;
|
||
|
if ( rc < 0 )
|
||
|
break ;
|
||
|
#ifndef S4STAND_ALONE
|
||
|
if ( d4 != 0 )
|
||
|
if ( packet4didUnlockData( connection->message->packet ) == 1 )
|
||
|
d4unlockClientData( d4 ) ;
|
||
|
#endif
|
||
|
rc = connection4status( connection ) ;
|
||
|
if ( loop == 0 ) /* get receive return if loop == 0 */
|
||
|
break ;
|
||
|
if ( rc != loopCode )
|
||
|
break ;
|
||
|
#ifdef S4LOCK_HOOK
|
||
|
rc = code4lockHook( c4, c4->lockedFileName, c4->lockedUserId, c4->lockedNetId, c4->lockedLockItem, count ) ;
|
||
|
if ( rc != 0 )
|
||
|
break ;
|
||
|
#endif
|
||
|
if ( connection->message != 0 )
|
||
|
{
|
||
|
connection4clear( connection ) ;
|
||
|
message4free( c4, connection->message ) ;
|
||
|
connection->message = 0 ;
|
||
|
}
|
||
|
u4delayHundredth( delayHundredths ) ;
|
||
|
}
|
||
|
|
||
|
saveMessage2 = connection->message ;
|
||
|
saveAdjustedLen = connection->adjustForLocked ;
|
||
|
if ( saveMessage2 != 0 )
|
||
|
{
|
||
|
memcpy( &saveData2, &connection->messageData, sizeof( LIST4 ) ) ;
|
||
|
saveTotal2 = connection->totalDataLen ;
|
||
|
}
|
||
|
|
||
|
if ( saveMessage != 0 )
|
||
|
{
|
||
|
connection->message = saveMessage ;
|
||
|
memcpy( &connection->messageData, &saveData, sizeof( LIST4 ) ) ;
|
||
|
memcpy( connection->message->packet, &savePacketInfo, sizeof( PACKET4 ) );
|
||
|
connection->totalDataLen = saveTotal ;
|
||
|
connection4clear( connection ) ;
|
||
|
message4free( c4, connection->message ) ;
|
||
|
connection->message = 0 ;
|
||
|
}
|
||
|
|
||
|
if ( saveMessage2 != 0 )
|
||
|
{
|
||
|
connection->message = saveMessage2 ;
|
||
|
memcpy( &connection->messageData, &saveData2, sizeof( LIST4 ) ) ;
|
||
|
connection->totalDataLen = saveTotal2 ;
|
||
|
connection->adjustForLocked = saveAdjustedLen ;
|
||
|
}
|
||
|
|
||
|
return rc ;
|
||
|
}
|
||
|
#endif /* S4SERVER */
|
||
|
|
||
|
#ifdef S4UTILS
|
||
|
int S4FUNCTION connection4send( CONNECTION4 *connection )
|
||
|
#else
|
||
|
int connection4send( CONNECTION4 *connection )
|
||
|
#endif
|
||
|
{
|
||
|
int rc, numParts, partNo ;
|
||
|
unsigned short int messageSendLen, incLen, dataPos, startLen ;
|
||
|
long int connectionLen ;
|
||
|
PACKET4HEADER *header ;
|
||
|
CONNECTION4ID id ;
|
||
|
MESSAGE4DATA *data ;
|
||
|
|
||
|
#ifdef E4PARM_LOW
|
||
|
if ( connection == 0 )
|
||
|
return error4( 0, e4parm_null, E90160 ) ;
|
||
|
#endif
|
||
|
|
||
|
#ifdef E4ANALYZE
|
||
|
if ( connection->cb == 0 )
|
||
|
return error4( 0, e4struct, E90160 ) ;
|
||
|
if ( connection->message == 0 )
|
||
|
{
|
||
|
connection->connectionFailure = e4struct ;
|
||
|
return error4( 0, e4struct, E90160 ) ;
|
||
|
}
|
||
|
#endif
|
||
|
|
||
|
if ( connection->connectionFailure < 0 )
|
||
|
return connection->connectionFailure ;
|
||
|
|
||
|
rc = connection4setLen( connection, connection->totalDataLen ) ;
|
||
|
if ( rc < 0 )
|
||
|
{
|
||
|
connection->connectionFailure = rc ;
|
||
|
return error4stack( connection->cb, (short)rc, E90160 ) ;
|
||
|
}
|
||
|
|
||
|
#ifdef S4COM_PRINT
|
||
|
printf( "Sending Message: " ) ;
|
||
|
s4connectionPrint( connection4type( connection ) ) ;
|
||
|
#endif
|
||
|
|
||
|
messageSendLen = connection4netMessageLen( connection->net ) ;
|
||
|
|
||
|
#ifdef E4ANALYZE
|
||
|
if ( messageSendLen < sizeof( PACKET4 ) )
|
||
|
{
|
||
|
connection->connectionFailure = e4info ;
|
||
|
return error4( connection->cb, e4info, E90160 ) ;
|
||
|
}
|
||
|
#endif
|
||
|
|
||
|
connectionLen = connection4len( connection ) ;
|
||
|
if ( connectionLen < 0 )
|
||
|
{
|
||
|
connection->connectionFailure = (short)connectionLen ;
|
||
|
return error4stack( connection->cb, (short)connectionLen, E90160 ) ;
|
||
|
}
|
||
|
|
||
|
startLen = messageSendLen - sizeof( PACKET4 ) ;
|
||
|
if ( connectionLen < (long)startLen )
|
||
|
startLen = (unsigned short int)connectionLen ;
|
||
|
|
||
|
incLen = messageSendLen - sizeof( PACKET4HEADER ) ;
|
||
|
numParts = (int) ( ( ( connectionLen - startLen ) + ( incLen - 1 ) ) / incLen + 1 ) ;
|
||
|
|
||
|
id = connection4netDestId( connection->net ) ;
|
||
|
memcpy( &connection->message->packet->connectionId, &id, sizeof( CONNECTION4ID ) ) ;
|
||
|
header = (PACKET4HEADER *)(connection->message->packet) ;
|
||
|
header->numParts = numParts ;
|
||
|
|
||
|
#ifndef S4SERVER
|
||
|
packet4setDidUnlock( connection->message->packet, 0 ) ;
|
||
|
packet4setDidUnlockData( connection->message->packet, 0 ) ;
|
||
|
#endif
|
||
|
|
||
|
dataPos = 0 ;
|
||
|
for( partNo = 1 ; partNo <= numParts ; partNo++ )
|
||
|
{
|
||
|
if ( partNo == 1 )
|
||
|
{
|
||
|
data = 0 ;
|
||
|
connection4placeData( connection, &dataPos, startLen, sizeof( PACKET4 ), &data ) ;
|
||
|
header->packetDataLen = startLen ;
|
||
|
header->packetDataOffset = sizeof( PACKET4 ) ;
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
if ( partNo == numParts )
|
||
|
incLen = (unsigned short int)(connectionLen - startLen - ( ( numParts - 2 ) * incLen ) ) ;
|
||
|
connection4placeData( connection, &dataPos, incLen, sizeof( PACKET4HEADER ), &data ) ;
|
||
|
header->packetDataLen = incLen ;
|
||
|
header->packetDataOffset = sizeof( PACKET4HEADER ) ;
|
||
|
}
|
||
|
|
||
|
header->partNo = partNo ;
|
||
|
rc = connection4netSend( connection->net, connection->message ) ;
|
||
|
if ( rc < 0 )
|
||
|
{
|
||
|
connection->connectionFailure = rc ;
|
||
|
return error4stack( connection->cb, (short)rc, E90160 ) ;
|
||
|
}
|
||
|
}
|
||
|
|
||
|
return 0 ;
|
||
|
}
|
||
|
|
||
|
int connection4setStatus( CONNECTION4 *connection, const int status )
|
||
|
{
|
||
|
int rc ;
|
||
|
|
||
|
#ifdef E4PARM_LOW
|
||
|
if ( connection == 0 )
|
||
|
return error4( 0, e4parm_null, E90160 ) ;
|
||
|
#endif
|
||
|
|
||
|
rc = connection4messageAlloc( connection ) ;
|
||
|
if ( rc < 0 )
|
||
|
return error4stack( connection->cb, (short)rc, E90160 ) ;
|
||
|
|
||
|
#ifdef E4ANALYZE
|
||
|
if ( connection->message == 0 )
|
||
|
return error4( connection->cb, e4parm_null, E90160 ) ;
|
||
|
#endif
|
||
|
|
||
|
packet4setStatus( connection->message->packet, status ) ;
|
||
|
#ifdef E4OFF_STRING
|
||
|
return packet4setErrCode2( connection->message->packet, connection->cb->errorCode2 ) ;
|
||
|
#else
|
||
|
return packet4setErrCode2( connection->message->packet, error4number2( connection->cb->errorCode2 ) ) ;
|
||
|
#endif
|
||
|
}
|
||
|
|
||
|
int connection4errorDescribeExecute( const CONNECTION4 *connection, CODE4 *c4, int c1, long c2, const char *s1, const char *s2, const char *s3 )
|
||
|
{
|
||
|
long cErr ;
|
||
|
|
||
|
if ( connection->message == 0 )
|
||
|
cErr = c2 ;
|
||
|
else
|
||
|
{
|
||
|
cErr = connection4errCode2( connection ) ;
|
||
|
if ( c2 != 0 && ( cErr > 90000 || cErr == 0 ) )
|
||
|
cErr = c2 ;
|
||
|
#ifndef E4OFF_STRING
|
||
|
else
|
||
|
cErr = error4seek( cErr ) ; /* convert the long value to the appropriate positional value */
|
||
|
#endif
|
||
|
}
|
||
|
return error4describeExecute( c4, c1, cErr, s1, s2, s3 ) ;
|
||
|
}
|
||
|
|
||
|
#ifdef E4PARM_LOW
|
||
|
long connection4serverId( const CONNECTION4 *connection )
|
||
|
{
|
||
|
if ( connection == 0 )
|
||
|
{
|
||
|
error4( 0, e4parm_null, E90160 ) ;
|
||
|
return 0 ;
|
||
|
}
|
||
|
if ( connection->message == 0 )
|
||
|
{
|
||
|
error4( 0, e4struct, E90160 ) ;
|
||
|
return 0 ;
|
||
|
}
|
||
|
|
||
|
return packet4serverId( connection->message->packet ) ;
|
||
|
}
|
||
|
|
||
|
long int connection4len( const CONNECTION4 *connection )
|
||
|
{
|
||
|
if ( connection == 0 )
|
||
|
{
|
||
|
error4( 0, e4parm_null, E90160 ) ;
|
||
|
return 0 ;
|
||
|
}
|
||
|
if ( connection->message == 0 )
|
||
|
{
|
||
|
error4( 0, e4struct, E90160 ) ;
|
||
|
return 0 ;
|
||
|
}
|
||
|
|
||
|
return ( packet4len( connection->message->packet ) - connection->adjustForLocked ) ;
|
||
|
}
|
||
|
|
||
|
int connection4setLen( CONNECTION4 *connection, const long int dataLen )
|
||
|
{
|
||
|
if ( connection == 0 )
|
||
|
return error4( 0, e4parm_null, E90160 ) ;
|
||
|
if ( connection->message == 0 )
|
||
|
return error4( 0, e4struct, E90160 ) ;
|
||
|
|
||
|
return packet4setLen( connection->message->packet, dataLen ) ;
|
||
|
}
|
||
|
|
||
|
|
||
|
void connection4setRequestLockedInfo( CONNECTION4 *connection, int val )
|
||
|
{
|
||
|
if ( connection == 0 )
|
||
|
{
|
||
|
error4( 0, e4parm_null, E90160 ) ;
|
||
|
return ;
|
||
|
}
|
||
|
if ( connection->message == 0 )
|
||
|
{
|
||
|
error4( 0, e4struct, E90160 ) ;
|
||
|
return ;
|
||
|
}
|
||
|
|
||
|
packet4setRequestLockedInfo( connection->message->packet, val ) ;
|
||
|
}
|
||
|
|
||
|
int connection4status( const CONNECTION4 *connection )
|
||
|
{
|
||
|
if ( connection == 0 )
|
||
|
return error4( 0, e4parm_null, E90160 ) ;
|
||
|
if ( connection->message == 0 )
|
||
|
return error4( 0, e4struct, E90160 ) ;
|
||
|
|
||
|
return packet4status( connection->message->packet ) ;
|
||
|
}
|
||
|
|
||
|
long connection4errCode2( const CONNECTION4 *connection )
|
||
|
{
|
||
|
if ( connection == 0 )
|
||
|
return error4( 0, e4parm_null, E90160 ) ;
|
||
|
if ( connection->message == 0 )
|
||
|
return error4( 0, e4struct, E90160 ) ;
|
||
|
|
||
|
return packet4errCode2( connection->message->packet ) ;
|
||
|
}
|
||
|
|
||
|
int connection4type( const CONNECTION4 *connection )
|
||
|
{
|
||
|
if ( connection == 0 )
|
||
|
return error4( 0, e4parm_null, E90160 ) ;
|
||
|
if ( connection->message == 0 )
|
||
|
return error4( 0, e4struct, E90160 ) ;
|
||
|
|
||
|
return packet4type( connection->message->packet ) ;
|
||
|
}
|
||
|
#endif /* E4PARM_LOW -- i.e. inline */
|
||
|
|
||
|
SOCKET4 *socket4alloc( CODE4 *c4 )
|
||
|
{
|
||
|
SOCKET4 *socket ;
|
||
|
|
||
|
#ifdef E4PARM_LOW
|
||
|
if ( c4 == 0 )
|
||
|
{
|
||
|
error4( 0, e4parm_null, E90161 ) ;
|
||
|
return 0 ;
|
||
|
}
|
||
|
#endif
|
||
|
|
||
|
socket = (SOCKET4 *)u4allocFree( c4, (long)sizeof( SOCKET4 ) ) ;
|
||
|
if ( socket == 0 )
|
||
|
{
|
||
|
#ifdef E4STACK
|
||
|
error4stack( c4, e4memory, E90161 ) ;
|
||
|
#endif
|
||
|
return 0 ;
|
||
|
}
|
||
|
|
||
|
socket->cb = c4 ;
|
||
|
|
||
|
socket->net = socket4netAlloc( socket ) ;
|
||
|
if ( socket->net == 0 )
|
||
|
{
|
||
|
#ifdef E4STACK
|
||
|
error4stack( c4, e4memory, E90161 ) ;
|
||
|
#endif
|
||
|
u4free( socket ) ;
|
||
|
return 0 ;
|
||
|
}
|
||
|
|
||
|
return socket ;
|
||
|
}
|
||
|
|
||
|
int socket4connect( SOCKET4 *socket, const char *serverName, const char *processId )
|
||
|
{
|
||
|
int rc ;
|
||
|
CODE4 *c4 ;
|
||
|
#ifndef S4SERVER
|
||
|
int len ;
|
||
|
#endif
|
||
|
|
||
|
#ifdef E4PARM_LOW
|
||
|
if ( socket == 0 )
|
||
|
return error4( 0, e4parm_null, E90161 ) ;
|
||
|
#ifndef S4SERVER
|
||
|
if ( serverName == 0 )
|
||
|
return error4( socket->cb, e4parm_null, E90161 ) ;
|
||
|
#endif
|
||
|
#endif
|
||
|
|
||
|
c4 = socket->cb ;
|
||
|
|
||
|
#ifdef E4ANALYZE
|
||
|
if ( socket->connect != 0 )
|
||
|
return error4( c4, e4connection, E80101 ) ;
|
||
|
#endif
|
||
|
|
||
|
for ( rc = 0 ;; )
|
||
|
{
|
||
|
socket->connect = connection4alloc( socket ) ;
|
||
|
if ( socket->connect == 0 )
|
||
|
{
|
||
|
rc = e4connection ;
|
||
|
break ;
|
||
|
}
|
||
|
#ifndef S4SERVER
|
||
|
len = strlen( serverName ) ;
|
||
|
len = len < sizeof( socket->serverName ) ? len : sizeof( socket->serverName ) - 1 ;
|
||
|
memcpy( socket->serverName, serverName, len ) ;
|
||
|
c4upper( socket->serverName ) ;
|
||
|
#endif
|
||
|
|
||
|
if ( socket->connect->net != 0 )
|
||
|
{
|
||
|
rc = e4socket ;
|
||
|
break ;
|
||
|
}
|
||
|
socket->connect->net = connection4netAlloc( socket->net ) ;
|
||
|
if ( socket->connect->net == 0 )
|
||
|
{
|
||
|
rc = error4code( c4 ) ;
|
||
|
if ( rc == 0 )
|
||
|
rc = e4memory ;
|
||
|
}
|
||
|
else
|
||
|
rc = connection4netInit( socket->connect->net, socket->net ) ;
|
||
|
|
||
|
if ( rc < 0 )
|
||
|
break ;
|
||
|
|
||
|
#ifdef S4SERVER
|
||
|
rc = socket4netConnectClient( socket->net, socket->connect, socket->connect->net ) ;
|
||
|
#else
|
||
|
rc = socket4netConnectServer( socket->net, socket->connect->net, socket->serverName, processId ) ;
|
||
|
if ( rc < 0 )
|
||
|
break ;
|
||
|
rc = connection4receive( socket->connect ) ;
|
||
|
if ( rc < 0 )
|
||
|
break ;
|
||
|
if ( connection4type( socket->connect ) != CON4ACK )
|
||
|
rc = error4( c4, e4connection, E80229 ) ;
|
||
|
#endif
|
||
|
break ;
|
||
|
}
|
||
|
|
||
|
if ( rc < 0 )
|
||
|
{
|
||
|
if ( error4code( c4 ) < 0 )
|
||
|
return error4code( c4 ) ;
|
||
|
return error4( c4, (short int)rc, E90161 ) ;
|
||
|
}
|
||
|
|
||
|
#ifndef S4SERVER
|
||
|
socket->connect->connected = 1 ;
|
||
|
#ifdef S4DISTRIBUTED
|
||
|
l4add( &c4->servers, socket ) ;
|
||
|
#endif
|
||
|
#endif
|
||
|
|
||
|
return 0 ;
|
||
|
}
|
||
|
|
||
|
CODE4 * S4FUNCTION socket4codeBase( SOCKET4 *socket )
|
||
|
{
|
||
|
return socket->cb ;
|
||
|
}
|
||
|
|
||
|
#ifdef S4SERVER
|
||
|
int socket4verifyConnections( SOCKET4 *socket )
|
||
|
{
|
||
|
SERVER4CLIENT *client, *nextClient ;
|
||
|
|
||
|
for ( nextClient = (SERVER4CLIENT *)l4first( &socket->cb->server->clients ) ;; )
|
||
|
{
|
||
|
client = nextClient ;
|
||
|
nextClient = (SERVER4CLIENT *)l4next( &socket->cb->server->clients, client ) ;
|
||
|
if ( client == 0 )
|
||
|
break ;
|
||
|
if ( client->connection != 0 )
|
||
|
if ( client->connection->connected )
|
||
|
if ( connection4netDisconnected( client->connection->net ) == 1 )
|
||
|
server4disconnect( client->server, client ) ;
|
||
|
}
|
||
|
|
||
|
return 0 ;
|
||
|
}
|
||
|
|
||
|
int socket4connected( SOCKET4 *socket )
|
||
|
{
|
||
|
int rc ;
|
||
|
CONNECTION4 *connection ;
|
||
|
|
||
|
#ifdef E4PARM_LOW
|
||
|
if ( socket == 0 )
|
||
|
return error4( 0, e4parm_null, E90161 ) ;
|
||
|
#endif
|
||
|
|
||
|
#ifdef E4ANALYZE
|
||
|
if ( socket->connect == 0 || socket->net == 0 )
|
||
|
return error4( socket->cb, e4struct, E90161 ) ;
|
||
|
#endif
|
||
|
|
||
|
rc = socket4netConnected( socket->net ) ;
|
||
|
if ( rc == 1 )
|
||
|
{
|
||
|
if ( socket->connect->net == 0 )
|
||
|
return error4( 0, e4info, E90161 ) ;
|
||
|
socket4verifyConnections( socket ) ; /* make sure existing connections are all valid */
|
||
|
socket->connect->connected = 1 ;
|
||
|
l4add( &socket->connections, socket->connect ) ;
|
||
|
connection = socket->connect ;
|
||
|
socket->connect = 0 ;
|
||
|
/* and send the acknowledgement message */
|
||
|
connection4assign( connection, CON4ACK, 0L, 0L ) ;
|
||
|
rc = connection4send( connection ) ;
|
||
|
if ( connection->message != 0 )
|
||
|
{
|
||
|
connection4clear( connection ) ;
|
||
|
message4free( socket->cb, connection->message ) ;
|
||
|
connection->message = 0 ;
|
||
|
}
|
||
|
if ( rc < 0 )
|
||
|
return error4stack( socket->cb, rc, E90161 ) ;
|
||
|
return 1 ;
|
||
|
}
|
||
|
|
||
|
return rc ;
|
||
|
}
|
||
|
#endif
|
||
|
|
||
|
#ifdef E4PARM_LOW
|
||
|
int socket4free( SOCKET4 *socket )
|
||
|
{
|
||
|
if ( socket == 0 )
|
||
|
return 0 ;
|
||
|
|
||
|
#ifdef E4ANALYZE
|
||
|
if ( socket->initUndone != 1 )
|
||
|
return error4( 0, e4info, E90161 ) ;
|
||
|
#endif
|
||
|
u4free( socket ) ;
|
||
|
|
||
|
return 0 ;
|
||
|
}
|
||
|
|
||
|
int socket4init( SOCKET4 *socket, CODE4 *c4, const char *socketName, const char *processId )
|
||
|
{
|
||
|
#ifdef E4PARM_LOW
|
||
|
if ( socket == 0 || c4 == 0 )
|
||
|
return error4( c4, e4parm_null, E90161 ) ;
|
||
|
#ifdef S4SERVER
|
||
|
if ( socketName == 0 )
|
||
|
return error4( c4, e4parm_null, E90161 ) ;
|
||
|
#endif
|
||
|
#endif
|
||
|
|
||
|
socket->cb = c4 ;
|
||
|
|
||
|
if ( processId == 0 )
|
||
|
processId = DEF4PROCESS_ID ;
|
||
|
|
||
|
#ifdef S4SERVER
|
||
|
return socket4netInitServer( socket->net, socketName, processId ) ;
|
||
|
#else
|
||
|
return 0 ;
|
||
|
#endif
|
||
|
}
|
||
|
|
||
|
#ifdef S4SERVER
|
||
|
int socket4shutdownAdvertising( SOCKET4 *socket )
|
||
|
{
|
||
|
return socket4netShutdownAdvertising( socket->net ) ;
|
||
|
}
|
||
|
#endif
|
||
|
#endif /* E4PARM_LOW -- i.e. inline */
|
||
|
|
||
|
int socket4initUndo( SOCKET4 *socket )
|
||
|
{
|
||
|
int rc, save_rc ;
|
||
|
#ifdef S4SERVER
|
||
|
CONNECTION4 *connection ;
|
||
|
#endif
|
||
|
|
||
|
#ifdef E4PARM_LOW
|
||
|
if ( socket == 0 )
|
||
|
return error4( 0, e4parm_null, E90161 ) ;
|
||
|
#endif
|
||
|
|
||
|
#ifdef E4ANALYZE
|
||
|
socket->initUndone = 1 ;
|
||
|
#endif
|
||
|
|
||
|
save_rc = 0 ;
|
||
|
if ( socket->connect != 0 )
|
||
|
{
|
||
|
rc = connection4initUndo( socket->connect ) ;
|
||
|
connection4free( socket->connect ) ;
|
||
|
socket->connect = 0 ;
|
||
|
if ( rc != 0 )
|
||
|
save_rc = rc ;
|
||
|
}
|
||
|
|
||
|
#ifdef S4SERVER
|
||
|
for( ;; )
|
||
|
{
|
||
|
connection = (CONNECTION4 *)l4first( &socket->connections ) ;
|
||
|
if ( connection == 0 )
|
||
|
break ;
|
||
|
rc = connection4initUndo( connection ) ;
|
||
|
if ( rc != 0 )
|
||
|
save_rc = rc ;
|
||
|
rc = connection4free( connection ) ;
|
||
|
if ( rc != 0 )
|
||
|
save_rc = rc ;
|
||
|
}
|
||
|
#endif
|
||
|
|
||
|
if ( socket->net != 0 )
|
||
|
{
|
||
|
rc = socket4netInitUndo( socket->net ) ;
|
||
|
socket4netFree( socket->net ) ;
|
||
|
socket->net = 0 ;
|
||
|
if ( rc != 0 )
|
||
|
save_rc = rc ;
|
||
|
}
|
||
|
|
||
|
return save_rc ;
|
||
|
}
|
||
|
|
||
|
MESSAGE4 *socket4receive( SOCKET4 *socket )
|
||
|
{
|
||
|
MESSAGE4 *message ;
|
||
|
|
||
|
#ifdef E4PARM_LOW
|
||
|
if ( socket == 0 )
|
||
|
{
|
||
|
error4( 0, e4parm_null, E90161 ) ;
|
||
|
return 0 ;
|
||
|
}
|
||
|
#endif
|
||
|
|
||
|
message = socket4netReceive( socket->net ) ;
|
||
|
#ifdef S4COM_PRINT
|
||
|
if ( message != 0 )
|
||
|
{
|
||
|
printf( "Received Message: " ) ;
|
||
|
s4connectionPrint( packet4type( message->packet ) ) ;
|
||
|
}
|
||
|
#endif
|
||
|
return message ;
|
||
|
}
|
||
|
|
||
|
#ifdef S4COM_PRINT
|
||
|
static void s4connectionPrint( const int type )
|
||
|
{
|
||
|
char *out ;
|
||
|
|
||
|
switch( type )
|
||
|
{
|
||
|
#ifndef S4SINGLE
|
||
|
case CON4LOCK:
|
||
|
out = "CON4LOCK" ;
|
||
|
break ;
|
||
|
case CON4UNLOCK:
|
||
|
out = "CON4UNLOCK" ;
|
||
|
break ;
|
||
|
#endif
|
||
|
case CON4WRITE:
|
||
|
out = "CON4WRITE" ;
|
||
|
break ;
|
||
|
case CON4GO:
|
||
|
out = "CON4GO" ;
|
||
|
break ;
|
||
|
case CON4SKIP:
|
||
|
out = "CON4SKIP" ;
|
||
|
break ;
|
||
|
case CON4SEEK:
|
||
|
out = "CON4SEEK" ;
|
||
|
break ;
|
||
|
case CON4SEEK_DBL:
|
||
|
out = "CON4SEEK_DBL" ;
|
||
|
break ;
|
||
|
case CON4START:
|
||
|
out = "CON4START" ;
|
||
|
break ;
|
||
|
case CON4COMMIT:
|
||
|
out = "CON4COMMIT" ;
|
||
|
break ;
|
||
|
case CON4COMPLETE:
|
||
|
out = "CON4COMPLETE" ;
|
||
|
break ;
|
||
|
case CON4ROLLBACK:
|
||
|
out = "CON4ROLLBACK" ;
|
||
|
break ;
|
||
|
case CON4OPEN:
|
||
|
out = "CON4OPEN" ;
|
||
|
break ;
|
||
|
case CON4CLOSE:
|
||
|
out = "CON4CLOSE" ;
|
||
|
break ;
|
||
|
case CON4RECCOUNT:
|
||
|
out = "CON4RECCOUNT" ;
|
||
|
break ;
|
||
|
#ifndef S4SINGLE
|
||
|
case CON4LOCK_CONFIRM:
|
||
|
out = "CON4LOCK_CONFIRM" ;
|
||
|
break ;
|
||
|
case CON4LOCK_GROUP:
|
||
|
out = "CON4LOCK_GROUP" ;
|
||
|
break ;
|
||
|
#endif
|
||
|
case CON4CONNECT:
|
||
|
out = "CON4CONNECT" ;
|
||
|
break ;
|
||
|
case CON4DISCONNECT:
|
||
|
out = "CON4DISCONNECT" ;
|
||
|
break ;
|
||
|
case CON4PACK:
|
||
|
out = "CON4PACK" ;
|
||
|
break ;
|
||
|
case CON4ZAP:
|
||
|
out = "CON4ZAP" ;
|
||
|
break ;
|
||
|
case CON4CREATE:
|
||
|
out = "CON4CREATE" ;
|
||
|
break ;
|
||
|
case CON4CANCEL:
|
||
|
out = "CON4CANCEL" ;
|
||
|
break ;
|
||
|
case CON4RELATE_INIT:
|
||
|
out = "CON4RELATE_INIT" ;
|
||
|
break ;
|
||
|
case CON4RELATE_TOP:
|
||
|
out = "CON4RELATE_TOP" ;
|
||
|
break ;
|
||
|
case CON4RELATE_BOTTOM:
|
||
|
out = "CON4RELATE_BOTTOM" ;
|
||
|
break ;
|
||
|
case CON4RELATE_DO:
|
||
|
out = "CON4RELATE_DO" ;
|
||
|
break ;
|
||
|
case CON4RELATE_DO_ONE:
|
||
|
out = "CON4RELATE_DO_ONE" ;
|
||
|
break ;
|
||
|
case CON4RELATE_FREE:
|
||
|
out = "CON4RELATE_FREE" ;
|
||
|
break ;
|
||
|
#ifndef S4SINGLE
|
||
|
case CON4RELATE_LOCK:
|
||
|
out = "CON4RELATE_LOCK" ;
|
||
|
break ;
|
||
|
case CON4RELATE_UNLOCK:
|
||
|
out = "CON4RELATE_UNLOCK" ;
|
||
|
break ;
|
||
|
#endif
|
||
|
case CON4RELATE_SKIP:
|
||
|
out = "CON4RELATE_SKIP" ;
|
||
|
break ;
|
||
|
case CON4INDEX_CREATE:
|
||
|
out = "CON4INDEX_CREATE" ;
|
||
|
break ;
|
||
|
case CON4INDEX_OPEN:
|
||
|
out = "CON4INDEX_OPEN" ;
|
||
|
break ;
|
||
|
case CON4INDEX_CLOSE:
|
||
|
out = "CON4INDEX_CLOSE" ;
|
||
|
break ;
|
||
|
case CON4POSITION:
|
||
|
out = "CON4POSITION" ;
|
||
|
break ;
|
||
|
case CON4POSITION_SET:
|
||
|
out = "CON4POSITION_SET" ;
|
||
|
break ;
|
||
|
case CON4REINDEX:
|
||
|
out = "CON4REINDEX" ;
|
||
|
break ;
|
||
|
case CON4CHECK:
|
||
|
out = "CON4CHECK" ;
|
||
|
break ;
|
||
|
case CON4TOP:
|
||
|
out = "CON4TOP" ;
|
||
|
break ;
|
||
|
case CON4BOTTOM:
|
||
|
out = "CON4BOTTOM" ;
|
||
|
break ;
|
||
|
case CON4APPEND:
|
||
|
out = "CON4APPEND" ;
|
||
|
break ;
|
||
|
case CON4MEMO_COMPRESS:
|
||
|
out = "CON4MEMO_COMPRESS" ;
|
||
|
break ;
|
||
|
case CON4MEMO:
|
||
|
out = "CON4MEMO" ;
|
||
|
break ;
|
||
|
case CON4INFO:
|
||
|
out = "CON4INFO" ;
|
||
|
break ;
|
||
|
case CON4UNIQUE_SET:
|
||
|
out = "CON4UNIQUE_SET" ;
|
||
|
break ;
|
||
|
case CON4PASSWORD:
|
||
|
out = "CON4PASSWORD" ;
|
||
|
break ;
|
||
|
case CON4TRANS_INIT:
|
||
|
out = "CON4TRANS_INIT" ;
|
||
|
break ;
|
||
|
case CON4RELATE_OPT:
|
||
|
out = "CON4RELATE_OPT" ;
|
||
|
break ;
|
||
|
case CON4SYSTEM:
|
||
|
out = "CON4SYSTEM" ;
|
||
|
break ;
|
||
|
case CON4TAG_SYNCH:
|
||
|
out = "CON4TAG_SYNCH" ;
|
||
|
break ;
|
||
|
case CON4DATE_FORMAT:
|
||
|
out = "CON4DATE_FORMAT" ;
|
||
|
break ;
|
||
|
case CON4TRAN_EOF:
|
||
|
out = "CON4TRAN_EOF" ;
|
||
|
break ;
|
||
|
case CON4TRAN_EOF_HALT:
|
||
|
out = "CON4TRAN_EOF_HALT" ;
|
||
|
break ;
|
||
|
case CON4TRAN_RESTART:
|
||
|
out = "CON4TRAN_RESTART" ;
|
||
|
break ;
|
||
|
case CON4INDEX_FORMAT:
|
||
|
out = "CON4INDEX_FORMAT" ;
|
||
|
break ;
|
||
|
default:
|
||
|
out = "INVALID MESSAGE" ;
|
||
|
break ;
|
||
|
}
|
||
|
printf( "%s\n", out ) ;
|
||
|
}
|
||
|
#endif
|
||
|
|
||
|
#endif /* S4OFF_COMMUNICATIONS */
|