Retired Document
Important: This sample code may not represent best practices for current development. The project may use deprecated symbols and illustrate technologies and techniques that are no longer recommended.
ZIP.c
/*------------------------------------------------------------------------------ |
# |
# ZIP.c : this module contains the Zone Information Protocol functions |
# to get zone names for both AppleTalk Phase 1 and Phase 2. |
# |
# |
# Versions: 1.0 10/91 |
# Built with MPW 3.2 |
# |
# C.Buttin - Apple Computer Europe |
# |
------------------------------------------------------------------------------*/ |
#include <Memory.h> |
#include <ToolUtils.h> |
#include <Devices.h> |
#include <AppleTalk.h> |
/* GetZones : returns the list of zones |
If Phase 2 driver available |
issues XPP calls |
else |
issues ATP calls |
Input : |
- a buffer to contain the list |
- buffer size |
Output : |
- total number of zones |
or |
-1 : buffer was to small |
or |
error : an error occured */ |
pascal short GetZones(Ptr buffer,short bufsize); |
/* GetZoneName : Extract a zone name from the buffer list |
Input : |
- buffer containing the zone list |
- index of the zone to be retrieved |
- Pascal string to receive the zone name (empty string if error) */ |
pascal void GetZoneName(char* buffer,short zoneNumber,char* zoneName); |
/* XPP functions */ |
/* InitXPP : Open the .XPP driver */ |
pascal OSErr InitXPP(short *driverNum); |
/* XPPGetZoneList : returns the list of zones |
Input : |
- a buffer to contain the list |
- buffer size |
Output : |
- total number of zones |
or |
-1 : buffer was to small |
or |
error : an error occured */ |
pascal short XPPGetZoneList(Ptr buffer,short bufsize,short driverNum); |
/* ATP functions */ |
/* InitATP : Open the .ATP driver */ |
pascal OSErr InitATP(void ); |
/* ATPGetZoneList : returns the list of zones |
Input : |
- a buffer to contain the list |
- buffer size |
Output : |
- total number of zones |
or |
-1 : buffer was to small |
or |
error : an error occured */ |
pascal short ATPGetZoneList(Ptr buffer,short bufsize); |
pascal short GetZones(Ptr buffer,short bufsize) |
{ |
SysEnvRec theConfig; |
short driverNum; |
OSErr error; |
SysEnvirons(1, &theConfig); |
if (theConfig.atDrvrVersNum < 53) { /* phase 1 calls */ |
if ((error = InitATP()) == noErr) |
return(ATPGetZoneList(buffer,bufsize)); |
else |
return error; |
} |
else { /* phase 2 calls */ |
if ((error = InitXPP(&driverNum)) == noErr) |
return XPPGetZoneList(buffer,bufsize,driverNum); |
else |
return error; |
} |
} |
/* XPP functions */ |
pascal OSErr InitXPP(short *driverNum) |
{ |
OSErr error; |
/* open .MPP driver and .ATP driver */ |
if ((error = InitATP()) != noErr) |
return error; |
/* Open .XPP driver */ |
return OpenXPP(driverNum) ; |
} /* InitXPP */ |
pascal short XPPGetZoneList(Ptr buffer,short bufsize,short driverNum) |
{ |
Ptr theBufferPtr; |
short numzone; |
short dataSize; |
Ptr p; |
OSErr error; |
XCallParam XPPBlock; |
Debugger(); |
numzone = 0; |
dataSize = 0; |
p = (Ptr)buffer; |
theBufferPtr = NewPtr(578); /* ZIP buffer (must be 578 bytes) */ |
/* set XPP record */ |
XPPBlock.zipInfoField[0] = 0; /* ALWAYS 0 on first call. contains state info |
on subsequent calls */ |
XPPBlock.zipInfoField[1] = 0; /* ALWAYS 0 on first call. contains state info |
on subsequent calls */ |
/* initialization for loop */ |
XPPBlock.ioRefNum = driverNum; |
XPPBlock.zipLastFlag = 0; |
XPPBlock.csCode = xCall; |
XPPBlock.xppSubCode = zipGetZoneList; |
XPPBlock.xppTimeout = 3; |
XPPBlock.xppRetry = 4; |
XPPBlock.zipBuffPtr = theBufferPtr; |
do { |
if ((error = GetZoneList((XPPParmBlkPtr)&XPPBlock, false)) != noErr) { |
DisposPtr(theBufferPtr); |
return error; |
} |
/* Get the actual number of zones */ |
numzone = numzone + XPPBlock.zipNumZones; |
dataSize = 33 * numzone; /* 33 char. for each zone */ |
if (bufsize - dataSize <= 0) { /* buffer overflow */ |
DisposPtr(theBufferPtr); |
return -1; |
} |
/* copy to buffer */ |
BlockMove(theBufferPtr,p,(long)33*XPPBlock.zipNumZones); |
p = (Ptr)buffer + dataSize; |
} |
while (XPPBlock.zipLastFlag == 0); /* ZIP sets user bytes to 0, while all |
the data have not been provided */ |
DisposPtr(theBufferPtr); |
return numzone; |
} /* XPPGetZoneList */ |
/** ATP functions **/ |
#pragma segment Main |
pascal OSErr InitATP(void) |
{ |
OSErr error; |
if ((error = MPPOpen()) != noErr) |
return error; |
/* open .ATP driver */ |
return (ATPLoad()); |
} /* InitATP */ |
pascal short ATPGetZoneList(Ptr buffer,short bufsize) |
{ |
short numzone; |
short node; |
BDSElement bdsp; |
short dataSize; |
ATPParamBlock ATPBlock; /* to build parameter block for ATP */ |
OSErr error; |
/* Get the address of a bridge (node value of the address) */ |
if ((node = GetBridgeAddress()) == 0) |
return 0; |
dataSize = 0; |
numzone = 0; |
/* set ATP record */ |
ATPBlock.SREQ.ioCompletion = nil; /* no completion routine */ |
ATPBlock.SREQ.addrBlock.aNet = 0; /* set destination address : current net */ |
ATPBlock.SREQ.addrBlock.aNode = node; /* bridge address */ |
ATPBlock.SREQ.addrBlock.aSocket = 6; /* ZIP socket */ |
ATPBlock.SREQ.atpFlags = 0; /* Control flags : ALO Request */ |
ATPBlock.SREQ.filler = 1; /* numOfBuffs : ZIP expects 1 */ |
ATPBlock.SREQ.timeOutVal = 1; /* timeout interval (in seconds) */ |
ATPBlock.SREQ.retryCount = 5; /* number of retries */ |
ATPBlock.SREQ.reqPointer = nil; /* number of retries */ |
ATPBlock.SREQ.reqLength = 0; |
do { |
if (bufsize - dataSize <= 0) /* buffer overflow */ |
return -1; |
bdsp.buffPtr = buffer+dataSize; /* set the received buffer */ |
bdsp.buffSize = bufsize - dataSize; |
ATPBlock.SREQ.userData = 0x08000000+numzone+1; /* specify GetZoneList from zone n */ |
ATPBlock.SREQ.bdsPointer = (Ptr)&bdsp; /* response BDS */ |
if ((error = PSendRequest((ATPPBPtr)&ATPBlock,false)) != noErr) |
return error; |
/* Get the actual number of zones */ |
numzone = numzone + LoWord(bdsp.userBytes); |
dataSize = dataSize + bdsp.dataSize; |
} |
while (HiWord(bdsp.userBytes) == 0); /* ZIP sets user bytes to 0, while all |
the data have not been provided */ |
return(numzone); |
} /* ATPGetZoneList */ |
pascal void GetZoneName(char* buffer,short zoneNumber,char* zoneName) |
{ |
short i,j,lgzone; |
for (i = 1; i <= zoneNumber;i++) { |
lgzone = *buffer; |
for (j = 0;j <= lgzone;j++) /* build zone name */ |
if (i == zoneNumber) |
*zoneName++ = *buffer++; |
else |
buffer++; |
} |
} /* GetZoneName */ |
Copyright © 2003 Apple Computer, Inc. All Rights Reserved. Terms of Use | Privacy Policy | Updated: 2003-01-14