/*
 * CESHELL : シェルアプリケーション：メインルーチン
 * Copyright(C) 1997-1999 Eiichiro Ito
 *
 * 1997/07/05:Eiichiro Ito
 *  (1) 作成開始
 * 修正履歴
 * 1998/04/11:Eiichiro Ito
 *  (1) 起動時にパスを取得するようにした
 *
 */
#include	"conslib.h"
#include	"batch.h"
#include	<tchar.h>

TCHAR	AppName[] = TEXT("CEShell") ;	/* 必須項目 */

TCHAR	Version[] = TEXT("0.28") ;
TCHAR	Prompt[ MAX_PATH ] = TEXT("") ;
TCHAR	MessageBuf[ 1024 ] ;
DWORD	ScreenW = 80, ScreenH = 24 ;

LPCTSTR	HelpCmd[] = {
	TEXT("CD\t cd directory\n"),
	TEXT("CLS\t cls\n"),
	TEXT("COPY\t copy source [dest]\n"),
	TEXT("DEL\t del filename\n"),
	TEXT("DIR\t dir [directory]\n"),
	TEXT("DIR/P\t dir/p [directory]\n"),
	TEXT("ECHO\t echo [string]\n"),
	TEXT("EXIT\t exit\n"),
	TEXT("KILL\t kill hWnd\n"),
	TEXT("MKDIR\t mkdir directory\n"),
	TEXT("MORE\t more filename\n"),
	TEXT("PS\t ps [1|2]\n"),
	TEXT("REN\t ren source dest\n"),
	TEXT("RMDIR\t rmdir directory\n"),
	TEXT("SET\t set var[=value]\n"),
	TEXT("START\t start filename\n"),
	TEXT("SWITCH\t switch hWnd\n"),
	TEXT("TYPE\t type filename\n"),
	TEXT("VER\t ver\n"),
} ;

void
dir( LPCTSTR curdir, BOOL f_pause )
{
	SYSTEMTIME		st ;
	FILETIME		lft ;
	WIN32_FIND_DATA	find ;
	HANDLE			hFind ;
	TCHAR			findPath[ MAX_PATH ] ;
	TCHAR			dirstr[20], timestr[20], c ;
	DWORD			len = _tcslen( curdir ), count = 0, cur_line = 0 ;

	rel2absdir( findPath, MAX_PATH, curdir ) ;
	if ( is_dir( findPath ) ) {
		catdir( findPath, TEXT("*.*"), NULL ) ;
	}
	hFind = FindFirstFile( findPath, &find ) ;
	if ( hFind == INVALID_HANDLE_VALUE ) {
		DWORD	rc = GetLastError() ;

		if ( rc == ERROR_NO_MORE_FILES ) {
			_tcscpy( MessageBuf, TEXT("No files.\n") ) ;
		} else {
			wsprintf( MessageBuf, TEXT("Error:%s(%d)\n"), findPath, rc ) ;
		}
		Cputs( MessageBuf ) ;
		return ;
	}
	ResetBreak() ;
	cur_line = 0 ;
	while ( 1 ) {
		if ( !FileTimeToLocalFileTime( &find.ftLastWriteTime, &lft ) ) {
			_tcscpy( timestr, TEXT("??/??/?? ??:??") ) ;
		} else if ( !FileTimeToSystemTime( &lft, &st ) ) {
			_tcscpy( timestr, TEXT("??/??/?? ??:??") ) ;
		} else {
			wsprintf( timestr, TEXT("%02d/%02d/%02d %02d:%02d"),
					  st.wYear % 100, st.wMonth % 100, st.wDay % 100,
					  st.wHour % 100, st.wMinute % 100 ) ;
		}
		if ( find.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY ) {
			_tcscpy( dirstr, TEXT("<DIR>   ") ) ;
		} else {
			wsprintf( dirstr, TEXT("%8d"), find.nFileSizeLow ) ;
		}
		wsprintf( MessageBuf, TEXT("%s %s %s\n"),
				  timestr, dirstr, find.cFileName ) ;
		Cputs( MessageBuf ) ;
		if ( SleepWithBreak( 0 ) ) {
			goto exit ;
		}
		count ++ ;
		if ( f_pause ) {
			if ( ++ cur_line >= ScreenH - 1 ) {
				cur_line = 0 ;
				Cputs( TEXT("More...") ) ;
				c = Getch() ;
				Putch( TEXT('\n') ) ;
				if ( c == 0x03 || c == TEXT('q') ) {
					goto exit ;
				}
			}
		}
		if ( !FindNextFile( hFind, &find ) ) {
			break ;
		}
	}
	wsprintf( MessageBuf, TEXT("%d File(s).\n"), count ) ;
	Cputs( MessageBuf ) ;

exit:
	FindClose( hFind ) ;
}

void
chdir( LPCTSTR dir )
{
	TCHAR	newdir[ MAX_PATH ] ;

	rel2absdir( newdir, MAX_PATH, dir ) ;
	if ( !is_dir( newdir ) ) {
		goto error ;
	}
	_tcscpy( CurrentDir, newdir ) ;
	SetCurDir( CurrentDir ) ;
	return ;

error:
	Cputs( TEXT("Invalid directory\n") ) ;
}

void
type( LPCTSTR file, BOOL f_pause )
{
	HANDLE		hFile ;
	BYTE		sjis[ 256 ], *src ;
	DWORD		readsize, cur_line, col, line ;
	TCHAR		path[ MAX_PATH ], unicode[ 256 + 1 ], *dst ;

	rel2absdir( path, MAX_PATH, file ) ;
	hFile = CreateFile( path, GENERIC_READ, FILE_SHARE_READ, NULL,
						OPEN_EXISTING, 0, 0 ) ;
	if ( hFile == INVALID_HANDLE_VALUE ) {
		Cputs( TEXT("Can't open the file\n") ) ;
		return ;
	}
	ResetBreak() ;
	cur_line = 0 ;
	while ( 1 ) {
		if ( !ReadFile( hFile, sjis, sizeof sjis, &readsize, NULL ) || !readsize ) {
			break ;
		}
		src = sjis ;
		dst = unicode ;
		do {
			TCHAR	c = (TCHAR) *src++ ;
			*dst++ = c ;
			if ( f_pause && c == TEXT('\n') ) {
				*dst = 0 ;
				Cputs( unicode ) ;
				if ( ++ cur_line >= ScreenH - 1 ) {
					cur_line = 0 ;
					Cputs( TEXT("More...") ) ;
					c = Getch() ;
					Putch( TEXT('\n') ) ;
					if ( c == 0x03 || c == TEXT('q') ) {
						goto exit ;
					}
				}
				dst = unicode ;
			} else if ( SleepWithBreak( 0 ) ) {
				Putch( TEXT('\n') ) ;
				goto exit ;
			}
		} while ( -- readsize ) ;
		*dst = 0 ;
		Cputs( unicode ) ;
	}
	GetCurPos( &col, &line ) ;
	if ( col ) {
		Putch( TEXT('\n') ) ;
	}

exit:
	CloseHandle( hFile ) ;
}

void
copy_file( LPCTSTR src, LPCTSTR dst )
{
	WIN32_FIND_DATA	find ;
	HANDLE			hFind ;
	DWORD			count = 0 ;
	TCHAR			srcBase[ MAX_PATH ] ;
	TCHAR			srcPath[ MAX_PATH ], srcDir[ MAX_PATH ] ;
	TCHAR			dstPath[ MAX_PATH ], dstDir[ MAX_PATH ] ;

	rel2absdir( srcDir, MAX_PATH, src ) ;
	rel2absdir( dstDir, MAX_PATH, dst ) ;
	if ( is_dir( srcDir ) ) {
		catdir( srcDir, TEXT("*.*"), NULL ) ;
	}
	_tcscpy( srcBase, srcDir ) ;
	UpDir( srcBase ) ;
	hFind = FindFirstFile( srcDir, &find ) ;
	if ( hFind == INVALID_HANDLE_VALUE ) {
		Cputs( srcDir ) ;
		Cputs( TEXT(": not found\n") ) ;
		return ;
	}
	while ( 1 ) {
		if ( !(find.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) ) {
			_tcscpy( srcPath, srcBase ) ;
			catdir( srcPath, find.cFileName, NULL ) ;
			_tcscpy( dstPath, dstDir ) ;
			if ( is_dir( dstPath ) ) {
				catdir( dstPath, find.cFileName, NULL ) ;
			}
			if ( CopyFile( srcPath, dstPath, FALSE ) ) {
				count ++ ;
			} else {
				wsprintf( MessageBuf, TEXT("Error:%s -> %s(%d)\n"), srcPath, dstPath, GetLastError() ) ;
				Cputs( MessageBuf ) ;
			}
		}
		if ( !FindNextFile( hFind, &find ) ) {
			break ;
		}
	}
	FindClose( hFind ) ;
	wsprintf( MessageBuf, TEXT("%d file(s) copied.\n"), count ) ;
	Cputs( MessageBuf ) ;
}

void
del_file( LPCTSTR delfile )
{
	WIN32_FIND_DATA	find ;
	HANDLE			hFind ;
	TCHAR			delDir[ MAX_PATH ] ;
	TCHAR			delBase[ MAX_PATH ] ;
	TCHAR			delPath[ MAX_PATH ] ;
	LPCTSTR			retmsg = TEXT("Done.\n") ;

	rel2absdir( delDir, MAX_PATH, delfile ) ;
	if ( is_dir( delDir ) ) {
		catdir( delDir, TEXT("*.*"), NULL ) ;
	}
	_tcscpy( delBase, delDir ) ;
	UpDir( delBase ) ;
	hFind = FindFirstFile( delDir, &find ) ;
	if ( hFind == INVALID_HANDLE_VALUE ) {
		Cputs( delDir ) ;
		Cputs( TEXT(": not found\n") ) ;
		return ;
	}
	ResetBreak() ;
	while ( 1 ) {
		if ( !(find.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) ) {
			_tcscpy( delPath, delBase ) ;
			catdir( delPath, find.cFileName, NULL ) ;
			if ( !DeleteFile( delPath ) ) {
				wsprintf( MessageBuf, TEXT("Error:%s(%d)\n"), delPath, GetLastError() ) ;
				Cputs( MessageBuf ) ;
			}
		}
		if ( SleepWithBreak( 0 ) ) {
			retmsg = TEXT("Break\n") ;
			break ;
		}
		if ( !FindNextFile( hFind, &find ) ) {
			break ;
		}
	}
	FindClose( hFind ) ;
	Cputs( retmsg ) ;
}

void
create_dir( LPCTSTR dir )
{
	TCHAR		mkdirPath[ MAX_PATH ] ;

	rel2absdir( mkdirPath, MAX_PATH, dir ) ;
	if ( !CreateDirectory( mkdirPath, NULL ) ) {
		wsprintf( MessageBuf, TEXT("Error:%s(%d)\n"), mkdirPath, GetLastError() ) ;
		Cputs( MessageBuf ) ;
		return ;
	}
	Cputs( TEXT("Done.\n") ) ;
}

void
remove_dir( LPCTSTR dir )
{
	TCHAR		rmdirPath[ MAX_PATH ] ;

	rel2absdir( rmdirPath, MAX_PATH, dir ) ;
	if ( !RemoveDirectory( rmdirPath ) ) {
		wsprintf( MessageBuf, TEXT("Error:%s(%d)\n"), rmdirPath, GetLastError() ) ;
		Cputs( MessageBuf ) ;
		return ;
	}
	Cputs( TEXT("Done.\n") ) ;
}

BOOL CALLBACK
ps( HWND hWnd, LPARAM lParam )
{
	TCHAR	className[ 128 ] ;
	TCHAR	buf[ 128 ], buf2[ 10 ] ;
	DWORD	index, mode = (DWORD) lParam ;

	if ( SleepWithBreak( 0 ) ) {
		return FALSE ;
	}
	if ( !GetClassName( hWnd, className, sizeof className / sizeof className[0] ) ) {
		_tcscpy( className, TEXT("???") ) ;
	}
	if ( mode == 0 ) {
		if ( _tcscmp( className, ClassName ) ) {
			return TRUE ;
		}
	}
	GetWindowText( hWnd, buf, sizeof buf / sizeof buf[0] ) ;
	if ( mode == 1 && !*buf ) {
		return TRUE ;
	}
	index = GetIndex( hWnd ) ;
	if ( index ) {
		wsprintf( buf2, TEXT("%d"), index ) ;
	} else {
		_tcscpy( buf2, TEXT("?") ) ;
	}
	wsprintf( MessageBuf, TEXT("%s %d %s(%s)\n"), buf2, (DWORD) hWnd, buf, className ) ;
	Cputs( MessageBuf ) ;
	return TRUE ;
}

void
switch_hwnd( DWORD hwnd )
{
	BOOL	ret = FALSE ;
	HWND	hWnd = (HWND) hwnd ;
	DWORD	index = GetIndex( hWnd ) ;

	if ( index ) {
		ret = SwitchClient( index ) ;
	} else if ( IsWindow( hWnd ) ) {
		ret = SetForegroundWindow( hWnd ) ;
	}
	if ( !ret ) {
		Cputs( TEXT("Switch failed\n") ) ;
	}
}

void
kill_hwnd( DWORD hwnd )
{
	HWND	hWnd = (HWND) hwnd ;

	if ( IsWindow( hWnd ) ) {
		SendMessage( hWnd, WM_CLOSE, 0, 0 ) ;
	}
}

void
ren_file( LPCTSTR src, LPCTSTR dst )
{
	WIN32_FIND_DATA	find ;
	HANDLE			hFind ;
	DWORD			count = 0 ;
	TCHAR			srcBase[ MAX_PATH ] ;
	TCHAR			srcPath[ MAX_PATH ], srcDir[ MAX_PATH ] ;
	TCHAR			dstPath[ MAX_PATH ], dstDir[ MAX_PATH ] ;

	rel2absdir( srcDir, MAX_PATH, src ) ;
	rel2absdir( dstDir, MAX_PATH, dst ) ;
	if ( is_dir( srcDir ) ) {
		catdir( srcDir, TEXT("*.*"), NULL ) ;
	}
	_tcscpy( srcBase, srcDir ) ;
	UpDir( srcBase ) ;
	hFind = FindFirstFile( srcDir, &find ) ;
	if ( hFind == INVALID_HANDLE_VALUE ) {
		Cputs( srcDir ) ;
		Cputs( TEXT(": not found\n") ) ;
		return ;
	}
	while ( 1 ) {
		if ( !(find.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) ) {
			_tcscpy( srcPath, srcBase ) ;
			catdir( srcPath, find.cFileName, NULL ) ;
			_tcscpy( dstPath, dstDir ) ;
			if ( is_dir( dstPath ) ) {
				catdir( dstPath, find.cFileName, NULL ) ;
			}
			if ( is_file( dstPath ) ) {
				wsprintf( MessageBuf, TEXT("A duplicate file name exists:%s\n"), dstPath ) ;
				Cputs( MessageBuf ) ;
			} else {
				if ( MoveFile( srcPath, dstPath ) ) {
					count ++ ;
				} else {
					wsprintf( MessageBuf, TEXT("Error:%s -> %s(%d)\n"), srcPath, dstPath, GetLastError() ) ;
					Cputs( MessageBuf ) ;
				}
			}
		}
		if ( !FindNextFile( hFind, &find ) ) {
			break ;
		}
	}
	FindClose( hFind ) ;
	wsprintf( MessageBuf, TEXT("%d file(s) renamed.\n"), count ) ;
	Cputs( MessageBuf ) ;
}

/*
 *
 */
#define		MAX_HIST	(10)
static	TCHAR	CgetsHist[ MAX_HIST ][ 256 ] ;
static	DWORD	CurHist = 0 ;

void
init_history( void )
{
	DWORD	i ;

	for ( i = 0 ; i < MAX_HIST ; i ++ ) {
		*CgetsHist[ i ] = 0 ;
	}
	CurHist = 0 ;
}

LPTSTR
Cgets_with_history( LPTSTR buf )
{
	LPTSTR	org = buf ;
	DWORD	col, line, cur_hist = CurHist ;

	ResetBreak() ;
	GetCurPos( &col, &line ) ;
	while ( 1 ) {
		TCHAR	c = Getch() ;
		if ( c == '\r' ) {
			*buf = 0 ;
			c = TEXT('\n') ;
			Putch( c ) ;
			_tcscpy( CgetsHist[CurHist], org ) ;
			CurHist = (CurHist + 1) % MAX_HIST ;
			return org ;
		}
		if ( c == 3 ) {
			if ( SleepWithBreak( 0 ) ) {
				Putch( TEXT('\n') ) ;
				*org = 0 ;
				return org ;
			}
		} else if ( c == 8 ) {
			/* BS の場合 */
			if ( org != buf ) {
				c = *--buf ;
				*buf = 0 ;
				if ( c < ' ' ) {
					Putch( 8 ) ;
				}
				Putch( 8 ) ;
			}
		} else if ( c == 27 ) {
			*org = 0 ;
			buf = org ;
			SetCurPos( col, line ) ;
			ClearEol() ;
		} else if ( c == 'P' - '@' ) {
			*org = 0 ;
			do {
				cur_hist = (cur_hist - 1 + MAX_HIST) % MAX_HIST ;
				if ( CgetsHist[cur_hist][0] ) {
					_tcscpy( org, CgetsHist[cur_hist] ) ;
					break ;
				}
			} while ( cur_hist != CurHist ) ;
			SetCurPos( col, line ) ;
			ClearEol() ;
			Cputs( org ) ;
			buf = &org[ _tcslen( org ) ] ;
		} else if ( c == 'N' - '@' ) {
			*org = 0 ;
			do {
				cur_hist = (cur_hist + 1) % MAX_HIST ;
				if ( CgetsHist[cur_hist][0] ) {
					_tcscpy( org, CgetsHist[cur_hist] ) ;
					break ;
				}
			} while ( cur_hist != CurHist ) ;
			SetCurPos( col, line ) ;
			ClearEol() ;
			Cputs( org ) ;
			buf = &org[ _tcslen( org ) ] ;
		} else if ( c == 0x7F ) {
		} else if ( c >= TEXT(' ') ) {
			*buf++ = c ;
			Putch( c ) ;
		} else {
			*buf++ = c ;
			Putch( TEXT('^') ) ;
			c += TEXT( '@' ) ;
			Putch( c ) ;
		}
	}
}

void
help( void )
{
	TCHAR	c ;
	DWORD	cur_line = 0, i = 0 ;
	DWORD	num = sizeof HelpCmd / sizeof *HelpCmd ;

	for ( i = 0 ; i < num ; i ++ ) {
		Cputs( HelpCmd[ i ] ) ;
		if ( ++ cur_line >= ScreenH - 1 ) {
			cur_line = 0 ;
			Cputs( TEXT("More...") ) ;
			c = Getch() ;
			Putch( TEXT('\n') ) ;
			if ( c == 0x03 || c == TEXT('q') ) {
				break ;
			}
		}
	}
}

DWORD
command_main( LPTSTR restarg, BOOL f_batch )
{
	LPCTSTR	ptr ;
	static	TCHAR	cmd[ MAX_PATH ] ;
	static	TCHAR	arg1[ MAX_PATH ] ;
	static	TCHAR	arg2[ MAX_PATH ] ;

	if ( Argc <= 1 ) {
		return 0 ;
	}
	_tcscpy( cmd, Argv[1] ) ;
	ExpandEnvVar( cmd ) ;
	if ( !_tcsicmp( cmd, TEXT("dir") ) ) {
		if ( Argc > 2 ) {
			ExpandEnvVar( restarg ) ;
			chop_quote( restarg ) ;
			ptr = restarg ;
		} else {
			ptr = CurrentDir ;
		}
		dir( ptr, FALSE ) ;
	} else if ( !_tcsicmp( cmd, TEXT("dir/p") ) ) {
		if ( Argc > 2 ) {
			ExpandEnvVar( restarg ) ;
			chop_quote( restarg ) ;
			ptr = restarg ;
		} else {
			ptr = CurrentDir ;
		}
		dir( ptr, TRUE ) ;
	} else if ( !_tcsicmp( cmd, TEXT("cd") ) ) {
		if ( Argc > 2 ) {
			ExpandEnvVar( restarg ) ;
			chop_quote( restarg ) ;
			chdir( restarg ) ;
		} else {
			wsprintf( MessageBuf, TEXT("%s\n"), CurrentDir ) ;
			Cputs( MessageBuf ) ;
		}
	} else if ( !_tcsicmp( cmd, TEXT("exit") ) ) {
		return 1 ;
	} else if ( !_tcsicmp( cmd, TEXT("type") ) ) {
		if ( Argc > 2 ) {
			ExpandEnvVar( restarg ) ;
			chop_quote( restarg ) ;
			type( restarg, FALSE ) ;
		} else {
			Cputs( TEXT("type filename\n") ) ;
		}
	} else if ( !_tcsicmp( cmd, TEXT("more") ) ) {
		if ( Argc > 2 ) {
			ExpandEnvVar( restarg ) ;
			chop_quote( restarg ) ;
			type( restarg, TRUE ) ;
		} else {
			Cputs( TEXT("more filename\n") ) ;
		}
	} else if ( !_tcsicmp( cmd, TEXT("copy") ) ) {
		if ( Argc > 2 ) {
			_tcscpy( arg1, Argv[2] ) ;
			_tcscpy( arg2, Argc > 3 ? Argv[3] : TEXT(".") ) ;
			ExpandEnvVar( arg1 ) ;
			ExpandEnvVar( arg2 ) ;
			copy_file( arg1, arg2 ) ;
		} else {
			Cputs( TEXT("copy source [dest]\n") ) ;
		}
	} else if ( !_tcsicmp( cmd, TEXT("del") ) ) {
		if ( Argc > 2 ) {
			ExpandEnvVar( restarg ) ;
			chop_quote( restarg ) ;
			del_file( restarg ) ;
		} else {
			Cputs( TEXT("del filename\n") ) ;
		}
	} else if ( !_tcsicmp( cmd, TEXT("mkdir") ) || !_tcsicmp( cmd, TEXT("md") ) ) {
		if ( Argc > 2 ) {
			ExpandEnvVar( restarg ) ;
			chop_quote( restarg ) ;
			create_dir( restarg ) ;
		} else {
			Cputs( TEXT("mkdir directory\n") ) ;
		}
	} else if ( !_tcsicmp( cmd, TEXT("rmdir") ) || !_tcsicmp( cmd, TEXT("rd") ) ) {
		if ( Argc > 2 ) {
			ExpandEnvVar( restarg ) ;
			chop_quote( restarg ) ;
			remove_dir( restarg ) ;
		} else {
			Cputs( TEXT("rmdir directory\n") ) ;
		}
	} else if ( !_tcsicmp( cmd, TEXT("cls") ) ) {
		Cls() ;
	} else if ( !_tcsicmp( cmd, TEXT("ps") ) ) {
		DWORD	mode = 0 ;

		if ( Argc > 2 ) {
			ExpandEnvVar( restarg ) ;
			chop_quote( restarg ) ;
			mode = _ttol( restarg ) ;
		}
		ResetBreak() ;
		EnumWindows( ps, (LPARAM) mode ) ;
	} else if ( !_tcsicmp( cmd, TEXT("switch") ) ) {
		if ( Argc > 2 ) {
			ExpandEnvVar( restarg ) ;
			chop_quote( restarg ) ;
			switch_hwnd( _ttol( restarg ) ) ;
		} else {
			Cputs( TEXT("switch hWnd\n") ) ;
		}
	} else if ( !_tcsicmp( cmd, TEXT("kill") ) ) {
		if ( Argc > 2 ) {
			ExpandEnvVar( restarg ) ;
			chop_quote( restarg ) ;
			kill_hwnd( _ttol( restarg ) ) ;
		} else {
			Cputs( TEXT("kill hWnd\n") ) ;
		}
	} else if ( !_tcsicmp( cmd, TEXT("ren") ) ) {
		if ( Argc > 3 ) {
			_tcscpy( arg1, Argv[2] ) ;
			_tcscpy( arg2, Argv[3] ) ;
			ExpandEnvVar( arg1 ) ;
			ExpandEnvVar( arg2 ) ;
			ren_file( arg1, arg2 ) ;
		} else {
			Cputs( TEXT("ren source dest\n") ) ;
		}
	} else if ( !_tcsicmp( cmd, TEXT("set") ) ) {
		setenv_main( restarg ) ;
	} else if ( !_tcsicmp( cmd, TEXT("echo") ) ) {
		ExpandEnvVar( restarg ) ;
		Cputs( restarg ) ;
		Putch( TEXT('\n') ) ;
	} else if ( !_tcsicmp( cmd, TEXT("ver") ) ) {
		DWORD	cver = GetConsoleVer() ;
		wsprintf( MessageBuf, TEXT("%s Version is %s.  "), AppName, Version ) ;
		Cputs( MessageBuf ) ;
		wsprintf( MessageBuf, TEXT("(Console Version is %d.%02d.)\n"), cver / 100, cver % 100 ) ;
		Cputs( MessageBuf ) ;
	} else if ( !_tcsicmp( cmd, TEXT("help") ) ) {
		help() ;
	} else if ( *cmd == TEXT('-') ) {
		if ( f_batch ) {
			return 2 ;
		} else {
			if ( !batch_main( &cmd[1], restarg ) ) {
				Cputs( &cmd[1] ) ;
				Cputs( TEXT(": not found\n") ) ;
			}
		}
	} else {
		exec( restarg ) ;
	}
	return 0 ;
}

int
Main( DWORD argc, LPTSTR argv[] )
{
	LPTSTR	ptr ;
	TCHAR	cmdline[ 256 ] ;
	TCHAR	cmdline2[ 256 ] ;

	if ( !init_batch() ) {
		return 0 ;
	}
	if ( _tcsicmp( argv[1], TEXT("/H") ) ) {
		wsprintf( MessageBuf, TEXT("Starting %s V%s.\n"), AppName, Version ) ;
		Cputs( MessageBuf ) ;
	}
	/* ヒストリを初期化 */
	init_history() ;
	/* 画面の幅・高さを求める */
	GetWH( &ScreenW, &ScreenH ) ;
	/* カレントディレクトリを取得する */
	GetCurDir( sizeof CurrentDir / sizeof (TCHAR), CurrentDir ) ;
	GetEnvVar( TEXT("PATH"), Env_Path, sizeof Env_Path / sizeof (TCHAR) ) ;
	while ( 1 ) {
		wsprintf( Prompt, TEXT("%s>"), CurrentDir ) ;
		Cputs( Prompt ) ;
		ptr = Cgets_with_history( cmdline ) ;
		if ( ptr == NULL ) {
			Putch( TEXT('\n') ) ;
			continue ;
		}
		cmdline2args( cmdline, &Argc, Argv, Quote, cmdline2 ) ;
		if ( Argc <= 1 ) {
			continue ;
		}
		if ( command_main( cmdline2, FALSE ) ) {
			wsprintf( MessageBuf, TEXT("Exiting %s.\n"), AppName ) ;
			Cputs( MessageBuf ) ;
			break ;
		}
	}
	release_batch() ;
	return 0 ;
}
