/* << MSC V5.1 >> [FM-TOWNS] ************************************************
*
*	環境変数領域の情報取得(MS-DOS汎用)
*	----------------------------------------------------------------------
*	All Rights Reserved, Copyright (C) Y.Hirata 1993.
*	Programmed by Y.Hirata ( NIFTY-ID: NAB03321  パオパオ )
*
*	NOTE: TAB=4
****************************************************************************/

#include <stdio.h>		/*  printf	*/
#include <stdlib.h>		/*  atoi	*/
#include <string.h>		/*  str**	*/
#include "lib\mem.h"	/*  _peek,_poke	*/
#include "environ.h"

#define	DEBUG			FALSE

enum Values_for_proc {
		ENV_NONE,	ENV_LOAD,	ENV_SAVE,	ENV_DUMP,
		ENV_CHECK,	ENV_ERACE,	ENV_REPLACE,ENV_UPDATE
} ;

char	IObuf[512] ;

int envchk( FILE *fp,int sw )
/*===========================================================================
*	環境変数ﾌｧｲﾙﾁｪｯｸ
*	< IN  >	: fp	ﾌｧｲﾙﾎﾟｲﾝﾀ
*			: sw	真値ならばﾁｪｯｸ情報を表示する.
*	< RET >	: ｴﾗｰｺｰﾄﾞを返す.
*				=0	正常
*				=1	環境変数ﾌｧｲﾙに誤りがある
===========================================================================*/
{
	int		len ;

	while ( fgets( IObuf,sizeof(IObuf),fp ) != NULL ) {
		len = strlen( IObuf ) ;
		if ( IObuf[len-1] != '\n' && !feof( fp ) ) {
			if ( sw ) {
				printf( "\x1b[33m%s\x1b[m\n",IObuf ) ;
				printf( "\a１行の文字数が" ) ;
				printf( " %u 文字を越えています.\n",sizeof(IObuf)-1 ) ;
			}
			return 1 ;
		}
		if ( IObuf[len-1] == '\n' ) IObuf[len-1] = '\0' ;
		if ( chkEnvName( IObuf ) == 2 ) {
			if ( sw ) {
				printf( "\x1b[33m%s\x1b[m\n",IObuf ) ;
				printf( "\a文法に誤りがあります.\n" ) ;
			}
			return 1 ;
		}
		if ( sw ) printf( "%s\n",IObuf ) ;
	}
	if ( sw ) printf( "正常です.\n" ) ;
	return 0 ;
}

void envload( FILE *fp,ENVINFS *env,int proc )
/*===========================================================================
*	環境変数設定
===========================================================================*/
{
	int		len ;

	if ( envchk( fp,FALSE ) ) {
		printf( "\a環境変数ファイルに誤りがあります.\n" ) ;
		return ;
	}
	rewind( fp ) ;
	if ( proc == ENV_LOAD ) clrEnvName( env ) ;	/*  環境変数全て削除	*/
	while ( fgets( IObuf,sizeof(IObuf),fp ) != NULL ) {
		len = strlen( IObuf ) ;
		if ( IObuf[len-1] != '\n' && !feof( fp ) ) {
			printf( "\x1b[33m%s\x1b[m\n",IObuf ) ;
			printf( "\a１行の文字数が" ) ;
			printf( " %u 文字を越えています. (処理中断)\n",sizeof(IObuf)-1 ) ;
			return ;
		}
		if ( IObuf[len-1] == '\n' ) IObuf[len-1] = '\0' ;
		switch ( setEnvName( env,IObuf ) ) {
		case 0	:
			printf( "%s\n",IObuf ) ;				/*  標準出力		*/
			break ;
		case 1	:
			printf( "\x1b[31m%s\x1b[m\n",IObuf ) ;
			printf( "環境変数を削除しました.\n" ) ;
			break ;
		case 2	:
			printf( "\x1b[33m%s\x1b[m\n",IObuf ) ;
			printf( "\a環境のための領域が足りません. (処理中断)\n" ) ;
			return ;
		case 3	:
			printf( "\x1b[33m%s\x1b[m\n",IObuf ) ;
			printf( "\a文法に誤りがあります.\n" ) ;
			return ;
		}
	}
	printf( "正常に設定しました.\n" ) ;
}

void envsave( FILE *fp,ENVINFS *env )
/*===========================================================================
*	環境変数保存
===========================================================================*/
{
	int		ret ;

	ret = getEnvName( env,IObuf,sizeof( IObuf ),1 ) ;	/*  最初の検索	*/
	while ( ret != -1 ) {
		fprintf( fp,"%s",IObuf ) ;
		if ( ret == 0 ) fprintf( fp,"\n" ) ;
		ret = getEnvName( env,IObuf,sizeof( IObuf ),0 ) ;/*  次の検索	*/
	}
}

void envtype( ENVINFS *env )
/*===========================================================================
*	環境変数表示
===========================================================================*/
{
	static char	buf[16] ;
	int		ret, flg ;

	ret = getEnvName( env,buf,sizeof( buf ),1 ) ;		/*  最初の検索	*/
	flg = TRUE ;
	while ( ret != -1 ) {
#if	DEBUG
		if ( flg ) printf( ">" ) ;
#endif
		printf( "%s",buf ) ;
		if ( ret == 0 ) printf( "\n" ) ;
		flg = ret == 0 ? TRUE : FALSE ;
		ret = getEnvName( env,buf,sizeof( buf ),0 ) ;	/*  次の検索	*/
	}
#if	DEBUG
	printf( "<END>\n" ) ;
#endif
}

void envdump( ENVINFS *env,char *name )
/*===========================================================================
*	環境変数表示
===========================================================================*/
{
	WORD	off ;
	BYTE	ch ;

	if ( strlen( name ) < 1 ) {					/*  環境変数なし		*/
		envtype( env ) ;
		return ;
	}
	if ( getEnvOff( env,name,&off ) ) {
		printf( "環境変数[%s]が見つかりません.\n",name ) ;
	} else {
		do {
			ch = _peekb( env->seg,off ) ;
			if ( ch == 0x00 ) {
				printf( "\n" ) ;
			} else {
				putchar( ch ) ;
			}
			off++ ;
		} while ( ch != 0x00 ) ;
	}
}

void enverace( ENVINFS *env,char *name )
/*===========================================================================
*	環境変数削除
===========================================================================*/
{
#if	DEBUG
	printf( "元の環境セグメント\n" ) ;
	printf( "SEG=%4Xh, SIZE=%uﾊﾞｲﾄ, 残り=%uﾊﾞｲﾄ, TAIL=%u[%4Xh]\n",\
						env->seg,env->size,env->res,env->tail,env->tail ) ;
#endif
	if ( delEnvName( env,name ) ) {
		printf( "\a環境変数[%s]が見つかりません.\n",name ) ;
	} else {
#if	DEBUG
		printf( "更新後の環境セグメント\n" ) ;
		printf( "SEG=%4Xh, SIZE=%uﾊﾞｲﾄ, 残り=%uﾊﾞｲﾄ, TAIL=%u[%4Xh]\n",\
						env->seg,env->size,env->res,env->tail,env->tail ) ;
#else
		printf( "環境変数[%s]を削除しました.\n",name ) ;
#endif
	}
}

void envset( ENVINFS *env,char *name )
/*===========================================================================
*	環境変数削除
===========================================================================*/
{
#if	DEBUG
	printf( "元の環境セグメント\n" ) ;
	printf( "SEG=%4Xh, SIZE=%uﾊﾞｲﾄ, 残り=%uﾊﾞｲﾄ, TAIL=%u[%4Xh]\n",\
						env->seg,env->size,env->res,env->tail,env->tail ) ;
#endif
	switch ( setEnvName( env,name ) ) {
	case 0	:
#if	DEBUG
		printf( "正常に設定しました.\n" ) ;
#endif
		break ;
	case 1	:
		printf( "環境変数を削除しました.\n" ) ;
		break ;
	case 2	:
		printf( "\a環境のための領域が足りません.\n" ) ;
		break ;
	case 3	:
		printf( "\a環境変数の指定が正しくありません.\n" ) ;
		break ;
	}
#if	DEBUG
	printf( "更新後の環境セグメント\n" ) ;
	printf( "SEG=%4Xh, SIZE=%uﾊﾞｲﾄ, 残り=%uﾊﾞｲﾄ, TAIL=%u[%4Xh]\n",\
						env->seg,env->size,env->res,env->tail,env->tail ) ;
#endif
}

void usage( void )
/*===========================================================================
*	使用方法表示
===========================================================================*/
{
	printf( "SET ENVIRON  V1.00  (C) パオパオ 1993.\n\n" ) ;
	printf( "Usage : env [-\\] -option\n" ) ;
	printf( "        -\\              ルートの環境変数領域を対象とする.\n" ) ;
	printf( "                        (省略時は,親の環境変数領域を対象)\n" ) ;
	printf( "option: -lファイル名    環境変数ファイルによる設定(初期化)\n" ) ;
	printf( "        -uファイル名    環境変数ファイルによる追加/更新\n" ) ;
	printf( "        -sファイル名    環境変数の取得" ) ;
	printf( "(環境変数ファイルの作成)\n" ) ;
	printf( "        -d[環境変数名]  環境変数名の表示\n" ) ;
	printf( "        -c[ファイル名]  環境変数ファイルのチェック\n" ) ;
	printf( "        -e環境変数名    環境変数名の削除\n" ) ;
	printf( "        -r環境変数      環境変数の設定\n" ) ;
	exit( 1 ) ;
}

FILE *fileopen( char *fname,char *mode )
/*===========================================================================
*	ﾌｧｲﾙｵｰﾌﾟﾝ
===========================================================================*/
{
	FILE	*fp ;

	fp = fopen( fname,mode ) ;
	if ( fp == NULL ) {
		printf( "file open error. [%s]\n",fname ) ;
		exit( 1 ) ;
	}
	return fp ;
}

int main( int ac,char *av[] )
/*===========================================================================
*	ﾒｲﾝ
===========================================================================*/
{
	ENVINFS	env ;
	int		proc=ENV_NONE ;
	FILE	*fp=NULL ;
	register int	cnt ;
	int		sw=ENV_PRE, no=1 ;
	static char	envstr[128] ;

	if ( ac < 2 ) usage() ;
	if ( *av[1] != '-' && *av[1] != '/' ) usage() ;
	if ( *(av[1]+1) == '\\' && *(av[1]+2) == '\0' ) {
		sw = ENV_ROOT ;
		if ( ac == 2 ) usage() ;
		no = 2 ;
		if ( *av[no] != '-' && *av[no] != '/' ) usage() ;
	}
	switch ( *(av[no]+1) ) {
	case 'l'	:
	case 'L'	:
		if ( no+1 < ac ) usage() ;
		proc = ENV_LOAD ;
		if ( strlen( av[no]+2 ) < 1 ) usage() ;
		fp = fileopen( av[no]+2,"r" ) ;
		break ;
	case 'u'	:
	case 'U'	:
		if ( no+1 < ac ) usage() ;
		proc = ENV_UPDATE ;
		if ( strlen( av[no]+2 ) < 1 ) usage() ;
		fp = fileopen( av[no]+2,"r" ) ;
		break ;
	case 's'	:
	case 'S'	:
		if ( no+1 < ac ) usage() ;
		proc = ENV_SAVE ;
		if ( strlen( av[no]+2 ) < 1 ) usage() ;
		fp = fileopen( av[no]+2,"w" ) ;
		break ;
	case 'd'	:
	case 'D'	:
		if ( no+1 < ac ) usage() ;
		proc = ENV_DUMP ;
		break ;
	case 'c'	:
	case 'C'	:
		if ( no+1 < ac ) usage() ;
		proc = ENV_CHECK ;
		if ( strlen( av[no]+2 ) > 0 ) fp = fileopen( av[no]+2,"r" ) ;
		break ;
	case 'e'	:
	case 'E'	:
		if ( no+1 < ac ) usage() ;
		proc = ENV_ERACE ;
		if ( strlen( av[no]+2 ) < 1 ) usage() ;
		break ;
	case 'r'	:
	case 'R'	:
		proc = ENV_REPLACE ;
		if ( strlen( av[no]+2 ) < 1 ) usage() ;
		strcpy( envstr,av[no]+2 ) ;
		for ( cnt=no+1; cnt<ac; cnt++ ) {
			strcat( envstr," " ) ;
			strcat( envstr,av[cnt] ) ;
		}
		break ;
	default		:
		usage() ;
	}

	if ( getEnvSeg( &env,sw ) ) {
		printf( "\a環境ｾｸﾞﾒﾝﾄを見つけられませんでした.\n" ) ;
	} else {
		switch ( proc ) {
		case ENV_LOAD	:
		case ENV_UPDATE	:
			envload( fp,&env,proc ) ;
			if ( fclose( fp ) ) {
				printf( "\aファイルクローズに失敗しました." ) ;
			}
			break ;
		case ENV_SAVE	:
			envsave( fp,&env ) ;
			if ( fclose( fp ) ) {
				printf( "\aファイルクローズに失敗しました." ) ;
			} else {
				printf( "環境変数ファイル[%s]を作成しました.",av[no]+2 ) ;
			}
			break ;
		case ENV_DUMP	:
			envdump( &env,av[no]+2 ) ;
			break ;
		case ENV_ERACE	:
			enverace( &env,av[no]+2 ) ;
			break ;
		case ENV_REPLACE	:
			envset( &env,envstr ) ;
			break ;
		case ENV_CHECK	:
			if ( fp != NULL ) {
				envchk( fp,TRUE ) ;
				fclose( fp ) ;
				break ;
			}
		default			:
			printf( "環境ｾｸﾞﾒﾝﾄを見つけました.\n" ) ;
			printf( "SEG=%4Xh, SIZE=%uﾊﾞｲﾄ, 残り=%uﾊﾞｲﾄ, TAIL=%u[%4Xh]\n",\
							env.seg,env.size,env.res,env.tail,env.tail ) ;
		}
	}

	return 0 ;
}

/*	HISTORY
-----------------------------------------------------------------------------
*	1993.03.21 : CREATE
---------------------------------------------------------------------------*/
