.ad 8
.bm 8
.fm 4
.bt $Copyright (c) 1992-2004 SAP AG-2002$$Page %$
.tm 12
.hm 6
.hs 3
.tt 1 $SQL$Project Distributed Database System$VPS01C$
.tt 2 $$$
.tt 3 $RaymondR$General Driver utilities$$$2001-01-12$
*********************************************************
.nf

.nf


    ========== licence begin  GPL
    Copyright (c) 1992-2004 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

.fo


.fo
Module  :
=========
.sp
Purpose :
.CM *-END-* purpose -------------------------------------
Define  :

int p01file (const char *path);
int p01size (const char *path);
void p01displ (const char *path);
void p01copy (const char *path1, const char *path2);
void p01cat (const char *path1, const char *path2);
void p01rmv (const char *path);
const char *p01basen (const char *path);
void p01minit (int lines);
void p01mfin (void);
void p01more (char *buf, int len);
void p01mdisp (const char *path);
int p01exec (const char* path, char *argv [], int ovl,
        const char *file, int mode);
#include "gip00.h"
#define PS01_COMPILER COMPILER_IP00
#define PS01_CPP_COMPILER CPP_COMPILER_IP00
#define PS01_LINKER   LINKER_IP00
#define PS01_CPP_LINKER CPP_LINKER_IP00
.CM *-END-* define --------------------------------------
Use     :
.CM *-END-* use -----------------------------------------
Synonym :
.CM *-END-* synonym -------------------------------------
.sp;.cp 3
Author  :
.sp
.cp 3
Created : 1994-03-15
.sp
.cp 3
Version : 1994-08-31
.sp
.cp 3
Release :      Date : 2001-01-12
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
.sp
.CM -lll-
Code    :
/*PRETTY*/
&ifdef DEBUG
&else
#line 79 "vps01c"
&endif

&if $OS = MSDOS
 #ifdef _WINDOWS
  #undef _WINDOWS
 #endif
&endif

#include <stdio.h>
#include <string.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <signal.h>

&if $OS in [ WIN32, OS2, MSDOS ]
&if $OS = WIN32 || $OS = MSDOS
  #include <windows.h>
&else
  #include <sys/stat.h>
  #include <process.h>
  #define _S_IREAD   S_IREAD
  #define _S_IWRITE  S_IWRITE
  #define _P_OVERLAY P_OVERLAY
  #define _P_WAIT    P_WAIT
&endif
 #include <conio.h>
 #include <malloc.h>
&else
#include <unistd.h>
 #include <sys/wait.h>
 #include <termio.h>
&if $MACH = NMP
 #include <errno.h>
&endif
&endif

extern int unlink (const char*);
&if $OS not in [ WIN32, OS2, MSDOS ]
  extern int isatty (int);
  extern char *ttyname (int);
  extern int dup (int);
  extern int close (int);
  extern void exit (int);

&if $OSSPEC not in [AIX]
&if $OSSPEC not in [LINUX]
/* ADIS 1000702 */
  extern int ioctl (int, int, ...);
&endif
&else
/* ADIS 4309 */
#ifdef _NO_PROTO
#undef _NO_PROTO
#endif
&endif

  static struct MSTR /* terminal description for "more" functions */
  {
        int lines, cnt;
        int ttydes;
        struct termio term;
  } ms = {0, 0};

&else

  static struct MSTR /* terminal description for "more" functions */
  {
        int lines, cnt;
&if $OS = WIN32
        HANDLE ttyhnd;
&else
        int ttydes;
&endif
  } ms = {0, 0};

&endif

&if $OS = MSDOS
  extern int e25_batchmode;
&endif

&ifdef DEBUG
&else
#line 151 "vps01c"
&endif

void p01minit (int lines);   /*exported functions*/
void p01mfin (void);

static void p01mmsg (void);  /*local function prototypes*/
static void p01mexit ();

int p01file (const char *path)

/*      Returns 1, if the file named by path exists, 0 otherwise.
*/

{
        struct stat fstat;
        return (stat ((char*) path, &fstat) == 0);
}

int p01size (const char *path)

/*      Returns the file size, if the file named by path exists, 0 otherwise.
*/

{
        struct stat fstat;
        int size = 0;

        if (stat ((char*) path, &fstat) == 0)
                size = fstat.st_size;
        return size;
}

void p01displ (const char *path)

/*      Displays the contents of the file named by path on stdout.
*/

{
        FILE *fp;
        int c;

        if (fp = fopen (path, "r"))
        {
                while ((c = getc (fp)) != EOF)
                        putchar (c);
                fclose (fp);
        }
}

void p01copy (const char *path1, const char *path2)

/*      Copies the contents of the file named by path1 to the file named by
        path2.
*/

{
        FILE *fp1, *fp2;
        int c;

        if ((fp1 = fopen (path1, "r")) && (fp2 = fopen (path2, "w")))
        {
                while ((c = getc (fp1)) != EOF)
                        putc (c, fp2);
                fclose (fp1);
                fclose (fp2);
        }
}

void p01cat (const char *path1, const char *path2)

/*      Appends the contents of the file named by path1 to the file named by
        path2.
*/

{
        FILE *fp1, *fp2;
        int c;

        if ((fp1 = fopen (path1, "r")) && (fp2 = fopen (path2, "a")))
        {
                while ((c = getc (fp1)) != EOF)
                        putc (c, fp2);
                fclose (fp1);
                fclose (fp2);
        }
}

void p01rmv (const char *path)

/*      Removes the file named by path, if it exists.
*/

{
        if (p01file (path))
                unlink (path);
}


void p01more (char *buf, int len)

/*      Output of len characters from buf as lines in more mode.
        Lines must be separated by '\n'. If buf [len - 1] is not '\n',
        a '\n' will be appended.
*/
{
        char *s0 = buf, *s1, *s2 = buf + len;

        if (ms.lines > 0)
        {
                for (s1 = buf; s1 < s2; s1++)
                        if (*s1 == '\n')
                        {
                                if (ms.lines > 0)
                                        p01mmsg ();
                                if (ms.lines > 0)
                                        printf ("%.*s\n", s1 - s0, s0);
                                s0 = s1 + 1;
                        }
                if (s0 < s2)
                {
                        if (ms.lines > 0)
                                p01mmsg ();
                        if (ms.lines > 0)
                                printf ("%.*s\n", s1 - s0, s0);
                }
        }
        else if (ms.lines == 0)
        {
                if (buf [len - 1] == '\n')
                        len--;
                printf ("%.*s\n", len, buf);
        }
}

void p01mdisp (const char *path)

/*      Displays the contents of the file named by path on stdout in
        more mode. A maximum of 80 characters per line are displayed.
*/

{
        FILE *fp;
        const int nlines = 20;
        char line [81];
        void (*hdl) (int);

        hdl = signal (SIGINT, (void (*) (int)) p01mexit);
        p01minit (nlines);

        if (fp = fopen (path, "r"))
        {
                while (fgets (line, sizeof (line), fp))
                        p01more (line, strlen (line));
        }
        p01mfin ();
        signal (SIGINT, hdl);
}


&if $OS not in [ WIN32, OS2, MSDOS ]

&ifdef DEBUG
&else
#line 296 "vps01c"
&endif

const char *p01basen (const char *path)

/*      Returns a pointer to the basename of the pathname path.
*/

{
        const char DC = '/';
        const char *s;

        if (s = strrchr (path, DC))
                s++;
        else
                s = path;

        return s;
}


void p01minit (int lines)

/*      Initialization of a tty for output in more mode.
        The parameter is the number of lines of an output page.
*/
{
        int outdes;
        struct termio term;

        ms.ttydes = fileno (stdin);
        outdes = fileno (stdout);
        if ((!isatty (ms.ttydes) || !isatty (outdes) || lines == 0 ) ? 1 :
                strcmp (ttyname (ms.ttydes), ttyname (outdes)))
                return;

        ms.lines = lines;
        ioctl (ms.ttydes, TCGETA, &ms.term);
        term = ms.term;
        term.c_lflag &= ~ICANON;
        term.c_lflag &= ~ECHO;
        term.c_cc[VEOF] = 1;
        ioctl (ms.ttydes, TCSETA, &term);
}

void p01mfin (void)

/*      Reset of a tty to its initial state stored in ms.term */
{
        if (ms.lines)
        {
                ms.lines = 0;
                ioctl (ms.ttydes, TCSETA, &ms.term);
        }
}

static void p01mmsg (void)
{
        int inp;

        if (++ms.cnt > ms.lines)
        {
                printf ("--More--");
                inp = getchar ();
                if (inp == 'q')
                        ms.lines = -1;
                else
                        ms.cnt = 0;
                printf ("\r        \r");
        }
}

static void p01mexit ()
{
        p01mfin ();
        exit (1);
}

int p01exec (const char* path, char *argv [], int ovl,
        const char *file, int mode)

/*      Submits a new process constructed from the file named by path.
        The environment is passed by the array argv, terminated by a
        null pointer.
        If ovl is nonzero, the new process overlays the caller,
        otherwise the function waits for the termination of the
        submitted process and returns its exit status.
        If file is not NULL, some of the submitted process' standard
        file descriptors will be redirected to file.
        If mode & i is nonzero (i = 0, 1, 2), the file descriptor i
        will be redirected to file.
*/

{
        pid_t pid;
        int stat;
        int fildes;

        if (!ovl)
                if ((pid = fork ()) != 0)
                {
		  /* ADIS 4284 */
		  stat = 0;
		  if (pid != -1) {
&if $MACH = NMP
			  int rc;			
			  do {	
				  rc=waitpid (pid, &stat, 0);
			  } while ((rc < 0) && (errno == EINTR)); /* PTS 1108681 */
&else
			  waitpid (pid, &stat, 0);
&endif		
		  }
		  else
		    {
		      perror ("p01exec");
		      exit (-1);
		    }
		  return WEXITSTATUS(stat);
                }
        stat = 0;
        if (file)
        {
                fildes = (mode == 0) ? open (file, O_RDONLY) :
                        open (file, O_WRONLY | O_CREAT | O_TRUNC, 0644);
                if (fildes == -1)
                {
                        perror (file);
                        stat = 256;
                }
                if (mode == 0)
                {
                        close (0);
                        dup (fildes);
                }
                else if (mode & 1)
                {
                        close (1);
                        dup (fildes);
                        if (mode & 2)
                        {
                                close (2);
                                dup (fildes);
                        }
                }
        }
        if (stat == 0)
	  stat = execvp (path, argv);
        if (ovl)
                return stat;
        else
                exit (stat);
}

&else

&ifdef DEBUG
&else
#line 444 "vps01c"
&endif

const char *p01basen (const char *path)

/*      Returns a pointer to the basename of the pathname path.
*/

{
        const char DC1 = '/', DC2 = '\\';
        const char *s, *s2;

        s  = strrchr (path, DC1);
        s2 = strrchr (path, DC2);

        if (s2 > s)
                s = s2;

        if (s)
                s++;
        else
                s = path;

        return s;
}

void p01mfin (void)

/*      Reset of a tty to its initial state stored in ms.term */
{
        if (ms.lines)
        {
                ms.lines = 0;
        }
}

&if $OS = MSDOS

&ifdef DEBUG
&else
#line 484 "vps01c"
&endif

static void p01mmsg (void)
{}

&else

&ifdef DEBUG
&else
#line 494 "vps01c"
&endif

static void p01mmsg (void)
{
        int inp;

        if (++ms.cnt > ms.lines)
        {
                printf ("--More--");
                inp = getch ();
                if (inp == 'q' || inp == 'Q')
                        ms.lines = -1;
                else
                        ms.cnt = 0;
                printf ("\r        \r");
        }
}

&endif

&ifdef DEBUG
&else
#line 517 "vps01c"
&endif

&if $OS = WIN32

&ifdef DEBUG
&else
#line 524 "vps01c"
&endif

void p01minit (int lines)

/*      Initialization of a tty for output in more mode.
        The parameter is the number of lines of an output page.
*/
{
        HANDLE outhnd;

        ms.ttyhnd = GetStdHandle (STD_INPUT_HANDLE);
        outhnd    = GetStdHandle (STD_OUTPUT_HANDLE);
        if (GetFileType (ms.ttyhnd) != FILE_TYPE_CHAR ||
            GetFileType (outhnd)    != FILE_TYPE_CHAR || lines == 0)
                return;
        ms.lines = lines;
}

static void p01mexit ()
{
        p01mfin ();
        ExitProcess (1);
}

int p01exec (const char* path, char *argv [], int ovl,
        const char *file, int mode)

/*      Submits a new process constructed from the file named by path.
        The environment is passed by the array argv, terminated by a
        null pointer.
        If ovl is nonzero, the new process overlays the caller,
        otherwise the function waits for the termination of the
        submitted process and returns its exit status.
        If file is not NULL, some of the submitted process' standard
        file descriptors will be redirected to file.
        If mode & i is nonzero (i = 0, 1, 2), the file descriptor i
        will be redirected to file.
*/

{
        STARTUPINFO         Si;
        PROCESS_INFORMATION Pi;
        BOOL                Ok;
        LPSTR               CmdLine;
        const char          **ArgP;
        char                *p;
        HANDLE              Fh      = INVALID_HANDLE_VALUE;
        LONG                Error   = NO_ERROR;
        int                 Size    = 0;

        memset (&Si, 0, sizeof (Si));
        Si.cb = sizeof (Si);
        if (file)
        {
                /* Security attributes must be set to inherit */
                /* the filehandle to another process. 12.11.96 R.A. */
                SECURITY_ATTRIBUTES Attr;
                Attr.nLength              = sizeof(SECURITY_ATTRIBUTES);
                Attr.bInheritHandle       = TRUE;
                Attr.lpSecurityDescriptor = NULL;
                Fh = CreateFile (file, mode ? GENERIC_WRITE : GENERIC_READ, 0,
                                &Attr, mode ? CREATE_ALWAYS : OPEN_EXISTING,
                                 FILE_ATTRIBUTE_NORMAL, NULL);
                if (Fh == INVALID_HANDLE_VALUE)
                        return (GetLastError ());
                Si.dwFlags |= STARTF_USESTDHANDLES;
                Si.hStdInput  = GetStdHandle (STD_INPUT_HANDLE);
                Si.hStdOutput = GetStdHandle (STD_OUTPUT_HANDLE);
                Si.hStdError  = GetStdHandle (STD_ERROR_HANDLE);
                if (mode == 0)
                        Si.hStdInput  = Fh;
                else if (mode & 1)
                {
                        Si.hStdOutput = Fh;
                        if (mode & 2)
                                Si.hStdError  = Fh;
                }
        }
        for (ArgP = argv; *ArgP; ++ArgP)
                Size += lstrlen (*ArgP) + 1;
        if (p = CmdLine = _alloca (Size))
        {
                for (ArgP = argv; *ArgP; ++ArgP)
                {
                        lstrcpy (p, *ArgP);
                        p += lstrlen (p);
                        *p++ = ' ';
                }
                *--p = '\0';
        }
        /* The fifth parameter must be set to TRUE to inherit */
        /* all filehandles to another process. 12.11.96 R.A. */
        Ok = CreateProcess (path, CmdLine, NULL, NULL, TRUE,
                            NORMAL_PRIORITY_CLASS, NULL, NULL, &Si, &Pi);
        if (!Ok)
                Error = GetLastError ();
        if (Fh != INVALID_HANDLE_VALUE)
                CloseHandle (Fh);
        if (!Ok)
                return (Error);
        CloseHandle (Pi.hThread);
        if (ovl)
                ExitProcess (0);
        if (WaitForSingleObject (Pi.hProcess, INFINITE) == WAIT_FAILED)
                Error = GetLastError ();
        else if (!GetExitCodeProcess (Pi.hProcess, &Error))
                Error = GetLastError ();
        CloseHandle (Pi.hProcess);
        return (Error);
}

&else

&ifdef DEBUG
&else
#line 632 "vps01c"
&endif

void p01minit (int lines)

/*      Initialization of a tty for output in more mode.
        The parameter is the number of lines of an output page.
*/
{
        int outdes;

        ms.ttydes = fileno (stdin);
        outdes = fileno (stdout);
        if (!_isatty (ms.ttydes) || !_isatty (outdes) || lines == 0 )
                return;
        ms.lines = lines;
}

static void p01mexit ()
{
        p01mfin ();
        exit (1);
}

&if $OS != MSDOS

&ifdef DEBUG
&else
#line 660 "vps01c"
&endif

int p01exec (const char* path, char *argv [], int ovl,
        const char *file, int mode)

/*      Submits a new process constructed from the file named by path.
        The environment is passed by the array argv, terminated by a
        null pointer.
        If ovl is nonzero, the new process overlays the caller,
        otherwise the function waits for the termination of the
        submitted process and returns its exit status.
        If file is not NULL, some of the submitted process' standard
        file descriptors will be redirected to file.
        If mode & i is nonzero (i = 0, 1, 2), the file descriptor i
        will be redirected to file.
*/

{
        int fildes;

        if (file)
        {
                fildes = (mode == 0) ? open (file, O_RDONLY) :
                        open (file, O_WRONLY | O_CREAT | O_TRUNC,
                                    _S_IREAD | _S_IWRITE);
                if (fildes == -1)
                {
                        perror (file);
                        return (256);
                }
                if (mode == 0)
                {
                        close (0);
                        dup (fildes);
                }
                else if (mode & 1)
                {
                        close (1);
                        dup (fildes);
                        if (mode & 2)
                        {
                                close (2);
                                dup (fildes);
                        }
                }
        }

        return (_spawnv (ovl ? _P_OVERLAY : _P_WAIT, path, argv));
}

&else

&ifdef DEBUG
&else
#line 715 "vps01c"
&endif

int p01exec (const char* path, char *argv [], int ovl,
	const char *file, int mode)

/*	Submits a new process constructed from the file named by path.
	The environment is passed by the array argv, terminated by a
	null pointer.
	If ovl is nonzero, the new process overlays the caller,
	otherwise the function waits for the termination of the
	submitted process and returns its exit status.
	If file is not NULL, some of the submitted process' standard
	file descriptors will be redirected to file.
	If mode & i is nonzero (i = 0, 1, 2), the file descriptor i
	will be redirected to file.
*/

{
	int fildes;
	char Buf[1024];
	strcpy (Buf, path);
	while (*++argv)
	{
		strcat (Buf, " ");
		strcat (Buf, *argv);
	}
	if (file)
	{
		if (mode)
			strcat (Buf, " >");
			/*stderr cannot be handled in dos boxes*/
		else
			strcat (Buf, " <");
		strcat (Buf, file);
		memmove(Buf+13, Buf, strlen(Buf)+1);
		memcpy (Buf, e25_batchmode ? "sqlbatch.bat " :
					     "sqlcall.bat  ", 13);
	}
	else
		if (e25_batchmode)
			strcat (Buf, " /batch");
			/*start pc3 as icon  and   */
			/*with "autoclose" property*/
	return (system (Buf));
}
&endif
&endif
&endif

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