campo-sirio/cb/source/d4close.c

465 lines
12 KiB
C
Raw Normal View History

/* d4close.c (c)Copyright Sequiter Software Inc., 1988-1996. All rights reserved. */
#include "d4all.h"
#ifndef S4UNIX
#ifdef __TURBOC__
#pragma hdrstop
#endif /* __TUROBC__ */
#endif /* S4UNIX */
#ifndef S4MEMO_OFF
extern char f4memoNullChar ;
#endif /* not S4MEMO_OFF */
#ifndef S4CLIENT
/* closes the given datafile if it's user count is zero */
int dfile4closeLow( DATA4FILE *data )
{
int finalRc ;
CODE4 *c4 ;
#ifndef S4OFF_INDEX
#ifdef N4OTHER
TAG4FILE *t4 ;
#else
INDEX4FILE *i4 ;
#endif
#endif
#ifdef E4PARM_LOW
if ( data == 0 )
return error4( 0, e4parm_null, E91102 ) ;
#endif
c4 = data->c4 ;
if ( data->userCount > 0 )
return 0 ;
if ( data->info != 0 )
{
u4free( data->info ) ;
data->info = 0 ;
}
finalRc = error4set( c4, 0 ) ;
if ( file4openTest( &data->file ) )
{
#ifndef S4SERVER
if ( c4->doRemove == 1 )
data->file.isTemp = 1 ;
#endif
#ifndef S4OFF_WRITE
if ( data->fileChanged && data->file.isTemp != 1 && data->file.isReadOnly == 0 )
{
#ifdef S4OFF_MULTI
dfile4updateHeader( data, 1, 1 ) ;
#else
if ( data->file.lowAccessMode == OPEN4DENY_RW )
dfile4updateHeader( data, 1, 1 ) ;
#endif
if ( data->doDate == 1 )
{
u4yymmdd( &data->yy ) ;
data->doDate = 0 ;
}
}
#endif
}
#ifndef S4MEMO_OFF
if ( file4openTest( &data->memoFile.file ) )
{
#ifndef S4SERVER
if ( c4->doRemove == 1 )
data->memoFile.file.isTemp = 1 ;
#endif
if ( file4close( &data->memoFile.file ) < 0 )
finalRc = error4set( c4, 0 ) ;
}
#endif
#ifndef S4OFF_INDEX
for ( ;; )
{
#ifdef N4OTHER
t4 = (TAG4FILE *)l4first( &data->tagfiles ) ;
if ( t4 == 0 )
break ;
tfile4close( t4, data ) ;
#else
i4 = (INDEX4FILE *)l4first( &data->indexes ) ;
if ( i4 == 0 )
break ;
index4close( i4 ) ;
#endif
}
#endif
if ( data->link.n != 0 )
l4remove( &c4->dataFileList, data ) ;
if ( file4openTest( &data->file ) )
if ( file4close( &data->file ) < 0 )
finalRc = error4set( c4, 0 ) ;
data->record = 0 ;
mem4free( c4->data4fileMemory, data ) ;
error4set( c4, (short)finalRc ) ;
return finalRc ;
}
/* closes all datafiles for which the user count is zero */
int code4dataFileCloseAll( CODE4 *c4 )
{
DATA4FILE *data ;
int rc ;
#ifdef E4PARM_LOW
if ( c4 == 0 )
return error4( 0, e4parm_null, E91304 ) ;
#endif
for( ;; )
{
for ( data = (DATA4FILE *)l4first( &c4->dataFileList ) ;; )
{
if ( data == 0 )
break ;
if ( data->userCount > 0 )
data = (DATA4FILE *)l4next( &c4->dataFileList, data ) ;
else
break ;
}
if ( data == 0 )
break ;
rc = dfile4closeLow( data ) ;
if ( rc < 0 ) /* need to return in order to avoid endless loop */
return error4stack( c4, (short)rc, E91304 ) ;
}
return 0 ;
}
#endif
int dfile4close( DATA4FILE *data )
{
#ifndef S4STAND_ALONE
CODE4 *c4 ;
#endif
#ifdef S4CLIENT
int finalRc ;
INDEX4FILE *i4 ;
CONNECTION4 *connection ;
#endif
#ifdef E4PARM_LOW
if ( data == 0 )
return error4( 0, e4parm_null, E91102 ) ;
#endif
#ifdef E4ANALYZE
if ( data->userCount <= 0 )
return error4( 0, e4struct, E91102 ) ;
#endif
#ifndef S4STAND_ALONE
c4 = data->c4 ;
#endif
#ifdef S4CLIENT
finalRc = error4set( c4, 0 ) ;
#endif
data->userCount-- ;
if ( data->userCount == 0 )
{
#ifdef S4CLIENT
if ( data->info != 0 )
{
u4free( data->info ) ;
data->info = 0 ;
}
connection = data->connection ;
if ( connection == 0 )
finalRc = e4connection ;
else
{
connection4assign( connection, CON4CLOSE, 0, data->serverId ) ;
connection4send( connection ) ;
finalRc = connection4receive( connection ) ;
if ( finalRc == 0 )
finalRc = connection4status( connection ) ;
}
#ifndef S4OFF_INDEX
for ( ;; )
{
i4 = (INDEX4FILE *)l4first( &data->indexes ) ;
if ( i4 == 0 )
break ;
index4close( i4 ) ;
}
#endif
l4remove( &c4->dataFileList, data ) ;
mem4free( c4->data4fileMemory, data ) ;
error4set( c4, finalRc ) ;
return finalRc ;
#else
#ifdef S4SERVER
if ( c4->server->keepOpen == 0 || data->valid != 1 ) /* not a valid datafile (failure in dfile4open) so close */
return dfile4closeLow( data ) ;
if ( data->file.isTemp && c4->server->keepOpen != 2 ) /* cannot leave temp files open or they will never close */
return dfile4closeLow( data ) ;
data->singleClient = 0 ;
time( &data->nullTime ) ;
#else
return dfile4closeLow( data ) ;
#endif
#endif /* S4CLIENT */
}
return 0 ;
}
#ifdef P4ARGS_USED
#pragma argsused
#endif
/* clears all locks for a given DATA4 from the list (useful when closing a file) */
void code4lockClearData( CODE4 *c4, DATA4 *data )
{
#ifndef S4SINGLE
LOCK4 *lock, *lockNext ;
TRAN4 *trans ;
#ifdef S4SERVER
trans = &c4->currentClient->trans ;
#else
trans = &c4->c4trans.trans ;
#endif
for ( lockNext = (LOCK4 *)l4first( &trans->locks ) ;; )
{
lock = lockNext ;
if ( lock == 0 )
break ;
lockNext = (LOCK4 *)l4next( &trans->locks, lock ) ;
#ifdef S4SERVER
if ( lock->id.clientId != data4clientId( data ) || lock->id.serverId != data4serverId( data ) )
continue ;
#else
#ifdef S4CLIENT
if ( lock->data != data )
#else
if ( lock->data != data->dataFile )
#endif
continue ;
#endif
l4remove( &trans->locks, lock ) ;
mem4free( c4->lockMemory, lock ) ;
}
#endif /* S4SINGLE */
return ;
}
int S4FUNCTION d4close( DATA4 *data )
{
int rc, saveRc, saveRc2 ;
CODE4 *c4 ;
#ifndef S4CLIENT
#ifndef S4OFF_WRITE
#ifndef S4OFF_TRAN
long connectionId ;
TRAN4 *trans = 0 ;
#endif
#endif
#endif
#ifndef S4INDEX_OFF
INDEX4 *indexNext, *indexOn ;
#endif
#ifdef E4ANALYZE
LINK4 compareLink ;
#endif
#ifndef S4MEMO_OFF
int i ;
#endif
#ifndef S4SINGLE
int saveAttempts ;
#endif
#ifdef E4PARM_HIGH
if ( data == 0 )
return error4( 0, e4parm_null, E91302 ) ;
#endif
c4 = data->codeBase ;
saveRc = 0 ;
#ifndef S4SINGLE
saveAttempts = c4->lockAttempts ;
c4->lockAttempts = WAIT4EVER ;
#endif
if ( error4code( c4 ) == e4unique )
data->recordChanged = 0 ;
if ( error4code( c4 ) < 0 )
saveRc2 = error4set( c4, 0 ) ;
else
saveRc2 = 0 ;
if ( data->dataFile != 0 )
{
/* need to remove any references to any code4lock() calls */
code4lockClearData( c4, data ) ;
#ifndef S4OFF_WRITE
saveRc = d4update( data ) ;
if ( saveRc == e4unique )
data->recordChanged = 0 ;
#endif
#ifndef S4OFF_TRAN
#ifndef S4OFF_WRITE
#ifndef S4CLIENT
#ifdef S4SERVER
if ( c4->currentClient != 0 )
#endif
if ( code4transEnabled( c4 ) )
{
trans = code4trans( c4 ) ;
#ifdef S4STAND_ALONE
connectionId = 0L ;
#else
connectionId = connection4id( c4->currentClient->connection ) ;
#endif
if ( trans->currentTranStatus != r4active )
{
rc = tran4set( trans, trans->currentTranStatus, -1L, connectionId, TRAN4CLOSE,
0, data4clientId( data ), data4serverId( data ) ) ;
if ( rc < 0 )
saveRc = rc ;
if ( tran4lowAppend( trans, "\0" ) != 0 )
saveRc = e4transAppend ;
}
}
else
trans = 0 ;
#endif
#endif /* S4OFF_WRITE */
#endif /* S4OFF_TRAN */
#ifndef S4OFF_TRAN
#ifndef S4OFF_WRITE
#ifdef S4CLIENT
if ( code4transEnabled( c4 ) ) /* can't unlock in this instance */
if ( code4tranStatus( c4 ) == r4active )
#else
if ( trans != 0 ) /* just add to list */
if ( trans->currentTranStatus == r4active )
#endif
{
l4remove( tran4dataList( data->trans ), data ) ;
l4add( &(code4trans( c4 )->closedDataFiles), data ) ;
#ifndef S4SINGLE
c4->lockAttempts = saveAttempts ;
#endif
return 0 ;
}
#endif
#endif
#ifndef S4SINGLE
if ( d4unlock( data ) < 0 )
saveRc = error4set( c4, 0 ) ;
#endif /* S4SINGLE */
#ifndef S4INDEX_OFF
for( indexNext = (INDEX4 *)l4first( &data->indexes );; )
{
indexOn = indexNext ;
indexNext = (INDEX4 *)l4next( &data->indexes, indexOn ) ;
if ( !indexOn )
break ;
rc = i4close( indexOn ) ;
if ( rc < 0 )
{
saveRc = rc ;
error4set( c4, 0 ) ;
}
}
#endif
#ifndef S4MEMO_OFF
if ( data->fieldsMemo != 0 )
{
for ( i = 0; i < data->dataFile->nFieldsMemo ; i++ )
if ( data->fieldsMemo[i].contents != &f4memoNullChar )
{
u4free( data->fieldsMemo[i].contents ) ;
data->fieldsMemo[i].contents = &f4memoNullChar ;
}
u4free( data->fieldsMemo ) ;
data->fieldsMemo = 0 ;
}
#endif /* S4MEMO_OFF */
#ifdef S4CLIENT
if ( c4->doRemove == 1 )
rc = dfile4remove( data->dataFile ) ;
else
#endif
rc = dfile4close( data->dataFile ) ;
if ( rc < 0 )
saveRc = rc ;
data->dataFile = 0 ;
if ( data->groupRecordAlloc != 0 )
{
u4free( data->groupRecordAlloc ) ;
data->record = 0 ;
data->recordOld = 0 ;
data->fields = 0 ;
}
else
{
u4free( data->record ) ;
u4free( data->recordOld ) ;
u4free( data->fields ) ;
}
if ( data->trans != 0 )
l4remove( tran4dataList( data->trans ), data ) ;
#ifdef E4ANALYZE
else
{
memset( &compareLink, 0, sizeof( LINK4 ) ) ;
if ( c4memcmp( &data->link, &compareLink, sizeof( LINK4 ) ) != 0 )
saveRc = error4( c4, e4struct, E81305 ) ;
}
#endif
}
else
if ( data->trans != 0 )
l4remove( tran4dataList( data->trans ), data ) ;
mem4free( c4->dataMemory, data ) ;
if ( saveRc != 0 )
error4set( c4, (short)saveRc ) ;
#ifndef S4SINGLE
c4->lockAttempts = saveAttempts ;
#endif
if ( saveRc2 < 0 )
{
error4set( c4, (short)saveRc2 ) ;
return saveRc2 ;
}
return saveRc ;
}