.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$vct05c$
.tt 2 $$$
.tt 3 $H.Becker$GetFilepath $1997-12-02$
***********************************************************
.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  : GetFilePtah
=========
.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  : H. Becker
.sp
.cp 3
Created : 02.12.97
.sp
.cp 3
Version :
.sp
.cp 3
Release :  6.2 	 Date : 1997-12-02
.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*/

//
//  INCLUDE FILES
//

#include      <stdlib.h>
#include      <windows.h>
#include      <windef.h>
#include      <stdarg.h>
#include      <winbase.h>
#include      <io.h>
#include      <direct.h>
#include      <string.h>
#include      <memory.h>


//
//  DEFINES
//


#define         FILENAMESIZE            64
#define         LINESIZE                256
#define         CMDBUFFERSIZE           5120


#define	FILL(d,v,l)	(void) memset ( (char*)(d) ,   (int)(v) , (int)(l) )

#undef	FALSE
#define	FALSE		0
#undef	TRUE
#define	TRUE		1
#undef	NULL
#define	NULL		0L

//
//  MACROS
//


//
//  LOCAL TYPE AND STRUCT DEFINITIONS
//


typedef char VFILENAME  [ FILENAMESIZE ];

//
//  EXTERNAL VARIABLES
//


//
//  EXPORTED VARIABLES
//


//
//  LOCAL VARIABLES
//


//
//  LOCAL FUNCTION PROTOTYPES
//

static void  PtoC   ( char *pszTarget, char *psSource, SHORT cbSource );
static void  CtoP   ( char *psTarget, char *pszSource, int  cbTarget );
static int   CmdExe ( char* Cmd, char* ErgLine, int*  ErgLen );

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



void  c05get_file_path (
             VFILENAME modul, 
             VFILENAME modulpath, 
             int*  ok)

{
 
   char  CModul    [sizeof(VFILENAME)+1];
   char  CmdResult [sizeof(VFILENAME)+1];
   int   CmdResultLen;
   int   rc;
   char  cmd [LINESIZE];              
   char  GetFilePath[]  = "GetFilePath";
   char  PerlOpt[]      = " -S ";
   char  *TOOLSHELL     = getenv("TOOLSHELL");
   char  *TOOLEXT       = getenv("TOOLEXT");
   int i;

   *ok = TRUE; 

   
   PtoC (CModul, modul, sizeof(VFILENAME));	
   
   strcpy (cmd, TOOLSHELL);
   strcat (cmd, PerlOpt);
   strcat (cmd, GetFilePath);
   strcat (cmd, TOOLEXT);
   strcat (cmd, " ");
   strcat (cmd, CModul);

   CmdResultLen = sizeof(VFILENAME);
   if ( CmdExe ( cmd, CmdResult, &CmdResultLen ) )
     ok = FALSE;
 
   CmdResult [CmdResultLen] = '\0';

   CtoP (modulpath, CmdResult, sizeof(VFILENAME));

}

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

void  PtoC ( char   *pszTarget,
             char   *psSource,
             SHORT  cbSource )
  {
  char *psS;       /* pascal string ptr */
  char *pszT;      /* C string ptr */


  psS = psSource + cbSource - 1;
  pszT = pszTarget + cbSource;

  *pszT-- = '\0';

  while (psS >= psSource && *psS == ' ')
    {
    *pszT-- = '\0';
    psS--;
    }

  while (psS >= psSource)
    *pszT-- = *psS--;

  }


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


void  CtoP ( char *psTarget,
             char *pszSource,
             int  cbTarget )
  {


  while (cbTarget-- > 0)
    if (*pszSource == '\0')
      *psTarget++ = ' ';
    else
      *psTarget++ = *pszSource++;

  }


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


int  CmdExe (char* Cmd, 
             char* ErgLine,
             int*  ErgLen )

{
    int				rc ;
    int				len ;
    DWORD			dwRead ;
    DWORD			errcode ;
    HANDLE			hChildStdoutRd ;
    HANDLE			hChildStdoutWr ;
    HANDLE			hChildStderrWr ;
    HANDLE			hSaveStdout ;
    HANDLE			hSaveStderr ;
    SECURITY_ATTRIBUTES		saAttr ;
    PROCESS_INFORMATION		piProcInfo ;
    STARTUPINFO			siStartInfo ;


    /*
     *  Set the bInheritHandle flag so pipe handles are inherited.
     */
    saAttr.nLength = sizeof(SECURITY_ATTRIBUTES);
    saAttr.bInheritHandle = TRUE;
    saAttr.lpSecurityDescriptor = NULL;

    /*
     * The steps for redirecting child's STDOUT:
     *     1.  Save current STDOUT, to be restored later.
     *     2.  Create anonymous pipe to be STDOUT for child.
     *     3.  Set STDOUT of parent to be write handle of pipe, so
     *         it is inherited by child.
     */

    /*
     *  Create a pipe for the child's STDOUT.
     */
    if (!CreatePipe(&hChildStdoutRd, &hChildStdoutWr, &saAttr, 0))
    {
	return ( -2 );
    }

    /*
     *  Create a duplicated pipe for the child's STDERR
     *  (duplicated from child's STDOUT)
     */
	if (! DuplicateHandle(
				GetCurrentProcess(),	
                                // handle to process with handle to duplicate 
				hChildStdoutWr,	
                                // handle to duplicate 
				GetCurrentProcess(),	
                                // handle to process to duplicate to 
				&hChildStderrWr,
                                // pointer to duplicate handle 
				DUPLICATE_SAME_ACCESS,	
                                // access for duplicate handle 
				TRUE,	
                                // handle inheritance flag
				DUPLICATE_SAME_ACCESS 	
                                // optional actions   
				) )
	{
	(void) CloseHandle(hChildStdoutWr);
	(void) CloseHandle(hChildStdoutRd);
	return ( -2 );
	}


    /*
     *  Save the handle to the current STDOUT.
     */
    hSaveStdout = GetStdHandle(STD_OUTPUT_HANDLE);
    hSaveStderr = GetStdHandle(STD_ERROR_HANDLE);

    /*
     *  Set a write handle to the pipe to be STDOUT and STDERR.
     */
    if (!SetStdHandle(STD_OUTPUT_HANDLE, hChildStdoutWr))
    {
	(void) CloseHandle(hChildStdoutWr);
	(void) CloseHandle(hChildStdoutRd);
	(void) CloseHandle(hChildStderrWr);
	return ( -2 );
    }
    if (!SetStdHandle(STD_ERROR_HANDLE, hChildStderrWr))
    {
	(void) CloseHandle(hChildStdoutWr);
	(void) CloseHandle(hChildStdoutRd);
	(void) CloseHandle(hChildStderrWr);
	return ( -2 );
    }

    /*
     *  Set up members of STARTUPINFO structure.
     */
    FILL ( &siStartInfo , 0 , sizeof(STARTUPINFO) );
    siStartInfo.cb = sizeof(STARTUPINFO);
    siStartInfo.lpReserved = NULL;
    siStartInfo.lpReserved2 = NULL;
    siStartInfo.cbReserved2 = 0;
    siStartInfo.lpDesktop = NULL;
    siStartInfo.dwFlags = 0;

    /*
     *  Now create the child process.
     */
    rc = CreateProcess( NULL ,
                        /* program                            */
			Cmd ,		
                        /* command line                       */
			NULL ,		
                        /* process security attributes        */
			NULL ,
                        /* primary thread security attributes */
			TRUE ,		
                        /* handles are inherited              */
			0 ,
                        /* creation flags                     */
			NULL ,	
                    	/* use parent's environment           */
			NULL ,
                        /* use parent's current directory     */
			&siStartInfo ,	
                        /* STARTUPINFO pointer                */
			&piProcInfo ); 	
                        /* receives PROCESS_INFORMATION       */

    /*
     *  After process creation, restore the saved STDOUT and STDERR.
     */
    if (!SetStdHandle(STD_ERROR_HANDLE, hSaveStderr))
    {
	(void) CloseHandle(hChildStdoutWr);
	(void) CloseHandle(hChildStdoutRd);
	(void) CloseHandle(hChildStderrWr);
	return ( -2 );
    }
    if (!SetStdHandle(STD_OUTPUT_HANDLE, hSaveStdout))
    {
	(void) CloseHandle(hChildStdoutWr);
	(void) CloseHandle(hChildStdoutRd);
	(void) CloseHandle(hChildStderrWr);
	return ( -2 );
    }

    /*
     *  If the process creation failed, give an error message
     *  AFTER stderr has been restored!
     */
    if ( ! rc )
    {
	(void) CloseHandle(hChildStdoutWr);
	(void) CloseHandle(hChildStdoutRd);
	(void) CloseHandle(hChildStderrWr);
	return ( -2 );
    }

    /* 
     *  Close the write end of the pipe before reading from the 
     *  read end of the pipe. 
     */
    (void) CloseHandle(hChildStdoutWr);
    (void) CloseHandle(hChildStderrWr);

    /*
     *  Read from pipe that is the standard output for child process.
     */
    for ( len = 0 ; ; )
    {
        if (!ReadFile(hChildStdoutRd, ErgLine , *ErgLen, &dwRead, NULL))
	{

	    if ( GetLastError() == ERROR_BROKEN_PIPE )
		dwRead = 0 ;
	    break ;
	}
	*ErgLen = dwRead ;
	if ( *ErgLen == 0 ) break ;

    }

    /* 
     *  Close the read end of the pipe.
     */
    (void) CloseHandle(hChildStdoutRd);

    if ( WaitForSingleObject ( piProcInfo.hProcess , INFINITE ) 
               == WAIT_FAILED )
    {
	return ( -2 );
    }

    if ( ! GetExitCodeProcess ( piProcInfo.hProcess , &dwRead ) )
    {
	return ( -2 );
    }

    CloseHandle ( piProcInfo.hThread ); 
    CloseHandle ( piProcInfo.hProcess );

    if ( dwRead == 0 ) return ( 0 );

    return ( -2 );
}

//
// =============================== END ========================================

.CM *-END-* code ----------------------------------------
.SP 2
***********************************************************
.PA
