/* i4lock.c (c)Copyright Sequiter Software Inc., 1988-1996. All rights reserved. */ #include "d4all.h" #ifndef S4UNIX #ifdef __TURBOC__ #pragma hdrstop #endif #endif #ifndef S4INDEX_OFF #ifndef S4CLIENT #ifdef N4OTHER #include #endif /* #ifdef E4ANALYZE_ALL static int blockFileCompare( B4BLOCK *b4 ) { B4BLOCK *deb4block ; long blockNo ; int rc ; deb4block = (B4BLOCK *)mem4alloc2( b4->tag->index->block_memory, b4->tag->codeBase ) ; if ( deb4block == 0 ) return -1 ; blockNo = b4->file_block ; rc = 0 ; #ifdef S4MDX if ( file4readAll( &b4->tag->index->file, I4MULTIPLY * blockNo, &deb4block->n_keys, deb4block->tag->index->header.blockRw ) < 0 ) rc = -1 ; else rc = c4memcmp( deb4block->n_keys, b4->n_keys, deb4block->tag->index->header.blockRw ) ; #endif #ifdef S4NDX if ( file4readAll( &b4->tag->file, I4MULTIPLY * blockNo, &deb4block->n_keys, B4BLOCK_SIZE ) < 0 ) rc = -1 ; else rc = c4memcmp( deb4block->n_keys, b4->n_keys, B4BLOCK_SIZE ) ; #endif #ifdef S4FOX if ( file4readAll( &b4->tag->index->file, I4MULTIPLY * blockNo, &deb4block->header, B4BLOCK_SIZE) < 0 ) rc = -1 ; else rc = c4memcmp( &deb4block->header, &b4->header, B4BLOCK_SIZE ) ; #endif #ifdef S4CLIPPER if ( file4readAll( &b4->tag->file, blockNo, &deb4block->n_keys, B4BLOCK_SIZE ) < 0 ) rc = -1 ; else rc = c4memcmp( deb4block->n_keys, b4->n_keys, B4BLOCK_SIZE ) ; #endif mem4free( b4->tag->index->block_memory, deb4block ) ; return rc ; } static int indexVersionVerify( INDEX4 *i4 ) { TAG4 *tagOn ; B4BLOCK *blockOn ; for ( tagOn = 0 ;; ) { tagOn = (TAG4 *)l4next( &i4->tags, tagOn ) ; if ( tagOn == 0 ) break ; for ( blockOn = 0 ;; ) { blockOn = (B4BLOCK *)l4next( &tagOn->blocks, blockOn ) ; if ( blockOn == 0 ) break ; if ( blockFileCompare( blockOn ) != 0 ) return -1 ; } for ( blockOn = 0 ;; ) { blockOn = (B4BLOCK *)l4next( &tagOn->saved, blockOn ) ; if ( blockOn == 0 ) break ; if ( blockFileCompare( blockOn ) != 0 ) return -1 ; } } return 0 ; } #endif */ #ifdef N4OTHER int tfile4lockTest( TAG4FILE *t4 ) { #ifdef S4OFF_MULTI return 1 ; #else if ( t4->file.lowAccessMode != OPEN4DENY_NONE ) return 1 ; return ( t4->fileLocked > 0 ? 1 : 0 ) ; #endif } #else #ifdef P4ARGS_USED #pragma argsused #endif int index4lockTest( INDEX4FILE *i4 ) { #ifdef S4OFF_MULTI return 1 ; #else if ( i4->file.lowAccessMode != OPEN4DENY_NONE ) return 1 ; return ( i4->fileLocked ? 1 : 0 ) ; #endif } #endif #ifdef N4OTHER int i4lock( INDEX4 *index ) { #ifdef S4OFF_MULTI return 1 ; #else return dfile4lockIndex( index->data->dataFile, data4serverId( index->data ) ) ; #endif } int tfile4unlock( TAG4FILE *t4, const long serverId ) { #ifndef S4OFF_MULTI int rc ; #ifdef E4PARM_LOW if ( t4 == 0 ) return error4( 0, e4parm, E95606 ) ; #endif if ( t4->fileLocked == 0 ) return 0 ; if ( t4->fileLocked == serverId || ( t4->fileLocked != 0 && serverId == 0 ) ) { #ifndef S4OFF_WRITE if ( tfile4update( t4 ) < 0 ) return -1 ; #endif rc = file4unlock( &t4->file, L4LOCK_POS, L4LOCK_POS ) ; if ( rc < 0 ) return rc ; t4->fileLocked = 0 ; return rc ; } #endif return 0 ; } int tfile4lock( TAG4FILE *t4, const long serverId ) { #ifndef S4OFF_MULTI int rc ; #ifdef E4PARM_LOW if ( t4 == 0 ) return error4( 0, e4parm_null, E95607 ) ; if ( serverId == 0 ) return error4( t4->codeBase, e4parm_null, E95607 ) ; #endif if ( error4code( t4->codeBase ) < 0 ) return e4codeBase ; if ( t4->fileLocked == serverId ) /* Already locked */ return 0 ; if ( t4->fileLocked != 0 ) /* Already locked by another client */ return r4locked ; rc = file4lock( &t4->file, L4LOCK_POS, L4LOCK_POS ) ; if ( rc ) return rc ; #ifndef S4OPTIMIZE_OFF file4refresh( &t4->file ) ; /* make sure all up to date */ #endif if ( file4len( &t4->file ) != 0 ) /* if the file exists (not being created), update header */ if ( tfile4versionCheck( t4, 1, 1 ) < 0 ) { #ifdef S4MDX file4unlock( &t4->file, L4LOCK_POS - 1L, 1L ) ; #endif #ifdef S4FOX file4unlock( &t4->file, L4LOCK_POS, 1L ) ; #endif return -1 ; } #ifdef S4FOX t4->eof = file4len( &t4->file ) ; #endif t4->fileLocked = serverId ; /* this flag must be set after the version_check is complete */ #endif /* S4OFF_MULTI */ return 0 ; } #else #ifndef S4OFF_MULTI static INDEX4 *code4index( CODE4 *cb, const long id, const char *name ) { DATA4 *data ; #ifdef S4SERVER SERVER4CLIENT *client ; #endif INDEX4 *index ; LIST4 *list ; if ( cb == 0 || id == 0 ) { error4( cb, e4parm_null, E95601 ) ; return 0 ; } #ifdef S4MEM_DBF if ( cb->server == 0 ) { return mem4index() ; } else #endif #ifdef S4SERVER for( client = 0 ;; ) { client = (SERVER4CLIENT *)l4next( &cb->server->clients, client ) ; if ( client == 0 ) break ; list = tran4dataList( &client->trans ) ; #else list = tran4dataList( &cb->c4trans.trans ) ; #endif for( data = 0 ;; ) { data = (DATA4 *)l4next( list, data ) ; if ( data == 0 ) break ; if ( data4serverId( data ) == id ) { for( index = 0 ;; ) { index = (INDEX4 *)l4next( &data->indexes, index ) ; if ( index == 0 ) return 0 ; if ( strcmp( name, index->indexFile->file.name ) == 0 ) return index ; } } } #ifdef S4SERVER } #endif #ifndef S4OFF_CATALOG if ( cb->catalog != 0 ) { data = cb->catalog->data ; if ( data != 0 ) if ( data4serverId( data ) == id ) /* maybe the catalog file */ for( index = 0 ;; ) { index = (INDEX4 *)l4next( &data->indexes, index ) ; if ( index == 0 ) return 0 ; if ( strcmp( name, index->indexFile->file.name ) == 0 ) return index ; } } #endif return 0 ; } #endif /* S4OFF_MULTI */ #ifdef P4ARGS_USED #pragma argsused #endif int index4lock( INDEX4FILE *i4, const long serverId ) { #ifndef S4OFF_MULTI int rc ; INDEX4 *index ; #ifdef E4PARM_LOW if ( i4 == 0 ) return error4( 0, e4parm_null, E95602 ) ; if ( serverId == 0 ) return error4( i4->codeBase, e4parm_null, E95602 ) ; #endif if ( error4code( i4->codeBase ) < 0 ) return e4codeBase ; if ( i4->fileLocked == serverId ) /* Already locked */ return 0 ; if ( i4->fileLocked != 0 ) /* Already locked by another client */ return r4locked ; #ifdef S4MDX rc = file4lock( &i4->file, L4LOCK_POS - 1L, 1L ) ; #endif #ifdef S4FOX rc = file4lock( &i4->file, L4LOCK_POS, 1L ) ; #endif if ( rc ) return rc ; #ifndef S4OPTIMIZE_OFF file4refresh( &i4->file ) ; /* make sure all up to date */ #endif index = code4index( i4->codeBase, serverId, i4->file.name ) ; if ( index != 0 && file4len( &i4->file ) != 0 ) /* if the file exists (not being created), update header */ if ( i4versionCheck( index, 1, 1 ) < 0 ) { #ifdef S4MDX file4unlock( &i4->file, L4LOCK_POS - 1L, 1L ) ; #endif #ifdef S4FOX file4unlock( &i4->file, L4LOCK_POS, 1L ) ; #endif return -1 ; } #ifdef S4FOX i4->eof = file4len( &i4->file ) ; #endif i4->fileLocked = serverId ; /* this flag must be set after the version_check is complete */ #endif return 0 ; } int i4unlock( INDEX4 *i4 ) { return index4unlock( i4->indexFile, data4serverId( i4->data ) ) ; } #ifdef P4ARGS_USED #pragma argsused #endif int index4unlock( INDEX4FILE *i4, const long serverId ) { #ifndef S4OFF_MULTI int rc ; #ifdef E4PARM_LOW if ( i4 == 0 ) return error4( 0, e4parm, E95603 ) ; #endif if ( i4->fileLocked == 0 ) return 0 ; if ( i4->fileLocked == serverId || ( i4->fileLocked != 0 && serverId == 0 ) ) { #ifndef S4OFF_WRITE if ( index4update( i4 ) < 0 ) return -1 ; #endif #ifdef S4MDX rc = file4unlock( &i4->file, L4LOCK_POS - 1L, 1L ) ; #else #ifdef S4FOX rc = file4unlock( &i4->file, L4LOCK_POS, 1L ) ; #else #error index format missing #endif #endif if ( rc < 0 ) return rc ; i4->fileLocked = 0 ; return 0 ; } #endif return 0 ; } #endif /* N4OTHER */ #ifdef N4OTHER /* unlocks all the corresponding tag files */ int i4unlock( INDEX4 *i4 ) { #ifdef S4OFF_MULTI return 0 ; #else int rc, save_rc = 0, setUnlock ; TAG4 *tagOn ; TAG4FILE *tagFileOn ; #ifdef S4VBASIC if ( c4parm_check( i4, 0, E95605 ) ) return -1 ; #endif #ifdef E4PARM_HIGH if ( i4 == 0 ) return error4( i4->codeBase, e4parm, E95605 ) ; #endif if ( i4->data->dataFile->indexLocked ) { #ifndef S4OFF_WRITE if ( i4update( i4 ) < 0 ) return -1 ; #endif for( tagOn = 0 ;; ) { tagOn = (TAG4 *)l4next( &i4->tags, tagOn ) ; if ( tagOn == 0 ) break ; rc = 0 ; if ( tagOn->tagFile->fileLocked == data4serverId( i4->data ) ) { rc = file4unlock( &tagOn->tagFile->file, L4LOCK_POS, L4LOCK_POS ) ; if ( rc ) save_rc = rc ; else tagOn->tagFile->fileLocked = 0 ; } } if ( save_rc == 0 ) { setUnlock = 1 ; for ( tagFileOn = 0 ;; ) { tagFileOn = (TAG4FILE *)l4next( &i4->data->dataFile->tagfiles, tagFileOn ) ; if ( tagFileOn == 0 ) break ; if ( tagFileOn->fileLocked != 0 ) /* positive value gives serverId */ { setUnlock = 0 ; break ; } } if ( setUnlock == 1 ) i4->data->dataFile->indexLocked = 0 ; } } return save_rc ; #endif } #endif /* N4OTHER */ #endif /* S4CLIENT */ #endif /* S4INDEX_OFF */