469 lines
		
	
	
		
			11 KiB
		
	
	
	
		
			C
		
	
	
		
			Executable File
		
	
	
	
	
			
		
		
	
	
			469 lines
		
	
	
		
			11 KiB
		
	
	
	
		
			C
		
	
	
		
			Executable File
		
	
	
	
	
/* 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 <time.h>
 | 
						|
#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 */
 |