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.
Talk.c
#include <Stdio.h> |
#include <Memory.h> |
#include <Types.h> |
#include <CursorCtl.h> |
#include <AppleTalk.h> |
#include <Packages.h> |
#include <Events.h> |
#include <SysEqu.h> |
#include <Desk.h> |
#include <Devices.h> |
#include <Errors.h> |
/* |
© Copyright 1989 Apple Computer, Inc. |
This is an MPW 3.0 tool to demonstrate how AppleTalk calls are implemented in MPW C 3.0 |
and assembler 3.0. |
AppleTalk protocols shown are: |
NBP |
DDP |
Echo |
ATP |
ZIP |
The functions we provide here are: |
Register a name in the network, the user provides an object name and a type, |
the tool provides a dummy socket listener so the socket does not get reused |
by another process. |
Lookup names in the network, the user can optionally give as parameters an |
object name, a type name, a zone or a combination of the three as search |
criteria. Initial buffer allocated is for 200 names. |
Write a DDP packet. The user provides a destination network number, |
destination node, socket, ddpType and optional data. Before sending |
a ddp packet a socket is opened and a socket listener installed in case |
we receive a response, then the packet is sent out and we wait 30 |
seconds for a response. If a response is received then we display the |
data we got. |
The socket and its listener are then disposed of. |
Write an ATP packet. The user provides a destination network number, |
destination node, socket, atpUserData and optional data. The packet |
is sent out as a transaction request and we wait 30 seconds for a response. |
If a response is received then we display the data we got back. |
Write an Echo packet. The user provides a destination network number, |
destination node, and optional data. To send an Echo packet we first |
create a ddp socket and a socket listener to receive the echo reply. |
The packet is sent out and we wait 30 seconds for the echo reply. |
If a reply is received then we display the data we got. |
The ddp socket and its listener are then disposed of. |
Set SelfSend flag. This enables or disables the capability to send |
and receive packets from our own machine. |
Zone names can be requested from the network, and the zone to which |
this machine belongs is pointed out to the user. |
NOTE: THIS TOOL IS NOT FULLY COMMENTED BECAUSE A NEW VERSION WILL BE |
IMPLEMENTED IN C++ |
Written by Ricardo Batista. 1/12/89 |
*/ |
#define Buf 20000 |
#define TRUE -1 |
#define FALSE 0 |
#define GetZoneList 0x8000000 |
#define GetMyZone 0x7000000 |
pascal void InitDDPListener(ATDDPRec *ddp); |
pascal void DDPListener(void); |
typedef struct { |
short moveq0_d3; |
long jmp2_a4; |
} dumb_listener; |
void DoDDP(int argc, char* argv[], Boolean echo); |
Boolean Abort(void); |
void SetSelf(char* argv[]); |
void Usage(char* argv[]); |
void Names(int argc, char* argv[]); |
void DoATP(int argc, char* argv[]); |
void DoRegName(int argc, char* argv[]); |
void DoZones(char* argv[]); |
short mpp; |
int main(int argc, char* argv[]) |
{ |
short err; |
char *copyright = {"© 1989 Apple Computer, Inc. By Ricardo Batista"}; |
// short counter; |
// fprintf(stdout,"argc = %d\n",argc); |
// for (counter = 0; counter < argc; counter++) |
// fprintf(stdout,"argv[%d] = %s\n",counter,argv[counter]); |
// fflush(stdout); |
if (argc < 2) { |
Usage(argv); |
return(1); |
} |
InitCursorCtl(0L); |
SpinCursor(1); |
err = OpenDriver("\p.MPP",&mpp); |
if (err) { |
fprintf(stderr,"## %s: Error opening AppleTalk %d\n",argv[0],err); |
return(1); |
} |
SpinCursor(1); |
if ((argv[1][0] == '-') && ((argv[1][1] == 'n') || (argv[1][1] == 'N'))) { |
Names(argc, argv); |
} |
if ((argv[1][0] == '-') && ((argv[1][1] == 'r') || (argv[1][1] == 'R'))) { |
if (argc != 6) { |
Usage(argv); |
return(1); |
} |
DoRegName(argc, argv); |
} |
if ((argv[1][0] == '-') && ((argv[1][1] == 's') || (argv[1][1] == 'S'))) { |
if (argc != 3) { |
Usage(argv); |
return(1); |
} |
SetSelf(argv); |
} |
if ((argv[1][0] == '-') && ((argv[1][1] == 'd') || (argv[1][1] == 'D'))) { |
if (argc < 6) { |
Usage(argv); |
return(1); |
} |
DoDDP(argc, argv, false); |
} |
if ((argv[1][0] == '-') && ((argv[1][1] == 'e') || (argv[1][1] == 'E'))) { |
if (argc < 3) { |
Usage(argv); |
return(1); |
} |
DoDDP(argc, argv, true); |
} |
if ((argv[1][0] == '-') && ((argv[1][1] == 'a') || (argv[1][1] == 'A'))) { |
if (argc < 6) { |
Usage(argv); |
return(1); |
} |
DoATP(argc, argv); |
} |
if ((argv[1][0] == '-') && ((argv[1][1] == 'z') || (argv[1][1] == 'Z'))) { |
if (argc < 1) { |
Usage(argv); |
return(1); |
} |
DoZones(argv); |
} |
return(0); |
} |
void DoRegName(int argc, char* argv[]) |
{ |
EntityName name; |
short err, counter, len; |
THz zone; |
MPPParamBlock p; |
NamesTableEntry *NTPtr; |
short index; |
unsigned char socket; |
dumb_listener *listener; |
SpinCursor(1); |
zone = GetZone(); |
SetZone(SystemZone()); |
listener = (dumb_listener*) NewPtr(sizeof(dumb_listener)); |
SetZone(zone); |
if (!listener) { |
fprintf(stderr,"## %s: Error getting space for socket listener\n\n",argv[0]); |
return; |
} |
listener->moveq0_d3 = 0x7600; |
listener->jmp2_a4 = 0x4EEC0002; |
p.MPPioCompletion = 0L; |
p.MPPioRefNum = mpp; |
p.DDPsocket = 0; |
p.DDPlistener = (Ptr) listener; |
err = POpenSkt(&p,FALSE); |
socket = p.DDPsocket; |
if (err) { |
fprintf(stderr,"## %s: Error opening socket %d\n\n",argv[0],err); |
return; |
} |
if (!socket) { |
fprintf(stderr,"## %s: Could not open socket, socket = %d, err = %d\n",argv[0],(short) socket,err); |
return; |
} |
name.objStr[1] = 0; |
name.typeStr[1] = 0; |
name.zoneStr[1] = 0; |
name.objStr[0] = '='; |
name.typeStr[0] = '='; |
name.zoneStr[0] = '*'; |
for (counter = 2; counter < argc; counter++) { |
if (argv[counter][0] == '-') { |
if ((argv[counter][1] == 'o') || (argv[counter][1] == 'O')) { |
BlockMove(argv[counter + 1],name.objStr,33L); |
} |
if ((argv[counter][1] == 't') || (argv[counter][1] == 'T')) { |
BlockMove(argv[counter + 1],name.typeStr,33L); |
} |
} |
} |
len = sizeof(NamesTableEntry); |
if ((name.typeStr[0] == '=') || (name.objStr[0] == '=')) { |
fprintf(stderr,"## %s: Object and type names must not be any of '@ * = :'\n",argv[0]); |
return; |
} |
zone = GetZone(); |
SetZone(SystemZone()); |
NTPtr = (NamesTableEntry*) NewPtr(len); |
SetZone(zone); |
if (!NTPtr) { |
fprintf(stderr,"## %s: Not enough memory.\n",argv[0]); |
return; |
} |
NTPtr->nt.nteAddress.aSocket = socket; |
p.NBPinterval = 3; |
p.NBPcount = 3; |
p.NBPverifyFlag = TRUE; |
p.NBPntQElPtr = (Ptr) NTPtr; |
fprintf(stdout,"## %s: Registering: '%s:%s@*'\n\n",argv[0],name.objStr,name.typeStr); |
fflush(stdout); |
c2pstr(name.objStr); |
c2pstr(name.typeStr); |
c2pstr(name.zoneStr); |
BlockMove(name.objStr,&(NTPtr->nt.entityData[0]),33L); |
index = name.objStr[0] + 1; |
BlockMove(name.typeStr,&(NTPtr->nt.entityData[index]),33L); |
index += name.typeStr[0] + 1; |
BlockMove(name.zoneStr,&(NTPtr->nt.entityData[index]),33L); |
err = PRegisterName(&p,TRUE); |
while ((p.MPPioResult > 0) && !Abort()) |
SpinCursor(1); |
err = p.MPPioResult; |
while (err == nbpDuplicate) { |
fprintf(stdout,"## %s: Duplicate name being modified\n",argv[0]); |
fflush(stdout); |
name.objStr[0]++; |
name.objStr[name.objStr[0]] = '1'; |
BlockMove(name.objStr,&(NTPtr->nt.entityData[0]),33L); |
index = name.objStr[0] + 1; |
BlockMove(name.typeStr,&(NTPtr->nt.entityData[index]),33L); |
index += name.typeStr[0] + 1; |
BlockMove(name.zoneStr,&(NTPtr->nt.entityData[index]),33L); |
err = PRegisterName(&p,TRUE); |
while ((p.MPPioResult > 0) && !Abort()) |
SpinCursor(1); |
err = p.MPPioResult; |
} |
if (err) |
fprintf(stderr,"## %s: err = %d\n",argv[0],err); |
else |
fprintf(stdout,"## %s: Socket %d\n\n",argv[0],(short) socket); |
} |
void DoATP(int argc, char* argv[]) |
{ |
ATPParamBlock a; |
short err = 0, counter, newline; |
long num; |
Str255 st; |
short len; |
char buffer[578],smallBuffer[5]; |
BDSElement bds; |
a.ATPioCompletion = 0L; |
a.ATPatpSocket = 0; |
BlockMove(argv[2],st,33L); |
c2pstr(st); |
StringToNum(st,&num); |
a.ATPaddrBlock.aNet = (short) num; |
BlockMove(argv[3],st,33L); |
c2pstr(st); |
StringToNum(st,&num); |
a.ATPaddrBlock.aNode = (short) num; |
BlockMove(argv[4],st,33L); |
c2pstr(st); |
StringToNum(st,&num); |
a.ATPaddrBlock.aSocket = (short) num; |
BlockMove(argv[5],st,33L); |
c2pstr(st); |
StringToNum(st,&num); |
a.ATPuserData = num; |
a.ATPatpFlags = 0; |
a.ATPreqLength = 0; |
a.ATPreqPointer = 0L; |
a.ATPnumOfBuffs = 1; |
a.ATPtimeOutVal = 4; |
a.ATPretryCount = 3; |
a.ATPbdsPointer = (Ptr) &bds; |
bds.buffSize = 600; |
bds.buffPtr = &buffer[0]; |
bds.dataSize = 0; |
bds.userBytes = 0L; |
buffer[0] = 0; |
len = 0; |
if (argc > 6) { |
a.ATPreqPointer = argv[6]; |
len = strlen(argv[6]); |
fprintf(stdout,"## %s: ATPData to write is %d bytes\n",argv[0],len); |
a.ATPreqLength = len; |
} |
fflush(stdout); |
err = PSendRequest(&a,TRUE); |
while ((a.ATPioResult > 0) && !Abort()) |
SpinCursor(1); |
err = a.ATPioResult; |
if (err) { |
if (err == 1) |
PKillSendReq(&a,false); |
} |
if (err) |
fprintf(stderr,"## %s: Error doing ATPRequest %d\n",argv[0],err); |
else { |
fprintf(stdout,"## %s: ATP packet sent, %d ATPData bytes sent.\n",argv[0],len); |
fprintf(stdout,"## %s: Response user data is %ld = '",argv[0],bds.userBytes); |
BlockMove((Ptr) &(bds.userBytes),(Ptr) &smallBuffer[0],4L); |
smallBuffer[4] = 0; |
fprintf(stdout,"%s'\n\n",smallBuffer); |
len = bds.dataSize; |
fprintf(stdout,"## %s: Actual response bytes: %d\n",argv[0],len); |
if (len) { |
for (counter = 0; counter < len; counter++, newline++) { |
fprintf(stdout,"%c",buffer[counter]); |
if (buffer[counter] == '\n') |
newline = 0; |
if ((newline % 70) == 0) |
fprintf(stdout,"\n"); |
} |
} |
} |
fprintf(stdout,"\n\n"); |
} |
void DoDDP(int argc, char* argv[], Boolean echo) |
{ |
MPPParamBlock p; |
short err = 0; |
unsigned char socket = 0; |
long num; |
Str255 st; |
short len, type; |
char buffer[600]; |
long ticks; |
int counter; |
WDSElement wds[4]; |
AddrBlock address; |
unsigned char header[20]; |
ATDDPRec ddp; |
char echoRequest = 1; |
ddp.abResult = 1; |
ddp.ddpActCount = 0; |
ddp.ddpReqCount = 586; |
ddp.ddpDataPtr = buffer; |
p.MPPioCompletion = 0L; |
p.MPPioRefNum = mpp; |
p.DDPsocket = 0; |
p.DDPlistener = (Ptr) (ProcPtr) DDPListener; |
err = POpenSkt(&p,FALSE); |
socket = p.DDPsocket; |
if (err) { |
fprintf(stderr,"## %s: Error opening socket %d\n\n",argv[0],err); |
return; |
} |
if (!socket) { |
fprintf(stderr,"## %s: Could not open socket, socket = %d, err = %d\n",argv[0],(short) socket,err); |
return; |
} |
InitDDPListener(&ddp); |
fprintf(stdout,"## %s: Temporary Socket is %d\n",argv[0],(short) socket); |
fflush(stdout); |
BlockMove(argv[2],st,33L); |
c2pstr(st); |
StringToNum(st,&num); |
address.aNet = (short) num; |
BlockMove(argv[3],st,33L); |
c2pstr(st); |
StringToNum(st,&num); |
address.aNode = (short) num; |
len = 0; |
wds[2].entryLength = 0; |
wds[2].entryPtr = 0L; |
wds[3].entryLength = 0; |
wds[3].entryPtr = 0L; |
if (!echo) { |
BlockMove(argv[4],st,33L); |
c2pstr(st); |
StringToNum(st,&num); |
address.aSocket = (short) num; |
BlockMove(argv[5],st,33L); |
c2pstr(st); |
StringToNum(st,&num); |
type = num; // ddpType to use |
if (argc > 6) { |
len = strlen(argv[6]); |
fprintf(stdout,"## %s: DDPData to write is %d bytes\n",argv[0],len); |
} |
wds[1].entryPtr = argv[6]; |
wds[1].entryLength = len; |
} |
else { |
address.aSocket = 4; |
type = 4; |
len = strlen(argv[4]); |
fprintf(stdout,"## %s: Echo protocol data to write is %d bytes\n",argv[0],len); |
wds[1].entryLength = 1; |
wds[1].entryPtr = &echoRequest; |
wds[2].entryLength = len; |
wds[2].entryPtr = argv[4]; |
} |
p.MPPioResult = 1; |
p.MPPioCompletion = 0L; |
p.MPPioRefNum = mpp; |
p.DDPchecksumFlag = FALSE; |
p.DDPsocket = socket; |
p.DDPwdsPointer = (Ptr) wds; |
fflush(stdout); |
wds[0].entryPtr = &header[1]; |
wds[0].entryLength = 16; |
BlockMove((Ptr) &address.aNet,&header[8],2L); |
header[12] = address.aNode; |
header[14] = address.aSocket; |
header[16] = type; |
err = PWriteDDP(&p,TRUE); |
while ((p.MPPioResult > 0) && !Abort()) |
SpinCursor(1); |
if (!err) |
err = p.MPPioResult; |
if (err) |
fprintf(stderr,"## %s: Error doing DDPWrite %d\n",argv[0],err); |
else { |
ticks = TickCount() + 1800; |
fprintf(stdout,"## %s: DDP packet type %d sent, %d DDPData bytes sent.\n",argv[0],type,len); |
fprintf(stdout,"## %s: waiting for a response (30 seconds)...\n",argv[0]); |
fflush(stdout); |
while ((ticks > TickCount()) && (ddp.abResult == 1) && !Abort()) |
SpinCursor(1); |
if (ddp.abResult == 0) { |
len = ddp.ddpActCount; |
fprintf(stdout,"## %s: Response received... %d bytes\n",argv[0],len); |
for (counter = 0; counter < len; counter++) |
fprintf(stdout,"%c",buffer[counter]); |
fprintf(stdout,"\n\n"); |
} |
if (ddp.abResult > 0) { |
fprintf(stdout,"## %s: No response...\n",argv[0]); |
} |
if (ddp.abResult < 0) |
fprintf(stdout,"## %s: Error reading a packet id %d...\n",argv[0],ddp.abResult); |
} |
err = PCloseSkt(&p,FALSE); |
if (err) |
fprintf(stderr,"## %s: Error disposing of socket %d\n",argv[0],err); |
} |
Boolean Abort(void) |
{ |
EventRecord myEvent; |
char theChar; |
if (EventAvail(keyDownMask,&myEvent)) { |
GetNextEvent(keyDownMask,&myEvent); |
theChar = myEvent.message & charCodeMask; |
if (theChar == '.') { |
if (myEvent.modifiers & cmdKey) |
return(true); |
} |
} |
return(false); |
} |
void SetSelf(char* argv[]) |
{ |
MPPParamBlock p; |
short err; |
p.MPPioCompletion = 0L; |
p.MPPioRefNum = mpp; |
p.SETSELF.newSelfFlag = argv[2][0] - '0'; |
err = PSetSelfSend(&p,false); |
if (err) |
fprintf(stderr,"## %s: Error setting SelfSend flag %d",argv[0],err); |
else |
fprintf(stdout,"## %s: Old SelfSend flag is %d\n",argv[0],(short) p.SETSELF.oldSelfFlag); |
} |
void Usage(char* argv[]) |
{ |
fprintf(stderr,"## %s: No parameters specified.\n## Usage :\n",argv[0]); |
fprintf(stderr,"## -n -o ObjectName -t TypeName -z zoneName ## Shows network names\n"); |
fprintf(stderr,"## -s 1 | 0 ## Sets Self send flag\n"); |
fprintf(stderr,"## -d Net Node Socket ddpType [data] ## Sends DDP packet\n"); |
fprintf(stderr,"## -e Net Node [Echo data] ## Sends Echo packet\n"); |
fprintf(stderr,"## -a Net Node Socket [UData] [data] ## Sends ATPRequest\n"); |
fprintf(stderr,"## -r -o ObjectName -t TypeName ## Registers Name\n"); |
fprintf(stderr,"## -z ## Display zone names\n"); |
fprintf(stderr,"## © 1989 Apple Computer, Inc. by Ricardo Batista\n## Version 1.1\n\n"); |
} |
void Names(int argc, char* argv[]) |
{ |
AddrBlock address; |
EntityName name; |
short err, counter; |
Handle buffer = 0L; |
short found; |
MPPParamBlock p; |
char Entity[100]; |
p.MPPioCompletion = 0L; |
p.MPPioRefNum = mpp; |
SpinCursor(1); |
buffer = NewHandle(Buf); |
if (!buffer) { |
fprintf(stderr,"## %s: Not enough memory.\n",argv[0]); |
return; |
} |
HLock(buffer); |
name.objStr[1] = 0; |
name.typeStr[1] = 0; |
name.zoneStr[1] = 0; |
name.objStr[0] = '='; |
name.typeStr[0] = '='; |
name.zoneStr[0] = '*'; |
for (counter = 2; counter < argc; counter++) { |
if (argv[counter][0] == '-') { |
if ((argv[counter][1] == 'o') || (argv[counter][1] == 'O')) { |
BlockMove(argv[counter + 1],name.objStr,33L); |
} |
if ((argv[counter][1] == 't') || (argv[counter][1] == 'T')) { |
BlockMove(argv[counter + 1],name.typeStr,33L); |
} |
if ((argv[counter][1] == 'z') || (argv[counter][1] == 'Z')) { |
BlockMove(argv[counter + 1],name.zoneStr,33L); |
} |
} |
} |
fprintf(stdout,"## %s: Network search for: '%s' '%s' '%s'\n\n\n",argv[0],name.objStr,name.typeStr,name.zoneStr); |
fflush(stdout); |
c2pstr(name.objStr); |
c2pstr(name.typeStr); |
c2pstr(name.zoneStr); |
BlockMove(name.objStr,Entity,33L); |
counter = Entity[0] + 1; |
BlockMove(name.typeStr,&Entity[counter],33L); |
counter += name.typeStr[0] + 1; |
BlockMove(name.zoneStr,&Entity[counter],33L); |
p.NBPinterval = 5; |
p.NBPcount = 4; |
p.NBPentityPtr = Entity; |
p.NBPretBuffPtr = *buffer; |
p.NBPretBuffSize = Buf; |
p.NBPmaxToGet = Buf / 110; |
err = PLookupName(&p,FALSE); |
if (!err) { |
while ((p.MPPioResult > 0) && !Abort()) |
SpinCursor(1); |
} |
err = p.MPPioResult; |
if (!err) { |
found = p.NBPnumGotten; |
if (found > 1) |
fprintf(stdout,"## %s: %d matches\n",argv[0],found); |
if (found == 1) |
fprintf(stdout,"## %s: %d match\n",argv[0],found); |
if (found == 0) |
fprintf(stdout,"## %s: No matches\n",argv[0]); |
if (found) { |
fprintf(stdout,"Object Type Zone "); |
fprintf(stdout,"Net Node Socket\n\n"); |
} |
for (counter = 0; counter < found; counter++) { |
address.aNet = 0; |
err = myNBPExtract(*buffer,found,counter + 1,&name, &address); |
p2cstr(name.objStr); |
p2cstr(name.typeStr); |
p2cstr(name.zoneStr); |
fprintf(stdout,"%-25s %-25s %-20s",name.objStr,name.typeStr,name.zoneStr); |
fprintf(stdout,"%-5u %-5u %-5u\n",(unsigned short) address.aNet,address.aNode,address.aSocket); |
} |
} |
fflush(stdout); |
if (err) |
fprintf(stderr,"err = %d\n",err); |
if (buffer) |
DisposHandle(buffer); |
buffer = 0L; |
} |
int myNBPExtract(buffer,howMany,which,Name,Addr) |
char *buffer; |
int howMany; |
int which; |
EntityName *Name; |
AddrBlock *Addr; |
{ |
char *p; |
register int index = 1, nameCounter = 0; |
p = buffer; |
while ((index < which) && (index < howMany)) { |
p += 5; /* skip addr and enumerator */ |
p += (*p) + 1; /* skip name */ |
p += (*p) + 1; /* skip type */ |
p += (*p) + 1; /* skip zone */ |
index++; |
} |
BlockMove(p,(Ptr) Addr,4L); |
p += 5; |
BlockMove(p,Name->objStr,33L); |
p += (*p) + 1; |
BlockMove(p,Name->typeStr,33L); |
p += (*p) + 1; |
BlockMove(p,Name->zoneStr,33L); |
return(0); |
} |
void DoZones(char* argv[]) |
{ |
ATPParamBlock a; |
short err = 0, counter; |
short len; |
char buffer[578]; |
BDSElement bds; |
short abridge, node, net; |
short howMany = 0, zones = 0; |
char dummy[4]; |
long ourData; |
Boolean done = FALSE; |
short index; |
char st[100]; |
abridge = GetBridgeAddress(); |
if (!abridge) { |
fprintf(stdout,"## %s: No zones in the network.\n\n",argv[0]); |
return; |
} |
net = node = 0; |
GetNodeAddress(&node,&net); |
a.ATPioCompletion = 0L; |
a.ATPatpSocket = 0; |
a.ATPaddrBlock.aNet = net; |
a.ATPaddrBlock.aNode = abridge; |
a.ATPaddrBlock.aSocket = 6; |
a.ATPuserData = GetZoneList; |
a.ATPatpFlags = 0; |
a.ATPreqLength = 0; |
a.ATPreqPointer = 0L; |
a.ATPnumOfBuffs = 1; |
a.ATPtimeOutVal = 4; |
a.ATPretryCount = 3; |
a.ATPbdsPointer = (Ptr) &bds; |
bds.buffSize = 600; |
bds.buffPtr = &buffer[0]; |
bds.dataSize = 0; |
bds.userBytes = 0L; |
buffer[0] = 0; |
ourData = 1; |
fprintf(stdout,"\n## %s: Getting the zone names from a router....\n\n",argv[0]); |
fflush(stdout); |
while (!done) { |
ourData |= GetZoneList; |
a.ATPuserData = ourData; |
err = PSendRequest(&a,TRUE); |
while ((a.ATPioResult > 0) && !Abort()) |
SpinCursor(1); |
err = a.ATPioResult; |
if (err) { |
fprintf(stderr,"## %s: Error requesting for zones %d\n",argv[0],err); |
done = TRUE; |
zones = 0; |
if (err == 1) |
PKillSendReq(&a,false); |
} |
else { |
BlockMove((Ptr) &(bds.userBytes),dummy,4L); |
BlockMove(&dummy[2],(Ptr) &howMany,2L); |
zones += howMany; |
ourData = zones; |
if (!done) { |
for (counter = 0, index = 0; counter < howMany; counter++) { |
len = buffer[index] + 1; |
BlockMove(&buffer[index],st,(long) len); |
p2cstr(st); |
fprintf(stdout,"## '%s'\n",st); |
index += len; |
} |
done = dummy[0]; |
fflush(stdout); |
} |
} |
} |
if (zones) { |
buffer[0] = 0; |
a.ATPuserData = GetMyZone; |
err = PSendRequest(&a,TRUE); |
while ((a.ATPioResult > 0) && !Abort()) |
SpinCursor(1); |
err = a.ATPioResult; |
if (!err) { |
p2cstr(buffer); |
fprintf(stdout,"\n## %s: My zone is '%s'\n",argv[0],buffer); |
} |
} |
fprintf(stdout,"\n\n"); |
} |
Copyright © 2003 Apple Computer, Inc. All Rights Reserved. Terms of Use | Privacy Policy | Updated: 2003-01-14