#include "mysccs.h"
SCCSID("@(#)contexts.c   %E%   SAP   %I%")

static char * this_File GNU_UNUSED = __FILE__;

/************************************************************************/
/* $Id: //tools/src/freeware/gsstest/platform.c#8 $
 ************************************************************************
 *
 * Copyright (c) 1998-2000  SAP AG.  All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions
 * are met:
 *
 * 1. Redistributions of source code must retain the above copyright
 *    notice, this list of conditions and the following disclaimer. 
 *
 * 2. Redistributions in binary form must reproduce the above copyright
 *    notice, this list of conditions and the following disclaimer in
 *    the documentation and/or other materials provided with the
 *    distribution.
 *
 * 3. All advertising materials mentioning features or use of this
 *    software must display the following acknowledgment:
 *    "This product includes software developed by SAP AG"
 *
 * 4. The name "SAP AG" must not be used to endorse or promote products
 *    derived from this software without prior written permission.
 *    For written permission, please contact www.press@sap.com
 *
 * 5. Redistributions of any form whatsoever must retain the following
 *    acknowledgment:
 *    "This product includes software developed by SAP AG"
 *
 * THIS SOFTWARE IS PROVIDED BY SAP AG ``AS IS'' AND ANY EXPRESSED
 * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
 * PURPOSE ARE DISCLAIMED. SAP AG SHALL BE LIABLE FOR ANY DAMAGES
 * ARISING OUT OF THE USE OF THIS SOFTWARE ONLY IF CAUSED BY SAP AG'S
 * INTENT OR GROSS NEGLIGENCE. IN CASE SAP AG IS LIABLE UNDER THIS
 * AGREEMENT FOR DAMAGES CAUSED BY SAP AG'S GROSS NEGLIGENCE SAP AG
 * FURTHER SHALL NOT BE LIABLE FOR ANY INDIRECT, INCIDENTAL, SPECIAL,
 * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
 * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA,
 * OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
 * OR TORT, AND SHALL NOT BE LIABLE IN EXCESS OF THE AMOUNT OF
 * DAMAGES TYPICALLY FORESEEABLE FOR SAP AG, WHICH SHALL IN NO EVENT
 * EXCEED US$ 500.000.- 
 *
 ************************************************************************/


#include "gsstest.h"
#include "non_ansi.h"
#include <sys/types.h>
#include <time.h>

#ifdef HAVE_UNISTD_H
#  include <unistd.h>
#endif /* HAVE_UNISTD_H */

#ifdef HAVE_PWD_H
#  include <pwd.h>
#endif /* HAVE_PWD_H */


float  perf_correction = 1.0;

char   * not_implemented = "(not implemented)";

char   * os_platform = OS_PLATFORM;

#ifdef UNIX

#  include <sys/utsname.h>

/*
 * sys_uts_osname()
 *
 *
 */
int
sys_uts_osname( struct sys_platform_s * p_pls )
{
   struct utsname  uts;
   int             rc;

   memset( &uts, 0, sizeof(uts) );
   rc = uname( &uts );
   if ( rc>=0 ) {
      strncpy( p_pls->os_name, uts.sysname, sizeof(p_pls->os_name) );
      p_pls->os_name[sizeof(p_pls->os_name)-1] = '\0';
      return(0);
   } else {
      XVEB((V_BUG, "uname() failed: %s\n", strerror(errno) ));
      memset( p_pls->os_name, 0, sizeof(p_pls->os_name) );
   }

   return(1);

} /* sys_uts_osname() */


/*
 * sys_uts_osrelease()
 *
 *
 */
int
sys_uts_osrelease( struct sys_platform_s * p_pls )
{
   struct utsname   uts;
   int              rc;

   memset( &uts, 0, sizeof(uts) );
   rc = uname( &uts );
   if ( rc>=0 ) {
      strncpy( p_pls->os_release, uts.release, sizeof(p_pls->os_release) );
      p_pls->os_release[sizeof(p_pls->os_release)-1] = '\0';
      return(0);
   } else {
      XVEB((V_BUG, "uname() failed: %s\n", strerror(errno) ));
      memset( p_pls->os_release, 0, sizeof(p_pls->os_release) );
   }

   return(1);

} /* sys_uts_osrelease() */


/*
 * sys_uts_oshardware()
 *
 *
 */
int
sys_uts_oshardware( struct sys_platform_s * p_pls )
{
   struct utsname  uts;
   int             rc;

   memset( &uts, 0, sizeof(uts) );
   rc = uname( &uts );
   if ( rc>=0 ) {
      strncpy( p_pls->os_hardware, uts.machine, sizeof(p_pls->os_hardware) );
      p_pls->os_hardware[sizeof(p_pls->os_hardware)-1] = '\0';
      return(0);
   } else {
      XVEB((V_BUG, "uname() failed: %s\n", strerror(errno) ));
      memset( p_pls->os_hardware, 0, sizeof(p_pls->os_hardware) );
   }

   return(1);

} /* sys_uts_hardware() */

  
/*
 * sys_popen()
 *
 * read a single line of output from a shell command
 * into a buffer
 *
 */
int
sys_popen( char   * p_command,  char   * p_buf,   size_t  p_buf_max )
{
   FILE   * fp  = NULL;
   size_t   len;
   int	    rc  = 1;

   memset( p_buf, 0, p_buf_max);

   fp = popen( p_command, "r" );
   if ( fp!=NULL ) {
      len = fread( p_buf, 1, p_buf_max-1, fp );
      if ( len>0 ) {
	 /* looks good -- we were able to read from stdout */
	 p_buf[len] = 0;
	 while( len>0 && (p_buf[len-1]=='\r' || p_buf[len-1]=='\n') ) {
	    /* cut end-of-line characters, in case there are any */
	    len--;
	    p_buf[len] = '\0';
	 }
	 if ( len>0 ) {
	    rc = 0; /* success -- we have a non-empty string left */
	 }
      }

      pclose( fp );

   } /* fp!=NULL */

   return(rc);

} /* sys_popen() */

 
#endif /* UNIX */


#ifdef SOLARIS_HARDWARE_QUERY


#include <sys/types.h>
#include <sys/processor.h>
#include <sys/systeminfo.h>


/*
 * sys_solaris_oshardware()
 *
 * Query more detailed hardware information
 *
 */
int
sys_solaris_oshardware( struct sys_platform_s * p_pls )
{

   processor_info_t		infop;
   char				machine[32];
   char				architecture[32];
   char  			platform[64];
   char                         cpu_info[64];

   machine[0] = architecture[0] = platform[0] = 0;
   sysinfo( SI_MACHINE, machine, sizeof(machine)-1 );
   machine[sizeof(machine)-1] = 0;
   sysinfo( SI_ARCHITECTURE, architecture, sizeof(architecture)-1 );
   architecture[sizeof(architecture)-1] = 0;
   sysinfo( SI_PLATFORM, platform, sizeof(platform)-1 );
   platform[sizeof(platform)-1] = 0;


   if ( processor_info( 0, &infop )==0 ) {
      cpu_info[0] = 0;
      infop.pi_processor_type[PI_TYPELEN-1]= 0;

      sprintf(p_pls->os_hardware, "%.24s (%.8s, %.12s, %dMhz)",
		platform, machine, infop.pi_processor_type, (int)infop.pi_clock);

   } else {

      sprintf(p_pls->os_hardware, "%.24s (%.8s, %.12s)",
	      platform, machine, architecture);

   }

   p_pls->os_hardware[sizeof(p_pls->os_hardware)-1] = 0;

   return(0);

} /* sys_solaris_oshardware() */

#endif /* SOLARIS_HARDWARE_QUERY */



#ifdef _WIN32


/*
 * win_osname()
 */
int
win_osname( struct sys_platform_s   * p_pls )
{
   OSVERSIONINFO     osvi;
   char           *  product;

   memset( p_pls->os_name, 0, sizeof(p_pls->os_name) );
   memset( &osvi, 0, sizeof(osvi) );

   osvi.dwOSVersionInfoSize = sizeof(osvi); /* REQUIRED! */
   GetVersionEx( &osvi );

   switch( (int) osvi.dwPlatformId ) {

      case VER_PLATFORM_WIN32s:
		  product = "Microsoft Win32";
		  break;

      case VER_PLATFORM_WIN32_WINDOWS:
		  product = (osvi.dwMinorVersion==0)
			    ? "Microsoft Windows 95" : "Microsoft Windows 98";
		  break;
		     
      case VER_PLATFORM_WIN32_NT:
		  product = "Microsoft Windows NT";
		  break;

      default:	  product = "Windows (?!)";
		  break;

   }

   strncpy( p_pls->os_name, product, sizeof(p_pls->os_name) );
   p_pls->os_name[sizeof(p_pls->os_name)-1] = '\0';

   return(0);

} /* win_osname() */


/*
 * win_osrelease()
 */
int
win_osrelease( struct sys_platform_s   * p_pls )
{
   OSVERSIONINFO     osvi;
   char              tmpbuf[256];
   char              build[128];
   HKEY              hkey = (HKEY)0;
   DWORD             len;
   DWORD	     type;

   memset( p_pls->os_release, 0, sizeof(p_pls->os_release) );
   memset( &osvi, 0, sizeof(osvi) );

   osvi.dwOSVersionInfoSize = sizeof(osvi); /* REQUIRED! */
   GetVersionEx( &osvi );

   build[0] = 0;
   if ( ERROR_SUCCESS==RegOpenKeyEx(HKEY_LOCAL_MACHINE, "SOFTWARE\\Microsoft\\Windows NT\\CurrentVersion",
	0, KEY_QUERY_VALUE, &hkey ) ) {
       len = sizeof(build)-1;
       if ( ERROR_SUCCESS==RegQueryValueEx(hkey, "BuildLab", NULL, &type, (BYTE *)&(build[0]), &len )
	    && REG_SZ == type ) {
	   build[len] = 0;
       } else {
	   build[0] = 0;
       }
   }
       
   if ( 0==build[0] ) {
       sprintf(build, "%d", (int)(osvi.dwBuildNumber&0xFFFF) );
   }

      
   sprintf(tmpbuf, "%d.%d (Build %.48s%.5s%.48s)",
		   (int) osvi.dwMajorVersion,
		   (int) osvi.dwMinorVersion,
		   build,
		   ((osvi.szCSDVersion[0])!=0 ? ": " : ""),
		   (char *) &(osvi.szCSDVersion[0]) );

   strncpy( p_pls->os_release, tmpbuf, sizeof(p_pls->os_release) );
   p_pls->os_release[sizeof(p_pls->os_release)-1] = '\0';

   if ( 0!=hkey ) {
       RegCloseKey( hkey );
   }
   
   return(0);

} /* win_osrelease() */


#ifndef PROCESSOR_ARCHITECTURE_IA64
#  define PROCESSOR_ARCHITECTURE_IA64 6
#endif
#ifndef PROCESSOR_ARCHITECTURE_AMD64
#  define PROCESSOR_ARCHITECTURE_AMD64 9
#endif
#ifndef PROCESSOR_ARCHITECTURE_IA32_ON_WIN64
#  define PROCESSOR_ARCHITECTURE_IA32_ON_WIN64 10
#endif

/*
 * win_hardware()
 */
int
win_hardware( struct sys_platform_s  * p_pls )
{
   SYSTEM_INFO    sinfo;
   size_t	  len;
   char         * cpu  = "(unknown)";
   char         * cpu2 = "";
   char           cpu_level[128];
   char	          cpu_rev[128];

   memset( p_pls->os_hardware, 0, sizeof(p_pls->os_hardware) );
   memset( &sinfo, 0, sizeof(sinfo) );
   GetSystemInfo( &sinfo );

   switch( (int)sinfo.wProcessorArchitecture ) {
      case PROCESSOR_ARCHITECTURE_INTEL:	 cpu = "x86/ia32"; break;
      case PROCESSOR_ARCHITECTURE_ALPHA:	 cpu = "Alpha";    break;
      case PROCESSOR_ARCHITECTURE_PPC:		 cpu = "PowerPC";  break;
      case PROCESSOR_ARCHITECTURE_MIPS:		 cpu = "Mips";     break;
      case PROCESSOR_ARCHITECTURE_IA64:		 cpu = "ia64";     break;
      case PROCESSOR_ARCHITECTURE_AMD64:	 cpu = "amd64";    break;
      case PROCESSOR_ARCHITECTURE_IA32_ON_WIN64: cpu = "ia32-on-win64"; break;
      default:	     break;
   }

#if 0
   if ( sinfo.wProcessorArchitecture == PROCESSOR_ARCHITECTURE_INTEL ) {
      switch( (int)sinfo.dwProcessorType ) {
	 case PROCESSOR_INTEL_386:	     cpu2 = " (386)";  break;
	 case PROCESSOR_INTEL_486:	     cpu2 = " (486)";  break;
	 case PROCESSOR_INTEL_PENTIUM:	     cpu2 = " (Pentium)";  break;
	 default:    break;
      }
   }
#endif

   sprintf( cpu_level, "cpu_level=%ld", (Ulong)sinfo.wProcessorLevel );
   sprintf( cpu_rev, "cpu_rev=0x%04lx", (Ulong)sinfo.wProcessorRevision );

   len = strlen(cpu) + strlen(cpu2) + strlen(cpu_level) + strlen(cpu_rev) + 4;
   if ( len < sizeof(p_pls->os_hardware) ) {
      sprintf(p_pls->os_hardware, "%s%s  %s, %s", cpu, cpu2, cpu_level, cpu_rev );
   } else {
      strncpy(p_pls->os_hardware, cpu, sizeof(p_pls->os_hardware));
   }
   p_pls->os_hardware[sizeof(p_pls->os_hardware)-1] = '\0';

   return(0);
   
} /* win_hardware() */


/*
 * win_username()
 */
int
win_username( struct sys_platform_s * p_pls )
{
   BOOL   result;
   DWORD  len;

   len = sizeof(p_pls->user) - 1;
   memset( p_pls->user, 0, sizeof(p_pls->user) );

   result = GetUserName( p_pls->user, &len );
   if ( result==0 ) {
      XVEB((V_BUG, "GetUserName() returned %08lx!\n",
		   (Ulong) GetLastError() ));
      memset( p_pls->user, 0, sizeof(p_pls->user) ); /* Don't rely on M$ */
      return(1);
   }

   p_pls->user[sizeof(p_pls->user)-1] = '\0';

   return(0);

} /* win_username() */


/*
 * win_computername()
 */
int
win_computername( struct sys_platform_s * p_pls )
{
   BOOL   result;
   DWORD  len;

   len = sizeof(p_pls->hostname) - 1;
   memset( p_pls->hostname, 0, sizeof(p_pls->hostname) );

   result = GetComputerName( p_pls->hostname, &len );
   if (result==0) {
      XVEB((V_BUG, "GetComputerName() returned %08lx!\n",
		   (Ulong) GetLastError() ));
      memset( p_pls->hostname, 0, sizeof(p_pls->hostname) );
      return(1);
   }

   p_pls->hostname[sizeof(p_pls->hostname)-1] = '\0';


   return(0);

} /* win_computername() */


#endif /* _WIN32 */


#ifdef SYS_PLATFORM_OS400

#define HAVE_BSD_GETHOSTNAME 1
#define sys_bsd_gethostname sys_os400_hostname

#define HAVE_POSIX_GETPWUID 1
#define sys_posix_getpwuid sys_os400_username
extern uid_t getuid(void);


#include <unistd.h>
#include <ledate.h>
#include <stdio.h>

long   timezone           = 0;
long   daylight           = 0;
char  *tzname[2]          = { "GMT", "" };

static char tznames[2][20];

void
os400_tzset( void )
{
  _INT4 utco_hrs, utco_min;
  _FLOAT8 utco_sec;
  _FEEDBACK utco_fc;

  CEEUTCO(&utco_hrs, &utco_min, &utco_sec, &utco_fc);

  daylight = 0;              /* daylight saving not supported  */
  timezone = (long)utco_sec; /* set e global variable-BSD lib  */
  sprintf(tznames[0], "GMT%+d", utco_hrs); /* timezone name     */
  sprintf(tznames[1], "GMT%+d", utco_hrs); /* daylightzone name */
  tzname[0] = tznames[0];
  tzname[1] = tznames[1];

} /* os400_tzset() */



/*
 * sys_os400_osname()
 *
 * Return the printable name for this operating system
 * in the structure member p_pls->os_name
 * (use a zero-terminated string, truncating the name if necessary (shouldn't be)
 *
 */
int
sys_os400_osname( struct sys_platform_s * p_pls )
{
    p_pls->os_name[0] = 0;  /* initialize with empty string */

    strncpy( p_pls->os_name, "OS/400", sizeof(p_pls->os_name) );

    p_pls->os_name[sizeof(p_pls->os_name)-1] = 0;  /* zero-terminate string (safety) */

    return(0); /* indicate success */

} /* sys_os400_osname() */



#include <qusec.h>
#include <qszrtvpr.h>

/*
 * sys_os400_osrelease()
 *
 * Return the printable name for the Operating System
 */
int
sys_os400_osrelease( struct sys_platform_s * p_pls )
{
    Qus_EC_t                errorCode;
    Qsz_PRDR0100_t          receiver;
    Qsz_Product_Info_Rec_t  product;

    p_pls->os_release[0] = 0;  /* initialize with empty string */
    memset( &errorCode, 0x00,  sizeof(errorCode) );
    errorCode.Bytes_Provided  = sizeof(errorCode);

    memset( &product, ' ',  sizeof(product) );
    memcpy(product.Product_Id, "*OPSYS ",7);
    memcpy(product.Release_Level, "*CUR  ",6);
    memcpy(product.Product_Option, "0000",4);
    memcpy(product.Load_Id, "*CODE     ",10);

    memset( &receiver, 0x00,  sizeof(receiver) );
    receiver.Bytes_Available = sizeof(Qsz_PRDR0100_t);

    QSZRTVPR((void *)&receiver,               /* Receiver variable           */
              sizeof(Qsz_Product_Info_Rec_t), /* Length of receiver variable */
              "PRDR0100",                     /* Format name for rec variable*/
              (void *)&product,               /* Product information         */
              (void *)&errorCode);            /* Error code                  */

    if ( errorCode.Bytes_Available > 0 )
    {
	sprintf(p_pls->os_release, "QSZRTVPR() failed: %.7s",
		errorCode.Exception_Id);
    } else {
	sprintf(p_pls->os_release, "%.6s", receiver.Release_Level);
    }

    /* zero-terminate string (safety) */
    p_pls->os_release[sizeof(p_pls->os_release)-1] = 0;

    return(0); /* indicate success */

} /* sys_os400_osrelease() */



#include <qusec.h>
#include <qwcrsval.h>

typedef struct sval_header_struct
{
    Qwc_Rsval_Data_Rtnd_t           header;
    int                             offset[1];
} sval_header_struct_t;

typedef struct sval_entry_struct
{
    Qwc_Rsval_Sys_Value_Table_t     entry[1];
    char                            data[20];
} sval_entry_struct_t;


/*
 * sys_os400_hardware()
 *
 * Return the printable name for the current machine or product type/model
 *
 */
int
sys_os400_hardware( struct sys_platform_s * p_pls )
{
    Qus_EC_t        errorCode;
    char *          sval;
    int             sval_len;
    char            value[11]    = "QMODEL    ";

    p_pls->os_hardware[0] = 0;  /* initialize with empty string */

    /* To determine the length of the receiver variable, the following    */
    /* calculation should be done. For each system value to be returned,  */
    /* get the length of the data returned for the system value and       */
    /* add 24. After adding the lengths for each system value, add 4.     */
    /*  This calculation takes into account the data alignment that needs */
    /*  to be done; therefore, this value is a worst-case estimate.       */

    sval_len = (24 + 4) + 4 ;  /* QMODEL = CHAR(4) */
    sval = malloc(sval_len);

    memset( &errorCode, 0x00,  sizeof(errorCode) );
    errorCode.Bytes_Provided  = sizeof(errorCode);

    QWCRSVAL((void *)sval,          /* Receiver variable              */
             sval_len,              /* Length of receiver variable    */
             1,                     /* Number of system values to rtv */
             (void *)value,         /* System value names             */
             (void *)&errorCode) ;  /* Error code                     */

    if ( errorCode.Bytes_Available > 0 )
    {
	sprintf(p_pls->os_hardware, "QWCRSVAL()failed: %.7s",
		errorCode.Exception_Id);
    } else  {
	int     len;
	char  * model;

	len   = ((sval_entry_struct_t*)(sval + ((sval_header_struct_t*)sval)->offset[0]))->entry[0].Length_Data;
	model = ((sval_entry_struct_t*)(sval + ((sval_header_struct_t*)sval)->offset[0]))->data;

	if ( len>=sizeof(p_pls->os_hardware) )
	    len = sizeof(p_pls->os_hardware)-1;

	sprintf(p_pls->os_hardware, "%.*s", len, model);
    }

    /* zero-terminate string (safety) */
    p_pls->os_hardware[sizeof(p_pls->os_hardware)-1] = 0;

    return(0); /* indicate success */

} /* sys_os400_hardware() */


#endif /* SYS_PLATFORM_OS400 */





#if defined(HAVE_POSIX_GETPWUID)

#  include <pwd.h>

/*
 * sys_posix_getpwuid()
 *
 *
 */
int
sys_posix_getpwuid( struct sys_platform_s * p_pls )
{
   struct passwd   * result;
   uid_t             my_uid = getuid();
   
   result = getpwuid( my_uid );
   memset( p_pls->user, 0, sizeof(p_pls->user) );
   if ( result==NULL ) {
      XVEB((V_BUG, "getpwent(%lu) failed: %s\n",
	           (Ulong)my_uid, strerror(errno) ));
   } else {
      strncpy( p_pls->user, result->pw_name, sizeof(p_pls->user) );
      p_pls->user[sizeof(p_pls->user)-1] = '\0';
      return(0);
   }

   return(1);

} /* sys_posix_getpwuid() */
#endif /* HAVE_POSIX_GETPWUID */



#if defined(HAVE_BSD_GETHOSTNAME)
/*
 * sys_bsd_gethostname()
 *
 *
 */
int
sys_bsd_gethostname( struct sys_platform_s * p_pls )
{
   int    rc;

   memset( p_pls->hostname, 0, sizeof(p_pls->hostname) );
   rc = gethostname( p_pls->hostname, sizeof(p_pls->hostname)-1 );
   if ( rc!=0 ) {
      XVEB((V_BUG, "gethostname() failed: %s\n", strerror(errno) ));
   }

   p_pls->hostname[sizeof(p_pls->hostname)-1] = '\0';

   if ( rc==0 )
      return(rc);

   return(1);

} /* sys_bsd_gethostname() */
#endif /* HAVE_BSD_GETHOSTNAME */


/************************************************************************
 ************************************************************************
 **								       **
 ** The Remaining is top level function and the same for all platforms **
 **								       **
 ************************************************************************
 ************************************************************************/

static char *days[] =
   { "Sun", "Mon", "Tue", "Wed", "Thu", "Fri", "Sat" };

static char *months[] =
   { "Jan", "Feb", "Mar", "Apr", "May", "Jun",
     "Jul", "Aug", "Sep", "Oct", "Nov", "Dec" };

union val_4 {
    unsigned int   intval;
    unsigned char  b4[4];
};

unsigned char little_endian[4] = { 1, 2, 3, 4 };
unsigned char big_endian[4]    = { 4, 3, 2, 1 };
unsigned char pdp_endian[4]    = { 3, 4, 1, 2 };


/*
 * sys_greeting()
 *
 *
 *
 */
void
sys_greeting( char * p_prefix, struct sys_platform_s * p_pls )
{
   struct tm             * ltime   = NULL;
   struct tm		 * gtime   = NULL;
   char			 * unknown = "(unknown)";
   char                  * endian  = unknown;
   char                  * charset = unknown;
   Ulong		   high, low;
   Ulong		   ohigh, olow;
   Ulong		   dbg_speed, opt_speed;
   long                    tl, tg;
   long			   tzdiffmin;
   time_t		   now;
   union val_4		   un4;
   int                     rc      = 0;

   XVEB((V_SHOW, "%s=====================================================================\n", p_prefix));

#ifdef SYS_PLATFORM_AS400
   as400_tzset();
#endif

   now   = time(NULL);
   ltime = localtime(&now);
   gtime = gmtime(&now);
   if ( ltime==NULL || gtime==NULL ) {
      XVEB((V_BUG, "HUH? localtime() failed!\n"));
   } else {
      /* calculate the difference between localtime and gmtime */
      /* to determine our offset from GMT/UTC		       */
      tl = ((ltime->tm_year-70)*365 + ltime->tm_yday)*24 + ltime->tm_hour;
      tl = tl*60 + ltime->tm_min;
      tg = ((gtime->tm_year-70)*365 + gtime->tm_yday)*24 + gtime->tm_hour;
      tg = tg*60 + gtime->tm_min;
      tzdiffmin = (tl - tg);
      tzdiffmin = (tzdiffmin/15)*15;

      XVEB((V_SHOW, "%s  Current Date&Time :  %s, %02d-%s-%4d   %02d:%02d:%02d   GMT %+03d:%02d\n", p_prefix,
		    days[ltime->tm_wday],
		    (int)ltime->tm_mday,
		    months[ltime->tm_mon],
		    (int)(1900+ltime->tm_year),
		    (int)ltime->tm_hour,
		    (int)ltime->tm_min,
		    (int)ltime->tm_sec,
		    (int)(tzdiffmin/60),
		    (int)(tzdiffmin%60) ));
   }

   Strmaxcpy( p_pls->os_name,     unknown, sizeof(p_pls->os_name)     );
   Strmaxcpy( p_pls->os_release,  unknown, sizeof(p_pls->os_release)  );
   Strmaxcpy( p_pls->os_hardware, unknown, sizeof(p_pls->os_hardware) );
   Strmaxcpy( p_pls->hostname,    unknown, sizeof(p_pls->hostname)    );
   Strmaxcpy( p_pls->user,        unknown, sizeof(p_pls->user)        );

   rc +=  SYS_GET_OSNAME(     p_pls );
   rc +=  SYS_GET_OSRELEASE(  p_pls );
   rc +=  SYS_GET_OSHARDWARE( p_pls );
   rc +=  SYS_GET_HOSTNAME(   p_pls );
   rc +=  SYS_GET_USERNAME(   p_pls );

   XVEB((V_SHOW, "%s  Operating System  :  %.100s\n",	 p_prefix, p_pls->os_name       ));
   XVEB((V_SHOW, "%s          -Release  :  %.100s\n",	 p_prefix, p_pls->os_release    ));
   XVEB((V_SHOW, "%s  Hardware/Machine  :  %.100s\n",	 p_prefix, p_pls->os_hardware   ));
   XVEB((V_SHOW, "%s  GSSTEST built for :  %.100s\n",    p_prefix, os_platform ));
   XVEB((V_SHOW, "%s  scalar C-types    :  void* ptrdiff_t size_t time_t long int wchar_t char\n", p_prefix));
   XVEB((V_SHOW, "%s    (sizes in bits) :   %3u     %u%s      %u%s    %u%s   %u%s %u%s   %u%s    %u%s\n",
			 p_prefix,
			 (Uint)(sizeof(void *)*8),   
			 (Uint)(sizeof(ptrdiff_t)*8),
				(((ptrdiff_t)-1)>>16 < 0) ? "s" : "u",
			 (Uint)(sizeof(size_t)*8),
				(((size_t)-1)>>16 < 0) ? "s" : "u",
			 (Uint)(sizeof(time_t)*8),
				(((time_t)-1)>>16 < 0) ? "s" : "u",
			 (Uint)(sizeof(long)*8),
				(((long)-1)>>2 < 0) ? "s" : "u",
			 (Uint)(sizeof(int)*8),
				(((int)-1)>>2 < 0) ? "s" : "u",
			 (Uint)(sizeof(wchar_t)*8),
				(((wchar_t)-1)>>2 < 0) ? "s" : "u",
			 (Uint)(sizeof(char)*8),
				(((char)-1)>>2 < 0) ? "s" : "u" ));

   un4.intval = 0x04030201;
   if ( memcmp(un4.b4, little_endian, 4)==0 ) {
       endian = "LITTLE_ENDIAN";
   } else if ( memcmp(un4.b4, big_endian, 4)==0 ) {
       endian = "BIG_ENDIAN";
   } else if ( memcmp(un4.b4, pdp_endian, 4)==0 ) {
       endian = "PDP_ENDIAN";
   }

   if ( 'A' == 0x41 && '1' == 0x31 ) {
       charset = "ASCII";
   } else if ( 'A' == 0xc1 && '1' == 0xF1 ) {
       charset = "EBCDIC";
   }

   XVEB((V_SHOW, "%s  Endianess, Charset:  %u%u%u%u (%s),  %s charset\n",
		 p_prefix, un4.b4[0], un4.b4[1], un4.b4[2], un4.b4[3],
		 endian, charset ));

   sys_machine_speed( &dbg_speed, &opt_speed );
   high  = dbg_speed / 100;
   low   = dbg_speed - (high*100);
   ohigh  = opt_speed / 100;
   olow   = opt_speed - (ohigh*100);
   XVEB((V_SHOW, "%s  Perf-Index (p-90) :  dbg= %lu.%02lu"
		 "   (opt= %lu.%02lu)\n",
		 p_prefix, (Ulong)high,  (Ulong)low,
		           (Ulong)ohigh, (Ulong)olow ));

   if (hrtimer_resolution!=0) {
      high = hrtimer_resolution / 1000;
      low  = hrtimer_resolution - (high * 1000);
      XVEB((V_SHOW, "%s  Timer Resolution  :  "
                    "%lu.%03lu millisec using \"%s\"\n",
		    p_prefix, (Ulong)high, (Ulong)low, hrtimer_name ));
   }

   XVEB((V_SHOW, "%s  Hostname          :  %.100s\n", p_prefix, p_pls->hostname ));
   XVEB((V_SHOW, "%s  Current user      :  %.100s\n", p_prefix, p_pls->user     ));

   XVEB((V_SHOW, "%s=====================================================================\n", p_prefix));

   return;

} /* sys_greeting() */




/*
 * sys_machine_speed()
 *
 * Description:
 *   Get a feeling for the CPU power of the current machine
 *   This is used to scale performance-related limits
 *
 */
void
sys_machine_speed( Ulong * dbg_speed, Ulong * opt_speed )
{
   char           * this_Call = "sys_machine_speed";
   Ulong            vals[16];
   Ulong            avg;
   Ulong            speed;
   Ulong            correction;
   unsigned char    digest[16];
   int              i;
   unsigned char  * memory;
   haMD5_CTX        md5_ctx;

   (*opt_speed) = (*dbg_speed) = 0;

   memory = (unsigned char *)malloc(BENCH_MEMSIZE);
   if ( memory==NULL ) {
      XVEB((V_BUG, "%s() error: malloc(%lu) failed!\n", this_Call, (Ulong) BENCH_MEMSIZE));
      return;
   }

   for ( i=0 ; i<16 ; i++ ) {
      start_timer();
      memset( memory, 0x5a, BENCH_MEMSIZE );
      haMD5Init(   &md5_ctx );
      haMD5Update( &md5_ctx, memory, BENCH_MEMSIZE );
      haMD5Final(   digest, &md5_ctx );
      vals[i] = read_timer();
   }

   avg = sample_avg( vals, sizeof(vals)/sizeof(vals[0]) );

   if ( avg>0 ) {
      speed        = (100 * PENTIUM90_SPEED_DBG) / avg;
      (*dbg_speed) = ((speed+5)/10) * 10;

      correction = (*dbg_speed + 70) / 2;
      if ( correction > 100 ) {
	 perf_correction = (float) correction / (float)100.0;
      } else {
	 perf_correction = 1.0;
      }

      speed        = (100 * PENTIUM90_SPEED_OPT) / avg;
      (*opt_speed) = ((speed+5)/10) * 10;
   }

   if ( memory!=NULL ) {
      free( memory );
      memory = NULL;
   }

   return;

} /* sys_machine_speed() */




/*
 * sys_get_hostname()
 *
 */
char *
sys_get_hostname( void )
{
   static struct sys_platform_s  pl;

   Strmaxcpy( pl.hostname,    "(unknown)", sizeof(pl.hostname) );

   SYS_GET_HOSTNAME( &pl );

   return( pl.hostname );

} /* sys_get_hostname() */




