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.
OTCheckNetForNBPName.c
/* |
* |
* File: OTCheckNetForNBPName.c |
* Sample code to demonstrate how to check for an AppleTalk NBPName on a |
* network. The sample works by first determining the number of zones that |
* will be searched. |
*/ |
//#define DEBUG 1 |
//#define TARGET_API_MAC_CARBON 1 |
#include <Types.h> |
#include <Events.h> |
#include <Windows.h> |
#include <Memory.h> |
#include <Resources.h> |
#include <Errors.h> |
#include <OSUtils.h> |
#include <String.h> |
#include <Gestalt.h> |
#include <stdio.h> |
#include <stdlib.h> |
#include <time.h> |
#include <OpenTransport.h> |
#include <OpenTptAppleTalk.h> |
#include "OTCheckNetForNBPName.h" |
// static globals here |
static ATSvcRef gOTSvcRef = nil; |
static MapperRef gOTMapper = nil; |
static UInt32 gNumZones = 0; |
static UInt32 gMatchesFound = 0; |
static UInt32 gNextLookup = 0; |
static UInt32 gNumLookupsCompleted = 0; |
static OTNameID gMyNameID = 0; |
static TLookupRequest *gLookupReqPtr = nil; |
static MyLookupReply *gLookupReplyPtr = nil; |
static ZoneBufPtr gZoneBufPtr = nil; |
static NBPEntity *gNBPEntityPtr; |
static Boolean gDone = false; |
static Boolean gTriggerAction = false; |
static Boolean gNameRegistered = false; |
static OTNotifyUPP gNotifier = nil; |
static UInt8 gNameToSearchFor[33] = "MyName"; |
static UInt8 gTypeToSearchFor[33] = "MyEntity"; |
static UInt8 gNameToRegister[33] = "MyName"; |
static UInt8 gTypeToRegister[33] = "MyEntity"; |
static UInt8 gNameBuf[100]; |
// |
// Prototypes here |
// |
extern OSStatus DoNegotiateSelfSendOption(EndpointRef ep, long enableSelfSend); |
OSStatus ActivateCheckNetStuff(void); |
void CleanupNetStuff(void); |
void CleanupLookupStuff(void); |
UInt32 GetNumZonesToCheckFor(void); |
UInt32 CountZonesFromUnpackedBuffer(UInt8 *buffer, long len); |
UInt32 MoveZonesToUnpackedBuffer(UInt8 *packedBuffer, ZoneBufPtr zoneBufPtr, long len); |
OSStatus DoOTGetZoneList(void); |
OSStatus SetNameMatchString(Str32 *matchString); |
OSStatus SetTypeMatchString(Str32 *matchString); |
OSStatus SetNameRegisterString(Str32 *registerString); |
OSStatus SetTypeRegisterString(Str32 *registerString); |
UInt32 GetNumberOfActiveLookups(void); |
UInt32 GetNumberOfEntitiesPerZone(void); |
UInt32 GetLookupTimeout(void); |
UInt32 GetEntitySize(Str32 *nameString, Str32 *typeString); |
OSStatus InitiateLookupStuff(Str32 *nameString, Str32 *typeString); |
OSStatus MakeOTLookupCall(UInt32 indx, UInt32 lindx, Str32 *nameString, Str32 *typeString); |
OSStatus OTRegisterMyName (void); |
void OTDeleteMyName (void); |
OSStatus DoLookupTest(void); |
short clen(char *cptr); |
void c2p(char *cptr); |
UInt16 OTMySetNBPEntity(char *buffer, Ptr nbpObject, Ptr nbpType, Ptr nbpZone); |
pascal void MyNBPHandler(void* contextPtr, OTEventCode event, OTResult result, void* cookie); |
void DoEvent(EventRecord *event); |
OSStatus ActivateCheckNetStuff(void) |
{ |
OSStatus err = noErr; |
if (gOTSvcRef == nil) |
{ |
// open the appletalk services provider |
gOTSvcRef = OTOpenAppleTalkServicesInContext(OTCreateConfiguration(kZIPName), 0, &err, nil); |
} |
if (err) |
fprintf(stdout, "error %d occurred on call to OTOpenAppleTalkServicesInContext\n", err); |
else |
fprintf(stdout, "OTOpenAppleTalkServicesInContext worked \n"); |
if ((err == noErr) && (gOTMapper == nil)) |
{ |
// open an NBP Mapper service provider |
gOTMapper = OTOpenMapperInContext(OTCreateConfiguration(kNBPName), 0, &err, nil); |
if (err == noErr) |
{ |
if (gNotifier == nil) |
{ |
gNotifier = NewOTNotifyUPP(MyNBPHandler); |
if (gNotifier == nil) |
{ |
err = memFullErr; |
fprintf(stdout, "NewOTNotifyUPP failed \n"); |
} |
} |
if (gNotifier) |
{ |
// install notifier for the mapper |
// note that since OpenTransport sets the A5 world for a 68K handler, |
// we don't need to mess with saving/setting/restoring A5 - yea!! |
err = OTInstallNotifier(gOTMapper, gNotifier, nil); |
} |
} |
else |
{ |
fprintf(stdout, "error %d occurred on call to OTOpenMapperInContext\n", err); |
} |
} |
fflush(stdout); |
return err; |
} |
/* |
Cleanup what we opened in the ActivateCheckNetStuff routine - this routine also frees up the |
memory associated with the zone list. It also checks whether an entity has been registered and |
deletes it. |
*/ |
void CleanupNetStuff(void) |
{ |
if (gZoneBufPtr) |
{ |
OTFreeMem(gZoneBufPtr); |
gZoneBufPtr = nil; |
} |
if (gOTSvcRef) |
{ |
OTCloseProvider(gOTSvcRef); |
gOTSvcRef = nil; |
} |
if (gOTMapper) |
{ |
if (gNameRegistered == true) |
{ |
OTDeleteMyName(); |
gNameRegistered = false; |
} |
OTCloseProvider(gOTMapper); |
gOTMapper = nil; |
} |
if (gNotifier) |
{ |
DisposeOTNotifyUPP(gNotifier); |
gNotifier = nil; |
} |
} |
/* |
Cleanup what we opened in the InitiateLookup routine |
*/ |
void CleanupLookupStuff(void) |
{ |
if (gLookupReqPtr) |
{ |
OTFreeMem(gLookupReqPtr); |
gLookupReqPtr= nil; |
} |
if (gLookupReplyPtr) |
{ |
OTFreeMem(gLookupReplyPtr); |
gLookupReplyPtr = nil; |
} |
if (gNBPEntityPtr) |
{ |
OTFreeMem(gNBPEntityPtr); |
gNBPEntityPtr = nil; |
} |
} |
/* |
CountZonesFromUnpackedBuffer takes a input the zone name buffer and the valid length of the |
buffer contents and returns the number of zone names in the buffer |
*/ |
UInt32 CountZonesFromUnpackedBuffer(UInt8 *buffer, long len) |
{ |
long index = 0L; |
short i = 0; |
while (index < len) |
{ |
index += (char)((Ptr)buffer+index)[0]+1L; |
i++; |
} |
return i; |
} |
/* |
MoveZonesToUnpackedBuffer takes as input the zone name buffer and the valid length of the |
buffer contents and moves the zones names into the ZoneBufPtr array elements. |
the zoneBufPtr will be an array of Pascal strings |
*/ |
UInt32 MoveZonesToUnpackedBuffer(UInt8 *packedBuffer, ZoneBufPtr zoneBufPtr, long len) |
{ |
long index = 0L; |
short i = 0; |
while (index < len) |
{ |
BlockMoveData((Ptr)packedBuffer+index, (Ptr)&zoneBufPtr[i].zoneName, zoneNameSize); |
index += (char)((Ptr)packedBuffer+index)[0]+1L; |
i++; |
} |
return i; |
} |
/* |
GetNumZonesToCheckFor returns the number of zones to start checking for. The smaller the number the more you may have to |
search until all of the zones are read |
*/ |
UInt32 GetNumZonesToCheckFor(void) |
{ |
// could store this in a resource and obtain the value here. |
return kNumZonesToCheckFor; |
} |
/* |
DoOTGetZoneList repeatedly calls OTAtalkGetZoneList until kOTBufferOverflowErr is no longer |
returned, which indicates that the provided buffer was too small for the number of AppleTalk zones present. |
Note that the global gZoneBufPtr is allocated here and is not de-allocated until the CleanupNetStuff call. |
*/ |
OSStatus DoOTGetZoneList(void) |
{ |
TNetbuf reply; |
OSStatus err = noErr; |
UInt8 *packedzonebuffptr = nil; |
UInt32 numZonesToCheckFor; |
short increment = 0; |
Boolean done = false; |
numZonesToCheckFor = GetNumZonesToCheckFor(); |
// set up to loop until we have a buffer big enough to hold all of the returned zones |
while (done == false) |
{ |
numZonesToCheckFor += increment; |
if (packedzonebuffptr != nil) |
OTFreeMem(packedzonebuffptr); |
packedzonebuffptr = OTAllocMemInContext(numZonesToCheckFor * zoneNameSize, nil); |
if (packedzonebuffptr != nil) |
{ |
reply.buf = packedzonebuffptr; |
reply.maxlen = numZonesToCheckFor * zoneNameSize; |
// by default, the AtalkServiceProvider is in synchronous mode |
err = OTATalkGetZoneList(gOTSvcRef, &reply); |
if (err == kOTBufferOverflowErr) |
{ |
fprintf(stdout, "Buffer Overflow error occurred with numZonesToCheckFor = %d\n", numZonesToCheckFor); |
// reset the err to noErr |
err = noErr; |
increment = numZonesIncrement; |
} |
else if( err == noErr) |
{ |
done = true; |
} |
else |
{ |
done = true; |
fprintf(stdout, "error %d occurred on call to OTATalkGetZoneList\n", err); |
} |
} |
else |
{ |
done = true; |
fprintf(stdout, "mem error occurred while allocating packedzonebuffptr for %d zones\n", numZonesToCheckFor); |
err = memFullErr; |
} |
} |
if (err == noErr) |
{ |
gNumZones = CountZonesFromUnpackedBuffer(packedzonebuffptr, reply.len); |
fprintf(stdout, "There are %d zones detected\n", gNumZones); |
// allocate the memory for the zone list structure |
// check first if any zones were found |
if (gNumZones == 0) |
gZoneBufPtr = (ZoneBufPtr)OTAllocMemInContext(sizeof(ZoneBuffer), nil); |
else |
gZoneBufPtr = (ZoneBufPtr)OTAllocMemInContext(gNumZones * sizeof(ZoneBuffer), nil); |
if (gZoneBufPtr == nil) |
{ |
fprintf(stdout, "mem error occurred while allocating ZoneBuffer array for %d zones\n", numZonesToCheckFor); |
err = memFullErr; |
} |
else |
{ |
if (gNumZones == 0) |
{ |
gZoneBufPtr->zoneName[0] = 1; |
gZoneBufPtr->zoneName[1] = '*'; |
gZoneBufPtr->zoneName[2] = 0; |
gNumZones = 1; |
} |
else |
MoveZonesToUnpackedBuffer(packedzonebuffptr, gZoneBufPtr, reply.len); |
} |
} |
// we're done with the packedzonebuffptr, so lets get rid of it. |
if (packedzonebuffptr != nil) |
OTFreeMem(packedzonebuffptr); |
return err; |
} |
/* |
SetNameMatchString is where you set the name string that the program will search for among the zones. |
replace this code with that where you define the NBP name string to search for |
*/ |
OSStatus SetNameMatchString(Str32 *matchString) |
{ |
BlockMoveData((Ptr)gNameToSearchFor, (Ptr)matchString, clen((char*)gNameToSearchFor)+1); |
c2p((char*)matchString); |
return noErr; |
} |
/* |
SetTypeMatchString is where you set the type string that the program will search for among the zones. |
replace this code with that where you define the NBP type string to search for |
*/ |
OSStatus SetTypeMatchString(Str32 *matchString) |
{ |
BlockMoveData((Ptr)gTypeToSearchFor, (Ptr)matchString, clen((char*)gTypeToSearchFor)+1); |
c2p((char*)matchString); |
return noErr; |
} |
/* |
SetNameRegisterString is where you set the name string that the program will register with NBP |
*/ |
OSStatus SetNameRegisterString(Str32 *registerString) |
{ |
BlockMoveData((Ptr)gNameToRegister, (Ptr)registerString, clen((char*)gNameToRegister)+1); |
c2p((char*)registerString); |
return noErr; |
} |
/* |
SetTypeMatchString is where you set the type string that the program will search for among the zones. |
*/ |
OSStatus SetTypeRegisterString(Str32 *registerString) |
{ |
BlockMoveData((Ptr)gTypeToRegister, (Ptr)registerString, clen((char*)gTypeToRegister)+1); |
c2p((char*)registerString); |
return noErr; |
} |
/* |
GetNumberOfActiveLookups returns the number of simultaneous lookups that are active at one time. The more you do at |
one time, the faster you get the search done. On the other hand, doing to many lookups at once may flood the |
network. GetNumberOfActiveLookups allows you to define how many lookups are active at the same time. |
*/ |
UInt32 GetNumberOfActiveLookups(void) |
{ |
if (gNumZones <= kMaxActiveLookups) |
{ |
// if there are no zones |
if (gNumZones == 0) |
return 1; |
else |
return gNumZones; |
} |
else return kMaxActiveLookups; |
} |
/* |
GetNumberOfEntitiesPerZone returns the maximum number of matches that I want to look for in a zone. If multiple matches are |
permitted, then you have to face the possibility that the maximum number of matches might exist in the same zone. |
*/ |
UInt32 GetNumberOfEntitiesPerZone(void) |
{ |
return 1; |
} |
/* |
return the lookup timeout value that the program will use |
*/ |
UInt32 GetLookupTimeout(void) |
{ |
return kDefaultTimeout; |
} |
/* |
GetEntitySize returns the entity size to use |
Note that we have only allocated a "minimum" size entity array rather than a full |
size array, in order to reduce the memory allocation requirement. Since we do this |
we can't treat the entity array as a simple array. In order to access each element |
we have to take the size of each element, multiply that value against the array index |
for the element and add the result to the base pointer to get each array element. |
*/ |
UInt32 GetEntitySize(Str32 *nameString, Str32 *typeString) |
{ |
UInt8 *c1, *c2; |
c1 = (UInt8*)nameString; |
c2 = (UInt8*)typeString; |
// return (c1[0] + c2[0] + 16); |
return (kNBPEntityBufferSize + 8); |
} |
/* |
Set up the lookup arrays that we will need for the NBP lookups. The request, reply and |
entity structures cannot go away while the lookup is active since we are making them asynchronously |
*/ |
OSStatus InitiateLookupStuff(Str32 *nameString, Str32 *typeString) |
{ |
UInt32 numLookupsActive; |
UInt32 entitySize; |
UInt32 numEntitiesPerZone; |
OSStatus err; |
short i; |
numLookupsActive = GetNumberOfActiveLookups(); |
#ifdef DEBUG |
DebugStr("\p about to allocate memory"); |
#endif |
gLookupReqPtr = (TLookupRequest*) OTAllocMemInContext(numLookupsActive * sizeof(TLookupRequest), nil); |
gLookupReplyPtr = (MyLookupReply*) OTAllocMemInContext(numLookupsActive * sizeof(MyLookupReply), nil); |
if ((gLookupReqPtr != nil) && (gLookupReplyPtr != nil)) |
{ |
err = noErr; |
// figure out the max number of entities we want to match on in a zone. If we want to find any |
// duplicate of a name, then return 1. But if we allow more than one entity at all, then plan on |
// that maximum number existing in the same zone. |
numEntitiesPerZone = GetNumberOfEntitiesPerZone(); |
// figure out how much memory to allocate for the entity buffer. |
// since we know the name and type strings, we can figure their length and add the max zone string |
// length instead of allocating the full max entity length string |
// make sure to also add space for the address, plus the 4 bytes at the beginning of each response |
// which is for the 2 length values - total of 8 bytes. |
entitySize = GetEntitySize(nameString, typeString); |
// allocate the entityptr array. Note that we will use the same entity structure for input and |
// potential output |
gNBPEntityPtr = (NBPEntity*) OTAllocMemInContext(numLookupsActive * entitySize * numEntitiesPerZone, nil); |
if (gNBPEntityPtr == nil) |
err = memFullErr; |
} |
else |
err = memFullErr; |
if (err == noErr) |
{ |
for (i = 0; i < numLookupsActive;) |
{ |
gLookupReplyPtr[i].index = i; |
i++; |
} |
// we initiate all of the lookups in the following loop, however, if there are more lookups than |
// we have lookuprequests in the array, then set the gNextLookup indice to numLookupsActive |
// so that this will be where we begin other lookups if the entity is not found. |
gNextLookup = numLookupsActive; |
// set the gOTMapper endpoint to operate asynchronously |
OTSetAsynchronous(gOTMapper); |
for (i = 0; (gDone == false) && (i < numLookupsActive);) |
{ |
err = MakeOTLookupCall(i, i, nameString, typeString); |
i++; |
} |
} |
return err; |
} |
/* |
MakeOTLookupCall is where we make the zone specific Lookup call. |
input parameters |
indx - index into the gLookupReqPtr, gNBPEntityPtr, and the gLookupReplyPtr arrays |
lindx - index into the gZoneBufPtr where we get the zone where we will perform the next lookup |
nameString - pascal name string |
typeString - pascal type string |
*/ |
OSStatus MakeOTLookupCall(UInt32 indx, UInt32 lindx, Str32 *nameString, Str32 *typeString) |
{ |
OSStatus err; |
UInt32 entitySize; |
UInt32 numEntitiesPerZone; |
char* entityPtrToUse; |
// figure out the max number of entities we want to match on in a zone. If we want to find any |
// duplicate of a name, then return 1. But if we allow more than one entity at all, then plan on |
// that maximum number existing in the same zone. |
numEntitiesPerZone = GetNumberOfEntitiesPerZone(); |
// figure out how much memory to allocate for the entity buffer. |
// since we know the name and type strings, we can figure their length and add the max zone string |
// length instead of allocating the full max entity length string |
entitySize = GetEntitySize(nameString, typeString); |
OTMemset(&gLookupReqPtr[indx], 0, sizeof(TLookupRequest)); |
// set up the lookup request record |
gLookupReqPtr[indx].maxcnt = numEntitiesPerZone; |
gLookupReqPtr[indx].timeout = GetLookupTimeout(); |
// figure out where the the pointer is in the array to use. |
entityPtrToUse = (char*) ((UInt32) gNBPEntityPtr + indx * entitySize * numEntitiesPerZone); |
gLookupReqPtr[indx].name.len = (size_t)OTMySetNBPEntity(entityPtrToUse, |
(char*)nameString, (char*)typeString, (char*)&gZoneBufPtr[lindx].zoneName); |
gLookupReqPtr[indx].name.buf = (unsigned char*)entityPtrToUse; |
gLookupReqPtr[indx].addr.len = 0; |
gLookupReqPtr[indx].addr.buf = nil; |
gLookupReqPtr[indx].addr.maxlen = 0; |
// set up the lookup reply record |
gLookupReplyPtr[indx].lkReply.names.maxlen = numEntitiesPerZone * entitySize; |
gLookupReplyPtr[indx].lkReply.names.len = 0; |
gLookupReplyPtr[indx].lkReply.names.buf = (unsigned char*)entityPtrToUse; |
gLookupReplyPtr[indx].lkReply.rspcount = 0; |
gLookupReplyPtr[indx].lindex = lindx; |
// make the lookup call |
err = OTLookupName(gOTMapper, &gLookupReqPtr[indx], (TLookupReply*)&gLookupReplyPtr[indx]); |
if (err != noErr) |
{ |
#ifdef DEBUG |
// this call can be made at deferred task time, so we can't make a call that |
// might allocate memory |
DebugStr("\p Error occurred making OTLookupName call"); |
#endif |
} |
return err; |
} |
/******************************************************************************* |
** Register my name using Open Transport |
********************************************************************************/ |
OSStatus OTRegisterMyName (void) |
{ |
TRegisterRequest regreq; |
TRegisterReply regreply; |
OSErr err; |
Str32 nameString; |
Str32 typeString; |
err = SetNameRegisterString(&nameString); |
if (err == noErr) |
{ |
err = SetTypeRegisterString(&typeString); |
} |
// create the NBP name string and set the len field for the string |
// and register in the local zone |
regreq.name.len = OTMySetNBPEntity((char*)gNameBuf, (Ptr)&nameString, (Ptr)&typeString, (Ptr)"\p*"); |
regreq.name.buf = gNameBuf; |
// let the system define the network address for this name |
regreq.addr.len = regreq.addr.maxlen = 0; |
regreq.addr.buf = NULL; |
// set up regreply |
regreply.addr.maxlen = 0; |
regreply.addr.buf = nil; |
OTSetSynchronous(gOTMapper); |
err = OTRegisterName(gOTMapper, ®req, ®reply); |
if (err == noErr) |
{ |
gMyNameID = regreply.nameid; |
gNameRegistered = true; |
} |
return err; |
} |
/******************************************************************************* |
** Delete my name using Open Transport |
********************************************************************************/ |
void OTDeleteMyName (void) |
{ |
OTSetSynchronous(gOTMapper); |
OTDeleteNameByID(gOTMapper, gMyNameID); |
gNameRegistered = false; |
} |
OSStatus DoLookupTest(void) |
{ |
EventRecord theEvent; |
OSStatus err; |
Str32 nameString; |
Str32 typeString; |
long ticks; |
Boolean watchTrigger = true; |
// we start the lookup test here by getting the NBP name and type to look for |
err = SetNameMatchString(&nameString); |
if (err == noErr) |
{ |
err = SetTypeMatchString(&typeString); |
} |
// we start the asynch lookup process here. |
if (err == noErr) |
{ |
err = InitiateLookupStuff(&nameString, &typeString); |
} |
// we sit in a WNE (WaitNextEvent) loop for the search to complete. |
if (err == noErr) |
{ |
ticks = TickCount() + 300; |
printf("Use Command-Q to quit.\n"); |
while (gDone == false) |
{ |
ticks++; |
if (!WaitNextEvent(everyEvent, &theEvent, 15, nil)) |
theEvent.what = nullEvent; |
DoEvent(&theEvent); |
if (ticks < TickCount()) |
{ |
ticks = TickCount() + 300; |
fprintf(stdout, "%d/%d ", gMatchesFound, gNumLookupsCompleted); |
fflush(stdout); |
} |
if (watchTrigger == true) |
{ |
if (gTriggerAction == true) |
{ |
fprintf(stdout, "\n Too many matches were found \n"); |
fflush(stdout); |
watchTrigger = false; |
} |
} |
if (gNumLookupsCompleted >= gNumZones) |
{ |
gDone = true; |
fprintf(stdout, "\nThere were %d matches found in %d zones\n\n", gMatchesFound, gNumLookupsCompleted); |
fflush(stdout); |
} |
} |
CleanupLookupStuff(); |
} |
return err; |
} |
int main(void) |
{ |
OSStatus err; |
printf ("Sample Program: OTCheckNetForNBPName!\n\n"); |
err = InitOpenTransportInContext(kInitOTForApplicationMask, nil); |
if (err != noErr) |
{ |
printf ("InitOpenTransport failed with error %d\n", err); |
return err; |
} |
else |
printf ("InitOpenTransportInContext worked!\n\n"); |
err = ActivateCheckNetStuff(); |
if (err != noErr) |
{ |
fprintf(stdout, "ActivateCheckNetStuff returned error %d.\n", err); |
} |
fflush(stdout); |
if (err == noErr) |
{ |
fprintf(stdout, "Checking for the number of zones present.\n"); |
fflush(stdout); |
err = DoOTGetZoneList(); |
if (err != noErr) |
{ |
fprintf(stdout, "DoOTGetZoneList returned error %d.\n", err); |
} |
} |
if (err == noErr) |
{ |
fprintf(stdout, "Beginning the lookup test.\n"); |
fflush(stdout); |
err = DoLookupTest(); |
} |
if ((err == noErr) && (gNumLookupsCompleted < gNumZones)) |
{ |
fprintf(stdout, "\nYou stopped the lookup test before all of the lookups were complete!\n"); |
fprintf(stdout, "Am closing the mapper endpoint to clear all outstanding lookups.\n"); |
// close the mapper endpoint and reopen it |
OTCloseProvider(gOTMapper); |
gOTMapper = nil; |
fprintf(stdout, "Am reopening the mapper endpoint.\n"); |
err = ActivateCheckNetStuff(); |
} |
if (err == noErr) |
{ |
fprintf(stdout, "Am registering a new NBP entity\n"); |
fflush(stdout); |
err = OTRegisterMyName(); |
if (err) |
fprintf(stdout, "Error occurred registering the name %d\n", err); |
else |
{ |
fprintf(stdout, "\nEntity successfully registered\n"); |
// the following code will enable SelfSend mode globally on the machine |
// otherwise it is only enabled for this process |
OTSetSynchronous(gOTMapper); |
err = DoNegotiateSelfSendOption(gOTMapper, 1); |
if (err == 1) |
{ |
fprintf(stdout, "self send previously enable\n"); |
// reset err |
err = noErr; |
} |
else |
{ |
fprintf(stdout, "Error occurred negotiating self send %d\n", err); |
fprintf(stdout, "Quitting program\n"); |
} |
} |
} |
fflush(stdout); |
if (err == noErr) |
{ |
fprintf(stdout, "\nPerforming the next lookup for the new entity\n"); |
fflush(stdout); |
// reset gDone and try the lookup test again |
gDone = false; |
gNumLookupsCompleted = 0; |
err = DoLookupTest(); |
} |
CleanupLookupStuff(); |
CleanupNetStuff(); |
CloseOpenTransportInContext(nil); |
fprintf(stdout, "\nTest ended\n"); |
return 0; |
} |
/*****************************************************************************/ |
/* Convert a c-string to a pascal-string. */ |
short clen(char *cptr) |
{ |
short i; |
for (i = 0; cptr[i]; ++i) {}; |
return(i); |
} |
/*****************************************************************************/ |
void c2p(char *cptr) |
{ |
char len; |
BlockMove(cptr, cptr + 1, len = clen(cptr)); |
*cptr = len; |
} |
/* |
OTMySetNBPEntity is used to set up an NBP lookup query buffer. |
All input strings are assumed to be pascal strings |
*/ |
UInt16 OTMySetNBPEntity(char *buffer, Ptr nbpObject, Ptr nbpType, Ptr nbpZone) |
{ |
char* bufPtr; |
UInt16 len; |
bufPtr = buffer; |
BlockMove((Ptr)&nbpObject[1], bufPtr, nbpObject[0]); |
bufPtr += nbpObject[0]; // point buffer to end of current string |
len = nbpObject[0]; // collect number of chars moved to buffer |
// add the ":" character between the object and type strings |
*bufPtr = ':'; |
bufPtr++; |
len++; |
BlockMove((Ptr)&nbpType[1], bufPtr, nbpType[0]); |
bufPtr += nbpType[0]; // point buffer to end of current string |
len += nbpType[0]; // collect number of chars moved to buffer |
// add the "@" character between the type and zone strings |
*bufPtr = '@'; |
bufPtr++; |
len++; |
BlockMove((Ptr)&nbpZone[1], bufPtr, nbpZone[0]); |
len += nbpZone[0]; // collect number of chars moved to buffer |
return len; |
} |
/******************************************************************************* |
** HandleMapperEvents TMapper (NBP) Event Handling |
********************************************************************************/ |
pascal void MyNBPHandler(void* contextPtr, OTEventCode event, OTResult result, void* cookie) |
{ |
#pragma unused (contextPtr) |
MyLookupReplyPtr myReplyPtr; |
OSStatus err; |
UInt32 indx; |
Boolean dolookup = false; |
Str32 nameString; |
Str32 typeString; |
switch (event) |
{ |
case T_LKUPNAMERESULT: // intermediate result notification |
break; |
case T_LKUPNAMECOMPLETE: |
#ifdef DEBUG |
DebugStr("\p about to set gNumLookupsCompleted"); |
#endif |
gNumLookupsCompleted++; |
// in a lookupcomplete event, the cookie is a OTLookupReply ptr. |
myReplyPtr = (MyLookupReplyPtr)cookie; |
if ((result == kOTBufferOverflowErr) || |
(result == noErr)) |
{ |
gMatchesFound += myReplyPtr->lkReply.rspcount; |
dolookup = true; |
if (gMatchesFound > GetNumberOfEntitiesPerZone()) |
gTriggerAction = true; |
} |
if (result == kOTNoDataErr) |
dolookup = true; |
if (dolookup == true) |
{ |
if (gNextLookup < gNumZones) |
{ |
indx = myReplyPtr->index; |
if (indx >= kMaxActiveLookups) |
{ |
#ifdef DEBUG |
DebugStr("\p about to set gNumLookupsCompleted"); |
#endif |
} |
else |
{ |
SetNameMatchString(&nameString); |
SetTypeMatchString(&typeString); |
err = MakeOTLookupCall(indx, gNextLookup, &nameString, &typeString); |
// increment the lookup index in to the zone array for the next |
// zone to look into. |
gNextLookup++; |
} |
} |
} |
else |
{ |
#ifdef DEBUG |
DebugStr("\p T_LKUPNAMECOMPLETE: Unexpected error"); |
#endif |
} |
break; |
case T_REGNAMECOMPLETE: |
break; |
case T_DELNAMECOMPLETE: |
break; |
default: |
#ifdef DEBUG |
DebugStr("\pHandleMapperEvents: Unexpected Event!;g"); |
#endif |
break; |
} |
} |
void DoEvent(EventRecord *event) |
{ |
char key; |
switch(event->what) |
{ |
case nullEvent: |
case mouseDown: |
case activateEvt: |
case updateEvt: |
case kHighLevelEvent: |
case osEvt: |
case diskEvt: |
break; |
case autoKey: |
case keyDown: |
key = event->message & charCodeMask; |
switch (key) |
{ |
case 'q': |
case 'Q': |
if (event->modifiers & cmdKey) |
gDone = true; |
break; |
} |
break; |
} |
} |
Copyright © 2003 Apple Computer, Inc. All Rights Reserved. Terms of Use | Privacy Policy | Updated: 2003-01-14