mac-rom/OS/PPC/PPCPort.c
Elliot Nunn 4325cdcc78 Bring in CubeE sources
Resource forks are included only for .rsrc files. These are DeRezzed into their data fork. 'ckid' resources, from the Projector VCS, are not included.

The Tools directory, containing mostly junk, is also excluded.
2017-12-26 09:52:23 +08:00

439 lines
14 KiB
C

/*
File: PPCPort.c
Contains: PPCPort Management Functions.
Written by: Sangam, Eric M. Trehus
Copyright: © 1990-1993 by Apple Computer, Inc., all rights reserved.
Change History (most recent first):
<SM5> 3/9/93 PN Remove ReQueueInformPB,Insert, Push,InitQueue, TraverseQueue
which is no longer used
<27> 4/14/92 BBM <JSM>: Remove unfinished PPC code that is under the contitional
ÒTheFututeÓ, and remove the conditional ÒCubeEÓ since that is
reality. Remove conditionals, since all they do is confuse.
<26> 10/4/91 JSM Change PsychoticFarmerOrLater conditionals to TheFuture.
<25> 9/29/91 DTY Conditionalize <21> through <24> out of CubeE.
<24> 6/26/91 EMT Add more range checking to ValidPortName
<23> 6/12/91 EMT Stop attempting to keep track of the number of pending messages.
<22> 6/10/91 EMT Optimize code for size, Combined WildPortMatch and
ComparePortName into 1 procedure, while fixing bugs in both of
these procedures.
<21> 6/4/91 EMT Roll in StoreAndForward Revisions
<20> 1/11/91 EMT <VC> Fix bug in GetPortNames.
<19> 11/8/90 EMT <stb>Continue working on the IPCListPorts fix
<18> 11/6/90 EMT Begin work on fixing IPCListPorts, change not yet in place, but
needed to check in file
<17> 10/30/90 EMT Fix GetPortTable
<16> 10/18/90 EMT Change userName to machineName where needed
<15> 10/11/90 EMT Make changes to obsole CompletionGlue.a
<14> 9/21/90 EMT Update constants, types, and field names as dictated by
PPCToolBox.h
<13> 9/15/90 EMT make reserved byte in portInfo always 0.
<12> 9/5/90 EMT Make this file C3.0 Friendly
<10+> 9/4/90 EMT Roll in Eric's changes
<10> 7/10/90 dba fix C warnings
<9> 6/28/90 S To Improve dynamic allocation scheme for the ports.
<8> 3/20/90 S Bug Fix in GetPortNames Call.
<7> 2/28/90 S To support Guest Selection in GetPortNames.
<6> 2/27/90 S To Make authRequest nonOptional.
<5> 1/24/90 S Fix Some Comments.
<4> 1/24/90 S Fix Bug in WildPortMatch function & returning
authRequired false for local ipclistport calls.
<2+> 1/5/90 Sangam Some Error Code Changes
Old Revision History:
05/31/89 Sangam New Today
07/20/89 Sangam 1.0d2 release today!
07/25/89 Sangam Changed FreePortTable and added ClosePortCompletion
08/25/89 Sangam Chganged GetPortNames to new IPCListPorts
09/19/89 Sangam Started changing to new PortName interface
Added ValidPortName and CopyPortName routines
09/27/89 Sangam Copying script code in CopyPortName
1/4/90 Sangam Some Bug Fixes
*/
#include "PPCCommon.h"
#include <String.h>
/*----------------------------------------------------------------------------------------
Prototypes used in this file only!
----------------------------------------------------------------------------------------*/
STATIC void NBPRemoveCompletion(void);
STATIC Boolean WildPortMatch(PPCPortPtr name1,PPCPortPtr name2);
OSErr ClosePortTable(PPCClosePBPtr closePB,
PPCPortEntryPtr portPtr,
PPCGlobalParamsPtr ppcglobPtr)
{
Boolean freePortTable;
PPCInformPBPtr informPB;
freePortTable = true;
portPtr->openPB = (Ptr)closePB; // Keep for later.
while (informPB = ServeQueue(&portPtr->informPBQueue))
CompleteWithResult(informPB,portClosedErr);
#ifdef IPMIncluded
if(portPtr->PortQueueRef)
{
freePortTable = false;
}
#endif
if (portPtr->nbpRegistered) // PortName was registered with nbp
{
PortLocationTablePtr locInfo;
freePortTable = false;
locInfo = portPtr->locationInfo;
RemoveName((EntityName *)&locInfo->nteQEle.nt.entityData,
true,
(ProcPtr)NBPRemoveCompletion,
&locInfo->nbpPB);
}
if (portPtr->sessCount)
{
freePortTable = false;
CleanSessions(portPtr, ppcglobPtr);
}
if(freePortTable)
CompleteClosePort(portPtr);
return(noErr);
}
STATIC void NBPRemoveCompletion(void)
{
PPCPortEntryPtr portPtr;
PortLocationTablePtr locInfo;
locInfo = GetA0();
portPtr = locInfo->portPtr;
portPtr->nbpRegistered = false; // nolonger registered.
CompleteClosePort(portPtr);
} // PortCloseCompletion
/*---------------------------------------------------------------------------------------------------
CompleteClosePort makes sure that the PPCClose operation has completed all outstanding
PPCInform calls, Ended all sessions, and un-registered the NBP LocName. With all
these accomplished, the port table is freed and the closePB is completed with a
result of noErr.
---------------------------------------------------------------------------------------------------*/
void CompleteClosePort(PPCPortEntryPtr portPtr)
{
if(portPtr->nbpRegistered ||
#ifdef IPMIncluded
portPtr->PortQueueRef ||
#endif
portPtr->sessCount ||
portPtr->informPBQueue.qSize)
return; // Port not fully closed.
else
{
PPCClosePBPtr closePB;
if (closePB = (PPCClosePBPtr)portPtr->openPB) // if there was a PPCClose call
{
portPtr->openPB = NULL; // Prevention
FreePortTable(portPtr);
CompleteWithResult(closePB,noErr);
}
}
}
/*----------------------------------------------------------------------------------------
CheckPortName returns the port that has the given port name.
----------------------------------------------------------------------------------------*/
PPCPortEntryPtr CheckPortName(PPCPortPtr portName,PPCGlobalParamsPtr ppcglobPtr)
{
PPCPortEntryPtr portPtr;
FOREACHELEMENT(portPtr,&ppcglobPtr->OpenPortQueue)
{
if (ComparePortName(portName, (PPCPortPtr)(&portPtr->portName.nameScript)))
return portPtr;
}
return(NULL);
}
/*----------------------------------------------------------------------------------------
ValidPortName verifies the structure and portKindSelector for any detectable errors.
----------------------------------------------------------------------------------------*/
Boolean ValidPortName(PPCPortPtr name)
{
if (name->portKindSelector == ppcByString || name->portKindSelector == ppcByCreatorAndType)
{
if (name->name[0] > 32)
return false;
if (name->portKindSelector == ppcByString)
{
if (name->u.portTypeStr[0] > 32)
return false;
}
return true;
}
return false;
} // ValidPortName
Boolean ComparePortName(PPCPortPtr name1,PPCPortPtr name2)
{
unsigned char len;
if (name1->nameScript != name2->nameScript)
return false;
if (name1->portKindSelector != name2->portKindSelector)
return false;
if (!(CompareByte(name1->name, name2->name, name1->name[0]+1)))
return false;
if (name1->portKindSelector == ppcByCreatorAndType)
len = 8;
else
len = name1->u.portTypeStr[0]+1;
return CompareByte(name1->u.portTypeStr, name2->u.portTypeStr, len);
} // ComparePortName
/*----------------------------------------------------------------------------------------
Since a PPCPortEntry nolonger wastes space by keeping a locationName structure in
tact, we have this routine that constructs one based on the given port.
----------------------------------------------------------------------------------------*/
void GetLocationName(PPCGlobalParamsPtr ppcglobPtr,
PPCPortEntryPtr portPtr,
LocationNamePtr locationName)
{
locationName->locationKindSelector = ppcNBPLocation;
BlockMove(ppcglobPtr->machineName,&locationName->u.nbpEntity.objStr,sizeof(Str32));
BlockMove(ppcglobPtr->zoneName,&locationName->u.nbpEntity.zoneStr,sizeof(Str32));
if(portPtr->locationInfo)
BlockMove(portPtr->locationInfo->typeStr,&locationName->u.nbpEntity.typeStr,sizeof(Str32));
else
BlockMove(ppcglobPtr->configData.ppctoolboxName,&locationName->u.nbpEntity.typeStr,sizeof(Str32));
}
/*----------------------------------------------------------------------------------------
PortRefNumCompare compares the portRefNum passed in to the portRefNum in the port.
----------------------------------------------------------------------------------------*/
STATIC Boolean PortRefNumCompare(PPCPortEntryPtr portPtr,unsigned long portRefNum)
{
return(portPtr->portRefNum == (PPCPortRefNum)portRefNum);
}
/*----------------------------------------------------------------------------------------
DeletePortByRefNum removes and returns the port specified by the portRefNum parameter.
----------------------------------------------------------------------------------------*/
PPCPortEntryPtr DeletePortByRefNum(unsigned short portRefNum,PPCGlobalParamsPtr ppcglobPtr)
{
return DeleteFromQueue(&ppcglobPtr->OpenPortQueue,(unsigned long)portRefNum,(SearchFuncPtr)PortRefNumCompare);
}
/*----------------------------------------------------------------------------------------
PortRefNumtoPtr finds the port specified by its portRefNum parameter.
----------------------------------------------------------------------------------------*/
PPCPortEntryPtr PortRefNumtoPtr(unsigned short portRefNum,PPCGlobalParamsPtr ppcglobPtr)
{
return SearchQueue(&ppcglobPtr->OpenPortQueue,(unsigned long)portRefNum,(SearchFuncPtr)PortRefNumCompare,1);
}
/*----------------------------------------------------------------------------------------
GetUniquePortRefNum returns a portRefNum that is not in use
----------------------------------------------------------------------------------------*/
STATIC short GetUniquePortRefNum(PPCGlobalParamsPtr ppcglobPtr)
{
PPCPortEntryPtr portPtr;
short portRefNum;
short p;
p = spl(kNoInterrupts);
StartOver:
portRefNum = ppcglobPtr->nextPortRefNum++;
if(!ppcglobPtr->nextPortRefNum) // nextPortRefNum can't be 0.
++ppcglobPtr->nextPortRefNum;
FOREACHELEMENT(portPtr,&ppcglobPtr->OpenPortQueue)
{
if(portPtr->portRefNum == portRefNum)
goto StartOver; // Should rarely happen!
}
spl(p);
return(portRefNum);
}
/*----------------------------------------------------------------------------------------
GetPortTable puts together and initializes a port structure. If the port has a
location name associated with it, a PortLocationTable is linked with the port. If
the port supports store and forward, then a PortSFTable is linked with the port.
NULL is returned if some strucute cannot be gotten that is required, and all
associated memory is returned to the proper pools.
----------------------------------------------------------------------------------------*/
PPCPortEntryPtr GetPortTable(PPCOpenPBPtr openPB,PPCGlobalParamsPtr ppcglobPtr)
{
PPCPortEntryPtr portPtr;
if(portPtr = ServeQueue(&ppcglobPtr->freePortQueue))
{
PortLocationTablePtr locInfo; // <25>
memset(portPtr,0,sizeof(PPCPortEntry));
openPB->portRefNum = portPtr->portRefNum = GetUniquePortRefNum(ppcglobPtr);
CopyPortName((openPB->portName), &(portPtr->portName));
portPtr->serviceType = openPB->serviceType;
portPtr->authRequest = true; // no longer an option (openPB->authRequest;)
portPtr->networkVisible = openPB->networkVisible;
portPtr->serviceType = openPB->serviceType;
portPtr->openPB = (Ptr)openPB;
if(openPB->networkVisible && openPB->locationName)
{
if(portPtr->locationInfo = locInfo = ServeQueue(&ppcglobPtr->freeLocationQueue))
{
locInfo->portPtr = portPtr;
BlockMove(openPB->locationName->u.nbpType,locInfo->typeStr,sizeof(Str32));
}
else // Should not ever ever happen in a million billion years, but just in case!
{
FreePortTable(portPtr);
return(NULL);
}
}
EnQueue(portPtr,&ppcglobPtr->OpenPortQueue); // Its open!
return(portPtr);
}
return(NULL);
}
/*----------------------------------------------------------------------------------------
FreePortTable frees a port and any linked structures.
----------------------------------------------------------------------------------------*/
void FreePortTable(PPCPortEntryPtr portPtr)
{
PPCGlobalParamsPtr ppcglobPtr;
ppcglobPtr = (PPCGlobalParamsPtr)getGlobal();
DeleteFromQueue(&ppcglobPtr->OpenPortQueue,(unsigned long)portPtr,PointerCompare);
if(portPtr->locationInfo)
EnQueue(portPtr->locationInfo,&ppcglobPtr->freeLocationQueue);
EnQueue(portPtr,&ppcglobPtr->freePortQueue);
}
void SetPortInformQue(PPCInformPBPtr PB,PPCPortEntryPtr portPtr)
{
EnQueue(PB,&portPtr->informPBQueue);
}
/*----------------------------------------------------------------------------------------
GetPortNames fills a buffer with PortInfo. The result of this operation is true if
all of the remaining would fit into the specified buffer. False is returned if the
reqCount+1 port is found.
----------------------------------------------------------------------------------------*/
Boolean GetPortNames(PPCGlobalParamsPtr ppcglobPtr,
PPCPortPtr name,
Boolean local,
Boolean guestUnChecked,
unsigned short index,
PortInfoPtr buffPtr,
unsigned short reqCount,
unsigned short *actCount)
{
PPCPortEntryPtr portPtr;
unsigned short currentIndex = 0;
unsigned long offSet =0;
*actCount = 0;
if (!reqCount)
return true;
FOREACHELEMENT(portPtr,&ppcglobPtr->OpenPortQueue)
{
if (index != currentIndex)
{
if (local || portPtr->networkVisible)
{
if (WildPortMatch(name, &portPtr->portName))
++currentIndex;
}
}
else
{
if (local || portPtr->networkVisible)
{
if (WildPortMatch(name, &portPtr->portName))
{
if (*actCount == reqCount)
return false; // we don't have enough space in the buffer
buffPtr->filler1 = 0; // Reserved for future expansion.
if (local || guestUnChecked)
buffPtr->authRequired = false; // Local or Guest is Enabled in user&Groups
else
buffPtr->authRequired = true; //
CopyPortName(&portPtr->portName, &buffPtr->name);
buffPtr++;
++*actCount;
}
}
}
}
return true;
} // GetPortNames
STATIC Boolean WildPortMatch(PPCPortPtr name1,PPCPortPtr name2)
{
Boolean wildType = false;
Boolean wildName = false;
unsigned char len;
if ((name1->name[0] == 1) &&
(name1->name[1] == metaCharacter))
wildName = true;
if ((name1->u.portTypeStr[0] == 1) &&
(name1->u.portTypeStr[1] == metaCharacter))
wildType = true;
if (wildName && wildType)
return true; // some one wants all the names
if (!wildName)
{
if (!(wildName = CompareByte((Ptr)(name1->name),
(Ptr)(name2->name),
name1->name[0]+1)))
return false; // Name Did not Match
}
if (!wildType)
{
if (name1->portKindSelector != name2->portKindSelector)
return false;
else
{
if (name1->portKindSelector == ppcByCreatorAndType)
len = 8;
else
len = name1->u.portTypeStr[0]+1;
if (!(wildType = CompareByte((Ptr)(name1->u.portTypeStr),
(Ptr)(name2->u.portTypeStr),
len)))
return false;
}
}
if (wildName && wildType)
return true; // Both Name and Type Match
} // WildPortMatch