2 * The Regina Rexx Interpreter
3 * Copyright (C) 1992 Anders Christensen <anders@pvv.unit.no>
5 * This library is free software; you can redistribute it and/or
6 * modify it under the terms of the GNU Library General Public
7 * License as published by the Free Software Foundation; either
8 * version 2 of the License, or (at your option) any later version.
10 * This library is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13 * Library General Public License for more details.
15 * You should have received a copy of the GNU Library General Public
16 * License along with this library; if not, write to the Free
17 * Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
21 * _XOPEN_SOURCE required for crypt()
22 * but it stuffs up SCO and QNX-RTO :-(
24 #if !defined(_SCO_ELF) && !defined(_SCO_COFF) && !defined(__QNXNTO__)
25 # ifndef _XOPEN_SOURCE
26 # define _XOPEN_SOURCE
28 # ifndef _XOPEN_SOURCE
34 /* At least Linux needs _GNU_SOURCE and _XOPEN_SOURCE together to allow
35 * a warning free compile.
41 #if defined(__WATCOMC__) || defined(_MSC_VER) || (defined(__IBMC__) && defined(WIN32)) || defined(__SASC) || defined(__MINGW32__) || defined(__BORLANDC__) || defined(DOS) || defined(__WINS__) || defined(__EPOC32__) || defined(__LCC__) || defined(_AMIGA) || defined(__AROS__)
44 #if defined(__WATCOMC__) && defined(__QNX__)
64 # include <sys/types.h>
68 # if defined(WIN32) && defined(__IBMC__)
71 # elif defined(__WATCOMC__) || defined(_MSC_VER) || defined(__MINGW32__) || defined(__BORLANDC__) || defined(__LCC__)
72 # if !defined(__QNX__)
79 streng
*unx_getpath( tsd_t
*TSD
, cparamboxptr dummy
)
81 TSD
= TSD
; /* keep compiler happy */
82 dummy
= dummy
; /* keep compiler happy */
83 return nullstringptr() ;
87 streng
*unx_popen( tsd_t
*TSD
, cparamboxptr parms
)
89 streng
*string
=NULL
, *result
=NULL
;
91 int length
=0, lines
=0, hl
;
92 int save_internal_queues_option
;
94 if ( TSD
->restricted
)
95 exiterror( ERR_RESTRICTED
, 1, "POPEN" ) ;
97 checkparam( parms
, 1, 2 , "POPEN" ) ;
98 string
= (parms
->value
) ;
101 * Because this sort of redirection is only valid with internal
102 * queues, we need to make regina think we are using internal
103 * queues for this function.
105 save_internal_queues_option
= get_options_flag( TSD
->currlevel
, EXT_INTERNAL_QUEUES
) ;
106 set_options_flag( TSD
->currlevel
, EXT_INTERNAL_QUEUES
, 1 ) ;
108 cptr
= Str_makeTSD( length
=Str_len(string
) + 6 ) ;
109 cptr
= Str_catTSD( cptr
, string
) ;
110 cptr
= Str_catstrTSD( cptr
, ">LIFO" ) ;
112 if (parms
->next
&& parms
->next
->value
)
114 lines
= lines_in_stack( TSD
, NULL
);
119 result
= perform( TSD
, cptr
, TSD
->currlevel
->environment
, TSD
->currentnode
, NULL
) ;
120 Free_stringTSD( cptr
) ;
122 if (parms
->next
&& parms
->next
->value
)
124 streng
*varname
=NULL
, *varstem
=NULL
;
127 streng
*tmpptr
=NULL
;
129 varstem
= parms
->next
->value
;
130 varname
= Str_makeTSD( (stemlen
=varstem
->len
) + 8 ) ;
132 memcpy( varname
->value
, varstem
->value
, stemlen
) ;
133 mem_upper( varname
->value
, stemlen
);
134 eptr
= varname
->value
+ stemlen
;
138 *((eptr
++)-1) = '.' ;
142 hl
= lines_in_stack( TSD
, NULL
);
143 lines
= ( ( hl
< 0 ) ? 0 : hl
) - lines
;
145 varname
->len
= stemlen
+1 ;
146 tmpptr
= int_to_streng( TSD
, lines
) ;
147 setvalue( TSD
, varname
, tmpptr
, -1 ) ;
148 for (; lines
>0; lines
--)
150 tmpptr
= popline( TSD
, NULL
, NULL
, 0 ) ;
151 sprintf(eptr
, "%d", lines
) ;
152 varname
->len
= strlen( varname
->value
) ;
153 setvalue( TSD
, varname
, tmpptr
, -1 ) ;
155 Free_stringTSD( varname
); /* bja */
157 set_options_flag( TSD
->currlevel
, EXT_INTERNAL_QUEUES
, save_internal_queues_option
) ;
161 /* Free_stringTSD( cptr ) ;
162 sprintf( (result=Str_makeTSD(SMALLSTR))->value, "%d", rcode ) ;
163 result->len = Str_len(result) ;
168 streng
*unx_getpid( tsd_t
*TSD
, cparamboxptr parms
)
170 checkparam( parms
, 0, 0 , "GETPID" ) ;
171 return int_to_streng( TSD
, getpid() ) ;
174 streng
*unx_gettid( tsd_t
*TSD
, cparamboxptr parms
)
176 checkparam( parms
, 0, 0 , "GETTID" ) ;
177 return int_to_streng( TSD
, TSD
->thread_id
) ;
181 streng
*unx_eof( tsd_t
*TSD
, cparamboxptr parms
)
183 checkparam( parms
, 0, 0 , "EOF" ) ;
184 /* sprintf(ptr=MallocTSD(SMALLSTR),"%d",eof_on_input()) ; */
185 return( nullstringptr() ) ;
189 streng
*unx_uname( tsd_t
*TSD
, cparamboxptr parms
)
194 streng
*result
=NULL
;
195 struct regina_utsname utsbox
;
197 checkparam( parms
, 0, 1 , "UNAME" ) ;
199 option
= getoptionchar( TSD
, parms
->value
, "UNAME", 1, "ASMNRV", "" ) ;
203 if (TSD
->OS
->uname( &utsbox
) <0)
204 exiterror( ERR_SYSTEM_FAILURE
, 1, strerror( errno
) ) ;
209 result
= Str_makeTSD( 1+sizeof(struct regina_utsname
)) ;
210 sprintf( result
->value
, "%s %s %s %s %s", utsbox
.sysname
,
211 utsbox
.nodename
, utsbox
.release
, utsbox
.version
,
213 result
->len
= strlen( result
->value
) ;
214 assert( result
->len
<= result
->max
) ;
217 case 'S': cptr
= utsbox
.sysname
; break ;
218 case 'N': cptr
= utsbox
.nodename
; break ;
219 case 'R': cptr
= utsbox
.release
; break ;
220 case 'V': cptr
= utsbox
.version
; break ;
221 case 'M': cptr
= utsbox
.machine
; break ;
226 length
= strlen(cptr
);
227 result
= Str_makeTSD( length
+1 ) ;
228 memcpy( result
->value
, cptr
, length
) ;
229 result
->len
= length
;
230 assert( result
->len
<= result
->max
) ;
235 streng
*unx_fork( tsd_t
*TSD
, cparamboxptr parms
)
239 checkparam( parms
, 0, 0 , "FORK" ) ;
240 #if defined(HAVE_FORK)
242 #endif /* MH 10-06-96 */
243 return int_to_streng( TSD
, i
) ;
247 streng
*unx_unixerror( tsd_t
*TSD
, cparamboxptr parms
)
249 const char *errtxt
=NULL
;
250 int errnum
=0 ; /* change name from errno to not conflist with global errno */
252 checkparam( parms
, 1, 1 , "UNIXERROR" ) ;
253 errnum
= atozpos( TSD
, parms
->value
, "UNIXERROR", 1 ) ;
254 errtxt
= strerror(errnum
) ;
255 return Str_creTSD( errtxt
) ;
259 streng
*unx_chdir( tsd_t
*TSD
, cparamboxptr parms
)
265 checkparam( parms
, 1, 1 , "CD" ) ;
267 * Check if we have a registred system exit
269 if (TSD
->systeminfo
->hooks
& HOOK_MASK(HOOK_SETCWD
))
270 ok
= hookup_output( TSD
, HOOK_SETCWD
, parms
->value
) ;
274 path
= str_of( TSD
, parms
->value
) ;
278 return int_to_streng( TSD
, rc
!=0 ) ;
282 streng
*unx_getenv( tsd_t
*TSD
, cparamboxptr parms
)
284 streng
*retval
=NULL
;
289 checkparam( parms
, 1, 1 , "GETENV" ) ;
291 if (TSD
->systeminfo
->hooks
& HOOK_MASK(HOOK_GETENV
))
292 ok
= hookup_input_output( TSD
, HOOK_GETENV
, parms
->value
, &retval
) ;
296 path
= str_of( TSD
, parms
->value
) ;
297 output
= mygetenv( TSD
, path
, NULL
, 0 ) ;
301 retval
= Str_creTSD( output
) ;
305 retval
= nullstringptr() ;
311 streng
*unx_putenv( tsd_t
*TSD
, cparamboxptr parms
)
315 streng
*retval
=NULL
;
316 int ok
=HOOK_GO_ON
,i
;
318 checkparam( parms
, 1, 1 , "PUTENV" ) ;
319 name
= Str_dupstrTSD( parms
->value
);
321 * Argument is of form ENV=[value]
323 for ( i
= 0; i
< Str_len(name
); i
++ )
325 if ( name
->value
[i
] == '=' )
327 name
->value
[i
] = '\0';
329 value
= Str_creTSD( (name
->value
)+i
+1 ) ;
330 value
->value
[Str_len(value
)] = '\0';
335 if (TSD
->systeminfo
->hooks
& HOOK_MASK(HOOK_SETENV
))
336 ok
= hookup_output2( TSD
, HOOK_SETENV
, name
, value
);
340 env
= Str_creTSD( "ENVIRONMENT" ) ;
341 retval
= ext_pool_value( TSD
, name
, value
, env
);
342 Free_stringTSD( env
);
344 Free_stringTSD( name
);
346 Free_stringTSD( value
);
348 retval
= nullstringptr() ;
353 streng
*unx_crypt( tsd_t
*TSD
, cparamboxptr parms
)
355 streng
*retval
=NULL
;
362 checkparam( parms
, 2, 2 , "CRYPT" ) ;
363 for ( i
= 0; i
< Str_len( parms
->next
->value
); i
++ )
365 ch2
= (int)*(parms
->next
->value
->value
+i
);
366 if ((ch2
>= (int)'A' && ch2
<= (int)'Z')
367 || (ch2
>= (int)'a' && ch2
<= (int)'z')
368 || (ch2
>= (int)'0' && ch2
<= (int)'9')
369 || (ch2
== (int)'.' || ch2
== (int)'/'))
377 exiterror( ERR_INCORRECT_CALL
, 914, "CRYPT", 2, "A-Za-z0-9./", tmp
) ;
381 key
= str_of( TSD
, parms
->value
);
382 salt
= str_of( TSD
, parms
->next
->value
);
383 output
= crypt( key
, salt
) ;
387 retval
= Str_creTSD(output
) ;
389 retval
= nullstringptr() ;
391 retval
= Str_dup( parms
->value
);
393 TSD
= TSD
; /* keep compiler happy */