1997-06-16 13:01:08 +00:00
/* c4code.c (c)Copyright Sequiter Software Inc., 1988-1996. All rights reserved. */
# include "d4all.h"
# ifdef __TURBOC__
# pragma hdrstop
# endif /* __TUROBC__ */
# ifdef S4WINTEL
# include <process.h>
# endif /* S4WINTEL */
# if S4VERSION != 6001
# error Your CodeBase source version does not match your header file version.
# endif
# ifdef S4TESTING
# include <fcntl.h>
# include <sys\types.h>
# include <sys\stat.h>
# endif
# ifdef S4WINTEL
# ifdef __TURBOC__
# pragma hdrstop
# ifndef __DLL__
# ifndef S4OS2PM
# ifndef S4WIN32
# ifndef S4WINDOWS
extern unsigned _stklen ;
# endif
# endif
# endif
# endif
# endif
# ifdef _MSC_VER
# ifndef __DLL__
# include <malloc.h>
# endif
# endif
# endif
# ifdef S4CBPP
# ifdef __cplusplus
# include "d4data.hpp"
# endif
# endif
# ifdef S4TESTING
FILE4 s4test ;
# else
# ifdef S4TRACK_FILES
FILE4 s4test ;
# endif
# endif
char f4memoNullChar = ' \0 ' ;
char * expr4buf = 0 ;
static unsigned int numCode4 = 0 ; /* used to determine when mem4reset() should be called */
int code4numCodeBase ( void )
{
return numCode4 ;
}
# ifdef S4SEMAPHORE
# ifdef S4OS2
# include <time.h>
static char sem4mem [ 20 ] , sem4expr [ 20 ] ;
static HMTX hmtx4mem , hmtx4expr ;
# endif
# endif
# ifdef S4IBMOS2
# ifdef S4OS2DLL
# ifndef __MULTI__ /* no multi-thread code is being produced */
int errno = 0 ;
# endif
# endif
# endif
# ifdef __DLL__
# ifdef S4PASCAL
# ifndef S4WIN32
typedef char far * LPSTR ;
typedef unsigned int HANDLE ;
typedef unsigned short WORD ;
# define PASCAL _pascal
# define S4USE_WEP
# endif
# endif
# ifndef S4PASCAL_DOS
# ifdef S4DLL
HINSTANCE cb5inst = ( HINSTANCE ) NULL ;
# endif
# endif
# ifdef S4OS2
ULONG _dllmain ( ULONG termflag , HMODULE modhandle )
{
# ifdef S4SEMAPHORE
int i ;
APIRET rc ;
time_t t ;
# endif
if ( termflag = = 0 )
{
# ifdef S4SEMAPHORE
strcpy ( sem4expr , " \\ SEM32 \\ S4A " ) ;
strcpy ( sem4mem , " \\ SEM32 \\ S4B " ) ;
for ( i = 0 ; i < 100 ; i + + )
{
u4delaySec ( ) ;
time ( & t ) ;
t % = 10000L ;
c4ltoa45 ( t , sem4expr + 10 , - 4 ) ;
c4ltoa45 ( t , sem4mem + 10 , - 4 ) ;
rc = DosCreateMutexSem ( sem4expr , & hmtx4expr , 0 , 0 ) ;
if ( rc ! = 0 )
continue ;
rc = DosCreateMutexSem ( sem4mem , & hmtx4mem , 0 , 0 ) ;
if ( rc ! = 0 )
{
DosCloseMutexSem ( hmtx4expr ) ;
continue ;
}
return 1 ;
}
# else
return 1 ;
# endif
}
else
{
# ifdef S4SEMAPHORE
DosCloseMutexSem ( hmtx4mem ) ;
DosCloseMutexSem ( hmtx4expr ) ;
# endif
}
return 1 ;
}
# endif
# ifdef S4PASCAL_DOS
/* 20-file handle fix for Pascal DOS */
void setfilemax ( void ) ;
# pragma startup setfilemax 0
# ifdef P4ARGS_USED
# pragma argsused
# endif
void setfilemax ( void )
{
asm
{
/*; If default number of file handles have changed then tell DOS*/
cmp _nfile , 20
jbe NoChange
cmp [ _osmajor ] , 3 ; /* Check for >= DOS 3.3*/
jb NoChange
ja DoChange
cmp [ _osminor ] , 1 Eh
jb NoChange
}
DoChange :
asm
{
mov ax , 5801 h /*; Set last fit allocation*/
mov bx , 2
int 21 h
jc BadInit
mov ah , 67 h /*; Expand handle table*/
mov bx , _nfile
int 21 h
jc BadInit
mov ax , 5801 h /*; Set first fit allocation*/
mov bx , 0
int 21 h
jnc NoChange
}
BadInit :
abort ( ) ;
NoChange :
return ;
}
int far PASCAL LibMain ( HANDLE hInstance , WORD wDataSeg , WORD cbHeapSize , LPSTR lpCmdLine )
{
_nfile = 255 ;
setfilemax ( ) ;
return 1 ;
}
# endif /* S4PASCAL_DOS */
# ifndef S4WIN32
# ifndef S4PASCAL_DOS
# ifdef S4WINDOWS
# ifdef P4ARGS_USED
# pragma argsused
# endif
int far PASCAL LibMain ( HINSTANCE hInstance , WORD wDataSeg , WORD cbHeapSize , LPSTR lpCmdLine )
{
if ( ! cb5inst )
cb5inst = hInstance ;
return 1 ;
}
# endif /* S4WINDOWS */
# endif /* S4PASCAL_DOS */
# ifdef P4ARGS_USED
# pragma argsused
# endif
int S4FUNCTION WEP ( int nParameter )
{
return 1 ;
}
# else
BOOL APIENTRY DllMain ( HANDLE hModule , DWORD reasonForCall , LPVOID reserved )
{
if ( ! cb5inst )
cb5inst = hModule ;
return 1 ;
}
# endif /* S4WIN32 */
# ifndef S4PASCAL_DOS
HINSTANCE S4FUNCTION c4dllInst ( void )
{
return cb5inst ;
}
# endif /* S4PASCAL_DOS */
# endif /* __DLL__ */
# ifndef S4OFF_COMMUNICATIONS
# ifndef S4SERVER
static int code4userConnect ( CODE4 * c4 , const char * userName , const char * password )
{
int rc ;
long version ;
CONNECTION4 * connection ;
static char defaultUser [ ] = " PUBLIC " ;
if ( c4 - > defaultServer = = 0 )
return 0 ;
connection = c4 - > defaultServer - > connect ;
if ( connection = = 0 )
return 0 ;
if ( userName = = 0 )
userName = defaultUser ;
else
if ( userName [ 0 ] = = 0 )
userName = defaultUser ;
if ( password = = 0 )
password = " " ;
connection4assign ( connection , CON4CONNECT , 0L , 0L ) ;
version = S4VERSION ;
connection4addData ( connection , & version , sizeof ( version ) , 0 ) ;
connection4addData ( connection , userName , strlen ( userName ) + 1 , 0 ) ;
connection4addData ( connection , password , strlen ( password ) + 1 , 0 ) ;
connection4send ( connection ) ;
rc = connection4receive ( connection ) ;
if ( rc < 0 )
return rc ;
rc = connection4status ( connection ) ;
if ( rc < 0 )
connection4error ( connection , c4 , rc , E91005 ) ;
return rc ;
}
int S4FUNCTION code4connect ( CODE4 * c4 , const char * serverId , const char * processId , const char * userName , const char * password , const char * protocol )
{
int rc ;
# ifndef S4DOS
int len ;
# endif
# ifdef S4VBASIC
if ( c4parm_check ( c4 , 1 , E91004 ) )
return 0 ;
# endif
# ifdef E4PARM_HIGH
if ( c4 = = 0 )
return error4 ( 0 , e4parm_null , E91004 ) ;
# endif
if ( c4 - > defaultServer ! = 0 )
return r4connected ;
# ifndef S4DOS
if ( c4 - > protocol [ 0 ] = = 0 )
{
if ( protocol = = 0 )
return error4 ( 0 , e4parm_null , E81005 ) ;
if ( protocol [ 0 ] = = 0 )
return error4 ( 0 , e4parm_null , E81005 ) ;
}
if ( protocol ! = 0 )
if ( protocol [ 0 ] ! = 0 )
{
len = strlen ( protocol ) ;
# ifdef E4PARM_HIGH
if ( len > LEN4PROTOCOL )
return error4 ( 0 , e4parm , E81005 ) ;
# endif
memcpy ( c4 - > protocol , protocol , len ) ;
c4 - > protocol [ len ] = 0 ;
}
# endif
c4 - > defaultServer = socket4alloc ( c4 ) ;
if ( c4 - > defaultServer = = 0 )
return error4 ( c4 , e4connection , E81001 ) ;
if ( serverId = = 0 )
serverId = DEF4SERVER_ID ;
else
if ( serverId [ 0 ] = = 0 )
serverId = DEF4SERVER_ID ;
if ( processId = = 0 )
processId = DEF4PROCESS_ID ;
else
if ( processId [ 0 ] = = 0 )
processId = DEF4PROCESS_ID ;
rc = socket4init ( c4 - > defaultServer , c4 , serverId , processId ) ;
if ( rc = = 0 )
rc = socket4connect ( c4 - > defaultServer , serverId , processId ) ;
# ifndef S4UTILS
if ( rc = = 0 )
rc = code4userConnect ( c4 , userName , password ) ;
# endif
if ( rc ! = 0 )
{
socket4initUndo ( c4 - > defaultServer ) ;
socket4free ( c4 - > defaultServer ) ;
c4 - > defaultServer = 0 ;
return rc ;
}
return 0 ;
}
# ifdef S4UTIL
int S4FUNCTION code4passwordSet ( CODE4 * c4 , const char * userId , const char * oldPass , const char * newPass ) ;
{
CONNECTION4 * connection ;
unsigned short int len [ 3 ] ;
# ifdef E4PARM_HIGH
if ( userId = = 0 | | oldPass = = 0 | | newPass = = 0 )
return error4 ( c4 , e4parmNull , E91017 ) ;
# endif
connection = c4 - > defaultServer - > connect ;
if ( connection = = 0 ) /* not connected */
return error4 ( c4 , e4connection , E91017 ) ;
connection4assign ( connection , CON4PASSWORD_SET , 0L , 0L ) ;
len [ 0 ] = strlen ( userId ) ;
len [ 1 ] = strlen ( oldPass ) ;
len [ 2 ] = strlen ( newPass ) ;
connection4send ( connection ) ;
connection4addData ( connection , len , sizeof ( len ) , 0 ) ;
connection4addData ( connection , userId , len [ 0 ] , 0 ) ;
connection4addData ( connection , oldPass , len [ 1 ] , 0 ) ;
connection4addData ( connection , newPass , len [ 2 ] , 0 ) ;
rc = connection4receive ( connection ) ;
if ( rc < 0 )
return rc ;
return connection4status ( connection ) ;
}
# endif /* S4UTIL */
# endif /* S4SERVER */
# endif /* S4OFF_COMMUNICATIONS */
# ifdef P4ARGS_USED
# pragma argsused
# endif
int S4FUNCTION code4initLow ( CODE4 * c4 , const char * defaultProtocol , long versionId )
{
char v1 [ 10 ] , v2 [ 10 ] ;
2003-05-02 09:28:02 +00:00
# ifdef S4WINDOWS
int n ;
# endif
2003-05-01 15:14:58 +00:00
1997-06-16 13:01:08 +00:00
# ifdef S4TESTING
int exclusiveFlag ;
int openFlag ;
char * envLog ;
# ifdef S4CASE_SEN
char * logFile = " T4TEST.log " ;
# else
char * logFile = " T4TEST.LOG " ;
# endif
# else
# ifdef S4TRACK_FILES
int openFlag ;
char * envLog ;
# ifdef S4CASE_SEN
char * logFile = " T4TEST.log " ;
# else
char * logFile = " T4TEST.LOG " ;
# endif
# endif
# endif
# ifndef S4SERVER
int rc ;
# endif
# ifdef S4CLIENT
# ifndef S4DOS
int len ;
# endif
# endif
# ifndef S4OFF_OPTIMIZE
# ifdef S4OPTIMIZE_STATS
DATA4 * stat ;
int oldOffErr ;
# endif
# endif
# ifdef E4PARM_HIGH
if ( c4 = = 0 )
return error4 ( 0 , e4parm , E91001 ) ;
# endif
/***********************************************************************
This code must reside at the beginning of the function to ensure that
no file open / create incorrectly auto - starts the optimization process
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
2003-05-01 15:14:58 +00:00
1997-06-16 13:10:44 +00:00
# ifdef S4WINDOWS
n = SetHandleCount ( 40 ) ;
# endif
1997-06-16 13:01:08 +00:00
# ifndef S4OFF_OPTIMIZE
c4 - > hadOpt = 1 ;
# endif
# ifdef S4TESTING
if ( numCode4 = = 0 )
{
memset ( & s4test , 0 , sizeof ( s4test ) ) ;
s4test . hand = - 1 ;
}
# else
# ifdef S4TRACK_FILES
if ( numCode4 = = 0 )
{
memset ( & s4test , 0 , sizeof ( s4test ) ) ;
s4test . hand = - 1 ;
}
# endif
# endif
if ( versionId ! = S4VERSION )
{
c4ltoa45 ( e4version , v1 , sizeof ( v1 ) ) ;
c4ltoa45 ( S4VERSION , v2 , sizeof ( v2 ) ) ;
return error4describe ( c4 , e4version , E91001 , v1 , v2 , 0 ) ;
}
memset ( ( void * ) c4 , 0 , sizeof ( CODE4 ) ) ;
/* if a DLL, can't check the stack length since this is a separate executable */
# ifndef S4WIN32
# ifndef S4WINDOWS
# ifndef __DLL__
# ifdef __TURBOC__
# ifndef S4OS2PM
if ( _stklen < 5000U ) /* 5000 seems to be an appropriate minimum */
return error4 ( c4 , e4result , E81003 ) ;
# endif
# endif
# endif
# ifdef _MSC_VER
if ( stackavail ( ) < 5000U )
error4 ( c4 , e4result , E81003 ) ;
# endif
# endif
# endif
if ( numCode4 = = 0 )
mem4init ( ) ;
numCode4 + + ;
# ifdef E4ANALYZE
c4 - > debugInt = E4DEBUG_INT ; /* Some random value for double checking. */
# else
# ifdef S4VBASIC
c4 - > debugInt = E4DEBUG_INT ; /* Some random value for double checking. */
# endif /* S4VBASIC */
# endif /* E4MISC */
# ifndef S4OFF_MEMO
c4 - > memSizeMemoExpr = 0x400 ; /* 1024 */
# endif
c4 - > numericStrLen = 17 ; /* default length for clipper numeric keys is 10 */
c4 - > decimals = 2 ;
/* Flags initialization */
c4 - > errCreate = 1 ;
c4 - > errDefaultUnique = r4uniqueContinue ;
c4 - > errExpr = 1 ;
c4 - > errFieldName = 1 ;
c4 - > errOpen = 1 ;
# ifndef S4OFF_INDEX
c4 - > errTagName = 1 ;
# endif
c4 - > autoOpen = 1 ;
c4 - > safety = 1 ;
# ifndef S4OFF_MULTI
c4 - > lockDelay = 100 ;
# endif
c4 - > collatingSequence = sort4machine ; /* default to FoxPro 2.x values */
c4 - > codePage = cp0 ;
c4 - > memStartDataFile = 5 ;
c4 - > memExpandDataFile = 5 ;
# ifndef S4OFF_INDEX
c4 - > memStartTagFile = 10 ;
c4 - > memExpandTagFile = 5 ;
# endif
# ifndef S4SINGLE
c4 - > memStartLock = 5 ;
c4 - > memExpandLock = 10 ;
# endif
# ifndef N4OTHER
c4 - > memStartIndexFile = 5 ;
c4 - > memExpandIndexFile = 5 ;
# endif
# ifndef S4OFF_MULTI
c4 - > lockAttemptsSingle = 1 ;
# endif
# ifdef S4SERVER
# ifdef S4DEBUG_LOG
c4 - > logFile . hand = - 1 ;
# endif
c4 - > lockAttempts = 1 ;
c4 - > memStartClient = 5 ;
c4 - > memExpandClient = 5 ;
# ifdef N4OTHER
c4 - > memStartIndex = 10 ;
c4 - > memStartTag = 10 ;
c4 - > memExpandIndex = 5 ;
c4 - > memExpandTag = 10 ;
# endif
# else
c4 - > errGo = 1 ;
c4 - > errSkip = 1 ;
c4 - > errRelate = 1 ;
# ifndef S4OFF_MULTI
c4 - > lockAttempts = WAIT4EVER ; /* wait forever */
# endif
c4 - > singleOpen = 1 ;
# ifndef S4OFF_ENFORCE_LOCK
c4 - > lockEnforce = 0 ;
# endif
# ifdef S4OFF_OPTIMIZE
# ifndef S4OFF_INDEX
c4 - > memSizeBlock = 0x400 ; /* 1024 */
# endif
# else
c4 - > memSizeBlock = 0x400 ; /* 1024 */
# endif
c4 - > memSizeSortPool = 0xF000 ; /* 61440 */
c4 - > memSizeSortBuffer = 0x1000 ; /* 4096 */
c4 - > memSizeBuffer = 0x8000 ; /* 32768 */
# ifndef S4OFF_MEMO
c4 - > memSizeMemo = 0x200 ; /* 512 */
# endif
c4 - > memStartData = 10 ;
c4 - > memExpandData = 5 ;
# ifndef S4OFF_INDEX
c4 - > memExpandBlock = 10 ;
c4 - > memStartBlock = 10 ;
c4 - > memStartIndex = 10 ;
c4 - > memStartTag = 10 ;
c4 - > memExpandIndex = 5 ;
c4 - > memExpandTag = 10 ;
# endif
# endif
# ifdef S4CLIENT
# ifndef S4DOS
if ( defaultProtocol ! = 0 )
{
len = strlen ( defaultProtocol ) ;
# ifdef E4PARM_HIGH
if ( len > LEN4PROTOCOL )
return error4 ( 0 , e4parm , E81005 ) ;
# endif
memcpy ( c4 - > protocol , defaultProtocol , len ) ;
c4 - > protocol [ len ] = 0 ;
}
# endif
# else
c4 - > doIndexVerify = 1 ;
# endif
# ifndef S4OFF_TRAN
# ifndef S4OFF_WRITE
# ifndef S4CIENT
c4 - > log = LOG4ON ;
# endif
# ifdef S4STAND_ALONE
c4 - > logOpen = 1 ;
# endif
# endif
# endif
# ifndef S4OFF_COMMUNICATIONS
# ifdef S4TIMEOUT_HOOK
c4 - > timeout = 100 ;
# else
c4 - > timeout = - 1 ;
# endif
# endif
# ifndef S4OPTIMIZE_OFF
c4 - > doOpt = 1 ; /* by default do optimization */
# ifndef S4SERVER
c4 - > optimize = OPT4EXCLUSIVE ; /* by default optimize non-shared files */
c4 - > optimizeWrite = OPT4EXCLUSIVE ;
# endif /* S4SERVER */
# endif /* not S4OPTIMIZE_OFF */
# ifndef S4SERVER
rc = code4tranInit ( c4 ) ;
if ( rc < 0 )
return error4 ( c4 , rc , E91001 ) ;
# ifndef S4OFF_COMMUNICATIONS
c4 - > clientDataCount = 1 ;
# endif
# ifndef S4LANGUAGE
code4dateFormatSet ( c4 , " MM/DD/YY " ) ;
# else
# ifdef S4GERMAN
code4dateFormatSet ( c4 , " DD.MM.YY " ) ;
# endif
# ifdef S4FRENCH
code4dateFormatSet ( c4 , " MM/DD/YY " ) ;
# endif
# ifdef S4SWEDISH
code4dateFormatSet ( c4 , " YYYY-MM-DD " ) ;
# endif
# ifdef S4FINNISH
code4dateFormatSet ( c4 , " YYYY-MM-DD " ) ;
# endif
# ifdef S4NORWEGIAN
code4dateFormatSet ( c4 , " DD-MM-YYYY " ) ;
# endif
# endif
# endif
c4 - > initialized = 1 ;
if ( numCode4 = = 1 )
{
# ifdef S4TESTING
openFlag = c4 - > errOpen ;
exclusiveFlag = c4 - > accessMode ;
c4 - > errOpen = 0 ;
c4 - > accessMode = OPEN4DENY_NONE ;
envLog = getenv ( " T4LOG " ) ;
if ( envLog ) /* if env. var. exists, use it */
logFile = envLog ;
if ( file4open ( & s4test , c4 , logFile , 0 ) ! = r4success )
file4create ( & s4test , c4 , logFile , 0 ) ;
c4 - > accessMode = exclusiveFlag ;
c4 - > errOpen = openFlag ;
# else
# ifdef S4TRACK_FILES
openFlag = c4 - > errOpen ;
c4 - > errOpen = 0 ;
envLog = getenv ( " CB51_LOG " ) ;
if ( envLog ) /* if env. var. exists, use it */
logFile = envLog ;
if ( file4open ( & s4test , c4 , logFile , 0 ) ! = r4success )
file4create ( & s4test , c4 , logFile , 0 ) ;
c4 - > errOpen = openFlag ;
# endif
# endif
}
# ifndef S4SERVER
# ifndef S4SINGLE
# ifdef S4CB51
code4unlockAutoSet ( c4 , LOCK4DATA ) ;
# else
code4unlockAutoSet ( c4 , LOCK4ALL ) ;
# endif
# endif
# endif
# ifndef S4OFF_OPTIMIZE
# ifdef S4OPTIMIZE_STATS
stat = c4 - > statusDbf ;
if ( stat = = 0 ) /* open the stat database */
{
oldOffErr = c4 - > errOpen ;
c4 - > errOpen = 0 ;
c4 - > statusDbf = d4open ( c4 , " OPT4STAT " ) ;
c4 - > errOpen = oldOffErr ;
stat = c4 - > statusDbf ;
if ( stat = = 0 )
error4set ( c4 , 0 ) ;
else
{
d4optimize ( stat , OPT4OFF ) ;
c4 - > typeFld = d4field ( stat , " TYPE " ) ;
c4 - > fileNameFld = d4field ( stat , " FILE_NAME " ) ;
c4 - > offsetFld = d4field ( stat , " OFFSET " ) ;
c4 - > lengthFld = d4field ( stat , " LENGTH " ) ;
if ( c4 - > typeFld = = 0 | | c4 - > fileNameFld = = 0 | | c4 - > offsetFld = = 0 | | c4 - > lengthFld = = 0 )
{
d4close ( stat ) ;
c4 - > statusDbf = 0 ;
}
}
}
# endif
# endif /* S4OFF_OPTIMIZE */
# ifdef S4WRITE_DELAY
/* if the begin thread fails, then delay-writes are simply not enabled,
which is ok because it will simply be bypassed . */
InitializeCriticalSection ( & c4 - > critical4delayWriteList ) ;
c4 - > pendingWriteEvent = CreateEvent ( 0 , TRUE , FALSE , 0 ) ;
if ( c4 - > pendingWriteEvent ! = INVALID_HANDLE_VALUE )
{
/* cast unsigned long to long for BORLAND C++ avoid warning message
( verified with Borland ) */
if ( ( long ) _beginthread ( file4writeDelayMain , 5000 , c4 ) = = - 1 )
{
CloseHandle ( c4 - > pendingWriteEvent ) ;
DeleteCriticalSection ( & c4 - > critical4delayWriteList ) ;
}
else
while ( c4 - > delayWritesEnabled ! = 1 ) /* ensure thread starts to avoid initUndo thread corruptions */
Sleep ( 0 ) ;
}
# endif
# ifdef S4READ_ADVANCE
/* if the begin thread fails, then delay-writes are simply not enabled,
which is ok because it will simply be bypassed . */
InitializeCriticalSection ( & c4 - > critical4advanceReadList ) ;
c4 - > pendingReadEvent = CreateEvent ( 0 , TRUE , FALSE , 0 ) ;
if ( c4 - > pendingReadEvent ! = INVALID_HANDLE_VALUE )
{
/* cast unsigned long to long for BORLAND C++ avoid warning message
( verified with Borland ) */
if ( ( long ) _beginthread ( file4advanceReadMain , 5000 , c4 ) = = - 1 )
{
CloseHandle ( c4 - > pendingReadEvent ) ;
DeleteCriticalSection ( & c4 - > critical4advanceReadList ) ;
}
else
while ( c4 - > advanceReadsEnabled ! = 1 ) /* ensure thread starts to avoid initUndo thread corruptions */
Sleep ( 0 ) ;
}
# endif
/***********************************************************************
This code must reside at the end of the function to ensure that no
file open / create incorrectly auto - starts the optimization process
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
# ifndef S4OFF_OPTIMIZE
c4 - > hadOpt = 1 ;
# ifdef S4SERVER
c4 - > memMaxPercent = - 1 ; /* use server configuration file */
# else
c4 - > memMaxPercent = 25 ; /* default use 25% of available memory */
# endif
# ifdef S4OS2
c4 - > memStartMax = 0xF0000L ;
# else
# ifndef S4WINTEL
c4 - > memStartMax = 0xF0000L ;
# else
# ifdef S4WINDOWS
c4 - > memStartMax = 0xF0000L ;
# else
c4 - > memStartMax = 0x50000L ;
# endif /* S4WINDOWS */
# endif
# endif
# endif
return 0 ;
}
/* if doInit is set to 1, code4init() is called on the allocated CODE4 */
CODE4 * S4FUNCTION code4allocLow ( int doInit , const char * defaultProtocol , long versionId )
{
CODE4 * c4 ;
# ifndef S4CBPP
c4 = ( CODE4 * ) u4alloc ( ( long ) sizeof ( CODE4 ) ) ;
# else
# ifdef __cplusplus
c4 = ( CODE4 * ) u4alloc ( ( long ) sizeof ( Code4 ) ) ;
# else
c4 = ( CODE4 * ) u4alloc ( ( long ) sizeof ( CODE4 ) ) ;
# endif
# endif
if ( c4 = = 0 )
return 0 ;
if ( doInit = = 1 )
code4initLow ( c4 , defaultProtocol , versionId ) ;
return c4 ;
}
void S4FUNCTION expr4calcDelete ( EXPR4CALC * calc )
{
CODE4 * c4 ;
if ( ! calc | | ! calc - > expr )
return ;
c4 = calc - > expr - > codeBase ;
# ifndef S4SERVER
if ( calc - > total ! = 0 )
{
expr4free ( calc - > total - > resetExpression ) ;
l4remove ( & c4 - > totalList , calc - > total ) ;
mem4free ( c4 - > totalMemory , calc - > total ) ;
}
# endif
# ifdef S4SERVER
l4remove ( & c4 - > currentClient - > calcList , calc ) ;
# else
l4remove ( & c4 - > calcList , calc ) ;
# endif
expr4free ( calc - > expr ) ;
mem4free ( c4 - > calcMemory , calc ) ;
}
void S4FUNCTION code4calcReset ( CODE4 * c4 )
{
LIST4 * list ;
# ifdef S4CLIENT
CONNECTION4 * connection ;
int rc ;
# endif
# ifdef E4PARM_HIGH
if ( c4 = = 0 )
{
error4 ( 0 , e4parm_null , E90921 ) ;
return ;
}
# endif
# ifdef S4SERVER
list = & c4 - > currentClient - > calcList ;
# else
list = & c4 - > calcList ;
# endif
if ( list > ( LIST4 * ) NULL )
{
while ( list - > nLink > 0 )
expr4calcDelete ( ( EXPR4CALC * ) list - > lastNode ) ;
# ifdef S4CLIENT
if ( c4 - > defaultServer ! = 0 )
{
connection = c4 - > defaultServer - > connect ;
rc = connection4assign ( connection , CON4CALC_RESET , 0 , 0 ) ;
if ( rc < 0 )
return ;
connection4send ( connection ) ;
rc = connection4receive ( connection ) ;
if ( rc < 0 )
return ;
rc = connection4status ( connection ) ;
if ( rc < 0 )
connection4error ( connection , c4 , rc , E90921 ) ;
}
# endif
}
}
# ifdef S4MEM_PRINT
extern char * write4buf ;
extern FILE4SEQ_WRITE * file4seqPtr ;
# endif
static int code4initUndo2 ( CODE4 * c4 , int doClose )
{
# ifdef S4DISTRIBUTED
# ifdef S4CLIENT
SOCKET4 * socket , * socketNext ;
# endif
# endif
# ifndef S4OFF_COMMUNICATIONS
MESSAGE4DATA * message ;
# endif
# ifndef S4SERVER
# ifndef S4OFF_TRAN
# endif
# endif
# ifdef E4PARM_HIGH
if ( c4 = = 0 )
return e4parm_null ;
# endif
if ( c4 - > initialized = = 0 ) /* already uninitialized */
return 0 ;
# ifdef E4MISC
if ( numCode4 = = 0 ) /* code4initUndo already called... */
{
if ( doClose = = 1 ) /* if zero, don't error out since severe already */
return error4 ( 0 , e4info , E81004 ) ;
else
return e4info ;
}
# endif
# ifdef S4SEMAPHORE
# ifdef S4OS2
DosCloseMutexSem ( hmtx4mem ) ;
DosCloseMutexSem ( hmtx4expr ) ;
# endif
# endif
# ifndef S4OPTIMIZE_OFF
code4optSuspend ( c4 ) ;
# endif
# ifndef S4SERVER
# ifndef S4OFF_TRAN
# ifndef S4CLIENT
if ( code4transEnabled ( c4 ) )
# endif
if ( code4tranStatus ( c4 ) = = r4active )
code4tranRollback ( c4 ) ;
# endif
if ( doClose )
code4close ( c4 ) ;
# endif
# ifndef S4SERVER
code4calcReset ( c4 ) ;
# ifndef S4OFF_COMMUNICATIONS
# ifdef S4DISTRIBUTED
socketNext = ( SOCKET4 * ) l4first ( & c4 - > servers ) ;
for ( ; ; )
{
socket = socketNext ;
if ( socket = = 0 )
break ;
socketNext = ( SOCKET4 * ) l4next ( & c4 - > servers , socket ) ;
socket4initUndo ( socket ) ;
l4remove ( & c4 - > servers , socket ) ;
socket4free ( socket ) ;
}
# else
if ( c4 - > defaultServer ! = 0 )
{
socket4initUndo ( c4 - > defaultServer ) ;
socket4free ( c4 - > defaultServer ) ;
}
# endif
c4 - > defaultServer = 0 ;
# endif
# ifndef S4OFF_TRAN
code4tranInitUndo ( c4 ) ;
# endif
# endif
# ifdef S4OPTIMIZE_STATS
if ( c4 - > statusDbf ! = 0 )
{
d4close ( c4 - > statusDbf ) ;
c4 - > statusDbf = 0 ;
}
# endif
if ( c4 - > version ! = 0 )
{
u4free ( c4 - > version ) ;
c4 - > version = 0 ;
}
# ifdef S4MNDX
if ( c4 - > memoUseBuffer ! = 0 )
{
u4free ( c4 - > memoUseBuffer ) ;
c4 - > memoUseBuffer = 0 ;
}
# endif
# ifdef S4WRITE_DELAY
/* set the event semaphore to terminate the delay-write thread */
if ( c4 - > delayWritesEnabled )
{
c4 - > initUndoDelayWrite = CreateEvent ( 0 , TRUE , FALSE , 0 ) ;
if ( c4 - > initUndoDelayWrite ! = INVALID_HANDLE_VALUE )
{
InterlockedIncrement ( & c4 - > uninitializeDelayWrite ) ;
/* notify the write thread */
if ( SetEvent ( c4 - > pendingWriteEvent ) = = TRUE ) /* wait for the delay-write thread to uninitialize */
WaitForSingleObject ( c4 - > initUndoDelayWrite , INFINITE ) ;
CloseHandle ( c4 - > initUndoDelayWrite ) ;
CloseHandle ( c4 - > pendingWriteEvent ) ;
DeleteCriticalSection ( & c4 - > critical4delayWriteList ) ;
}
}
# endif
# ifdef S4READ_ADVANCE
/* set the event semaphore to terminate the advance-read thread */
if ( c4 - > advanceReadsEnabled )
{
c4 - > initUndoAdvanceRead = CreateEvent ( 0 , TRUE , FALSE , 0 ) ;
if ( c4 - > initUndoAdvanceRead ! = INVALID_HANDLE_VALUE )
{
InterlockedIncrement ( & c4 - > uninitializeAdvanceRead ) ;
/* notify the write thread */
if ( SetEvent ( c4 - > pendingReadEvent ) = = TRUE ) /* wait for the delay-write thread to uninitialize */
WaitForSingleObject ( c4 - > initUndoAdvanceRead , INFINITE ) ;
CloseHandle ( c4 - > initUndoAdvanceRead ) ;
CloseHandle ( c4 - > pendingReadEvent ) ;
DeleteCriticalSection ( & c4 - > critical4advanceReadList ) ;
}
}
# endif
# ifndef S4OFF_INDEX
mem4release ( c4 - > indexMemory ) ;
c4 - > indexMemory = 0 ;
mem4release ( c4 - > index4fileMemory ) ;
c4 - > index4fileMemory = 0 ;
# endif
mem4release ( c4 - > dataMemory ) ;
c4 - > dataMemory = 0 ;
mem4release ( c4 - > data4fileMemory ) ;
c4 - > data4fileMemory = 0 ;
# ifndef S4OFF_MULTI
mem4release ( c4 - > lockMemory ) ;
c4 - > lockMemory = 0 ;
mem4release ( c4 - > lockLinkMemory ) ;
c4 - > lockLinkMemory = 0 ;
# endif
# ifndef S4OFF_INDEX
mem4release ( c4 - > tagMemory ) ;
c4 - > tagMemory = 0 ;
mem4release ( c4 - > tagFileMemory ) ;
c4 - > tagFileMemory = 0 ;
# endif
mem4release ( c4 - > dataListMemory ) ;
c4 - > dataListMemory = 0 ;
mem4release ( c4 - > relateDataListMemory ) ;
c4 - > relateDataListMemory = 0 ;
mem4release ( c4 - > relateMemory ) ;
c4 - > relateMemory = 0 ;
mem4release ( c4 - > relateListMemory ) ;
c4 - > relateListMemory = 0 ;
mem4release ( c4 - > relationMemory ) ;
c4 - > relationMemory = 0 ;
mem4release ( c4 - > calcMemory ) ;
c4 - > calcMemory = 0 ;
# ifdef S4SERVER
if ( c4 - > catalogClient ! = 0 )
{
mem4free ( c4 - > clientMemory , c4 - > catalogClient ) ;
c4 - > catalogClient = 0 ;
}
mem4release ( c4 - > clientMemory ) ;
c4 - > clientMemory = 0 ;
# endif
# ifndef S4STAND_ALONE
message4release ( c4 ) ;
# endif
mem4release ( c4 - > bitmapMemory ) ;
c4 - > bitmapMemory = 0 ;
if ( c4 - > fieldBuffer ! = 0 )
{
u4free ( c4 - > fieldBuffer ) ;
c4 - > fieldBuffer = 0 ;
c4 - > bufLen = 0 ;
}
if ( c4 - > exprWorkBuf ! = 0 )
{
u4free ( c4 - > exprWorkBuf ) ;
c4 - > exprWorkBuf = 0 ;
c4 - > exprBufLen = 0 ;
}
if ( c4 - > storedKey ! = 0 )
{
u4free ( c4 - > storedKey ) ;
c4 - > storedKey = 0 ;
c4 - > storedKeyLen = 0 ;
}
if ( c4 - > errorLog ! = 0 )
{
if ( c4 - > errorLog - > hand > 0 )
file4close ( c4 - > errorLog ) ;
u4free ( c4 - > errorLog ) ;
c4 - > errorLog = 0 ;
}
# ifdef E4ANALYZE
c4 - > debugInt = 0 ; /* Some random value for double checking. */
# endif
# ifdef S4DEBUG_LOG
# ifdef S4SERVER
code4logInitUndo ( c4 ) ;
# endif
# endif
# ifndef S4OFF_TRAN
if ( c4 - > tranData ! = 0 )
{
u4free ( c4 - > tranData ) ;
c4 - > tranData = 0 ;
c4 - > tranDataLen = 0 ;
}
# endif
# ifndef S4OFF_COMMUNICATIONS
for ( ; ; )
{
message = ( MESSAGE4DATA * ) l4pop ( & c4 - > availDataMessages ) ;
if ( message = = 0 )
break ;
if ( message - > didAlloc = = 1 )
{
u4free ( message - > allocatedData ) ;
message - > didAlloc = 0 ;
}
mem4free ( c4 - > messageLinkMemory , message ) ;
}
mem4release ( c4 - > messageLinkMemory ) ;
c4 - > messageLinkMemory = 0 ;
mem4release ( c4 - > connectionMemory ) ;
c4 - > connectionMemory = 0 ;
mem4release ( c4 - > connectionNetMemory ) ;
c4 - > connectionNetMemory = 0 ;
# endif
numCode4 - - ;
# ifdef S4TESTING
if ( s4test . codeBase = = c4 )
{
if ( s4test . hand )
{
# ifdef S4MEM_PRINT
if ( write4buf ! = 0 )
{
file4seqWriteFlush ( file4seqPtr ) ;
u4free ( write4buf ) ;
write4buf = 0 ;
}
# endif
file4close ( & s4test ) ;
}
}
# else
# ifdef S4TRACK_FILES
if ( s4test . codeBase = = c4 )
if ( s4test . hand )
file4close ( & s4test ) ;
# endif
# endif
if ( numCode4 = = 0 ) /* reset memory */
mem4reset ( ) ;
c4 - > initialized = 0 ;
return error4code ( c4 ) ;
}
# ifndef S4SERVER
void S4FUNCTION code4exit ( CODE4 * c4 )
{
# ifndef S4WINDOWS
int rc ;
if ( c4 = = 0 )
rc = - 1 ;
else
{
rc = c4 - > errorCode ;
# endif
code4initUndo2 ( c4 , 0 ) ;
# ifdef E4MISC
# ifdef S4TESTING
mem4freeCheck ( 100 ) ;
mem4checkMemory ( ) ;
mem4reset ( ) ;
# endif
# endif
# ifndef S4WINDOWS
}
exit ( rc ) ;
# else
# ifdef S4TESTING
u4terminate ( ) ;
# else
FatalAppExit ( 0 , E4_MESSAG_EXI ) ;
# endif
# endif
}
# endif /* S4SERVER */
int S4FUNCTION code4initUndo ( CODE4 * c4 )
{
# ifdef S4SERVER
return code4initUndo2 ( c4 , 0 ) ;
# else
return code4initUndo2 ( c4 , 1 ) ;
# endif
}
# ifndef S4SERVER
int S4FUNCTION code4close ( CODE4 * c4 )
{
DATA4 * dataOn , * dataNext ;
LIST4 * list ;
# ifdef S4VBASIC
if ( c4parm_check ( c4 , 1 , E91003 ) )
return - 1 ;
# endif /* S4VBASIC */
# ifdef E4PARM_HIGH
if ( c4 = = 0 )
return error4 ( 0 , e4parm_null , E91003 ) ;
# endif
list = tran4dataList ( ( & ( c4 - > c4trans . trans ) ) ) ;
for ( dataNext = ( DATA4 * ) l4first ( list ) ; ; )
{
dataOn = dataNext ;
if ( dataOn = = 0 )
break ;
dataNext = ( DATA4 * ) l4next ( list , dataNext ) ;
if ( dataOn = = dataNext ) /* error -- stuck in endless loop */
return - 1 ;
# ifndef S4OFF_OPTIMIZE
# ifdef S4OPTIMIZE_STATS
/* don't close the internal opt tracking dbf here. */
if ( dataOn ! = dataOn - > codeBase - > statusDbf )
# endif
# endif
d4close ( dataOn ) ;
}
if ( error4code ( c4 ) < 0 )
return error4code ( c4 ) ;
return 0 ;
}
# endif
/* input must be in capital letters */
DATA4FILE * dfile4data ( CODE4 * c4 , const char * aliasName )
{
DATA4FILE * dataOn ;
# ifdef E4MISC
DATA4FILE * dataResult ;
# endif
# ifdef E4PARM_LOW
if ( c4 = = 0 | | aliasName = = 0 )
{
error4 ( c4 , e4parm_null , E91102 ) ;
return 0 ;
}
# endif
dataOn = 0 ;
# ifdef E4MISC
dataResult = 0 ;
# endif
for ( ; ; )
{
dataOn = ( DATA4FILE * ) l4next ( & c4 - > dataFileList , dataOn ) ;
if ( ! dataOn )
break ;
if ( strcmp ( aliasName , dfile4name ( dataOn ) ) = = 0 )
{
# ifdef E4MISC
if ( dataResult ! = 0 )
{
error4 ( c4 , e4info , E83501 ) ;
return 0 ;
}
dataResult = dataOn ;
# else
return dataOn ;
# endif /* E4MISC */
}
}
# ifdef E4MISC
return dataResult ;
# else
return dataOn ;
# endif
}
# ifdef P4ARGS_USED
# pragma argsused
# endif
DATA4 * tran4dataName ( TRAN4 * trans , const char * name , const long clientId , const int doPath )
{
DATA4 * dataOn ;
# ifdef E4MISC
DATA4 * dataResult ;
# endif
# ifndef S4CLIENT
char name1 [ 258 ] ;
# endif
# ifdef E4ANALYZE
if ( tran4verify ( trans , 1 ) < 0 )
return 0 ;
# endif
dataOn = 0 ;
# ifdef E4MISC
dataResult = 0 ;
# endif
# ifndef S4CLIENT
u4nameCurrent ( name1 , sizeof ( name1 ) , name ) ;
# ifdef S4CASE_SEN
u4nameExt ( name1 , sizeof ( name1 ) , " .dbf " , 0 ) ;
# else
u4nameExt ( name1 , sizeof ( name1 ) , " .DBF " , 0 ) ;
# endif
# endif
for ( ; ; )
{
dataOn = ( DATA4 * ) l4next ( tran4dataList ( trans ) , dataOn ) ;
if ( dataOn = = 0 )
break ;
if ( strcmp ( name , d4alias ( dataOn ) ) = = 0 ) /* try simple alias check */
{
# ifdef S4SERVER
if ( clientId ! = 0 )
dataOn - > clientId = clientId ;
# endif
# ifdef E4MISC
if ( dataResult ! = 0 )
{
error4 ( trans - > c4trans - > c4 , e4info , E83501 ) ;
return 0 ;
}
dataResult = dataOn ;
# else
return dataOn ;
# endif
}
# ifndef S4CLIENT
# ifdef E4MISC
else
# endif
/* otherwise, try file name check */
if ( doPath )
if ( strcmp ( name1 , dataOn - > dataFile - > file . name ) = = 0 )
{
# ifdef S4SERVER
if ( clientId ! = 0 )
dataOn - > clientId = clientId ;
# endif
# ifdef E4MISC
if ( dataResult ! = 0 )
{
error4 ( trans - > c4trans - > c4 , e4info , E83501 ) ;
return 0 ;
}
dataResult = dataOn ;
# else
return dataOn ;
# endif
}
# endif
}
# ifdef E4MISC
return dataResult ;
# else
return dataOn ;
# endif
}
/* gets the data4 corresponding to the serverId, and sets the current clientId to clientId */
DATA4 * tran4data ( TRAN4 * trans , const long serverId , const long clientId )
{
DATA4 * dataOn ;
# ifdef E4MISC
DATA4 * dataResult ;
# endif
# ifdef S4SERVER
int rc = 0 ;
# endif
# ifdef E4ANALYZE
if ( tran4verify ( trans , 1 ) < 0 )
return 0 ;
# endif
dataOn = 0 ;
# ifdef E4MISC
dataResult = 0 ;
# endif
for ( ; ; )
{
dataOn = ( DATA4 * ) l4next ( tran4dataList ( trans ) , dataOn ) ;
if ( dataOn = = 0 )
break ;
if ( data4serverId ( dataOn ) = = serverId )
{
dataOn - > clientId = clientId ;
# ifdef E4MISC
if ( dataResult ! = 0 )
{
error4 ( trans - > c4trans - > c4 , e4info , E83501 ) ;
return 0 ;
}
dataResult = dataOn ;
# else
break ;
# endif
}
}
/*
# ifdef S4SERVER
# ifdef E4MISC
if ( dataResult ! = 0 )
rc = d4tagUniqueSync ( dataResult ) ;
# else
if ( dataOn ! = 0 )
rc = d4tagUniqueSync ( dataOn ) ;
# endif
if ( rc < 0 )
return 0 ;
# endif
*/
# ifdef E4MISC
return dataResult ;
# else
return dataOn ;
# endif
}
DATA4 * S4FUNCTION code4data ( CODE4 * c4 , const char * aliasName )
{
char buf [ 12 ] ;
# ifdef S4SERVER
RELATE4 * relate ;
# endif
# ifdef S4VBASIC
if ( c4parm_check ( c4 , 1 , E91102 ) )
return 0 ;
# endif /* S4VBASIC */
# ifdef E4PARM_HIGH
if ( c4 = = 0 | | aliasName = = 0 )
{
error4 ( c4 , e4parm_null , E91102 ) ;
return 0 ;
}
# endif
u4ncpy ( buf , aliasName , sizeof ( buf ) ) ;
# ifndef S4CASE_SEN
c4upper ( buf ) ;
# endif
# ifdef S4SERVER
if ( c4 - > currentRelation = = 0 )
return tran4dataName ( code4trans ( c4 ) , buf , 0L , 1 ) ;
relate = & ( c4 - > currentRelation - > relate ) ;
for ( ; ; )
{
if ( relate = = 0 )
return 0 ;
if ( strcmp ( aliasName , d4alias ( relate - > data ) ) = = 0 )
return relate - > data ;
if ( relate4next ( & relate ) = = 2 )
return 0 ;
}
# else
return tran4dataName ( code4trans ( c4 ) , buf , 0L , 0 ) ;
# endif
}
const char * code4version ( CODE4 * c4 )
{
char ver [ ] = " S4VERSION " ;
# ifdef E4PARM_HIGH
if ( c4 = = 0 )
{
error4 ( 0 , e4parm_null , E91111 ) ;
return 0 ;
}
# endif
if ( c4 - > version = = 0 )
{
c4 - > version = ( char * ) u4allocFree ( c4 , ( long ) sizeof ( ver ) ) ;
if ( c4 - > version = = 0 )
return 0 ;
memcpy ( c4 - > version , ver , sizeof ( ver ) ) ;
}
return c4 - > version ;
}
# ifdef S4CLIENT
/* used for testing only */
int S4FUNCTION code4catalogSet ( CODE4 * c4 , int catalogAdd , int catalogStatus )
{
CONNECTION4 * connection ;
CONNECTION4CATALOG_SET_INFO_IN infoIn ;
int rc ;
if ( c4 - > defaultServer ! = 0 )
{
connection = c4 - > defaultServer - > connect ;
connection4assign ( connection , CON4CATALOG , 0L , 0L ) ;
infoIn . catalogAdd = catalogAdd ;
infoIn . catalogStatus = catalogStatus ;
connection4addData ( connection , & infoIn , sizeof ( CONNECTION4CATALOG_SET_INFO_IN ) , 0 ) ;
connection4send ( connection ) ;
rc = connection4receive ( connection ) ;
if ( rc < 0 )
return rc ;
rc = connection4status ( connection ) ;
if ( rc < 0 )
connection4error ( connection , c4 , rc , 0 ) ;
return rc ;
}
return 0 ;
}
const char * S4FUNCTION code4serverName ( CODE4 * c4 )
{
# ifdef E4PARM_HIGH
if ( c4 = = 0 )
{
error4 ( 0 , e4parm_null , E91112 ) ;
return 0 ;
}
# endif
# ifdef S4OFF_COMMUNICATIONS
return 0 ;
# else
if ( c4 - > defaultServer = = 0 )
return 0 ;
return c4 - > defaultServer - > serverName ;
# endif
}
int S4FUNCTION code4indexFormat ( CODE4 * c4 )
{
# ifdef S4OFF_INDEX
return 0 ;
# else
CONNECTION4 * connection ;
int rc ;
# ifdef E4PARM_HIGH
if ( c4 = = 0 )
return error4 ( 0 , e4parm_null , E91110 ) ;
# endif
if ( c4 - > indexFormat ! = 0 )
return c4 - > indexFormat ;
if ( c4 - > defaultServer = = 0 )
return r4unknown ;
connection = c4 - > defaultServer - > connect ;
if ( connection = = 0 )
return r4unknown ;
connection4assign ( connection , CON4INDEX_FORMAT , 0L , 0L ) ;
connection4send ( connection ) ;
rc = connection4receive ( connection ) ;
if ( rc < 0 )
return error4stack ( c4 , rc , E91110 ) ;
rc = connection4status ( connection ) ;
if ( rc < 0 )
return connection4error ( connection , c4 , rc , E91110 ) ;
# ifdef E4MISC
switch ( rc )
{
case r4ndx :
case r4mdx :
case r4cdx :
case r4ntx :
break ;
default :
return error4 ( c4 , e4info , E81102 ) ;
}
# endif
c4 - > indexFormat = rc ;
return rc ;
# endif
}
/*#ifdef S4TESTING*/
/* for testing only, restarts the server if this is the last client, after
we disconnect */
int S4FUNCTION code4serverRestart ( CODE4 * c4 )
{
CONNECTION4 * connection ;
int rc ;
connection = c4 - > defaultServer - > connect ;
if ( connection = = 0 )
return error4 ( c4 , e4connection , E81102 ) ;
connection4assign ( connection , CON4RESTART , 0L , 0L ) ;
connection4send ( connection ) ;
rc = connection4receive ( connection ) ;
if ( rc < 0 )
return error4stack ( c4 , rc , E91110 ) ;
rc = connection4status ( connection ) ;
if ( rc < 0 )
return connection4error ( connection , c4 , rc , E91110 ) ;
return rc ;
}
/* for testing only, causes a server crash */
int S4FUNCTION code4serverCrash ( CODE4 * c4 )
{
CONNECTION4 * connection ;
int rc ;
connection = c4 - > defaultServer - > connect ;
if ( connection = = 0 )
return error4 ( c4 , e4connection , E81102 ) ;
connection4assign ( connection , CON4CRASH , 0L , 0L ) ;
connection4send ( connection ) ;
rc = connection4receive ( connection ) ;
if ( rc < 0 )
return error4stack ( c4 , rc , E91110 ) ;
rc = connection4status ( connection ) ;
if ( rc < 0 )
return connection4error ( connection , c4 , rc , E91110 ) ;
return rc ;
}
# else /* S4CLIENT */
# ifdef P4ARGS_USED
# pragma argsused
# endif
int S4FUNCTION code4indexFormat ( CODE4 * c4 )
{
# ifdef S4OFF_INDEX
return 0 ;
# else
# ifdef E4PARM_HIGH
if ( c4 = = 0 )
return error4 ( 0 , e4parm_null , E91110 ) ;
# endif
# ifdef S4MDX
return r4mdx ;
# endif
# ifdef S4FOX
return r4cdx ;
# endif
# ifdef S4CLIPPER
return r4ntx ;
# endif
# ifdef S4NDX
return r4ndx ;
# endif
# endif
}
# endif
# ifndef S4SERVER
# ifdef S4STAND_ALONE
# ifndef S4OFF_WRITE
# ifndef S4OFF_TRAN
int S4FUNCTION code4logCreate ( CODE4 * c4 , const char * fileName , const char * userId )
{
int rc ;
static char defaultUser [ ] = " PUBLIC " ;
# ifdef E4PARM_HIGH
if ( c4 = = 0 )
return error4 ( c4 , e4parm_null , E91013 ) ;
# endif
if ( userId = = 0 )
userId = defaultUser ;
else
if ( userId [ 0 ] = = 0 ) /* null string */
userId = defaultUser ;
if ( c4 - > c4trans . transFile ! = 0 )
return r4logOpen ;
if ( fileName = = 0 )
# ifdef S4CASE_SEN
fileName = " C4.log " ;
# else
fileName = " C4.LOG " ;
# endif
else
if ( fileName [ 0 ] = = 0 ) /* null string */
# ifdef S4CASE_SEN
fileName = " C4.log " ;
# else
fileName = " C4.LOG " ;
# endif
rc = code4transFileEnable ( & c4 - > c4trans , fileName , 1 ) ;
# ifndef S4UTILS
tran4addUser ( & c4 - > c4trans . trans , 0L , userId , ( unsigned short int ) strlen ( userId ) ) ;
# endif
return rc ;
}
const char * S4FUNCTION code4logFileName ( CODE4 * c4 )
{
# ifdef E4PARM_HIGH
if ( c4 = = 0 )
{
error4 ( c4 , e4parm_null , E91014 ) ;
return 0 ;
}
# endif
if ( c4 - > c4trans . transFile = = 0 )
return 0 ;
return c4 - > c4trans . transFile - > file . name ;
}
int S4FUNCTION code4logOpen ( CODE4 * c4 , const char * fileName , const char * userId )
{
int rc ;
static char defaultUser [ ] = " PUBLIC " ;
# ifdef E4PARM_HIGH
if ( c4 = = 0 )
return error4 ( c4 , e4parm_null , E91015 ) ;
# endif
if ( userId = = 0 )
userId = defaultUser ;
else
if ( userId [ 0 ] = = 0 ) /* null string */
userId = defaultUser ;
if ( c4 - > c4trans . transFile ! = 0 )
return r4logOpen ;
if ( fileName = = 0 )
# ifdef S4CASE_SEN
fileName = " C4.log " ;
# else
fileName = " C4.LOG " ;
# endif
else
if ( fileName [ 0 ] = = 0 ) /* null string */
# ifdef S4CASE_SEN
fileName = " C4.log " ;
# else
fileName = " C4.LOG " ;
# endif
rc = code4transFileEnable ( code4trans ( c4 ) - > c4trans , fileName , 0 ) ;
# ifndef S4UTILS
tran4addUser ( & c4 - > c4trans . trans , 0L , userId , ( unsigned short int ) strlen ( userId ) ) ;
# endif
return rc ;
}
void S4FUNCTION code4logOpenOff ( CODE4 * c4 )
{
# ifdef E4PARM_HIGH
if ( c4 = = 0 )
{
error4 ( c4 , e4parm_null , E91016 ) ;
return ;
}
# endif
c4 - > logOpen = 0 ;
}
# endif /* S4OFF_TRAN */
# endif /* S4OFF_WRITE */
# endif /* S4STAND_ALONE */
# endif /* S4SERVER */
const char * S4FUNCTION code4indexExtension ( CODE4 * c4 )
{
if ( c4 - > indexExtension [ 0 ] = = 0 )
switch ( code4indexFormat ( c4 ) )
{
case r4mdx :
# ifdef S4CASE_SEN
memcpy ( c4 - > indexExtension , " mdx " , 3 ) ;
# else
memcpy ( c4 - > indexExtension , " MDX " , 3 ) ;
# endif
break ;
case r4cdx :
# ifdef S4CASE_SEN
memcpy ( c4 - > indexExtension , " cdx " , 3 ) ;
# else
memcpy ( c4 - > indexExtension , " CDX " , 3 ) ;
# endif
break ;
case r4ntx :
# ifdef S4CASE_SEN
memcpy ( c4 - > indexExtension , " ntx " , 3 ) ;
# else
memcpy ( c4 - > indexExtension , " NTX " , 3 ) ;
# endif
break ;
case r4ndx :
# ifdef S4CASE_SEN
memcpy ( c4 - > indexExtension , " ndx " , 3 ) ;
# else
memcpy ( c4 - > indexExtension , " NDX " , 3 ) ;
# endif
break ;
default :
return 0 ;
}
return c4 - > indexExtension ;
}
# ifdef S4FOX
# define S4FORMAT 1
# endif
# ifdef S4CLIPPER
# ifdef S4FORMAT
# error Choose only one CodeBase index file compatibility option.
# endif
# define S4FORMAT 2
# endif
# ifdef S4MDX
# ifdef S4FORMAT
# error Choose only one CodeBase index file compatibility option.
# endif
# define S4FORMAT 4
# endif
# ifdef S4CLIENT
# ifndef S4FORMAT
# define S4FORMAT 0
# endif
# else
# ifndef S4FORMAT
# error You must define either S4FOX, S4CLIPPER or S4MDX
# endif
# endif
# ifdef S4CLIENT
# define S4CLIENT_VAL 0x8
# else
# define S4CLIENT_VAL 0x0
# endif
# ifdef S4DOS
# define S4OPERATING 0x10
# endif
# ifdef S4WIN16
# ifdef S4OPERATING
# error Choose only one of CodeBase switches S4DOS, S4WIN16, S4WIN32, S4OS2, S4UNIX, S4MACINTOSH or S4PASCAL_WIN
# endif
# define S4OPERATING 0x20
# endif
# ifdef S4WIN32
# ifdef S4OPERATING
# error Choose only one of CodeBase switches S4DOS, S4WIN16, S4WIN32, S4OS2, S4UNIX, S4MACINTOSH or S4PASCAL_WIN
# endif
# define S4OPERATING 0x40
# endif
# ifdef S4STAND_ALONE
# define S4STAND_ALONE_VAL 0x80
# else
# define S4STAND_ALONE_VAL 0x0
# endif
# ifdef S4OS2
# ifdef S4OPERATING
# error Choose only one of CodeBase switches S4DOS, S4WIN16, S4WIN32, S4OS2, S4UNIX, S4MACINTOSH or S4PASCAL_WIN
# endif
# define S4OPERATING 0x100
# endif
# ifdef S4UNIX
# ifdef S4OPERATING
# error Choose only one of CodeBase switches S4DOS, S4WIN16, S4WIN32, S4OS2, S4UNIX, S4MACINTOSH or S4PASCAL_WIN
# endif
# define S4OPERATING 0x200
# endif
/* */
/* */
/* */
/* */
/* */
/* */
# ifdef S4PASCAL_WIN
# ifdef S4OPERATING
# error Choose only one of CodeBase switches S4DOS, S4WIN16, S4WIN32, S4OS2, S4UNIX, S4MACINTOSH or S4PASCAL_WIN
# endif
# define S4OPERATING 0x800
# endif
# ifndef S4OPERATING
# error Must choose one of CodeBase switches S4DOS, S4WIN16, S4WIN32, S4OS2, S4UNIX, S4MACINTOSH or S4PASCAL_WIN
# endif
# ifdef S4CB51
# define S4CB51_VAL 0x1000
# else
# define S4CB51_VAL 0
# endif
# ifdef S4SAFE
# define S4SAFE_VAL 0x2000
# else
# define S4SAFE_VAL 0
# endif
# ifdef S4LOCK_HOOK
# define S4LOCK_HOOK_VAL 0x4000
# else
# define S4LOCK_HOOK_VAL 0
# endif
# ifdef S4MAX
# define S4MAX_VAL 0x8000
# else
# define S4MAX_VAL 0
# endif
# ifdef S4TIMEOUT_HOOK
# define S4TIMEOUT_HOOK_VAL 0x10000
# else
# define S4TIMEOUT_HOOK_VAL 0
# endif
# ifdef E4ANALYZE
# define E4ANALYZE_VAL 0x20000
# else
# define E4ANALYZE_VAL 0
# endif
# ifdef E4DEBUG
# define E4DEBUG_VAL 0x40000
# else
# define E4DEBUG_VAL 0
# endif
# ifdef E4HOOK
# define E4HOOK_VAL 0x80000
# else
# define E4HOOK_VAL 0
# endif
# ifdef E4LINK
# define E4LINK_VAL 0x100000
# else
# define E4LINK_VAL 0
# endif
# ifdef E4MISC
# define E4MISC_VAL 0x200000
# else
# define E4MISC_VAL 0
# endif
# ifdef E4OFF
# define E4OFF_VAL 0x400000
# else
# define E4OFF_VAL 0
# endif
# ifdef E4OFF_STRING
# define E4OFF_STRING_VAL 0x800000
# else
# define E4OFF_STRING_VAL 0
# endif
# ifdef E4PARM_HIGH
# define E4PARM_HIGH_VAL 0x1000000
# else
# define E4PARM_HIGH_VAL 0
# endif
# ifdef E4PAUSE
# define E4PAUSE_VAL 0x2000000
# else
# define E4PAUSE_VAL 0
# endif
# ifdef E4STOP
# define E4STOP_VAL 0x4000000
# else
# define E4STOP_VAL 0
# endif
# ifdef E4STOP_CRITICAL
# define E4STOP_CRITICAL_VAL 0x8000000
# else
# define E4STOP_CRITICAL_VAL 0
# endif
# ifdef S4OFF_INDEX
# define S4OFF_INDEX_VAL 0x10000000
# else
# define S4OFF_INDEX_VAL 0
# endif
# ifdef S4OFF_MEMO
# define S4OFF_MEMO_VAL 0x20000000
# else
# define S4OFF_MEMO_VAL 0
# endif
# ifdef S4OFF_MULTI
# define S4OFF_MULTI_VAL 0x40000000
# else
# define S4OFF_MULTI_VAL 0
# endif
# ifdef S4OFF_OPTIMIZE
# define S4OFF_OPTIMIZE_VAL 0x80000000
# else
# define S4OFF_OPTIMIZE_VAL 0
# endif
/*
no room for these switches
# ifdef S4OFF_REPORT
# define S4OFF_REPORT_VAL 0x100000000
# else
# define S4OFF_REPORT_VAL 0
# endif
# ifdef S4OFF_TRAN
# define S4OFF_TRAN_VAL 0x200000000
# else
# define S4OFF_TRAN_VAL 0
# endif
# ifdef S4OFF_WRITE
# define S4OFF_WRITE_VAL 0x400000000
# else
# define S4OFF_WRITE_VAL 0
# endif
*/
long S4FUNCTION u4switch ( )
{
return ( long ) ( S4FORMAT + S4OPERATING + S4CB51_VAL + S4SAFE_VAL +
S4LOCK_HOOK_VAL + S4MAX_VAL + S4TIMEOUT_HOOK_VAL + E4ANALYZE_VAL +
E4DEBUG_VAL + E4HOOK_VAL + E4LINK_VAL + E4MISC_VAL + E4OFF_VAL +
E4OFF_STRING_VAL + E4PARM_HIGH_VAL + E4PAUSE_VAL + E4STOP_VAL +
E4STOP_CRITICAL_VAL + S4OFF_INDEX_VAL + S4OFF_MEMO_VAL +
S4OFF_MULTI_VAL + S4OFF_OPTIMIZE_VAL +
/* S4OFF_REPORT_VAL + S4OFF_TRAN_VAL + S4OFF_WRITE_VAL + no room */
S4CLIENT_VAL + S4STAND_ALONE_VAL ) ;
}
# ifdef S4VB_DOS
DATA4 * d4data_v ( CODE4 * c4 , char * alias )
{
return code4data ( c4 , c4str ( alias ) ) ;
}
# endif
/*#ifdef S4CB51*/
# ifndef S4SERVER
# ifdef S4DLL_BUILD
# ifndef S4PASCAL_DOS
# define CTRL4SERVERNAMESIZE 260
/*Structures for CodeControls Functions */
typedef struct ctrl4code_tag
{
LINK4 link ;
HINSTANCE hInst ;
CODE4 * code ;
int alloc ;
LIST4 form ;
# ifdef S4CLIENT
char ServerName [ CTRL4SERVERNAMESIZE ] ;
# endif
} CTRL4CODE ;
/***************************************************************\
\ * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
int S4FUNCTION ctrl4addCode ( HINSTANCE hInst ) ; /*450*/
void S4FUNCTION ctrl4codeListInit ( void ) ; /*451*/
void S4FUNCTION ctrl4freeCtrlNode ( CTRL4CODE * node ) ;
void S4FUNCTION ctrl4freeCodeList ( void ) ; /*452*/
CTRL4CODE * S4FUNCTION ctrl4getCtrlCode ( HINSTANCE hInst ) ; /*453*/
void S4FUNCTION ctrl4getServerName ( HINSTANCE hInst , char * serverName , int strLen ) ; /* 5 oh something */
void S4FUNCTION ctrl4setServerName ( HINSTANCE hInst , char * serverName ) ; /* 5 oh something */
void S4FUNCTION ctrl4initVBX ( CODE4 * code , HINSTANCE hInstance , int initialize ) ; /*454*/
void S4FUNCTION ctrl4initVBXUndo ( CODE4 * code , HINSTANCE hInstance ) ; /*455*/
/***************************************************************\
* List Containing CODE4 and hInstance
* structures for CodeControls
\ * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
LIST4 ctrl4codeListVBX ;
/***************************************************************\
\ * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
void S4FUNCTION ctrl4codeListInit ( void )
{
/*memset( &ctrl4codeListVBX,0,sizeof( LIST4 ) );*/
}
/***************************************************************\
\ * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
int S4FUNCTION ctrl4addCode ( HINSTANCE hInst )
{
CTRL4CODE * node ;
if ( ! hInst )
return - 1 ;
node = ( CTRL4CODE * ) u4alloc ( sizeof ( CTRL4CODE ) ) ;
if ( node )
{
node - > hInst = hInst ;
node - > alloc = 1 ;
node - > code = NULL ;
l4add ( & ctrl4codeListVBX , node ) ;
}
return 0 ;
}
/***************************************************************\
\ * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
void S4FUNCTION ctrl4freeCtrlNode ( CTRL4CODE * node )
{
if ( node )
{
l4remove ( & ctrl4codeListVBX , node ) ;
if ( node - > code )
{
code4initUndo ( node - > code ) ;
u4free ( node - > code ) ;
}
u4free ( node ) ;
}
}
/***************************************************************\
\ * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
void S4FUNCTION ctrl4freeCodeList ( void )
{
CTRL4CODE * node ;
for ( node = ( CTRL4CODE * ) l4first ( & ctrl4codeListVBX ) ; node ! = NULL ; )
{
l4remove ( & ctrl4codeListVBX , node ) ;
if ( node - > code & & node - > alloc )
{
code4initUndo ( node - > code ) ;
u4free ( node - > code ) ;
}
u4free ( node ) ;
node = ( CTRL4CODE * ) l4next ( & ctrl4codeListVBX , node ) ;
}
}
/***************************************************************\
\ * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
CTRL4CODE * S4FUNCTION ctrl4getCtrlCode ( HINSTANCE hInst )
{
CTRL4CODE * node , * returnnode = NULL ;
if ( hInst = = 0 )
return NULL ;
for ( node = ( CTRL4CODE * ) l4first ( & ctrl4codeListVBX ) ; node ! = NULL ; )
{
if ( node - > hInst = = hInst )
{
returnnode = node ;
node = NULL ;
}
else
node = ( CTRL4CODE * ) l4next ( & ctrl4codeListVBX , node ) ;
}
return returnnode ;
}
/***************************************************************\
\ * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
void S4FUNCTION ctrl4initVBXUndo ( CODE4 * code , HINSTANCE hInstance )
{
CTRL4CODE * node ;
node = ctrl4getCtrlCode ( hInstance ) ;
if ( node )
{
if ( code ! = node - > code )
code4initUndo ( code ) ;
code4initUndo ( node - > code ) ;
if ( node - > alloc )
{
u4free ( node - > code ) ;
}
l4remove ( & ctrl4codeListVBX , node ) ;
u4free ( node ) ;
}
}
/***************************************************************\
\ * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
void S4FUNCTION ctrl4initVBX ( CODE4 * code , HINSTANCE hInstance , int initialize )
{
int dealloc ;
CODE4 * oldcode ;
CTRL4CODE * node ;
if ( code )
{
node = ctrl4getCtrlCode ( hInstance ) ;
if ( ! node )
{
ctrl4addCode ( hInstance ) ;
node = ctrl4getCtrlCode ( hInstance ) ;
if ( node )
node - > alloc = 0 ;
}
if ( node )
{
if ( node - > code )
{
dealloc = 0 ;
if ( node - > alloc )
dealloc = IDYES ;
else
dealloc = MessageBox ( 0 ,
" Warning! Detected two calls to ctrl4init \n without intervening call to ctrl4initUndo! \n \n Ok to free previously allocated CODE4 memory ? " , " Multiple CODE4 Detected "
, MB_YESNO | MB_TASKMODAL | MB_ICONEXCLAMATION ) ;
if ( dealloc = = IDYES )
{
oldcode = node - > code ;
ctrl4initVBXUndo ( node - > code , hInstance ) ;
u4free ( oldcode ) ;
node - > code = NULL ;
}
}
node - > alloc = 0 ;
node - > code = code ;
if ( initialize )
{
# ifdef S4CLIENT
char setProtocol = 0 ;
/* must choose a default protocol for C/C++ client/server dll
if user will be calling ctrl4init ( ) */
# ifndef S4VBASIC
# ifndef S4PASCAL
setProtocol = 1 ;
# endif
# endif
if ( setProtocol )
code4initLow ( code , " C4SPX.DLL " , S4VERSION ) ;
else
# ifdef S4SPX
code4initLow ( code , " C4SPX.DLL " , S4VERSION ) ;
# else
code4initLow ( code , " C4SOCK.DLL " , S4VERSION ) ;
# endif
# else
code4init ( code ) ;
# endif
}
}
}
}
# ifdef S4CLIENT
void S4FUNCTION ctrl4getServerName ( HINSTANCE hInst , char * serverName , int strLen ) /*5 oh something*/
{
CTRL4CODE * code = NULL ;
if ( ! hInst )
return ;
if ( ! serverName | | strLen < = 0 )
return ;
memset ( serverName , 0 , strLen ) ;
code = ctrl4getCtrlCode ( hInst ) ;
if ( code )
{
memcpy ( serverName , code - > ServerName , min ( strLen , CTRL4SERVERNAMESIZE ) ) ;
}
return ;
}
void S4FUNCTION ctrl4setServerName ( HINSTANCE hInst , char * serverName ) /*5 oh something*/
{
CTRL4CODE * code = NULL ;
if ( ! hInst )
return ;
if ( ! serverName )
return ;
code = ctrl4getCtrlCode ( hInst ) ;
if ( code )
{
memcpy ( code - > ServerName , serverName , CTRL4SERVERNAMESIZE ) ;
}
return ;
}
# else
# ifdef S4STAND_ALONE
# ifdef P4ARGS_USED
# pragma argsused
# endif
void S4FUNCTION ctrl4getServerName ( HINSTANCE hInst , char * serverName , int strLen ) /*5 oh something*/
{
return ;
}
# ifdef P4ARGS_USED
# pragma argsused
# endif
void S4FUNCTION ctrl4setServerName ( HINSTANCE hInst , char * serverName ) /*5 oh something*/
{
return ;
}
# endif
# endif /* S4CLIENT */
# endif /* S4PASCAL_DOS */
# endif /* S4DLL_BUILD */
# endif /* S4SERVER */
/*#endif */ /* S4CB51 */
# ifdef S4STAND_ALONE
/* assumes that code4tranInitLow has already been called internally ( code4init ) */
# ifndef S4OFF_TRAN
# ifndef S4OFF_WRITE
int S4FUNCTION code4tranInit2 ( CODE4 * c4 , const char * fileName , const char * charId )
{
int rc ;
# ifdef E4PARM_LOW
if ( c4 = = 0 | | fileName = = 0 )
return error4 ( 0 , e4parm_null , E93801 ) ;
# endif
c4 - > c4trans . c4 = c4 ;
rc = code4transFileEnable ( & c4 - > c4trans , fileName , 0 ) ;
if ( rc < 0 )
return rc ;
c4 - > c4trans . trans . c4trans = & c4 - > c4trans ;
if ( charId ! = 0 )
return tran4addUser ( & c4 - > c4trans . trans , 0L , charId , ( unsigned short ) strlen ( charId ) ) ;
return 0 ;
}
# endif
# endif
int S4FUNCTION code4tranInit ( CODE4 * c4 )
{
# ifdef E4PARM_LOW
if ( c4 = = 0 )
return error4 ( 0 , e4parm_null , E93802 ) ;
# endif
c4 - > c4trans . c4 = c4 ;
c4 - > c4trans . trans . c4trans = & c4 - > c4trans ;
tran4dataListSet ( & c4 - > c4trans . trans , & c4 - > c4trans . trans . localDataList ) ;
return 0 ;
}
# endif
# ifdef S4CLIENT
# ifndef S4INLINE
int S4FUNCTION code4tranInit2 ( CODE4 * c4 , const char * fileName , const char * charId )
{
# ifdef E4PARM_LOW
if ( c4 = = 0 | | fileName = = 0 )
return error4 ( 0 , e4parm_null , E93801 ) ;
# endif
return 0 ;
}
# endif
int S4FUNCTION code4tranInit ( CODE4 * c4 )
{
# ifdef E4PARM_LOW
if ( c4 = = 0 )
return error4 ( 0 , e4parm_null , E93802 ) ;
# endif
# ifndef S4OFF_TRAN
if ( code4transEnabled ( c4 ) )
return 0 ;
# endif
c4 - > c4trans . c4 = c4 ;
c4 - > c4trans . trans . c4trans = & c4 - > c4trans ;
# ifndef S4OFF_TRAN
c4 - > c4trans . enabled = 1 ;
# endif
tran4dataListSet ( & c4 - > c4trans . trans , & c4 - > c4trans . trans . localDataList ) ;
return 0 ;
}
# endif
# ifndef S4OFF_TRAN
# ifndef S4OFF_WRITE
# ifdef S4CLIENT
# ifndef S4INLINE
void code4tranInitUndo ( CODE4 * c4 )
{
return ;
}
# endif /* S4INLINE */
# else
int code4tranInitUndoLow ( TRAN4 * t4 , const long clientId )
{
int rc ;
if ( t4 = = 0 )
return 0 ;
if ( t4 - > c4trans - > enabled = = 1 & & t4 - > userId [ 0 ] ! = 0 ) /* if it has been initialized */
{
rc = tran4set ( t4 , t4 - > currentTranStatus , - 1L , clientId , TRAN4INIT_UNDO , 0 , 0L , 0L ) ;
if ( rc < 0 )
return rc ;
if ( tran4lowAppend ( t4 , 0 ) ! = 0 )
return e4transAppend ;
memset ( t4 - > userId , 0 , sizeof ( t4 - > userId ) ) ;
}
t4 - > dataPos = 0 ;
return 0 ;
}
# ifdef S4STAND_ALONE
void code4tranInitUndo ( CODE4 * c4 )
{
# ifdef E4PARM_LOW
if ( c4 = = 0 )
{
error4 ( 0 , e4parm_null , E93804 ) ;
return ;
}
# endif
if ( code4transEnabled ( c4 ) )
code4transInitUndo ( & c4 - > c4trans ) ;
}
# endif /* S4STAND_ALONE */
# endif
# endif
# endif