mirror of
https://github.com/ctm/executor.git
synced 2024-05-29 06:41:34 +00:00
1224 lines
29 KiB
C
1224 lines
29 KiB
C
/* Copyright 1986-1997 by Abacus Research and
|
|
* Development, Inc. All rights reserved.
|
|
*/
|
|
|
|
#if !defined (OMIT_RCSID_STRINGS)
|
|
char ROMlib_rcsid_fileMisc[] =
|
|
"$Id: fileMisc.c 86 2005-05-25 00:47:12Z ctm $";
|
|
#endif
|
|
|
|
/* Forward declarations in FileMgr.h (DO NOT DELETE THIS LINE) */
|
|
|
|
#include "rsys/common.h"
|
|
#include "QuickDraw.h"
|
|
#include "FileMgr.h"
|
|
#include "OSEvent.h"
|
|
#include "VRetraceMgr.h"
|
|
#include "OSUtil.h"
|
|
#include "MemoryMgr.h"
|
|
#include "StdFilePkg.h"
|
|
|
|
#include "rsys/hfs.h"
|
|
#include "rsys/file.h"
|
|
#include "rsys/notmac.h"
|
|
#include "rsys/stdfile.h"
|
|
#include "rsys/ini.h"
|
|
#include "rsys/string.h"
|
|
#include "rsys/custom.h"
|
|
#include "rsys/segment.h"
|
|
#include "rsys/suffix_maps.h"
|
|
|
|
#if defined (MSDOS) || defined (CYGWIN32)
|
|
#include "rsys/checkpoint.h"
|
|
#endif
|
|
|
|
#if !defined (CYGWIN32)
|
|
#include <pwd.h>
|
|
#else
|
|
#include "winfs.h"
|
|
#include "dosdisk.h"
|
|
#endif
|
|
|
|
#if defined(MSDOS)
|
|
#include <mntent.h>
|
|
#include <sys/vfs.h>
|
|
#include "aspi.h"
|
|
#endif
|
|
|
|
#include <ctype.h>
|
|
|
|
/* NOTE: calling most of the routines here is a sign that the user may
|
|
be depending on the internal layout of things a bit too much */
|
|
|
|
A0(PUBLIC trap, void, FInitQueue) /* IMIV-128 */
|
|
{
|
|
}
|
|
|
|
A0(PUBLIC trap, QHdrPtr, GetFSQHdr) /* IMIV-175 */
|
|
{
|
|
return(&FSQHdr); /* in UNIX domain, everything is synchronous */
|
|
}
|
|
|
|
A0(PUBLIC trap, QHdrPtr, GetVCBQHdr) /* IMIV-178 */
|
|
{
|
|
return(&VCBQHdr);
|
|
}
|
|
|
|
A0(PUBLIC trap, QHdrPtr, GetDrvQHdr) /* IMIV-182 */
|
|
{
|
|
return(&DrvQHdr);
|
|
}
|
|
|
|
A2(PUBLIC, OSErr, ufsPBGetFCBInfo, FCBPBPtr, pb, /* INTERNAL */
|
|
BOOLEAN, a)
|
|
{
|
|
int rn;
|
|
OSErr err;
|
|
fcbrec *fp;
|
|
int i, count;
|
|
|
|
#if !defined (LETGCCWAIL)
|
|
rn = -1;
|
|
fp = 0;
|
|
#endif /* LETGCCWAIL */
|
|
|
|
err = noErr;
|
|
if (pb->ioFCBIndx == 0) {
|
|
rn = Cx(pb->ioRefNum);
|
|
fp = PRNTOFPERR(rn, &err);
|
|
} else if (Cx(pb->ioFCBIndx) > 0) {
|
|
for (count = 0, i = 0; i < NFCB && count < Cx(pb->ioFCBIndx); i++)
|
|
if (ROMlib_fcblocks[i].fdfnum && (!pb->ioVRefNum ||
|
|
ROMlib_fcblocks[i].fcvptr->vcbVRefNum == pb->ioVRefNum))
|
|
count++;
|
|
if (count == Cx(pb->ioFCBIndx)) {
|
|
fp = ROMlib_fcblocks+i-1;
|
|
rn = (Ptr) fp - MR(FCBSPtr);
|
|
} else
|
|
err = paramErr;
|
|
} else
|
|
err = paramErr;
|
|
if (err == noErr) {
|
|
if (pb->ioNamePtr)
|
|
str255assign(MR(pb->ioNamePtr), fp->fcname);
|
|
pb->ioVRefNum = MR(fp->fcvptr)->vcbVRefNum;
|
|
pb->ioRefNum = CW(rn);
|
|
pb->ioFCBFlNm = fp->fdfnum;
|
|
pb->ioFCBFlags = (fp->fcflags << 8) | (unsigned char)fp->fcbTypByt;
|
|
pb->ioFCBStBlk = 0;
|
|
pb->ioFCBEOF = fp->fcleof;
|
|
pb->ioFCBPLen = fp->fcleof;
|
|
pb->ioFCBCrPs = lseek(fp->fcfd, 0, L_INCR) - FORKOFFSET(fp);
|
|
pb->ioFCBVRefNum = MR(fp->fcvptr)->vcbVRefNum; /* what's this? */
|
|
pb->ioFCBClpSiz = MR(fp->fcvptr)->vcbClpSiz;
|
|
pb->ioFCBParID = fp->fcparid;
|
|
}
|
|
return err;
|
|
}
|
|
|
|
#if 0 && defined (MSDOS)
|
|
#define slashstrcmp strcmp
|
|
#else
|
|
|
|
PRIVATE boolean_t
|
|
charcmp (char c1, char c2)
|
|
{
|
|
boolean_t retval;
|
|
|
|
if (c1 == c2)
|
|
retval = TRUE;
|
|
else if (c1 == '/')
|
|
retval = c2 == '\\';
|
|
else if (c1 == '\\')
|
|
retval = c2 == '/';
|
|
else
|
|
retval = tolower (c1) == tolower (c2);
|
|
return retval;
|
|
}
|
|
|
|
PRIVATE int
|
|
slashstrcmp (const char *p1, const char *p2)
|
|
{
|
|
int retval;
|
|
|
|
retval = 0;
|
|
|
|
while (*p1 || *p2)
|
|
{
|
|
if (!charcmp (*p1, *p2))
|
|
{
|
|
retval = -1;
|
|
break;
|
|
}
|
|
++p1;
|
|
++p2;
|
|
}
|
|
return retval;
|
|
}
|
|
#endif
|
|
|
|
PRIVATE INTEGER ROMlib_driveno = 3;
|
|
PRIVATE INTEGER ROMlib_ejdriveno = 2;
|
|
|
|
/*
|
|
* NOTE: The way we handle drive information is pretty messed up right now.
|
|
* In general the correct information is in the VCBExtra; we only recently
|
|
* began putting it in the DriveExtra and right now we only use the info
|
|
* in the DriveExtra to allow us to format floppies -- no other formatting
|
|
* is currently permitted. The problem is there's no easy way to map drive
|
|
* characteristics from the non-Mac host into Mac type information unless
|
|
* we can pull the information out of the Mac filesystem.
|
|
*/
|
|
|
|
PUBLIC DrvQExtra *
|
|
ROMlib_addtodq (ULONGINT drvsize, const char *devicename, INTEGER partition,
|
|
INTEGER drefnum, drive_flags_t flags, hfs_access_t *hfsp)
|
|
{
|
|
INTEGER dno;
|
|
DrvQExtra *dqp;
|
|
DrvQEl *dp;
|
|
int strl;
|
|
THz saveZone;
|
|
static boolean_t seen_floppy = FALSE;
|
|
|
|
saveZone = TheZone;
|
|
TheZone = SysZone;
|
|
#if !defined(LETGCCWAIL)
|
|
dqp = (DrvQExtra *) 0;
|
|
#endif
|
|
dno = 0;
|
|
for (dp = (DrvQEl *) MR(DrvQHdr.qHead); dp; dp = (DrvQEl *) MR(dp->qLink)) {
|
|
dqp = (DrvQExtra *) ((char *)dp - sizeof(LONGINT));
|
|
if (dqp->partition == CW(partition) &&
|
|
slashstrcmp((char *) dqp->devicename, devicename) == 0) {
|
|
dno = Cx(dqp->dq.dQDrive);
|
|
/*-->*/ break;
|
|
}
|
|
}
|
|
if (!dno) {
|
|
if ((flags & DRIVE_FLAGS_FLOPPY) && !seen_floppy)
|
|
{
|
|
dno = 1;
|
|
seen_floppy = TRUE;
|
|
}
|
|
else
|
|
{
|
|
if ((flags & DRIVE_FLAGS_FIXED) || ROMlib_ejdriveno == 3)
|
|
dno = ROMlib_driveno++;
|
|
else
|
|
dno = ROMlib_ejdriveno++;
|
|
}
|
|
dqp = (DrvQExtra *) NewPtr(sizeof(DrvQExtra));
|
|
dqp->flags = CL(1 << 7); /* is not single sided */
|
|
if (flags & DRIVE_FLAGS_LOCKED)
|
|
dqp->flags = CL(CL(dqp->flags) | 1L << 31);
|
|
if (flags & DRIVE_FLAGS_FIXED)
|
|
dqp->flags = CL(CL(dqp->flags) | 8L << 16);
|
|
else
|
|
dqp->flags = CL(CL(dqp->flags) | 2); /* IMIV-181 says
|
|
it can be 1 or 2 */
|
|
|
|
/* dqp->dq.qLink will be set up when we Enqueue this baby */
|
|
dqp->dq.dQDrvSz = CW(drvsize);
|
|
dqp->dq.dQDrvSz2 = CW(drvsize>>16);
|
|
dqp->dq.qType = CWC(1);
|
|
dqp->dq.dQDrive = CW(dno);
|
|
dqp->dq.dQRefNum = CW(drefnum);
|
|
dqp->dq.dQFSID = 0;
|
|
if (!devicename)
|
|
dqp->devicename = 0;
|
|
else {
|
|
strl = strlen(devicename);
|
|
dqp->devicename = NewPtr(strl + 1);
|
|
strcpy((char *) dqp->devicename, devicename);
|
|
}
|
|
dqp->partition = CW(partition);
|
|
if (hfsp)
|
|
dqp->hfs = *hfsp;
|
|
else
|
|
{
|
|
memset (&dqp->hfs, 0, sizeof (dqp->hfs));
|
|
dqp->hfs.fd = -1;
|
|
}
|
|
Enqueue((QElemPtr) &dqp->dq, &DrvQHdr);
|
|
}
|
|
TheZone = saveZone;
|
|
return dqp;
|
|
}
|
|
|
|
PRIVATE boolean_t
|
|
root_directory_p(char *path, dev_t our_dev)
|
|
{
|
|
char *slash;
|
|
boolean_t retval;
|
|
|
|
/* we used to just compare our_inode to 2, but that doesn't work with
|
|
NFS mounted filesystems that aren't mounted at the root directory or
|
|
with DOS filesystems mounted under Linux */
|
|
|
|
slash = strrchr(path, '/');
|
|
if (!slash || ((slash == path + SLASH_CHAR_OFFSET) && !slash[1]))
|
|
retval = TRUE;
|
|
else
|
|
{
|
|
struct stat sbuf;
|
|
char save_char;
|
|
|
|
if (slash == path + SLASH_CHAR_OFFSET)
|
|
++slash;
|
|
save_char = *slash;
|
|
*slash = 0;
|
|
if (Ustat(path, &sbuf) != 0)
|
|
retval = TRUE;
|
|
else
|
|
retval = sbuf.st_dev != our_dev;
|
|
*slash = save_char;
|
|
}
|
|
return retval;
|
|
}
|
|
|
|
/*
|
|
* ROMlib_volumename is a magic global variable that tells MountVol
|
|
* the name of the volume that you're mounting (since there is no
|
|
* way to map the "drive number" into such a string)
|
|
*/
|
|
|
|
PUBLIC char *ROMlib_volumename;
|
|
|
|
PRIVATE void ROMlib_automount_helper(char *path, char *aliasp)
|
|
{
|
|
struct stat sbuf;
|
|
char *oldsavep, *savep, save;
|
|
ParamBlockRec pb;
|
|
int sret;
|
|
int i;
|
|
LONGINT dirid;
|
|
INTEGER retval;
|
|
HVCB *vcbp;
|
|
DrvQExtra *dqp;
|
|
|
|
#if defined(MSDOS)
|
|
char *newpath;
|
|
#endif
|
|
|
|
#if defined (MSDOS) || defined (CYGWIN32)
|
|
{
|
|
char *temppath, *op, c;
|
|
int len;
|
|
|
|
len = strlen (path) + 1;
|
|
|
|
/* If we don't have x:/ then we need to prepend the start drive */
|
|
if (path[0] && (path[1] != ':' || path[2] != '/'))
|
|
len += 2;
|
|
temppath = alloca (len);
|
|
if (path[0] && (path[1] != ':' || path[2] != '/'))
|
|
{
|
|
temppath[0] = ROMlib_start_drive;
|
|
temppath[1] = ':';
|
|
temppath += 2;
|
|
}
|
|
|
|
/* convert backslashes to slashes */
|
|
op = temppath;
|
|
while ((c = *path++))
|
|
*op++ = c == '\\' ? '/' : c;
|
|
*op = 0;
|
|
path = temppath;
|
|
}
|
|
#endif
|
|
|
|
retval = 0;
|
|
#if !defined(LETGCCWAIL)
|
|
save = 0;
|
|
#endif
|
|
if (path[0] == '/'
|
|
#if defined(MSDOS) || defined (CYGWIN32)
|
|
|| (path[1] == ':' && path[2] == '/')
|
|
#endif
|
|
)
|
|
{
|
|
#if !defined(MSDOS) || defined (CYGWIN32)
|
|
ROMlib_undotdot(path);
|
|
#else
|
|
newpath = alloca(strlen(path) + 3); /* one for null, two for drive */
|
|
_fixpath(path, newpath);
|
|
path = newpath;
|
|
#endif
|
|
/* Make two passes: On the first pass (i == 0) we identify
|
|
filesystems and mount them. On the second pass (i == 1) we
|
|
store away intermediate directory numbers */
|
|
|
|
for (i = 0; i < 2; ++i) {
|
|
boolean_t done;
|
|
sret = Ustat(path, &sbuf);
|
|
savep = 0;
|
|
oldsavep = 0;
|
|
done = FALSE;
|
|
do {
|
|
if (sret == 0 && S_ISDIR (sbuf.st_mode)) {
|
|
if (root_directory_p (path, sbuf.st_dev) || aliasp) {
|
|
if (i == 0) {
|
|
ROMlib_volumename = path;
|
|
dqp = ROMlib_addtodq(2048L * 50,
|
|
ROMlib_volumename, 0,
|
|
OURUFSDREF,
|
|
DRIVE_FLAGS_FIXED, 0);
|
|
pb.ioParam.ioVRefNum = dqp->dq.dQDrive;
|
|
ufsPBMountVol(&pb);
|
|
if (aliasp)
|
|
{
|
|
HVCB *vcbp;
|
|
|
|
vcbp =
|
|
ROMlib_vcbbyvrn (CW (pb.ioParam.ioVRefNum));
|
|
str255_from_c_string (vcbp->vcbVN, aliasp);
|
|
/* hack in name */
|
|
/*-->*/ return;
|
|
}
|
|
}
|
|
} else {
|
|
if (i == 1) {
|
|
vcbp = ROMlib_vcbbybiggestunixname(path);
|
|
gui_assert(vcbp);
|
|
dirid = ST_INO (sbuf);
|
|
ROMlib_dbm_store((VCBExtra *) vcbp, path, &dirid,
|
|
FALSE);
|
|
}
|
|
}
|
|
}
|
|
if (savep == path + SLASH_CHAR_OFFSET + 1)
|
|
done = TRUE;
|
|
else
|
|
{
|
|
savep = strrchr(path, '/');
|
|
if (savep == path + SLASH_CHAR_OFFSET)
|
|
++savep;
|
|
if (oldsavep)
|
|
*oldsavep = save;
|
|
save = *savep;
|
|
*savep = 0;
|
|
oldsavep = savep;
|
|
sret = Ustat(path, &sbuf);
|
|
}
|
|
} while (!done);
|
|
if (oldsavep)
|
|
*oldsavep = save;
|
|
}
|
|
}
|
|
}
|
|
|
|
PUBLIC void ROMlib_automount(char *path)
|
|
{
|
|
ROMlib_automount_helper (path, NULL);
|
|
}
|
|
|
|
PUBLIC void ROMlib_volume_alias (const char *path, const char *alias_name)
|
|
{
|
|
ROMlib_automount_helper ((char *) path, (char *) alias_name);
|
|
}
|
|
|
|
char *combine_str(const char *str1, const char *str2)
|
|
{
|
|
int len1;
|
|
char *retval;
|
|
|
|
if (!str1 || !str2)
|
|
return 0;
|
|
len1 = strlen(str1);
|
|
retval = malloc(len1 + strlen(str2) + 1);
|
|
strcpy(retval, str1);
|
|
strcpy(retval + len1, str2);
|
|
return retval;
|
|
}
|
|
|
|
PUBLIC void
|
|
convert_slashs_to_backslashs (char *p)
|
|
{
|
|
if (p)
|
|
{
|
|
while (*p)
|
|
{
|
|
if (*p == '/')
|
|
*p = '\\';
|
|
++p;
|
|
}
|
|
}
|
|
}
|
|
|
|
#if defined (LINUX)
|
|
|
|
PRIVATE char *
|
|
substr (const char *source_string,
|
|
const char *source_substring,
|
|
const char *dest_substring)
|
|
{
|
|
int source_string_len;
|
|
int source_substring_len;
|
|
int dest_substring_len;
|
|
int max_len;
|
|
char *retval;
|
|
|
|
source_string_len = strlen (source_string);
|
|
source_substring_len = strlen (source_substring);
|
|
dest_substring_len = strlen (dest_substring);
|
|
if (dest_substring_len > source_substring_len)
|
|
max_len = ((source_string_len + source_substring_len - 1) /
|
|
source_substring_len * dest_substring_len) + 1;
|
|
else
|
|
max_len = source_string_len + 1;
|
|
retval = malloc (max_len);
|
|
if (retval)
|
|
{
|
|
const char *ip;
|
|
char *op;
|
|
|
|
for (op = retval, ip = source_string; *ip; )
|
|
{
|
|
if (strncmp (ip, source_substring, source_substring_len) != 0)
|
|
*op++ = *ip++;
|
|
else
|
|
{
|
|
memcpy (op, dest_substring, dest_substring_len);
|
|
ip += source_substring_len;
|
|
op += dest_substring_len;
|
|
}
|
|
}
|
|
*op = 0;
|
|
}
|
|
return retval;
|
|
}
|
|
|
|
PRIVATE char *
|
|
convert_executors_to_appnames (char *str)
|
|
{
|
|
char *retval;
|
|
int appname_len;
|
|
char *appname;
|
|
char *dash;
|
|
|
|
if (!str)
|
|
retval = NULL;
|
|
else
|
|
{
|
|
appname_len = strlen (ROMlib_appname);
|
|
appname = alloca (appname_len + 1);
|
|
memcpy (appname, ROMlib_appname, appname_len + 1);
|
|
dash = strchr (appname, '-');
|
|
if (dash)
|
|
*dash = 0;
|
|
if (strcmp (appname, "executor") == 0)
|
|
retval = str;
|
|
else
|
|
{
|
|
retval = substr (str, "executor", appname);
|
|
if (retval)
|
|
free (str);
|
|
else
|
|
retval = str;
|
|
}
|
|
}
|
|
return retval;
|
|
}
|
|
#endif
|
|
|
|
PUBLIC char *
|
|
copystr (const char *name)
|
|
{
|
|
char *retval;
|
|
|
|
if (!name)
|
|
retval = 0;
|
|
else
|
|
{
|
|
switch (name[0])
|
|
{
|
|
case '+':
|
|
#if !defined(LINUX)
|
|
retval = combine_str(ROMlib_startdir, name+1);
|
|
#else
|
|
retval = combine_str("/home/executor", name+1);
|
|
#endif
|
|
break;
|
|
#if !defined (CYGWIN32)
|
|
case '~':
|
|
{
|
|
struct passwd *pwp;
|
|
|
|
#if defined (LINUX)
|
|
{
|
|
char *home;
|
|
|
|
home = getenv ("HOME");
|
|
if (home)
|
|
{
|
|
retval = combine_str (home, name+1);
|
|
break;
|
|
}
|
|
}
|
|
#endif
|
|
pwp = getpwuid(getuid());
|
|
if (pwp)
|
|
{
|
|
retval = combine_str(pwp->pw_dir, name+1);
|
|
break;
|
|
}
|
|
}
|
|
/* FALL THROUGH */
|
|
#endif
|
|
default:
|
|
retval = combine_str("", name);
|
|
break;
|
|
}
|
|
}
|
|
|
|
#if defined (MSDOS) || defined (CYGWIN32)
|
|
convert_slashs_to_backslashs (retval);
|
|
#endif
|
|
|
|
#if defined (LINUX)
|
|
retval = convert_executors_to_appnames (retval);
|
|
#endif
|
|
|
|
return retval;
|
|
}
|
|
|
|
#if defined (MSDOS) || defined (CYGWIN32)
|
|
PUBLIC boolean_t cd_mounted_by_trickery_p = FALSE;
|
|
|
|
#define MACCDROM \
|
|
(ROMlib_mac_cdromp ? (char *) ROMlib_mac_cdromp->chars : \
|
|
"DOS/EXTRA/LIBRARY/MACCDROM.HFV")
|
|
|
|
#if defined (MSDOS) || defined (CYGWIN32)
|
|
PRIVATE char *cd_big_hfv = 0;
|
|
|
|
PRIVATE void
|
|
check_for_executor_cd (const char *drive)
|
|
{
|
|
if (!cd_big_hfv)
|
|
{
|
|
struct stat sbuf;
|
|
|
|
cd_big_hfv = malloc (strlen (drive) + strlen (MACCDROM) + 1);
|
|
sprintf (cd_big_hfv, "%s%s", drive, MACCDROM);
|
|
if (stat (cd_big_hfv, &sbuf) != 0)
|
|
{
|
|
free (cd_big_hfv);
|
|
cd_big_hfv = 0;
|
|
}
|
|
}
|
|
}
|
|
|
|
PRIVATE boolean_t
|
|
e2_is_mounted (void)
|
|
{
|
|
boolean_t retval;
|
|
const char e2_name[] = "Executor2";
|
|
|
|
retval = !!vlookupbyname (e2_name, e2_name + strlen (e2_name));
|
|
return retval;
|
|
}
|
|
#endif
|
|
|
|
#endif
|
|
|
|
|
|
PUBLIC StringPtr ROMlib_exefname;
|
|
PUBLIC char *ROMlib_exeuname;
|
|
|
|
PUBLIC char *ROMlib_ConfigurationFolder;
|
|
PUBLIC char *ROMlib_SystemFolder;
|
|
PUBLIC char *ROMlib_DefaultFolder;
|
|
PUBLIC char *ROMlib_PublicDirectoryMap;
|
|
PUBLIC char *ROMlib_PrivateDirectoryMap;
|
|
PUBLIC char *ROMlib_ExcelApp;
|
|
PUBLIC char *ROMlib_WordApp;
|
|
PUBLIC char *ROMlib_MacVolumes;
|
|
PUBLIC char *ROMlib_ScreenDumpFile;
|
|
PRIVATE char *ROMlib_OffsetFile;
|
|
|
|
PUBLIC LONGINT ROMlib_magic_offset = -1;
|
|
|
|
PRIVATE void
|
|
skip_comments (FILE *fp)
|
|
{
|
|
int c;
|
|
|
|
while ((c = getc (fp)) == '#')
|
|
{
|
|
while (c != '\n')
|
|
c = getc (fp);
|
|
}
|
|
ungetc (c, fp);
|
|
}
|
|
|
|
PRIVATE void
|
|
parse_offset_file (void)
|
|
{
|
|
FILE *fp;
|
|
|
|
fp = Ufopen (ROMlib_OffsetFile, "r");
|
|
if (!fp)
|
|
{
|
|
#if 0
|
|
warning_unexpected ("Couldn't open \"%s\"", ROMlib_OffsetFile);
|
|
#endif
|
|
}
|
|
else
|
|
{
|
|
int n_found;
|
|
|
|
skip_comments (fp);
|
|
n_found = fscanf (fp, "0x%08x", &ROMlib_magic_offset);
|
|
if (n_found != 1)
|
|
warning_unexpected ("n_found = %d", n_found);
|
|
fclose (fp);
|
|
}
|
|
}
|
|
|
|
#if defined (MSDOS)
|
|
|
|
PRIVATE uint32
|
|
drive_char_to_bit (char c)
|
|
{
|
|
uint32 retval;
|
|
|
|
if (c >= 'a' && c <= 'z')
|
|
retval = 1 << (c - 'a');
|
|
else if (c >= 'A' && c <= 'Z')
|
|
retval = 1 << (c - 'A');
|
|
else
|
|
retval = 0;
|
|
return retval;
|
|
}
|
|
#endif
|
|
|
|
PRIVATE boolean_t
|
|
is_unix_path (const char *pathname)
|
|
{
|
|
boolean_t retval;
|
|
|
|
#if defined(MSDOS) || defined (CYGWIN32)
|
|
if (pathname[0] && pathname[1] == ':' && (pathname[2] == '/' ||
|
|
pathname[2] == '\\'))
|
|
pathname += 3;
|
|
#endif
|
|
retval = strchr (pathname, ':') == 0;
|
|
return retval;
|
|
}
|
|
|
|
A0(PUBLIC, void, ROMlib_fileinit) /* INTERNAL */
|
|
{
|
|
INTEGER i;
|
|
CInfoPBRec cpb;
|
|
WDPBRec wpb;
|
|
INTEGER wdlen;
|
|
HVCB *vcbp;
|
|
LONGINT m;
|
|
THz savezone;
|
|
struct stat sbuf;
|
|
char *sysname;
|
|
int sysnamelen;
|
|
char *p, *ep, *newp;
|
|
static struct dangerstr { /* DANGER DANGER DANGER */
|
|
char *name; /* this is taken from <defaults.h> */
|
|
char *value; /* instead of us including it ... */
|
|
} defvec[] = { /* if <defaults.h> changes we're SOL */
|
|
#if defined (LINUX)
|
|
{"ConfigurationFolder", "/var/opt/executor/share/conf"},
|
|
{"SystemFolder", "/home/executor/System Folder"},
|
|
{"PublicDirectoryMap", "/var/opt/executor/directory_map"},
|
|
{"PrivateDirectoryMap", "~/.executor/directory_map"},
|
|
{"DefaultFolder", "/home/executor"},
|
|
{"ExcelApp", "/home/executor/Excel/Microsoft Excel.appl"},
|
|
{"WordApp", "/home/executor/Word/Microsoft Word.appl"},
|
|
{"MacVolumes", "/var/opt/executor/exsystem.hfv;/var/opt/executor"},
|
|
{"ScreenDumpFile", "/tmp/excscrn*.tiff"},
|
|
{"OffsetFile", "/opt/executor/offset_file"},
|
|
{"PrintersIni", "/opt/executor/printers.ini"},
|
|
{"PrintDef", "/var/opt/executor/printdef.ini"},
|
|
|
|
{NULL, "/home/executor.afpd/System Folder"},
|
|
{NULL, "/home/executor.afpd"},
|
|
{NULL, "/home/executor.afpd/Excel/Microsoft Excel.appl"},
|
|
{NULL, "/home/executor.afpd/Word/Microsoft Word.appl"},
|
|
|
|
|
|
#elif !defined(MSDOS) && !defined (CYGWIN32)
|
|
{"ConfigurationFolder", "+/Configuration"},
|
|
{"SystemFolder", "+/ExecutorVolume/System Folder"},
|
|
{"PublicDirectoryMap", "+/DirectoryMap"},
|
|
{"PrivateDirectoryMap", "~/.Executor/DirectoryMap"},
|
|
{"DefaultFolder", "+/ExecutorVolume"},
|
|
{"ExcelApp", "+/ExecutorVolume/Excel/Microsoft Excel.appl"},
|
|
{"WordApp", "+/ExecutorVolume/Word/Microsoft Word.appl"},
|
|
{"MacVolumes", "+/exsystem.hfv;+"},
|
|
{"ScreenDumpFile", "/tmp/excscrn*.tif"},
|
|
{"OffsetFile", "+/offset_file"},
|
|
{"PrintersIni", "+/printers.ini"},
|
|
{"PrintDef", "+/printdef.ini"},
|
|
#else /* defined(MSDOS) || defined (CYGWIN32) */
|
|
{"CONFIGURATIONFOLDER", "+/configur"},
|
|
|
|
#if defined (MSDOS)
|
|
{"SYSTEMFOLDER", "System:System Folder"},
|
|
#else
|
|
{"SYSTEMFOLDER", "+/Apps/System Folder"},
|
|
#endif
|
|
|
|
{"PUBLICDIRECTORYMAP", "+/dirMap"},
|
|
{"PRIVATEDIRECTORYMAP", "~/.executor/directorymap"},
|
|
|
|
#if defined (MSDOS)
|
|
{"DEFAULTFOLDER", "System:"},
|
|
#else
|
|
{"DEFAULTFOLDER", "+/Apps"},
|
|
#endif
|
|
|
|
{"EXCELAPP", "User:Excel:Microsoft Excel"},
|
|
{"WORDAPP", "User:Word:Microsoft Word"},
|
|
{"MACVOLUMES", "+/exsystem.hfv;+"},
|
|
{"SCREENDUMPFILE", "+"},
|
|
{"OFFSETFILE", "+/offset.txt"},
|
|
{"PRINTERSINI", "+/printers.ini"},
|
|
{"PRINTDEF", "+/printdef.ini"},
|
|
#endif /* defined(MSDOS) */
|
|
{0, 0},
|
|
};
|
|
|
|
#if !defined (LINUX)
|
|
#define AFPD(m,n) (m)
|
|
#else
|
|
#define AFPD(m,n) (afpd_conventions_p ? (n) : (m))
|
|
#endif
|
|
|
|
#define CONFIGURATIONFOLDER defvec[0].name
|
|
#define SYSTEMFOLDER defvec[1].name
|
|
#define PUBLICDIRECTORYMAP defvec[2].name
|
|
#define PRIVATEDIRECTORYMAP defvec[3].name
|
|
#define DEFAULTFOLDER defvec[4].name
|
|
#define EXCELAPP defvec[5].name
|
|
#define WORDAPP defvec[6].name
|
|
#define MACVOLUMES defvec[7].name
|
|
#define SCREENDUMPFILE defvec[8].name
|
|
#define OFFSETFILE defvec[9].name
|
|
#define PRINTERSINI defvec[10].name
|
|
#define PRINTDEF defvec[11].name
|
|
|
|
#define CONFIGURATIONFOLDER_DEF defvec[0].value
|
|
#define SYSTEMFOLDER_DEF defvec[AFPD (1, 12)].value
|
|
#define PUBLICDIRECTORYMAP_DEF defvec[2].value
|
|
#define PRIVATEDIRECTORYMAP_DEF defvec[3].value
|
|
#define DEFAULTFOLDER_DEF defvec[AFPD (4, 13)].value
|
|
#define EXCELAPP_DEF defvec[AFPD (5, 14)].value
|
|
#define WORDAPP_DEF defvec[AFPD (6, 15)].value
|
|
#define MACVOLUMES_DEF defvec[7].value
|
|
#define SCREENDUMPFILE_DEF defvec[8].value
|
|
#define OFFSETFILE_DEF defvec[9].value
|
|
#define PRINTERSINI_DEF defvec[10].value
|
|
#define PRINTDEF_DEF defvec[11].value
|
|
|
|
CurDirStore = CLC(2);
|
|
|
|
savezone = TheZone;
|
|
TheZone = SysZone;
|
|
FCBSPtr = RM(NewPtr((Size) sizeof(fcbhidden)));
|
|
((fcbhidden *)MR(FCBSPtr))->nbytes = CW(sizeof(fcbhidden));
|
|
|
|
for (i = 0 ; i < NFCB ; i++) {
|
|
ROMlib_fcblocks[i].fdfnum = 0;
|
|
ROMlib_fcblocks[i].fcleof = i + 1;
|
|
ROMlib_fcblocks[i].fcbTypByt = 0;
|
|
ROMlib_fcblocks[i].fcbSBlk = 0;
|
|
ROMlib_fcblocks[i].fcPLen = 0;
|
|
ROMlib_fcblocks[i].fcbCrPs = 0;
|
|
ROMlib_fcblocks[i].fcbBfAdr = 0;
|
|
ROMlib_fcblocks[i].fcbFlPos = 0;
|
|
ROMlib_fcblocks[i].fcbClmpSize = CLC(1);
|
|
ROMlib_fcblocks[i].fcbFType = 0;
|
|
ROMlib_fcblocks[i].zero[0] = 0;
|
|
ROMlib_fcblocks[i].zero[1] = 0;
|
|
ROMlib_fcblocks[i].zero[2] = 0;
|
|
ROMlib_fcblocks[i].fcname[0] = 0;
|
|
}
|
|
ROMlib_fcblocks[NFCB-1].fcleof = -1;
|
|
|
|
#define NWDENTRIES 40
|
|
wdlen = NWDENTRIES * sizeof(wdentry) + sizeof(INTEGER);
|
|
WDCBsPtr = RM(NewPtr((Size) wdlen));
|
|
TheZone = savezone;
|
|
memset (MR(WDCBsPtr), 0, wdlen);
|
|
*(INTEGER *)MR(WDCBsPtr) = CW(wdlen);
|
|
|
|
ROMlib_ConfigurationFolder = copystr(getenv(CONFIGURATIONFOLDER));
|
|
ROMlib_SystemFolder = copystr(getenv(SYSTEMFOLDER));
|
|
ROMlib_PublicDirectoryMap = copystr(getenv(PUBLICDIRECTORYMAP));
|
|
ROMlib_PrivateDirectoryMap = copystr(getenv(PRIVATEDIRECTORYMAP));
|
|
ROMlib_DefaultFolder = copystr(getenv(DEFAULTFOLDER));
|
|
ROMlib_ExcelApp = copystr(getenv(EXCELAPP));
|
|
ROMlib_WordApp = copystr(getenv(WORDAPP));
|
|
ROMlib_MacVolumes = copystr(getenv(MACVOLUMES));
|
|
ROMlib_ScreenDumpFile = copystr(getenv(SCREENDUMPFILE));
|
|
ROMlib_OffsetFile = copystr(getenv(OFFSETFILE));
|
|
ROMlib_PrintersIni = copystr(getenv(PRINTERSINI));
|
|
ROMlib_PrintDef = copystr(getenv(PRINTDEF));
|
|
|
|
#if defined(NEXTSTEP)
|
|
NXRegisterDefaults(ROMlib_appname, defvec);
|
|
|
|
if (!ROMlib_ConfigurationFolder)
|
|
ROMlib_ConfigurationFolder =
|
|
copystr(NXGetDefaultValue(ROMlib_appname, CONFIGURATIONFOLDER));
|
|
if (!ROMlib_SystemFolder)
|
|
ROMlib_SystemFolder =
|
|
copystr(NXGetDefaultValue(ROMlib_appname, SYSTEMFOLDER));
|
|
if (!ROMlib_PublicDirectoryMap)
|
|
ROMlib_PublicDirectoryMap =
|
|
copystr(NXGetDefaultValue(ROMlib_appname, PUBLICDIRECTORYMAP));
|
|
if (!ROMlib_PrivateDirectoryMap)
|
|
ROMlib_PrivateDirectoryMap =
|
|
copystr(NXGetDefaultValue(ROMlib_appname, PRIVATEDIRECTORYMAP));
|
|
if (!ROMlib_DefaultFolder)
|
|
ROMlib_DefaultFolder =
|
|
copystr(NXGetDefaultValue(ROMlib_appname, DEFAULTFOLDER));
|
|
if (!ROMlib_ExcelApp)
|
|
ROMlib_ExcelApp =
|
|
copystr(NXGetDefaultValue(ROMlib_appname, EXCELAPP));
|
|
if (!ROMlib_WordApp)
|
|
ROMlib_WordApp =
|
|
copystr(NXGetDefaultValue(ROMlib_appname, WORDAPP));
|
|
if (!ROMlib_MacVolumes)
|
|
ROMlib_MacVolumes =
|
|
copystr(NXGetDefaultValue(ROMlib_appname, MACVOLUMES));
|
|
if (!ROMlib_ScreenDumpFile)
|
|
ROMlib_ScreenDumpFile =
|
|
copystr(NXGetDefaultValue(ROMlib_appname, SCREENDUMPFILE));
|
|
if (!ROMlib_OffsetFile)
|
|
ROMlib_OffsetFile =
|
|
copystr(NXGetDefaultValue(ROMlib_appname, OFFSETFILE));
|
|
if (!ROMlib_PrintersIni)
|
|
ROMlib_PrintersIni =
|
|
copystr(NXGetDefaultValue(ROMlib_appname, PRINTERSINI));
|
|
if (!ROMlib_PrintDef)
|
|
ROMlib_PrintDef =
|
|
copystr(NXGetDefaultValue(ROMlib_appname, PRINTDEF));
|
|
#else
|
|
if (!ROMlib_ConfigurationFolder)
|
|
ROMlib_ConfigurationFolder = copystr(CONFIGURATIONFOLDER_DEF);
|
|
if (!ROMlib_SystemFolder)
|
|
ROMlib_SystemFolder = copystr(SYSTEMFOLDER_DEF);
|
|
if (!ROMlib_PublicDirectoryMap)
|
|
ROMlib_PublicDirectoryMap = copystr(PUBLICDIRECTORYMAP_DEF);
|
|
if (!ROMlib_PrivateDirectoryMap)
|
|
ROMlib_PrivateDirectoryMap = copystr(PRIVATEDIRECTORYMAP_DEF);
|
|
if (!ROMlib_DefaultFolder)
|
|
ROMlib_DefaultFolder = copystr(DEFAULTFOLDER_DEF);
|
|
if (!ROMlib_ExcelApp)
|
|
ROMlib_ExcelApp = copystr(EXCELAPP_DEF);
|
|
if (!ROMlib_WordApp)
|
|
ROMlib_WordApp = copystr(WORDAPP_DEF);
|
|
if (!ROMlib_MacVolumes)
|
|
ROMlib_MacVolumes = copystr(MACVOLUMES_DEF);
|
|
if (!ROMlib_ScreenDumpFile)
|
|
ROMlib_ScreenDumpFile = copystr(SCREENDUMPFILE_DEF);
|
|
if (!ROMlib_OffsetFile)
|
|
ROMlib_OffsetFile = copystr(OFFSETFILE_DEF);
|
|
if (!ROMlib_PrintersIni)
|
|
ROMlib_PrintersIni = copystr(PRINTERSINI_DEF);
|
|
if (!ROMlib_PrintDef)
|
|
ROMlib_PrintDef = copystr(PRINTDEF_DEF);
|
|
#endif
|
|
|
|
parse_offset_file ();
|
|
|
|
/*
|
|
* NOTE: The following is a hack that will remain in place until we have
|
|
* a replacement for using the ndbm routines which apparently can't
|
|
* share files between machines of different endianness.
|
|
*/
|
|
|
|
#if defined(LITTLEENDIAN)
|
|
|
|
#define STR_APPEND(str, suffix) \
|
|
{ \
|
|
char *str2; \
|
|
\
|
|
str2 = malloc(strlen(str) + strlen(suffix) + 1); \
|
|
sprintf(str2, "%s%s", str, suffix); \
|
|
str = str2; \
|
|
}
|
|
|
|
#define LITTLE_ENDIAN_SUFFIX "-le"
|
|
|
|
STR_APPEND(ROMlib_PublicDirectoryMap, LITTLE_ENDIAN_SUFFIX);
|
|
STR_APPEND(ROMlib_PrivateDirectoryMap, LITTLE_ENDIAN_SUFFIX);
|
|
|
|
#endif /* defined(LITTLEENDIAN) */
|
|
|
|
ROMlib_hfsinit();
|
|
ROMlib_automount(ROMlib_SystemFolder);
|
|
|
|
#if 0
|
|
m = 0;
|
|
if (Ustat(ROMlib_DefaultFolder, &sbuf) == 0)
|
|
if ((sbuf.st_mode & S_IFMT) == S_IFREG)
|
|
ROMlib_openharddisk(ROMlib_DefaultFolder, &m);
|
|
#else
|
|
m = 0;
|
|
p = ROMlib_MacVolumes;
|
|
while (p && *p) {
|
|
ep = strchr(p, ';');
|
|
if (ep)
|
|
*ep = 0;
|
|
newp = copystr(p);
|
|
if (Ustat(newp, &sbuf) == 0)
|
|
{
|
|
if (! S_ISDIR (sbuf.st_mode))
|
|
ROMlib_openharddisk(newp, &m);
|
|
else
|
|
{
|
|
DIR *dirp;
|
|
|
|
dirp = Uopendir(newp);
|
|
if (dirp)
|
|
{
|
|
#if defined (USE_STRUCT_DIRECT)
|
|
struct direct *direntp;
|
|
#else
|
|
struct dirent *direntp;
|
|
#endif
|
|
|
|
while ((direntp = readdir(dirp)))
|
|
{
|
|
int namelen;
|
|
|
|
namelen = strlen(direntp->d_name);
|
|
if (namelen >= 4 && (
|
|
strcasecmp(direntp->d_name + namelen - 4, ".hfv")
|
|
== 0 ||
|
|
strcasecmp(direntp->d_name + namelen - 4, ".ima")
|
|
== 0))
|
|
{
|
|
char *tempname;
|
|
|
|
tempname = alloca(strlen(newp) + 1 + namelen + 1);
|
|
sprintf(tempname, "%s/%s", newp, direntp->d_name);
|
|
ROMlib_openharddisk(tempname, &m);
|
|
}
|
|
}
|
|
closedir(dirp);
|
|
}
|
|
}
|
|
}
|
|
free(newp);
|
|
if (ep) {
|
|
*ep = ';';
|
|
p = ep + 1;
|
|
} else
|
|
p = 0;
|
|
}
|
|
#endif
|
|
|
|
ROMlib_automount(ROMlib_startdir);
|
|
ROMlib_automount(ROMlib_DefaultFolder);
|
|
if (is_unix_path (ROMlib_DefaultFolder)
|
|
&& Ustat(ROMlib_DefaultFolder, &sbuf) == 0)
|
|
{
|
|
CurDirStore = CL((LONGINT) ST_INO (sbuf));
|
|
vcbp = ROMlib_vcbbybiggestunixname(ROMlib_DefaultFolder);
|
|
SFSaveDisk = CW(-CW(vcbp->vcbVRefNum));
|
|
}
|
|
if (is_unix_path (ROMlib_SystemFolder)) {
|
|
if (Ustat(ROMlib_SystemFolder, &sbuf) < 0) {
|
|
fprintf(stderr, "Couldn't find '%s'\n", ROMlib_SystemFolder);
|
|
exit(1);
|
|
}
|
|
cpb.hFileInfo.ioNamePtr = RM((StringPtr) SYSMACNAME);
|
|
cpb.hFileInfo.ioVRefNum = -1;
|
|
cpb.hFileInfo.ioDirID = CL((LONGINT) ST_INO (sbuf));
|
|
} else {
|
|
sysnamelen = 1+strlen(ROMlib_SystemFolder)+1+strlen(SYSMACNAME+1)+1;
|
|
sysname = alloca(sysnamelen);
|
|
*sysname = sysnamelen - 2; /* don't count first byte or nul */
|
|
sprintf(sysname+1, "%s:%s", ROMlib_SystemFolder, SYSMACNAME+1);
|
|
cpb.hFileInfo.ioNamePtr = (StringPtr) RM(sysname);
|
|
cpb.hFileInfo.ioVRefNum = 0;
|
|
cpb.hFileInfo.ioDirID = 0;
|
|
}
|
|
cpb.hFileInfo.ioFDirIndex = CWC (0);
|
|
if (PBGetCatInfo(&cpb, FALSE) == noErr) {
|
|
wpb.ioNamePtr = 0;
|
|
wpb.ioVRefNum = cpb.hFileInfo.ioVRefNum;
|
|
wpb.ioWDProcID = TICKX("unix");
|
|
wpb.ioWDDirID = cpb.hFileInfo.ioFlParID;
|
|
if (PBOpenWD(&wpb, FALSE) == noErr)
|
|
BootDrive = wpb.ioVRefNum;
|
|
} else {
|
|
fprintf(stderr, "Couldn't open System: '%s'\n", ROMlib_SystemFolder);
|
|
exit(1);
|
|
}
|
|
#if defined(MSDOS) || defined (CYGWIN32)
|
|
{
|
|
static char drive_to_mount[4] = "x:/";
|
|
|
|
#if defined (MSDOS)
|
|
if (ROMlib_dosdrives == ~0)
|
|
{
|
|
struct mntent *mp;
|
|
FILE *mnt_fp;
|
|
|
|
mnt_fp = setmntent("", "");
|
|
if (mnt_fp) {
|
|
while ((mp = getmntent(mnt_fp)))
|
|
{
|
|
drive_to_mount[0] = mp->mnt_dir[0];
|
|
{
|
|
struct statfs sbuf;
|
|
static char stat_test[] = "x:";
|
|
|
|
stat_test[0] = mp->mnt_dir[0];
|
|
if (statfs (stat_test, &sbuf) == 0)
|
|
{
|
|
uint32 bit;
|
|
|
|
bit = drive_char_to_bit (stat_test[0]);
|
|
checkpoint_dosdrives (checkpointp, begin, bit);
|
|
ROMlib_automount(drive_to_mount);
|
|
check_for_executor_cd (drive_to_mount);
|
|
checkpoint_dosdrives (checkpointp, end, bit);
|
|
}
|
|
}
|
|
}
|
|
endmntent(mnt_fp);
|
|
}
|
|
}
|
|
else
|
|
#endif
|
|
{
|
|
#if WRAPPER_NAME != SUNPATH && WRAPPER_NAME != BLOODBATH
|
|
int i;
|
|
|
|
for (i = 0; i <= 31; ++i)
|
|
{
|
|
uint32 bit;
|
|
|
|
bit = 1 << i;
|
|
if (ROMlib_dosdrives & bit)
|
|
{
|
|
drive_to_mount[0] = 'a' + i;
|
|
checkpoint_dosdrives (checkpointp, begin, bit);
|
|
#if defined (CYGWIN32)
|
|
drive_to_mount[0] += 'A' - 'a';
|
|
if (win_access (drive_to_mount))
|
|
{
|
|
#endif
|
|
ROMlib_automount(drive_to_mount);
|
|
#if defined (MSDOS) || defined (CYGWIN32)
|
|
check_for_executor_cd (drive_to_mount);
|
|
#endif
|
|
#if defined (CYGWIN32)
|
|
}
|
|
#endif
|
|
checkpoint_dosdrives (checkpointp, end, bit);
|
|
}
|
|
}
|
|
#endif
|
|
}
|
|
}
|
|
#endif
|
|
|
|
#if defined (MSDOS)
|
|
aspi_init ();
|
|
#endif
|
|
|
|
#if defined (MSDOS) || defined (CYGWIN32)
|
|
if (ROMlib_dosdrives)
|
|
#endif
|
|
futzwithdosdisks();
|
|
|
|
#if defined (MSDOS) || defined (CYGWIN32)
|
|
if (!e2_is_mounted () && cd_big_hfv)
|
|
{
|
|
LONGINT m;
|
|
|
|
ROMlib_openharddisk (cd_big_hfv, &m);
|
|
if (m)
|
|
cd_mounted_by_trickery_p = TRUE;
|
|
}
|
|
#endif
|
|
if (ROMlib_magic_volumesp)
|
|
{
|
|
char *p, *pathp, *aliasp;
|
|
|
|
p = (char *) ROMlib_magic_volumesp->chars;
|
|
do
|
|
{
|
|
pathp = p;
|
|
p += strlen (p) + 1;
|
|
aliasp = p;
|
|
p += strlen (p) + 1;
|
|
|
|
if (*pathp && *aliasp)
|
|
{
|
|
char *newpath;
|
|
|
|
newpath = copystr (pathp);
|
|
ROMlib_volume_alias (newpath, aliasp);
|
|
free (newpath);
|
|
}
|
|
}
|
|
while (*pathp && *aliasp);
|
|
}
|
|
if (ROMlib_suffix_mapsp)
|
|
{
|
|
char *p, *suffixp;
|
|
|
|
p = (char *) ROMlib_suffix_mapsp->chars;
|
|
do
|
|
{
|
|
suffixp = p;
|
|
if (*suffixp)
|
|
{
|
|
char *creator_hexp, *type_hexp, *applicationp;
|
|
|
|
p += strlen (p) + 1;
|
|
creator_hexp = p;
|
|
p += strlen (p) + 1;
|
|
type_hexp = p;
|
|
p += strlen (p) + 1;
|
|
applicationp = p;
|
|
p += strlen (p) + 1;
|
|
|
|
ROMlib_add_suffix_quad (suffixp, creator_hexp, type_hexp,
|
|
applicationp);
|
|
}
|
|
}
|
|
while (*suffixp);
|
|
}
|
|
}
|
|
|
|
|
|
#if defined (BINCOMPAT)
|
|
fcbrec *
|
|
PRNTOFPERR (INTEGER prn, OSErr *errp)
|
|
{
|
|
fcbrec *retval;
|
|
OSErr err;
|
|
|
|
if (prn < 0 || prn >= CW(*(short *)MR(FCBSPtr)) || (prn % 94) != 2) {
|
|
retval = 0;
|
|
err = rfNumErr;
|
|
} else {
|
|
retval = (fcbrec *) ((char *) MR(FCBSPtr) + prn);
|
|
if (!retval->fdfnum) {
|
|
retval = 0;
|
|
err = rfNumErr;
|
|
} else
|
|
err = noErr;
|
|
}
|
|
*errp = err;
|
|
return retval;
|
|
}
|
|
#endif /* BINCOMPAT */
|