.ad 8
.bm 8
.fm 4
.bt $Copyright by   Software AG, 1993$$Page %$
.tm 12
.hm 6
.hs 3
.tt 1 $NME$Project Distributed Database System$VOS97CC$
.tt 2 $$$
.tt 3 $R.Roedling$SHOW$1997-05-07$
***********************************************************
.nf


    ========== licence begin LGPL
    Copyright (C) 2002 SAP AG

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

    This library 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
    Lesser General Public License for more details.

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

.fo
.nf
.sp
Module	:	SHOW
=========
.sp
Purpose :
.CM *-END-* purpose -------------------------------------
.sp
.cp 3
Define	:

.CM *-END-* define --------------------------------------
.sp;.cp 3
Use	:

.CM *-END-* use -----------------------------------------
.sp;.cp 3
Synonym :

.CM *-END-* synonym -------------------------------------
.sp;.cp 3
Author	: R.Roedling
.sp
.cp 3
Created : 1992-11-06
.sp
.cp 3
Version : 1992-11-06
.sp
.cp 3
Release :  6.2 	 Date : 1997-05-07
.br
.sp
***********************************************************
.sp
.cp 10
.fo
.oc _/1
Specification:

.CM *-END-* specification -------------------------------
.sp 2
***********************************************************
.sp
.cp 10
.fo
.oc _/1
Description:

.CM *-END-* description ---------------------------------
.sp 2
***********************************************************
.sp
.cp 10
.nf
.oc _/1
Structure:

.CM *-END-* structure -----------------------------------
.sp 2
**********************************************************
.sp
.cp 10
.nf
.oc _/1
.CM -lll-
Code	:
/* PRETTY */

/*
 * MODULE - XSHOW
 */

/*
 * INCLUDE FILES
 */
#include	   <stdarg.h>

/*
 *  DEFINES
 */
#define MOD__  "VOS97CC : "
#define MF__   MOD__"UNDEFINED"


#define OPTION_STRING		  "rvn:"
#define SHOW_VERSION		  1
#define SHOW_DBROOT		  2

/*
 *  MACROS
 */


/*
 *  LOCAL TYPE AND STRUCT DEFINITIONS
 */

typedef struct DBEnumT {
    BOOLEAN	fullInfo;
    BOOLEAN	firstRead;
} DBEnumT;

typedef struct InstallationEnumT {
    HKEY	keyHandle;
    DWORD	index;
} InstallationEnumT;

/*
 * EXTERNAL VARIABLES
 */
#if defined(_WIN32)
 extern int	   sql80_OptInd;
 extern int	   sql80_OptErr;
 extern char*	   sql80_OptArg;
#endif


/*
 *  EXPORTED VARIABLES
 */


/*
 * LOCAL VARIABLES
 */

/*
 * LOCAL FUNCTION PROTOTYPES
 */

static APIRET sql97c_show_dbs_gws   ( PCHAR    pszNodeName, ULONG ulShow );
static APIRET sql97c_show_server    ( PCHAR    pszNodeName, ULONG ulShow );

#if defined (_WIN32)
 static PSZ sql97c_get_db_gw_version       ( PSZ                   pszNodeName,
                                             BOOL                  fGateway,
                                             PSZ                   szServerDB,
                                             VF_FILENAMEC          szDBRoot,
                                             tsp9_release_version* binaryVersion );
 static PSZ  sql97c_get_DBROOT_of_db_gw    ( PSZ       pszNodeName,
                                             BOOL      fGateway,
                                             PSZ       szServerDB );
 static PSZ sql97c_get_server_version      ( PSZ       pszNodeName );
 static PSZ  sql97c_get_DBROOT_of_server   ( PSZ       pszNodeName );
 static VOID sql97c_compress_path          ( PSZ       pszCompPathName,
                                             PSZ       pszPathName,
                                             ULONG     ulCompPathLen );
 static BOOL sql97c_newestDBRoot           ( PSZ       pszDBRoot );
 static void sql97c_translateChar          ( char*     str,
                                             char      fromChar,
                                             char      toChar);
#endif

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

#if !defined (CTRLCOMP)

int _CDECL main ( int argc, char  *argv[] )
  {
  #undef  MF__
  #define MF__ MOD__"main"
  APIRET   rc		 = NO_ERROR;
  PCHAR	   pszNodeName	 = NULL;
  #if defined(_WIN32)
   INT	   OptionChar;
   BOOL	   fCommandError = FALSE;
   ULONG   ulShow	 = 0;
  #endif

  DBGPAS;

  #if defined(_WIN32)
   while ( (OptionChar = sql80_GetOpt ( argc, argv, OPTION_STRING )) != -1 )
     {
     switch ( OptionChar )
       {
       case 'n' :
	       pszNodeName   = sql80_OptArg;
	       break;
       #if defined (_WIN32)
        case 'v' :
          if ( sql02_get_platform_id() == VER_PLATFORM_WIN32_NT )
            ulShow = SHOW_VERSION;
          else
            fCommandError = TRUE;
          break;
        case 'r' :
          if ( sql02_get_platform_id() == VER_PLATFORM_WIN32_NT )
            ulShow = SHOW_DBROOT;
          else
            fCommandError = TRUE;
          break;
       #endif
       default :
	       fCommandError = TRUE;
       }
     }

   if ( (argc - sql80_OptInd) || (fCommandError == TRUE) )
     {
     if ( sql02_get_platform_id() == VER_PLATFORM_WIN32_NT )
       printf (SHOW_USAGE);
     else
       printf (SHOW_USAGE_95);

     EXITPROCESS(0);
     }

   rc = sql97_update( pszNodeName );

   if ( rc != NO_ERROR )
     return ( rc );

  #endif


  rc = sql97c_show_dbs_gws( pszNodeName, ulShow );

  if ( rc == NO_ERROR )
    rc = sql97c_show_server( pszNodeName, ulShow );

  return ( rc );
  }

#else

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

#if !defined (RUN_AS_SERVICE)

global void sqlxopen_db_enum (
    void** handle,
    BOOLEAN fullinfo,
    tsp9_rte_xerror* xerror)
{
    #undef MF__
    #define MF__ MOD__"sqlxopen_db_enum"
    DBEnumT* dbEnum;
    APIRET	  rc	 = NO_ERROR;

    eo44initError (xerror);
    rc = sql97_update(NULL );
    if (rc != NO_ERROR) {
      eo44osError (xerror);
      return;
    }
    if ( ALLOC_MEM( (PVOID*)&dbEnum, sizeof (DBEnumT) ) ) {
      eo44anyError (xerror, "Out of memory");
      return;
    }
    dbEnum->fullInfo = fullinfo;
    dbEnum->firstRead = FALSE;
    *handle = dbEnum;
}

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

global void sqlxnext_db (
    void* handle,
    tsp9_rte_dbinfo* dbinfo,
    tsp9_rte_xerror* xerror)
{
    #undef MF__
    #define MF__ MOD__"sqlxnext_db"
    DBEnumT*	  dbEnum;
    APIRET	  rc	 = NO_ERROR;
    BOOL	  fActive;
    SQL_DBNAMEC	  szServerDB;
    int		  i;
    char	 *modeName;

    dbEnum = (DBEnumT*) handle;
    eo44initError (xerror);
    if (!dbEnum->firstRead) {
      rc = sql97_first_db_gw_state ( FALSE, szServerDB, &fActive );
      dbEnum->firstRead = TRUE;
    }
    else {
      rc = sql97_next_db_gw_state (szServerDB, &fActive);
    }
    switch (rc) {
    case NO_ERROR:
      strcpy (dbinfo->dbname, szServerDB);
      strcpy (dbinfo->dbroot, "<Unkown>");
      for (i = 0; i < csp9_version_digits; ++i) {
        dbinfo->version.no [i] = csp9_invalid_version;
        }
      sql97c_get_db_gw_version ( NULL, FALSE, szServerDB,
                                 dbinfo->dbroot, &dbinfo->version);
      modeName = strrchr (dbinfo->dbname, '(');
      if (modeName == NULL) {
        dbinfo->pgmKind = csp9_fast_pgm;
      }
      else {
        --modeName; /* skip over space */
        if (strcmp (modeName, SERVICE_QUICK_EXT) == 0) {
            *modeName  = '\0';
            dbinfo->pgmKind = csp9_quick_pgm;
        }
        else if (strcmp (modeName, SERVICE_SLOW_EXT) == 0) {
            *modeName  = '\0';
            dbinfo->pgmKind = csp9_slow_pgm;
        }
        else {
            dbinfo->pgmKind = csp9_fast_pgm;
        }
      }
      /* get options */
      /* get state */
      break;
    case ERROR_NO_MORE_FILES:
      eo44eoshowError (xerror);
      break;
    default:
      eo44osError (xerror);
      break;
    }
}
/*------------------------------*/

global void sqlxclose_db_enum (
    void* handle)
{
    #undef MF__
    #define MF__ MOD__"sqlxclose_db_enum"
    FREE_MEM( (PVOID)handle );

}

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

global void sqlxregisterinst (
    tsp9_cstr dbroot,
    tsp9_release_version* version,
    tsp9_rte_xerror* xerror)
{
    #undef MF__
    #define MF__ MOD__"sqlxregisterinst"
    APIRET		rc  = NO_ERROR;
    PATHNAME		szKey;
    REG_ENTRY_REC	RegistryEntries[1];
    char               *stringMark;

    eo44initError (xerror);
    /* build entry */
    strcpy (szKey, "Installations\\");
    stringMark = szKey + strlen (szKey);
    strcpy (stringMark, dbroot);
    /* registry keys cannot contain backslashes */
    sql97c_translateChar (stringMark, '\\', '/');
    RegistryEntries[0].pszValueName = REG_VN_VERSION_ID;
    RegistryEntries[0].pValue	    = version;
    RegistryEntries[0].ulValueSize  = sizeof(tsp9_release_version);
    RegistryEntries[0].ulValueType  = REG_BINARY;
    rc = sql50_reg_put_applic_values (NULL, HKEY_LOCAL_MACHINE, szKey,
                                      NULL, 1, RegistryEntries);
    if (rc != NO_ERROR) {
      eo44osError (xerror);
    }
}
/*------------------------------*/

global void sqlxunregisterinst (
    tsp9_cstr dbroot,
    tsp9_rte_xerror* xerror)
{
  #undef MF__
  #define MF__ MOD__"sqlxunregisterinst"
    APIRET		rc  = NO_ERROR;
    PATHNAME		szKey;
    char               *stringMark;

    eo44initError (xerror);
    strcpy (szKey, "Installations\\");
    stringMark = szKey + strlen (szKey);
    strcpy (stringMark, dbroot);
    /* registry keys cannot contain backslashes */
    sql97c_translateChar (stringMark, '\\', '/');
    rc =  sql50_reg_del_applic_key (NULL, HKEY_LOCAL_MACHINE, szKey);
    if (rc != NO_ERROR) {
      eo44osError (xerror);
    }
}

#endif
/*------------------------------*/

global void sqlxopen_installation_enum (
    void** handle,
    tsp9_rte_xerror* xerror)
{
    #undef MF__
    #define MF__ MOD__"sqlxopen_installation_enum"
    InstallationEnumT* installationEnum;
    APIRET	  rc	 = NO_ERROR;
    PATHNAME		szKey;

    eo44initError (xerror);
    // rc = sql97_update(NULL );
    if (rc != NO_ERROR) {
      eo44osError (xerror);
      return;
    }

    if ( ALLOC_MEM( (PVOID*)&installationEnum,
                    sizeof (InstallationEnumT) ) ) {
      eo44anyError (xerror, "Out of memory");
      return;
    }
    strcpy (szKey, REG_SK_BASE );
    strcat (szKey, "\\" );
    strcat (szKey, REG_SK_APPLIC );
    strcat (szKey, "\\" );
    strcat (szKey, "Installations");
    rc = RegOpenKeyEx (HKEY_LOCAL_MACHINE, szKey, 0,
                       KEY_ENUMERATE_SUB_KEYS, &installationEnum->keyHandle);
    if (rc != NO_ERROR) {
      eo44osError (xerror);
      return;
    }
    installationEnum->index = 0;
    *handle = installationEnum;
}

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

global void sqlxnext_installation (
    void* handle,
    tsp9_rte_installationinfo* releaseinfo,
    tsp9_rte_xerror* xerror)
{
    #undef MF__
    #define MF__ MOD__"sqlxnext_installation"
    InstallationEnumT *installationEnum;
    APIRET	  rc	 = NO_ERROR;
    FILETIME	  dummyTime;
    DWORD	  outlen;
    PATHNAME	  szKey;
    REG_ENTRY_REC RegistryEntries[1];

    installationEnum = (InstallationEnumT*) handle;
    eo44initError (xerror);
    outlen = sizeof (releaseinfo->dbroot);
    rc = RegEnumKeyEx (installationEnum->keyHandle, installationEnum->index,
                      (LPTSTR)&releaseinfo->dbroot, &outlen,
                       NULL, NULL, NULL, &dummyTime);
    switch (rc) {
    case NO_ERROR:
        ++installationEnum->index;
        strcpy (szKey, "Installations\\");
        strcat (szKey, releaseinfo->dbroot);
        RegistryEntries[0].pszValueName = REG_VN_VERSION_ID;
        RegistryEntries[0].pValue     = &releaseinfo->version;
        RegistryEntries[0].ulValueSize  = sizeof(tsp9_release_version);
        RegistryEntries[0].ulValueType  = REG_BINARY;
        rc = sql50_reg_get_applic_values (NULL, HKEY_LOCAL_MACHINE, szKey,
          1, RegistryEntries);
        if (rc != NO_ERROR) {
      eo44osError (xerror);
        }
              sql97c_translateChar (releaseinfo->dbroot, '/', '\\');
        break;
    case ERROR_NO_MORE_ITEMS:
        eo44eoshowError (xerror);
        break;
    default:
        eo44osError (xerror);
        break;
    }
}

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

global void sqlxclose_installation_enum (
    void* handle)
{
  #undef MF__
  #define MF__ MOD__"sqlxclose_installation_enum"
    InstallationEnumT *installationEnum;

    if (handle != NULL) {
      installationEnum = (InstallationEnumT*) handle;
      RegCloseKey (installationEnum->keyHandle);
      FREE_MEM( (PVOID)handle );
    }
}

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

BOOL sql97cc_findControlServer ( PSZ	pszExecutable,	 // OUT
				 PSZ	pszServerDB,	 // IN
				 PSZ	pszServerPgm,	 // IN
				 PSZ	pszDBRoot)	 // IN/OUT
{
    #undef MF__
    #define MF__ MOD__"sql97cc_findControlServer"
    BOOLEAN	found = FALSE;
    PSZ		pszRegistryValue;
    char	firstChar;
    int		rc;

    if ((pszServerDB != NULL) && (pszServerDB [0] != '\0')) {
      // first precedence: explicit dbname
      pszRegistryValue = sql97c_get_DBROOT_of_db_gw (NULL, FALSE, pszServerDB);
      firstChar = pszRegistryValue [0];
      if ((firstChar != '?') && (firstChar != '\0')) {
          strcpy (pszDBRoot, pszRegistryValue);
          found = TRUE;
      }
    }
    else if ((pszDBRoot != NULL) && (pszDBRoot [0] != '\0')) {
      // second precedence: explicit dbroot
      found = TRUE;
    }
    else {
      // last chance: get newest installation
      found = sql97c_newestDBRoot (pszDBRoot);
    }
    if (found) {
      strcpy (pszExecutable, pszDBRoot);
      strcat (pszExecutable, "\\pgm\\");
            strcat (pszExecutable, pszServerPgm);
            strcat (pszExecutable, ".exe");
      rc = 0;  // check existence of file, not implemented
      if (rc != 0) {
          found = FALSE;
      }
    }
    return found;
}

#endif


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

static APIRET sql97c_show_dbs_gws ( PCHAR    pszNodeName, ULONG ulShow )
  {
  #undef  MF__
  #define MF__ MOD__"sql97c_show_dbs_gws"
  APIRET                rc         = NO_ERROR;
  ULONG                 ulFound    = 0;
  BOOL                  fActive;
  SQL_DBNAMEC           szServerDB;
  PATHNAME              szDBRoot;
  PSZ                   pszVersion = NULL;
  PSZ                   pszDBRoot  = NULL;
  BOOL                  fGateway   = FALSE;
  tsp9_release_version  BinaryVersion;

  for (;;)
    {
    ulFound = 0;

    rc = sql97_first_db_gw_state ( fGateway, szServerDB, &fActive );

    if (( rc != ERROR_NO_MORE_FILES  ) && ( rc != NO_ERROR ))
      {
      DBGOUT;
      return ( rc );
      }

    if (( fGateway ) && ( rc == NO_ERROR ))
      printf ( XSHOW_GATEWAYS );
    else if ( !fGateway )
      printf ( XSHOW_SERVERDBS );

    // --- check SERVERDBs
    while ( rc == NO_ERROR )
      {
      ulFound++;

      switch ( ulShow )
        {
        case SHOW_VERSION:
          #if defined (_WIN32)
          if ( sql02_get_platform_id() == VER_PLATFORM_WIN32_NT )
            pszVersion = sql97c_get_db_gw_version ( pszNodeName, fGateway,
                                                    szServerDB, szDBRoot,
                                                    &BinaryVersion);
          #endif

          if ( pszVersion == NULL )
            pszVersion = "???";

          if ( fActive )
            printf ( XSHOW_SERVERDB_GW_VER_RUNNING, szServerDB, pszVersion );
          else
            printf ( XSHOW_SERVERDB_GW_VER_STOPPED, szServerDB, pszVersion );
          break;

        case SHOW_DBROOT:
          #if defined (_WIN32)
          if ( sql02_get_platform_id() == VER_PLATFORM_WIN32_NT )
            pszDBRoot  = sql97c_get_DBROOT_of_db_gw ( pszNodeName, fGateway,
                                                      szServerDB );
            if ( pszDBRoot == NULL )
              pszDBRoot = "???\'";
            else
              {
              sql97c_compress_path ( szDBRoot, pszDBRoot, 40 );
              strcat ( szDBRoot, "'" );
              pszDBRoot = szDBRoot;
              }
          #else
          pszDBRoot = "???\'";
          #endif


          if ( fActive )
            printf ( XSHOW_SERVERDB_GW_DBR_RUNNING, szServerDB, pszDBRoot );
          else
            printf ( XSHOW_SERVERDB_GW_DBR_STOPPED, szServerDB, pszDBRoot );
          break;

        default:
          if ( fActive )
            printf ( XSHOW_SERVERDB_GW_RUNNING, szServerDB );
          else
            printf ( XSHOW_SERVERDB_GW_STOPPED, szServerDB );
          break;
        }

      rc = sql97_next_db_gw_state ( szServerDB, &fActive );

      if (( rc != ERROR_NO_MORE_FILES  ) && ( rc != NO_ERROR ))
        {
        DBGOUT;
        return ( rc );
        }
      }

    if (( ulFound == 0 ) && ( !fGateway ))
      printf ( XSHOW_NO_SERVERDBS_GATEWAYS );

    if ( sql02_get_platform_id() == VER_PLATFORM_WIN32_NT )
      {
      if( !fGateway )
        fGateway = TRUE;
      else
        break;
      }
    else
      break;
    }


  DBGOUT;
  return ( NO_ERROR );
  }

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

static APIRET sql97c_show_server ( PCHAR    pszNodeName, ULONG ulShow )
  {
  #undef  MF__
  #define MF__ MOD__"sql97c_show_server"
  APIRET	rc	   = NO_ERROR;
  PSZ       pszVersion = NULL;
  PSZ       pszDBRoot  = NULL;
  PATHNAME	szDBRoot;
  BOOL      fActive;

  rc = sql97_xserver_state ( pszNodeName, &fActive );

  // --- check SERVER
  if ( rc == NO_ERROR )
    {
    switch ( ulShow )
      {
      case SHOW_VERSION:
        #if defined (_WIN32)
        if ( sql02_get_platform_id() == VER_PLATFORM_WIN32_NT )
          pszVersion = sql97c_get_server_version ( pszNodeName );
        #endif

        if ( pszVersion == NULL )
          pszVersion = "???";

        if ( fActive )
          printf ( XSHOW_XSERVER_VER_ACTIVE, pszVersion );
        else
          printf ( XSHOW_XSERVER_VER_NOT_ACTIVE, pszVersion );
        break;

      case SHOW_DBROOT:
        #if defined (_WIN32)
        if ( sql02_get_platform_id() == VER_PLATFORM_WIN32_NT )
          pszDBRoot  = sql97c_get_DBROOT_of_server ( pszNodeName );

          if ( pszDBRoot == NULL )
            pszDBRoot = "???\'";
          else
            {
            sql97c_compress_path ( szDBRoot, pszDBRoot, 40 );
            strcat ( szDBRoot, "'" );
            pszDBRoot = szDBRoot;
            }
        #else
        pszDBRoot = "???\'";
        #endif


        if ( fActive )
          printf ( XSHOW_XSERVER_DBR_ACTIVE, pszDBRoot );
        else
          printf ( XSHOW_XSERVER_DBR_NOT_ACTIVE, pszDBRoot );
        break;

      default:
        if ( fActive )
          printf ( XSHOW_XSERVER_ACTIVE );
        else
          printf ( XSHOW_XSERVER_NOT_ACTIVE );
        break;
      }
    }

  DBGOUT;
  return ( rc );
  }

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

#if defined (_WIN32)
 static PSZ sql97c_get_db_gw_version ( PSZ                   pszNodeName,
                                       BOOL                  fGateway,
                                       PSZ                   szServerDB,
                                       VF_FILENAMEC          szDBRoot,
                                       tsp9_release_version* binaryVersion)
   {
   #undef  MF__
   #define MF__ MOD__"sql97c_get_db_gw_version"
   CHAR			   szService[MX_DBNAME + 80];
   PATHNAME		   szSubKey;
   REG_ENTRY_REC	   RegistryEntries[4];
   static C40C		   szRTEVersion;
   static C40C		   szKernelVersion;
   LONG			   rc = NO_ERROR;

   DBGIN;

   if ( fGateway )
     strcpy ( szService, SERVICE_ID_GW);
   else
     strcpy ( szService, SERVICE_ID);

   strcat ( szService, szServerDB);
   CharUpperBuff(szService, strlen(szService));
   strcpy ( szSubKey,  szService );
   strcat ( szSubKey, "\\"REG_SK_SERVICE_PARAM );

   RegistryEntries[0].pszValueName = REG_VN_KERNEL_VERSION;
   RegistryEntries[0].pValue       = szKernelVersion;
   RegistryEntries[0].ulValueSize  = sizeof(szKernelVersion);
   RegistryEntries[0].ulValueType  = REG_SZ;
   RegistryEntries[0].rc           = NO_ERROR;

   RegistryEntries[1].pszValueName = REG_VN_VERSION;
   RegistryEntries[1].pValue       = szRTEVersion;
   RegistryEntries[1].ulValueSize  = sizeof(szRTEVersion);
   RegistryEntries[1].ulValueType  = REG_SZ;
   RegistryEntries[1].rc           = NO_ERROR;

   RegistryEntries[2].pszValueName = REG_VN_DBROOT;
   RegistryEntries[2].pValue       = szDBRoot;
   RegistryEntries[2].ulValueSize  = sizeof(VF_FILENAMEC);
   RegistryEntries[2].ulValueType  = REG_SZ;
   RegistryEntries[2].rc	   = NO_ERROR;

   RegistryEntries[3].pszValueName = REG_VN_VERSION_ID;
   RegistryEntries[3].pValue       = binaryVersion;
   RegistryEntries[3].ulValueSize  = sizeof(*binaryVersion);
   RegistryEntries[3].ulValueType  = REG_BINARY;
   RegistryEntries[3].rc           = NO_ERROR;


   sql50_reg_get_service_values ( pszNodeName, szSubKey, 4, RegistryEntries );

   if ( RegistryEntries[0].rc == NO_ERROR )
     {
     DBGOUT;
     return (PSZ)RegistryEntries[0].pValue;
     }

   if ( RegistryEntries[1].rc == NO_ERROR )
     {
     DBGOUT;
     return (PSZ)RegistryEntries[1].pValue;
     }

   DBGOUT;
   return "???";
   }

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

 static PSZ sql97c_get_server_version ( PSZ  pszNodeName )
   {
   #undef  MF__
   #define MF__ MOD__"sql97c_get_server_version"
   PATHNAME		   szSubKey;
   REG_ENTRY_REC	   RegistryEntries[1];
   static C40C		   szRTEVersion;
   static C40C		   szKernelVersion;
   LONG			   rc = NO_ERROR;

   DBGIN;

   strcpy ( szSubKey, XSERV_TITLE );
   strcat ( szSubKey, "\\"REG_SK_SERVICE_PARAM );

   RegistryEntries[0].pszValueName = REG_VN_VERSION;
   RegistryEntries[0].pValue       = szRTEVersion;
   RegistryEntries[0].ulValueSize  = sizeof(szRTEVersion);
   RegistryEntries[0].ulValueType  = REG_SZ;
   RegistryEntries[0].rc           = NO_ERROR;


   sql50_reg_get_service_values ( pszNodeName, szSubKey, 1, RegistryEntries );

   if ( RegistryEntries[0].rc == NO_ERROR )
     {
     DBGOUT;
     return (PSZ)RegistryEntries[0].pValue;
     }

   DBGOUT;
   return NULL;
   }

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

 static PSZ sql97c_get_DBROOT_of_db_gw ( PSZ    pszNodeName,
                                         BOOL   fGateway,
                                         PSZ    szServerDB )
   {
   #undef  MF__
   #define MF__ MOD__"sql97c_get_DBROOT_of_db_gw"
   CHAR			   szService[MX_DBNAME + 80];
   PATHNAME		   szSubKey;
   REG_ENTRY_REC	   RegistryEntries[1];
   PATHNAME		   szDBRoot;
   LONG			   rc = NO_ERROR;

   DBGIN;

   if ( fGateway )
     strcpy ( szService, SERVICE_ID_GW);
   else
     strcpy ( szService, SERVICE_ID);

   strcat ( szService, szServerDB);
   CharUpperBuff(szService, strlen(szService));
   strcpy ( szSubKey,  szService );
   strcat ( szSubKey, "\\"REG_SK_SERVICE_PARAM );

   RegistryEntries[0].pszValueName = REG_VN_DBROOT;
   RegistryEntries[0].pValue       = szDBRoot;
   RegistryEntries[0].ulValueSize  = sizeof(szDBRoot);
   RegistryEntries[0].ulValueType  = REG_SZ;
   RegistryEntries[0].rc           = NO_ERROR;


   sql50_reg_get_service_values ( pszNodeName, szSubKey, 1, RegistryEntries );

   if ( RegistryEntries[0].rc == NO_ERROR )
     {
     DBGOUT;
     return (PSZ)RegistryEntries[0].pValue;
     }

   DBGOUT;
   return "???";
   }

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

 static PSZ sql97c_get_DBROOT_of_server ( PSZ  pszNodeName )
   {
   #undef  MF__
   #define MF__ MOD__"sql97c_get_DBROOT_of_server"
   PATHNAME		   szSubKey;
   REG_ENTRY_REC	   RegistryEntries[1];
   PATHNAME		   szDBRoot;
   LONG			   rc = NO_ERROR;

   DBGIN;

   strcpy ( szSubKey, XSERV_TITLE );
   strcat ( szSubKey, "\\"REG_SK_SERVICE_PARAM );

   RegistryEntries[0].pszValueName = REG_VN_DBROOT;
   RegistryEntries[0].pValue	   = szDBRoot;
   RegistryEntries[0].ulValueSize  = sizeof(szDBRoot);
   RegistryEntries[0].ulValueType  = REG_SZ;
   RegistryEntries[0].rc	   = NO_ERROR;

   sql50_reg_get_service_values ( pszNodeName, szSubKey, 1, RegistryEntries );

   if ( RegistryEntries[0].rc == NO_ERROR )
     {
     DBGOUT;
     return (PSZ)RegistryEntries[0].pValue;
     }

   DBGOUT;
   return NULL;
   }

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

 static VOID sql97c_compress_path ( PSZ	   pszCompPathName,
				    PSZ	   pszPathName,
				    ULONG  ulCompPathLen )
   {
   #undef  MF__
   #define MF__ MOD__"sql97c_compress_path"
   LONG		  lPathLen;
   LONG		  lSplitPos;
   LONG		  lRest;

   DBGPAS;

   if ( ulCompPathLen < 4 )
     {
     pszCompPathName[0] = '\0';
     return;
     }

   lPathLen = strlen ( pszPathName );

   if ( lPathLen > (INT)ulCompPathLen )
     {
     lSplitPos = (ulCompPathLen / 2) - 2;
     lRest     = ulCompPathLen - lSplitPos - 4;

     strncpy ( pszCompPathName, pszPathName, lSplitPos );
     pszCompPathName [ lSplitPos ] = '\0';
     strcat ( pszCompPathName, "...." );
     strcat ( pszCompPathName, pszPathName + lPathLen - lRest );
     }
   else
     {
     strcpy ( pszCompPathName, pszPathName );
     }
  return;
  }


 /*------------------------------*/
#if defined (CTRLCOMP)

static BOOL sql97c_newerInstallation ( tsp9_rte_installationinfo* currentRead,
				       tsp9_rte_installationinfo* currentNewest)
{
  #undef MF__
  #define MF__ MOD__"sql97c_newestDBRoot"
  int i;

  for (i = 0; i < csp9_version_digits; ++i) {
      if (currentRead->version.no [i] > currentNewest->version.no [i]) {
	  return TRUE;
      }
      if (currentRead->version.no [i] < currentNewest->version.no [i]) {
	  return FALSE;
      }
  }
  return FALSE;
}

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

static BOOL sql97c_newestDBRoot ( PSZ  pszDBRoot )     // OUT parameter
{
  #undef MF__
  #define MF__ MOD__"sql97c_newestDBRoot"
  void*				handle;
  tsp9_rte_installationinfo	releaseInfo;
  tsp9_rte_xerror		xerror;
  tsp9_rte_installationinfo	choosenInstallation;
  BOOL				result;

  choosenInstallation.version.no [0] = csp9_invalid_version;
  sqlxopen_installation_enum (&handle, &xerror);
  while (xerror.xe_result == csp9_xrte_ok) {
      sqlxnext_installation (handle, &releaseInfo, &xerror);
      if (sql97c_newerInstallation (&releaseInfo, &choosenInstallation)) {
	  choosenInstallation = releaseInfo;
      }
  }
  sqlxclose_installation_enum (handle);
  if (choosenInstallation.version.no [0] != csp9_invalid_version) {
      strcpy (pszDBRoot, releaseInfo.dbroot);
      result = TRUE;
  }
  else {
      pszDBRoot [0] = '\0';
      result = FALSE;
  }
  return result;
}

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

static void sql97c_translateChar (char* str, char fromChar, char toChar)
{
  #undef MF__
  #define MF__ MOD__"sql97c_newestDBRoot"

    while (*str != '\0') {
        if (*str == fromChar) {
            *str = toChar;
        }
        ++str;
    }
}

#endif

#endif
/*
 * =============================== END ========================================
 */

.CM *-END-* code ----------------------------------------
.SP 2
***********************************************************
*-PRETTY-*  statements	  :	    38
*-PRETTY-*  lines of code :	    38	      PRETTY  1.07
*-PRETTY-*  lines in file :	   141	       1989-01-20
.PA
