#ifndef lint
static char *RCSid = "$Id: unixfuncs.c,v 1.11 1993/05/10 06:08:07 anders Exp anders $";
#endif

/*
 *  The Regina Rexx Interpreter
 *  Copyright (C) 1992  Anders Christensen <anders@pvv.unit.no>
 *
 *  This library is free software; you can redistribute it and/or
 *  modify it under the terms of the GNU Library General Public
 *  License as published by the Free Software Foundation; either
 *  version 2 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
 *  Library General Public License for more details.
 *
 *  You should have received a copy of the GNU Library General Public
 *  License along with this library; if not, write to the Free
 *  Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
 */

#include "rexx.h"
#include <stdio.h>
#include <string.h>
#include <ctype.h>
#ifdef HAVE_ASSERT_H
# include <assert.h>
#endif
#include <errno.h>
#ifdef VAXC
# include <types.h>
#else
# include <sys/types.h>
# ifdef HAVE_UNISTD_H
#  include <unistd.h>
#endif
# if defined(__WATCOMC__) || defined(_MSC_VER)          /* MH 10-06-96 */
#  include "utsname.h"                                  /* MH 10-06-96 */
#  include <process.h>
#  include <direct.h>
# else                                                  /* MH 10-06-96 */
#  include <sys/utsname.h>                              /* MH 10-06-96 */
# endif                                                 /* MH 10-06-96 */
#endif

#if defined(CRAY)
FILE *popen( char *command, char *access ) ;
#endif

streng *unx_getpath( paramboxptr parms )
{
   return nullstringptr() ;
}


streng *unx_popen( paramboxptr parms )
{
   extern proclevel currlevel ;
   streng *string=NULL, *result=NULL ;
   streng *cptr=NULL ;
   int length=0, lines=0 ;

   checkparam(  parms,  1,  2 , "POPEN" ) ;
   string = (parms->value) ;

   cptr = Str_make( length=Str_len(string) + 6 ) ;
   cptr = Str_cat( cptr, string ) ;
   cptr = Str_catstr( cptr, ">LIFO" ) ;

   if (parms->next && parms->next->value)
   {
      lines = lines_in_stack() ;
   }

   result = perform( cptr, currlevel->environment, NULL ) ; 
   Free( cptr ) ;

   if (parms->next && parms->next->value)
   {
      streng *varname=NULL, *varstem=NULL ;
      int stemlen=0 ;
      char *cptr=NULL, *eptr=NULL ;
      streng *tmpptr=NULL ;

      varstem = parms->next->value ;
      varname = Str_make( (stemlen=varstem->len) + 8 ) ;

      memcpy( varname->value, varstem->value, stemlen ) ;
      cptr = varname->value ;
      eptr = cptr + varstem->len ;
      for (; cptr<eptr; cptr++)
         if (islower(*cptr))
            *cptr = toupper(*cptr) ;

      if (*(eptr-1)!='.')
      {
         *((eptr++)-1) = '.' ;
         stemlen++ ;
      }
      
      lines = lines_in_stack() - lines ;
      *eptr = '0' ;
      varname->len = stemlen+1 ;
      tmpptr = int_to_streng( lines ) ;
      setvalue( varname, tmpptr ) ;
      for (; lines>0; lines--)
      {
         tmpptr = popline() ;
         sprintf(eptr, "%d", lines ) ;
         varname->len = strlen( varname->value ) ;
         setvalue( varname, tmpptr ) ;
      }
      Free( varname ); /* bja */
   }

   return result ;

/*   Free( cptr ) ;
   sprintf( (result=Str_make(SMALLSTR))->value, "%d", rcode ) ;
   result->len = Str_len(result) ;
   return result ; */
}


streng *unx_getpid( paramboxptr parms )
{
   checkparam(  parms,  0,  0 , "GETPID" ) ;
   return int_to_streng( getpid() ) ;
}


streng *unx_eof( paramboxptr parms )
{
   checkparam(  parms,  0,  0 , "EOF" ) ;
/*    sprintf(ptr=Malloc(SMALLSTR),"%d",eof_on_input()) ; */
   return( nullstringptr() ) ;
}


streng *unx_uname( paramboxptr parms ) 
{
   char option=' ' ;
   char *cptr=NULL ;
   int length=0 ;
   streng *result=NULL ;
   struct utsname utsbox ;

   checkparam(  parms,  0,  1 , "UNAME" ) ;
   if (parms->value)
   {
      if (parms->value->len == 0)
         exiterror( ERR_INCORRECT_CALL, 21, "UNAME", 1 )  ;
      option = getoptionchar( parms->value, "ASMNRV" ) ;
      if (!option)
         exiterror( ERR_INCORRECT_CALL, 28, "UNAME", 1, "ASMNRV", parms->value->value )  ;
   }
   else
      option = 'A' ;

   if (uname( &utsbox ) <0) 
       exiterror( ERR_SYSTEM_FAILURE, 0 )  ;

   switch( option )
   {
      case 'A':
         result = Str_make( sizeof(struct utsname)) ;
         sprintf( result->value, "%s %s %s %s %s", utsbox.sysname, 
                  utsbox.nodename, utsbox.release, utsbox.version,
                  utsbox.machine ) ;
         result->len = strlen( result->value ) ;
         assert( result->len+1 <= result->max ) ; /* +1 for "\0" */
         return result ;

      case 'S': cptr = utsbox.sysname ; break ;
      case 'N': cptr = utsbox.nodename ; break ;
      case 'R': cptr = utsbox.release ; break ;
      case 'V': cptr = utsbox.version ; break ;
      case 'M': cptr = utsbox.machine ; break ;
      default:
         assert( 0 ) ;
   }
   
   result = Str_make( length=strlen(cptr) ) ;
   memcpy( result->value, cptr, length ) ;
   result->len = length ;
   assert( result->len+1 <= result->max ) ;
   return result ;
}


streng *unx_fork( paramboxptr parms ) 
{
   int i=0 ;

   checkparam(  parms,  0,  0 , "FORK" ) ;
#if !defined(__WATCOMC__) && !defined(_MSC_VER)         /* MH 10-06-96 */
   i = fork() ;
#endif                                                  /* MH 10-06-96 */
   return int_to_streng( i ) ;
}   


char *unx_unixerror( paramboxptr parms )
{
   char *result=NULL, *errtxt=NULL ;
   int errnum=0 ; /* change name from errno to not conflist with global errno */
   
   checkparam(  parms,  1,  1 , "UNIXERROR" ) ;
   errnum = atozpos( parms->value ) ;
   errtxt = strerror(errnum) ;
   strcpy( result=Malloc(strlen(errtxt)+1+STRHEAD), errtxt ) ;
   return result ;
}
   


streng *unx_chdir( paramboxptr parms )
{
   checkparam(  parms,  1,  1 , "CD" ) ;
   return int_to_streng( chdir(Str_ify(parms->value)->value)!=0 ) ;
}


streng *unx_getenv( paramboxptr parms ) 
{
   streng *retval=NULL ;
   char *output=NULL ;

   checkparam(  parms,  1,  1 , "GETENV" ) ;
   output = getenv( Str_ify(parms->value)->value ) ;
   if (output) 
      retval = Str_cre(output) ;
   else 
      retval = nullstringptr() ;

   return retval ;
}
   

