static char sccsid[] = "@(#)sapinfo     20.25.1.1     SAP     96/07/10";

#include "stdio.h"
#include "stdlib.h"
#include "string.h"
#include "saprfc.h"
#include "rfcsi.h"

/* rfc_error darf wegen Windows DLL nicht static sein. */
void DLL_CALL_BACK_FUNCTION rfc_error( char * operation );

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


main( int argc, char ** argv )
{
   static RFC_OPTIONS rfc_opt;
   static RFC_CONNOPT_CPIC   rfc_connopt_cpic;
   static RFC_CONNOPT_R3ONLY rfc_connopt_r3only;
   RFC_ENV            new_env;
   RFC_HANDLE         handle;
   RFC_RC             rfc_rc;
   static RFC_PARAMETER      exporting[32];
   static RFC_PARAMETER      importing[32];
   static RFC_TABLE          tables[32];
   RFCSI              rfcsi;
   char *             exception_ptr = NULL;
   int        argcnt;
   char VersionBuffer[256];

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

   /* -----------------------------------------------
    * Defaults
    * ---------------------------------------------*/
   rfc_opt.client   = "000";
   rfc_opt.user     = "SAP*";
   rfc_opt.language = "E";
   rfc_opt.password = "PASS";
   rfc_opt.trace    = 0;
   rfc_opt.mode     = RFC_MODE_R3ONLY;

   /* -----------------------------------------------
    * Macintosh init
    * ---------------------------------------------*/
#ifdef SAPonApple
	MacInit(&argc, &argv);
#endif

   /* -----------------------------------------------
    * Command line parsing
    * ---------------------------------------------*/
   if(RfcFileArgv(&argc, &argv) == RFC_FAILURE)
		printf("Error handling reading or writing commandline arguments from/to file\n");
   /* warning: RfcConnArgv changes argv  without changing argc !! */
   RfcConnArgv( argv, &rfc_opt, &rfc_connopt_cpic,
		&rfc_connopt_r3only );

argcnt = 1;

   while( argv[argcnt] != NULL )
   {
      if( argv[argcnt][0] == '-' )
      {
          switch( argv[argcnt][1] )
          {
             case 'v':   
               RfcGetAllLibVersions(VersionBuffer, sizeof(VersionBuffer)); 
               printf(VersionBuffer);
               return 0;
             case '?' :
               help();
               return 0;
             default  :
               help();
               return 1;
          }
		  /* not neccessary cause all options return */
          /* if( argv[argcnt] != NULL ) argcnt++; */ 
      }
      else
      {
          rfc_opt.destination = argv[argcnt];
          argcnt++;
          break;
      }
   }

   if( rfc_opt.destination == NULL )
   {
      help();
      return 1;
   }

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

   /* -----------------------------------------------
    * Open connection
    * ---------------------------------------------*/
   handle = RfcOpen( &rfc_opt );

   if( handle == RFC_HANDLE_NULL )
   {
      rfc_error( "open" );
      return 1;
   }

   /* -----------------------------------------------
    * Parameters
    * ---------------------------------------------*/
   importing[0].name = "RFCSI_EXPORT";
   importing[0].nlen = 12;
   importing[0].addr = &rfcsi;
   importing[0].leng = sizeof(rfcsi);
   importing[0].type = TYPC;

   importing[1].name = NULL;
   exporting[0].name = NULL;
   tables[0].name    = NULL;

   /* -----------------------------------------------
    * Call RFC function
    * ---------------------------------------------*/
   rfc_rc = RfcCallReceive( handle, "RFC_SYSTEM_INFO",
				    exporting,
				    importing,
				    tables,
				    &exception_ptr );
   if( rfc_rc != RFC_OK )
   {
       if( rfc_rc == RFC_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, sizeof(rfcsi->value), rfcsi->value );
#define OUTX( text, value, add ) \
    printf( "%-22s %-.*s %s\n", text, 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;
    OUT( "Host", rfchost );
    OUT( "System ID", rfcsysid );
    OUT( "Database", rfcdatabs );
    OUT( "DB host", rfcdbhost );
    OUT( "DB system", rfcdbsys );
    NLINE;
    OUT( "SAP release", rfcsaprl );
    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 )
{
   RFC_ERROR_INFO error_info;
   fprintf( stderr, "RFC error : operation/code %s\n", operation );
   memset( &error_info, 0, sizeof( error_info ) );
   RfcLastError( &error_info );
   fprintf( stderr, "Error info :\n" );
   fprintf( stderr, "key     : %s\n", error_info.key );
   fprintf( stderr, "status  : %s\n", error_info.status );
   fprintf( stderr, "message : %s\n", error_info.message );
   fprintf( stderr, "internal: %s\n", error_info.intstat );
   return;
} /* rfc_error */

static void RfcConnArgvHelp ( FILE * file )
{
   fprintf( file, 
      "RFC connection options:\n\n" );
   fprintf( file, 
      "  -d <destination>      name of the RFC destination.\n"
      "           Necessary, if you are using a 'sideinfo' file.\n\n" );
   fprintf( file,
      "  -2                    SNA mode on.\n"
      "           You must set this if you want to connect to R/2.\n"
      "           All other conection data must be suppplied by a\n"
      "           sideinfo file.\n\n" );
   fprintf( file,
      "  -3                    R/3 mode on.\n"
      "           You must set this if you want to connect to R/3.\n"
      "           Specify the following options:\n\n" );
   fprintf( file,
      "      -h <hostname>         hostname of the R/3 target system.\n\n" );
   fprintf( file,
      "      -s <system number>    system number of the target system.\n"
      "           this determines the TCP/IP service to be used to connect\n"
      "           to the R/3 system. The default value is 0 and the default\n"
      "           service being used then is sapgw00.\n\n" );
#ifndef SAPonWINDOWS
   fprintf( file,
      "      -gui               start sapgui\n"
      "           to allow dynpro and graphics processing\n"
      "           (3.0C or later required on the target system).\n\n" );  
#endif                       
   fprintf( file, 
      "      Using an intermediate SAP gateway, specify:\n"
      "           -g <gateway host>\n"
      "           -x <gateway service>\n"
      "           (must not be used with -gui or -debug option).\n\n" );      
#ifndef SAPonWINDOWS
   fprintf( file,
      "  -balanced             load balancing mode.\n"
      "           Another way to connect to R/3, if the R/3 system is 3.0C\n"
      "           or later and workload balancing is active on that system.\n"
      "           Requests are automatically routed to the application server\n"
      "           having the best response times in the moment.\n"
      "           Specify the following options:\n\n" );  
   fprintf( file,
      "      -h <host name>     hostname of R/3's message server.\n\n" );
   fprintf( file,
      "      -s <system name>   name of the target system.\n"
      "           This determines the TCP/IP service to be used to connect\n"
      "           to the R/3 system. \n"
      "           The system name is a 3 letter word. If the system name\n"
      "           is XXX, the service being used is sapXXX.\n\n" );
   fprintf( file,
      "      -g <group name>    name of application server group.\n"
      "           The default is PUBLIC.\n\n" );
   fprintf( file,
      "      -gui               start sapgui\n"
      "           to allow dynpro and graphics processing.\n\n" );                   
#endif
   fprintf( file,
      "additional options:\n\n" );
   fprintf( file,
      "  -t              turn trace on.\n"
      "           all operations are written to the trace file 'dev_rfc'\n\n" );
#ifndef SAPonWINDOWS
   fprintf( file,
      "  -debug          turn ABAP/4 debugging mode on.\n"
      "           this can only be done, if sapgui is installed on the client\n"
      "           system and the target system has version 3.0C or later.\n\n" );
#endif
   fprintf( file, 
      "RFC logon data:\n\n");
   fprintf( file, 
      "  -u <userid>      SAP userid.\n\n" );
   fprintf( file, 
      "  -p <password>    password.\n\n" );
   fprintf( file, 
      "  -c <client>      client.\n\n" );
   fprintf( file, 
      "  -l <language>    logon language.\n\n" );

   return;
}


static void help( void )
{
#define NL "\n"
   printf( NL                                                              );
   printf( "Give informations on SAP system "                        NL NL );
   printf( "Syntax :"                                                NL );
   printf( "         sapinfo [options] [<destination>]"              NL NL );

   RfcConnArgvHelp( stdout );

   printf( "Further options:"                                        NL );
   printf( "          -v                             show lib versions" NL );
   printf( "          -o <output file for argv>      "               NL );
   printf( "          -i <input file for argv>       "               NL );
   printf( "          -?                             this text"      NL NL );
   return;
}
