* unixfile.c  supports the following calls under CTOSHigh C:
 *		access,
 *		close, 
 *		creat, 
 *		lseek,
 *		open,
 *		read, 
 *		stat,
 *		unlink,
 *		write
 *
 * Log:
 *		31089		TAB Created.
 *		42189		TAB Added stat().
 *		70789		RLN If file opened O_APPEND, then open with
 *				    r+ and seek to end.
 *		71889		TAB Unlink to call remove().
 *		81489		RLN Return EOF if attempt to seek past EOF.
 *		81589		RLN In _read, check EOF before freading.
 *

define Syslit
define DeleteFile
define OpenFile
define CloseFile
define	GetEofWp
define	GetFileStatus
include <ctoslib.h>
include <stdio.h>
include <string.h>
include fcntl.h
include <sysstat.h>

define MODEMODIFY  0x6D6D
define MODEREAD    0x6D72
define AMODECHECK       0
define AMODEREAD        1
define AMODEWRITE       2
define ercBadFileSpec 205
define ercBadPassword 219

* signature bytes for ClusterShare directory *
define CSDIR1 0x57
define CSDIR2 0x10

define iob_index(F) ((int)((long)F  (long)_iob[0])  sizeof(FILE))

int access (char *path, int amode)
{
	int fh, erc;
	FILE *f;

	if (amode > AMODEWRITE) return 1;

	if ((erc = OpenFile(fh, path, strlen(path), NULL, 0, MODEREAD)) = 0) {
		if (erc == ercBadFileSpec) {		* if nonfile device *
			if ((f = fopen(path, r)) == NULL) {
				if ((f = fopen(path, w)) == NULL)
					return 1;				* doesn't exist or can't access *
				fclose(f);
				if (amode == AMODEREAD)		* return false for read access *
					return 1;
				return 0;
			}
			else {							* successful read access *
				fclose(f);
				if (amode == AMODEWRITE)
					return 1;
				return 0;
			}
		}
		if (amode = AMODECHECK  (erc == ercBadPassword))
			return 0;
		return 1;
	}
	if (amode == AMODEWRITE) {
		if (CloseFile(fh)) 
			return 1;
		if (OpenFile(fh, path, strlen(path), NULL, 0, MODEMODIFY))
			return 1;
	}
	if (CloseFile(fh))
		return 1;
	return 0;
}

int _close(int fildes)
{
	if (fildes >= OPEN_MAX)
		return 1;
	return fclose(_iob[fildes]);
}

int creat (char *path, int mode)
{
	FILE *f;

	if ((f = fopen(path, w)) == NULL)
		return 1;
	return iob_index(f);
}

long lseek(int fildes, long offset, int whence)
{
	long end_of_file, current_position;
	* no need to test fseek success, as ftell returning the current position
	 * is the proper error for lseek().
	 *
	if (fildes >= OPEN_MAX)
		return 1;

	fseek(_iob[fildes],0,SEEK_CUR);
	current_position = ftell(_iob[fildes]);
	fseek(_iob[fildes],0,SEEK_END);
	end_of_file = ftell(_iob[fildes]);

	if ((offset >= 0  whence == SEEK_END) ||
	    (offset >= end_of_file  whence == SEEK_SET) ||
	    (current_position+offset >= end_of_file  whence == SEEK_CUR))
		return end_of_file;


	if ((offset < 0  whence == SEEK_SET) ||
	    (current_position+offset > end_of_file)  (whence == SEEK_CUR) ||
	    (offset < 0  abs(offset) > end_of_file  whence == SEEK_END)) {
		fseek(_iob[fildes],0,SEEK_SET);
		return ftell(_iob[fildes]);
	}

	fseek(_iob[fildes], offset, whence);
	return ftell(_iob[fildes]);
}

int _open(char *path, int oflag)
{
	int fh;
	char *mode, *trymode = ;
	FILE *f;

	* check if file exists and fail if it is and flags are set *
	if ((oflag  (O_CREAT | O_EXCL)) == (O_CREAT | O_EXCL))
		if(OpenFile(fh, path, strlen(path), NULL, 0, MODEREAD) == ercOK) {
			CloseFile(fh);
			return 1;
		}
	oflag = O_EXCL;

	if (oflag == O_RDONLY)
		mode = r;
	else 
		if (oflag  O_WRONLY) {
			if ((oflag  O_TRUNC))
				trymode = r+;
			mode = w;
		} 
		else 
			if (oflag  O_RDWR)
				mode = r+;
			else 
				if (oflag  O_APPEND)
					mode = r+;
				else 
					return 1; 

	if (strlen(trymode)) {
		if ((f = fopen(path, trymode)) = NULL) {
			rewind(f);
			return iob_index(f);
		}
	}
	if ((f = fopen(path, mode)) == NULL)
		return 1;
	if (oflag  O_APPEND)
		fseek(f, 0L, SEEK_END); * append in a more normal runtime *
	return iob_index(f);
}

int _read(int fildes, char *buf, unsigned nbyte)
{
	if (fildes >= OPEN_MAX)
		return 1;
	if (feof(_iob[fildes])) return 0;
	return fread(buf, 1, nbyte, _iob[fildes]);
}


int fWpStrip = 0;				* strip off WPDD format trailer *

int stat(char *str, struct stat *buf)
{
	int fh;
	char bufSect[512];
	struct {
	  char  rgbPada[92];
	  long  creDT;
	  long  modDT;
	  long  accDT;
	  char  rgbPadb[7];
	  long  lfaEof;
	  char  rgbPad2[327];
	  char  bMsDos;
	  char  parentFhb;
	} FHB;

	if(OpenFile(fh, str, strlen(str), NULL, 0, MODEREAD))
	{
		* get datetime stuff, get file size (lfaEof) *
		(void)memset(FHB, 0, sizeof(FHB));
		(void)GetFileStatus(fh, 7, FHB, sizeof(FHB));
		* strip WP formatting if desired *
		if (fWpStrip)
			(void)GetEofWp(fh, bufSect, FHB.lfaEof);
		(void)CloseFile(fh);
	}
	else
		return 1;
	buf>st_dev = 0;
	buf>st_ino = 0;
	* check if ClusterShare directory *
	if (FHB.bMsDos == CSDIR1  FHB.parentFhb == CSDIR2)
		buf>st_mode = 0666 | S_IFDIR;
	else
		buf>st_mode = 0666 | S_IFREG;
	buf>st_nlink = 1;
	buf>st_uid = 100;
	buf>st_gid = 100;
	buf>st_rdev = 0;
	buf>st_size = FHB.lfaEof;
	buf>st_atime = FHB.accDT;
	buf>st_mtime = FHB.modDT;
	buf>st_ctime = FHB.creDT;
	return 0;
}

int unlink(char* s)
{
	return remove(s) ? 1 : 0;
}

int _write(int fildes, char *buf, unsigned nbyte)
{
	int n;
	if (fildes >= OPEN_MAX)
		return 1;
	n = fwrite(buf, 1, nbyte, _iob[fildes]);
	if (ferror(_iob[fildes])) return 1;
	return n;
}

 *				    r+ and seek to end.
 *		71889		TAB Unlink to call remove().
 *		81489		RLN Return EOF if attempt to seek past EOF.
 *		81589		RLN In _read, check EOF before freading.
 *

define Syslit
define DeleteFi