mirror of
https://github.com/elliotnunn/mac-rom.git
synced 2025-01-01 11:29:27 +00:00
0ba83392d4
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.
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
|