/*
	TSET.EXE Ver 0.04  1991.07.24  by Y.Kurihara (Nifty PDC01620)
		環境変数操作コマンド (TownsOS用)

	(1) Tset [-c] <環境変数>=<値>
	(2) Tset [-c] <環境変数>=
	(3) Tset [-c] @<ファイル名>
	(4) Tset [-c]
	(5) Tset [-c] =

	(1) 環境変数を設定する
	(2) 環境変数を削除する
	(3) 環境設定ファイルを読み込む
	(4) 環境変数を表示する
	(5) 環境変数領域＋１バイトを表示する(デバック用)

	ｵﾌﾟｼｮﾝ -c  CONTROL.EXE の環境を操作する｡

	このプロクラムは LSI C-86 Ver 3.20 試食版 で作成しました｡
*/

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <dos.h>
#include <farstr.h>
#include "environ.h"

#define  MAXbuffer (256)

void envlst( int env )					/* 環境変数の出力 */
{
	char far *ptr;

	if( !env )  return;
	ptr = MK_FP( env,0 );
	while( *ptr ) {
		while( *ptr )  putchar( *ptr++ );
		putchar( '\n' );
		ptr++;
	}
}

void envdmp( int env )					/* 環境変数のダンプ */
{
	char far *ptr;
	unsigned size,n;

	if( !env )  return;
	ptr  = MK_FP( env,0 );
	size = MCB_size( env ) * 16;
	printf( "%04x:0000 - %04x\n",env,size - 1 );
	for( n = 0; n <= size ; n++ ) {
		if( ptr[n] >= ' ' ) {
			putchar( ptr[n] );
		} else {
			putchar( '^' );
			putchar( ptr[n] + '@' );
		}
	}
	putchar( '\n' );
	putchar( '\n' );
}

char *getcmd( void )				/* PSPのコマンドラインを取得 */
{
	static char buff[ MAXbuffer + 1 ];
	char far *ptr,*p = buff;

	ptr = MK_FP( _psp,0x81 );
	while( *ptr && *ptr != 0x0d )  *p++ = *ptr++;
	*p = 0;
	return( buff );
}

int prgpsp( char *prgname )			/* プログラムのPSPを得る */
{
	int env,mem;
	char *name,*p;
	
	mem = getrpid();
	while( MCB_mark( mem ) == 'M' ) {
		mem = MCB_next( mem );
		if( MCB_owner( mem ) != mem )  continue;
		if( ( env = pspenv( mem ) ) == 0 )  continue;
		if( ( name = envpath( env ) ) == NULL )  continue;
		for( p = name; *p; p++ )  if( *p == ':' )   name = p + 1;
		for( p = name; *p; p++ )  if( *p == '\\' )  name = p + 1;
		if( stricmp( prgname,name ) )  continue;
		return( mem );
	}
	return  0;
}

int getControlEnv( void )			/* CONTROL.EXEの環境変数領域 */
{
	unsigned psp1,psp2,env;

	psp1 = prgpsp( "CONTROL.EXE" );
	psp2 = prgpsp( "T_OAK2.EXE" );

	if( psp2 == 0 )  goto error2;
	if( psp1 ) {
		if( psp1 != PSP_parent( psp2 ) ) goto error3;
	} else {
		if( ( psp1 = PSP_parent( psp2 ) ) == 0 )  goto error3;
		if( ( env  = pspenv( psp1 ) ) == 0 )  goto error3;
		if( envpath( env ) != NULL )  goto error3;
	}
	env = pspenv( psp1 );
	if( env == 0 )  goto error1;
	return( env );

error1:
	puts( "\"CONTROL.EXE\"が見つからない｡" );
	exit( 1 );
error2:
	puts( "\"T_OAK2.EXE\"が見つからない｡" );
	exit( 1 );
error3:
	puts( "\"T_OAK2.EXE\"の親プロセスが\"CONTROL.EXE\"ではない｡" );
	exit( 1 );
}

void tset( char *cmd,int env )				/* 環境変数の設定 */
{
	char *var;

	var = cmd;
	while( *cmd && *cmd != '=' )  cmd++;
	if( *cmd == 0 )  goto error1;
	*cmd++ = 0;

	if( envset( var,cmd,env ) )  goto error2;
	return;

error1:
	puts( "書式が間違っている｡" );
	return;
error2:
	puts( "環境変数領域が不足している｡" );
	return;
}

int far handler(unsigned deverror, unsigned errcode,unsigned far *devhdr)
{							/* int 24h の処理 */
	return( _HARDERR_FAIL );
}

void envrd( int env,char *file )			/* 環境変数のロード */
{
	int c,n = 0;
	char buf[ MAXbuffer + 1 ];
	FILE *fp;

	_harderr( handler );
	fp = fopen( file,"r" );
	if( fp == NULL ) {
		puts( "ファイルがオープンできない｡" );
		exit( 1 );
	}

	while( c = getc( fp ),c != EOF ) {
		if( c == '\n' ) {
			buf[ n ] = 0;
			tset( buf,env );
			n = 0;
		} else if( n < MAXbuffer ) {
			buf[ n++ ] = c;
		}
	}
	fclose( fp );
	exit( 0 );
}

main( int argc,char **argv )
{
	char *cmd;
	int env;

	env = pspenv( getcpid() );
	if( env == 0 ) {
		puts( "環境変数領域が見つからない｡" );
		exit( 1 );
	}
	cmd = getcmd();
	while( *cmd == ' ' || *cmd == '\t' )  cmd++;
	if( cmd[0] == '-' ) {
		if( cmd[1] == 'C' || cmd[1] == 'c' ) {
			env = getControlEnv();
		} else if( cmd[1] == 'R' || cmd[1] == 'r' ) {
			env = pspenv( getrpid() );
		}
		cmd += 2;
		while( *cmd == ' ' || *cmd == '\t' )  cmd++;
	}

	if( *cmd == 0 ) {
		envlst( env );
	} else if( cmd[0] == '=' ) {
		envdmp( env );
	} else if( cmd[0] == '@' ) {
		envrd( env,cmd + 1 );
	} else {
		tset( cmd,env );
	}
	exit( 0 );
}

