2595 lines
		
	
	
		
			60 KiB
		
	
	
	
		
			C
		
	
	
		
			Executable File
		
	
	
	
	
			
		
		
	
	
			2595 lines
		
	
	
		
			60 KiB
		
	
	
	
		
			C
		
	
	
		
			Executable File
		
	
	
	
	
| /* 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], 1Eh
 | |
|       jb      NoChange
 | |
|    }
 | |
| 
 | |
|    DoChange:
 | |
|       asm
 | |
|       {
 | |
|          mov     ax, 5801h      /*; Set last fit allocation*/
 | |
|          mov     bx, 2
 | |
|          int     21h
 | |
|          jc      BadInit
 | |
| 
 | |
|          mov     ah, 67h        /*; Expand handle table*/
 | |
|          mov     bx, _nfile
 | |
|          int     21h
 | |
|          jc      BadInit
 | |
| 
 | |
|          mov     ax, 5801h      /*; Set first fit allocation*/
 | |
|          mov     bx, 0
 | |
|          int     21h
 | |
|          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] ;
 | |
|    int n;
 | |
|    #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
 | |
| 
 | |
|     ***********************************************************************/
 | |
|    
 | |
|    #ifdef S4WINDOWS
 | |
|      n = SetHandleCount(40);
 | |
|    #endif
 | |
|    #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\nwithout intervening call to ctrl4initUndo!\n\nOk 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
 |