/*!================================================================

  module:       vpi01Libpcrl.c

 -------------------------------------------------------------------

  responsible:  BurkhardD

  special area: Dynamic Runtime Loader

  description:                 
                Laedt die Interface Runtime aus dem versionsabhaengigen 
		Verzeichniss. 


  see also:

  -------------------------------------------------------------------------





    ========== licence begin  GPL
    Copyright (c) 1998-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




 ===================================================================*/

/*==================================================================*
 *  INCLUDES                                                        *
 *==================================================================*/

#include "vpr100.h"
#include "heo102.h"
#include "heo02x.h"
#include "gsp09.h"
#define sql_default
#include "vpi01Libpcrl.h"
#include "vpr09Config.h"
#include "gpr00.h"
#include "vpi00fc.h"
#include "vpr07c.h"
#include "precom/sqlinfo.h"
#include "precom/sqlcancel.h"
#include "vpr09DynaDesc.h"
#include "vpi01GetModuleName.h"
#include <stdlib.h>
#include <stdio.h>
#include <malloc.h>
#include <time.h>
#ifdef WIN32
#include <process.h>
#else
#include <unistd.h>
#endif

/*==================================================================*
 *  EXTERNAL PROTOTYPES                                             *
 *==================================================================*/

extern char *s98CPCDrvBuildNumber(void);

/*==================================================================*
 *  EXTERNAL VARIABLES                                              *
 *==================================================================*/
extern sqlcatype sqlca;
extern int argc;

/*==================================================================*
 *  DECLARATIONS                                                    *
 *==================================================================*/

#define MAX_TRACE_FILE_SIZE 51200
#define LIBNAME_PI01 "libpcr"
static char *szLibName = LIBNAME_PI01;
static char *pi01LibPath = SHLPATH_IP00;
static char *pi01Lib64Path = SHL64PATH_IP00;
static boolean pi01TraceEnabled = false;

#define PI01COMPONENT P07_PRODNAME" "P07_PC_RUNTIME
static char *pi01WhatString = "@(#)"COMP_NAME_C_PREC_SP100" Dynamic Loader "P07_FILEVERSION_STR" for "SHLPATH_IP00""PATHSEP_IP00""SHL64PATH_IP00""LIBNAME_PI01""DLLEXT_IP00;

typedef enum TraceType_epi01 {
  ok_epi01,
  wrn_epi01,
  err_epi01
} TraceType_epi01;

static tpi01_PathC pi01_szInstallationPath;
static char *pi01DBLIBPATH = "SAPDBLIBPATH";
static char *pi01INSTKEY =   "SAPDBINSTKEY";
static FILE *pi01TraceFile;
static int LoadErr = TRUE;
static int WriteTrace = FALSE;

typedef char *(*pi01charPROC)();
typedef void *(*pi01voidPROC)();
typedef int   (*pi01intPROC)();
typedef struct SQLDA *(*pi01SQLDAPROC)();

#define sqlPROC(proc) sqlPROC lp##proc

typedef struct {
  sqlPROC(sqccatb);
  sqlPROC(sqcccan);
  sqlPROC(sqccver);
  sqlPROC(sqccchk);
  sqlPROC(sqls);
  sqlPROC(sqlr);
  sqlPROC(sqccv2b);
  sqlPROC(sqccv3b);
  sqlPROC(sqcccab);
  sqlPROC(sqccpab);
  sqlPROC(sqcckab);
  sqlPROC(sqlCPCPrBind);
  sqlPROC(sqlCPCStBind);
  sqlPROC(sqlCPCLocalBind);
  sqlPROC(sqccxab);
  sqlPROC(sqccsdb);
  sqlPROC(sqccfnb);
  sqlPROC(sqccmab);
  sqlPROC(sqccgab);
  sqlPROC(sqcctrs);
  sqlPROC(sqccmts);
  sqlPROC(sqlCPCExecDirect);
  sqlPROC(sqlCPCExecute);
  sqlPROC(sqlCPCTryExecute);
  sqlPROC(sqlCPCOpen);
  sqlPROC(sqlCPCDescribe);
  sqlPROC(sqcccmd);
  sqlPROC(sqcctrl);
  sqlPROC(sqccnol);
  sqlPROC(sqlCPCNoLog);
  sqlPROC(sqlCPCBegin);
  sqlPROC(sqccdam);
  sqlPROC(sqccdaa);
  sqlPROC(sqlCPCEnd);
  sqlPROC(sqccrcn);
  sqlPROC(sqccstp);
  sqlPROC(sqccexi);
  sqlPROC(sqlCPCPrepare);
  pi01voidPROC lpsqlcaddr;
  sqlPROC(sqlcisol);
  sqlPROC(sqlclu);
  sqlPROC(sqlprc);
  sqlPROC(sqlnul);
  sqlPROC(sqlblnk);
  sqlPROC(sqlglm);
  sqlPROC(sqlgetver);
  sqlPROC(sqlgetbuild);
  pi01SQLDAPROC lpsqlald;
  pi01intPROC   lpsqlcsize;
  pi01voidPROC  lpsqlcdynp;
  sqlPROC(sqlCPCDeclare);
  sqlPROC(sqlTCompGetConnection);
  pi01intPROC lpsqlTCompGetSessionByName;
  SQLABAPInfoProc *(*lpsqlInitABAPInfo)(SQLABAPInfoProc *fnABAPInfo);
  SQLCheckPointProc *(*lpsqlInitCheckPoint)(SQLCheckPointProc *fnCheckPoint);
  sqlPROC(sqlCPCEndInit);
  sqlPROC(sqlCPCCheck);
  sqlPROC(sqlCPCCheckU);
  sqlPROC(sqlCPCOption);
  sqlPROC(sqlCPCTraceLine);
  sqlPROC(sqlCPCPutDriverName);
  pi01charPROC lpsqlCPCGetDriverName;
  SQLCancelProc *(*lpsqlInitCancelProc)(SQLCancelProc *sqlCancelCallBack);
  sqlPROC(sqlCPCGaBind);
} pi01DynaPCRProcs;

static pi01DynaPCRProcs pi01PCRProc; /* ANSI C initialisiert alle Elemente mit 0 */
#define PI01PCRCALL(proc, param) \
if (!pi01PCRProc.lp##proc)\
   pi01PCRProc.lp##proc = pi01DynamicLoad(#proc);\
if (pi01PCRProc.lp##proc)\
   pi01PCRProc.lp##proc param

typedef struct {
  sqlPROC(sqlinit);
  sqlPROC(sqlfinish);
  sqlPROC(sqluid);
  sqlPROC(sqlos);
  sqlPROC(sqlresult);
  sqlPROC(sqlsleep);
  sqlPROC(sqlgetenv);
  sqlPROC(sqlaconnect);
  sqlPROC(sqlarelease);
  sqlPROC(sqlarequest);
  sqlPROC(sqlareplyavailable);
  sqlPROC(sqlareceive);
  sqlPROC(sqlacancel);
  sqlPROC(sqladump);
  sqlPROC(sqlpon);
  sqlPROC(sqlprint);
  sqlPROC(sqlpoff);
  sqlPROC(sqlfinit);
  sqlPROC(sqlfopen);
  sqlPROC(sqlfclose);
  sqlPROC(sqlfread);
  sqlPROC(sqlfwrite);
  sqlPROC(sqlfseek);
  sqlPROC(sqlferase);
  sqlPROC(sqlexec);
  sqlPROC(sqlfopenc);
  sqlPROC(sqlfopenp);
  sqlPROC(sqlfclosec);
  sqlPROC(sqlfclosep);
  sqlPROC(sqlfreadc);
  sqlPROC(sqlfreadp);
  sqlPROC(sqlfwritec);
  sqlPROC(sqlfwritep);
  sqlPROC(sqlfseekc);
  sqlPROC(sqlfseekp);
  sqlPROC(sqlferasec);
  sqlPROC(sqlferasep);
  sqlPROC(sqlgetuser);
  sqlPROC(sqlputuser);
  sqlPROC(sqlindexuser);
  sqlPROC(sqlinfouser);
  pi01intPROC lpsqlclearuser;
  sqlPROC(sqlfree);
  sqlPROC(sqlallocat);
  sqlPROC(sqldattime);
  sqlPROC(sqlclock);
  sqlPROC(sqlhostname);
  sqlPROC(sqlnodename);
  sqlPROC(sqltoff);
  sqlPROC(sqlcharsetname);
  sqlPROC(sqlabort);
  sqlPROC(sqlftellp);
  sqlPROC(sqltermvar);
  sqlPROC(sqlfclose_next_tape);
  sqlPROC(SqlDevSize);
  sqlPROC(sqlton);
  sqlPROC(sqlttable);
  sqlPROC(sqltio);
  sqlPROC(sqltermid);
  sqlPROC(sqlwrite);
  sqlPROC(sqlvalidatealloc);
  sqlPROC(sqlk_assert);
  pi01intPROC lpsqlk_rangeviolation;
} pi01LZUProcs;

static pi01LZUProcs pi01LZUProc; /* ANSI C initialisiert alle Elemente mit 0 */

#define PI01LZUCALL(proc, param) \
if (!pi01LZUProc.lp##proc)\
   pi01LZUProc.lp##proc = pi01DynamicLoad(#proc);\
if (pi01LZUProc.lp##proc)\
  pi01LZUProc.lp##proc param


static HANDLE pi01hinstPCR=0;
static char pi01szVersion[32] = "";

/*==================================================================*
 *  FUNCTION PROTOTYPES                                             *
 *==================================================================*/

static void pi01TraceLineHeader(TraceType_epi01 tType);

/*==================================================================*
 *  CODE                                                            *
 *==================================================================*/

char *pi01GetMyName() {
  return("Dynamic Loader");
}

void pi01Error(char *szErrorText) {
    int cbLen = PR07MIN( (70-22-3) , (int)strlen(szErrorText));
    sqlca.sqlcode = -888; /*Could not load libpcr*/
    strncpy ( &(sqlca.sqlerrmc[0]), "Could not load libpcr ", 22);
    if (szErrorText) {
      strncpy( &(sqlca.sqlerrmc[22]),      "("        ,1);
      strncpy( &(sqlca.sqlerrmc[23]),      szErrorText,cbLen);
      strncpy( &(sqlca.sqlerrmc[23+cbLen]),")"        ,1);
      sqlca.sqlerrml = (23+ cbLen +1);
    }        
    else {
      sqlca.sqlerrml = 22;
    }    
}

void pi01ErrorAndExit(char *szErrorText) {
  pi01Error(szErrorText);
  exit(-1); 
}

void pi01ErrorNoVersionInfoFound(char *szVersion) {
  char szMsg[512];
  sprintf(szMsg, "%s:\nNo versioninfo found for '%s'.", pi01GetMyName(), szVersion);
  pi01Error(szMsg);
}

void pi01ErrorLibNotFoundVersion(char *szLibrary, char *szVersion, tsp00_ErrText errtext) {
  char szMsg[512];
/*  sprintf(szMsg, "%s:\nLibrary %s for version '%s' could not be loaded:%s.", pi01GetMyName(), szLibrary, szVersion, errtext);*/
  sprintf(szMsg, "%s-%s.", szVersion, errtext);
  pi01Error(szMsg);
}

void pi01ErrorLibNotFoundKey(char *szLibrary, char *szKey, tsp00_ErrText errtext) {
  char szMsg[512];
/*  sprintf(szMsg, "%s:\nLibrary %s for key '%s' could not be loaded:%s.", pi01GetMyName(), szLibrary, szKey, errtext);*/
  sprintf(szMsg, "Library for key %s not found:%s", szKey, errtext);
  pi01Error(szMsg);
}

void pi01ErrorPathLibNotFound(char *szLibrary, char *szVersion, tsp00_ErrText errtext)
{
  char szMsg[512];
/*  sprintf(szMsg, "%s:\nLibrary %s on %s could not be loaded:%s.", 
	  pi01GetMyName(), szLibrary, pi01DBLIBPATH, errtext);*/
  sprintf(szMsg, "%s-%s.", szLibrary, errtext);
  pi01Error(szMsg);
  sprintf (szMsg, " %s version %s - %s.\n", szLibrary, szVersion, errtext);
}

void pi01ErrorFuntionNotFound(char *szFunction, char *szLibrary)
{
  char szMsg[512];
/*  sprintf(szMsg, "%s:\nFunction %s not found in %s.", pi01GetMyName(), szFunction, szLibrary);*/
  sprintf(szMsg, "Function %s not found in %s.", szFunction, szLibrary);
  pi01Error(szMsg);
}


void pi01ErrorInstallation(char *szVersion)
{
  char szMsg[512];
/*  sprintf(szMsg, "%s:\nNo registered version (%s) found.", pi01GetMyName(), szVersion);*/
  sprintf(szMsg, "No registered version (%s) found.", szVersion);
  pi01Error(szMsg);
}

void sqlgetver(char *szVersion, char* szMinVersion);
void sqlgetbuild(char *szBuild);

boolean pi01IsGoodPCRLib(HANDLE hLib, char *szVersion, char* szMinVersion)
{
  char szRelNr[8];
  P07_FORMATVERSION(szRelNr); 
  if (hLib) {
    sqlgetver(szVersion, szMinVersion);    
    if (strcmp(szRelNr, szMinVersion) >= 0)
      if (strcmp(szRelNr, szVersion) <= 0)
	return(TRUE);
  }
  return(FALSE);
}

char *pi01GetPid()
{
  static char *pidstrp = NULL;
  if (pidstrp == NULL) {
    static char pidstr[30];
    sprintf(pidstr, "0x%x", getpid());
    pidstrp = pidstr;
  }
  return pidstrp;
}

char *pi01GetTime()
{
  static char tstr[30];
  time_t ltime;
  struct tm *ltm;
  time(&ltime);
  ltm = localtime(&ltime);
  strftime(tstr, sizeof(tstr), "%Y-%m-%d %H:%M:%S", ltm);
  return(tstr);
}

char *pi01UnpackVersion(char *szVersion, char *szCompactVersion)
{
  char *c = szCompactVersion;
  int Major, Minor, Corr;
  Major = (c[0]-'0');
  Minor = (c[1]-'0')*10+(c[2]-'0');
  Corr = (c[3]-'0')*10+(c[4]-'0');
  sprintf(szVersion, "%d.%d.%d", Major, Minor, Corr);
  return szVersion;
}

void pi01IfAppendPathSep(char *szPath)
{
  static char *PathSep = PATHSEP_IP00;
  int len = (int)strlen(szPath);
  if (len > 0) {
    if (szPath[len-1] != PathSep[0]) {
      strcat(szPath, PathSep);
    }
  }  
}

static void pi01TraceOpenFile () {
  static int first = TRUE;
  
  if (first) {
    tsp00_ErrText ErrText;
    char szTraceFile[2048];
    char buf[2048];
    ConfigResult_tpr09 res;

    res = pr09ConfigGetRuntimeStringEx (SAPDB_GLOBALS_SECTION, PI01_LDRDIAG_KEY, buf,
				 sizeof(buf)-sizeof(TRACE_FILE_NAME)-1, ErrText);
    if (res == ERR_OK_epr09) {
      if (strcmp (buf, "YES")) {
	pi01TraceFile = NULL;
	pi01TraceEnabled = false;
	return;
      } else {
	pi01TraceEnabled = true;
      }
    } else {
      pi01TraceFile = NULL;
      pi01TraceEnabled = false;
    }


    if (pi01TraceEnabled == true) {
           RTE_Path ConfigPath;
           RTE_IniFileErrtext iniErrText;
           if ( RTE_GetUserSpecificConfigPath ( ConfigPath,
                                                true,
                                                iniErrText ) ) {
   	       strcpy (szTraceFile, ConfigPath);
           strcat (szTraceFile, TRACE_FILE_NAME);
           pi01TraceFile = fopen (szTraceFile, "a");
	       if (!pi01TraceFile)
	           strcpy (szTraceFile, TRACE_FILE_NAME);
      }
      pi01TraceFile = fopen (szTraceFile, "a");
      if (pi01TraceFile) {
	fseek (pi01TraceFile, 0, SEEK_END);
	if (ftell (pi01TraceFile) > MAX_TRACE_FILE_SIZE) {
	  char szTraceFileBak[2048];
	  
	  fclose (pi01TraceFile);
	  strcpy (szTraceFileBak, szTraceFile);
	  strcat (szTraceFileBak, TRACE_FILE_NAME_SUFFIX);
	  remove (szTraceFileBak);
	  rename (szTraceFile, szTraceFileBak);
	  pi01TraceFile = fopen (szTraceFile, "a");
	}
      } else {
	fprintf (stderr, "ERROR: Can't open trace file %s. Using stderr.\n", 
		 szTraceFile);
	pi01TraceFile = stderr;
      }
    }
    first = FALSE;
  }
}

static void pi01TraceCloseFile () {
  static int first = TRUE;

  if ((pi01TraceEnabled == false) ||
      (pi01TraceFile == NULL))
    return;

  if (first){
    if (fclose (pi01TraceFile)) {
      fprintf (stderr, "ERROR: Can't close trace file.\n");
    }
    if ((LoadErr == FALSE) && (WriteTrace == FALSE))
      remove (TRACE_FILE_NAME);
    first = FALSE;
  }
}

static void pi01TraceLineHeader(TraceType_epi01 tType)
{
  if ((pi01TraceEnabled == false) ||
      (pi01TraceFile == NULL))
    return;

  fprintf(pi01TraceFile, "%s %s", pi01GetTime(), pi01GetPid());
  switch(tType) {
  case (ok_epi01):{
    fprintf(pi01TraceFile, " OK ");
    break;
  }
  case (wrn_epi01):{
    fprintf(pi01TraceFile, " WNR");
    break;
  }  
  case (err_epi01):{
    fprintf(pi01TraceFile, " ERR");
    break;
  }  
  }
}

static void pi01TraceAppVersionFailed(char *szPath, char *szCVersion, char *szCMinVersion)
{
  static firstmsg = TRUE;
  char szVersion[64];
  char szMinVersion[64];

  if ((pi01TraceEnabled == false) ||
      (pi01TraceFile == NULL))
    return;

  if (firstmsg) {
    pi01TraceLineHeader (err_epi01);
    fprintf (pi01TraceFile, " Wrong version. %s supports %s - %s.\n", 
	     szPath, pi01UnpackVersion(szVersion, szCMinVersion), 
	     pi01UnpackVersion(szMinVersion, szCVersion));
    firstmsg = FALSE;
  }
}

static void pi01TracePathLibNotFound(char *szLibrary, char *szVersion, tsp00_ErrText errtext) {
  static firstmsg = TRUE;

  if ((pi01TraceEnabled == false) ||
      (pi01TraceFile == NULL))
    return;

  if (firstmsg) {
    pi01TraceLineHeader (err_epi01);
    fprintf (pi01TraceFile, " %s version %s - %s.\n", szLibrary, szVersion, errtext);
    firstmsg = FALSE;
  }
}

static void pi01TraceLibNotFoundKey(char *szLibrary, char *szKey, tsp00_ErrText errtext) {
  static firstmsg = TRUE;

  if ((pi01TraceEnabled == false) ||
      (pi01TraceFile == NULL))
    return;

  if (firstmsg) {
    pi01TraceLineHeader (err_epi01);
    fprintf (pi01TraceFile, " Library for key %s not found.\n", szKey);
    firstmsg = FALSE;
  }
}

static void pi01TraceLibNotFound(char *szPath) {
  if ((pi01TraceEnabled == false) ||
      (pi01TraceFile == NULL))
    return;

  pi01TraceLineHeader (err_epi01);
  fprintf (pi01TraceFile, " Library not found: %s.\n", szPath);
}


#ifdef NOTIMPLEMENTED
pi01ProtOpen()
{
  static FILE *pi01_protfile;
  if (pi01_protfile) {
    tpi01_PathC szProtFile; 
    tsp01_RteError pfad_error;	
    if (! sqlGetIndependentProtPath(szProtFile, TERM_WITH_DELIMITER_EO01, &error)) {
      fprintf(stderr, "Could not find independent prot path");
      exit -99;
    }
    pi01IfAppendPathSep(szProtFile);
    strcat(szProtFile, "irtdiag");
    pi01_protfile = fopen(szProtFile,"w+");
    if (!pi01_protfile) {
      fprintf(stderr, "Could not open protfile %s", szProtFile);
      exit ERR_OPEN_PROT_FILE;
    }
  }
}
#endif

static void pi01TraceAppStarted(char *szVersion)
{
  static firstmsg = TRUE;

  if ((pi01TraceEnabled == false) ||
      (pi01TraceFile == NULL))
    return;

  if (firstmsg) {
    pi01TraceLineHeader (ok_epi01);
    fprintf (pi01TraceFile, " Application %s %s started.\n", 
	     vpi01ModuleName (pi01TraceFile), szVersion);
    firstmsg = FALSE;
  }
}

static void pi01TraceLoadLibSucceed(char *szPath, char *szCompactVersion)
{
  char szVersion[64];
  char szBuild[16] = "";

  if ((pi01TraceEnabled == false) ||
      (pi01TraceFile == NULL))
    return;

  pi01TraceLineHeader (ok_epi01);
  sqlgetbuild(szBuild);
  if (szBuild[0] == '\0') {
    fprintf (pi01TraceFile, " %s %s Build <unknown> load succeed.\n", szPath, 
             pi01UnpackVersion(szVersion, szCompactVersion));
  } else {
    fprintf (pi01TraceFile, " %s %s Build %s load succeed.\n", szPath, 
             pi01UnpackVersion(szVersion, szCompactVersion), szBuild);
  }
  LoadErr = FALSE;
}

int pi01IsEqualVersion(tpi01_VersionID *p1, tpi01_VersionID *p2)
{
  int i;
  for (i = 0; i < 4; ++i) {
    if (p1->No[i] < p2->No[i]) {
      return -1;
    }
    if (p1->No[i] > p2->No[i]) {
      return 1;
    }
  }
  return 0;  
}

static int pi01OlderVersion(tpi01_VersionInfo **p1, tpi01_VersionInfo **p2)
{
  return pi01IsEqualVersion(&(*p1)->version, &(*p2)->version);
}

typedef struct {
  int cbIndex;
  tpr09DynamicDescriptor *pVersionList;
} tpi01VersionDesc;

void pi01InitVersionDesc(tpi01VersionDesc *pVersionInfo)
{
  pVersionInfo->cbIndex = 0;
  pVersionInfo->pVersionList = NULL;
}

tpi01VersionDesc *pi01NewVersionDesc()
{
  tpi01VersionDesc *p = malloc(sizeof(tpi01VersionDesc));
  if (p)
    pi01InitVersionDesc(p);
  return p;
}

void pi01DeleteVersionDesc(tpi01VersionDesc *pVersionInfo)
{
  if (pVersionInfo) {
    if (pVersionInfo->pVersionList)
      pr09DeleteDescriptor(pVersionInfo->pVersionList);
    free(pVersionInfo);
  }
}

int pi01OpenVersionInfo(tpi01VersionDesc *VerDesc)
{
  ConfigHandle_tpr09 hConfig;                /* Handle to configuration file */
  RTE_RegistryLocation location;             /* location of retrieved entry */
  tsp00_ErrText ErrText;                     /* Errormessage returned from Config */
  int count=0;
  ConfigResult_tpr09 ret = ERR_OK_epr09;
  tpi01_VersionInfo *InstVer;                  /* versioninfo from Configuration file */

  VerDesc->pVersionList = pr09NewDescriptor(5, sizeof(*InstVer));
  hConfig = pr09ConfigOpenRuntimeSection( SAPDB_RUNTIME_SECTION, ErrText);
  if (hConfig) {
    tpi01_PathC szPath="";
    VersionStr_tpi01 szVersion;
    while (ERR_OK_epr09 == ret) {
      InstVer = pr09AddItem(VerDesc->pVersionList);
      ret = pr09ConfigNextRuntimeEntry(hConfig, &location, szPath, sizeof(szPath), szVersion, sizeof(szVersion), ErrText);
      if (ERR_OK_epr09 == ret) {
        pi01VersionS2B(szVersion, &InstVer->version);
        strncpy(InstVer->szPath, szPath, sizeof(InstVer->szPath));
        count++;
      } else if (ret == ERR_READ_VALUE_epr09 ){
        continue;
      } else if (ERR_NO_MORE_DATA_epr09 == ret) {
          pr09CloseItem(VerDesc->pVersionList);
      } 
    }      
    pr09SetIndex(VerDesc->pVersionList, Start_epr09);
    pr09ConfigCloseRuntimeSection(hConfig, ErrText);
  }
  return(count);
}

void pi01AppendOSLibPath(char *szPath)
{
  pi01IfAppendPathSep(szPath);
  strcat(szPath, pi01LibPath);
  pi01IfAppendPathSep(szPath);
  strcat(szPath, pi01Lib64Path);
  pi01IfAppendPathSep(szPath);
}

void pi01OrderVersionInfo(tpi01VersionDesc *pVersionDesc)
{
  if (pVersionDesc) {
    pr09OrderItems(pVersionDesc->pVersionList, (int(*)(const void *, const void *))pi01OlderVersion);
  }
  pr09SetIndex(pVersionDesc->pVersionList, Start_epr09);
}

tsp00_Bool pi01NextVersionInfo(
tpi01VersionDesc *pVersionDesc, 
tpi01_VersionInfo *versioninfo, 
char *szPath)
{
  tpi01_VersionInfo *installinfo;  
  for(;;) {
    if (installinfo = pr09GetNextItem(pVersionDesc->pVersionList)) {
      if (versioninfo->version.szKey[0] != '\0') {
	/* Installationkey ist set, ignore versionnumber */
	if (!strcmp(versioninfo->version.szKey, installinfo->version.szKey)) {
	  strcpy(szPath, installinfo->szPath);
	  pi01AppendOSLibPath(szPath);
	  return TRUE;
	}
	/* key does't match */
	continue;
      }
      if (pi01OlderVersion(&installinfo, &versioninfo) >= 0) {
	/* newer or equal installed version is returned */
	strcpy(szPath, installinfo->szPath);
	pi01AppendOSLibPath(szPath);
      }
      else
	continue;
      return TRUE;
    }
    else
      return FALSE;
  }
}

/*!
  Function: pi01LoadPCRLib 

  description: Laedt die Interface Runtime Bibliothek.

  arguments:
      szPath       [in]  Pfad auf das Installationsverzeichniss.
                         Ermittelt mittel sqlxnext_installation

  return value: Handle auf die Interface Runtime Bibliothek
 */

HANDLE pi01LoadPCRLib(char *szPath, tsp00_ErrText *errtext)
{
  strcat(szPath, szLibName);
  return sqlLoadLibrary(szPath, (char*)errtext, sizeof(tsp00_ErrText));
}

/*!
  Function: pi01FreePCRLib 

  description: Gibt die Reference (Handle) auf die Interface Runtime 
               Bibliothek und deren Funktioen frei.

  arguments:
      hinst  [in]  Handle der Library.

  return value: ---
 */

void pi01FreePCRLib(HANDLE hinst)
{
  tsp00_ErrText errtext;
  boolean ret = sqlFreeLibrary(hinst, (char*)&errtext, sizeof(errtext));
  memset(&pi01PCRProc, 0, sizeof(pi01PCRProc));
  memset(&pi01LZUProc, 0, sizeof(pi01LZUProc));
}

/*!
  Function: pi01DynamicLoad 

  description: Laedt eine exportierte Funktion der Interface Runtime Bibliothek.

  arguments:
      szSqlFunction  [in]  Name der zu ladenen Funktion.

  return value: Zeiger auf die Funktion oder NULL im Fehlerfalle.
 */

sqlPROC pi01DynamicLoad(char *szSqlFunction)
{
  sqlPROC p=NULL;  
  tsp00_ErrText errtext;
  tpi01VersionDesc *hVersionDesc=NULL;
  errtext[0] = '\0';
  if (!pi01hinstPCR) {
    tpi01_VersionInfo thisversion;
    char * szLibPath = NULL;
    char * szInstKey = NULL;
    boolean openlib = FALSE;

    pi01TraceOpenFile ();
    pi01TraceAppStarted(P07_RELSTR);
    
    if (!hVersionDesc && !szLibPath ) {
      tsp00_Int4 a[4] = { 0, 0, 0, 0 };
      szLibPath = getenv(pi01DBLIBPATH); /*environment variable SAPDBLIBPATH*/ 
      szInstKey = getenv(pi01INSTKEY);   /*environment variable SAPDBINSTKEY*/ 
      sscanf(P07_RELSTR, "%d.%d.%d.%d.", &a[0], &a[1], &a[2], &a[3]); /*current Version*/
      thisversion.version.No[0] = (0xFF & a[0]);
      thisversion.version.No[1] = (0xFF & a[1]);
      thisversion.version.No[2] = (0xFF & a[2]);
      thisversion.version.No[3] = (0xFF & a[3]);
      if (szInstKey) {
        /*SAPDBINSTKEY was set*/  
	strncpy(thisversion.version.szKey, szInstKey, sizeof(thisversion.version.szKey));
	thisversion.version.szKey[sizeof(thisversion.version.szKey)-1] = '\0';
      }
      else {
	thisversion.version.szKey[0] = '\0';
      }

      if (szLibPath) {
        /*SAPDBLIBPATH was set*/
	strcpy(pi01_szInstallationPath, szLibPath);
	pi01IfAppendPathSep(pi01_szInstallationPath);
	openlib = TRUE;
      }
      else {
        /*get registered libpcr`s from registry and build a sorted list of it*/
	hVersionDesc = pi01NewVersionDesc();
	if (pi01OpenVersionInfo(hVersionDesc)) {
	  pi01OrderVersionInfo(hVersionDesc);      
	}
	else {
	  pi01ErrorInstallation(P07_RELSTR);
	  return (NULL);
        }
      }
    }/*end if !hVersionDesc && !szLibPath */
    
    while (!pi01hinstPCR) {
    /*try to find libpcr by SAPDBLIBPATH or by registry*/
      if (hVersionDesc) {
	openlib = pi01NextVersionInfo(hVersionDesc, &thisversion, pi01_szInstallationPath);
      }
      if (openlib) {
	char szVersion[8], szMinVersion[8];
	pi01hinstPCR = pi01LoadPCRLib(pi01_szInstallationPath, &errtext);
	if (szLibPath && !pi01hinstPCR) {
	  /* Fehlermeldung kommt unten */
	  break;
	}
	if (!pi01IsGoodPCRLib(pi01hinstPCR, szVersion, szMinVersion)) {
          if (!pi01hinstPCR) {
	    pi01TraceLibNotFound(pi01_szInstallationPath);
	  } else {
	    pi01TraceAppVersionFailed(pi01_szInstallationPath, szVersion, szMinVersion);
	    pi01FreePCRLib(pi01hinstPCR);
	    pi01hinstPCR = NULL;
	  }
	}
	else {
	  pi01TraceLoadLibSucceed(pi01_szInstallationPath, szVersion);
	}
      }
      else {
	break;
      }
    }/*end while*/
    
    if (hVersionDesc){
      /*delete list of libpcr`s found in registry*/  
      pi01DeleteVersionDesc(hVersionDesc);
    }
    if (!pi01hinstPCR) {
      /*error occured*/  
      if (szLibPath) {
	pi01ErrorPathLibNotFound(pi01_szInstallationPath, P07_RELSTR, errtext);
	pi01TracePathLibNotFound(pi01_szInstallationPath, P07_RELSTR, errtext);
      }
      else {
	if (szInstKey) {
	  pi01ErrorLibNotFoundKey(pi01_szInstallationPath, szInstKey, errtext);
	  pi01TraceLibNotFoundKey(pi01_szInstallationPath, szInstKey, errtext);
	}
	else {
	  pi01ErrorLibNotFoundVersion(pi01_szInstallationPath, P07_RELSTR, errtext);
	}
      }
    }
    else {
      /*write location and name of libpcr into trace*/
      sqlCPCPutDriverName(pi01_szInstallationPath);
    }
  }

  if (pi01hinstPCR) {
  /*try to load function*/
    if(!(p = sqlGetProcAddress(pi01hinstPCR, szSqlFunction, (char*)&errtext, sizeof(errtext)))) {
      pi01ErrorFuntionNotFound(szSqlFunction, pi01_szInstallationPath);
      return(NULL);
    }
  } else
    pi01TraceCloseFile ();

  return(p);
}

void pi01VersionS2B(char *szVersion, tpi01_VersionID *version)
{
  int No[4] = {0,0,0,0};
  if (version && szVersion) {
    memset(version, 0, sizeof(tpi01_VersionID));
    sscanf(szVersion, PI01_VERSION_FMT, &No[0], &No[1], &No[2], &No[3], version->szKey);
    version->No[0] = No[0];
    version->No[1] = No[1];
    version->No[2] = No[2];
    version->No[3] = No[3];
  }
}

void pi01VersionB2S(tpi01_VersionID *version, char *szVersion)
{
  if (szVersion && version) {
    sprintf(szVersion, PI01_VERSION_FMT, version->No[0], version->No[1], version->No[2], version->No[3], version->szKey);
  }
}

/* Precompiler Runtime Functions */

void sqccatb (sqlatpointer p1, long p2, long p3, long p4, char* p5, char* p6)
{
  PI01PCRCALL(sqccatb, (p1, p2, p3, p4, p5, p6));
}

void sqcccan (sqlcatype *sqlca, sqlxatype *sqlxa, long stno)
{
  PI01PCRCALL(sqcccan, (sqlca, sqlxa, stno));
}

void sqccver (sqlcatype *sqlca, sqlxatype *sqlxa, long stno)
{
  PI01PCRCALL(sqccver, (sqlca, sqlxa, stno));
}

void sqccchk (sqlcatype *sqlca, sqlxatype *sqlxa,
	      sqlint2 *sqlstci, sqlint2 *sqlexti, long sqlext, long connplen)
{
  PI01PCRCALL(sqccchk, (sqlca, sqlxa, sqlstci, sqlexti, sqlext, connplen));
}

void sqls (sqlva1en *sqlva1, long va1ix, long va1ix1, long cnt,
	   long size, void *addr)
{
  PI01PCRCALL(sqls, (sqlva1, va1ix, va1ix1, cnt, size, addr));
}

void sqlr (sqlva1en *sqlva1, long va1ix, long va1ix1, void *addr)
{
  PI01PCRCALL(sqlr, (sqlva1, va1ix, va1ix1, addr));
}

void sqccv2b (sqlva2en *sqlva2, long va2no, long va2typ, long va2size,
	long va2digit, long va2frac, long va2const)
{
  PI01PCRCALL(sqccv2b, (sqlva2, va2no, va2typ, va2size, va2digit, va2frac, va2const));
}

void sqccv3b (sqlva3en *sqlva3, long va3no, long va3naml, char *va3name)
{
  PI01PCRCALL(sqccv3b, (sqlva3, va3no, va3naml, va3name));
}

void sqcccab (sqlcatype *sqlca, long dbkind, long datetime, long ansi)
{
  PI01PCRCALL(sqcccab, (sqlca, dbkind, datetime, ansi));
}

void sqccpab (sqlparentry *sqlpa, long pano, long pakind, long paparm2,
	long paparm3, long paparm4)
{
  PI01PCRCALL(sqccpab, (sqlpa, pano, pakind, paparm2, paparm3, paparm4));
}

void sqcckab (sqlorentry *sqlor, sqlkaentry *sqlka, long kano,
	long katype, long kastate, long kacount, long kaindex,
	long kastcount, long kastindex, long kamacro,
	long kaprindex, long kadiindex, long kalineno,
	long kafaindex, long kaatindex, long kacuindex, long kamode)
{
  PI01PCRCALL(sqcckab, (sqlor, sqlka, kano, katype, kastate, kacount, kaindex,
	kastcount, kastindex, kamacro, kaprindex, kadiindex, kalineno,
	kafaindex, kaatindex, kacuindex, kamode));
}

void sqlCPCPrBind(sqlprentry *sqlpr, long prno, long prStmtNameIndex, 
      long prCursorNameIndex, long prstate,
      long prkaindex, long prarea, long prDescribe, long prstcount, long prstindex,
      long prcuindex, long prnaml, long prcunaml,
      char *prname, char *prcuname)
{
  PI01PCRCALL(sqlCPCPrBind, (sqlpr, prno, prStmtNameIndex, prCursorNameIndex, 
			     prstate, prkaindex, prarea, prDescribe, prstcount,
			     prstindex, prcuindex, prnaml, prcunaml, prname, 
			     prcuname));
}

void sqlCPCStBind (sqlcatype *sqlca, sqlxatype *sqlxa, long stno, long fOption, long sess, long stlen, char *stval)
{
  PI01PCRCALL(sqlCPCStBind, (sqlca, sqlxa, stno, fOption, sess, stlen, stval));
}

void sqlCPCLocalBind (sqlcatype *sqlca, sqlxatype *sqlxa, long stno, long fOption, long sess, long stlen, char *stval)
{
  PI01PCRCALL(sqlCPCLocalBind, (sqlca, sqlxa, stno, fOption, sess, stlen, stval));
}

void sqccxab (sqlxatype *sqlxa, long xlang, long progc, long modc,
	char *progn, char *modn)
{
  PI01PCRCALL(sqccxab, (sqlxa, xlang, progc, modc, progn, modn));
}

void sqccsdb (void *sqlsd, long sdno, long sd1cnt, long sd1ix)
{
  /* never used anymore */ 
  PI01PCRCALL(sqccsdb, (sqlsd, sdno, sd1cnt, sd1ix));
}

void sqccfnb (sqlfnentry *sqlfn, long fnno, long kanomin, long kanomax,
	long incllno, char *filen)
{
  PI01PCRCALL(sqccfnb, (sqlfn, fnno, kanomin, kanomax, incllno, filen));
}

void sqccmab (sqlcatype *sqlca, sqlxatype *sqlxa, long mano, long malen,
	char *maval)
{
  PI01PCRCALL(sqccmab, (sqlca, sqlxa, mano, malen, maval));
}

void sqccgab (sqlcatype *sqlca, long index, long dbnl, long nodenl,
	char *dbn, char *node)
{
  PI01PCRCALL(sqccgab, (sqlca, index, dbnl, nodenl, dbn, node));
}

void sqlCPCGaBind (sqlcatype *sqlca, sqlxatype *sqlxa, 
		   long index, long dbnl, long nodenl,
		   char *dbn, char *node)
{
  PI01PCRCALL(sqlCPCGaBind, (sqlca, sqlxa, index, dbnl, nodenl, dbn, node));
}

void sqcctrs (sqlcatype *sqlca, long trcty)
{
  PI01PCRCALL(sqcctrs, (sqlca, trcty));
}

void sqccmts (sqlcatype *sqlca, long mtrcty, char *mtrcfn)
{
  PI01PCRCALL(sqccmts, (sqlca, mtrcty, mtrcfn));
}

void sqlCPCExecDirect (sqlcatype *sqlca, sqlxatype *sqlxa, long stno, long sess)
{
  PI01PCRCALL(sqlCPCExecDirect, (sqlca, sqlxa, stno, sess));
}

void sqlCPCOpen (sqlcatype *sqlca, sqlxatype *sqlxa, long stno, long sess)
{
  PI01PCRCALL(sqlCPCOpen, (sqlca, sqlxa, stno, sess));
}

void sqlCPCDescribe (sqlcatype *sqlca, sqlxatype *sqlxa, long stno, long sess)
{
  PI01PCRCALL(sqlCPCDescribe, (sqlca, sqlxa, stno, sess));
}

void sqlCPCDeclare (sqlcatype *sqlca, sqlxatype *sqlxa, long prno, long sess)
{
  PI01PCRCALL(sqlCPCDeclare, (sqlca, sqlxa, prno, sess));
}

void sqcccmd (sqlcatype *sqlca, sqlxatype *sqlxa, long kano)
{
  PI01PCRCALL(sqcccmd, (sqlca, sqlxa, kano));
}

void sqcctrl (sqlcatype *sqlca, sqlxatype *sqlxa, long stno)
{
  PI01PCRCALL(sqcctrl, (sqlca, sqlxa, stno));
}

void sqccnol (sqlcatype *sqlca, long sess)
{
  PI01PCRCALL(sqccnol, (sqlca, sess));
}

void sqlCPCNoLog (sqlcatype *sqlca, sqlxatype *sqlxa, long sess)
{
  PI01PCRCALL(sqlCPCNoLog, (sqlca, sqlxa, sess));
}

void sqlCPCTryExecute (sqlcatype *sqlca, sqlxatype *sqlxa, long stno, long sess)
{
  PI01PCRCALL(sqlCPCTryExecute, (sqlca, sqlxa, stno, sess));
}

void sqccdam (sqlcatype *sqlca, sqldatype *sqlda)
{
  PI01PCRCALL(sqccdam, (sqlca, sqlda));
}

void sqccdaa (sqlcatype *sqlca, sqldatype *sqlda)
{
  PI01PCRCALL(sqccdaa, (sqlca, sqlda));
}

void sqlCPCExecute (sqlcatype *sqlca, sqlxatype *sqlxa, long stno, long sess)
{
  PI01PCRCALL(sqlCPCExecute, (sqlca, sqlxa, stno, sess));
}

void sqccrcn (sqlcatype *sqlca, long sess)
{
  PI01PCRCALL(sqccrcn, (sqlca, sess));
}

void sqccstp (sqlcatype *sqlca, sqlxatype *sqlxa)
{
  PI01PCRCALL(sqccstp, (sqlca, sqlxa));
}

void sqccexi (sqlcatype *sqlca, sqlxatype *sqlxa)
{
  PI01PCRCALL(sqccexi, (sqlca, sqlxa));
}

void sqlCPCPrepare (sqlcatype *sqlca, sqlxatype *sqlxa, long prind, long sess)
{
  PI01PCRCALL(sqlCPCPrepare, (sqlca, sqlxa, prind, sess));
}


void *sqlcaddr (SQLAREAS cbAreaNum, void *pBaseClass)
{
  if (!pi01PCRProc.lpsqlcaddr)
    pi01PCRProc.lpsqlcaddr = (pi01voidPROC)pi01DynamicLoad("sqlcaddr");
  if (pi01PCRProc.lpsqlcaddr)
    return(pi01PCRProc.lpsqlcaddr (cbAreaNum, pBaseClass));
  return NULL;
}

void *sqlcdynp (SQLAREAS cbAreaNum, void *pBaseClass, int cbNumElem)
{
  if (!pi01PCRProc.lpsqlcdynp)
    pi01PCRProc.lpsqlcdynp = (pi01voidPROC)pi01DynamicLoad("sqlcdynp");
  if (pi01PCRProc.lpsqlcdynp)
    return(pi01PCRProc.lpsqlcdynp(cbAreaNum, pBaseClass, cbNumElem));
  return NULL;
}

int sqlcsize (SQLAREAS cbAreaNum)
{
  if (!pi01PCRProc.lpsqlcsize)
    pi01PCRProc.lpsqlcsize = (pi01intPROC)pi01DynamicLoad("sqlcsize");
  if (pi01PCRProc.lpsqlcsize)
    return(pi01PCRProc.lpsqlcsize(cbAreaNum));
  return 0;
}

void sqlCPCEndInit (sqlcatype *sqlca, sqlxatype *sqlxa, char *szPCVersion )
{
  PI01PCRCALL(sqlCPCEndInit, (sqlca, sqlxa, szPCVersion));
}

void sqlcisol (sqlcatype *sqlca, long isol)
{
  PI01PCRCALL(sqlcisol, (sqlca, isol));
}


struct SQLDA *sqlald (int max_vars, size_t max_name, size_t max_ind_name)
{
  if (!pi01PCRProc.lpsqlald)
    pi01PCRProc.lpsqlald = (pi01SQLDAPROC)pi01DynamicLoad("sqlald");
  if (pi01PCRProc.lpsqlald)
    return(pi01PCRProc.lpsqlald(max_vars, max_name, max_ind_name));
  return NULL;
}

void sqlclu (struct SQLDA *sqldp)
{
  PI01PCRCALL(sqlclu, (sqldp));
}

void sqlprc (long *length, int *precision, int *scale)
{
  PI01PCRCALL(sqlprc, (length, precision, scale));
}

void sqlnul (unsigned short *value_type, unsigned short *type_code,
	int *null_status)
{
  PI01PCRCALL(sqlnul, (value_type, type_code, null_status));
}

void sqlblnk (struct SQLDA *sqldp, int arrsiz)
{
  PI01PCRCALL(sqlblnk, (sqldp, arrsiz));
}

void sqlglm (unsigned char *msg, size_t *siz, size_t *len)
{
  PI01PCRCALL(sqlglm, (msg, siz, len));
}

void sqlgetver(char *szVersion, char* szMinVersion)
{
  PI01PCRCALL(sqlgetver, (szVersion, szMinVersion));
}

void sqlgetbuild(char *szBuild)
{
  PI01PCRCALL(sqlgetbuild, (szBuild));
}

void sqlTCompGetConnection (
			    void        *rawca,
			    int          sessionNumber,
			    int         *connectionHandleP,
			    void       **packetAddrP,
			    void       **xuserAddrP)
{
  PI01PCRCALL(sqlTCompGetConnection, (rawca, sessionNumber, connectionHandleP, packetAddrP, xuserAddrP));
}


SQLABAPInfoProc *
sqlInitABAPInfo(SQLABAPInfoProc *sqlABAPInfoCallBack)
{
  if (!pi01PCRProc.lpsqlInitABAPInfo)
    pi01PCRProc.lpsqlInitABAPInfo = (SQLABAPInfoProc *(*)(SQLABAPInfoProc *))pi01DynamicLoad("sqlInitABAPInfo");
  if (pi01PCRProc.lpsqlInitABAPInfo)
    return(pi01PCRProc.lpsqlInitABAPInfo(sqlABAPInfoCallBack));
  return NULL;
}

SQLCheckPointProc *
sqlInitCheckPoint(SQLCheckPointProc *fnCheckPoint)
{
  if (!pi01PCRProc.lpsqlInitCheckPoint)
    pi01PCRProc.lpsqlInitCheckPoint = (SQLCheckPointProc *(*)(SQLCheckPointProc *))pi01DynamicLoad("sqlInitCheckPoint");
  if (pi01PCRProc.lpsqlInitCheckPoint)
    return(pi01PCRProc.lpsqlInitCheckPoint(fnCheckPoint));
  return NULL;
}

void sqlCPCOption (sqlcatype *sqlca, sqlxatype *sqlxa, long stno)
{
  PI01PCRCALL(sqlCPCOption, (sqlca, sqlxa, stno));  
}

void sqlCPCPutDriverName (char *szDriverName)
{
  PI01PCRCALL(sqlCPCPutDriverName, (szDriverName));  
}

char *sqlCPCGetDriverName ()
{
  if (!pi01PCRProc.lpsqlCPCGetDriverName)
    pi01PCRProc.lpsqlCPCGetDriverName = (pi01charPROC)pi01DynamicLoad("sqlCPCGetDriverName");
  if (pi01PCRProc.lpsqlCPCGetDriverName)
    return(pi01PCRProc.lpsqlCPCGetDriverName ());
  return NULL;
}

SQLCancelProc *
sqlInitCancelProc(SQLCancelProc *sqlCancelCallBack)
{
  if (!pi01PCRProc.lpsqlInitCancelProc)
    pi01PCRProc.lpsqlInitCancelProc = (SQLCancelProc *(*)(SQLCancelProc *))pi01DynamicLoad("sqlInitCancelProc");
  if (pi01PCRProc.lpsqlInitCancelProc)
    return(pi01PCRProc.lpsqlInitCancelProc (sqlCancelCallBack));
  return NULL;
}

void sqlCPCTraceLine (sqlcatype *sqlca, sqlxatype *sqlxa, long stno)
{
  PI01PCRCALL(sqlCPCTraceLine, (sqlca, sqlxa, stno));  
}

void sqlCPCCheck (sqlcatype *sqlca, sqlxatype *sqlxa,
	sqlint2 *sqlstci, sqlint2 *sqlexti, long sqlext, long connplen)
{
  PI01PCRCALL(sqlCPCCheck, (sqlca, sqlxa, sqlstci, sqlexti, sqlext, connplen));  
}

void sqlCPCCheckU (sqlcatype *sqlca, sqlxatype *sqlxa,
	sqlint2 *sqlstci, sqlint2 *sqlexti, long sqlext, long connplen)
{
  PI01PCRCALL(sqlCPCCheckU, (sqlca, sqlxa, sqlstci, sqlexti, sqlext, connplen));  
}

int sqlTCompGetSessionByName(
			     void        *rawca,
			     char        *szDataBaseName)
{
  if (!pi01PCRProc.lpsqlTCompGetSessionByName)
    pi01PCRProc.lpsqlTCompGetSessionByName = (pi01intPROC)pi01DynamicLoad("sqlTCompGetSessionByName");
  if (pi01PCRProc.lpsqlTCompGetSessionByName)
    return(pi01PCRProc.lpsqlTCompGetSessionByName(rawca, szDataBaseName));
  return 0;
}

/* General LZU Functions */
externC void sqlinit (tsp00_CompName acComponent,
		      tsp00_BoolAddr       pbCancelAddress)
{
  PI01LZUCALL(sqlinit, ( acComponent, pbCancelAddress ));
}

externC void sqlfinish (pasbool bTerminate)
{
  PI01LZUCALL(sqlfinish, (bTerminate));
}

externC void sqluid (tsp00_TaskId* pUserID)
{
  PI01LZUCALL(sqluid, (pUserID));
}

externC void sqlos (tsp00_Os *pfOS)
{
  PI01LZUCALL(sqlos, (pfOS));
}

externC void sqlresult (tsp00_Uint1 fResult)
{
  PI01LZUCALL(sqlresult, (fResult));
}

externC void sqlsleep (tsp00_Int2 limit)
{
  PI01LZUCALL(sqlsleep, (limit));
}

externC void sqlgetenv (tsp00_C64              envname,
			tsp00_C64              envvalue,
			tsp00_BoolAddr envfound)
{
  PI01LZUCALL(sqlgetenv, (envname, envvalue, envfound));
}

externC void sqlaconnect (tsp00_TaskId   pid,
			  tsp00_NodeId	  servernode,
			  tsp00_DbName   serverdb,
			  tsp01_Service_Enum  service,
			  tsp00_Int4     packet_cnt,			
			  tsp00_Int4    *reference,
			  tsp00_Int4    *sql_packet_size,
			  void         **sql_packet_list,
			  tsp00_ErrText  errtext,
			  tsp01_CommErr *returncode)
{
  PI01LZUCALL(sqlaconnect, (pid, servernode, serverdb, service, packet_cnt, reference, sql_packet_size, sql_packet_list, errtext, returncode));
}

externC void sqlarelease (tsp00_Int4	 reference)
{
  PI01LZUCALL(sqlarelease, (reference));
}

externC void sqlarequest (tsp00_Int4	  reference,
			  void	         *sql_packet_addr,
			  tsp00_Int4     sql_packet_length,
			  tsp00_ErrText  errtext,			
			  tsp01_CommErr *returncode)
{
  PI01LZUCALL(sqlarequest, (reference, sql_packet_addr, sql_packet_length, errtext, returncode));
}

externC void sqlareplyavailable (tsp00_Int4	   reference,
				 tsp00_ErrText	   errtext,			
				 tsp01_CommErr   *returncode)
{
  PI01LZUCALL(sqlareplyavailable, (reference, errtext, returncode));
}

externC void sqlareceive (tsp00_Int4		reference,
			  void                **res_packet_ptr,
			  tsp00_Int4           *res_packet_length,
			  tsp00_ErrText 	errtext,
			  tsp01_CommErr        *returncode)
{
  PI01LZUCALL(sqlareceive, (reference, res_packet_ptr, res_packet_length, errtext, returncode));
}

externC void sqlacancel (tsp00_Int4       reference)
{
  PI01LZUCALL(sqlacancel, (reference));
}


externC void sqladump (void)
{
  PI01LZUCALL(sqladump, ());
}


externC void sqlpon (tsp00_PrtName       printer,
		     tsp00_BoolAddr      vpok)
{
  PI01LZUCALL(sqlpon, (printer, vpok));
}


externC void sqlprint (tsp00_PrtLine     line,
		       tsp00_Int2        length,
		       tsp00_VpLinefeeds lfeeds,
		       tsp00_ErrText     errtext,
		       tsp00_BoolAddr    vpok)
{
  PI01LZUCALL(sqlprint, (line, length, lfeeds, errtext, vpok));
}


externC void sqlpoff (tsp00_BoolAddr  print,
		      tsp00_ErrText   errtext,
		      tsp00_BoolAddr  vpok)
{
  PI01LZUCALL(sqlpoff, (print, errtext, vpok));
}

externC void sqlfinit (tsp00_Int2     buf_pool_size,
		       tsp00_Int4    *poolptr,
		       tsp00_BoolAddr ok)
{
  PI01LZUCALL(sqlfinit, (buf_pool_size, poolptr, ok));
}

externC void sqlfopen (tsp00_VFilename     vf_filename,
		       tsp00_VFileOpCodes  direction,
		       tsp00_VfResource    resource,
		       tsp00_Int4         *hostfileno,
		       tsp00_VfFormat     *format,
		       tsp00_Int4         *rec_len,
		       tsp00_Int4          poolptr,
		       tsp00_Int2          buf_count,
		       char               **block,
		       tsp00_VfReturn     *error,
		       tsp00_ErrText       errtext)
{
  PI01LZUCALL(sqlfopen, (vf_filename, direction, resource, hostfileno, format, rec_len, poolptr, buf_count, block, error, errtext));
}

externC void sqlfclose (tsp00_Int4        *hostfileno,
			pasbool            erase,
			tsp00_Int4         poolptr,
			tsp00_Int2         buf_count,
			char               *block,
			tsp00_VfReturn    *error,
			tsp00_ErrText      errtext)
{
  PI01LZUCALL(sqlfclose, (hostfileno, erase, poolptr, buf_count, block, error, errtext));
}

externC void sqlfread (tsp00_Int4*         hostfileno,
		       char                *block,
		       tsp00_Int4*         length,
		       tsp00_VfReturn*     error,
		       tsp00_ErrText       errtext)
{
  PI01LZUCALL(sqlfread, (hostfileno, block, length, error, errtext));
}

externC void sqlfwrite (tsp00_Int4*        hostfileno,
			char              *block,
			tsp00_Int4         length,
			tsp00_VfReturn*    error,
			tsp00_ErrText      errtext)
{
  PI01LZUCALL(sqlfwrite, (hostfileno, block, length, error, errtext));
}

externC void sqlfseek (tsp00_Int4       plHostFileNo,
		       tsp00_Int4        lFilePos,
		       tsp00_VfReturn*  peError,
		       tsp00_ErrText   acErrorText)
{
  PI01LZUCALL(sqlfseek, (plHostFileNo, lFilePos, peError, acErrorText));
}

externC void sqlferase (tsp00_VFilename acFileName,
			tsp00_VfReturn*      peError,
			tsp00_ErrText       acErrorText)
{
  PI01LZUCALL(sqlferase, (acFileName, peError, acErrorText));
}

externC void sqlexec (tsp00_ExecArgLine   pszCommand,
		      tsp00_ExecMode      eMode,
		      tsp00_ExecReturn   *peResult,
		      tsp00_ErrText       pszErrMsg,
		      tsp00_Int2         *pfProgResult)
{
  PI01LZUCALL(sqlexec, (pszCommand, eMode, peResult, pszErrMsg, pfProgResult));
}

externC void sqlfopenc (const char *rawFName,
			tsp05_RteDataKind_Param dataKind,
			tsp05_RteFileMode_Param fileMode,
			tsp05_RteBufferingKind_Param buffering,
			tsp00_Int4 *fileHandle,
			tsp05_RteFileError *ferr)
{
  PI01LZUCALL(sqlfopenc, (rawFName, dataKind, fileMode, buffering, fileHandle, ferr));
}

externC void sqlfopenp (const tsp00_VFilename rawFName,
			tsp05_RteDataKind dataKind,
			tsp05_RteFileMode fileMode,
			tsp05_RteBufferingKind buffering,
			tsp00_Int4 *fileHandle,
			tsp05_RteFileError *ferr)
{
  PI01LZUCALL(sqlfopenp, (rawFName, dataKind, fileMode, buffering, fileHandle, ferr));
}

externC void sqlfclosec (tsp00_Int4 fileHandle,
			 tsp05_RteCloseOption_Param option,
			 tsp05_RteFileError *ferr)
{
  PI01LZUCALL(sqlfclosec, (fileHandle, option, ferr));
}

externC void sqlfclosep (tsp00_Int4 fileHandle,
			 tsp05_RteCloseOption option,
			 tsp05_RteFileError *ferr)
{
  PI01LZUCALL(sqlfclosep, (fileHandle, option, ferr));
}

externC void sqlfreadc (tsp00_Int4 fileHandle,
			void* buf,
			tsp00_Longint bufSize,
			tsp00_Longint* outLen,
			tsp05_RteFileError *ferr)
{
  PI01LZUCALL(sqlfreadc, (fileHandle, buf, bufSize, outLen, ferr));
}

externC void sqlfreadp (tsp00_Int4 fileHandle,
			void* buf,
			tsp00_Longint bufSize,
			tsp00_Longint* outLen,
			tsp05_RteFileError *ferr)
{
  PI01LZUCALL(sqlfreadp, (fileHandle, buf, bufSize, outLen, ferr));
}

externC void sqlfwritec (tsp00_Int4 fileHandle,
			 const void* buf,
			 tsp00_Longint inLen,
			 tsp05_RteFileError *ferr)
{
  PI01LZUCALL(sqlfwritec, (fileHandle, buf, inLen, ferr));
}

externC void sqlfwritep (tsp00_Int4 fileHandle,
			 const void* buf,
			 tsp00_Longint inLen,
			 tsp05_RteFileError *ferr)
{
  PI01LZUCALL(sqlfwritep, (fileHandle, buf, inLen, ferr));
}

externC void sqlfseekc (tsp00_Int4 fileHandle,
			tsp00_Longint distance,
			tsp05_RteSeekKind_Param whence,
			tsp05_RteFileError *ferr)
{
  PI01LZUCALL(sqlfseekc, (fileHandle, distance, whence, ferr));
}

externC void sqlfseekp (tsp00_Int4 fileHandle,
			tsp00_Longint distance,
			tsp05_RteSeekKind whence,
			tsp05_RteFileError *ferr)
{
  PI01LZUCALL(sqlfseekp, (fileHandle, distance, whence, ferr));
}

externC void sqlferasec (const char *rawFName,
			 tsp05_RteFileError *ferr)
{
  PI01LZUCALL(sqlferasec, (rawFName, ferr));
}

externC void sqlferasep (const tsp00_VFilename rawFName,
			 tsp05_RteFileError *ferr)
{
  PI01LZUCALL(sqlferasep, (rawFName, ferr));
}

externC void sqlgetuser (tsp4_xuser_record  *prcUserParams,
             SAPDB_Char *         accountName,
			 tsp00_ErrText        acErrorText,
			 tsp00_BoolAddr       pbOk)
{
  PI01LZUCALL(sqlgetuser, (prcUserParams, accountName, acErrorText, pbOk));
}

externC void sqlputuser (tsp4_xuser_record  *prcUserParams,
             SAPDB_Char *         accountName,
			 tsp00_ErrText        acErrorText,
			 tsp00_BoolAddr       pbOk)
{
  PI01LZUCALL(sqlputuser, (prcUserParams, accountName, acErrorText, pbOk));
}

externC void sqlindexuser (tsp00_Int2          kUserIndex,
			   tsp4_xuser_record  *prcUserParams,
               SAPDB_Char *        accountName,
			   tsp00_ErrText       acErrorText,
			   tsp00_BoolAddr      pbOk)
{
  PI01LZUCALL(sqlindexuser, (kUserIndex, prcUserParams, accountName, acErrorText, pbOk));
}

externC void sqlinfouser (tsp00_KnlIdentifier acUser,
			  tsp00_CryptPw       acPassword,
			  tsp00_C64           acComponent,
			  tsp00_Uint1         *pfResult)
{
  PI01LZUCALL(sqlinfouser, (acUser, acPassword, acComponent, pfResult));
}

externC tsp00_Int4 sqlclearuser (SAPDB_Char *        accountName)
{
  if (!pi01LZUProc.lpsqlclearuser)
    pi01LZUProc.lpsqlclearuser = (pi01intPROC)pi01DynamicLoad("sqlclearuser");
  if (pi01LZUProc.lpsqlclearuser)
    return(pi01LZUProc.lpsqlclearuser(accountName));
  return 0;
}

externC void sqlfree (tsp00_Uint1*  pucObjPtr)
{
  PI01LZUCALL(sqlfree, (pucObjPtr));
}

externC void sqlallocat (tsp00_Int4        lSize,
			 tsp00_Uint1**     ppucObjPtr,
			 tsp00_BoolAddr    pbOk)
{
  PI01LZUCALL(sqlallocat, (lSize, ppucObjPtr, pbOk));
}

externC void sqldattime (tsp00_Date   pDate,
			 tsp00_Time   pTime)
{
  PI01LZUCALL(sqldattime, ( pDate, pTime));
}

externC void sqlclock (tsp00_Int4   *pSeconds,
		       tsp00_Int4   *pMilliSeconds)
{
  PI01LZUCALL(sqlclock, ( pSeconds, pMilliSeconds));
}

externC void sqlhostname (tsp00_NodeId      host,
			  tsp00_ErrText     errtext,
			  tsp01_CommErr    *returncode)
{
  PI01LZUCALL(sqlhostname, ( host,errtext,returncode));
}

externC void sqlnodename (tsp00_NodeId        host,
			  tsp00_NodeId        node,
			  tsp00_ErrText       errtext,
			  tsp01_CommErr      *returncode)
{
  PI01LZUCALL(sqlnodename, ( host,node,errtext,returncode));
}

externC void sqltoff (tsp00_Int4 lTermRef,
		      tsp00_ScreenBufAddr *ppsScreenBuffer,
		      tsp00_ScreenBufAddr *ppsAttributeBuffer,
		      tsp00_C80           psMsg)
{
  PI01LZUCALL(sqltoff, ( lTermRef,ppsScreenBuffer,ppsAttributeBuffer,psMsg));
}

externC void sqlcharsetname (tsp00_KnlIdentifier acCharSetName)
{
  PI01LZUCALL(sqlcharsetname, ( acCharSetName));
}

externC void sqlabort (void)
{
  PI01LZUCALL(sqlabort, ( ));
}

externC void sqlftellp (tsp00_Int4 fileHandle,
			tsp00_Longint *pos,
			tsp05_RteFileError *ferr)
{
  PI01LZUCALL(sqlftellp, (fileHandle,    pos,    ferr ));
}

externC void sqltermvar (tsp00_Uint1 *psTerminalType)
{
  PI01LZUCALL(sqltermvar, (psTerminalType ));
}

externC void sqlfclose_next_tape (tsp00_Int4         *hostfileno,
				  pasbool             erase,
				  tsp00_Int4          poolptr,
				  tsp00_Int2          buf_count,
				  char               *block,
				  tsp00_VfReturn     *error,
				  tsp00_VfReturn     *next_tape_error,
				  tsp00_ErrText       errtext)
{
  PI01LZUCALL(sqlfclose_next_tape, (hostfileno, erase, poolptr, buf_count, block, error, next_tape_error, errtext ));
}

void  SqlDevSize ( tsp00_DevName       dev_name,
                   tsp00_Int4         *devcapacity ,
                   tsp00_ErrText       errtext,
                   tsp00_BoolAddr      ok)
{
  PI01LZUCALL(SqlDevSize, (dev_name, devcapacity, errtext, ok ));
}


externC void sqlton (pasbool multi_task, 
		     tsp00_Int4 *term_ref, 
		     tsp00_TerminalDescription *desc,
		     tsp00_BoolAddr ok)
{
  PI01LZUCALL(sqlton, (multi_task, term_ref, desc, ok ));
}

externC void sqlttable (tsp00_Int2 i,
			      tsp00_VtAttrib ptoc_ptr_att,
			      tsp00_VtColor foreground,
			      tsp00_VtColor background)
{
  PI01LZUCALL(sqlttable, (i, ptoc_ptr_att, foreground, background ));
}

externC void sqltio (tsp00_Int4 term_ref, 
			   tsp00_ScreenBufAddr *screen_buf,
			   tsp00_ScreenBufAddr *attributes_buf,
			   pasbool refresh, 
			   tsp00_Int2 *cursorline, 
			   tsp00_Int2 *cursorcolumn,
			   tsp00_HifParms *hif,
			   tsp00_VtOptions *options,
			   tsp00_VtResult *result,
			   tsp00_BoolAddr ok)
{
  PI01LZUCALL(sqltio, (term_ref, screen_buf, attributes_buf, refresh, cursorline, cursorcolumn, hif, options, result, ok));
}

void    sqltermid   (   tsp00_TermId  acTerminalId    )
{
  PI01LZUCALL(sqltermid, (acTerminalId));
}

void sqlwrite ( tsp00_Line acLine )
{
  PI01LZUCALL(sqlwrite, (acLine));
}

void sqlvalidatealloc ( tsp00_Uint1*    Buffer, tsp00_BoolAddr  Ok )
{
  PI01LZUCALL(sqlvalidatealloc, (Buffer, Ok));
}

global void
sqlk_assert (int            kind,
		  int            lineno,
		  const char    *filename,
		  const char    *condition)
{
  PI01LZUCALL(sqlk_assert, ( kind, lineno, filename, condition));
}

global tsp00_Longint
sqlk_rangeviolation (tsp00_Longint     val,
                     tsp00_Longint     minVal,
                     tsp00_Longint     maxVal,
                     int               lineno,
                     const char       *fileName)
{
  if (!pi01LZUProc.lpsqlk_rangeviolation)
    pi01LZUProc.lpsqlk_rangeviolation = (pi01intPROC)pi01DynamicLoad("sqlk_rangeviolation");
  if (pi01LZUProc.lpsqlk_rangeviolation)
    return(pi01LZUProc.lpsqlk_rangeviolation(val, minVal, maxVal, lineno, fileName));
  return 0;
}

