static char sccsid[] = "@(#) $Id: //bas/46D/src/krn/rfc/sapinfo.c#1 $ SAP";

/* Usage :							*/
/* ./sap-banner ashost=10.0.0.2 sysnr=0 			*/
/*								*/
/* Compiling :							*/
/* ROOT=/home/nicob/SAP/rfcsdk-linux				*/
/* INCLUDE=$ROOT/include/					*/
/* LIB=$ROOT/lib/						*/
/* gcc  -I$INCLUDE -L$LIB sap-banner.c -o sapbnr -lrfc -ldl -lm	*/

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <ctype.h>
#include "saprfc.h"
#include "rfcsi.h"

void DLL_CALL_BACK_FUNCTION rfc_error( char * operation );

static void display_rfcsi( RFCSI * rfcsi );
static void help( void );

RFC_ERROR_INFO_EX  error_info;

main( int argc, char ** argv )
{
   RFC_ENV            new_env;
   RFC_HANDLE         handle;
   RFC_RC             rfc_rc;
   RFC_PARAMETER      exporting[32];
   RFC_PARAMETER      importing[32];
   RFC_TABLE          tables[32];
   RFCSI              rfcsi;
   char             * exception_ptr = NULL,
                      VersionBuffer[256],
		    * ptr,
		    * pa,
		    * pb,
		      pm_buf[257],
		      connect_param[1024];

   int                i, j, len,
		      client_found   = 0,
		      user_found     = 0,
		      passwd_found   = 0,
		      language_found = 0;

   char               std_client[4] = "360",
		      std_user[13]  = "Unknown",
		      std_pass[9]   = "Useless",
		      std_lang[3]   = "EN";

   if (argc < 2)
   {
     help();
     return 1;
   }

   /* -----------------------------------------------
    * Install error handler
    * ---------------------------------------------*/
   new_env.allocate = NULL;
   new_env.errorhandler = rfc_error;
   RfcEnvironment( &new_env );

   /* -----------------------------------------------
    * Put parameters from command to RfcOpenEx-Param.
    * ---------------------------------------------*/
    memset(connect_param, 0, sizeof(connect_param));
    ptr = connect_param;
    for (i=1; i<argc; i++)
    {
      len = strlen(argv[i]);

      /* Check syntax of connection parameters */
      pa = (char*)memchr(argv[i], '=', len);
      if (pa == NULL)
      {
        help();
        return 1;
      }

      /* Values which include blanks must be set in "..." */
      pb = (char*)memchr(argv[i], ' ', len);
      if (pb == NULL)
        strcpy(pm_buf, argv[i]);
      else
      {
        memset(pm_buf, 0, sizeof(pm_buf));
        pa = pa + 1;
        len = pa - argv[i];
        memcpy(pm_buf, argv[i], len);
        pm_buf[len] = '"';
        strcpy(pm_buf+len+1, pa);
        pm_buf[strlen(pm_buf)] = '"';
      }

      /* Copy into connect_param of RfcOpenEx */
      strcpy(ptr, pm_buf);
      ptr = ptr + strlen(ptr);
      *ptr++ = ' ';

      /* Special handling for SAP logon with default data */
      for (j=0; j<(int) strlen(argv[i]); j++)
      {
	if (argv[i][j] == '=')
	  break;
        argv[i][j] = (char) toupper(argv[i][j]);
      }

      if (memcmp(argv[i], "CLIENT=", 5) == 0)
        client_found = 1;
      else if (memcmp(argv[i], "USER=", 5) == 0)
        user_found = 1;
      else if (memcmp(argv[i], "PASSWD=", 7) == 0)
        passwd_found = 1;
      else if (memcmp(argv[i], "LANG=", 7) == 0)
        language_found = 1;
    }

    /* No logon check at OPEN time */
    strcpy(connect_param+strlen(connect_param), "LCHECK=0");

    /* Use default logon data if missing */
    if (client_found == 0)
      sprintf(connect_param+strlen(connect_param), " CLIENT=%s", std_client);
    if (user_found == 0)
      sprintf(connect_param+strlen(connect_param), " USER=%s", std_user);
    if (passwd_found == 0)
      sprintf(connect_param+strlen(connect_param), " PASSWD=%s", std_pass);
    if (language_found == 0)
      sprintf(connect_param+strlen(connect_param), " LANG=%s", std_lang);

   printf("Parametres de connexion : \n%s\n", connect_param);
   /* -----------------------------------------------
    * Open connection
    * ---------------------------------------------*/
   handle = RfcOpenEx(connect_param,
                      &error_info);

   if (handle == RFC_HANDLE_NULL)
   {
     printf("\nGroup       Error group %d", error_info.group);
     printf("\nKey         %s", error_info.key);
     printf("\nMessage     %s\n", error_info.message);
     exit(1);
   }

   printf("\nSucces !\n");

   /* -----------------------------------------------
    * Parameters
    * ---------------------------------------------*/

   importing[0].name = "RFCSI_EXPORT";
   importing[0].nlen = 12;
   importing[0].addr = &rfcsi;
   importing[0].leng = sizeof(rfcsi);
   importing[0].type = RFCTYPE_CHAR;
   
   importing[1].name = NULL;
   exporting[0].name = NULL;
   tables[0].name    = NULL;

   /* -----------------------------------------------
    * Call RFC function
    * ---------------------------------------------*/
   rfc_rc = RfcCallReceive( handle, "RFC_SYSTEM_INFO",
   /* rfc_rc = RfcCallReceive( handle, "RFC_PING", */
				    exporting,
				    importing,
				    tables,
				    &exception_ptr );
   
   if( rfc_rc != RFC_OK )
   {
     if ((rfc_rc == RFC_EXCEPTION) ||
         (rfc_rc == RFC_SYS_EXCEPTION))
       rfc_error( exception_ptr );
     else
       rfc_error( "RfcCallReceive" );
   }          
   else
   {
     /* -----------------------------------------------
      * Display results
      * ---------------------------------------------*/
      display_rfcsi( &rfcsi );
   }

   /* -----------------------------------------------
    * Close connection
    * ---------------------------------------------*/
   RfcClose( handle );

   return 0;
} /* main */


static void display_rfcsi( RFCSI * rfcsi )
{
#define OUT( text, value ) \
    printf( "%-22s %-.*s\n", text, (int) sizeof(rfcsi->value), rfcsi->value )
#define OUTX( text, value, add ) \
    printf( "%-22s %-.*s %s\n", text, (int) sizeof(rfcsi->value), \
	    rfcsi->value, (add) )
#define NLINE printf( "\n" )
#define HEADER( text ) \
   printf( "%s\n-----------------------------------------------\n\n", \
	   (text) )

    NLINE;
    NLINE;
    HEADER( "SAP System Information" );
    NLINE;
    OUT( "Destination", rfcdest );
    NLINE;
    if (rfcsi->rfchost2[0] != ' ')
      OUT( "Host", rfchost2 );
    else
      OUT( "Host1", rfchost );
      OUT( "Host2", rfchost2 );
    OUT( "System ID", rfcsysid );
    OUT( "Database", rfcdatabs );
    OUT( "DB host", rfcdbhost );
    OUT( "DB system", rfcdbsys );
    OUT( "OP sys ", rfcopsys );
    OUT( "IP addr ", rfcipaddr );
    OUT( "Resv ", rfcsi_resv );
    NLINE;
    OUT( "SAP release", rfcsaprl );
    OUT( "SAP kernel release", rfckernrl );
    NLINE;
    OUT( "RFC Protokoll", rfcproto );
    OUT( "Characters", rfcchartyp );
    OUT( "Integers ", rfcinttyp );
    OUT( "Floating P.", rfcflotyp );
    OUT( "SAP machine id", rfcmach );
    NLINE;
    OUTX( "Timezone", rfctzone,
	  rfcsi->rfcdayst[0] != ' ' ? "(Daylight saving time)" : "" );

    NLINE;
    NLINE;
} /* display_rfcsi */


void DLL_CALL_BACK_FUNCTION rfc_error( char * operation )
{
   printf("RFC Call/Exception: %s\n", operation );

   RfcLastErrorEx(&error_info);

   printf("\nGroup       Error group %d", error_info.group);
   printf("\nKey         %s", error_info.key);
   printf("\nMessage     %s\n", error_info.message);

   exit(1);

} /* rfc_error */


static void help( void )
{
#define NL "\n"
   printf( NL"Syntax: ./sap-banner ashost=10.0.0.2 sysnr=0"NL );
   return;
}
