/* i4check.c (c)Copyright Sequiter Software Inc., 1988-1996. All rights reserved. */ #include "d4all.h" #ifndef S4UNIX #ifdef __TURBOC__ #pragma hdrstop #endif #endif #ifdef S4CLIENT int S4FUNCTION d4check( DATA4 *d4 ) { #ifdef S4INDEX_OFF return 0 ; #else CONNECTION4 *connection ; int rc ; CONNECTION4CHECK_INFO_OUT *out ; #ifdef E4PARM_HIGH if ( d4 == 0 ) return error4( 0, e4parm_null, E95702 ) ; #endif #ifndef S4OFF_MULTI #ifdef S4SERVER rc = dfile4lockFile( d4->dataFile, d4->currentClientId, d4->serverId ) ; /* returns -1 if error4code( codeBase ) < 0 */ #else rc = d4lockFile( d4 ) ; /* returns -1 if error4code( codeBase ) < 0 */ #endif if ( rc ) return rc ; #endif connection = d4->dataFile->connection ; if ( connection == 0 ) return e4connection ; connection4assign( connection, CON4CHECK, data4clientId( d4 ), data4serverId( d4 ) ) ; connection4send( connection ) ; rc = connection4receive( connection ) ; if ( rc < 0 ) return rc ; rc = connection4status( connection ) ; if ( rc != 0 ) return connection4error( connection, d4->codeBase, rc, E95702 ) ; if ( connection4len( connection ) != sizeof( CONNECTION4CHECK_INFO_OUT ) ) return error4( d4->codeBase, e4packetLen, E95702 ) ; out = (CONNECTION4CHECK_INFO_OUT *)connection4data( connection ) ; if ( out->lockedDatafile == 1 ) d4->dataFile->fileLock = d4 ; return 0 ; #endif /* S4INDEX_OFF */ } #else #ifndef S4INDEX_OFF typedef struct { F4FLAG flag ; TAG4FILE *tag ; char *oldKey ; long oldRec ; long numRecs ; int doCompare ; /* Do not compare the first time */ CODE4 *codeBase ; DATA4 *data ; } C4CHECK ; static int c4checkInit( C4CHECK *check, CODE4 *cb, TAG4FILE *t4, long nRecs, DATA4 *d4 ) { int rc ; memset( (void *)check, 0, sizeof(C4CHECK) ) ; rc = f4flagInit( &check->flag, cb, (unsigned long)nRecs ) ; if ( rc < 0 ) return rc ; check->codeBase = cb ; check->tag = t4 ; check->numRecs = nRecs ; check->data = d4 ; check->oldKey = (char *)u4allocFree( t4->codeBase, (long)t4->header.keyLen ) ; if (check->oldKey == 0) return e4memory ; return 0 ; } static void c4checkFree( C4CHECK *c4 ) { u4free( c4->flag.flags ) ; u4free( c4->oldKey ) ; } static int c4checkRecord( C4CHECK *check ) { B4KEY_DATA *keyData ; TAG4FILE *t4 ; unsigned char *newPtr ; int len, rc ; t4 = check->tag ; keyData = tfile4keyData( check->tag ) ; if ( keyData == 0 ) return error4( check->codeBase, e4index, E95701 ) ; if ( keyData->num < 1 || keyData->num > check->numRecs ) return error4describe( check->codeBase, e4index, E85703, check->tag->alias, (char *)0, (char *)0 ) ; if ( f4flagIsSet( &check->flag, (unsigned long)keyData->num) ) return error4describe( check->codeBase, e4index, E85703, check->tag->alias, (char *)0, (char *)0 ) ; else f4flagSet( &check->flag, (unsigned long)keyData->num ) ; rc = d4go( check->data, keyData->num ) ; if ( rc < 0 ) return rc ; rc = expr4context( t4->expr, check->data ) ; if ( rc < 0 ) return rc ; len = tfile4exprKey( t4, &newPtr ) ; if ( len != t4->header.keyLen ) return error4describe( check->codeBase, e4index, E85704, t4->alias, (char *)0, (char *)0 ) ; #ifdef S4MDX if ( expr4type( t4->expr ) == r4num ) { if ( c4bcdCmp( newPtr, keyData->value, 0 ) != 0 ) return error4describe( check->codeBase, e4index, E85705, t4->alias, (char *)0, (char *)0 ) ; } else #endif if ( c4memcmp( newPtr, keyData->value, (unsigned int)t4->header.keyLen ) != 0 ) return error4describe( check->codeBase, e4index, E85705, t4->alias, (char *)0, (char *)0 ) ; if ( check->doCompare ) { #ifdef S4FOX #ifdef S4VFP_KEY if ( tfile4type( t4 ) != r4str ) rc = c4memcmp( check->oldKey, newPtr, (unsigned int)t4->header.keyLen ) ; else #endif rc = u4keycmp( check->oldKey, newPtr, (unsigned int)t4->header.keyLen, (unsigned int)t4->header.keyLen, 0, &t4->vfpInfo ) ; #else rc = (*t4->cmp)( check->oldKey, newPtr, (unsigned int)t4->header.keyLen ) ; #endif if ( rc > 0) error4describe( check->codeBase, e4index, E85706, t4->alias, (char *)0, (char *)0 ) ; #ifdef S4FOX if ( rc == 0 && keyData->num <= check->oldRec ) error4describe( check->codeBase, e4index, E85707, t4->alias, (char *)0, (char *)0 ) ; #endif /* S4FOX */ #ifdef S4FOX if ( t4->header.typeCode & 0x01 ) #else if ( t4->header.unique ) #endif /* S4FOX */ if ( rc == 0 ) error4describe( check->codeBase, e4index, E85708, t4->alias, (char *)0, (char *)0 ) ; } else check->doCompare = 1 ; memcpy( check->oldKey, newPtr, (unsigned int)t4->header.keyLen ) ; check->oldRec = keyData->num ; if ( error4code( check->codeBase ) < 0 ) return error4code( check->codeBase ) ; return 0 ; } #ifdef S4CLIPPER static int tfile4blockCheck( TAG4FILE *t4, int firstTime ) { B4BLOCK *b4 ; int i, bType, rc ; CODE4 *c4 ; if ( firstTime ) tfile4upToRoot( t4 ) ; c4 = t4->codeBase ; b4 = (B4BLOCK *)t4->blocks.lastNode ; if ( b4 == 0 ) return 0 ; if ( b4->nKeys < t4->header.keysHalf && t4->header.root / 512 != b4->fileBlock ) return error4describe( c4, e4index, E85709, tfile4alias( t4 ), (char *)0, (char *)0 ) ; if ( !b4leaf( b4 ) ) { for ( i = 0 ; i <= b4->nKeys ; i++ ) { b4->keyOn = i ; rc = tfile4down( t4 ) ; if ( rc != 0 ) return error4describe( c4, e4index, E81601, tfile4alias( t4 ), 0, 0 ) ; if ( i == 0 ) bType = b4leaf( (B4BLOCK *)t4->blocks.lastNode ) ; else if ( bType != b4leaf( (B4BLOCK *)t4->blocks.lastNode ) ) return error4describe( c4, e4index, E85709, tfile4alias( t4 ), (char *)0, (char *)0 ) ; rc = tfile4blockCheck( t4, 0 ) ; if ( rc != 0 ) return rc ; rc = tfile4up( t4 ) ; if ( rc != 0 ) return error4describe( c4, e4index, E81601, tfile4alias( t4 ), (char *)0, (char *)0 ) ; } } return 0 ; } #endif #ifdef S4NDX static int tfile4blockCheck( TAG4FILE *t4, int firstTime ) { B4BLOCK *b4 ; int i, bType, rc ; CODE4 *c4 ; if ( firstTime ) tfile4upToRoot( t4 ) ; c4 = t4->codeBase ; b4 = (B4BLOCK *)t4->blocks.lastNode ; if ( b4 == 0 ) return 0 ; if ( !b4leaf( b4 ) ) { for ( i = 0 ; i <= b4->nKeys ; i++ ) { if ( b4key( b4, b4->keyOn )->pointer >= t4->header.eof ) return error4describe( c4, e4index, E81601, tfile4alias( t4 ), (char *)0, (char *)0 ) ; b4->keyOn = i ; rc = tfile4down( t4 ) ; if ( rc != 0 ) return error4describe( c4, e4index, E81601, tfile4alias( t4 ), (char *)0, (char *)0 ) ; rc = tfile4blockCheck( t4, 0 ) ; if ( rc != 0 ) return rc ; rc = tfile4up( t4 ) ; if ( rc != 0 ) return error4describe( c4, e4index, E81601, tfile4alias( t4 ), (char *)0, (char *)0 ) ; } } return 0 ; } #endif int t4check( TAG4 *t4 ) { C4CHECK check ; int rc, isRecord, keysSkip, rc2 ; CODE4 *c4 ; TAG4 *oldSelectedTag ; B4BLOCK *blockOn ; long baseSize, onRec ; unsigned char *ptr ; DATA4 *d4 ; #ifdef S4FOX unsigned char *tempVal ; long tempLong ; #endif #ifndef S4CLIPPER B4KEY_DATA *keyBranch, *keyLeaf ; #endif #ifdef S4PRINTF_OUT unsigned long loop ; #endif #ifdef E4PARM_LOW if ( t4 == 0 ) return error4( 0, e4parm_null, E95703 ) ; #endif d4 = t4->index->data ; c4 = d4->codeBase ; rc = expr4context( t4->tagFile->expr, d4 ) ; if ( rc < 0 ) return rc ; if ( t4->tagFile->filter != 0 ) { rc = expr4context( t4->tagFile->filter, d4 ) ; if ( rc < 0 ) return rc ; } #ifndef S4OFF_MULTI #ifdef S4SERVER rc = dfile4lockFile( d4->dataFile, data4clientId( d4 ), data4serverId( d4 ) ) ; /* returns -1 if error4code( codeBase ) < 0 */ #else rc = d4lockFile( d4 ) ; /* returns -1 if error4code( codeBase ) < 0 */ #endif if ( rc != 0 ) return rc ; #ifdef N4OTHER rc = i4lock( t4->index ) ; #else rc = index4lock( t4->tagFile->indexFile, data4serverId( d4 ) ) ; #endif if ( rc != 0 ) return rc ; rc = d4refresh( d4 ) ; if ( rc != 0 ) return rc ; #endif #ifndef S4OFF_WRITE rc = d4updateRecord( d4, 1 ) ; if ( rc < 0 ) return rc ; if ( rc ) return error4( c4, rc, E95703 ) ; #endif oldSelectedTag = d4tagSelected( d4 ) ; d4tagSelect( d4, t4 ) ; #ifdef N4OTHER rc = tfile4blockCheck( t4->tagFile, 1 ) ; if ( rc != 0 ) return rc ; #endif baseSize = d4recCount( d4 ) ; if ( baseSize < 0L ) return (int)baseSize ; rc = d4top( d4 ) ; if (rc < 0 ) return rc ; if ( rc == 0 ) rc = 1 ; if ( baseSize == 0L ) { if ( tfile4skip( t4->tagFile, 1L ) == 0 ) { d4tagSelect( d4, oldSelectedTag ) ; return( 0 ) ; } else return error4describe( c4, e4index, E85710, d4alias( d4 ), tfile4alias( t4->tagFile ), (char *)0 ) ; } rc2 = c4checkInit( &check, c4, t4->tagFile, baseSize, d4 ) ; if ( rc2 < 0 ) return rc2 ; #ifdef S4PRINTF_OUT loop = 0 ; printf( "On Rec %10ld\n", loop ) ; #endif while ( rc == 1 ) { rc = c4checkRecord( &check ) ; if ( rc ) break ; rc = (int)tfile4skip( t4->tagFile, 1L ) ; if ( rc < 0 ) break ; #ifdef S4PRINTF_OUT if ( (loop++ % 100) == 0 ) printf( "\b\b\b\b\b\b\b\b\b\b%10ld", loop ) ; #endif } if ( rc < 0 ) { c4checkFree( &check ) ; return rc ; } isRecord = 1 ; /* Now Test for Duplication */ for ( onRec = 1; onRec <= baseSize; onRec++) { #ifndef S4NDX if ( t4->tagFile->filter != 0 ) { if ( d4go( d4, onRec ) < 0 ) break ; rc2 = expr4context( t4->tagFile->filter, check.data ) ; if ( rc2 < 0 ) return rc2 ; isRecord = expr4true( t4->tagFile->filter ) ; } #endif if ( f4flagIsSet( &check.flag, (unsigned long)onRec ) ) { if ( !isRecord ) { error4describe( c4, e4index, E95703, t4->tagFile->alias, (char *)0, (char *)0 ) ; break ; } } else { if ( ! isRecord ) continue ; #ifdef S4FOX if ( t4->tagFile->header.typeCode & 0x01 ) #else if ( t4->tagFile->header.unique ) #endif { if ( d4go(d4,onRec) < 0 ) break ; if ( expr4context( t4->tagFile->expr, check.data ) < 0 ) break ; if ( tfile4exprKey( t4->tagFile, &ptr) < 0 ) break ; if ( tfile4seek( t4->tagFile, ptr, expr4keyLen( t4->tagFile->expr ) ) == 0 ) continue ; } error4describe( c4, e4index, E85711, t4->tagFile->alias, 0, 0 ) ; break ; } } c4checkFree( &check ) ; if ( error4code( c4 ) < 0 ) return error4code( c4 ) ; /* Now make sure the block key pointers match the blocks they point to. */ /* This needs to be true for d4seek to function perfectly. */ rc = d4bottom( d4 ) ; if ( rc < 0 ) return rc ; if ( rc == 3 ) { d4tagSelect( d4, oldSelectedTag ) ; return 0 ; } for(;;) { #ifdef S4FOX keysSkip = -tfile4block(t4->tagFile)->header.nKeys ; #else keysSkip = -tfile4block(t4->tagFile)->nKeys ; #endif rc = (int)tfile4skip( t4->tagFile, (long) keysSkip ) ; if ( error4code( c4 ) < 0 ) return error4code( c4 ) ; if ( rc != keysSkip ) { d4tagSelect( d4, oldSelectedTag ) ; return 0 ; } blockOn = (B4BLOCK *)t4->tagFile->blocks.lastNode ; if ( blockOn == 0 ) return error4describe( c4, e4index, E85712, tfile4alias( t4->tagFile ), (char *)0, (char *)0 ) ; #ifdef S4FOX tempVal = (unsigned char *)u4allocFree( c4, (long)t4->tagFile->header.keyLen ) ; if ( tempVal == 0 ) return error4stack( c4, e4memory, E95703 ) ; memcpy( tempVal, (void *)b4keyKey( blockOn, blockOn->keyOn ), (unsigned int)t4->tagFile->header.keyLen ) ; tempLong = b4recNo( blockOn, blockOn->keyOn ) ; if ( tfile4go( t4->tagFile, tempVal, tempLong, 0 ) ) { u4free( tempVal ) ; return error4describe( c4, e4index, E85712, tfile4alias( t4->tagFile ), (char *)0, (char *)0 ) ; } u4free( tempVal ) ; #endif #ifndef S4CLIPPER for ( ;; ) { blockOn = (B4BLOCK *)blockOn->link.p ; if ( blockOn == 0 ) break ; if ( blockOn == (B4BLOCK *)t4->tagFile->blocks.lastNode ) break ; #ifdef S4FOX if ( blockOn->keyOn < blockOn->header.nKeys ) #else if ( blockOn->keyOn < blockOn->nKeys ) #endif { keyBranch = b4key( blockOn, blockOn->keyOn ) ; keyLeaf = b4key( tfile4block( t4->tagFile ), tfile4block( t4->tagFile )->keyOn ) ; if ( c4memcmp( keyBranch->value, keyLeaf->value, (unsigned int)t4->tagFile->header.keyLen) != 0 ) return error4describe( c4, e4index, E85712, tfile4alias( t4->tagFile ), (char *)0, (char *)0 ) ; break ; } } if ( blockOn == 0 ) return error4describe( c4, e4index, E85712, tfile4alias( t4->tagFile ), (char *)0, (char *)0 ) ; #endif } } #ifdef S4FOX static int flag4blocks( TAG4FILE *t4, F4FLAG *f4, long *node1, long *node2, long *node3 ) { int i, rc ; B4BLOCK *blockOn ; long flagNo ; rc = tfile4down( t4 ) ; if ( rc < 0 ) return rc ; if ( rc == 2 ) return e4index ; if ( rc == 1 ) return error4( t4->codeBase, e4index, E95704 ) ; blockOn = tfile4block(t4) ; flagNo = blockOn->fileBlock / B4BLOCK_SIZE ; if ( *node2 != -2 ) if ( *node2 != blockOn->fileBlock ) return error4( t4->codeBase, e4index, E81601 ) ; if ( *node1 != -2 ) if ( *node1 != blockOn->header.leftNode ) return error4( t4->codeBase, e4index, E81601 ) ; if ( *node3 != -2 ) if ( *node3 != blockOn->header.rightNode ) return error4( t4->codeBase, e4index, E81601 ) ; if ( f4flagIsSet( f4, (unsigned long)flagNo ) ) return error4( t4->codeBase, e4index, E81601 ) ; rc = f4flagSet( f4, (unsigned long)flagNo ) ; if ( rc < 0 ) return rc ; if ( ! b4leaf(blockOn) ) { if ( blockOn->header.leftNode == -1 ) *node1 = -1L ; else *node1 = -2L ; *node2 = b4key( blockOn, 0 )->num ; for( i = 0; i < blockOn->header.nKeys; i++ ) { b4go( blockOn, (long)i ) ; if ( i == blockOn->header.nKeys - 1 && blockOn->header.rightNode == -1 ) *node3 = -1 ; else *node3 = -2 ; rc = flag4blocks( t4, f4, node1, node2, node3 ) ; if ( rc < 0 ) return rc ; } } *node1 = blockOn->fileBlock ; *node2 = blockOn->header.rightNode ; tfile4up(t4) ; return 0 ; } #else #ifndef S4NDX static int flag4blocks( TAG4FILE *t4, F4FLAG *f4 ) { int i, rc ; B4BLOCK *blockOn ; long flagNo ; rc = tfile4down( t4 ) ; if ( rc < 0 ) return rc ; if ( rc == 2 ) return -1 ; if ( rc == 1 ) return error4( t4->codeBase, e4index, E95704 ) ; blockOn = tfile4block(t4) ; #ifdef S4CLIPPER flagNo = (blockOn->fileBlock) * I4MULTIPLY / B4BLOCK_SIZE ; #else flagNo = (blockOn->fileBlock-4) * I4MULTIPLY / t4->indexFile->header.blockRw ; #endif if ( f4flagIsSet( f4, flagNo ) ) return error4( t4->codeBase, e4index, E81601 ) ; rc = f4flagSet( f4, flagNo ) ; if ( rc < 0 ) return rc ; if ( ! b4leaf(blockOn) ) { #ifdef S4MDX for( i = 0; i <= blockOn->nKeys; i++ ) { blockOn->keyOn = i ; rc = flag4blocks( t4, f4 ) ; if ( rc < 0 ) return rc ; } #else #ifdef S4CLIPPER for( i = 0; i <= blockOn->nKeys; i++ ) { blockOn->keyOn = i ; rc = flag4blocks( t4, f4 ) ; if ( rc < 0 ) return rc ; } #endif #endif } tfile4up(t4) ; return 0 ; } #endif /* ifndef S4NDX */ #endif /* ifdef S4FOX */ /* checks that all blocks in the file are on free list or are being used */ #ifdef P4ARGS_USED #pragma argsused #endif static int i4checkBlocks( INDEX4 *i4 ) { #ifndef N4OTHER TAG4FILE *tagOn ; F4FLAG flags ; #ifndef S4OFF_MULTI int rc ; #endif long flagNo ; S4LONG totBlocks, freeBlock, eofBlockNo, len ; CODE4 *c4 ; #ifdef S4FOX long node1, node2, node3 ; #else T4DESC desc[48] ; int i ; #endif c4 = i4->codeBase ; #ifndef S4OFF_MULTI rc = d4lockIndex( i4->data ) ; if ( rc < 0 ) return rc ; #endif len = file4len(&i4->indexFile->file) ; #ifdef S4MDX totBlocks = (len-2048) / i4->indexFile->header.blockRw ; #else totBlocks = len / B4BLOCK_SIZE ; #endif /* First Flag for the Free Chain */ f4flagInit( &flags, i4->codeBase, (unsigned long)totBlocks ) ; eofBlockNo = len/I4MULTIPLY ; #ifdef S4FOX for ( freeBlock = i4->indexFile->tagIndex->header.freeList ; freeBlock ; ) #else for ( freeBlock = i4->indexFile->header.freeList ; freeBlock ; ) #endif { if ( freeBlock == eofBlockNo || error4code( c4 ) < 0 ) break ; #ifdef S4MDX flagNo = (int)((freeBlock-4)*I4MULTIPLY/i4->indexFile->header.blockRw) ; #else flagNo = (int) (freeBlock / B4BLOCK_SIZE) ; #endif if ( freeBlock >= eofBlockNo || f4flagIsSet(&flags, (unsigned long)flagNo ) ) { error4( c4, e4index, E85701 ) ; break ; } f4flagSet( &flags, (unsigned long)flagNo ) ; #ifdef S4MDX file4readAll( &i4->indexFile->file, freeBlock * I4MULTIPLY + sizeof(long), &freeBlock, sizeof(freeBlock) ) ; #else file4readAll( &i4->indexFile->file, freeBlock * I4MULTIPLY, &freeBlock, sizeof(freeBlock) ) ; #endif #ifdef S4BYTE_SWAP freeBlock = x4reverseLong( (void *)&freeBlock ) ; #endif } #ifdef S4FOX /* do the header tag */ tagOn = i4->indexFile->tagIndex ; flagNo = (int)((tagOn->headerOffset) / (long)B4BLOCK_SIZE) ; if ( f4flagIsSet( &flags, (unsigned long)flagNo ) ) return error4( i4->codeBase, e4index, E81601 ) ; f4flagSet( &flags, (unsigned long)flagNo ) ; f4flagSet( &flags, (unsigned long)flagNo + 1L ) ; /* tag header is 2 blocks long */ if ( tfile4freeAll( tagOn ) >= 0 ) { #ifdef S4FOX node1 = -1L ; node2 = tagOn->header.root ; node3 = -1L ; flag4blocks( tagOn, &flags, &node1, &node2, &node3 ) ; #else flag4blocks( tagOn, &flags ) ; #endif /* Now Flag for each block in each tag */ for ( tagOn = 0 ;; ) { tagOn = (TAG4FILE *)l4next( &i4->indexFile->tags,tagOn ) ; if ( tagOn == 0 ) break ; flagNo = (int)( tagOn->headerOffset / (long)B4BLOCK_SIZE) ; if ( f4flagIsSet( &flags, (unsigned long)flagNo ) ) return error4( i4->codeBase, e4index, E81601 ) ; f4flagSet( &flags, (unsigned long)flagNo ) ; f4flagSet( &flags, (unsigned long)flagNo + 1L ) ; /* tag header is 2 blocks long */ if ( tfile4freeAll( tagOn ) < 0 ) break ; #ifdef S4FOX node1 = -1L ; node2 = tagOn->header.root ; node3 = -1L ; if ( node2 == -1 ) { if ( file4readAll( &i4->indexFile->file, tagOn->headerOffset, &node2, sizeof(node2)) < 0 ) return error4( i4->codeBase, e4index, E81601 ) ; #ifdef S4BYTE_SWAP node2 = x4reverseLong( (void *)&node2 ) ; #endif } flag4blocks( tagOn, &flags, &node1, &node2, &node3 ) ; #else flag4blocks( tagOn, &flags ) ; #endif } } #else /* Read header information to flag the tag header blocks */ file4readAll( &i4->indexFile->file, 512, desc, sizeof(desc) ) ; /* Now Flag for each block in each tag */ i = 1 ; for ( tagOn = 0 ;; i++ ) { tagOn = (TAG4FILE *)l4next( &i4->indexFile->tags, tagOn ) ; if ( tagOn == 0 ) break ; #ifdef S4BYTE_SWAP desc[i].headerPos = x4reverseLong( (void *)&desc[i].headerPos ) ; desc[i].x1000 = 0x1000 ; #endif flagNo = (int) ((desc[i].headerPos * I4MULTIPLY - 2048) / (long) i4->indexFile->header.blockRw) ; if ( f4flagIsSet( &flags, flagNo ) ) return error4( i4->codeBase, e4index, E81601 ) ; f4flagSet( &flags, flagNo ) ; if ( tfile4freeAll(tagOn) < 0 ) break ; flag4blocks( tagOn, &flags ) ; } #endif if ( f4flagIsAllSet( &flags, 0UL, (unsigned long)totBlocks - 1L ) == 0 ) error4( i4->codeBase, e4index, E85702 ) ; u4free( flags.flags ) ; if ( error4code( i4->codeBase ) < 0 ) return error4code( i4->codeBase ) ; #endif return 0 ; } int i4check( INDEX4 *i4 ) { int rc ; TAG4 *tagOn ; #ifdef S4HAS_DESCENDING int oldDesc ; #endif #ifdef E4PARM_HIGH if ( i4 == 0 ) return error4( 0, e4parm_null, E95705 ) ; #endif if ( error4code( i4->codeBase ) < 0 ) return e4codeBase ; #ifndef S4OFF_WRITE #ifdef N4OTHER rc = i4update( i4 ) ; #else rc = index4update( i4->indexFile ) ; #endif if ( rc < 0 ) return rc ; #endif rc = i4checkBlocks( i4 ) ; if ( rc < 0 ) return rc ; for( tagOn = 0 ;; ) { tagOn = (TAG4 *)l4next( &i4->tags, tagOn ) ; if ( tagOn == 0 ) return 0 ; #ifdef S4HAS_DESCENDING oldDesc = tagOn->tagFile->header.descending ; tagOn->tagFile->header.descending = 0 ; /* force ascending */ rc = t4check( tagOn ) ; tagOn->tagFile->header.descending = (short)oldDesc ; /* return to previous */ if ( rc < 0 ) return rc ; #else rc = t4check( tagOn ) ; if ( rc < 0 ) return rc ; #endif } } #endif /* S4INDEX_OFF */ #ifdef P4ARGS_USED #pragma argsused #endif int S4FUNCTION d4check( DATA4 *d4 ) { #ifdef S4INDEX_OFF return 0 ; #else INDEX4 *indexOn ; int rc ; #ifdef E4PARM_HIGH if ( d4 == 0 ) return error4( 0, e4parm_null, E95702 ) ; #endif #ifndef S4OFF_WRITE rc = d4updateRecord( d4, 1 ) ; if ( rc != 0 ) /* either an error or r4unique */ return rc ; #endif #ifndef S4OFF_MULTI #ifdef S4SERVER rc = dfile4lockFile( d4->dataFile, data4clientId( d4 ), data4serverId( d4 ) ) ; /* returns -1 if error4code( codeBase ) < 0 */ #else rc = d4lockFile( d4 ) ; /* returns -1 if error4code( codeBase ) < 0 */ #endif if ( rc ) return rc ; #endif #ifndef S4OFF_TRAN rc = tran4active( d4->codeBase, d4 ) ; if ( rc != 0 ) return error4( d4->codeBase, rc, E81517 ) ; #endif for( indexOn = 0 ;; ) { indexOn = (INDEX4 *)l4next( &d4->indexes, indexOn ) ; if ( indexOn == 0 ) return 0 ; rc = i4check( indexOn ) ; if ( rc < 0 ) return -1 ; } #endif /* S4INDEX_OFF */ } #endif /* S4CLIENT */