/*!================================================================
 module:    

 responsible: MarcoP
 special area:   CPCDrv | Client | Trace SQL Commands 
 description: Tool zum Ein-/Aus-/Umschalten des Traces
              der Interface Runtime zur Laufzeit
               
 Tracemöglichkeiten:  short int   mögliche Tracearten der IRT
                                  nur Tracesatus in ShM schreiben = -2
                                  IRT beendet               	  = -1
                                  nicht initialisiert      		  =  0
                                  trace aus                		  =  1
                                  kurzer trace an          		  =  2
                                  langer trace an          		  =  3
                                  kurzer moduletrace an    		  =  4
                                  langer moduletrace an    		  =  5
                                  traceoptions aus profile 		  =  6
             
 
 see:  
 



    ========== licence begin  GPL
    Copyright (c) 2000-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 <stdlib.h>

#include "vpr08SharedMem.h"
#include "hsp100.h"
#include "vps99c.h"
#include "geo900.h"
#include "heo102.h"


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

static tpr08_sharedMem ashared_mem;
static tpr08_sharedMem *myshared_mem = &ashared_mem;
       
/*extern "C" int optind;
extern "C" char *optarg;
extern "C" int opterr;
*/
#define CALLER "IRTrace" 
/*==================================================================*
 *  PROTOTYPES                                                      *
 *==================================================================*/

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

void print_error(int errornr)
  {

   	switch (errornr)
   	{
   		case 0: /*shared memory object errors */
   		  fprintf(stderr,"Error! %d %s\n",myshared_mem->getErrornr(myshared_mem),myshared_mem->getErrortxt(myshared_mem));
          break;
   		case 1: /*help */
   		  fprintf(stderr,"usage: %s [-t<tracetyp>] -p <process-id | all> [-f pathname]\n\n"\
           	  		 "Options:\n"\
           			 "              -t type of trace\n"\
           			 "                   short  :: switch short trace on\n"\ 
           			 "                   long   :: switch long  trace on\n"\ 
           			 "                   off    :: switch trace off\n"\ 
           			 "              -p process id (for a single process)\n"\
           			 "           or -p all        (for all processes)\n"\
           	  		 "              -f path of shared memory file\n"\
           			  , CALLER);
          break;
        case 2:   /*usage */
          fprintf (stderr,"usage: %s [-t<tracetyp>] -p <process-id | all> [-f pathname]\n",CALLER);
          fprintf (stderr,"       %s -h : display help information\n",CALLER);
          break;        
        case 4:   /*argument is false */
          fprintf (stderr,"\nno trace options set for process-id \n",CALLER);
          break;        	
        default:   /* standard */
          fprintf (stderr,"usage: %s [-t<tracetyp>] -p <process-id | *>\n",CALLER);
          fprintf (stderr,"       %s -h : display help information\n",CALLER);
   	}
	exit(1);
  }
   
void set_trace(int apid, short int traceart)
   {
     if (myshared_mem->newPart(myshared_mem,apid))
     { 
     	myshared_mem->part_set_tracetyp(myshared_mem->part, traceart);
     	myshared_mem->header_set_traceswitchcount(myshared_mem->header);
     }
     else print_error(0);     
   }
   
void trace_all_on()
   {
     /* only if trace is off */
     if (myshared_mem->header_get_trace_all(myshared_mem->header) != 'y')
     {
      myshared_mem->header_set_trace_all_on(myshared_mem->header);
      myshared_mem->header_set_traceswitchcount(myshared_mem->header);
     } 
   }
  
void trace_all_off()
   {
     /* only if trace is on */
     if (myshared_mem->header_get_trace_all(myshared_mem->header) != 'n')
     {
     	myshared_mem->header_set_trace_all_off(myshared_mem->header);
      	myshared_mem->header_set_traceswitchcount(myshared_mem->header);
     }
   } 

void print_smdaten(int apid)
   {
   	fprintf( stderr , "\nlocation of shared memory file: %s \n",myshared_mem->getPath(myshared_mem));
    fprintf( stderr , "\nHeader\n");
    fprintf( stderr ,   "======\n");
    fprintf( stderr , "   TRACESWITCH     TRACE ALL     SHARED MEMORY SIZE\n");
    fprintf( stderr , "        %6d         %c                %d\n",myshared_mem->header_get_traceswitchcount(myshared_mem->header)\
        										       ,myshared_mem->header_get_trace_all(myshared_mem->header)\
        										       ,myshared_mem->header_get_sharedmemsize(myshared_mem->header));
 
    if (apid == 0)
    {
    	if (myshared_mem->firstPart(myshared_mem))
        {
        	fprintf( stderr , "\nPart\n");
          	fprintf( stderr ,   "====\n");
          	fprintf( stderr , "   PID    VERSION    TRACE STATUS   TRACE TYPE   PROFILE   LAST TRACE SWITCH\n");
            do
            {
          		fprintf( stderr , " %5d     %6d         %2d            %2d      %8s       %6d\n"\
          		                                    ,myshared_mem->part_get_pid            (myshared_mem->part)\
          										    ,myshared_mem->part_get_version        (myshared_mem->part)\
        										    ,myshared_mem->part_get_irt_tracestatus(myshared_mem->part)\
        										    ,myshared_mem->part_get_tracetyp       (myshared_mem->part)\
        										    ,myshared_mem->part_get_profile        (myshared_mem->part)\
        										    ,myshared_mem->part_get_lasttraceswitch(myshared_mem->part));
        	} while (myshared_mem->nextPart(myshared_mem));
        }
        else fprintf( stderr , "\nno parts in shared memory \n");
    }    
    else if (myshared_mem->findPart(myshared_mem,apid))
    {
        fprintf( stderr , "\nPart\n");
        fprintf( stderr ,   "====\n");
        fprintf( stderr , "   PID    VERSION    TRACE STATUS   TRACE TYPE   PROFILE   LAST TRACE SWITCH\n");
        fprintf( stderr , " %5d     %6d         %2d            %2d         %8s    %6d\n"\
                                                    ,myshared_mem->part_get_pid             (myshared_mem->part)\
          		  									,myshared_mem->part_get_version         (myshared_mem->part)\
        										    ,myshared_mem->part_get_irt_tracestatus (myshared_mem->part)\
        										    ,myshared_mem->part_get_tracetyp        (myshared_mem->part)\
        										    ,myshared_mem->part_get_profile         (myshared_mem->part)\
        										    ,myshared_mem->part_get_lasttraceswitch (myshared_mem->part));
	}
	else 
	{	
		fprintf( stderr , "\nno trace options for process %d \n",apid);
    }   
  } /* print_smsdaten */

void initShM(ShMInitTyp aInitTyp, char *path )
  {
    if (path)
    {
        printf("Pfad: %s\n",path);
    }
	    /* ShM initialize */
    if(! tpr08_sharedMem__init_sharedMem(myshared_mem, aInitTyp, path))
    {
         	print_error(0);
    }	 
  }

int  main( int argc , char **argv )
{
	int c;
	int error=0;
	int tflag=0;
	int pflag=0;
	int sflag=0;
	int fflag=0;
	char *toption,*poption,*foption=NULL; 
    opterr=0; /*  no echo if argument failed */
 
   /*parse options from command line */    
    while ((c = getopt(argc, argv, "hVsf:t:p:?")) != -1)
    {
        switch (c)
        {
        	case 'h':
            	print_error(1);
                exit(0);
            case 'V':
            {                          
	        	tsp00_Versionc  VersionString;
	        	sp100_GetVersionString ("IRTrace",s100buildnumber,VersionString);                         
	        	fprintf(stderr,"%s\n", &VersionString);
               	exit(0);
            }
            case 'f':
            {
            	fflag=optind;
                foption=optarg;
                break;
            }
            case 't':
            	tflag=optind;
                toption=optarg;
                break;

            case 'p':
            	 pflag=optind;
                 poption=optarg;
                 break;

          	case 's':
            	sflag=optind;
                break;
            case '?':
                print_error(2);
                break;
            default:
                print_error(2);
                break;        
		} /* case */
    } /* while */


    /* no paramters */
	if (!sflag && !tflag && !pflag)
    {
    	print_error(2);
    	exit(0);
    }
	
	/* only pflag is set => only print status for pid */
	if (pflag && !tflag && !sflag)
    {
		initShM(SHM_NOTERASE,foption);
		
		if (strcmp(poption,"all") == 0 )
		{   
		   /* list all processes */	
        	if (myshared_mem->firstPart(myshared_mem))
            {
         		fprintf( stderr , "\n    PID     VERSION     TRACE\n");
                do
                {	if(myshared_mem->part_get_irt_tracestatus(myshared_mem->part)!=-1)
                	{
          	    		fprintf( stderr , "  %5d      %6d     %s\n",myshared_mem->part_get_pid(myshared_mem->part)\
          			 	                      				   ,myshared_mem->part_get_version(myshared_mem->part)\
        							      					   ,myshared_mem->tracetyp_tochar(myshared_mem, myshared_mem->part_get_irt_tracestatus(myshared_mem->part)));
					}
        	    } while (myshared_mem->nextPart(myshared_mem));
            }
            else fprintf( stderr , "\nno tracing processes\n");
		}
		else
		{
			int k, mypid = atoi(poption);
			RTEProc_Handle  myHandle;
            bool            erg;
            erg = RTEProc_Open (mypid, &myHandle);
         	
          	if( RTEProc_GetState( myHandle ) != Alive)
           	{
           		fprintf( stderr , "\nno running process with ID %d\n",mypid);
           	}
			else
			{
            	/* write tracetyp -2 in ShM and wait a moment */
        		for (k=0; k<=5; k++)
        		{
        	   		if (myshared_mem->findPart(myshared_mem, mypid) && myshared_mem->part_get_irt_tracestatus(myshared_mem->part)!=0)
        	   		{
        				fprintf( stderr , "\n    PID     VERSION     TRACE\n");
          				fprintf( stderr , "  %5d      %6d     %s\n"	,myshared_mem->part_get_pid(myshared_mem->part)\
          	            	   				           				,myshared_mem->part_get_version(myshared_mem->part)\
                            	                       				,myshared_mem->tracetyp_tochar(myshared_mem, myshared_mem->part_get_irt_tracestatus(myshared_mem->part)));
                        break; 
        	    	}
        	    	set_trace(mypid,-2);
        			sqlsleep (1);
        		}
        		if (!myshared_mem->findPart(myshared_mem,mypid) || myshared_mem->part_get_irt_tracestatus(myshared_mem->part)==0)
        	   	{ fprintf( stderr , "\nno trace options for process %d available\n",mypid);}
    		}
            /*close handle of process*/
            erg = RTEProc_Close ( myHandle );


    		/* if trace all is on */
        	if(myshared_mem->header_get_trace_all(myshared_mem->header) == 'y')
        	{
       			fprintf( stderr , "\ntrace switched on for all interface runtimes\n");
        	}
    	}
    }
	
	/* only tflag is set */
	if (tflag && !pflag)
    {
    	print_error(2);
    	exit(0);	
    }		

	/* tflag and pflag is set */
	if (tflag && pflag)
        {	
            int  mypid;
            
        	if (strcmp(poption,"all") == 0 )
			{
        		initShM(SHM_ERASE,foption);	
            	/* trace all on/off */
				if (strcmp(toption,"short") == 0 || strcmp(toption,"long") == 0)
		  		{
     				trace_all_on();
    	            fprintf(stderr , "\ntrace switched on for all interface runtimes\n");
    	        }     
				else if (strcmp(toption,"off") == 0 )
		   		{
		        	trace_all_off();
    	            fprintf(stderr , "\ntrace switched off for all interface runtimes\n");
    	        }    
				else    {print_error(2);}
                exit(0);
            }
        	
        	
        	mypid= atoi(poption);
        	if ( mypid != 0)
        	{
        	    if (strcmp(toption,"info") == 0 )
        	    {
        	    	initShM(SHM_NOTERASE,foption);
        	    	set_trace(mypid,-2);
    	            fprintf( stderr , "\ninfos about tracing for process %d comming soon\n",mypid);
    	            fprintf( stderr , "type: %s -p %d\n",CALLER,mypid);
        	        exit (0);	
        	    }
        	    
        	    initShM(SHM_ERASE,foption);	
				if (strcmp(toption,"off") == 0 )
		  		{
                	set_trace(mypid,0);
    	            fprintf( stderr , "\ntracing for process %d switched off\n",mypid);
    	        }     
				else if (strcmp(toption,"long") == 0 )
		   		{
                   	set_trace(mypid,3);
    	           	fprintf( stderr , "\nlong trace for process %d switched on\n",mypid);
    	        }    
				else if (strcmp(toption,"short") == 0 )
		   		{
                   	set_trace(mypid,2);
    	           	fprintf( stderr , "\nshort trace for process %d switched on\n",mypid);
    	        }    
			else    {print_error(2);}
        }
        else    {print_error(2);}
        exit(0);
	}

	/* sflag and pflag is set -> print content of shared memory part */ 
	if (sflag)
    {
		initShM(SHM_NOTERASE,foption);    	
        if (pflag)
        {   
        	int mypid = atoi(poption);
	        print_smdaten(mypid);
	   	}
	   	else print_smdaten(0);
    exit(0);
    }
return (0);    
}   /* main */	
    