mirror of
https://github.com/elliotnunn/supermario.git
synced 2024-11-22 04:31:30 +00:00
439 lines
14 KiB
C
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
|