/*
	環境変数領域操作関数(LsiC/HighC用)  by Y.Kurihara (Nifty PDC01620)

	Ver 1.00  1991.06.05
	Ver 1.01  1991.06.10    マクロ HIGH_C を __HIGHC__ に変更
	Ver 1.02  1991.07.18    ルートの COMMAND.COM の環境に対応
*/

#include <stdlib.h>
#include <string.h>
#include <ctype.h>
#include "environ.h"

#define MAXbuffer (128)
static char buff[ MAXbuffer + 1 ];

/* * * * * * * * * * * *     ＬＳＩ Ｃ８６     * * * * * * * * * * * * */
#if  defined( LSI_C )

int far_strnicmp( Fchar *s1,Fchar *s2,int len );
Fchar *far_strncpy( Fchar *s1,Fchar *s2,int len );

#endif	/*  defined( LSI_C )  */

/* * * * * * * * * * * *      Ｈｉｇｈ Ｃ      * * * * * * * * * * * * */
#if  defined( __HIGHC__ )

Fchar  *fp_dos;
Fchar  *fp_psp;

int getpid( void )	/* RUN386.EXEのプロセスIDを得る */
{
	struct Fptr {  int off;  short seg;  };

	( (struct Fptr *)&fp_psp ) -> seg = 0x24;
	( (struct Fptr *)&fp_psp ) -> off = 0x00;
	( (struct Fptr *)&fp_dos ) -> seg = 0x60;
	( (struct Fptr *)&fp_dos ) -> off = 0x00;

	return  *(Fint *)(fp_psp + 0x16);
}

int far_strnicmp( Fchar *s1,Fchar *s2,int len )		/* 文字列の比較 */
{
	while( len-- > 0 ) {
		if( toupper( *s1 ) != toupper( *s2 ) )  return(1);
		if( *s1 == 0 )  break;
		s1++;
		s2++;
	}
	return( 0 );
}

Fchar *far_strncpy( Fchar *s1,Fchar *s2,int len )	/* 文字列の複写 */
{
	while( len-- > 0 ) {
		*s1 = *s2;
		if( *s1 == 0 )  break;
		s1++;
		s2++;
	}
	return( 0 );
}

#endif	/*  defined( __HIGHC__ )  */

/* * * * * * * * * * * *     ＣＯＭＭＯＮ      * * * * * * * * * * * * */

int getrpid( void )			/* rootのプロセスIDを得る */
{					/* (int 2eh のベクタのセグメント)  */
	getpid();
	return  *(Fint *)FARPTR( 0,0x2e *4 +2 );
}

int getppid( void )			/* 親のプロセスIDを得る */
{
	return  PSP_parent( getpid() );
}

int getcpid( void )			/* COMMAND.COMのプロセスIDを得る */
{
	unsigned psp,ppsp;

	psp  = getpid();
	ppsp = PSP_parent( psp );
	while( ppsp != psp ) {
		ppsp = PSP_parent( psp = ppsp );
	}
	return( psp );
}

int pspenv( int psp )			/* PSPの環境変数領域を得る */
{
	unsigned env;

	if( ( env = PSP_environ( psp ) )== 0 ) {
				/* 環境変数領域がPSPに設定されてない */
		if( MCB_owner( psp ) != psp )  return( 0 );
		env = MCB_next( psp );
		if( MCB_owner( env ) != psp )  return( 0 );
		if( envget( "COMSPEC",env ) == NULL )  return( 0 );
		if( envget( "PATH",env ) == NULL )  return( 0 );
		return( env );
	}
	if( MCB_mark( env ) != 'M' )  return( 0 );
	if( MCB_size( env ) == 0 )  return( 0 );
				/* 環境変数領域がMCBの管理下にない */
	if( MCB_owner( env ) != psp )  return( 0 );
				/* 環境変数領域がPSPの管理下にない */
	return( env );
}

int envdel( char *var,int env )			/* 環境変数の削除 */
{
	Fchar *ptr;
	Fchar *p;
	int  n;

	if( var == NULL || *var == 0 || env == 0 )  return(1);

	n = strlen( var );
	ptr = FARPTR( env,0 );
	while( *ptr ) {
		if( !far_strnicmp( ptr,(Fchar *)var,n ) ) {
			if( ptr[n] == 0 || ptr[n] == '=' ) {
				p = ptr;
				while( *ptr++ );
				while( *ptr )  while( (*p++ = *ptr++)!= 0 );
				*p = 0;
				if( *(p+1) == 1 )  *(p+1) = 0;
				return(0);
			}
		}
		while( *ptr++ );
	}
	return(0);
}

int envset( char *var,char *val,int env )	/* 環境変数の変更 */
{
	Fchar *fp_env;
	int  size,n,c;

	if( envdel( var,env ) )  return(1);
	if( val == NULL || *val == 0 )  return(0);

	fp_env  = FARPTR( env,0 );
	size = MCB_size( env ) * 16 - 2;
	for( n = 0; fp_env[ n ]; )  while( fp_env[ n++ ] );

	if( n >= size )  goto error2;
	while( (c = *var++)!= 0 ) {
		if( n >= size )  goto error1;
		fp_env[ n++ ] = toupper( c );
	}
	if( n >= size )  goto error1;
	fp_env[ n++ ] = '=';
	while( (c = *val++)!= 0 ) {
		if( n >= size )  goto error1;
		fp_env[ n++ ] = c;
	}
	fp_env[ n ] = fp_env[ n+1 ] = 0;
	if( fp_env[ n+2 ] == 1 )  fp_env[ n+2 ] = 0;
	return(0);

error1:				/* 環境変数領域が足りない */
	fp_env[ n ] = fp_env[ n+1 ] = 0;
	if( fp_env[ n+2 ] == 1 )  fp_env[ n+2 ] = 0;
error2:
	return(1);
}

char *envpath( int env )			/* 環境からパス名を得る */
{
	Fchar *fp_env;

	if( env == 0 )  return  NULL;

	fp_env  = FARPTR( env,0 );
	while( *fp_env )  while( *fp_env++ );
	if( fp_env[1] != 1 || fp_env[2] != 0 )  return  NULL;
	far_strncpy( (Fchar *)buff,fp_env + 3,MAXbuffer );
	buff[ MAXbuffer ] = 0;
	return  buff;
}

char *envget( char *var,int env )		/* 環境変数の値を得る */
{
	Fchar *ptr;
	int  n;

	if( var == NULL || *var == 0 || env == 0 )  return  NULL;

	n = strlen( var );
	ptr = FARPTR( env,0 );
	while( *ptr ) {
		if( !far_strnicmp( ptr,(Fchar *)var,n ) && ptr[n] == '=' ) {
			far_strncpy( (Fchar *)buff,ptr + n + 1,MAXbuffer );
			buff[ MAXbuffer ] = 0;
			return  buff;
		}
		while( *ptr++ );
	}
	return  NULL;
}

