#define		STRICT
#include	<windows.h>
#include	<tchar.h>
#include	"config.h"
#include	"def.h"
#include	"cetools.h"
#include	"kctrl.h"

void	bufetos( char *p, int len ) ;
int		bufstoe_c( char *p, int len ) ;
int		bufstoe( char *p, int len ) ;
void	kputc( char c, int kfio ) ;
void	kfselectcode( int next_is_k ) ;
char*	fftolower( char *name ) ;
int		bclear( BUFFER *bp ) ;
int		addline( BUFFER *bp, char *text ) ;

TCHAR	g_szPath[ MAX_PATH ] = TEXT("") ;
TCHAR	g_szCurDir[ MAX_PATH ] = TEXT("\\") ;

#define	MALLOC_STEP	256

int
fffiles( char *name, char **buf )
{
	char	pathbuf[ NFILEN ], tmpnam[ NFILEN ] ;
	char	pathbufs[ NFILEN ], ff_namee[ NFILEN ] ;
	char	*cp, *dirpart, *nampart, *buffer ;
	int		n, len, size, dirpartlen, nampartlen, l ;
	HANDLE	hFind ;
	WIN32_FIND_DATA	find ;
	TCHAR	findPath[ MAX_PATH ], unicode[ MAX_PATH ] ;

	strcpy( pathbuf, name ) ;
	dirpart = NULL ;
	for ( cp = pathbuf ; *cp ; cp ++ ) {
		if ( *cp == '/' ) {
			*cp = '\\' ;
			dirpart = cp ;
		} else if ( *cp == '\\' ) {
			dirpart = cp ;
		} else if ( dirpart == NULL && *cp == ':' ) {
			dirpart = cp ;
		}
	}
	if ( dirpart ) {
		*++dirpart = '\0' ;
		dirpartlen = dirpart - pathbuf ;
	} else {
		strcpy( pathbuf, ".\\" ) ;	/* 90.05.30  by A.Shirahashi */
		dirpartlen = 0 ;
	}
	nampart = name + dirpartlen ;
	nampartlen = strlen( nampart ) ;

	buffer = malloc( MALLOC_STEP ) ;
	if ( buffer == NULL ) {
		return -1 ;
	}
	size = MALLOC_STEP ;
	len = 0 ;
	n = 0 ;

	(VOID) strcat( pathbuf, "*.*" ) ;
	strcpy( pathbufs, pathbuf ) ;
	bufetos( pathbufs, strlen(pathbufs) + 1 ) ;
	/* 検索パスをUnicodeにし、カレントディレクトリから絶対パスを得る */
	sjis2unicode( (LPBYTE) pathbufs, unicode, sizeof unicode ) ;
	rel2abs( findPath, g_szCurDir, unicode ) ;
	/* ファイルを検索する */
	hFind = FindFirstFile( findPath, &find ) ;
	if ( hFind == INVALID_HANDLE_VALUE ) {
		*buf = buffer ;
		buffer[0] = '\0' ;
		return 0 ;
	}
	do {
		if ( !_tcscmp( find.cFileName, TEXT(".") ) ) {
			continue ;
		} else if ( !_tcscmp( find.cFileName, TEXT("..") ) ) {
			continue ;
		}
		unicode2sjis( find.cFileName, (LPBYTE) ff_namee, sizeof ff_namee ) ;
		bufstoe( ff_namee, strlen(ff_namee) + 1 ) ;
		if ( strnicmp( nampart, ff_namee, nampartlen ) ) {
			continue ;		/* no-case-sensitive comparison */
		}
		strncpy( tmpnam, pathbuf, dirpartlen ) ;
		strcpy( tmpnam + dirpartlen, ff_namee ) ;
		if ( find.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY ) {
			strcat( tmpnam, "\\" ) ;
		}
		l = strlen(tmpnam) + 1 ;
		/* 90.05.30  by A.Shirahashi */
		if ( l > 5 && (stricmp( &tmpnam[l-5], ".OBJ" ) == 0 ||
						stricmp( &tmpnam[l-5], ".EXE" ) == 0 ||
						stricmp( &tmpnam[l-5], ".COM" ) == 0 ) ) {
			/* 90.05.30  by A.Shirahashi */
			continue ;
		}
		if ( l + len >= size ) {
			/* make room for double null */
			if ( ( buffer = realloc( buffer, size += MALLOC_STEP ) ) == NULL ) {
				return -1 ;
			}
		}
		/* 90.06.08  by A.Shirahashi: to */
		strcpy( buffer + len, tmpnam ) ;
		len += l ;
		n ++ ;
	} while ( FindNextFile( hFind, &find ) ) ;

	*buf = buffer ;
	buffer[len] = '\0' ;
	return n ;
}

char *
file_name_part( char *s )
{
	int		i ;

	for ( i = strlen (s) - 1 ; i > 0 ; i -- ) {
		if ( s[i - 1] == '/' ) {
			break ;
		}
	}
	return s + i ;
}

char *
getwd( char *buf )
{
	unicode2sjis( g_szCurDir, (LPBYTE) buf, MAX_PATH ) ;
	return buf ;
}

/*
 * The string "fn" is a file name.
 * Perform any required appending of directory name or case adjustments.
 * If NO_DIR is not defined, the same file should be refered to even if the
 * working directory changes.
 */
#ifndef NO_DIR
extern	char	*wdir ;
#endif

char *
adjustname( char *fn )
{
	char		*cp ;
	static char	fnb[ NFILEN ] ;

	cp = fnb ;
	switch( *fn ) {
	case '/':
		*fn = '\\' ;
	case '\\':
		*cp++ = *fn++ ;
		break ;
	default:
#ifndef	NO_DIR	/* 91.01.17  NODIR -> NO_DIR. by S.Yoshida */
		if ( cp == fnb || fnb[0] == wdir[0] ) {
			(VOID) strcpy( fnb, wdir ) ;
			cp = fnb + strlen( fnb ) ;
		} else {			/* Different drive. */
			unicode2sjis( g_szCurDir, (LPBYTE) fnb, NFILEN - 1 ) ;
			/* 90.07.01  Add fftolower() by S.Yoshida */
			if ( !fftolower( fnb ) ) {
				cp = fnb ;
			} else {
				cp = fnb + strlen( fnb ) ;
			}
		}
		break ;
#else
		return fn ;				/* punt */
#endif
	}
	if ( cp != fnb && cp[-1] != '\\' ) {
		*cp++ = '\\' ;
	}
	while ( *fn ) {
		switch ( *fn ) {
		case '.':
			switch ( fn[1] ) {
			case '\0':
				*--cp = '\0' ;
				return fnb ;
			case '/':
			case '\\':
				fn += 2 ;
				continue ;
			case '.':
				if ( fn[2]=='\\' || fn[2] == '/' || fn[2] == '\0' ) {
					--cp ;
					while ( cp > fnb && *--cp != '\\' ) {
					}
					++cp ;
					if ( fn[2] == '\0' ) {
						*--cp = '\0' ;
						return fnb ;
					}
					fn += 3 ;
					continue ;
				}
				break ;
			default:
				break ;
			}
			break ;
		case '/':
		case '\\':
			fn ++ ;
			continue ;
		default:
			break ;
		}
		while ( *fn && (*cp++ = *fn++) != '\\' ) {
			/* 90.06.05  by S.Yoshida */
			/* 90.06.08  by A.Shirahashi, convert to lower case */
			if ( ISUPPER( cp[-1] ) ) {
				cp[-1] = TOLOWER( cp[-1] ) ;
			}
			if ( cp[-1] == '/' ) {
				cp[-1] = '\\' ;
				break ;
			}
		}
	}
	if ( cp[-1] == '\\' ) {
		if ( cp != &fnb[1] ) {
			--cp ;
		}
	}
	*cp = '\0' ;
	return fnb ;
}

/*
 * Open a file for reading.
 */
int
ffropen( char *fn )
{
	CHAR	fns[ NFILEN ] ;
	WCHAR	unicode[ MAX_PATH ] ;

	strcpy( fns, fn ) ;
	bufetos( fns, strlen(fns) + 1 ) ;
	unicode[0] = 0 ;
	sjis2unicode( (LPBYTE) fns, unicode, sizeof unicode ) ;
	rel2abs( g_szPath, g_szCurDir, unicode ) ;
	if ( !Fopen( g_szPath, TEXT("r") ) ) {
		return FIOFNF ;
	}
	return FIOSUC ;
}

/*
 * Open a file for writing.
 * Return TRUE if all is well, and
 * FALSE on error (cannot create).
 */
int
ffwopen( char *fn )
{
	CHAR	fns[ NFILEN ] ;
	WCHAR	unicode[ MAX_PATH ] ;

	strcpy( fns, fn ) ;
	bufetos( fns, strlen(fns) + 1 ) ;
	unicode[0] = 0 ;
	sjis2unicode( (LPBYTE) fns, unicode, sizeof unicode ) ;
	rel2abs( g_szPath, g_szCurDir, unicode ) ;
	if ( !Fopen( g_szPath, TEXT("w") ) ) {
		ewprintf( "Cannot open file for writing" ) ;
		return FIOERR ;
	}
	return FIOSUC ;
}

/*
 * Close a file.
 * Should look at the status.
 */
int
ffclose()
{
	Fclose() ;
	return FIOSUC ;
}

/*
 * Write a buffer to the already
 * opened file. bp points to the
 * buffer. Return the status.
 * Check only at the newline and
 * end of buffer.
 */
int
ffputbuf( BUFFER *bp )
{
	char	*cp ;
	char	*cpend ;
	LINE	*lp ;
	LINE	*lpend ;
	int		kfio ;

	lpend = bp->b_linep ;
	kfio  = bp->b_kfio ;
	lp = lforw(lpend) ;
	do {
		cp = &ltext(lp)[0] ;		/* begining of line	*/
		cpend = &cp[llength(lp)] ;	/* end of line		*/
		while ( cp != cpend ) {
			kputc( *cp, kfio ) ;
			cp ++ ;		/* putc may evalualte arguments more than once */
		}
		if ( kfio == JIS ) {
			kfselectcode( FALSE ) ;
		}
		lp = lforw( lp ) ;
		if ( lp == lpend ) {
			break ;		/* no implied newline on last line */
		}
		Fputc( '\n' ) ;
	} while( !Ferror() ) ;
	if ( Ferror() ) {
		ewprintf( "Write I/O error" ) ;
		return FIOERR ;
	}
	return FIOSUC ;
}

/*
 * Read a line from a file, and store the bytes
 * in the supplied buffer. Stop on end of file or end of
 * line.  When FIOEOF is returned, there is a valid line
 * of data without the normally implied \n.
 */
int
ffgetline( char *buf, int nbuf, int *nbytes )
{
	int		c ;
	int		i ;

	i = 0 ;
	while ( ( c = Fgetc() ) != -1 && c != '\n' ) {
		buf[ i++ ] = c ;
		if ( i >= nbuf ) {
			return FIOLONG ;
		}
	}
	if ( c == -1  && Ferror() != FALSE ) {
		ewprintf( "File read error" ) ;
		return FIOERR ;
	}
	*nbytes = i ;
	return c == -1 ? FIOEOF : FIOSUC ;
}

#ifdef	READONLY
/*
 * Check whether file is read-only of a file fn.
 */
int
fchkreadonly( char *fn )
{
	DWORD	attr ;
	char	fns[ NFILEN ] ;
	TCHAR	szPath[ MAX_PATH ], unicode[ MAX_PATH ] ;

	strcpy( fns, fn ) ;
	bufetos( fns, strlen( fns ) + 1 ) ;
	/* カレントディレクトリを基に絶対パスを作成する */
	sjis2unicode( (LPBYTE) fns, unicode, sizeof unicode ) ;
	rel2abs( szPath, g_szCurDir, unicode ) ;
	attr = GetFileAttributes( szPath ) ;
	if ( attr == 0xFFFFFFFF ) {
		return FALSE ;
	}
	return attr & FILE_ATTRIBUTE_READONLY ;
}
#endif	/* READONLY */

#ifndef	NO_STARTUP
/*
 * Find a startup file for the user and return its name. As a service
 * to other pieces of code that may want to find a startup file (like
 * the terminal driver in particular), accepts a suffix to be appended
 * to the startup file name.
 */
char *
startupfile( char *suffix )
{
	static	BYTE	sjis[ MAX_PATH ] ;
	TCHAR	unicode[ MAX_PATH ] ;

	_tcscpy( unicode, TEXT("\\ng.ini") ) ;
	if ( GetFileAttributes( unicode ) == 0xFFFFFFFF ) {
		_tcscpy( unicode, TEXT("\\Storage Card\\ng.ini") ) ;
		if ( GetFileAttributes( unicode ) == 0xFFFFFFFF ) {
			return NULL ;
		}
	}
	unicode2sjis( unicode, sjis, sizeof sjis ) ;
	return (char*) sjis ;
}
#endif	/* NO_STARTUP */

#ifndef NO_DIRED
#include "kbd.h"

int		mkfileline( LPSTR *_line, WIN32_FIND_DATA *info ) ;

int
unlink( const char *fn )
{
	char	fns[ NFILEN ] ;
	TCHAR	unicode[ MAX_PATH ], szPath[ MAX_PATH ] ;

	strcpy( fns, fn ) ;
	bufetos( fns, strlen( fns ) + 1 ) ;
	sjis2unicode( (LPBYTE) fns, unicode, sizeof unicode ) ;
	rel2abs( szPath, g_szCurDir, unicode ) ;

	return DeleteFile( szPath ) ? 0 : -1 ;
}

int
rmdir( const char *fn )
{
	char	fns[ NFILEN ] ;
	TCHAR	unicode[ MAX_PATH ], szPath[ MAX_PATH ] ;

	strcpy( fns, fn ) ;
	bufetos( fns, strlen( fns ) + 1 ) ;
	sjis2unicode( (LPBYTE) fns, unicode, sizeof unicode ) ;
	rel2abs( szPath, g_szCurDir, unicode ) ;
	return RemoveDirectory( szPath ) ? 0 : -1 ;
}

int
rename( const char *oldfn, const char *newfn )
{
	static	char	oldfns[ NFILEN ], newfns[ NFILEN ] ;
	static	TCHAR	unicode[ MAX_PATH ], szOldPath[ MAX_PATH ], szNewPath[ MAX_PATH ] ;

	strcpy( oldfns, oldfn ) ;
	bufetos( oldfns, strlen( oldfns ) + 1 ) ;
	sjis2unicode( (LPBYTE) oldfns, unicode, sizeof unicode ) ;
	rel2abs( szOldPath, g_szCurDir, unicode ) ;

	strcpy( newfns, newfn ) ;
	bufetos( newfns, strlen( newfns ) + 1 ) ;
	sjis2unicode( (LPBYTE) newfns, unicode, sizeof unicode ) ;
	rel2abs( szNewPath, g_szCurDir, unicode ) ;

	return MoveFile( szOldPath, szNewPath ) ? 0 : -1 ;
}

int
copy( char *oldfn, char *newfn )
{
	static	char	oldfns[ NFILEN ], newfns[ NFILEN ] ;
	static	TCHAR	unicode[ MAX_PATH ], szOldPath[ MAX_PATH ], szNewPath[ MAX_PATH ] ;

	strcpy( oldfns, oldfn ) ;
	bufetos( oldfns, strlen( oldfns ) + 1 ) ;
	sjis2unicode( (LPBYTE) oldfns, unicode, sizeof unicode ) ;
	rel2abs( szOldPath, g_szCurDir, unicode ) ;

	strcpy( newfns, newfn ) ;
	bufetos( newfns, strlen( newfns ) + 1 ) ;
	sjis2unicode( (LPBYTE) newfns, unicode, sizeof unicode ) ;
	rel2abs( szNewPath, g_szCurDir, unicode ) ;

	return CopyFile( szOldPath, szNewPath, FALSE ) ? 0 : -1 ;
}

BUFFER *
dired_( char *dirname )
{
	BUFFER	*bp ;
	BUFFER	*findbuffer() ;
	char	**files, **getfilelist() ;
	int		numfiles ;
	int		i ;

	if ( ( dirname = adjustname( dirname ) ) == NULL ) {
		ewprintf( "Bad directory name" ) ;
		return NULL ;
	}
	if ( dirname[ strlen( dirname ) - 1 ] != '\\' ) {
		(VOID) strcat( dirname, "\\" ) ;
	}
	if ( ( bp = findbuffer( dirname ) ) == NULL ) {
		ewprintf( "Could not create buffer" ) ;
		return NULL ;
	}
	if ( bclear( bp ) != TRUE ) {
		return FALSE ;
	}
	if ( ( files = getfilelist( &numfiles, dirname ) ) == NULL ) {
		ewprintf( "Could not get directory info" ) ;
		return NULL ;
	}
	for ( i = 0 ; i < numfiles ; i ++ ) {
		(VOID) addline( bp, files[i] ) ;
		free( files[i] ) ;
	}
	free( files ) ;
	bp->b_dotp = lforw( bp->b_linep ) ;		/* go to first line */
	(VOID) strncpy( bp->b_fname, dirname, NFILEN ) ;
	if ( ( bp->b_modes[0] = name_mode( "dired" ) ) == NULL ) {
		bp->b_modes[0] = &map_table[0] ;
		ewprintf( "Could not find mode dired" ) ;
		return NULL ;
	}
	bp->b_nmodes = 0 ;
	return bp ;
}

int
d_makename( LINE *lp, char *fn )
{
	char	*cp ;

	if ( llength( lp ) <= 41 ) {
		return ABORT ;
	}
	(VOID) strcpy( fn, curbp->b_fname ) ;
	cp = fn + strlen( fn ) ;
	bcopy( &lp->l_text[41], cp, llength(lp) - 41 ) ;
	cp[ llength(lp) - 41 ] = '\0' ;
	return lgetc( lp, 2 ) == 'd' ;
}

char **
getfilelist( int *numfiles, char *dirname )
{
	int		i, j ;
	char	**files, *linebuf ;
	int		maxfiles ;
	char	filename[ NFILEN ] ;
	char	filenames[ NFILEN ] ;
	HANDLE	hFind ;
	TCHAR	unicode[ MAX_PATH ], findPath[ MAX_PATH ] ;
	WIN32_FIND_DATA		find ;

	*numfiles = 0 ;
	if ( strlen(dirname) + 4 > NFILEN ) {
		return NULL ;
	}
	(VOID) strcpy( filename, dirname ) ;
	(VOID) strcat( filename, "*.*" ) ;

	maxfiles = 50 ;
	files = (char **) malloc( maxfiles * sizeof (char *) ) ;
	if ( files == NULL ) {
		return NULL ;
	}
	memset( files, 0, maxfiles * sizeof (char *) ) ;

	strcpy( filenames, filename ) ;
	bufetos( filenames, strlen(filenames) + 1 ) ;
	/* 検索パスをUnicodeにし、カレントディレクトリから絶対パスを得る */
	sjis2unicode( (LPBYTE) filenames, unicode, sizeof unicode ) ;
	rel2abs( findPath, g_szCurDir, unicode ) ;
	/* ルートディレクトリ以外の場合に「..」を加える */
	if ( *dirname && strcmp( dirname, "\\" ) ) {
		if ( !mkfileline( &linebuf, NULL ) ) {
			free( files ) ;
			return NULL ;
		}
		files[ 0 ] = linebuf ;
		(*numfiles) ++ ;
	}
	/* ファイルを検索する */
	hFind = FindFirstFile( findPath, &find ) ;
	if ( hFind == INVALID_HANDLE_VALUE ) {
		free( files ) ;
		return NULL ;
	}
	do {
		if ( !_tcscmp( find.cFileName, TEXT(".") ) ) {
			continue ;
		} else if ( !_tcscmp( find.cFileName, TEXT("..") ) ) {
			continue ;
		}
		if ( *numfiles >= maxfiles ) {
			files = (char **) realloc( files, sizeof(char *) * (maxfiles + 20) ) ;
			if ( files == NULL ) {
				return NULL ;
			}
			maxfiles += 20 ;
		}
		if ( !mkfileline( &linebuf, &find ) ) {
			for ( i = 0 ; i < *numfiles ; i ++ ) {
				free( files[i] ) ;
			}
			free( files ) ;
			return NULL ;
		}
		for ( i = 0 ; i < *numfiles ; i ++ ) {
			if ( stricmp( &files[ i ][ 41 ], &linebuf[ 41 ] ) > 0 ) {
				break ;
			}
		}
		for ( j = *numfiles ; j > i ; j -- ) {
			files[ j ] = files[ j - 1 ] ;
		}
		files[ i ] = linebuf ;
		(*numfiles) ++ ;
	} while ( FindNextFile( hFind, &find ) ) ;
	return files ;
}

int
mkfileline( LPSTR *lptr, WIN32_FIND_DATA *info )
{
	SYSTEMTIME	st ;
	FILETIME	lft ;
	int			len ;
	BYTE		sjis[ MAX_PATH ] ;
	TCHAR		unicode[ MAX_PATH ], *line = unicode ;

	line[0] = line[1] = TEXT(' ') ;
	line[2] = !info || (info->dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) ? TEXT('d') : TEXT('-') ;
	line[3] = TEXT('r') ;
	line[4] = !info || (info->dwFileAttributes & FILE_ATTRIBUTE_READONLY) ? TEXT('-') : TEXT('w') ;
	line[5] = TEXT('-') ;
	line[6] = info && (info->dwFileAttributes & FILE_ATTRIBUTE_ARCHIVE) ? TEXT('a') : TEXT('-') ;
	wsprintf( &line[7], TEXT("%15d"), info ? info->nFileSizeLow : 0 ) ;
	if ( info
	  && FileTimeToLocalFileTime( &info->ftLastWriteTime, &lft )
	  && FileTimeToSystemTime( &lft, &st ) ) {
		wsprintf( &line[22], TEXT("  %02d-%02d-%02d  %02d:%02d  "),
				  st.wYear % 100, st.wMonth, st.wDay,
				  st.wHour, st.wMinute ) ;
	} else {
		_tcscpy( &line[22], TEXT("                   ") ) ;
	}
	_tcscpy( &line[41], info ? info->cFileName : TEXT("..") ) ;
	unicode2sjis( unicode, sjis, sizeof sjis ) ;
	len = bufstoe_c( sjis, strlen( sjis ) + 1 ) ;
	(*lptr) = (LPSTR) malloc( len * sizeof (CHAR) ) ;
	if ( !*lptr ) {
		return FALSE ;
	}
	strcpy( *lptr, sjis ) ;
	(VOID) bufstoe( &(*lptr)[41], strlen( &(*lptr)[41] ) + 1 ) ;
	(VOID) fftolower( &(*lptr)[41] ) ;
	return TRUE ;
}

/*
 * Check whether file "dn" is directory.
 */
int
ffisdir( char *dn )
{
	DWORD	attr ;
	char	dns[ NFILEN ] ;
	TCHAR	szPath[ MAX_PATH ], szUnicode[ MAX_PATH ] ;

	strcpy( dns, dn ) ;
	bufetos( dns, strlen( dns ) + 1 ) ;
	sjis2unicode( (LPBYTE) dns, szUnicode, sizeof szUnicode ) ;
	/* カレントディレクトリを基に絶対パスを作成する */
	rel2abs( szPath, g_szCurDir, szUnicode ) ;
	attr = GetFileAttributes( szPath ) ;
	if ( attr == 0xFFFFFFFF ) {
		return FALSE ;
	}
	return attr & FILE_ATTRIBUTE_DIRECTORY ;
}
#endif

/* 90.07.01  Add function to convert strings into lower case by S.Yoshida */
char *
fftolower( char *name )
{
	char	*p ;

	if ( (p = name) != NULL ) {
		while ( *p != '\0' ) {
			if ( ISUPPER( *p ) ) {
				*p = TOLOWER( *p ) ;
			}
			p ++ ;
		}
	}
	return name ;
}

int
chdir( const char *dir )
{
	DWORD	attr ;
	TCHAR	unicode[ MAX_PATH ], szPath[ MAX_PATH ] ;

	sjis2unicode( (LPBYTE) dir, unicode, sizeof unicode ) ;
	rel2abs( szPath, g_szCurDir, unicode ) ;
	attr = GetFileAttributes( szPath ) ;
	if ( attr == 0xFFFFFFFF || !(attr & FILE_ATTRIBUTE_DIRECTORY) ) {
		return -1 ;
	}
	_tcscpy( g_szCurDir, szPath ) ;
	return 0 ;
}

#ifndef	NO_BACKUP
/*
 * Get file mode of a file fn.
 */
int
fgetfilemode( char *fn )
{
	DWORD	attr ;
	char	fns[ NFILEN ] ;
	TCHAR	unicode[ MAX_PATH ], szPath[ MAX_PATH ] ;

	strcpy( fns, fn ) ;
	bufetos( fns, strlen( fns ) + 1 ) ;
	sjis2unicode( (LPBYTE) fns, unicode, sizeof unicode ) ;
	rel2abs( szPath, g_szCurDir, unicode ) ;
	attr = GetFileAttributes( szPath ) ;
	if ( attr == 0xFFFFFFFF ) {
		return -1 ;
	}
	return (int) attr ;
}

/*
 * Set file mode of a file fn to the specified mode.
 */
VOID
fsetfilemode( char *fn, int mode )
{
	char	fns[ NFILEN ] ;
	TCHAR	unicode[ MAX_PATH ], szPath[ MAX_PATH ] ;

	strcpy( fns, fn ) ;
	bufetos( fns, strlen( fns ) + 1 ) ;
	sjis2unicode( (LPBYTE) fns, unicode, sizeof unicode ) ;
	rel2abs( szPath, g_szCurDir, unicode ) ;
	SetFileAttributes( szPath, (DWORD) mode ) ;
}

/*
 * Rename the file "fname" into a backup
 * copy. On Unix the backup has the same name as the
 * original file, with a "~" on the end; this seems to
 * be newest of the new-speak. The error handling is
 * all in "file.c". The "unlink" is perhaps not the
 * right thing here; I don't care that much as
 * I don't enable backups myself.
 */
int
fbackupfile( char *fn )
{
	char	*nname ;
	char	*dotp ;		/* 90.07.26  Add by N.Kamei */
	VOID	strmfe() ;	/* 90.07.26  Add by N.Kamei */
	char	fns[ NFILEN ] ;
	char	nnames[ NFILEN ] ;
	TCHAR	szFns[ MAX_PATH ] ;
	TCHAR	szNNames[ MAX_PATH ] ;

	if ( ( nname = malloc( (unsigned) (strlen(fn) + 4 + 1) ) ) == NULL ) {
		/* 90.07.26  1+1 -> 4+1 by N.Kamei */
		ewprintf( "Can't get %d bytes", strlen(fn) + 4 + 1 ) ;
		return ABORT ;
	}
	/* 90.07.26  by N.Kamei
	   This is not good for MS-DOS.
		(VOID) strcpy(nname, fn);
		(VOID) strcat(nname, "~");
	 */
	strmfe( nname, fn, "bak" ) ;	/* 90.07.26  by N.Kamei */
	strcpy( nnames, nname ) ;
	strcpy( fns, fn ) ;
	bufetos( nnames, strlen( nnames ) + 1 ) ;
	bufetos( fns, strlen( fns ) + 1 ) ;
	sjis2unicode( (LPBYTE) nnames, unicode, sizeof unicode ) ;
	rel2abs( szNNames, g_szCurDir, unicode ) ;
	sjis2unicode( (LPBYTE) fns, unicode, sizeof unicode ) ;
	rel2abs( szFns, g_szCurDir, unicode ) ;
	DeleteFile( szNNames ) ;
	if ( MoveFile( szFns, szNNames ) < 0 ) {
		free( nname ) ;
		return FALSE ;
	}
	free( nname ) ;
	return TRUE ;
}
#endif	/* NO_BACKUP */
