mirror of
https://github.com/elliotnunn/supermario.git
synced 2024-08-29 23:28:53 +00:00
1904 lines
62 KiB
C
1904 lines
62 KiB
C
/*
|
|
File: PPCNetwork.c
|
|
|
|
Contains: PPCNetwork related functions.
|
|
|
|
Written by: Sangam, Eric M. Trehus
|
|
|
|
Copyright: © 1989-1992 by Apple Computer, Inc., all rights reserved.
|
|
|
|
Change History (most recent first):
|
|
|
|
<46> 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.
|
|
<45> 10/4/91 JSM Change PsychoticFarmerOrLater conditionals to TheFuture.
|
|
<44> 9/29/91 DTY Conditionalize <42> and <43> out of CubeE.
|
|
<43> 6/10/91 EMT continue code reduction
|
|
<42> 6/4/91 EMT Roll in StoreAndForward Revisions
|
|
<41> 1/14/91 EMT <VC> Fix race condition in RemoveNetworkConnection.
|
|
<40> 1/11/91 EMT <VC> Fix bug in IPCListPorts.
|
|
<39> 12/13/90 EMT <JSM> Remove race condition, add debug code (for debug versions)
|
|
<38> 11/13/90 EMT <stb> Remove redundant error checks in StartNetworkSession and
|
|
ListNetworkPorts, add noUserNameErr back in (bug fix).
|
|
<37> 11/8/90 EMT <stb> Change key used in scramble, and some error codes.
|
|
<36> 11/6/90 EMT use STATIC in place of static for link maps
|
|
<35> 10/30/90 EMT Remove a tiny window of oppertunity
|
|
<34> 10/24/90 EMT Update error codes
|
|
<33> 10/11/90 EMT Add conditionals around debug code, remove reference to
|
|
Assembly language completion routine glue.
|
|
<32> 9/21/90 EMT Update constants, types, and field names as dictated by
|
|
PPCToolBox.h
|
|
<31> 9/14/90 EMT Fix type problem
|
|
<30> 9/5/90 EMT Remove a conditional that appears to cause 3.0C some problems
|
|
<29> 9/4/90 EMT Fix priority 1 bug
|
|
<27+> 9/4/90 EMT Roll in Eric's changes
|
|
<27> 8/14/90 S Fixed Bug in copying the user name in ProcessInform.
|
|
<26> 8/6/90 S Bug Fixes.
|
|
<25> 6/28/90 S To Improve Dynamic allocation of sessions.
|
|
<23+> 6/1/90 EMT Fix ConnectionRequestCompletion bug that causes failure in
|
|
RepostConnectionListener when ADSP calls it directly
|
|
<23> 6/1/90 VC Added the checking of UserFlag after getting the user record.
|
|
<22> 5/31/90 EMT Added support to clear the originated flag on inform calls, and
|
|
set it on start.
|
|
<21> 4/23/90 JSM Add CopyReadBlk routine to copy readBlk to writeHdrBlk and
|
|
writeBlk in NetIPCParams, fix bug in AuthAcceptCompletion, add
|
|
AvoidDuplicateCompletion prototype, misc. other code size
|
|
reductions.
|
|
<20> 4/10/90 S To Include Checking of PPC Global Flag.
|
|
<19> 3/20/90 S Fix Bugs Related NetInvisible Ports.
|
|
<17> 2/28/90 S IPCListPort Info Returned to refelect Guest Selected Icon.
|
|
<16> 2/27/90 S Fix the Guest Stuff.
|
|
<15> 2/27/90 S To Make it work with ADSP 1.5(it did not).
|
|
<14> 2/23/90 S Bug fix
|
|
<13> 2/20/90 S Fix the actual length in write completion during error
|
|
condition.
|
|
<12> 2/20/90 S Bug Fix.
|
|
<11> 2/13/90 S Bug Fix.
|
|
<10> 2/8/90 S No Change.
|
|
<9> 2/5/90 S Changed Error Code For PPCStart(portClosedErr) if user close the
|
|
port after making start.
|
|
<8> 2/2/90 S Fixed Crash on noInform Error.
|
|
<7> 1/30/90 S Changed ErrorCode on Open Completion.
|
|
<6> 1/30/90 S Bug Fixes for some error codes.
|
|
<5> 1/26/90 S Fix Writeing > 32k problem & reading 0 byte
|
|
<4> 1/24/90 S Fix Bug related ppcportclose when the session is being opened.
|
|
<1.7> 11/8/89 CVC Made changes to fix ppcreject crash
|
|
<1.6> 11/6/89 KON Fixed typo: SdssReject -> SessReject
|
|
<1.5> 11/6/89 CVC Fixed a bug in PPCReject
|
|
<1.4> 10/12/89 CCH Fixed header
|
|
<•1.3> 10/12/89 CVC Added access control stuff
|
|
<1.2> 10/2/89 CVC Fixed a bug in PPCInform call.
|
|
<1.1> 9/25/89 ss Added support for 'more' in PPCwrite call
|
|
<1.0> 9/18/89 CVC Adding PPC toolbox for the first time.
|
|
|
|
Old Revision History:
|
|
|
|
06/05/89 Sangam New Today
|
|
07/20/89 Sangam 1.0d2 release today!
|
|
08/01/89 Sangam Fixed Bug in End session call
|
|
08/02/89 Sangam Fixed ADSP bug with a work around (ReadCompletion & RemoveCompletion)
|
|
08/10/89 Sangam Made Change to IPCListPorts calls
|
|
08/10/89 Sangam Added userEntry filed for read/write headers
|
|
08/10/89 Sangam Fixed a bug in listport call
|
|
08/29/89 Sangam Fixed duplicate completion with informPB
|
|
08/30/89 Sangam Fixed actualLength filed in Read Calls
|
|
09/07/89 Sangam Added Appletalk Phase2 Transition Routines
|
|
so that Network can be switched dynamicallly.
|
|
09/07/89 Sangam Took out the gracefull end for outstanding write.
|
|
Looks like ADSP will not time out anyway
|
|
09/08/89 Sangam Fixed a bug in WriteData (i.e. res->deadLock was set to 1
|
|
which prevented completion routines being not called
|
|
09/21/89 Sangam Changed GetPortNames interface
|
|
09/22/89 Sangam Removed destportName and destlocname from session data structure
|
|
09/25/89 Sangam Added support for 'more' in PPCwrite call
|
|
09/26/89 Sangam Major changes to support authentication
|
|
09/27/89 Sangam Made change to ListRead to take size of PortInfo
|
|
10/09/89 Sangam Made changes to support guest login
|
|
11/08/89 Sangam Made changes to fix ppcreject crash
|
|
1/4/90 Sangam Several Bug Fixes
|
|
|
|
*/
|
|
|
|
#include "PPCCommon.h"
|
|
#include <String.h>
|
|
|
|
/*----------------------------------------------------------------------------------------
|
|
Constants used only in this file.
|
|
----------------------------------------------------------------------------------------*/
|
|
#define MaxADSPWrite 0x7FFF // 32767 bytes is the most we should ever write.
|
|
|
|
/*----------------------------------------------------------------------------------------
|
|
Prototypes for procedures used only in this file.
|
|
----------------------------------------------------------------------------------------*/
|
|
STATIC NetIPCParamsPtr GetRemSess(PPCGlobalParamsPtr ppcglobPtr);
|
|
STATIC void FreeRemSess(NetIPCParamsPtr theSess);
|
|
STATIC void RemoveCompletion(void); // <44>
|
|
STATIC void BeginNetworkConnection(NetIPCParamsPtr sessPtr);
|
|
STATIC void AcceptNetworkConnection(NetIPCParamsPtr sessPtr);
|
|
STATIC void RemoveNetworkConnection(NetIPCParamsPtr sessPtr,Boolean abortFlag);
|
|
STATIC void NetLookUpCompletion(void);
|
|
STATIC void ConnectionEndCompletion(void);
|
|
STATIC void OpenCompletion(void);
|
|
STATIC void StartSendCompletion(void);
|
|
STATIC void StartCommandCompletion(void);
|
|
STATIC void AuthRespSendCompletion(void);
|
|
STATIC void AuthAcceptCompletion(void);
|
|
STATIC void ListSendCompletion(void);
|
|
STATIC void ListReadCompletion(void);
|
|
STATIC void ListCommandCompletion(void);
|
|
STATIC void RespConnectionEndCompletion(void);
|
|
STATIC void RespOpenCompletion(void);
|
|
STATIC void RecvSessReqCompletion(void);
|
|
STATIC void GuestRecCompletion(UserRecPb *uRec);
|
|
STATIC void UserRecCompletion(UserRecPb *uRec);
|
|
STATIC void AuthSendCompletion(void);
|
|
STATIC void AuthRespCompletion(void);
|
|
STATIC void ProcessInform(NetIPCParams *sessPtr,unsigned short userFlags);
|
|
STATIC void RespSendCompletion(void);
|
|
STATIC void ARepostConnectionListener(void);
|
|
STATIC void RepostConnectionListener(DSPParamBlock *dsp);
|
|
STATIC void ListWrite(NetIPCParams *sessPtr);
|
|
STATIC void ListWriteCompletion(void);
|
|
STATIC void ListRespCompletion(void);
|
|
|
|
STATIC void BeginWriteBlock(NetIPCParamsPtr sessPtr);
|
|
STATIC void WriteHdrCompletion(void);
|
|
STATIC void WriteBlockData(NetIPCParamsPtr sessPtr);
|
|
STATIC void WriteBlockDataCompletion(void);
|
|
STATIC void CompleteWriteRequest(NetIPCParamsPtr sessPtr,OSErr result);
|
|
|
|
STATIC void BeginReadBlock(NetIPCParamsPtr sessPtr);
|
|
STATIC void ReadHdrCompletion(void);
|
|
STATIC void ReadBlockData(NetIPCParamsPtr sessPtr);
|
|
STATIC void ReadDataCompletion(void);
|
|
STATIC void ReadData(NetIPCParamsPtr sessPtr);
|
|
STATIC void CompleteReadRequest(NetIPCParamsPtr sessPtr,OSErr result);
|
|
|
|
STATIC void CopyReadBlk(NetIPCParamsPtr sessPtr);
|
|
|
|
/*----------------------------------------------------------------------------------------
|
|
GetRemSess
|
|
----------------------------------------------------------------------------------------*/
|
|
STATIC NetIPCParamsPtr GetRemSess(PPCGlobalParamsPtr ppcglobPtr)
|
|
{
|
|
NetIPCParamsPtr sessPtr;
|
|
|
|
if(sessPtr = ServeQueue(&ppcglobPtr->freeRemSessQueue))
|
|
{
|
|
memset(sessPtr,0,sizeof(NetIPCParams)); // Wipe it clean
|
|
sessPtr->sessUse = netUse;
|
|
EnQueue(sessPtr,&ppcglobPtr->RemSessQueue);
|
|
}
|
|
return(sessPtr);
|
|
}
|
|
|
|
/*----------------------------------------------------------------------------------------
|
|
FreeRemSess
|
|
----------------------------------------------------------------------------------------*/
|
|
STATIC void FreeRemSess(NetIPCParamsPtr theSess)
|
|
{
|
|
PPCGlobalParamsPtr ppcglobPtr;
|
|
PPCPortEntryPtr portPtr;
|
|
|
|
ppcglobPtr = (PPCGlobalParamsPtr)getGlobal();
|
|
portPtr = theSess->portEntry;
|
|
DeleteFromQueue(&ppcglobPtr->RemSessQueue,(unsigned long)theSess,PointerCompare);
|
|
if(portPtr) // <44>if this session belongs to a port.
|
|
--portPtr->sessCount; // <44> update the port table.
|
|
theSess->portEntry = (void *)-1; // check for bug!
|
|
EnQueue(theSess,&ppcglobPtr->freeRemSessQueue);
|
|
}
|
|
|
|
/*----------------------------------------------------------------------------------------
|
|
RemoveNetworkConnection is responsible for scheduling a job to remove the network connection.
|
|
----------------------------------------------------------------------------------------*/
|
|
STATIC void RemoveNetworkConnection(NetIPCParamsPtr sessPtr,Boolean abortFlag)
|
|
{
|
|
PPCGlobalParamsPtr ppcglobPtr;
|
|
short sr;
|
|
|
|
sr = spl(kNoInterrupts);
|
|
if(sessPtr->sessState != AwaitAbortComp) // if we arn't already aborting it then…
|
|
{
|
|
sessPtr->sessState = AwaitAbortComp;
|
|
sessPtr->abortFlag = abortFlag; // remember how we are aborting this.
|
|
|
|
ppcglobPtr = (PPCGlobalParamsPtr)getGlobal();
|
|
DeleteFromQueue(&ppcglobPtr->RemSessQueue,(unsigned long)sessPtr,PointerCompare);
|
|
EnQueue(sessPtr,&ppcglobPtr->dspAbortQueue); // place it in the queue of things to do.
|
|
if(!ppcglobPtr->killSessPtr) // if we are not busy then…
|
|
{
|
|
ppcglobPtr->killSessPtr = ServeQueue(&ppcglobPtr->dspAbortQueue);
|
|
spl(sr);
|
|
BlockMove((Ptr)&sessPtr->readBlk.dsp,(Ptr)&ppcglobPtr->dspRemovePB,sizeof(DSPParamBlock));
|
|
RemoveConnectionEnd(sessPtr->abortFlag, // abort flag (Kill all pending requests)
|
|
true,
|
|
(ProcPtr)RemoveCompletion, // Completion Routine
|
|
&ppcglobPtr->dspRemovePB);
|
|
return;
|
|
}
|
|
}
|
|
spl(sr);
|
|
}
|
|
|
|
/*---------------------------------------------------------------------------------------------------
|
|
RemoveCompletion
|
|
---------------------------------------------------------------------------------------------------*/
|
|
STATIC void RemoveCompletion(void)
|
|
{
|
|
PPCGlobalParamsPtr ppcglobPtr;
|
|
PPCPortEntryPtr portPtr;
|
|
PPCParamBlockPtr PB;
|
|
NetIPCParams *sessPtr;
|
|
|
|
ppcglobPtr = (PPCGlobalParamsPtr)getGlobal();
|
|
sessPtr = ppcglobPtr->killSessPtr;
|
|
|
|
#ifdef DEBUG
|
|
if(ppcglobPtr->dspRemovePB.ioResult)
|
|
DebugStr("\pError in removing a network connection");
|
|
#endif
|
|
PB = (PPCParamBlockPtr)sessPtr->endPB;
|
|
KillReadAndWrite(sessPtr);
|
|
portPtr = (PPCPortEntryPtr)sessPtr->portEntry;
|
|
FreeRemSess(sessPtr);
|
|
if (PB)
|
|
CompleteWithResult(PB,noErr);
|
|
else if (portPtr) // Must be a PPCClose operation.
|
|
CompleteClosePort(portPtr);
|
|
|
|
// Don't change the next two lines or some day you may be sorry!!!
|
|
ppcglobPtr->killSessPtr = sessPtr = ServeQueue(&ppcglobPtr->dspAbortQueue);
|
|
if(sessPtr)
|
|
{
|
|
BlockMove((Ptr)&sessPtr->readBlk.dsp,(Ptr)&ppcglobPtr->dspRemovePB,sizeof(DSPParamBlock));
|
|
RemoveConnectionEnd(sessPtr->abortFlag,
|
|
true,
|
|
(ProcPtr)RemoveCompletion, // Completion Routine
|
|
&ppcglobPtr->dspRemovePB);
|
|
}
|
|
}
|
|
|
|
/*----------------------------------------------------------------------------------------
|
|
StartNetworkSession
|
|
----------------------------------------------------------------------------------------*/
|
|
void StartNetworkSession(PPCStartPBPtr startPB,
|
|
PPCPortEntryPtr portPtr,
|
|
PPCGlobalParamsPtr ppcglobPtr)
|
|
{
|
|
NetIPCParamsPtr sessPtr;
|
|
|
|
if ((startPB->userRefNum) && (!findUserByRef(startPB->userRefNum)))
|
|
{
|
|
CompleteWithResult(startPB,noUserRecErr);
|
|
return;
|
|
}
|
|
if (!(sessPtr = GetRemSess(ppcglobPtr)))
|
|
{
|
|
CompleteWithResult(startPB,sessTableErr);
|
|
return;
|
|
}
|
|
|
|
SetSessionTable((CommonSessionParamsPtr)sessPtr, portPtr, ppcglobPtr);
|
|
sessPtr->PBPtr = startPB; // First PB for this Session
|
|
BeginNetworkConnection(sessPtr);
|
|
}
|
|
|
|
/*----------------------------------------------------------------------------------------
|
|
AcceptNetworkSession
|
|
----------------------------------------------------------------------------------------*/
|
|
void AcceptNetworkSession(PPCAcceptPBPtr acceptPB,
|
|
NetIPCParamsPtr sessPtr)
|
|
{
|
|
IPCAcceptBlkPtr accept;
|
|
|
|
accept = (IPCAcceptBlkPtr)&((sessPtr)->writeBlk.buffer);
|
|
accept->respType = SessAccept; // Stuff the message
|
|
sessPtr->PBPtr = acceptPB;
|
|
AcceptNetworkConnection(sessPtr);
|
|
|
|
} // AcceptNetworkSession
|
|
|
|
/*----------------------------------------------------------------------------------------
|
|
RejectNetworkSession
|
|
----------------------------------------------------------------------------------------*/
|
|
void RejectNetworkSession(PPCRejectPBPtr rejectPB,
|
|
NetIPCParamsPtr sessPtr)
|
|
{
|
|
IPCRejectBlkPtr reject;
|
|
|
|
reject = (IPCRejectBlkPtr)&((sessPtr)->writeBlk.buffer);
|
|
reject->respType = UserReject; // Stuff the message
|
|
reject->rejectInfo = rejectPB->rejectInfo;
|
|
sessPtr->PBPtr = rejectPB; // This will make sure that connection gets closed
|
|
AcceptNetworkConnection(sessPtr);
|
|
} // RejectNetworkSession
|
|
|
|
/*----------------------------------------------------------------------------------------
|
|
WriteNetworkData Begins to write the clients data immediatly if not already doing so in a
|
|
previous request, otherwise it just leaves it on the queue for processing later.
|
|
----------------------------------------------------------------------------------------*/
|
|
void WriteNetworkData(PPCWritePBPtr writePB,
|
|
NetIPCParamsPtr sessPtr)
|
|
{
|
|
short sr;
|
|
|
|
AddWritePB(sessPtr,writePB);
|
|
sr = spl(kNoInterrupts);
|
|
if(!sessPtr->writePB)
|
|
{
|
|
sessPtr->writePB = GetWritePB(sessPtr);
|
|
spl(sr);
|
|
BeginWriteBlock(sessPtr);
|
|
}
|
|
else
|
|
spl(sr);
|
|
} // WriteNetworkData
|
|
|
|
/*----------------------------------------------------------------------------------------
|
|
ReadNetworkData begins to read data immediatly if not already doing so in a previous request,
|
|
otherwise it just places the read on the queue for later processing.
|
|
----------------------------------------------------------------------------------------*/
|
|
void ReadNetworkData(PPCReadPBPtr readPB,
|
|
NetIPCParamsPtr sessPtr)
|
|
{
|
|
short sr;
|
|
|
|
AddReadPB(sessPtr,readPB);
|
|
sr = spl(kNoInterrupts);
|
|
if(!sessPtr->readPB)
|
|
{
|
|
sessPtr->readPB = GetReadPB(sessPtr);
|
|
spl(sr);
|
|
BeginReadBlock(sessPtr);
|
|
}
|
|
else
|
|
spl(sr);
|
|
} // ReadNetworkData
|
|
|
|
|
|
/*----------------------------------------------------------------------------------------
|
|
EndNetworkSession
|
|
----------------------------------------------------------------------------------------*/
|
|
void EndNetworkSession(PPCEndPBPtr endPB,NetIPCParamsPtr sessPtr)
|
|
{
|
|
sessPtr->endPB = endPB; // Save it for later use.
|
|
RemoveNetworkConnection(sessPtr,true);
|
|
}
|
|
|
|
/*----------------------------------------------------------------------------------------
|
|
ListNetworkPorts is the entry point for a network Initiated IPCListPorts requests. A session
|
|
table is gotten, and initialized here.
|
|
----------------------------------------------------------------------------------------*/
|
|
void ListNetworkPorts(IPCListPortsPBPtr listPB,PPCGlobalParamsPtr ppcglobPtr)
|
|
{
|
|
NetIPCParamsPtr sessPtr;
|
|
PBWriteResPtr res;
|
|
|
|
res =(PBWriteResPtr)(listPB->Reserved);
|
|
|
|
if (sessPtr = GetRemSess(ppcglobPtr))
|
|
{
|
|
SetSessionTable((CommonSessionParamsPtr)sessPtr, nil, ppcglobPtr);
|
|
sessPtr->PBPtr = listPB; // First PB for this Session
|
|
sessPtr->portEntry = nil;
|
|
BeginNetworkConnection(sessPtr);
|
|
}
|
|
else
|
|
CompleteWithResult(listPB,sessTableErr);
|
|
|
|
} // ListNetworkPorts
|
|
|
|
/*----------------------------------------------------------------------------------------
|
|
BeginNetworkConnection is where session establishment begins for both IPCListPorts and PPCStart.
|
|
The first thing that occurs is an NBPLookup to find the destination address.
|
|
----------------------------------------------------------------------------------------*/
|
|
STATIC void BeginNetworkConnection(NetIPCParamsPtr sessPtr)
|
|
{
|
|
IPCListPortsPBPtr listPB = sessPtr->PBPtr;
|
|
PPCStartPBPtr startPB = sessPtr->PBPtr;
|
|
LocationNamePtr locationName;
|
|
|
|
if (startPB->csCode == PPCStartCall)
|
|
locationName = startPB->locationName;
|
|
else
|
|
locationName = listPB->locationName;
|
|
|
|
|
|
sessPtr->sessState = AwaitLookupResp;
|
|
NBPSetEntity((unsigned char *)sessPtr->miscData.nbpData.lkupentity,
|
|
(Ptr)&(locationName->u.nbpEntity.objStr),
|
|
(Ptr)&(locationName->u.nbpEntity.typeStr),
|
|
(Ptr)&(locationName->u.nbpEntity.zoneStr));
|
|
|
|
LookupName((EntityName *)sessPtr->miscData.nbpData.lkupentity,
|
|
true, // Get Asynchronously
|
|
(ProcPtr)NetLookUpCompletion, // Completion Routine
|
|
(unsigned char *)sessPtr->miscData.nbpData.lkupbuf, //lookup bufferptr
|
|
lkupbufSize, // BufferSize
|
|
(NBPparms *)&(sessPtr->miscData.nbpData.nbpPB));
|
|
|
|
} // BeginNetworkConnection
|
|
|
|
/*---------------------------------------------------------------------------------------------------
|
|
AcceptNetworkConnection
|
|
---------------------------------------------------------------------------------------------------*/
|
|
STATIC void AcceptNetworkConnection(NetIPCParamsPtr sessPtr)
|
|
{
|
|
sessPtr->sessState = AwaitAcceptSendComp;
|
|
|
|
WriteToConnection(sizeof(IPCAcceptBlk),
|
|
(char *)&(sessPtr->writeBlk.buffer),
|
|
1, // eom
|
|
1, // flush
|
|
true, // Asynchronously
|
|
(ProcPtr)RespSendCompletion, // Completion Routine
|
|
(DSPParamBlock *)&(sessPtr->writeBlk.dsp));
|
|
} // AcceptNetworkConnection
|
|
|
|
/*----------------------------------------------------------------------------------------
|
|
NetLookUpCompletion is chained from BeginNetworkConnection. This is a completion routine for
|
|
an NBPLookup. We are either trying to perform an IPCListPorts, or a PPCStart.
|
|
----------------------------------------------------------------------------------------*/
|
|
STATIC void NetLookUpCompletion(void)
|
|
{
|
|
NBPparms *nbpPB;
|
|
NetIPCParamsPtr sessPtr;
|
|
PPCGlobalParamsPtr ppcglobPtr;
|
|
PPCStartPBPtr startPB;
|
|
|
|
nbpPB = GetA0();
|
|
sessPtr = TOP_OF_RECORD_PTR(nbpPB,NetIPCParams,miscData.nbpData.nbpPB);
|
|
startPB = (PPCStartPBPtr)sessPtr->PBPtr; // Might be IPCListPorts as well.
|
|
|
|
if (nbpPB->ioResult)
|
|
{
|
|
FreeRemSess(sessPtr);
|
|
CompleteWithResult(startPB,nbpPB->ioResult);
|
|
}
|
|
else if (nbpPB->parm.Lookup.numGotten == 0)
|
|
{
|
|
FreeRemSess(sessPtr);
|
|
CompleteWithResult(startPB,noResponseErr);
|
|
}
|
|
else
|
|
{
|
|
BlockMove((char *)(nbpPB->parm.Lookup.retBuffPtr),
|
|
(char *)&(sessPtr->destAddr),
|
|
sizeof(AddrBlock));
|
|
|
|
ppcglobPtr = (PPCGlobalParamsPtr)getGlobal();
|
|
sessPtr->sessState = AwaitDSPInit;
|
|
CreateConnectionEnd((TRCCB *)&(sessPtr->ce), //ccbPtr
|
|
nil, // no user Routine
|
|
DspSendQSize,
|
|
sessPtr->sendQ,
|
|
DspRecvQSize,
|
|
sessPtr->recvQ,
|
|
sessPtr->attnBuffer,
|
|
0, // ADSP picks our socket.
|
|
ppcglobPtr->dspDrvrRef,
|
|
true, // Asynhcronous
|
|
(ProcPtr)ConnectionEndCompletion, // CompletionRoutine
|
|
&sessPtr->readBlk.dsp);
|
|
}
|
|
} // NetLookUpCompletion
|
|
|
|
/*----------------------------------------------------------------------------------------
|
|
ConnectionEndCompletion is chained from NetLookUpCompletion. This is a completion routine for
|
|
a dspInit. A new ADSP Connection Listener has been established. The socket for this
|
|
connection listener is different than the one where PPCToolBox name is registered.
|
|
----------------------------------------------------------------------------------------*/
|
|
STATIC void ConnectionEndCompletion(void)
|
|
{
|
|
NetIPCParams *sessPtr;
|
|
PPCStartPBPtr startPB;
|
|
DSPParamBlock *dsp;
|
|
|
|
dsp = GetA0();
|
|
sessPtr= TOP_OF_RECORD_PTR(dsp,NetIPCParams,readBlk.dsp);
|
|
startPB = sessPtr->PBPtr;
|
|
|
|
if (dsp->ioResult)
|
|
{
|
|
CompleteWithResult(startPB,dsp->ioResult);
|
|
FreeRemSess(sessPtr);
|
|
}
|
|
else
|
|
{
|
|
sessPtr->sessState = AwaitOpenComp;
|
|
/* Copy the parameter Block */
|
|
CopyReadBlk(sessPtr);
|
|
|
|
OpenConnectionEnd(0, // remoteCID
|
|
(AddrBlock *)&(sessPtr->destAddr), // Remote Addess
|
|
(AddrBlock *)&(sessPtr->destAddr), // Filter Addess
|
|
0, // Initial sendSeq
|
|
0, // Initial sendWindow
|
|
0, // attnSendSeq
|
|
ocRequest, // ocMode
|
|
true, // Asynchronous
|
|
(ProcPtr)OpenCompletion, // Completion Routine
|
|
&sessPtr->readBlk.dsp);
|
|
|
|
}
|
|
}
|
|
|
|
/*----------------------------------------------------------------------------------------
|
|
OpenCompletion is chained from ConnectionEndCompletion. This is a completion routine for
|
|
a dspOpen call. If all went well, we will have an ADSP connection established at this time.
|
|
At this point we begin to diverge if we are performing an IPCListPorts, or a PPCStart.
|
|
|
|
If PPCStart, then we transmit an IPCStartBlk structure (See PPCCommon.h for the format).
|
|
If IPCListPorts, then we transmit an IPCListReqBlk structure. (See PPCCommon.h for the format).
|
|
----------------------------------------------------------------------------------------*/
|
|
STATIC void OpenCompletion(void)
|
|
{
|
|
DSPParamBlock *dsp;
|
|
NetIPCParams *sessPtr;
|
|
PPCStartPBPtr startPB;
|
|
UserEntryPtr uEntry;
|
|
|
|
dsp = GetA0();
|
|
sessPtr= TOP_OF_RECORD_PTR(dsp,NetIPCParams,readBlk.dsp);
|
|
startPB = sessPtr->PBPtr; // in fact may be an IPCListPorts PB.
|
|
if (dsp->ioResult)
|
|
{
|
|
CompleteWithResult(startPB,sessPtr->sessState != AwaitAbortComp?
|
|
noResponseErr:portClosedErr);
|
|
sessPtr->PBPtr = NULL;
|
|
RemoveNetworkConnection(sessPtr,false);
|
|
return;
|
|
|
|
}
|
|
|
|
CopyReadBlk(sessPtr); /* Copy the parameter Block */
|
|
if (startPB->csCode == PPCStartCall)
|
|
{
|
|
IPCStartBlkPtr startBlk; // Protocol to begin PPCStart.
|
|
|
|
startBlk = &sessPtr->writeBlk.buffer.buffer.startBlk;
|
|
if (startPB->userRefNum == 0)
|
|
startBlk->userName[0] = 0; // No User Name
|
|
|
|
// FIXME -- Can this be done earlier in the game???
|
|
else if ((uEntry = findUserByRef(startPB->userRefNum)) == nil)
|
|
{
|
|
CompleteWithResult(startPB,noUserRecErr);
|
|
RemoveNetworkConnection(sessPtr,false);
|
|
return;
|
|
}
|
|
else
|
|
{
|
|
// This unscrambles the name we just looked up in the table.
|
|
scramble (kNameKey, uEntry->name, (char *)(startBlk->userName));
|
|
}
|
|
sessPtr->sessState = AwaitStartSendComp;
|
|
|
|
/* Prepare the header block */
|
|
startBlk->reqType = SessRequest;
|
|
startBlk->userData = startPB->userData;
|
|
|
|
CopyPortName(&sessPtr->portEntry->portName,&startBlk->reqportName);
|
|
CopyPortName(startPB->portName,&startBlk->destportName);
|
|
GetLocationName((PPCGlobalParamsPtr)getGlobal(),sessPtr->portEntry,&startBlk->locationName);
|
|
|
|
WriteToConnection(sizeof(IPCStartBlk),
|
|
(char *)startBlk,
|
|
1, // eom
|
|
1, // flush
|
|
true, // Asynchronously
|
|
(ProcPtr)StartSendCompletion, // Completion Routine
|
|
(DSPParamBlock *)&(sessPtr->writeBlk.dsp)
|
|
);
|
|
}
|
|
else if (startPB->csCode == IPCListPortsCall)
|
|
{
|
|
IPCListReqBlkPtr list;
|
|
IPCListPortsPBPtr listPB;
|
|
|
|
sessPtr->sessState = AwaitListSendComp;
|
|
list = (IPCListReqBlkPtr)&(sessPtr->writeBlk.buffer);
|
|
listPB = (IPCListPortsPBPtr)(startPB);
|
|
list->reqType = ListRequest;
|
|
list->startIndex = listPB->startIndex;
|
|
list->requestCount = listPB->requestCount;
|
|
CopyPortName(listPB->portName, &(list->portName));
|
|
|
|
WriteToConnection(sizeof(IPCListReqBlk),
|
|
(char *)list,
|
|
1, // eom
|
|
1, // flush
|
|
true, // Asynchronously
|
|
(ProcPtr)ListSendCompletion, // Completion Routine
|
|
&sessPtr->writeBlk.dsp);
|
|
}
|
|
} // OpenCompletion
|
|
|
|
/*----------------------------------------------------------------------------------------
|
|
StartSendCompletion is chained from OpenCompletion. This is a completion routine for a
|
|
dspWrite call. At this point we have written the IPCStartBlk structure. We now prepare
|
|
to read in the reply. The format of the reply is described in an AuthInfoBlk structure.
|
|
----------------------------------------------------------------------------------------*/
|
|
STATIC void StartSendCompletion(void)
|
|
{
|
|
DSPParamBlock *dsp;
|
|
NetIPCParams *sessPtr;
|
|
PPCStartPBPtr startPB;
|
|
|
|
dsp = GetA0();
|
|
sessPtr = TOP_OF_RECORD_PTR(dsp,NetIPCParams,writeBlk.dsp);
|
|
if (dsp->ioResult)
|
|
{
|
|
if(startPB = sessPtr->PBPtr)
|
|
{
|
|
sessPtr->PBPtr = NULL;
|
|
CompleteWithResult(startPB,dsp->ioResult);
|
|
}
|
|
|
|
RemoveNetworkConnection(sessPtr,false);
|
|
}
|
|
else
|
|
{
|
|
if(sessPtr->sessState == AwaitStartSendComp)
|
|
sessPtr->sessState = AwaitAcceptResp;
|
|
else
|
|
sessPtr->sessState = AwaitAuthAccept;
|
|
ReadFromConnection(sizeof(IPCBufBlk),
|
|
(char *)&(sessPtr->readBlk.buffer),
|
|
true, // Asynchronously
|
|
(ProcPtr)StartCommandCompletion, // completion Routine
|
|
&sessPtr->readBlk.dsp);
|
|
}
|
|
} // StartSendCompletion
|
|
|
|
/*----------------------------------------------------------------------------------------
|
|
StartCommandCompletion
|
|
----------------------------------------------------------------------------------------*/
|
|
|
|
STATIC void StartCommandCompletion(void)
|
|
{
|
|
DSPParamBlock *dsp;
|
|
IPCReadBlk *rblk;
|
|
NetIPCParams *sessPtr;
|
|
PPCStartPBPtr startPB;
|
|
IPCAcceptBlk *ablk;
|
|
AuthInfoBlk *auth1, *auth2;
|
|
|
|
dsp = GetA0();
|
|
sessPtr = TOP_OF_RECORD_PTR(dsp,NetIPCParams,readBlk.dsp);
|
|
rblk = &sessPtr->readBlk;
|
|
|
|
startPB = sessPtr->PBPtr;
|
|
startPB->rejectInfo = nil; // Assume this (If reject, this will change)
|
|
|
|
if(sessPtr->sessState != AwaitAcceptResp &&
|
|
sessPtr->sessState != AwaitAuthAccept)
|
|
startPB->ioResult = portClosedErr; // Port must be closing.
|
|
else if(dsp->ioResult)
|
|
startPB->ioResult = dsp->ioResult;
|
|
else if(!dsp->u.ioParams.actCount && !dsp->u.ioParams.eom)
|
|
startPB->ioResult = destPortErr;
|
|
else
|
|
{
|
|
|
|
ablk = (IPCAcceptBlk *)&(rblk->buffer);
|
|
switch (ablk->respType)
|
|
{
|
|
case SessAccept:
|
|
{
|
|
sessPtr->sessState = DataXferState;
|
|
sessPtr->PBPtr = NULL; // Nothing in the Que
|
|
sessPtr->originator = true; // we started this session.
|
|
startPB->sessRefNum = sessPtr->sessRefNum;
|
|
CompleteWithResult(startPB,noErr);
|
|
return;
|
|
}
|
|
break;
|
|
case AuthContinue:
|
|
{
|
|
#ifdef DEBUG
|
|
if(sessPtr->sessState != AwaitAcceptResp)
|
|
Debugger();
|
|
#endif
|
|
// Server wants the connection to be authenticated
|
|
auth1 = (AuthInfoBlk *)ablk;
|
|
if (!(GetAuthInfo((long *)auth1->authInfo, startPB->userRefNum)))
|
|
startPB->ioResult = noUserRecErr;
|
|
else
|
|
{
|
|
sessPtr->sessState = AwaitAuthRespSend;
|
|
auth2 =(AuthInfoBlk *)&(sessPtr->writeBlk.buffer);
|
|
auth2->respType = AuthInfoResp;
|
|
auth2->authInfo[0] = auth1->authInfo[0];
|
|
auth2->authInfo[1] = auth1->authInfo[1];
|
|
WriteToConnection(sizeof(AuthInfoBlk),
|
|
(char *)auth2,
|
|
1, // eom
|
|
1, // flush
|
|
true, // Asynchronously
|
|
(ProcPtr)StartSendCompletion, // Completion Routine
|
|
(DSPParamBlock *)&(sessPtr->writeBlk.dsp)
|
|
);
|
|
return;
|
|
|
|
}
|
|
}
|
|
break;
|
|
case SessReject:
|
|
{
|
|
switch (ablk->rejectInfo)
|
|
{
|
|
case notVisible:
|
|
case noPort:
|
|
startPB->ioResult = destPortErr;
|
|
break;
|
|
case noInforms:
|
|
startPB->ioResult = noInformErr;
|
|
break;
|
|
case noGuestEnabled:
|
|
startPB->ioResult = guestNotAllowedErr;
|
|
break;
|
|
case iacDisabled:
|
|
startPB->ioResult = userRejectErr;
|
|
break;
|
|
case noUserRec: // UnKnown User on target computer.
|
|
startPB->ioResult = noUserNameErr;
|
|
break;
|
|
case AuthFailure:
|
|
startPB->ioResult = authFailErr;
|
|
break;
|
|
} // end switch ablk->rejectInfo
|
|
startPB->rejectInfo = 0;
|
|
|
|
}
|
|
break;
|
|
case UserReject:
|
|
{
|
|
startPB->ioResult = userRejectErr;
|
|
startPB->rejectInfo = ablk->rejectInfo;
|
|
}
|
|
break;
|
|
default: // I don't think we can get here, unless were talking to a non-PPCToolBox.
|
|
startPB->ioResult = networkErr;
|
|
break;
|
|
} // end switch ablk->respType
|
|
} // End else
|
|
CompleteWithResult(startPB,startPB->ioResult);
|
|
sessPtr->PBPtr = NULL;
|
|
RemoveNetworkConnection(sessPtr,false);
|
|
|
|
}
|
|
|
|
/*----------------------------------------------------------------------------------------
|
|
ListSendCompletion is chained from OpenCompletion.
|
|
----------------------------------------------------------------------------------------*/
|
|
|
|
STATIC void ListSendCompletion(void)
|
|
{
|
|
DSPParamBlock *dsp;
|
|
NetIPCParams *sessPtr;
|
|
IPCListPortsPBPtr listPB;
|
|
|
|
dsp = GetA0();
|
|
sessPtr = TOP_OF_RECORD_PTR(dsp,NetIPCParams,writeBlk.dsp);
|
|
listPB = sessPtr->PBPtr;
|
|
if (dsp->ioResult != noErr)
|
|
{
|
|
CompleteWithResult(listPB,dsp->ioResult);
|
|
sessPtr->PBPtr = NULL;
|
|
RemoveNetworkConnection(sessPtr,false);
|
|
}
|
|
else
|
|
{
|
|
sessPtr->sessState = AwaitListRead;
|
|
ReadFromConnection(sizeof(PortInfoRec) * listPB->requestCount,
|
|
(Ptr)listPB->bufferPtr,
|
|
true, // Asynchronously
|
|
(ProcPtr)ListReadCompletion, // completion Routine
|
|
&sessPtr->readBlk.dsp);
|
|
}
|
|
} // ListSendCompletion
|
|
|
|
/*----------------------------------------------------------------------------------------
|
|
ListReadCompletion is chained from ListSendCompletion.
|
|
----------------------------------------------------------------------------------------*/
|
|
STATIC void ListReadCompletion(void)
|
|
{
|
|
DSPParamBlock *dsp;
|
|
NetIPCParams *sessPtr;
|
|
IPCListPortsPBPtr listPB;
|
|
|
|
dsp = GetA0();
|
|
sessPtr = TOP_OF_RECORD_PTR(dsp,NetIPCParams,readBlk.dsp);
|
|
listPB = sessPtr->PBPtr;
|
|
if (dsp->ioResult != noErr)
|
|
{
|
|
CompleteWithResult(listPB,dsp->ioResult);
|
|
sessPtr->PBPtr = NULL;
|
|
RemoveNetworkConnection(sessPtr,false);
|
|
}
|
|
else
|
|
{
|
|
sessPtr->sessState = AwaitListResp;
|
|
ReadFromConnection(sizeof(IPCListRespBlk),
|
|
(char *)&(sessPtr->readBlk.buffer),
|
|
true, // Asynchronously
|
|
(ProcPtr)ListCommandCompletion, // completion Routine
|
|
&sessPtr->readBlk.dsp);
|
|
}
|
|
} // ListReadCompletion
|
|
|
|
/*----------------------------------------------------------------------------------------
|
|
ListCommandCompletion is chained from ListReadCompletion.
|
|
----------------------------------------------------------------------------------------*/
|
|
STATIC void ListCommandCompletion(void)
|
|
{
|
|
DSPParamBlock *dsp;
|
|
IPCReadBlk *rblk;
|
|
NetIPCParams *sessPtr;
|
|
IPCListPortsPBPtr listPB;
|
|
IPCListRespBlk *lblk;
|
|
|
|
dsp = GetA0();
|
|
rblk = (IPCReadBlk *)dsp;
|
|
sessPtr = TOP_OF_RECORD_PTR(dsp,NetIPCParams,readBlk.dsp);
|
|
listPB = sessPtr->PBPtr;
|
|
sessPtr->PBPtr = NULL;
|
|
if (dsp->ioResult != noErr)
|
|
listPB->ioResult = dsp->ioResult;
|
|
else
|
|
{
|
|
|
|
lblk = (IPCListRespBlk *)&(rblk->buffer);
|
|
if (lblk->respType == ListResp)
|
|
{
|
|
listPB->ioResult = noErr;
|
|
listPB->actualCount = lblk->actualCount;
|
|
}
|
|
else
|
|
listPB->ioResult = networkErr;
|
|
}
|
|
CompleteWithResult(listPB,listPB->ioResult);
|
|
sessPtr->PBPtr = NULL;
|
|
RemoveNetworkConnection(sessPtr,false);
|
|
} // ListCommandCompletion
|
|
|
|
/*----------------------------------------------------------------------------------------
|
|
ConnectionRequestCompletion is chained from PPCInit.c:SetUpConnectionListeners, and
|
|
RepostConnectionListener.
|
|
|
|
On Entry A0 has a pointer to a completed dspCLListen parameter block. This is the
|
|
point at which session conception begins for PPCToolbox. Either its an IPCListPorts
|
|
or a PPCStart that initiated the session, and we are here receiving it.
|
|
----------------------------------------------------------------------------------------*/
|
|
void ConnectionRequestCompletion(void)
|
|
{
|
|
DSPParamBlock *dsp;
|
|
NetIPCParamsPtr sessPtr;
|
|
TRopenParams *open, *open2;
|
|
DSPParamBlock *dsp2;
|
|
PPCGlobalParams *ppcglobPtr;
|
|
|
|
dsp = GetA0();
|
|
ppcglobPtr = (PPCGlobalParams *)getGlobal();
|
|
if (dsp->ioResult == errAborted)
|
|
return; // Looks like someone wants to remove listeners
|
|
else if ((!(ppcglobPtr->allowIncommingRequests)) ||
|
|
(!(sessPtr = GetRemSess(ppcglobPtr))))
|
|
RejectConnectionRequest(dsp,
|
|
true, // Asynchronous
|
|
(ProcPtr)ARepostConnectionListener
|
|
);
|
|
else
|
|
{
|
|
sessPtr->portEntry = 0; // we don't have them yet
|
|
sessPtr->endPB = 0; // we don't have them yet
|
|
dsp2 = (DSPParamBlock *)&(sessPtr->writeBlk.dsp);
|
|
open = (TRopenParams *)&(dsp->u.initParams);
|
|
/* Copy the Session Parameters */
|
|
open2 = (TRopenParams *)&(dsp2->u.initParams);
|
|
open2->remoteCID = open->remoteCID;
|
|
open2->remoteAddress.aNet = open->remoteAddress.aNet;
|
|
open2->remoteAddress.aNode = open->remoteAddress.aNode;
|
|
open2->remoteAddress.aSocket = open->remoteAddress.aSocket;
|
|
open2->sendSeq = open->sendSeq;
|
|
open2->sendWindow = open->sendWindow;
|
|
open2->attnSendSeq = open->attnSendSeq;
|
|
sessPtr->sessState = AwaitRecvDSPInit;
|
|
CreateConnectionEnd((TRCCB *)&(sessPtr->ce), //ccbPtr
|
|
nil, // no user Routine (we need a routine to release session
|
|
DspSendQSize,
|
|
sessPtr->sendQ,
|
|
DspRecvQSize,
|
|
sessPtr->recvQ,
|
|
sessPtr->attnBuffer,
|
|
ppcglobPtr->adspSocket,
|
|
ppcglobPtr->dspDrvrRef,
|
|
true, // Asynhcronous
|
|
(ProcPtr)RespConnectionEndCompletion, // CompletionRoutine
|
|
(DSPParamBlock *)&(sessPtr->readBlk.dsp)
|
|
);
|
|
|
|
RepostConnectionListener(dsp);
|
|
}
|
|
|
|
} // ConnectionRequestCompletion
|
|
|
|
/*----------------------------------------------------------------------------------------
|
|
RespConnectionEndCompletion is chained from ConnectionRequestCompletion.
|
|
|
|
On Entry A0 contains a pointer to a completed dspInit parameter block that
|
|
corresponds to the readBlk of our session.
|
|
In the session table there is a copy of a completed dspCLListen PB in the
|
|
writeBlk. We use this PB to make the dspOpen since the remoteCID, remoteAddress,
|
|
sendSeq, sendWindow, and attnSendSeq numbers are already correctly filled in.
|
|
----------------------------------------------------------------------------------------*/
|
|
STATIC void RespConnectionEndCompletion(void)
|
|
{
|
|
DSPParamBlock *dsp;
|
|
IPCReadBlk *rblk;
|
|
NetIPCParams *sessPtr;
|
|
TRopenParams *open;
|
|
DSPParamBlock *dsp2;
|
|
|
|
dsp = GetA0();
|
|
rblk = (IPCReadBlk *)dsp;
|
|
sessPtr = TOP_OF_RECORD_PTR(dsp,NetIPCParams,readBlk.dsp);
|
|
dsp2 = (DSPParamBlock *)&(sessPtr->writeBlk.dsp);
|
|
open = (TRopenParams *)&(dsp2->u.initParams);
|
|
|
|
if (dsp->ioResult) // some error occured
|
|
FreeRemSess(sessPtr);
|
|
else
|
|
{
|
|
sessPtr->sessState = AwaitocAcceptComp;
|
|
OpenConnectionEnd(open->remoteCID, // remoteCID
|
|
(AddrBlock *)&(open->remoteAddress), // Remote Addess
|
|
(AddrBlock *)&(open->remoteAddress), // Filter Addess
|
|
open->sendSeq, // Initial sendSeq
|
|
open->sendWindow, // Initial sendWindow
|
|
open->attnSendSeq, // attnSendSeq
|
|
ocAccept, // ocMode
|
|
true, // Asynchronous
|
|
(ProcPtr)RespOpenCompletion, // Completion Routine
|
|
(DSPParamBlock *)&(sessPtr->readBlk.dsp)
|
|
);
|
|
}
|
|
} // RespConnectionEndCompletion
|
|
|
|
/*----------------------------------------------------------------------------------------
|
|
RespOpenCompletion is chained from RespConnectionEndCompletion. At this point the
|
|
ADSP session is fully established.
|
|
|
|
On Entry A0 cointains a pointer to a completed dspOpen parameter block that corresponds
|
|
to the sessions writeBlk. Read in the first block of data that was written by PPC.
|
|
----------------------------------------------------------------------------------------*/
|
|
STATIC void RespOpenCompletion(void)
|
|
{
|
|
DSPParamBlock *dsp;
|
|
NetIPCParams *sessPtr;
|
|
|
|
dsp = GetA0();
|
|
sessPtr = TOP_OF_RECORD_PTR(dsp,NetIPCParams,readBlk.dsp);
|
|
|
|
if (dsp->ioResult)
|
|
{
|
|
// some Error occured
|
|
RemoveNetworkConnection(sessPtr,false);
|
|
}
|
|
else
|
|
{
|
|
sessPtr->sessState = AwaitRecvSessReq;
|
|
ReadFromConnection(sizeof(IPCStartBlk),
|
|
(char *)&(sessPtr->readBlk.buffer),
|
|
true, // Asynchronously
|
|
(ProcPtr)RecvSessReqCompletion, // completion Routine
|
|
&sessPtr->readBlk.dsp);
|
|
}
|
|
|
|
|
|
} // RespOpenCompletion
|
|
|
|
/*----------------------------------------------------------------------------------------
|
|
RecvSessReqCompletion is chained from RespOpenCompletion.
|
|
----------------------------------------------------------------------------------------*/
|
|
STATIC void RecvSessReqCompletion(void)
|
|
{
|
|
DSPParamBlock *dsp;
|
|
IPCReadBlk *rblk;
|
|
NetIPCParams *sessPtr;
|
|
IPCStartBlk *sblk;
|
|
PPCPortEntryPtr portPtr;
|
|
PPCGlobalParams *ppcglobPtr;
|
|
IPCAcceptBlkPtr accept;
|
|
IPCListReqBlkPtr list;
|
|
unsigned short sr;
|
|
|
|
dsp = GetA0();
|
|
ppcglobPtr = (PPCGlobalParams *)getGlobal();
|
|
rblk = (IPCReadBlk *)dsp;
|
|
sessPtr = TOP_OF_RECORD_PTR(dsp,NetIPCParams,readBlk.dsp);
|
|
sblk = (IPCStartBlk *)&(rblk->buffer);
|
|
accept = (IPCAcceptBlkPtr)&(sessPtr->writeBlk.buffer);
|
|
|
|
|
|
if (dsp->ioResult == noErr && dsp->u.ioParams.actCount != 0)
|
|
{
|
|
|
|
/* Copy the parameter Block */
|
|
CopyReadBlk(sessPtr);
|
|
switch(sblk->reqType)
|
|
{
|
|
case SessRequest:
|
|
if (portPtr = CheckPortName((PPCPortPtr)&(sblk->destportName),ppcglobPtr))
|
|
{
|
|
// We Have a valid Port
|
|
|
|
SetSessionTable((CommonSessionParamsPtr)sessPtr, portPtr, ppcglobPtr);
|
|
|
|
if (portPtr->networkVisible)
|
|
{
|
|
// We have Port exported for network access
|
|
if (portPtr->authRequest)
|
|
{
|
|
if (sblk->userName[0] == 0)
|
|
{
|
|
sessPtr->miscData.btreeData.guestRec = true;
|
|
}
|
|
else
|
|
sessPtr->miscData.btreeData.guestRec = false;
|
|
|
|
// Requires Authentication
|
|
sessPtr->sessState = AwaitBtreeComp;
|
|
if (ppcglobPtr->ugFile.refNum != 0)
|
|
{
|
|
getUserRec((UserRecPb *)&(sessPtr->miscData.btreeData),
|
|
0, // Key ID
|
|
(char *)sblk->userName,
|
|
(ProcPtr)UserRecCompletion,
|
|
ppcglobPtr->ugFile.refNum);
|
|
}
|
|
else
|
|
{
|
|
accept->rejectInfo = noUserRec; // Trouble with BTree, deny knowing this user.
|
|
accept->respType = SessReject;
|
|
sessPtr->PBPtr = NULL;
|
|
AcceptNetworkConnection(sessPtr);
|
|
|
|
}
|
|
return;
|
|
}
|
|
else
|
|
{
|
|
ProcessInform(sessPtr, 0 );
|
|
return;
|
|
}
|
|
}
|
|
else
|
|
accept->rejectInfo = notVisible; //Only Internal
|
|
}
|
|
else
|
|
accept->rejectInfo = noPort;
|
|
accept->respType = SessReject;
|
|
sessPtr->PBPtr = NULL;
|
|
AcceptNetworkConnection(sessPtr);
|
|
return;
|
|
|
|
case ListRequest:
|
|
DeleteFromQueue(&ppcglobPtr->RemSessQueue,(unsigned long)sessPtr,PointerCompare);
|
|
SetSessionTable((CommonSessionParamsPtr)sessPtr, nil, ppcglobPtr);
|
|
sessPtr->PBPtr = NULL;
|
|
sessPtr->portEntry = nil;
|
|
sessPtr->sessState = AwaitListWriteComp;
|
|
|
|
// For Later Guest Record Checkup
|
|
list = (IPCListReqBlkPtr)sblk;
|
|
list->userName[0] =0;
|
|
|
|
sessPtr->miscData.btreeData.guestRec = true;
|
|
|
|
EnQueue(sessPtr,&ppcglobPtr->ListSessQueue);
|
|
sr = spl(kNoInterrupts);
|
|
if (!ppcglobPtr->listsessPtr)
|
|
{
|
|
// we can process the request
|
|
ppcglobPtr->listsessPtr = ServeQueue(&ppcglobPtr->ListSessQueue);
|
|
spl(sr);
|
|
ppcglobPtr->totalCount = 0; // Total count so far
|
|
ppcglobPtr->listIndex = list->startIndex;
|
|
if (ppcglobPtr->ugFile.refNum != 0)
|
|
{
|
|
getUserRec((UserRecPb *)&(sessPtr->miscData.btreeData),
|
|
0, // Key ID
|
|
(char *)list->userName,
|
|
(ProcPtr)GuestRecCompletion,
|
|
ppcglobPtr->ugFile.refNum);
|
|
}
|
|
else
|
|
{
|
|
ppcglobPtr->guestUnchecked = false;
|
|
ListWrite(sessPtr);
|
|
}
|
|
|
|
}
|
|
else
|
|
{
|
|
spl(sr);
|
|
}
|
|
return;
|
|
} // end switch
|
|
}
|
|
// If it is not anyyone of the above abort it any way
|
|
RemoveNetworkConnection(sessPtr,false);
|
|
} // RecvSessReqCompletion
|
|
|
|
|
|
/*----------------------------------------------------------------------------------------
|
|
GuestRecCompletion chained from RecvSessReqCompletion and UserRecCompletion.
|
|
----------------------------------------------------------------------------------------*/
|
|
STATIC void GuestRecCompletion(UserRecPb *uRec)
|
|
{
|
|
NetIPCParams *sessPtr;
|
|
PPCGlobalParams *ppcglobPtr;
|
|
|
|
|
|
sessPtr = TOP_OF_RECORD_PTR(uRec,NetIPCParams,miscData.btreeData);
|
|
ppcglobPtr = (PPCGlobalParams *)getGlobal();
|
|
|
|
if (sessPtr->sessState == AwaitListWriteComp)
|
|
{
|
|
ppcglobPtr->guestUnchecked = false;
|
|
if ((uRec->btPb.ioResult == noErr) &&
|
|
(uRec->u.ulRecord.ServerFlags & IACGuestEnabled))
|
|
ppcglobPtr->guestUnchecked = true;
|
|
ListWrite(sessPtr);
|
|
}
|
|
|
|
} // GuestRecCompletion
|
|
|
|
/*----------------------------------------------------------------------------------------
|
|
UserRecCompletion chained from RecvSessReqCompletion.
|
|
----------------------------------------------------------------------------------------*/
|
|
STATIC void UserRecCompletion(UserRecPb *uRec)
|
|
{
|
|
NetIPCParams *sessPtr;
|
|
IPCAcceptBlkPtr accept; // <44>
|
|
AuthInfoBlkPtr auth; // <44>
|
|
|
|
sessPtr = TOP_OF_RECORD_PTR(uRec,NetIPCParams,miscData.btreeData);
|
|
accept = (IPCAcceptBlkPtr)&(sessPtr->writeBlk.buffer);
|
|
|
|
if (sessPtr->sessState != AwaitBtreeComp)
|
|
{
|
|
RemoveNetworkConnection(sessPtr,false);
|
|
}
|
|
else if (uRec->btPb.ioResult)
|
|
{
|
|
accept->rejectInfo = noUserRec; // User name not in my BTree.
|
|
accept->respType = SessReject;
|
|
sessPtr->PBPtr = NULL;
|
|
AcceptNetworkConnection(sessPtr);
|
|
}
|
|
else if (uRec->guestRec)
|
|
{
|
|
if (uRec->u.ulRecord.ServerFlags & IACGuestEnabled)
|
|
// Guest is enabled
|
|
ProcessInform(sessPtr, 0x0001);
|
|
else
|
|
{
|
|
accept->rejectInfo = noGuestEnabled;
|
|
accept->respType = SessReject;
|
|
sessPtr->PBPtr = NULL;
|
|
AcceptNetworkConnection(sessPtr);
|
|
}
|
|
}
|
|
else if (uRec->u.record.UserFlags & 0x0001)
|
|
{
|
|
sessPtr->sessState = AwaitRandWrite;
|
|
auth = (AuthInfoBlkPtr)&(sessPtr->writeBlk.buffer);
|
|
auth->respType = AuthContinue; // Send AuthInfo
|
|
auth->authInfo[0] = uRec->random[0];
|
|
auth->authInfo[1] = uRec->random[1];
|
|
WriteToConnection(sizeof(AuthInfoBlk),
|
|
(char *)&(sessPtr->writeBlk.buffer),
|
|
1, // eom
|
|
1, // flush
|
|
true, // Asynchronously
|
|
(ProcPtr)AuthSendCompletion, // Completion Routine
|
|
(DSPParamBlock *)&(sessPtr->writeBlk.dsp));
|
|
}
|
|
else
|
|
{
|
|
accept->rejectInfo = iacDisabled; // <44>
|
|
accept->respType = SessReject; // <44>
|
|
sessPtr->PBPtr = NULL; // <44>
|
|
AcceptNetworkConnection(sessPtr);
|
|
}
|
|
}
|
|
|
|
/*----------------------------------------------------------------------------------------
|
|
AuthSendCompletion is chained from UserRecCompletion.
|
|
----------------------------------------------------------------------------------------*/
|
|
STATIC void AuthSendCompletion(void)
|
|
{
|
|
DSPParamBlock *dsp;
|
|
NetIPCParams *sessPtr;
|
|
|
|
dsp = GetA0();
|
|
sessPtr = TOP_OF_RECORD_PTR(dsp,NetIPCParams,writeBlk.dsp);
|
|
|
|
if ((dsp->ioResult) || (sessPtr->sessState != AwaitRandWrite))
|
|
{
|
|
RemoveNetworkConnection(sessPtr,false);
|
|
}
|
|
else
|
|
{
|
|
sessPtr->sessState = AwaitAuthResp;
|
|
ReadFromConnection(sizeof(AuthInfoBlk),
|
|
(char *)&(sessPtr->readBlk.authBuf),
|
|
true, // Asynchronously
|
|
(ProcPtr)AuthRespCompletion, // completion Routine
|
|
&sessPtr->readBlk.dsp);
|
|
}
|
|
|
|
} // AuthSendCompletion
|
|
|
|
/*----------------------------------------------------------------------------------------
|
|
AuthRespCompletion is chained from AuthSendCompletion.
|
|
----------------------------------------------------------------------------------------*/
|
|
STATIC void AuthRespCompletion(void)
|
|
{
|
|
DSPParamBlock *dsp; // <44>
|
|
AuthInfoBlkPtr auth; // <44>
|
|
NetIPCParams *sessPtr;
|
|
IPCReadBlk *rblk;
|
|
UserRecPbPtr uRec;
|
|
IPCAcceptBlkPtr accept;
|
|
|
|
dsp = GetA0();
|
|
rblk = (IPCReadBlk *)dsp;
|
|
sessPtr = TOP_OF_RECORD_PTR(dsp,NetIPCParams,readBlk.dsp);
|
|
auth = (AuthInfoBlkPtr)&(sessPtr->readBlk.authBuf);
|
|
|
|
|
|
if ((dsp->ioResult) || (sessPtr->sessState != AwaitAuthResp)
|
|
|| (dsp->u.ioParams.actCount == 0) || (auth->respType != AuthInfoResp))
|
|
{
|
|
RemoveNetworkConnection(sessPtr,false);
|
|
}
|
|
else
|
|
{
|
|
uRec = (UserRecPbPtr)&(sessPtr->miscData.btreeData);
|
|
if ((auth->authInfo[0] == uRec->encryptedRandom[0]) &&
|
|
(auth->authInfo[1] == uRec->encryptedRandom[1]))
|
|
{
|
|
ProcessInform(sessPtr, uRec->u.record.UserFlags); // Authenticated
|
|
}
|
|
else
|
|
{
|
|
accept = (IPCAcceptBlkPtr)&(sessPtr->writeBlk.buffer);
|
|
accept->rejectInfo = AuthFailure;
|
|
accept->respType = SessReject;
|
|
sessPtr->PBPtr = NULL;
|
|
AcceptNetworkConnection(sessPtr);
|
|
}
|
|
}
|
|
}
|
|
|
|
|
|
/*----------------------------------------------------------------------------------------
|
|
ProcessInform gets a pending PPCInform for the associated port and completes it, it also
|
|
writes back the session accept response. If no Informs are pending for the port, PPC Rejects
|
|
the request and sets the rejectInfo to noInforms.
|
|
----------------------------------------------------------------------------------------*/
|
|
STATIC void ProcessInform(NetIPCParams *sessPtr,unsigned short userFlags)
|
|
{
|
|
IPCStartBlk *sblk; // <44>
|
|
PPCPortEntryPtr portPtr;
|
|
PPCInformPBPtr informPB;
|
|
IPCAcceptBlkPtr accept;
|
|
PBWriteResPtr res;
|
|
|
|
|
|
sblk = (IPCStartBlk *)&(sessPtr->readBlk.buffer);
|
|
portPtr = sessPtr->portEntry;
|
|
accept = (IPCAcceptBlkPtr)&(sessPtr->writeBlk.buffer);
|
|
|
|
if (!(informPB = ServeQueue(&portPtr->informPBQueue)))
|
|
{
|
|
accept->respType = SessReject; // <44> Stuff the message
|
|
accept->rejectInfo = noInforms; // <44> No Oustanding Informs
|
|
sessPtr->PBPtr = NULL; // <44>
|
|
AcceptNetworkConnection(sessPtr);
|
|
return;
|
|
}
|
|
|
|
informPB->sessRefNum = sessPtr->sessRefNum;
|
|
informPB->userData = sblk->userData; // <44>
|
|
informPB->serviceType = ppcServiceRealTime;
|
|
informPB->requestType = ppcRemoteOrigin;
|
|
|
|
res = (PBWriteResPtr)informPB->Reserved;
|
|
if (userFlags & 0x0001)
|
|
res->multiFinder = 0x01;
|
|
else
|
|
res->multiFinder = 0x00;
|
|
|
|
if (informPB->portName)
|
|
CopyPortName(&(sblk->reqportName), informPB->portName);
|
|
|
|
if (informPB->locationName)
|
|
BlockMove((char *)&(sblk->locationName), (char *)(informPB->locationName), sizeof(LocationNameRec));
|
|
|
|
if(sblk->userName[0] < 31)
|
|
{
|
|
if (sblk->userName[0] == 0)
|
|
BlockMove("\p<Guest>",sessPtr->userName,8);
|
|
else
|
|
BlockMove((char *)sblk->userName,sessPtr->userName, sblk->userName[0] +1);
|
|
if (informPB->userName)
|
|
BlockMove((char *)sblk->userName, (informPB->userName), sblk->userName[0] +1);
|
|
}
|
|
|
|
sessPtr->originator = false; // We did not originate this session.
|
|
|
|
if (informPB->autoAccept)
|
|
{
|
|
sessPtr->PBPtr = informPB;
|
|
accept->respType = SessAccept; // <44> Stuff the message
|
|
AcceptNetworkConnection(sessPtr);
|
|
}
|
|
else
|
|
{
|
|
sessPtr->PBPtr = NULL;
|
|
sessPtr->sessState = AwaitAcceptReq;
|
|
CompleteWithResult(informPB,noErr);
|
|
}
|
|
}
|
|
|
|
/*----------------------------------------------------------------------------------------
|
|
RespSendCompletion is chained from AcceptNetworkConnection.
|
|
----------------------------------------------------------------------------------------*/
|
|
STATIC void RespSendCompletion(void)
|
|
{
|
|
DSPParamBlock *dsp;
|
|
NetIPCParams *sessPtr;
|
|
PPCAcceptPBPtr acceptPB;
|
|
PBWriteResPtr res;
|
|
OSErr result;
|
|
|
|
dsp = GetA0();
|
|
sessPtr = TOP_OF_RECORD_PTR(dsp,NetIPCParams,writeBlk.dsp);
|
|
|
|
acceptPB = sessPtr->PBPtr;
|
|
res =(PBWriteResPtr)(acceptPB->Reserved);
|
|
|
|
if ((acceptPB) && (acceptPB->csCode == PPCRejectCall))
|
|
sessPtr->PBPtr = NULL;
|
|
|
|
if ((result=dsp->ioResult) || (acceptPB==nil) || acceptPB->csCode == PPCRejectCall)
|
|
{
|
|
sessPtr->PBPtr = NULL;
|
|
RemoveNetworkConnection(sessPtr,false);
|
|
}
|
|
else
|
|
{
|
|
sessPtr->sessState = DataXferState;
|
|
sessPtr->PBPtr = NULL;
|
|
}
|
|
if (result && acceptPB && acceptPB->csCode == PPCInformCall)
|
|
SetPortInformQue((PPCInformPBPtr)acceptPB, sessPtr->portEntry); // Add the PB back
|
|
else if (acceptPB)
|
|
CompleteWithResult(acceptPB,result?noSessionErr:noErr);
|
|
} // RespSendCompletion
|
|
|
|
/*----------------------------------------------------------------------------------------
|
|
ARepostConnectionListener is chained from ConnectionRequestCompletion.
|
|
----------------------------------------------------------------------------------------*/
|
|
STATIC void ARepostConnectionListener(void)
|
|
{
|
|
RepostConnectionListener(GetA0());
|
|
}
|
|
|
|
STATIC void RepostConnectionListener(DSPParamBlock *dsp)
|
|
{
|
|
PPCGlobalParams *ppcglobPtr;
|
|
ppcglobPtr = (PPCGlobalParams *)getGlobal();
|
|
if (ppcglobPtr->allowIncommingRequests)
|
|
{
|
|
// Incomming Requests are allowed.
|
|
if ((ListenConnectionRequest(dsp, true,
|
|
(ProcPtr)ConnectionRequestCompletion)))
|
|
{
|
|
#ifdef DEBUG
|
|
Debugger(); // should not happen
|
|
#endif
|
|
}
|
|
}
|
|
} // RepostConnectionListener
|
|
|
|
/*----------------------------------------------------------------------------------------
|
|
ListWrite is called to write out the portInfo on an established network connection.
|
|
----------------------------------------------------------------------------------------*/
|
|
STATIC void ListWrite(NetIPCParams *sessPtr)
|
|
{
|
|
IPCReadBlk *rblk; // <44>
|
|
PPCGlobalParams *ppcglobPtr;
|
|
IPCListReqBlkPtr list; // <44>
|
|
Boolean eom;
|
|
unsigned short actCount=0, remCount, reqCount;
|
|
|
|
ppcglobPtr = (PPCGlobalParams *)getGlobal();
|
|
rblk = (IPCReadBlk *)&(sessPtr->readBlk);
|
|
list = (IPCListReqBlkPtr)&(rblk->buffer);
|
|
remCount = list->requestCount - ppcglobPtr->totalCount;
|
|
if (remCount > MaxListEntries)
|
|
reqCount = MaxListEntries;
|
|
else
|
|
reqCount = remCount;
|
|
|
|
eom = true; // assume we are going to exhaust
|
|
ppcglobPtr->listContinue = false; // assume we are going to exhaust
|
|
if (!(GetPortNames(ppcglobPtr,
|
|
&list->portName, // <44>
|
|
false, // nework request
|
|
ppcglobPtr->guestUnchecked, // Secure Machine ports or Not
|
|
ppcglobPtr->listIndex,
|
|
ppcglobPtr->listBuffer,
|
|
reqCount,
|
|
&actCount)))
|
|
{
|
|
ppcglobPtr->totalCount += actCount;
|
|
if (list->requestCount > ppcglobPtr->totalCount)
|
|
{
|
|
// User can receive some more
|
|
eom = false; // we have some more processing
|
|
ppcglobPtr->listContinue = true;
|
|
|
|
}
|
|
}
|
|
else
|
|
ppcglobPtr->totalCount += actCount;
|
|
|
|
ppcglobPtr->listIndex += actCount;
|
|
|
|
WriteToConnection(sizeof(PortInfoRec) * actCount,
|
|
(char *)ppcglobPtr->listBuffer,
|
|
eom, // eom
|
|
1, // flush
|
|
true, // Asynchronously
|
|
(ProcPtr)ListWriteCompletion, // Completion Routine
|
|
(DSPParamBlock *)&(sessPtr->writeBlk.dsp));
|
|
} // ListWrite
|
|
|
|
/*----------------------------------------------------------------------------------------
|
|
ListWriteCompletion is chained from ListWrite.
|
|
----------------------------------------------------------------------------------------*/
|
|
STATIC void ListWriteCompletion(void)
|
|
{
|
|
DSPParamBlock *dsp;
|
|
IPCReadBlk *rblk;
|
|
NetIPCParams *sessPtr, *sessPtr1;
|
|
IPCListReqBlkPtr list;
|
|
IPCListRespBlkPtr resp;
|
|
PPCGlobalParams *ppcglobPtr;
|
|
|
|
dsp = GetA0();
|
|
ppcglobPtr = (PPCGlobalParams *)getGlobal();
|
|
rblk = (IPCReadBlk *)dsp;
|
|
sessPtr = TOP_OF_RECORD_PTR(dsp,NetIPCParams,writeBlk.dsp);
|
|
list = (IPCListReqBlkPtr)&(rblk->buffer);
|
|
|
|
if (dsp->ioResult)
|
|
{
|
|
// some Error occured
|
|
RemoveNetworkConnection(sessPtr,false);
|
|
ppcglobPtr->listsessPtr = sessPtr1 = ServeQueue(&ppcglobPtr->ListSessQueue);
|
|
if (sessPtr1)
|
|
{
|
|
// First Lookfor Guest Icon 2/28/90
|
|
list = (IPCListReqBlkPtr)&sessPtr1->readBlk.buffer;
|
|
ppcglobPtr->totalCount = 0;
|
|
ppcglobPtr->listIndex = list->startIndex;
|
|
|
|
if (ppcglobPtr->ugFile.refNum != 0)
|
|
{
|
|
getUserRec((UserRecPb *)&(sessPtr1->miscData.btreeData),
|
|
0, // Key ID
|
|
(char *)list->userName,
|
|
(ProcPtr)GuestRecCompletion,
|
|
ppcglobPtr->ugFile.refNum);
|
|
}
|
|
else
|
|
{
|
|
ppcglobPtr->guestUnchecked = false;
|
|
ListWrite((NetIPCParams *)(ppcglobPtr->listsessPtr));
|
|
}
|
|
}
|
|
}
|
|
else if (ppcglobPtr->listContinue)
|
|
ListWrite(sessPtr); // need some more writing
|
|
else
|
|
{
|
|
resp = (IPCListRespBlkPtr)&(sessPtr->writeBlk.buffer);
|
|
resp->respType = ListResp; // Stuff the message
|
|
resp->actualCount = ppcglobPtr->totalCount;
|
|
sessPtr->sessState = AwaitListRespComp;
|
|
WriteToConnection(sizeof(IPCListRespBlk),
|
|
(char *)&(sessPtr->writeBlk.buffer),
|
|
1, // eom
|
|
1, // flush
|
|
true, // Asynchronously
|
|
(ProcPtr)ListRespCompletion, // Completion Routine
|
|
&sessPtr->writeBlk.dsp);
|
|
}
|
|
} // ListWriteCompletion
|
|
|
|
/*----------------------------------------------------------------------------------------
|
|
ListRespCompletion is chained from ListWriteCompletion. We have just completed the writing
|
|
the response to an IPCListPorts request. If we have another request pending, we begin processing
|
|
that request here.
|
|
----------------------------------------------------------------------------------------*/
|
|
|
|
STATIC void ListRespCompletion(void)
|
|
{
|
|
DSPParamBlock *dsp;
|
|
IPCReadBlk *rblk;
|
|
NetIPCParams *sessPtr, *sessPtr1;
|
|
IPCListReqBlkPtr list;
|
|
PPCGlobalParams *ppcglobPtr;
|
|
|
|
dsp = GetA0();
|
|
ppcglobPtr = (PPCGlobalParams *)getGlobal();
|
|
rblk = (IPCReadBlk *)dsp;
|
|
sessPtr = TOP_OF_RECORD_PTR(dsp,NetIPCParams,writeBlk.dsp);
|
|
list = (IPCListReqBlkPtr)&(rblk->buffer);
|
|
|
|
RemoveNetworkConnection(sessPtr,false);
|
|
|
|
ppcglobPtr->listsessPtr = sessPtr1 = ServeQueue(&ppcglobPtr->ListSessQueue);
|
|
if (sessPtr1)
|
|
{
|
|
// First Lookfor Guest Icon 2/28/90
|
|
list = (IPCListReqBlkPtr)&sessPtr1->readBlk.buffer;
|
|
ppcglobPtr->totalCount = 0;
|
|
ppcglobPtr->listIndex = list->startIndex;
|
|
if (ppcglobPtr->ugFile.refNum != 0)
|
|
{
|
|
getUserRec((UserRecPb *)&(sessPtr1->miscData.btreeData),
|
|
0, // Key ID
|
|
(char *)list->userName,
|
|
(ProcPtr)GuestRecCompletion,
|
|
ppcglobPtr->ugFile.refNum);
|
|
}
|
|
else
|
|
{
|
|
ppcglobPtr->guestUnchecked = false;
|
|
ListWrite(ppcglobPtr->listsessPtr);
|
|
}
|
|
}
|
|
} // ListRespCompletion
|
|
|
|
/*----------------------------------------------------------------------------------------
|
|
BeginWriteBlock is the first real step in processing of a writePB. It initializes the reserved
|
|
fields for in the PPCWrite PB, and if we are to write a header, we do so, otherwise we call
|
|
WriteBlockData to append data onto the current block.
|
|
----------------------------------------------------------------------------------------*/
|
|
STATIC void BeginWriteBlock(NetIPCParamsPtr sessPtr)
|
|
{
|
|
PBWriteResPtr res; // <44>
|
|
PPCWritePBPtr writePB;
|
|
|
|
// Setup reserved fields in PPCWrite PB to initial values.
|
|
writePB = sessPtr->writePB;
|
|
|
|
res = (PBWriteResPtr)(writePB->Reserved);
|
|
res->length = writePB->bufferLength;
|
|
res->curBufPos = writePB->bufferPtr;
|
|
if(sessPtr->writeHdr)
|
|
{
|
|
IPCHdrBlk *hdr; // <44>
|
|
Boolean HeaderOnly; // True if client just wants the header only written.
|
|
|
|
// This pisses me off, If I could change the protocol,
|
|
// I could save 12 bytes, and the following 4 lines of code.
|
|
hdr = &sessPtr->writeBlk.buffer.buffer.headerBlk;
|
|
hdr->blockCreator = writePB->blockCreator;
|
|
hdr->blockType = writePB->blockType;
|
|
hdr->userData = writePB->userData;
|
|
HeaderOnly = !writePB->more && !writePB->bufferLength; // usually false!
|
|
sessPtr->writeHdr = !writePB->more; // for next PPCWrite pb.
|
|
|
|
WriteToConnection(sizeof(IPCHdrBlk),
|
|
(char *)hdr,
|
|
HeaderOnly, // eom.
|
|
HeaderOnly, // flush.
|
|
true, // Asynchronously
|
|
(ProcPtr)WriteHdrCompletion, // Completion Routine
|
|
&sessPtr->writeBlk.dsp);
|
|
}
|
|
else
|
|
WriteBlockData(sessPtr);
|
|
}
|
|
|
|
|
|
/*----------------------------------------------------------------------------------------
|
|
WriteHdrCompletion is chained from BeginWriteBlock. Assuming success, and their is data that
|
|
is to follow the header, we call WrtieBlockData to handle that, otherwise we complete their
|
|
PPCWrite call.
|
|
----------------------------------------------------------------------------------------*/
|
|
STATIC void WriteHdrCompletion(void)
|
|
{
|
|
DSPParamBlock *dsp; // <44>
|
|
NetIPCParamsPtr sessPtr;
|
|
PPCWritePBPtr writePB;
|
|
|
|
dsp = GetA0();
|
|
sessPtr = TOP_OF_RECORD_PTR(dsp,NetIPCParams,writeBlk.dsp);
|
|
|
|
if (dsp->ioResult)
|
|
{
|
|
RemoveNetworkConnection(sessPtr,false);
|
|
return;
|
|
}
|
|
|
|
writePB = sessPtr->writePB;
|
|
if(writePB->bufferLength)
|
|
WriteBlockData(sessPtr);
|
|
else
|
|
CompleteWriteRequest(sessPtr,noErr);
|
|
}
|
|
|
|
/*----------------------------------------------------------------------------------------
|
|
WriteBlockData is responsible for writing the data portion of a PPCBlock. It breaks a block
|
|
into MaxADSPWrite size chuncks so that ADSP can easily swallow it.
|
|
----------------------------------------------------------------------------------------*/
|
|
STATIC void WriteBlockData(NetIPCParamsPtr sessPtr)
|
|
{
|
|
unsigned short len;
|
|
unsigned char eom;
|
|
PBWriteResPtr res; // <44>
|
|
PPCWritePBPtr writePB;
|
|
|
|
writePB = sessPtr->writePB;
|
|
res = (PBWriteResPtr)(writePB->Reserved);
|
|
if (res->length > MaxADSPWrite)
|
|
{
|
|
len = MaxADSPWrite;
|
|
eom =false;
|
|
}
|
|
else
|
|
{
|
|
len = res->length; // <44>
|
|
eom = !writePB->more;
|
|
}
|
|
sessPtr->writeHdr = !writePB->more;
|
|
|
|
WriteToConnection(len,
|
|
res->curBufPos,
|
|
eom, // eom
|
|
eom, // flush when we finish a block.
|
|
true, // Asynchronously
|
|
(ProcPtr)WriteBlockDataCompletion, // Completion Routine
|
|
&sessPtr->writeBlk.dsp);
|
|
}
|
|
|
|
/*----------------------------------------------------------------------------------------
|
|
WriteBlockDataCompletion is chained from WriteBlockData. If more data for a given PPCWrite
|
|
is to be written, it calls WriteBlockData, otherwise the Write PB has completed, and it is
|
|
time to complete that, and process any pending writes.
|
|
----------------------------------------------------------------------------------------*/
|
|
STATIC void WriteBlockDataCompletion(void)
|
|
{
|
|
DSPParamBlock *dsp; // <44>
|
|
NetIPCParamsPtr sessPtr;
|
|
PPCWritePBPtr writePB;
|
|
PBWriteResPtr res;
|
|
|
|
dsp = GetA0();
|
|
sessPtr = TOP_OF_RECORD_PTR(dsp,NetIPCParams,writeBlk.dsp);
|
|
writePB = sessPtr->writePB;
|
|
res = (PBWriteResPtr)(writePB->Reserved);
|
|
|
|
// Update reserved fields to indicate the amount to be written.
|
|
res->length -= dsp->u.ioParams.actCount;
|
|
res->curBufPos += dsp->u.ioParams.actCount;
|
|
writePB->actualLength += dsp->u.ioParams.actCount;
|
|
|
|
if (dsp->ioResult)
|
|
{
|
|
RemoveNetworkConnection(sessPtr,false);
|
|
return;
|
|
}
|
|
|
|
if(res->length) // <44> if there is more to write
|
|
{
|
|
WriteBlockData(sessPtr);
|
|
}
|
|
else
|
|
{
|
|
CompleteWriteRequest(sessPtr,noErr);
|
|
}
|
|
}
|
|
|
|
/*----------------------------------------------------------------------------------------
|
|
CompleteWriteRequest is responsible for completing a current write request, and start the next
|
|
if any are pending.
|
|
----------------------------------------------------------------------------------------*/
|
|
STATIC void CompleteWriteRequest(NetIPCParamsPtr sessPtr,OSErr result)
|
|
{
|
|
short sr;
|
|
|
|
CompleteWithResult(sessPtr->writePB,result);
|
|
|
|
sr = spl(kNoInterrupts);
|
|
if(sessPtr->writePB = GetWritePB(sessPtr))
|
|
{
|
|
spl(sr);
|
|
BeginWriteBlock(sessPtr);
|
|
}
|
|
else
|
|
spl(sr);
|
|
}
|
|
|
|
|
|
/*----------------------------------------------------------------------------------------
|
|
BeginReadBlock
|
|
----------------------------------------------------------------------------------------*/
|
|
|
|
STATIC void BeginReadBlock(NetIPCParamsPtr sessPtr)
|
|
{
|
|
PPCReadPBPtr readPB;
|
|
PBReadResPtr res; // <44>
|
|
IPCHdrBlk *hdr; // <44>
|
|
readPB = sessPtr->readPB;
|
|
// Setup reserved fields in PPCRead PB to initial values.
|
|
res = (PBReadResPtr)(readPB->Reserved);
|
|
res->length = readPB->bufferLength; // Count down from this length.
|
|
res->curBufPos = readPB->bufferPtr;
|
|
if(!sessPtr->readMore) // if readHeader.
|
|
{
|
|
ReadFromConnection(sizeof(IPCHdrBlk),
|
|
(Ptr)&sessPtr->readBlk.buffer,
|
|
true, // Asynchronously
|
|
(ProcPtr)ReadHdrCompletion, // completion Routine
|
|
&sessPtr->readBlk.dsp);
|
|
}
|
|
else
|
|
{
|
|
hdr = &sessPtr->readBlk.buffer.buffer.headerBlk;
|
|
readPB->blockCreator = hdr->blockCreator;
|
|
readPB->blockType = hdr->blockType;
|
|
readPB->userData = hdr->userData;
|
|
ReadBlockData(sessPtr);
|
|
}
|
|
}
|
|
|
|
/*----------------------------------------------------------------------------------------
|
|
ReadHdrCompletion is chained from ReadData.
|
|
----------------------------------------------------------------------------------------*/
|
|
STATIC void ReadHdrCompletion(void)
|
|
{
|
|
DSPParamBlock *dsp; // <44>
|
|
PPCReadPBPtr readPB;
|
|
NetIPCParamsPtr sessPtr;
|
|
PBReadResPtr res; // <44>
|
|
IPCHdrBlk *hdr;
|
|
dsp = GetA0();
|
|
sessPtr = TOP_OF_RECORD_PTR(dsp,NetIPCParams,readBlk);
|
|
readPB = sessPtr->readPB;
|
|
res = (PBReadResPtr)(readPB->Reserved);
|
|
readPB->more = sessPtr->readMore = !dsp->u.ioParams.eom; // do we need to read a different header?
|
|
|
|
if (dsp->ioResult || (dsp->u.ioParams.actCount == 0 && dsp->u.ioParams.eom == 0) &&
|
|
(sessPtr->ce.state == sClosing || sessPtr->ce.state == sClosed))
|
|
{
|
|
RemoveNetworkConnection(sessPtr,false);
|
|
return;
|
|
}
|
|
|
|
hdr = &sessPtr->readBlk.buffer.buffer.headerBlk;
|
|
readPB->blockCreator = hdr->blockCreator;
|
|
readPB->blockType = hdr->blockType;
|
|
readPB->userData = hdr->userData;
|
|
|
|
if(sessPtr->readMore)
|
|
ReadBlockData(sessPtr);
|
|
else
|
|
CompleteReadRequest(sessPtr,noErr);
|
|
}
|
|
|
|
/*----------------------------------------------------------------------------------------
|
|
ReadBlockData
|
|
----------------------------------------------------------------------------------------*/
|
|
|
|
STATIC void ReadBlockData(NetIPCParamsPtr sessPtr)
|
|
{
|
|
PBReadResPtr res;
|
|
unsigned short len;
|
|
|
|
res = (PBReadResPtr)(sessPtr->readPB->Reserved);
|
|
|
|
len = res->length < MaxADSPWrite?res->length:MaxADSPWrite;
|
|
if (len) // User Does not want to read zero bytes
|
|
{
|
|
ReadFromConnection(len,
|
|
res->curBufPos,
|
|
true, // Asynchronously
|
|
(ProcPtr)ReadDataCompletion, // completion Routine
|
|
&sessPtr->readBlk.dsp);
|
|
}
|
|
else
|
|
CompleteReadRequest(sessPtr,noErr);
|
|
}
|
|
|
|
/*----------------------------------------------------------------------------------------
|
|
ReadDataCompletion
|
|
----------------------------------------------------------------------------------------*/
|
|
STATIC void ReadDataCompletion(void)
|
|
{
|
|
DSPParamBlock *dsp; // <44>
|
|
PPCReadPBPtr readPB;
|
|
NetIPCParamsPtr sessPtr;
|
|
PBReadResPtr res;
|
|
|
|
|
|
dsp = GetA0();
|
|
sessPtr = TOP_OF_RECORD_PTR(dsp,NetIPCParams,readBlk);
|
|
readPB = sessPtr->readPB;
|
|
res = (PBReadResPtr)(readPB->Reserved);
|
|
|
|
res->length -= dsp->u.ioParams.actCount; // we have this much less to read.
|
|
res->curBufPos += dsp->u.ioParams.actCount; // next spot to append to clients buffer.
|
|
readPB->actualLength += dsp->u.ioParams.actCount; // update how much we put into clients buffer.
|
|
readPB->more = sessPtr->readMore = !dsp->u.ioParams.eom; // do we need to read a different header?
|
|
|
|
|
|
if (dsp->ioResult || (dsp->u.ioParams.actCount == 0 && dsp->u.ioParams.eom == 0) &&
|
|
(sessPtr->ce.state == sClosing || sessPtr->ce.state == sClosed))
|
|
{
|
|
RemoveNetworkConnection(sessPtr,false);
|
|
return;
|
|
}
|
|
|
|
if(res->length && sessPtr->readMore) // <44>
|
|
ReadBlockData(sessPtr);
|
|
else // EOM or clients buffer full.
|
|
CompleteReadRequest(sessPtr,noErr);
|
|
} // ReadDataCompletion
|
|
|
|
|
|
/*----------------------------------------------------------------------------------------
|
|
CompleteReadRequest is responsible for completing a current read request, and start the next
|
|
if any are pending for this session.
|
|
----------------------------------------------------------------------------------------*/
|
|
STATIC void CompleteReadRequest(NetIPCParamsPtr sessPtr,OSErr result)
|
|
{
|
|
short sr;
|
|
|
|
CompleteWithResult(sessPtr->readPB,result);
|
|
|
|
sr = spl(kNoInterrupts);
|
|
if(sessPtr->readPB = GetReadPB(sessPtr))
|
|
{
|
|
spl(sr);
|
|
BeginReadBlock(sessPtr);
|
|
}
|
|
else
|
|
spl(sr);
|
|
}
|
|
|
|
/*----------------------------------------------------------------------------------------
|
|
CopyReadBlk, copies the contents of a DSP parameter block (used for read operations). To a
|
|
another parameter block (used for writing).
|
|
----------------------------------------------------------------------------------------*/
|
|
STATIC void CopyReadBlk(NetIPCParamsPtr sessPtr)
|
|
{
|
|
BlockMove((char *)&(sessPtr->readBlk.dsp),
|
|
(char *)&(sessPtr->writeBlk.dsp),
|
|
sizeof(DSPParamBlock));
|
|
|
|
} // CopyReadBlk
|