/*!
  @file           vos06u.c
  @author         RaymondR
  @brief          Virtual File ( User Part )
  @see            

\if EMIT_LICENCE

    ========== licence begin  GPL
    Copyright (c) 2001-2005 SAP AG

    This program is free software; you can redistribute it and/or
    modify it under the terms of the GNU General Public License
    as published by the Free Software Foundation; either version 2
    of the License, or (at your option) any later version.

    This program is distributed in the hope that it will be useful,
    but WITHOUT ANY WARRANTY; without even the implied warranty of
    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
    GNU General Public License for more details.

    You should have received a copy of the GNU General Public License
    along with this program; if not, write to the Free Software
    Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
    ========== licence end



\endif
*/




//
//  INCLUDE FILES
//
#include "gos00.h"
#include "heo00.h"
#include "heo46.h"
#include "geo007_1.h"
#include "geo007_2.h"
#include "hos06.h"
#include "gos44.h"


//
//  DEFINES
//

#define MOD__  "VOS06UC : "
#define MF__   MOD__"UNDEFINED"


//
//  MACROS
//


//
//  LOCAL TYPE AND STRUCT DEFINITIONS
//


//
//  EXTERNAL VARIABLES
//


//
//  EXPORTED VARIABLES
//


//
//  LOCAL VARIABLES
//

static HOSTFILE_CTRL_REC        FileCtrlTab [ HF_MAX ];
static PVOID                    pBufPool;
static BOOLEAN                  fFirstCall = TRUE;  // used for the first call
                                                    // to sqlfinit()

//
//  EXTERNAL FUNCTION PROTOTYPES
//

#ifdef WINTERM
extern BOOL e71_file_open_save_box ( VF_FILENAMEC szHostFileName,
                                     BOOL         FileSave );
#endif

//
//  LOCAL FUNCTION PROTOTYPES
//


//
// ========================== GLOBAL FUNCTIONS ================================
//

void  SqlDevSize ( const char                        *devspace,
                   tsp00_Int4                        *devcapacity ,
                   tsp00_ErrTextc                     errtext,
                   tsp00_Bool                        *ok) 

{
   *ok = FALSE ;
}


/*------------------------------*/


VOID    sqlfinit    (   INT2     buf_pool_size,
                        tsp00_Int4 *poolptr,
                        BOOLEAN  *ok            )
  {
  #undef  MF__
  #define MF__ MOD__"sqlfinit"

  DBGIN;

  sql06c_finit ( buf_pool_size, poolptr,
                 &fFirstCall, FileCtrlTab, &pBufPool, ok );

  DBGOUT;
  }



/*------------------------------*/


VOID    sqlfopen    (   tsp00_VFilename     vf_filename,
                        OPCODES             direction,
                        VF_RESOURCE         resource,
                        INT4*               hostfileno,
                        VF_FORMAT*          format,
                        INT4*               rec_len,
                        INT4                poolptr,
                        INT2                buf_count,
                        VF_BUFFERADDRESS*   block,
                        VF_RETURN*          error,
                        ERRORTEXT           errtext         )
  {
  #undef  MF__
  #define MF__ MOD__"sqlfopen"
  #ifdef WINTERM
  PATHNAME           szTempFileName;
  PATHNAME           szHostFileName;
  #else
  VF_FILENAMEC       szHostFileName;
  #endif
  PHOSTFILE_CTRL_REC pHF;
  ERRORTEXT          TmpErrText;

  DBGIN;

  eo46PtoC ( szHostFileName,  vf_filename, sizeof(tsp00_VFilename) );

  DBG3 (( MF__, "szHostFileName  = '%s'", szHostFileName ));
  DBG3 (( MF__, "direction       = %u",   direction ));
  DBG3 (( MF__, "resource        = %u",   resource ));
  DBG3 (( MF__, "* format        = %u",   *format ));
  DBG3 (( MF__, "* rec_len       = %d",   *rec_len ));
  DBG3 (( MF__, "poolptr         = 0x%x", poolptr));
  DBG3 (( MF__, "buf_count       = %d",   buf_count ));


  *error = VF_OK;

  if ( direction == VREAD_ORA )
    direction = VREAD;

  // --- check the parameters 'format' and 'direction'

  // --- noch wird die LZU-Spez. in diesem Punkt nicht so richtig befolgt !!!
  /*
  if ( ( direction == VREAD )  &&
       (( *format == VF_RECORD ) || ( *format == VF_PLAINTEXT ))  )
    {
    *error = VF_NOTOK;
    sql46c_build_error_string ( errtext, ERRMSG_VF_ILL_READ_FORMAT_COMB, 0 );
    DBGOUT;
    return;
    }
  */

  if ((   *format    == VF_UNKNOWN    ) &&
      (( direction   == VWRITE       ) ||
       ( direction   == VOVERWRITE   ) ||
       ( direction   == VAPPEND      )))
    {
    * error = VF_NOTOK;
    sql46c_build_error_string ( errtext, ERRMSG_VF_ILL_READ_FORMAT_COMB, 0 );
    DBGOUT;
    return;
    }

  #ifdef WINTERM
  strcpy ( szTempFileName,  szHostFileName );
  sql44c_subst_log_parts ( szHostFileName,  szTempFileName );
  (VOID)e71_file_open_save_box ( szHostFileName,
                                 (( direction == VWRITE    ) ||
                                  ( direction == VAPPEND   ) ||
                                  ( direction == VOVERWRITE)) );
  #endif

  // --- check host file name
  if ( !strlen ( szHostFileName ) )
    {
    *error = VF_NOTOK;
    sql46c_build_error_string ( errtext, ERRMSG_VF_ILL_HOST_FILE_NAME, 0 );
    DBGOUT;
    return;
    }

  // --- get pointer to a free file-control-record
  * error = (VF_RETURN) sql06c_search ( szHostFileName, FileCtrlTab,
                                        hostfileno, &pHF, errtext );

  DBG3 (( MF__, "*hostfileno(sql06c_search) = %d", *hostfileno ));

  if ( * error == VF_OK )
    {
    pHF->lHeaderLength = buf_count > 1 && *format == VF_RECORD &&
                         direction == VREAD
                       ? buf_count * sizeof (VF_BLOCK) : sizeof (VF_BLOCK) ;

    // --- reserve buffers for file i/o and internal use
    * error = (VF_RETURN) sql06c_reserve_buffer ( pHF, pBufPool, resource,
                                                  buf_count, block, errtext );

    if ( * error == VF_OK )
      {
      strcpy ( pHF->szFileName,  szHostFileName );

      pHF->lDevType        = sql44c_get_dev_type_by_filename (pHF->szFileName);
      pHF->lEndOfBuffer    = sizeof (VF_BLOCK);
      pHF->lRecordLength   = * rec_len;
      pHF->FileFormat      = * format;
      pHF->Direction       = direction;
      pHF->fBlocked        = sql06c_blocked_file( pHF->szFileName,
                                                  *format,
                                                  *rec_len);

      if ((pHF->lDevType == DT_OTHER) || (pHF->lDevType == DT_NUL))
        {
        DBG3 (( MF__, "Device type: DT_OTHER or DT_NUL" ));

        switch ( direction )
          {
          case VWRITE:
            pHF->lMaxPos = pHF->lEndOfBuffer;
            * error = (VF_RETURN)
                      sql06c_write_open ( pHF->szFileName, pHF, errtext );
            break;

          case VOVERWRITE:
            pHF->lMaxPos = pHF->lEndOfBuffer;
            * error = (VF_RETURN)
                      sql06c_overwrite_open ( pHF->szFileName, pHF, errtext );
            break;

          case VREAD:
            pHF->lMaxPos = 0;
            * error = (VF_RETURN)
                      sql06c_read_open ( pHF->szFileName, pHF, errtext );
            break;

          case  VAPPEND:
            pHF->lMaxPos = pHF->lEndOfBuffer;
            * error = (VF_RETURN)
                      sql06c_append_open ( pHF->szFileName, pHF, errtext );
            break;

          default :
            * error = VF_NOTOK;
            sql46c_build_error_string ( errtext, ERRMSG_VF_ILL_DIREC, 0 );
            break;
          }
        }
      else if (pHF->lDevType == DT_TAPE)
        {
        DBG3 (( MF__, "Device type == DT_TAPE" ));

        switch ( direction )
          {
          case VWRITE    :
          case VOVERWRITE:
            pHF->lMaxPos = pHF->lEndOfBuffer;
            * error = (VF_RETURN)
                      sql06c_tape_open ( pHF->szFileName, pHF, errtext, FALSE );
            break;

          case VREAD:
            pHF->lMaxPos = 0;
            * error = (VF_RETURN)
                      sql06c_tape_open ( pHF->szFileName , pHF, errtext, TRUE );
            break;

          default      :
            * error = VF_NOTOK;
            sql46c_build_error_string ( errtext, ERRMSG_VF_ILL_DIREC, 0 );
            break;
          }
        }
      else if (pHF->lDevType == DT_PIPE)
        {
        DBG3 (( MF__, "Device type == DT_PIPE" ));

        switch ( direction )
          {
          case VWRITE    :
          case VOVERWRITE:
            pHF->lMaxPos = pHF->lEndOfBuffer;
            * error = (VF_RETURN)
                      sql06c_pipe_write_open ( pHF->szFileName, pHF, errtext );
            break;

          case VREAD:
            pHF->lMaxPos = 0;
            * error = (VF_RETURN)
                      sql06c_pipe_read_open ( pHF->szFileName, pHF, errtext );
            break;

          default      :
            * error = VF_NOTOK;
            sql46c_build_error_string ( errtext, ERRMSG_VF_ILL_DIREC, 0 );
            break;
          }
        }
      else if ((pHF->lDevType == DT_CON )  ||
               (pHF->lDevType == DT_CONOUT ))
        {
        DBG3 (( MF__, "Device type == DT_CONOUT" ));

        switch ( direction )
          {
          case VWRITE    :
          case VOVERWRITE:
            pHF->lMaxPos = pHF->lEndOfBuffer;
            * error = (VF_RETURN)
                      sql06c_con_open ( pHF, errtext );
            break;

          default      :
            * error = VF_NOTOK;
            sql46c_build_error_string ( errtext, ERRMSG_VF_ILL_DIREC, 0 );
            break;
          }
        }
      else if (pHF->lDevType == DT_CONIN )
        {
        DBG3 (( MF__, "Device type == DT_CONIN" ));

        switch ( direction )
          {
          case VREAD:
            pHF->lMaxPos = 0;
            * error = (VF_RETURN)
                      sql06c_con_open ( pHF, errtext );
            break;

          default      :
            * error = VF_NOTOK;
            sql46c_build_error_string ( errtext, ERRMSG_VF_ILL_DIREC, 0 );
            break;
          }
        }
      else
        {
        DBG3 (( MF__, "invalid device type" ));
        sql46c_build_error_string ( errtext, ERRMSG_VF_WRONG_FILE_NAME, 0 );
        * error = VF_NOTOK;
        }
      }

    // --- tidy up some things
    if (( * error == VF_NOTOK ) || ( * error == VF_EOF ))
      {
      if ( * error == VF_EOF )
        {
        DBG3 (( MF__, "invalid device type" ));
        sql46c_build_error_string ( errtext, ERRMSG_VF_WRONG_FILE_NAME, 0 );
        * error = VF_NOTOK;
        }

      if ( pHF->hfFileHandle != (HANDLE)INVALID_HANDLE_VALUE )
        {
        CLOSE_FILE (pHF->hfFileHandle);
        }

      // --- free buffers
      sql06c_free_buffer ( pHF, pBufPool, buf_count, TmpErrText );

      // --- init file control structure
      sql06c_init_file_ctrl ( pHF );

      // --- set unvalid host file number
      * hostfileno = 0;
      }
    }

  DBGOUT;
  return;
  }



/*------------------------------*/

VOID    sqlfclose_next_tape   (   INT4*               hostfileno,
                                  BOOLEAN             erase,
                                  INT4                poolptr,
                                  INT2                buf_count,
                                  VF_BUFFERADDRESS    block,
                                  VF_RETURN*          error,
                                  VF_RETURN*          next_tape_error,
                                  ERRORTEXT           errtext         )
  {
  #undef  MF__
  #define MF__ MOD__"sqlfclose_next_tape"
#if defined(_WIN32)
  PHOSTFILE_CTRL_REC  pHF;

  if ( sql06c_valid_fileno( * hostfileno, FileCtrlTab ) == FALSE)
    {
    * error = VF_NOTOK;
    sql46c_build_error_string ( errtext, ERRMSG_VF_BAD_FILENO, 0 );
    DBGOUT;
    return;
    }

  pHF     = &FileCtrlTab[*hostfileno - 1];
  pHF->fNxtInAutoLoader = TRUE ;
  sqlfclose ( hostfileno, erase, poolptr, buf_count,
              block, error, errtext ) ;
  pHF->fNxtInAutoLoader = FALSE ;
  * next_tape_error = (VF_RETURN ) pHF->lNxtInAutoLoaderError ;
#else
  sqlfclose ( hostfileno, erase, poolptr, buf_count,
              block, error, errtext ) ;
  * next_tape_error = (VF_RETURN ) VF_NOTOK ;
#endif
  DBGOUT;
  return;
  }

/*------------------------------*/


VOID    sqlfclose   (   INT4*               hostfileno,
                        BOOLEAN             erase,
                        INT4                poolptr,
                        INT2                buf_count,
                        VF_BUFFERADDRESS    block,
                        VF_RETURN*          error,
                        ERRORTEXT           errtext         )
  {
  #undef  MF__
  #define MF__ MOD__"sqlfclose"
  PHOSTFILE_CTRL_REC  pHF;
  ERRORTEXT           TmpErrText;


  DBGIN;

  DBG3 (( MF__, "* hostfileno  = 0x%x", * hostfileno ));

  if ( sql06c_valid_fileno( * hostfileno, FileCtrlTab ) == FALSE)
    {
    * error = VF_NOTOK;
    sql46c_build_error_string ( errtext, ERRMSG_VF_BAD_FILENO, 0 );
    DBGOUT;
    return;
    }

  * error = VF_OK;
  pHF     = &FileCtrlTab[*hostfileno - 1];

  DBG3 (( MF__, "pHF->ulState        = %d", pHF->ulState ));
  DBG3 (( MF__, "pHF->lPos           = %d", pHF->lPos ));
  DBG3 (( MF__, "pHF->szFileName     = '%s'", pHF->szFileName ));
  DBG3 (( MF__, "erase               = %f", erase ));
  DBG3 (( MF__, "poolptr             = 0x%x", poolptr ));
  DBG3 (( MF__, "buf_count           = %d", buf_count ));
  DBG3 (( MF__, "block               = 0x%x", block ));

  // --- be sure we have written out the complete data
  if ((pHF->Direction == VWRITE)      ||
      (pHF->Direction == VOVERWRITE)  ||
      (pHF->Direction == VAPPEND))
    {
    if (( pHF->lPos > UNDEF ) && (pHF->ulState != HFS_ERROR))
      {
      if (( pHF->FileFormat == VF_PLAINTEXT ) &&
          ( pHF->lDevType   == DT_TAPE ))
        {
        // -- write complete blocks only
        pHF->lPos = pHF->lMaxPos - 1;
        }

      // --- write last block - write 'pHF->lPos' bytes
      * error = (VF_RETURN) sql06c_putbuffer ( pHF,  errtext );
      }
    }

  if ( * error != VF_OK )
    {
    // --- free buffers
    sql06c_free_buffer ( pHF, pBufPool, buf_count, TmpErrText );
    sql06c_close ( pHF, erase, TmpErrText );
    }
  else
    {
    // --- free buffers
    * error = (VF_RETURN)
              sql06c_free_buffer ( pHF, pBufPool, buf_count, errtext );

    if ( * error == VF_NOTOK )
      sql06c_close ( pHF, erase, TmpErrText );
    else
        * error = (VF_RETURN) sql06c_close ( pHF, erase, errtext );
    }

  // --- init file control structure
  sql06c_init_file_ctrl ( pHF );

  DBGOUT;
  return;
  }



/*------------------------------*/


VOID    sqlfread    (   INT4*               hostfileno,
                        VF_BUFFERADDRESS    block,
                        INT4*               length,
                        VF_RETURN*          error,
                        ERRORTEXT           errtext     )
  {
  #undef  MF__
  #define MF__ MOD__"sqlfread"
  PHOSTFILE_CTRL_REC  pHF;


  DBGIN;

  DBG3 (( MF__, "*hostfileno = 0x%x", *hostfileno ));

  if ( sql06c_valid_fileno( *hostfileno, FileCtrlTab ) == FALSE ) {
      *error = VF_NOTOK;

      DBG1 (( MF__, ERRMSG_VF_BAD_FILENO ));
      MSGD (( ERR_VF_BAD_FILENO ));
      sql46c_build_error_string ( errtext, ERRMSG_VF_BAD_FILENO, 0 );

      DBGOUT;

      return;
  }

  *error = VF_OK;
  pHF    = &FileCtrlTab[*hostfileno - 1];

  DBG3 (( MF__, "pHF->lRecordLength     = %d", pHF->lRecordLength ));
  DBG3 (( MF__, "pHF->ulEffFileFormat   = %d", pHF->ulEffFileFormat ));
  DBG3 (( MF__, "* length               = %d", * length ));
  DBG3 (( MF__, "block                  = 0x%x", block));

  if (( pHF -> Direction == VREAD ) && ( pHF -> ulState == HFS_USED )) {
      if ( pHF -> ulEffFileFormat == VF_PLAINTEXT ) {
          // --- read ASCII
          *error = (VF_RETURN)
                   sql06c_read_asc_var ( pHF, block, length, errtext );
          if ( *error != VF_OK ) {
              DBG3 (( MF__, "SQLFREAD ( sql06c_read_asc_var ): "
                             "returning, with error %d", *error ));
          }
      }
      else {
          // --- read ASCII
          if ( pHF -> lRecordLength == 0 ) {
              // --- read binary variable
              *error = (VF_RETURN)
                       sql06c_read_bin_var ( pHF, block, length, errtext );
              if ( *error != VF_OK ) {
                  DBG3 (( MF__, "SQLFREAD ( sql06c_read_bin_var ): "
                                 "returning, with error %d", *error ));
              }
          }
          else {
              // --- read binary fixed
              *error = (VF_RETURN)
                       sql06c_read_bin_fix ( pHF, block, length, errtext );
              if ( *error != VF_OK ) {
                  DBG3 (( MF__, "SQLFREAD ( sql06c_read_bin_fix ): "
                                 "returning, with error %d", *error ));
              }
          }
      }
  }
  else {
      if (( pHF -> Direction == VREAD ) && ( pHF -> ulState == HFS_EOF )) {
          // --- end of file
          *length = 0;
          *error  = VF_EOF;
          if ( *error != VF_OK ) {
              DBG3 (( MF__, "SQLFREAD ( EOF reached ): "
                             "returning, with error %d", *error ));
          }
      }
      else {
          // --- error
          *error         = VF_NOTOK;
          pHF -> ulState = HFS_ERROR;

          DBG1 (( MF__, ERRMSG_VF_ILL_FILE_DESC ));
          MSGD (( ERR_VF_ILL_FILE_DESC ));
          sql46c_build_error_string ( errtext, ERRMSG_VF_ILL_FILE_DESC, 0 );
      }
  }

  DBG3 (( MF__, "* length    = %d", * length ));
  DBG3 (( MF__, "block [ 0 ] = %c", block [ 0 ] ));
  DBG3 (( MF__, "block  adr  = 0x%x", block  ));

  if ( *error != VF_OK ) {
      DBG3 (( MF__, "SQLFREAD: returning, with error %d", *error ));
  }

  DBGOUT;

  return;
  }



/*------------------------------*/


VOID    sqlfwrite   (   INT4*               hostfileno,
                        VF_BUFFERADDRESS    block,
                        INT4                length,
                        VF_RETURN*          error,
                        ERRORTEXT           errtext         )
  {
  #undef  MF__
  #define MF__ MOD__"sqlfwrite"
  PHOSTFILE_CTRL_REC     pHF = NULL;


  DBGIN;

  DBG3 (( MF__, "* hostfileno  = 0x%x", * hostfileno ));

  if ( sql06c_valid_fileno ( *hostfileno, FileCtrlTab ) == FALSE ) {
      *error = VF_NOTOK;

      DBG3 (( MF__, "%d not a valid file no", *hostfileno ));
      sql46c_build_error_string ( errtext, ERRMSG_VF_BAD_FILENO, 0 );

      DBGOUT;

      return;
  }

  DBG3 (( MF__, "%d is a valid file no", *hostfileno ));
  *error = VF_OK;
  pHF    = &FileCtrlTab [ *hostfileno - 1 ];

  if ((( pHF -> Direction == VWRITE     )  ||
       ( pHF -> Direction == VOVERWRITE )  ||
       ( pHF -> Direction == VAPPEND    )) &&
      ( pHF -> ulState != HFS_ERROR )) {

      *error = VF_OK;
      pHF    = &FileCtrlTab [ *hostfileno - 1 ];

      DBG3 (( MF__, "pHF -> lRecordLength = %d", pHF->lRecordLength ));
      DBG3 (( MF__, "pHF -> FileFormat    = %d", pHF->FileFormat ));
      DBG3 (( MF__, "length               = %d", length ));
      DBG3 (( MF__, "block                = 0x%x", block));


      if ( pHF -> FileFormat == VF_PLAINTEXT ) {
          // --- write ASCII
          *error = (VF_RETURN)
                   sql06c_write_asc_var ( pHF, block, length, errtext );
      }
      else {
          // --- write binary
          if (( pHF -> lRecordLength == 0   ||
                pHF -> lRecordLength == -1 ) &&
			  ( pHF -> FileFormat    != VF_STREAM )) {
              // --- write binary variable
              *error = (VF_RETURN)
                       sql06c_write_bin_var ( pHF, block, length, errtext );
          }
          else {
              // --- check length of binary fixed
              if ( pHF -> lRecordLength == length      ||
                   pHF -> FileFormat    == VF_4K_BLOCK ||
                   pHF -> FileFormat    == VF_STREAM ) {
                  // --- read binary fixed
                  *error = (VF_RETURN)sql06c_write_bin_fix (pHF,  block,
                                                            length, errtext );
              }
              else {
                  *error         = VF_NOTOK;
                  pHF -> ulState = HFS_ERROR;
                  sql46c_build_error_string ( errtext,
                                              ERRMSG_VF_NON_CONST_REC_LEN,
                                              0 );
              }
          }
      }

      if ( pHF -> lFilePos + pHF->lPos + 1 > pHF -> lMaxFilePos ) {
          pHF -> lMaxFilePos = pHF -> lFilePos + pHF -> lPos + 1;
      }
  }
  else {
      // --- error
      *error         = VF_NOTOK;
      pHF -> ulState = HFS_ERROR;
      sql46c_build_error_string ( errtext, ERRMSG_VF_ILL_FILE_DESC, 0 );
  }

  if ( *error != VF_OK ) {
      DBG3 (( MF__, "sqlfwrite: returning, with error %d ", *error ));
  }

  DBGOUT;

  return;
  }



/*------------------------------*/


VOID    os06_fseek    (   PINT4       plHostFileNo,
                        INT4        lFilePos,
                        VF_RETURN*  peError,
                        ERRORTEXT   acErrorText,
                        int         fAllowText)

  {
  #undef  MF__
  #define MF__ MOD__"sqlfseek"
  ULONG               ulActualFilePos;
  INT4                lSeekPos;
  PHOSTFILE_CTRL_REC  prcHF;


  DBGIN;

  DBG3 (( MF__, "lFilePos = %d", lFilePos ));

  // check for valid internal file number
  if ( !sql06c_valid_fileno( *plHostFileNo, FileCtrlTab )) {
      *peError = VF_NOTOK;

      DBG1    (( MF__, ERRMSG_VF_BAD_FILENO     ));
      MSGD    ((        ERR_VF_BAD_FILENO       ));
      sql46c_build_error_string ( acErrorText, ERRMSG_VF_BAD_FILENO, 0 );

      DBGOUT;

      return;
  }

  // initialize return parameter
  *peError = VF_OK;
  prcHF    = &FileCtrlTab [ *plHostFileNo - 1 ];

  DBG3 (( MF__, "prcHF -> ulFileType = %d", prcHF -> ulFileType ));
  DBG3 (( MF__, "prcHF -> FileFormat = %d", prcHF -> FileFormat ));

  // seek only for disk files ( not for character devices or pipes )
  if ( prcHF -> ulFileType == VFT_DISK     &&
#if defined (NO_TEXT_SEEK)
        prcHF -> FileFormat != VF_PLAINTEXT &&
#endif
       prcHF -> lDevType   != DT_TAPE ) {
      switch ( prcHF -> FileFormat ) {
          
# if !defined (NO_TEXT_SEEK)          
          case VF_PLAINTEXT:
              if (!fAllowText) {
                  *peError = VF_NOSEEK;

                  DBG1    (( MF__, ERRMSG_VF_FTYPE_NOT_TO_SEEK     ));
                  sql46c_build_error_string ( acErrorText, 
                      ERRMSG_VF_FTYPE_NOT_TO_SEEK, 0 );

                  DBGOUT;

                  return;
              }
              if ( prcHF -> Direction != VREAD ) {
                  *peError = (VF_RETURN)
                             sql06c_putbuffer ( prcHF, acErrorText );
              }

              if ( *peError == VF_OK ) {
		  /* adjust lFilePos because externally, first byte is "1" */
		  --lFilePos;
                  *peError = (VF_RETURN)
                             sql06c_posbuffer ( prcHF, lFilePos,
                                                FILE_BEGIN, &ulActualFilePos,
                                                acErrorText );

                  if ( *peError == VF_OK ) {
                      prcHF->lMaxPos = 0; /* This should have been
                            done in sql06c_posbuffer, but who knows what
                            this would break for binary files DD */
                      FILL ( prcHF -> pBuffer, '\0', prcHF -> lEndOfBuffer );
                      *peError = (VF_RETURN)
                                 sql06c_getbuffer ( prcHF, acErrorText );
                  }
              }
              
              break;
#endif
          case VF_STREAM:
              lSeekPos = lFilePos + KBYTE_4 - 1;
              DBG3 (( MF__, "lSeekPos = %d", lSeekPos ));

              *peError = VF_OK;
              DBG3 (( MF__, "prcHF -> lMaxFilePos = %d",
                              prcHF -> lMaxFilePos ));

              if ( lSeekPos > prcHF -> lMaxFilePos ) {
                  // lSeekPos > EOF
                  *peError = VF_EOF;

                  DBG1    (( MF__, ERRMSG_VF_SEEK_REACHED_EOF     ));
                  sql46c_build_error_string ( acErrorText,
                                              ERRMSG_VF_SEEK_REACHED_EOF, 0 );

                  prcHF -> ulState = HFS_END;

                  DBGOUT;

                  return;
              }
          break;

          case VF_RECORD:
          case VF_UNKNOWN:
          default:
              lSeekPos = prcHF -> lRecordLength * ( lFilePos - 1 ) +
                           prcHF -> lHeaderLength - 1;
                           // KBYTE_4  - 1;
              DBG3 (( MF__, "lSeekPos = %d", lSeekPos ));

              DBG3 (( MF__, "prcHF -> Direction = %d", prcHF ->Direction ));

              if ( prcHF -> FileFormat == VF_RECORD &&
                   prcHF -> Direction  == VREAD ) {

                  lSeekPos++;
              }

              *peError = VF_OK;
              DBG3 (( MF__, "prcHF -> lMaxFilePos = %d",
                              prcHF -> lMaxFilePos ));

              if ( lSeekPos >
                 ( prcHF -> lMaxFilePos - prcHF -> lRecordLength )) {
                  // lSeekPos > EOF
                  *peError = VF_EOF;

                  DBG1    (( MF__, ERRMSG_VF_SEEK_REACHED_EOF     ));
                  sql46c_build_error_string ( acErrorText,
                                              ERRMSG_VF_SEEK_REACHED_EOF, 0 );

                  prcHF -> ulState = HFS_END;

                  DBGOUT;

                  return;
              }

              if ( prcHF -> Direction != VREAD ) {
                  *peError = (VF_RETURN)
                             sql06c_putbuffer ( prcHF, acErrorText );
              }

              if ( *peError == VF_OK ) {
                  *peError = (VF_RETURN)
                             sql06c_posbuffer ( prcHF, lSeekPos,
                                                FILE_BEGIN, &ulActualFilePos,
                                                acErrorText );

                  if ( prcHF -> lRecordLength < MAXBUFFERLENGTH  &&
                                                *peError == VF_OK ) {
                      // prcHF -> lRecordLength < mbl
                      FILL ( prcHF -> pBuffer, '\0', prcHF -> lEndOfBuffer );
                      *peError = (VF_RETURN)
                                 sql06c_getbuffer ( prcHF, acErrorText );
                  }
              }
          break;
      }
  }
  else {
      *peError = VF_NOSEEK;

      DBG1    (( MF__, ERRMSG_VF_FTYPE_NOT_TO_SEEK     ));
      sql46c_build_error_string ( acErrorText, ERRMSG_VF_FTYPE_NOT_TO_SEEK, 0 );

      DBGOUT;

      return;
  }

  DBGOUT;
  }


  
VOID    sqlfseek    (   PINT4       plHostFileNo,
                        INT4        lFilePos,
                        VF_RETURN*  peError,
                        ERRORTEXT   acErrorText     )

  {
      os06_fseek (plHostFileNo, lFilePos, peError, acErrorText, FALSE);
  }

/*------------------------------*/
  
VOID    sqlftextseek    (   PINT4       plHostFileNo,
                        INT4        lFilePos,
                        VF_RETURN*  peError,
                        ERRORTEXT   acErrorText     )

  {
      os06_fseek (plHostFileNo, lFilePos, peError, acErrorText, TRUE);
  }

/*------------------------------*/
  
VOID    sqlftell    (   PINT4       plHostFileNo,
                        INT4*       lFilePos,
                        VF_RETURN*  peError,
                        ERRORTEXT   acErrorText     )

  {
  #undef  MF__
  #define MF__ MOD__"sqlftell"
  PHOSTFILE_CTRL_REC  prcHF;


  DBGIN;

  // check for valid internal file number
  if ( !sql06c_valid_fileno( *plHostFileNo, FileCtrlTab )) {
      *peError = VF_NOTOK;

      DBG1    (( MF__, ERRMSG_VF_BAD_FILENO     ));
      MSGD    ((        ERR_VF_BAD_FILENO       ));
      sql46c_build_error_string ( acErrorText, ERRMSG_VF_BAD_FILENO, 0 );

      DBGOUT;

      return;
  }

  // initialize return parameter
  *peError = VF_OK;
  prcHF    = &FileCtrlTab [ *plHostFileNo - 1 ];

  DBG3 (( MF__, "prcHF -> ulFileType = %d", prcHF -> ulFileType ));
  DBG3 (( MF__, "prcHF -> FileFormat = %d", prcHF -> FileFormat ));

  // seek only for disk files ( not for character devices or pipes )
  if ( prcHF -> ulFileType == VFT_DISK     &&
       prcHF -> lDevType   != DT_TAPE ) {
       
       *lFilePos = (prcHF->lFilePos + 1) + max (prcHF->lPos + 1, 0);
       /* adjust lFilePos, because externally, first byte is "1" */
       ++(*lFilePos);
       /* fprintf (stdout, "filepos: %d; pos: %d; result: %d  \n",
           prcHF->lFilePos, prcHF->lPos, *lFilePos);*/
  }
  else {
      *peError = VF_NOSEEK;

      DBG1    (( MF__, ERRMSG_VF_FTYPE_NOT_TO_SEEK     ));
      sql46c_build_error_string ( acErrorText, ERRMSG_VF_FTYPE_NOT_TO_SEEK, 0 );

      DBGOUT;

      return;
  }

  DBGOUT;
  }


/*------------------------------*/


VOID    sqlferase   (   tsp00_VFilename acFileName,
                        VF_RETURN*      peError,
                        ERRORTEXT       acErrorText     )
  {
  #undef  MF__
  #define MF__ MOD__"sqlferase"
  VF_FILENAMEC    acFileNameC;
  PATHNAME        szPhysFileName;
  APIRET          rc       = NO_ERROR;
  LONG            lAtt     = 0;
  ULONG           ulTmp    = 0;


  DBGIN;

  // initializing
  *peError = VF_OK;

  eo46PtoC ( acFileNameC, acFileName, sizeof ( tsp00_VFilename ) );
  DBG3 (( MF__, "acFileNameC = '%s'", acFileNameC ));

  sql44c_subst_log_parts ( szPhysFileName, acFileNameC );
  DBG3 (( MF__, "szPhysFileName = '%s'", szPhysFileName ));

  // check file for regular file. if true delete file
  rc = sql44c_get_file_info ( szPhysFileName, &lAtt, &ulTmp, &ulTmp );

  if (( rc == NO_ERROR ) && !(lAtt &= FILE_DIRECTORY) && !(lAtt &= FILE_READONLY)) {
      #if defined(_WIN32)
       if (DeleteFile(szPhysFileName) == FALSE)
         rc = GetLastError();
      #else
       rc = DosDelete ( szPhysFileName );
      #endif

      if (rc != NO_ERROR) {
          *peError = VF_NOTOK;

          DBG1    (( MF__, ERRMSG_VF_DELETE     ));
          MSGD    ((        ERR_VF_DELETE       ));
          sql46c_build_error_string ( acErrorText, ERRMSG_VF_DELETE, 0 );
      }
  }
  else {
      // no regfile
      *peError = VF_NOTOK;

      DBG1    (( MF__, ERRMSG_VF_NO_REG_FILE ));
      sql46c_build_error_string ( acErrorText, ERRMSG_VF_NO_REG_FILE, 0 );
  }

  DBGOUT;
  }


//
// ========================== LOCAL FUNCTIONS =================================
//


//
// =============================== END ========================================
//
