#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>
#include <assert.h>
#ifdef VAXC
# include <types.h>
#else
# include <sys/types.h>
# include <unistd.h>
# include <sys/utsname.h>
#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, *result ;
   streng *cptr ;
   int length, lines ;

   checkparam( parms, 1, 2 ) ;
   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, *varstem ;
      int stemlen ;
      char *cptr, *eptr ;
      streng *tmpptr ;

      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 ) ;
      }
   }

   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 ) ;
   return int_to_streng( getpid() ) ;
}


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


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

   checkparam( parms, 0, 1 ) ;
   if (parms->value)
      option = getoptionchar( parms->value, "ASNRVM" ) ;
   else
      option = 'A' ;

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

   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 ;

   checkparam( parms, 0, 0 ) ;
   i = fork() ;
   return int_to_streng( i ) ;
}   


char *unx_unixerror( paramboxptr parms )
{
   char *result, *errtxt ;
   extern char *sys_errlist[] ;
   int errno ;
   
   checkparam( parms, 1, 1 ) ;
   errno = atozpos( parms->value ) ;
   errtxt = sys_errlist[ errno ] ;
   strcpy( result=Malloc(strlen(errtxt)+1+STRHEAD), errtxt ) ;
   return result ;
}
   


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


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

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

   return retval ;
}
   

