primitiveDirectoryGetMacTypeAndCreator(void)
{
	// FilePlugin>>#primitiveDirectoryGetMacTypeAndCreator
    sqInt creatorString;
    char *creatorStringIndex;
    sqInt fileName;
    char *fileNameIndex;
    sqInt fileNameSize;
    sqInt okToGet;
    sqInt typeString;
    char *typeStringIndex;

	creatorString = stackValue(0);
	typeString = stackValue(1);
	fileName = stackValue(2);
	if (!((isBytes(creatorString))
		 && ((byteSizeOf(creatorString)) == 4))) {
		return primitiveFail();
	}
	if (!((isBytes(typeString))
		 && ((byteSizeOf(typeString)) == 4))) {
		return primitiveFail();
	}
	if (!(isBytes(fileName))) {
		return primitiveFail();
	}
	creatorStringIndex = firstIndexableField(creatorString);
	typeStringIndex = firstIndexableField(typeString);
	fileNameIndex = firstIndexableField(fileName);

	/* If the security plugin can be loaded, use it to check for permission.
	   If not, assume it's ok */

	fileNameSize = byteSizeOf(fileName);
	if (sCGFTfn != 0) {
		okToGet =  ((sqInt (*)(char *, sqInt))sCGFTfn)(fileNameIndex, fileNameSize);
		if (!okToGet) {
return primitiveFail();
		}
	}
	if (!(dir_GetMacFileTypeAndCreator(fileNameIndex, fileNameSize, typeStringIndex, creatorStringIndex))) {
		return primitiveFail();
	}
	pop(3);
}
sqInt
sqFileOpen(SQFile *f, char* sqFileName, sqInt sqFileNameSize, sqInt writeFlag) {
	/* Opens the given file using the supplied sqFile structure
	   to record its state. Fails with no side effects if f is
	   already open. Files are always opened in binary mode;
	   Squeak must take care of any line-end character mapping.
	*/

	char cFileName[PATH_MAX];

	/* don't open an already open file */
	if (sqFileValid(f))
		return interpreterProxy->success(false);

	/* copy the file name into a null-terminated C string */
	if (sqFileNameSize >= sizeof(cFileName))
		return interpreterProxy->success(false);
	/* can fail when alias resolution is enabled */
	if (interpreterProxy->ioFilenamefromStringofLengthresolveAliases(cFileName, sqFileName, sqFileNameSize, true) != 0)
		return interpreterProxy->success(false);

	if (writeFlag) {
		/* First try to open an existing file read/write: */
		setFile(f, fopen(cFileName, "r+b"));
		if (getFile(f) == NULL) {
			/* Previous call fails if file does not exist. In that case,
			   try opening it in write mode to create a new, empty file.
			*/
			setFile(f, fopen(cFileName, "w+b"));
			/* and if w+b fails, try ab to open a write-only file in append mode,
			   not wb which opens a write-only file but overwrites its contents.
			 */
			if (getFile(f) == NULL)
				setFile(f, fopen(cFileName, "ab"));
			if (getFile(f) != NULL) {
			    /* New file created, set Mac file characteristics */
			    char type[4],creator[4];
				dir_GetMacFileTypeAndCreator(sqFileName, sqFileNameSize, type, creator);
				if (strncmp(type,"BINA",4) == 0 || strncmp(type,"????",4) == 0 || *(int *)type == 0 ) 
				    dir_SetMacFileTypeAndCreator(sqFileName, sqFileNameSize,"TEXT","R*ch");	
			} else {
				/* If the file could not be opened read/write and if a new file
				   could not be created, then it may be that the file exists but
				   does not permit read access. Try opening as a write only file,
				   opened for append to preserve existing file contents.
				*/
				setFile(f, fopen(cFileName, "ab"));
				if (getFile(f) == NULL) {
					return interpreterProxy->success(false);
				}
			}
		}
		f->writable = true;
	} else {
		setFile(f, fopen(cFileName, "rb"));
		f->writable = false;
	}

	if (getFile(f) == NULL) {
		f->sessionID = 0;
		setSize(f, 0);
		return interpreterProxy->success(false);
	} else {
		FILE *file= getFile(f);
		f->sessionID = thisSession;
		/* compute and cache file size */
		fseek(file, 0, SEEK_END);
		setSize(f, ftell(file));
		fseek(file, 0, SEEK_SET);
	}
	f->lastOp = UNCOMMITTED;
	return 1;
}
sqInt sqFileOpen(SQFile *f, char* sqFileName, sqInt sqFileNameSize, sqInt writeFlag) {
	/* Opens the given file using the supplied sqFile structure
	   to record its state. Fails with no side effects if f is
	   already open. Files are always opened in binary mode;
	   Squeak must take care of any line-end character mapping.
	*/

	char cFileName[1001];

	/* don't open an already open file */
	if (sqFileValid(f)) return interpreterProxy->success(false);

	/* copy the file name into a null-terminated C string */
	if (sqFileNameSize > 1000) {
		return interpreterProxy->success(false);
	}

	if (setStdFilename("/dev/stdin", cFileName, sqFileName, sqFileNameSize)) 
	  setFile(f, stdin);
	else if (setStdFilename("/dev/stdout", cFileName, sqFileName, sqFileNameSize))
	  setFile(f, stdout);
	else if (setStdFilename("/dev/stderr", cFileName, sqFileName, sqFileNameSize))
	  setFile(f, stderr);
	else
	  interpreterProxy->ioFilenamefromStringofLengthresolveAliases(cFileName, sqFileName, sqFileNameSize, true);

	if (writeFlag) {
		/* First try to open an existing file read/write: */
		if (getFile(f) == NULL)
			setFile(f, fopen(cFileName, "r+b"));
		if (getFile(f) == NULL) {
			/* Previous call fails if file does not exist. In that case,
			   try opening it in write mode to create a new, empty file.
			*/
			setFile(f, fopen(cFileName, "w+b"));
			if (getFile(f) != NULL) {
			    char type[4],creator[4];
				dir_GetMacFileTypeAndCreator(sqFileName, sqFileNameSize, type, creator);
				if (strncmp(type,"BINA",4) == 0 || strncmp(type,"????",4) == 0 || *(int *)type == 0 ) 
				    dir_SetMacFileTypeAndCreator(sqFileName, sqFileNameSize,"TEXT","R*ch");	
			}
		}
		f->writable = true;
	} else {
		if (getFile(f) == NULL)
			setFile(f, fopen(cFileName, "rb"));
		f->writable = false;
	}

	if (getFile(f) == NULL) {
		f->sessionID = 0;
		setSize(f, 0);
		return interpreterProxy->success(false);
	} else {
		FILE *file= getFile(f);
		f->sessionID = thisSession;
		/* compute and cache file size */
		fseek(file, 0, SEEK_END);
		setSize(f, ftell(file));
		fseek(file, 0, SEEK_SET);
	}
	f->lastOp = UNCOMMITTED;
}