which included commits to RCS files with non-trunk default branches. git-svn-id: svn://10.65.10.50/trunk@976 c028cbd2-c16b-5b4b-a496-9718f37d4682
		
			
				
	
	
		
			770 lines
		
	
	
		
			18 KiB
		
	
	
	
		
			C
		
	
	
		
			Executable File
		
	
	
	
	
			
		
		
	
	
			770 lines
		
	
	
		
			18 KiB
		
	
	
	
		
			C
		
	
	
		
			Executable File
		
	
	
	
	
/* i4check.c   (C)Copyright Sequiter Software Inc., 1990-1994.  All rights reserved. */
 | 
						|
 | 
						|
#include "d4all.h"
 | 
						|
#ifndef S4UNIX
 | 
						|
#ifdef __TURBOC__
 | 
						|
#pragma hdrstop
 | 
						|
#endif
 | 
						|
#endif
 | 
						|
 | 
						|
#ifndef S4INDEX_OFF
 | 
						|
 | 
						|
typedef struct
 | 
						|
{
 | 
						|
  F4FLAG    flag ;
 | 
						|
 | 
						|
  TAG4    *tag ;
 | 
						|
  char     *old_key ;
 | 
						|
  long      old_rec ;
 | 
						|
  long      num_recs ;
 | 
						|
  int       do_compare ;  /* Do not compare the first time */
 | 
						|
  CODE4   *code_base ;
 | 
						|
} C4CHECK ;
 | 
						|
 | 
						|
static int c4check_init( C4CHECK *check, CODE4 *cb, TAG4 *t4, long n_recs )
 | 
						|
{
 | 
						|
  memset( (void *)check, 0, sizeof(C4CHECK) ) ;
 | 
						|
 | 
						|
  if ( f4flag_init( &check->flag, cb, n_recs ) < 0 )
 | 
						|
    return -1 ;
 | 
						|
 | 
						|
  check->code_base = cb ;
 | 
						|
  check->tag = t4 ;
 | 
						|
  check->num_recs = n_recs ;
 | 
						|
 | 
						|
  check->old_key = (char *)u4alloc_free( t4->code_base, t4->header.key_len ) ;
 | 
						|
  if (check->old_key == 0)
 | 
						|
    return -1 ;
 | 
						|
  return 0 ;
 | 
						|
}
 | 
						|
 | 
						|
static void c4check_free( C4CHECK *c4 )
 | 
						|
{
 | 
						|
  u4free( c4->flag.flags ) ;
 | 
						|
  u4free( c4->old_key ) ;
 | 
						|
}
 | 
						|
 | 
						|
static int  c4check_record( C4CHECK *check )
 | 
						|
{
 | 
						|
  B4KEY_DATA *key_data ;
 | 
						|
  TAG4 *t4 ;
 | 
						|
  char *new_ptr ;
 | 
						|
  int len, rc ;
 | 
						|
 | 
						|
  t4 = check->tag ;
 | 
						|
 | 
						|
  key_data = t4key_data( check->tag ) ;
 | 
						|
  if ( key_data == 0 )
 | 
						|
    return e4( check->code_base, e4result, 0 ) ;
 | 
						|
 | 
						|
  if ( key_data->num < 1  ||  key_data->num > check->num_recs )
 | 
						|
    return e4describe( check->code_base, e4info, E4_INFO_INC, check->tag->alias, (char *)0 ) ;
 | 
						|
 | 
						|
  if ( f4flag_is_set( &check->flag, key_data->num) )
 | 
						|
    return e4describe( check->code_base, e4info, E4_INFO_REP, check->tag->alias, (char *)0 ) ;
 | 
						|
  else
 | 
						|
    f4flag_set( &check->flag, key_data->num ) ;
 | 
						|
 | 
						|
  if ( d4go( t4->index->data, key_data->num ) < 0)  return( -1) ;
 | 
						|
  len = t4expr_key( t4, &new_ptr ) ;
 | 
						|
 | 
						|
  if ( len != t4->header.key_len )
 | 
						|
    return e4describe( check->code_base, e4result, E4_RESULT_UNE, t4->alias, (char *)0 ) ;
 | 
						|
 | 
						|
#ifdef S4MDX
 | 
						|
  if ( expr4type( t4->expr ) == r4num )
 | 
						|
  {
 | 
						|
    if ( c4bcd_cmp( new_ptr, key_data->value, 0 ) != 0 )
 | 
						|
      return e4describe( check->code_base, e4result, E4_RESULT_TAG, t4->alias, (char *)0 ) ;
 | 
						|
  }
 | 
						|
  else
 | 
						|
#endif
 | 
						|
    if ( memcmp( new_ptr, key_data->value, t4->header.key_len ) != 0 )
 | 
						|
      return e4describe( check->code_base, e4result, E4_RESULT_TAG, t4->alias, (char *)0 ) ;
 | 
						|
 | 
						|
  if ( check->do_compare )
 | 
						|
  {
 | 
						|
#ifdef S4FOX
 | 
						|
    rc = u4memcmp( check->old_key, new_ptr, check->tag->header.key_len ) ;
 | 
						|
#else
 | 
						|
    rc = (*t4->cmp)( check->old_key, new_ptr, check->tag->header.key_len ) ;
 | 
						|
#endif
 | 
						|
 | 
						|
    if ( rc > 0)
 | 
						|
      e4describe( check->code_base, e4result, E4_RESULT_THE, t4->alias, (char *)0 ) ;
 | 
						|
#ifdef S4FOX
 | 
						|
    if ( rc == 0  &&  key_data->num <= check->old_rec )
 | 
						|
      e4describe( check->code_base, e4result, E4_RESULT_REC, t4->alias, (char *)0 ) ;
 | 
						|
#endif /* S4FOX */
 | 
						|
 | 
						|
#ifdef S4FOX
 | 
						|
    if ( t4->header.type_code & 0x01 )
 | 
						|
#else
 | 
						|
      if ( t4->header.unique )
 | 
						|
#endif /* S4FOX */
 | 
						|
        if ( rc == 0 )
 | 
						|
          e4describe( check->code_base, e4result, E4_RESULT_IDE, t4->alias, (char *)0 ) ;
 | 
						|
  }
 | 
						|
  else
 | 
						|
    check->do_compare = 1 ;
 | 
						|
 | 
						|
  memcpy( check->old_key, new_ptr, t4->header.key_len ) ;
 | 
						|
 | 
						|
  check->old_rec = key_data->num ;
 | 
						|
 | 
						|
  if ( check->code_base->error_code < 0 )
 | 
						|
    return -1 ;
 | 
						|
  return 0 ;
 | 
						|
}
 | 
						|
 | 
						|
#ifdef S4CLIPPER
 | 
						|
static int t4block_check( TAG4 *t4, int first_time )
 | 
						|
{
 | 
						|
  B4BLOCK *b4 ;
 | 
						|
  int i, b_type, rc ;
 | 
						|
  CODE4 *c4 ;
 | 
						|
 | 
						|
  if ( first_time )
 | 
						|
    t4up_to_root( t4 ) ;
 | 
						|
 | 
						|
  c4 = t4->code_base ;
 | 
						|
  b4 = (B4BLOCK *)t4->blocks.last_node ;
 | 
						|
  if ( b4 == 0 )
 | 
						|
    return 0 ;
 | 
						|
  if ( b4->n_keys < t4->header.keys_half && t4->header.root / 512 != b4->file_block )
 | 
						|
    return e4describe( c4, e4result, E4_T4BLOCK_CHK, E4_RESULT_CII, (char *)0 ) ;
 | 
						|
  if ( !b4leaf( b4 ) )
 | 
						|
  {
 | 
						|
    for ( i = 0 ; i <= b4->n_keys ; i++ )
 | 
						|
    {
 | 
						|
      b4->key_on = i ;
 | 
						|
      rc = t4down( t4 ) ;
 | 
						|
      if ( rc != 0 )
 | 
						|
        return e4describe( c4, e4result, E4_T4BLOCK_CHK, E4_INFO_CIF, (char *)0 ) ;
 | 
						|
      if ( i == 0 )
 | 
						|
        b_type = b4leaf( (B4BLOCK *)t4->blocks.last_node ) ;
 | 
						|
      else
 | 
						|
        if ( b_type != b4leaf( (B4BLOCK *)t4->blocks.last_node ) )
 | 
						|
          return e4describe( c4, e4result, E4_T4BLOCK_CHK, E4_RESULT_CII, (char *)0 ) ;
 | 
						|
      rc = t4block_check( t4, 0 ) ;
 | 
						|
      if ( rc != 0 )
 | 
						|
        return rc ;
 | 
						|
      rc = t4up( t4 ) ;
 | 
						|
      if ( rc != 0 )
 | 
						|
        return e4describe( c4, e4result, E4_T4BLOCK_CHK, E4_INFO_CIF, (char *)0 ) ;
 | 
						|
    }
 | 
						|
  }
 | 
						|
  return 0 ;
 | 
						|
}
 | 
						|
#endif
 | 
						|
 | 
						|
#ifdef S4NDX
 | 
						|
static int t4block_check( TAG4 *t4, int first_time )
 | 
						|
{
 | 
						|
  B4BLOCK *b4 ;
 | 
						|
  int i, b_type, rc ;
 | 
						|
  CODE4 *c4 ;
 | 
						|
 | 
						|
  if ( first_time )
 | 
						|
    t4up_to_root( t4 ) ;
 | 
						|
 | 
						|
  c4 = t4->code_base ;
 | 
						|
  b4 = (B4BLOCK *)t4->blocks.last_node ;
 | 
						|
  if ( b4 == 0 )
 | 
						|
    return 0 ;
 | 
						|
  if ( !b4leaf( b4 ) )
 | 
						|
  {
 | 
						|
    for ( i = 0 ; i <= b4->n_keys ; i++ )
 | 
						|
    {
 | 
						|
      if ( b4key( b4, b4->key_on )->pointer >= t4->header.eof )
 | 
						|
        return e4describe( c4, e4result, E4_T4BLOCK_CHK, E4_INFO_CIF, (char *)0 ) ;
 | 
						|
      b4->key_on = i ;
 | 
						|
      rc = t4down( t4 ) ;
 | 
						|
      if ( rc != 0 )
 | 
						|
        return e4describe( c4, e4result, E4_T4BLOCK_CHK, E4_INFO_CIF, (char *)0 ) ;
 | 
						|
      rc = t4block_check( t4, 0 ) ;
 | 
						|
      if ( rc != 0 )
 | 
						|
        return rc ;
 | 
						|
      rc = t4up( t4 ) ;
 | 
						|
      if ( rc != 0 )
 | 
						|
        return e4describe( c4, e4result, E4_T4BLOCK_CHK, E4_INFO_CIF, (char *)0 ) ;
 | 
						|
    }
 | 
						|
  }
 | 
						|
  return 0 ;
 | 
						|
}
 | 
						|
#endif
 | 
						|
 | 
						|
int S4FUNCTION t4check( TAG4 *t4 )
 | 
						|
{
 | 
						|
  C4CHECK check ;
 | 
						|
  int rc, is_record, keys_skip ;
 | 
						|
  INDEX4 *i4 ;
 | 
						|
  DATA4 *d4 ;
 | 
						|
  CODE4 *c4 ;
 | 
						|
  TAG4 *old_selected_tag ;
 | 
						|
  B4BLOCK *block_on ;
 | 
						|
  long base_size, on_rec ;
 | 
						|
  char *ptr ;
 | 
						|
#ifdef S4FOX
 | 
						|
  char *temp_val ;
 | 
						|
  long temp_lng ;
 | 
						|
#endif
 | 
						|
#ifndef S4CLIPPER
 | 
						|
  B4KEY_DATA *key_branch, *key_leaf ;
 | 
						|
#endif
 | 
						|
#ifdef S4PRINTF_OUT
 | 
						|
  unsigned long loop ;
 | 
						|
#endif
 | 
						|
 | 
						|
#ifdef S4DEBUG
 | 
						|
  if ( t4 == 0 )
 | 
						|
    e4severe( e4parm, E4_T4CHECK ) ;
 | 
						|
#endif
 | 
						|
 | 
						|
  i4 = t4->index ;
 | 
						|
  d4 = i4->data ;
 | 
						|
  c4 = t4->code_base ;
 | 
						|
 | 
						|
#ifndef S4SINGLE
 | 
						|
  rc = d4lock_file( d4 ) ;
 | 
						|
  if ( rc != 0 )
 | 
						|
    return rc ;
 | 
						|
  rc = i4lock( t4->index ) ;
 | 
						|
  if ( rc != 0 )
 | 
						|
    return rc ;
 | 
						|
  rc = d4refresh( d4 ) ;
 | 
						|
  if ( rc != 0 )
 | 
						|
    return rc ;
 | 
						|
#endif
 | 
						|
 | 
						|
  rc = d4update_record( d4, 1 ) ;
 | 
						|
  if ( rc < 0 )
 | 
						|
    return -1 ;
 | 
						|
  if ( rc )
 | 
						|
    return e4describe( c4, e4result, E4_T4CHECK, E4_RESULT_D4F, (char *)0 ) ;
 | 
						|
 | 
						|
  old_selected_tag = d4tag_selected( d4 ) ;
 | 
						|
  d4tag_select( d4, t4 ) ;
 | 
						|
 | 
						|
#ifdef N4OTHER
 | 
						|
  rc = t4block_check( t4, 1 ) ;
 | 
						|
  if ( rc != 0 )
 | 
						|
    return rc ;
 | 
						|
#endif
 | 
						|
 | 
						|
  base_size = d4reccount( d4 ) ;
 | 
						|
  if ( base_size < 0L )
 | 
						|
    return -1 ;
 | 
						|
 | 
						|
  rc = d4top( d4 ) ;
 | 
						|
  if (rc < 0 )
 | 
						|
    return -1 ;
 | 
						|
  if (rc == 0)
 | 
						|
    rc = 1 ;
 | 
						|
 | 
						|
  if ( base_size == 0L )
 | 
						|
  {
 | 
						|
    if ( t4skip( t4, 1L ) == 0 )
 | 
						|
    {
 | 
						|
      d4tag_select( d4, old_selected_tag ) ;
 | 
						|
      return( 0 ) ;
 | 
						|
    }
 | 
						|
    else
 | 
						|
      return e4describe( c4, e4info, E4_T4CHECK, E4_INFO_DAT, (char *)0 ) ;
 | 
						|
  }
 | 
						|
 | 
						|
  if ( c4check_init( &check, c4, t4, base_size ) < 0 )
 | 
						|
    return -1 ;
 | 
						|
 | 
						|
#ifdef S4PRINTF_OUT
 | 
						|
  loop = 0 ;
 | 
						|
  printf( "On Rec %10ld\n", loop ) ;
 | 
						|
#endif
 | 
						|
  while ( rc == 1 )
 | 
						|
  {
 | 
						|
    rc = c4check_record( &check ) ;
 | 
						|
    if ( rc )
 | 
						|
      break ;
 | 
						|
    rc = (int)t4skip( t4, 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 )
 | 
						|
  {
 | 
						|
    c4check_free( &check ) ;
 | 
						|
    return -1 ;
 | 
						|
  }
 | 
						|
 | 
						|
  is_record = 1 ;
 | 
						|
 | 
						|
  /* Now Test for Duplication */
 | 
						|
  for ( on_rec = 1;  on_rec <= base_size; on_rec++)
 | 
						|
  {
 | 
						|
#ifndef S4NDX
 | 
						|
    if ( t4->filter != 0 )
 | 
						|
    {
 | 
						|
      if ( d4go(d4,on_rec) < 0 )  break ;
 | 
						|
      is_record = expr4true( t4->filter ) ;
 | 
						|
    }
 | 
						|
#endif
 | 
						|
 | 
						|
    if ( f4flag_is_set(&check.flag,on_rec) )
 | 
						|
    {
 | 
						|
      if ( ! is_record )
 | 
						|
      {
 | 
						|
        e4describe( c4, e4info, E4_T4CHECK, t4->alias, (char *)0 ) ;
 | 
						|
        break ;
 | 
						|
      }
 | 
						|
    }
 | 
						|
    else
 | 
						|
    {
 | 
						|
      if ( ! is_record )
 | 
						|
        continue ;
 | 
						|
 | 
						|
#ifdef S4FOX
 | 
						|
      if ( t4->header.type_code & 0x01 )
 | 
						|
#else
 | 
						|
        if ( t4->header.unique )
 | 
						|
#endif
 | 
						|
        {
 | 
						|
          if ( d4go(d4,on_rec) < 0 )
 | 
						|
            break ;
 | 
						|
          if ( t4expr_key( t4, &ptr) < 0 )
 | 
						|
            break ;
 | 
						|
          if ( t4seek( t4, ptr, expr4key_len( t4->expr ) ) == 0 )
 | 
						|
            continue ;
 | 
						|
        }
 | 
						|
 | 
						|
      e4describe( c4, e4info, E4_T4CHECK, E4_INFO_REC, t4->alias ) ;
 | 
						|
      break ;
 | 
						|
    }
 | 
						|
  }
 | 
						|
 | 
						|
  c4check_free( &check ) ;
 | 
						|
  if ( t4->code_base->error_code < 0 )
 | 
						|
    return -1 ;
 | 
						|
 | 
						|
  /* 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 -1 ;
 | 
						|
 | 
						|
  if ( rc == 3 )
 | 
						|
  {
 | 
						|
    d4tag_select( d4, old_selected_tag ) ;
 | 
						|
    return 0 ;
 | 
						|
  }
 | 
						|
 | 
						|
  for(;;)
 | 
						|
  {
 | 
						|
#ifdef S4FOX
 | 
						|
    keys_skip = -t4block(t4)->header.n_keys ;
 | 
						|
#else
 | 
						|
    keys_skip = -t4block(t4)->n_keys ;
 | 
						|
#endif
 | 
						|
 | 
						|
    rc = (int)t4skip( t4, (long) keys_skip ) ;
 | 
						|
    if ( c4->error_code < 0 )
 | 
						|
      return -1 ;
 | 
						|
    if ( rc != keys_skip )
 | 
						|
    {
 | 
						|
      d4tag_select( d4, old_selected_tag ) ;
 | 
						|
      return 0 ;
 | 
						|
    }
 | 
						|
 | 
						|
    block_on = (B4BLOCK *)t4->blocks.last_node ;
 | 
						|
    if ( block_on == 0 )
 | 
						|
      return e4describe( c4, e4info, E4_INFO_TAG, t4->alias, (char *)0 ) ;
 | 
						|
 | 
						|
#ifdef S4FOX
 | 
						|
    temp_val = (char *)u4alloc_free( c4, t4->header.key_len ) ;
 | 
						|
    if ( temp_val == 0 )
 | 
						|
      e4( t4->code_base, e4memory, 0 ) ;
 | 
						|
    memcpy( temp_val, (void *)b4key_key( block_on, block_on->key_on ), t4->header.key_len ) ;
 | 
						|
    temp_lng = b4recno( block_on, block_on->key_on ) ;
 | 
						|
 | 
						|
    if ( t4go( t4, temp_val, temp_lng ) )
 | 
						|
    {
 | 
						|
      u4free( temp_val ) ;
 | 
						|
      return e4describe( c4, e4info, E4_INFO_TAG, t4->alias, (char *)0 ) ;
 | 
						|
    }
 | 
						|
    u4free( temp_val ) ;
 | 
						|
#endif
 | 
						|
 | 
						|
#ifndef S4CLIPPER
 | 
						|
    for ( ;; )
 | 
						|
    {
 | 
						|
      block_on = (B4BLOCK *)block_on->link.p ;
 | 
						|
      if ( block_on == 0 )
 | 
						|
        break ;
 | 
						|
      if ( block_on == (B4BLOCK *)t4->blocks.last_node )
 | 
						|
        break ;
 | 
						|
 | 
						|
#ifdef S4FOX
 | 
						|
      if ( block_on->key_on < block_on->header.n_keys )
 | 
						|
#else
 | 
						|
        if ( block_on->key_on < block_on->n_keys )
 | 
						|
#endif
 | 
						|
        {
 | 
						|
          key_branch = b4key( block_on, block_on->key_on ) ;
 | 
						|
          key_leaf = b4key( t4block(t4), t4block(t4)->key_on ) ;
 | 
						|
 | 
						|
          if ( memcmp( key_branch->value, key_leaf->value, t4->header.key_len) != 0)
 | 
						|
            return e4describe( c4, e4info, E4_INFO_TAG, t4->alias, (char *)0 ) ;
 | 
						|
 | 
						|
          break ;
 | 
						|
        }
 | 
						|
    }
 | 
						|
    if ( block_on == 0 )
 | 
						|
      return e4describe( c4, e4info, E4_INFO_TAG, t4->alias, (char *)0 ) ;
 | 
						|
#endif
 | 
						|
  }
 | 
						|
}
 | 
						|
 | 
						|
#ifdef S4FOX
 | 
						|
static int flag_blocks( TAG4 *t4, F4FLAG *f4, long *node1, long *node2, long *node3 )
 | 
						|
{
 | 
						|
  int i, rc ;
 | 
						|
  B4BLOCK *block_on ;
 | 
						|
  long flag_no ;
 | 
						|
 | 
						|
  rc = t4down( t4 ) ;
 | 
						|
  if ( rc < 0 || rc == 2 )
 | 
						|
    return -1 ;
 | 
						|
  if ( rc == 1 )
 | 
						|
    e4severe( e4result, (char *)0 ) ;
 | 
						|
 | 
						|
  block_on = t4block(t4) ;
 | 
						|
 | 
						|
  flag_no = block_on->file_block / B4BLOCK_SIZE ;
 | 
						|
  if ( *node2 != -2 )
 | 
						|
    if ( *node2 != block_on->file_block )
 | 
						|
      e4severe( e4result, E4_RESULT_COR ) ;
 | 
						|
  if ( *node1 != -2 )
 | 
						|
    if ( *node1 != block_on->header.left_node )
 | 
						|
      e4severe( e4result, E4_RESULT_COR ) ;
 | 
						|
  if ( *node3 != -2 )
 | 
						|
    if ( *node3 != block_on->header.right_node )
 | 
						|
      e4severe( e4result, E4_RESULT_COR ) ;
 | 
						|
 | 
						|
  if ( f4flag_is_set( f4, flag_no ) )
 | 
						|
    e4severe( e4result, E4_RESULT_COR ) ;
 | 
						|
 | 
						|
  if ( f4flag_set( f4, flag_no ) < 0 )
 | 
						|
    return -1 ;
 | 
						|
  if ( ! b4leaf(block_on) )
 | 
						|
  {
 | 
						|
    if ( block_on->header.left_node == -1 )
 | 
						|
      *node1 = -1L ;
 | 
						|
    else
 | 
						|
      *node1 = -2L ;
 | 
						|
    *node2 = b4key( block_on, 0 )->num ;
 | 
						|
 | 
						|
    for( i = 0; i < block_on->header.n_keys; i++ )
 | 
						|
    {
 | 
						|
      b4go( block_on, i ) ;
 | 
						|
      if ( i == block_on->header.n_keys - 1 && block_on->header.right_node == -1 )
 | 
						|
        *node3 = -1 ;
 | 
						|
      else
 | 
						|
        *node3 = -2 ;
 | 
						|
      if ( flag_blocks( t4, f4, node1, node2, node3 ) < 0 )
 | 
						|
        return -1 ;
 | 
						|
    }
 | 
						|
  }
 | 
						|
 | 
						|
  *node1 = block_on->file_block ;
 | 
						|
  *node2 = block_on->header.right_node ;
 | 
						|
  t4up(t4) ;
 | 
						|
  return 0 ;
 | 
						|
}
 | 
						|
#else
 | 
						|
#ifndef S4NDX
 | 
						|
static int flag_blocks( TAG4 *t4, F4FLAG *f4 )
 | 
						|
{
 | 
						|
  int i, rc ;
 | 
						|
  B4BLOCK *block_on ;
 | 
						|
  long flag_no ;
 | 
						|
 | 
						|
  rc = t4down( t4 ) ;
 | 
						|
  if ( rc < 0 || rc == 2 )
 | 
						|
    return -1 ;
 | 
						|
  if ( rc == 1 )
 | 
						|
    e4severe( e4result, (char *)0 ) ;
 | 
						|
 | 
						|
  block_on = t4block(t4) ;
 | 
						|
 | 
						|
#ifdef S4CLIPPER
 | 
						|
  flag_no = (block_on->file_block) * I4MULTIPLY / B4BLOCK_SIZE ;
 | 
						|
#else
 | 
						|
  flag_no = (block_on->file_block-4) * I4MULTIPLY / t4->index->header.block_rw ;
 | 
						|
#endif
 | 
						|
 | 
						|
  if ( f4flag_is_set( f4, flag_no ) )
 | 
						|
    e4severe( e4result, E4_RESULT_COR ) ;
 | 
						|
 | 
						|
  if ( f4flag_set( f4, flag_no ) < 0 )
 | 
						|
    return -1 ;
 | 
						|
  if ( ! b4leaf(block_on) )
 | 
						|
  {
 | 
						|
#ifdef S4MDX
 | 
						|
    for( i = 0; i <= block_on->n_keys; i++ )
 | 
						|
    {
 | 
						|
      block_on->key_on = i ;
 | 
						|
      if ( flag_blocks( t4, f4 ) < 0 )
 | 
						|
        return -1 ;
 | 
						|
    }
 | 
						|
#else
 | 
						|
#ifdef S4CLIPPER
 | 
						|
    for( i = 0; i <= block_on->n_keys; i++ )
 | 
						|
    {
 | 
						|
      block_on->key_on = i ;
 | 
						|
      if ( flag_blocks( t4, f4 ) < 0 )
 | 
						|
        return -1 ;
 | 
						|
    }
 | 
						|
#endif
 | 
						|
#endif
 | 
						|
  }
 | 
						|
 | 
						|
  t4up(t4) ;
 | 
						|
  return 0 ;
 | 
						|
}
 | 
						|
#endif   /*  ifndef S4NDX  */
 | 
						|
#endif   /*  ifdef S4FOX   */
 | 
						|
 | 
						|
/* checks that all blocks in the file are on free list or are being used */
 | 
						|
static int i4check_blocks( INDEX4 *i4 )
 | 
						|
{
 | 
						|
#ifndef N4OTHER
 | 
						|
  TAG4  *tag_on ;
 | 
						|
  F4FLAG  flags ;
 | 
						|
  int     i, flag_no ;
 | 
						|
  S4LONG    tot_blocks, free_block, eof_block_no, len ;
 | 
						|
  CODE4 *c4 ;
 | 
						|
#ifdef S4FOX
 | 
						|
  long node1, node2, node3 ;
 | 
						|
#else
 | 
						|
  T4DESC  desc[48] ;
 | 
						|
#endif
 | 
						|
 | 
						|
  c4 = i4->code_base ;
 | 
						|
 | 
						|
#ifndef S4SINGLE
 | 
						|
  if ( i4lock( i4 ) < 0 )
 | 
						|
    return -1 ;
 | 
						|
#endif
 | 
						|
 | 
						|
  len = file4len(&i4->file) ;
 | 
						|
 | 
						|
#ifdef S4MDX
 | 
						|
  tot_blocks = (len-2048) / i4->header.block_rw ;
 | 
						|
#else
 | 
						|
  tot_blocks = len / B4BLOCK_SIZE ;
 | 
						|
#endif
 | 
						|
 | 
						|
  /* First Flag for the Free Chain */
 | 
						|
  f4flag_init( &flags, i4->code_base, tot_blocks ) ;
 | 
						|
 | 
						|
  eof_block_no = len/I4MULTIPLY ;
 | 
						|
#ifdef S4FOX
 | 
						|
  for ( free_block = i4->tag_index->header.free_list ; free_block ; )
 | 
						|
#else
 | 
						|
    for ( free_block = i4->header.free_list ; free_block ; )
 | 
						|
#endif
 | 
						|
    {
 | 
						|
      if ( free_block == eof_block_no  ||  c4->error_code < 0 )
 | 
						|
        break ;
 | 
						|
 | 
						|
#ifdef S4MDX
 | 
						|
      flag_no = (int)((free_block-4)*I4MULTIPLY/i4->header.block_rw) ;
 | 
						|
#else
 | 
						|
      flag_no = (int) (free_block / B4BLOCK_SIZE) ;
 | 
						|
#endif
 | 
						|
 | 
						|
      if ( free_block >= eof_block_no  || f4flag_is_set(&flags, flag_no) )
 | 
						|
      {
 | 
						|
        e4( c4, e4index, E4_INDEX_COR ) ;
 | 
						|
        break ;
 | 
						|
      }
 | 
						|
      f4flag_set( &flags, flag_no ) ;
 | 
						|
 | 
						|
#ifdef S4MDX
 | 
						|
      file4read_all( &i4->file, free_block * I4MULTIPLY + sizeof(S4LONG), &free_block, sizeof(free_block) ) ;
 | 
						|
#else
 | 
						|
      file4read_all( &i4->file, free_block * I4MULTIPLY, &free_block, sizeof(free_block) ) ;
 | 
						|
#endif
 | 
						|
 | 
						|
#ifdef S4BYTE_SWAP
 | 
						|
      free_block = x4reverse_long( (void *)&free_block ) ;
 | 
						|
#endif
 | 
						|
    }
 | 
						|
 | 
						|
#ifdef S4FOX
 | 
						|
  /* do the header tag */
 | 
						|
  tag_on = i4->tag_index ;
 | 
						|
  flag_no = (int)((tag_on->header_offset) / (long)B4BLOCK_SIZE) ;
 | 
						|
  if ( f4flag_is_set( &flags, flag_no ) )
 | 
						|
    e4severe( e4result, E4_RESULT_COR ) ;
 | 
						|
  f4flag_set( &flags, flag_no ) ;
 | 
						|
  f4flag_set( &flags, flag_no + 1L ) ;  /* tag header is 2 blocks long */
 | 
						|
 | 
						|
  if ( t4free_all( tag_on ) >= 0 )
 | 
						|
  {
 | 
						|
#ifdef S4FOX
 | 
						|
    node1 = -1L ;
 | 
						|
    node2 = tag_on->header.root ;
 | 
						|
    node3 = -1L ;
 | 
						|
    flag_blocks( tag_on, &flags, &node1, &node2, &node3 ) ;
 | 
						|
#else
 | 
						|
    flag_blocks( tag_on, &flags ) ;
 | 
						|
#endif
 | 
						|
 | 
						|
    /* Now Flag for each block in each tag */
 | 
						|
    i = 1 ;
 | 
						|
    for ( tag_on = 0 ;; i++ )
 | 
						|
    {
 | 
						|
      tag_on = (TAG4 *)l4next( &i4->tags,tag_on ) ;
 | 
						|
      if ( tag_on == 0 )
 | 
						|
        break ;
 | 
						|
      flag_no = (int)( tag_on->header_offset / (long)B4BLOCK_SIZE) ;
 | 
						|
      if ( f4flag_is_set( &flags, flag_no ) )
 | 
						|
        e4severe( e4result, E4_RESULT_COR ) ;
 | 
						|
      f4flag_set( &flags, flag_no ) ;
 | 
						|
      f4flag_set( &flags, flag_no + 1L ) ;  /* tag header is 2 blocks long */
 | 
						|
 | 
						|
      if ( t4free_all( tag_on ) < 0 )
 | 
						|
        break ;
 | 
						|
#ifdef S4FOX
 | 
						|
      node1 = -1L ;
 | 
						|
      node2 = tag_on->header.root ;
 | 
						|
      node3 = -1L ;
 | 
						|
      if ( node2 == -1 )
 | 
						|
      {
 | 
						|
        if ( file4read_all( &i4->file, tag_on->header_offset, &node2, sizeof(node2)) < 0 )
 | 
						|
          e4severe( e4info, E4_RESULT_COR ) ;
 | 
						|
#ifdef S4BYTE_SWAP
 | 
						|
        node2 = x4reverse_long( (void *)&node2 ) ;
 | 
						|
#endif
 | 
						|
      }
 | 
						|
      flag_blocks( tag_on, &flags, &node1, &node2, &node3 ) ;
 | 
						|
#else
 | 
						|
      flag_blocks( tag_on, &flags ) ;
 | 
						|
#endif
 | 
						|
    }
 | 
						|
  }
 | 
						|
#else
 | 
						|
  /* Read header information to flag the tag header blocks */
 | 
						|
  file4read_all( &i4->file, 512, desc, sizeof(desc) ) ;
 | 
						|
 | 
						|
  /* Now Flag for each block in each tag */
 | 
						|
  i = 1 ;
 | 
						|
  for ( tag_on = 0 ;; i++ )
 | 
						|
  {
 | 
						|
    tag_on = (TAG4 *)l4next( &i4->tags, tag_on ) ;
 | 
						|
    if ( tag_on == 0 )
 | 
						|
      break ;
 | 
						|
#ifdef S4BYTE_SWAP
 | 
						|
    desc[i].header_pos = x4reverse_long( (void *)&desc[i].header_pos ) ;
 | 
						|
    desc[i].x1000 = 0x1000 ;
 | 
						|
#endif
 | 
						|
 | 
						|
    flag_no = (int) ((desc[i].header_pos * I4MULTIPLY - 2048) / (long) i4->header.block_rw) ;
 | 
						|
    if ( f4flag_is_set( &flags, flag_no ) )
 | 
						|
      e4severe( e4result, E4_RESULT_COR ) ;
 | 
						|
    f4flag_set( &flags, flag_no ) ;
 | 
						|
 | 
						|
    if ( t4free_all(tag_on) < 0 )
 | 
						|
      break ;
 | 
						|
    flag_blocks( tag_on, &flags ) ;
 | 
						|
  }
 | 
						|
#endif
 | 
						|
 | 
						|
  if ( f4flag_is_all_set( &flags, 0, tot_blocks - 1 ) == 0 )
 | 
						|
    e4( i4->code_base, e4result, E4_RESULT_LOS ) ;
 | 
						|
 | 
						|
  u4free( flags.flags ) ;
 | 
						|
  if ( i4->code_base->error_code < 0 )
 | 
						|
    return -1 ;
 | 
						|
 | 
						|
#endif
 | 
						|
  return 0 ;
 | 
						|
}
 | 
						|
 | 
						|
int S4FUNCTION i4check( INDEX4 *i4 )
 | 
						|
{
 | 
						|
  TAG4 *tag_on ;
 | 
						|
#ifdef S4HAS_DESCENDING
 | 
						|
  int old_desc, rc ;
 | 
						|
#endif
 | 
						|
 | 
						|
#ifdef S4DEBUG
 | 
						|
  if ( i4 == 0 )
 | 
						|
    e4severe( e4parm, E4_I4CHECK ) ;
 | 
						|
#endif
 | 
						|
 | 
						|
  if ( i4->code_base->error_code < 0 )
 | 
						|
    return -1 ;
 | 
						|
 | 
						|
  if ( i4update( i4 ) < 0 )
 | 
						|
    return -1 ;
 | 
						|
  if ( i4check_blocks(i4) < 0 )
 | 
						|
    return -1 ;
 | 
						|
 | 
						|
  for( tag_on = 0 ;; )
 | 
						|
  {
 | 
						|
    tag_on = (TAG4 *)l4next( &i4->tags, tag_on ) ;
 | 
						|
    if ( tag_on == 0 )
 | 
						|
      return 0 ;
 | 
						|
#ifdef S4HAS_DESCENDING
 | 
						|
    old_desc = tag_on->header.descending ;
 | 
						|
    tag_on->header.descending = 0 ;   /* force ascending */
 | 
						|
    rc = t4check( tag_on ) ;
 | 
						|
    tag_on->header.descending = (short) old_desc ;   /* return to previous */
 | 
						|
    if ( rc < 0 ) return rc ;
 | 
						|
#else
 | 
						|
    if ( t4check(tag_on) < 0 )
 | 
						|
      return -1 ;
 | 
						|
#endif
 | 
						|
  }
 | 
						|
}
 | 
						|
 | 
						|
#endif  /* S4INDEX_OFF */
 | 
						|
 | 
						|
int S4FUNCTION d4check( DATA4 *d4 )
 | 
						|
{
 | 
						|
#ifdef S4INDEX_OFF
 | 
						|
  return 0 ;
 | 
						|
#else
 | 
						|
  INDEX4 *index_on ;
 | 
						|
  int rc ;
 | 
						|
 | 
						|
  if ( d4 == 0 )
 | 
						|
#ifdef S4DEBUG
 | 
						|
    e4severe( e4parm, E4_D4CHECK ) ;
 | 
						|
#else
 | 
						|
  return -1 ;
 | 
						|
#endif
 | 
						|
 | 
						|
#ifndef S4SINGLE
 | 
						|
  rc = d4lock_file( d4 ) ;   /* returns -1 if code_base->error_code < 0 */
 | 
						|
  if ( rc )
 | 
						|
    return rc ;
 | 
						|
#endif
 | 
						|
 | 
						|
  for( index_on = 0 ;; )
 | 
						|
  {
 | 
						|
    index_on = (INDEX4 *)l4next( &d4->indexes, index_on ) ;
 | 
						|
    if ( index_on == 0 )
 | 
						|
      return 0 ;
 | 
						|
    if ( i4check( index_on ) < 0 )
 | 
						|
      return -1 ;
 | 
						|
  }
 | 
						|
#endif  /* S4INDEX_OFF */
 | 
						|
}
 |