home *** CD-ROM | disk | FTP | other *** search
/ Developer CD Series 2000 April: Mac OS SDK / Dev.CD Apr 00 SDK1.toast / Development Kits / Mac OS / NSL 1.1 SDK / Sample Code / Test.c < prev   
Encoding:
C/C++ Source or Header  |  1999-10-12  |  18.5 KB  |  655 lines  |  [TEXT/CWIE]

  1. /*
  2.     File:        Test.c
  3.  
  4.     Contains:    xxx put contents here xxx
  5.  
  6.     Written by:    Kevin Arnold - based on sample code from Nav services written by Tony Bacigalupi
  7.  
  8.     Copyright:    © 1998 - 1999 by Apple Computer, Inc., all rights reserved.
  9.  
  10.     Change History (most recent first):
  11.  
  12.     <18>    07-21-99    KA        converted to UPP for async callback code
  13.     <17>    05-11-99    sns        remove endless error loop in TestSyncNeighborhoodLookup()
  14.     <16>    03-24-99    KA        converting to new headers
  15.     <15>    03-22-99    KA        converting to new data type names (ie NSLxxx) and handle NSLStandardGetURL returning OSStatus
  16.     <14>    02-23-99    KA        added parameter to the NSLGetStandardURL call
  17.     <13>    02-05-99    KA        added async calling to NSL
  18.     <12>    01-12-99    KA        put back reference to NSLStandardGetURL and use new parsing pb call
  19.     <11>    12-15-98    KA        removed reference to NSLStandardGetURL
  20.     <10>    11-05-98    KA        removed reference to NSLStandardURL.h
  21.     <09>    10-20-98    KA        fixed bug in non-fatal error handling
  22.     <08>    10-15-98    KA        added showURLTEField param option
  23.     <06>    10/08/98    KA        added filter proc param to NSLStandardGetURL call
  24.     <05>     8/25/98    KA        we weren't setting done to false in the beginning of TestSyncServicesLookup
  25.     <04>     8/12/98    KA        added cleanup calls to free our NSL made objects
  26.     <03>     7/21/98    KA        added NSLErrorToString calls
  27.     <01>     4/06/98    KA        Initial check-in.
  28.  
  29.     To Do:
  30. */
  31.  
  32. #include "NSL.h"
  33.  
  34.  
  35. #if PROFILE
  36. #include <Profiler.h>
  37. #endif
  38.  
  39. #include <StdIO.h>
  40. #include <string.h>
  41.  
  42. #include <Threads.h>
  43.  
  44. #ifdef __MWERKS__
  45. #include <SIOUX.h>
  46. #endif
  47.  
  48.  
  49. #define kWebServerType        "http"
  50. #define kFTPServerType        "ftp"
  51. #define kAppleShareType        "AFPServer"
  52. #define kLaserWriterType    "LaserWriter"
  53.  
  54. NSLClientRef        gOurClientRef;
  55. char                gErrorString[256];
  56. char                gSolutionString[256];
  57.  
  58. void TestDefaultNeighborhoodLookup( void );
  59. void TestSyncNeighborhoodLookup( NSLNeighborhood neighborhood ); 
  60. void TestSyncServicesLookup( char* service );
  61. void TestAsyncServicesLookup( char* service );
  62. void TestStandardRegisterURL(void);
  63. void TestStandardDeregisterURL(void);
  64. void DoNSLFatalAlert( NSLError theError );
  65. void DoNSLNonFatalAlert( NSLError theError, Boolean* cancelSearch );
  66.  
  67. static char GetPressedKey()
  68. {
  69.     char c;
  70.     char dummy;
  71.     
  72.     scanf("%c%c", &c, &dummy);
  73.     
  74.     return c;
  75. }
  76.  
  77. void DoNSLFatalAlert( NSLError theError )
  78. {
  79.     char    errorString[256];
  80.     char    solutionString[256];
  81.     
  82.     // call this if you don't want to give the user the option of canceling the search
  83.     NSLErrorToString( theError, errorString, solutionString );
  84.     printf( "Fatal error occurred: %ld\r%s\r%s\r", theError.theErr, errorString, solutionString );
  85. }
  86.  
  87. void DoNSLNonFatalAlert( NSLError theError, Boolean* cancelSearch )
  88. {
  89.     char    errorString[256];
  90.     char    solutionString[256];
  91.     char    result;
  92.     
  93.     // call this if the error isn't fatal and the user might want to continue/cancel the search
  94.     NSLErrorToString( theError, errorString, solutionString );
  95.     printf( "Non Fatal error occurred: %ld\r%s\r%s\r", theError.theErr, errorString, solutionString );
  96.     printf( "Press Y to continue or N to cancel" );
  97.  
  98.     result = GetPressedKey();
  99.     
  100.     if ( result == 'y' || result == 'Y' )
  101.         *cancelSearch = false;
  102.     else
  103.         *cancelSearch = true;
  104. }
  105.  
  106.  
  107. void main()
  108. {
  109.     OSStatus                status;
  110.     Boolean                 quit        = false;
  111.     Boolean                    doBanner    = true;
  112.     Ptr                        url;
  113.     NSLDialogOptions        options;
  114. //    NSLEventUPP             eventUPP = NewNSLEventUPP(OurEventHandler);
  115.     
  116.         
  117.     #ifdef __MWERKS__
  118.     SIOUXSettings.asktosaveonclose = 0;
  119.     #endif
  120.  
  121.     #if PROFILE
  122.     ProfilerInit(collectDetailed, bestTimeBase, 500, 20);
  123.     #endif
  124.  
  125.     printf("NSL API Test\rGenerated %s at %s\r\r", __DATE__, __TIME__);
  126.  
  127.     status = NSLOpenNavigationAPI( &gOurClientRef );
  128.     
  129.     if ( status && status != kNSLSomePluginsFailedToLoad )
  130.         printf("NSLAPI could not be opened due to an internal error\r");
  131.     else
  132.     {
  133.         if ( status == kNSLSomePluginsFailedToLoad )
  134.         {
  135.             // this isn't a fatal error, so we want to let someone know but we will continue.
  136.             NSLError    cludgeError;            // we have to crock one as this is the only time we will get back an OSStatus
  137.                                                 // instead of an NSLError.  Just make theContext be zero
  138.             cludgeError.theErr = status;
  139.             cludgeError.theContext = 0;
  140.             
  141.             NSLErrorToString( cludgeError, gErrorString, gSolutionString );
  142.             printf("Error #%ld: %s\r", cludgeError.theErr, gErrorString );
  143.             printf("Solution: %s\r", gSolutionString );
  144.         }
  145.         
  146.         do {
  147.             char c;
  148.             
  149.             if ( doBanner )
  150.                 printf("\r\r\rPlease make a choice [1-6 and hit return]:\r\t1 - Get list of Default Neighborhoods available\r\t2 - Get list of Webservers in a Neighborhood(sync)\r\t3 - Get list of Webservers in a Neighborhood(async)\r\t4 - Get list of AppleShare servers in a Neighborhood\r\t5 - Browse for url\r\t6 - QUIT\r\r> ");
  151.  
  152.             c = GetPressedKey();        
  153.             
  154.             doBanner = true;
  155.             
  156.             switch ( c)
  157.             {
  158.                 case '1':
  159.                     TestDefaultNeighborhoodLookup();
  160.                     break;
  161.                     
  162.                 case '2':
  163.                     TestSyncServicesLookup(kWebServerType);
  164.                     break;
  165.                     
  166.                 case '3':
  167.                     TestAsyncServicesLookup(kWebServerType);
  168.                     break;
  169.                     
  170.                 case '4':
  171.                     TestSyncServicesLookup(kAppleShareType);
  172.                     break;
  173.                     
  174.                 case '5':
  175.                     NSLGetDefaultDialogOptions( &options );
  176.                     
  177.                     status = NSLStandardGetURL( &options, nil, nil, nil, "Web,http,https;FTP,ftp;AppleShare,AFPServer,afp;", &url );
  178.                     
  179.                     if ( status == noErr )
  180.                     {
  181.                         printf( "\rURL Returned: %s\r", url );
  182.                         url = NSLFreeURL( url );
  183.                     }
  184.                     else if ( status == kNSLUserCanceled )
  185.                         printf( "\rUser Canceled URL Selection\r");
  186.                     else
  187.                         printf( "\rNSLStandardGetURL returned: %ld", status );
  188.                     
  189.                     break;
  190.                     
  191.                 case '6':
  192.                     printf("Bye now!\r");
  193.                     quit = true;
  194.                     break;
  195.                 
  196.                 default:
  197.                     doBanner = false;
  198.             }
  199.  
  200.         } while ( quit == false );
  201.     }
  202.     
  203.     #if PROFILE
  204.     ProfilerDump("\pPerformances");
  205.     ProfilerTerm();
  206.     #endif
  207.     
  208.     ExitToShell();
  209. }
  210.  
  211. #define    kBufferLength    4096
  212.  
  213. void TestDefaultNeighborhoodLookup( void )
  214. {
  215.     NSLNeighborhood neighborhood;
  216.     
  217.     printf( "Getting default NSLNeighborhoods\r\r" );
  218.     
  219.     neighborhood = NSLMakeNewNeighborhood( "", NULL );        // empty string for default neighborhood lookup, NULL for empty protocol string 
  220.                                                             // meaning we want all default neighborhoods
  221.     TestSyncNeighborhoodLookup( neighborhood );
  222.  
  223.     NSLFreeNeighborhood( neighborhood );                    // make sure we free up this memory
  224. }
  225.  
  226.  
  227.  
  228. void TestSyncNeighborhoodLookup( NSLNeighborhood neighborhood )
  229. {
  230.     char                tempName[256];
  231.     long                bufLen = kBufferLength;
  232.     char*                buffer = NULL;
  233.     char*                tempPtr = NULL;
  234.     NSLRequestRef        ourRequestRef;
  235.     NSLClientAsyncInfoPtr    ourAsyncInfo;
  236.     NSLError            iErr = kNSLErrorNoErr;
  237.     NSLNeighborhood        nhPtr = NULL;
  238.     long                nhLength, tempPtrLength;
  239.     Boolean                done = false;
  240.     
  241.     printf( "Looking up Neighborhoods\r\r" );
  242.     
  243.     buffer = NewPtr( bufLen );
  244.     
  245.     // first prepare the request which will set up a NSLClientAsyncInfoPtr for us
  246.     iErr = NSLPrepareRequest( NULL, NULL, gOurClientRef, &ourRequestRef, buffer, bufLen, &ourAsyncInfo );
  247.  
  248.     if ( iErr.theErr )
  249.     {
  250.         printf("NSLPrepareRequest returned error %ld\r", iErr.theErr );
  251.         NSLErrorToString( iErr, gErrorString, gSolutionString );
  252.         printf("Error: %s\r", gErrorString );
  253.         printf("Solution: %s\r", gSolutionString );
  254.     }
  255.         
  256.     // set the values of ourAsyncInfo pb
  257.     ourAsyncInfo->clientContextPtr = NULL;
  258.     ourAsyncInfo->maxSearchTime = 0;        // no max search time
  259.     ourAsyncInfo->alertInterval = 0;         // no alert interval
  260.     ourAsyncInfo->alertThreshold = 1;        // make alert threshold every item...
  261.  
  262.     if ( iErr.theErr == noErr )
  263.         iErr = NSLStartNeighborhoodLookup( ourRequestRef, neighborhood, ourAsyncInfo );
  264.     
  265.     do {
  266.         if ( iErr.theErr == noErr && ourAsyncInfo->totalItems > 0 )
  267.         {
  268.             while ( NSLGetNextNeighborhood( ourAsyncInfo, &nhPtr, &nhLength ) )
  269.             {        
  270.                 if ( nhLength > 0 && nhLength < kBufferLength  )
  271.                 {
  272.                     NSLGetNameFromNeighborhood( nhPtr, &tempPtr, &tempPtrLength );
  273.                     memcpy( tempName, tempPtr, tempPtrLength );
  274.                     tempName[tempPtrLength] = '\0';
  275.  
  276.                     printf( "%s\r", tempName );
  277.                 }
  278.             }
  279.         }
  280.         
  281.         if ( ourAsyncInfo->searchState == kNSLSearchStateComplete )
  282.             done = true;
  283.         else
  284.             iErr = NSLContinueLookup( ourAsyncInfo );    // <17> if search state isn't complete, then the error isn't fatal
  285.         
  286.     } while ( !iErr.theErr && !done );
  287.     
  288.     if ( iErr.theErr )
  289.     {
  290.         NSLErrorToString( iErr, gErrorString, gSolutionString );
  291.         printf("Error: %s\r", gErrorString );
  292.         printf("Solution: %s\r", gSolutionString );
  293.     }    
  294.     
  295.     if ( buffer )
  296.         DisposePtr(buffer);
  297. }
  298.  
  299. void TestSyncServicesLookup( char* service )
  300. {
  301.     char                name[256] = "\p";
  302.     char                url[1024];
  303.     long                bufLen = kBufferLength;
  304.     char*                buffer = NewPtr( bufLen );
  305.     NSLRequestRef        ourRequestRef;
  306.     NSLClientAsyncInfoPtr    ourAsyncInfo;
  307.     NSLError            iErr = kNSLErrorNoErr;
  308.     NSLServicesList        serviceList = NULL;
  309.     NSLTypedDataPtr         newDataPtr = NULL;
  310.     NSLNeighborhood        neighborhood, urlPtr = NULL;
  311.     long                urlLength;
  312.     Boolean                done = false;
  313.     char                c;
  314.     
  315.     printf( "Please Type in the neighborhood you want to search then hit return\r" );
  316.     scanf("%c", &c );
  317.     
  318.     while ( c != '\r' && c != '\n' && name[0] < 256 )
  319.     {
  320.         name[0]++;
  321.         name[name[0]] = c;
  322.         scanf("%c", &c );
  323.     };
  324.     
  325.     p2cstr( (unsigned char*)name );
  326.     
  327.     neighborhood = NSLMakeNewNeighborhood( name, NULL );
  328.     printf( "Looking up Service\r\r" );
  329.     
  330.     // first prepare the request which will set up a NSLClientAsyncInfoPtr for us
  331.     iErr = NSLPrepareRequest( NULL, NULL, gOurClientRef, &ourRequestRef, buffer, bufLen, &ourAsyncInfo );
  332.  
  333.     if ( iErr.theErr )
  334.     {
  335.         printf("NSLPrepareRequest returned error %ld\r", iErr.theErr );
  336.  
  337.         NSLErrorToString( iErr, gErrorString, gSolutionString );
  338.         printf("Error #%ld: %s\r", iErr.theErr, gErrorString );
  339.         printf("Solution: %s\r", gSolutionString );
  340.     }
  341.     else
  342.     {
  343.         serviceList = NSLMakeNewServicesList( service );    // we can pass a comma delimited cstring here (ie "http,ftp")
  344.         
  345.         // now we need to create a NSLTypedDataPtr which holds teh serviceList info as well as an attribute if we wish
  346.         if ( serviceList != NULL )
  347.         {
  348.             iErr.theErr = NSLMakeServicesRequestPB( serviceList, &newDataPtr );    // we can also pass an attribute if we want to get more specific
  349.             NSLDisposeServicesList( serviceList );                            // we are done with this, free this memory!        
  350.         }
  351.         
  352.         // set the values of ourAsyncInfo pb
  353.         ourAsyncInfo->clientContextPtr = NULL;
  354.         ourAsyncInfo->maxSearchTime = 0;        // no max search time
  355.         ourAsyncInfo->alertInterval = 0;         // no alert interval
  356.         ourAsyncInfo->alertThreshold = 1;        // make alert threshold every item...
  357.  
  358.         if ( iErr.theErr == noErr )
  359.             iErr = NSLStartServicesLookup( ourRequestRef, neighborhood, newDataPtr, ourAsyncInfo );
  360.  
  361.         do {
  362.             if ( iErr.theErr == noErr && ourAsyncInfo->totalItems > 0 )
  363.             {
  364.                 while ( NSLGetNextUrl( ourAsyncInfo, &urlPtr, &urlLength ) )
  365.                 {        
  366.                     if ( urlLength > 0 )
  367.                     {
  368.                         memcpy( url, urlPtr, urlLength );
  369.                         url[urlLength] = '\0';
  370.                         printf( "%s\r", url );
  371.                     }
  372.                 }
  373.             }
  374.             else if ( iErr.theErr )
  375.             {
  376.                 NSLErrorToString( iErr, gErrorString, gSolutionString );
  377.                 printf("Error #%ld: %s\r", iErr.theErr, gErrorString );
  378.                 printf("Solution: %s\r", gSolutionString );
  379.             }
  380.                     
  381.             if ( ourAsyncInfo->searchState == kNSLSearchStateComplete )
  382.                 done = true;
  383.             else
  384.                 iErr = NSLContinueLookup( ourAsyncInfo );    // if search state isn't complete, then the error isn't fatal
  385.  
  386.         } while ( !done );                                    // it is possible to get errors back, but if the search state isn't complete, then one or more
  387.                                                             // plugins are still working!
  388.  
  389.         NSLFreeTypedDataPtr( newDataPtr );                    // dispose this
  390.     }
  391.     
  392.     NSLFreeNeighborhood( neighborhood );                    // make sure we free up this memory
  393.     
  394.     if ( buffer )
  395.         DisposePtr(buffer);
  396. }
  397.  
  398. typedef struct {
  399.     NSLRequestRef            theRequestRef;
  400.     NSLTypedDataPtr            theRequestDataPtr;
  401.     Boolean                    lookupFinished;
  402. } LookupContext, *LookupContextPtr;
  403.  
  404. pascal void ServicesLookupNotifyProc( NSLClientAsyncInfoPtr nslInfoPtr );
  405. pascal void ServicesLookupNotifyProc( NSLClientAsyncInfoPtr nslInfoPtr )
  406. {
  407.     LookupContextPtr    lookupContext = (LookupContextPtr)nslInfoPtr->clientContextPtr;
  408.     char*                curURL;
  409.     char*                urlPtr = NULL;
  410.     NSLError            nslError;
  411.     long                urlLength;
  412.     Boolean                weDone = false, cancelSearch = false;;
  413.     
  414.     // first check our ptrs and to see if this is from the current request
  415.     if ( nslInfoPtr && lookupContext )
  416.     {
  417.         // we might want to think about putting up an alert message here if we have received one...
  418.         if ( nslInfoPtr->searchResult.theErr )
  419.         {
  420.             if ( nslInfoPtr->searchState != kNSLSearchStateComplete )
  421.             {
  422.                 DoNSLNonFatalAlert( nslInfoPtr->searchResult, &cancelSearch );
  423.             }
  424.             else
  425.             {
  426.                 DoNSLFatalAlert( nslInfoPtr->searchResult );        // user has no choice
  427.                 cancelSearch = true;
  428.             }
  429.         }
  430.         
  431.         if ( nslInfoPtr->totalItems > 0 && !cancelSearch )
  432.         {
  433.             while ( NSLGetNextUrl( nslInfoPtr, &urlPtr, &urlLength ) )
  434.             {        
  435.                 if ( urlLength > 0 )
  436.                 {
  437.                     curURL = NewPtr( urlLength + 1 );                    // The NSL Manager WON'T call us at interrupt time so mem aloocation is OK!
  438.                     
  439.                     BlockMove( urlPtr, curURL, urlLength );
  440.                     curURL[urlLength] = '\0';                            // null terminate!
  441.                 }
  442.                 else
  443.                 {
  444.                     weDone = true;
  445.                 }
  446.                 
  447.                 if ( !weDone )
  448.                 {
  449.                     printf( "%s\r", curURL );
  450.                 }
  451.                 
  452.                 if ( curURL )
  453.                     DisposePtr( curURL );                                // now we could just have curURL be on the stack in this case but to show that 
  454.                                                                         // memory allocation is cool in the notifier we did it this way...
  455.                 
  456.                 curURL = NULL;
  457.             }
  458.         }
  459.     
  460.         if ( !cancelSearch && nslInfoPtr->searchState != kNSLSearchStateComplete )
  461.         {
  462.             nslError = NSLContinueLookup(nslInfoPtr);                    // don't forget to call NSLContinueLookup when you are done with the data in the buffer!
  463.             
  464.             if ( nslError.theErr )
  465.             {
  466.                 if ( nslInfoPtr->searchState != kNSLSearchStateComplete )
  467.                 {
  468.                     DoNSLNonFatalAlert( nslError, &cancelSearch );
  469.                 }
  470.                 else
  471.                 {
  472.                     DoNSLFatalAlert( nslError );        // user has no choice
  473.                     cancelSearch = true;
  474.                 }
  475.             }
  476.         }
  477.         
  478.         if ( !cancelSearch && nslInfoPtr->searchState == kNSLSearchStateComplete )
  479.         {
  480.             lookupContext->lookupFinished = true;
  481.             nslError = NSLDeleteRequest( lookupContext->theRequestRef );
  482.             
  483.             if ( nslError.theErr )
  484.                 DoNSLFatalAlert( nslError );        // user has no choice
  485.         }
  486.         else if ( cancelSearch )                    // user decided error was bad enough to cancel the entire search
  487.         {
  488.             lookupContext->lookupFinished = true;
  489.             nslError = NSLCancelRequest( lookupContext->theRequestRef );
  490.             
  491.             if ( nslError.theErr == noErr )
  492.                 nslError = NSLDeleteRequest( lookupContext->theRequestRef );
  493.         }
  494.     }
  495. }
  496.  
  497.  
  498.  
  499. void TestAsyncServicesLookup( char* service )
  500. {
  501.     char                name[256] = "\p";
  502.     long                bufLen = kBufferLength;
  503.     char*                buffer = NewPtr( bufLen );
  504.     LookupContextPtr    contextPtr;
  505.     NSLRequestRef        ourRequestRef;
  506.     NSLClientNotifyUPP     myServicesNotifyUPP;
  507.     NSLClientAsyncInfoPtr    ourAsyncInfo;
  508.     NSLError            iErr = kNSLErrorNoErr;
  509.     NSLServicesList        serviceList = NULL;
  510.     NSLTypedDataPtr         newDataPtr = NULL;
  511.     NSLNeighborhood        neighborhood, urlPtr = NULL;
  512.     Boolean                done = false;
  513.     char                c;
  514.     
  515.     printf( "Please Type in the neighborhood you want to search then hit return\r" );
  516.     scanf("%c", &c );
  517.     
  518.     while ( c != '\r' && c != '\n' && name[0] < 256 )
  519.     {
  520.         name[0]++;
  521.         name[name[0]] = c;
  522.         scanf("%c", &c );
  523.     };
  524.     
  525.     p2cstr( (unsigned char*)name );
  526.     
  527.     neighborhood = NSLMakeNewNeighborhood( name, NULL );
  528.     printf( "Looking up Service\r\r" );
  529.     
  530.     // first prepare the request which will set up a NSLClientAsyncInfoPtr for us
  531.     contextPtr = NewPtr( sizeof( LookupContext ) );
  532.     if ( !contextPtr )
  533.     {
  534.         printf( "NewPtr call failed!" );
  535.         return;
  536.     }
  537.     
  538.     myServicesNotifyUPP = NewNSLClientNotifyUPP(ServicesLookupNotifyProc);
  539.     
  540.     iErr = NSLPrepareRequest( myServicesNotifyUPP, contextPtr, gOurClientRef, &ourRequestRef, buffer, bufLen, &ourAsyncInfo );
  541.  
  542.     if ( iErr.theErr )
  543.     {
  544.         printf("NSLPrepareRequest returned error %ld\r", iErr.theErr );
  545.  
  546.         NSLErrorToString( iErr, gErrorString, gSolutionString );
  547.         printf("Error #%ld: %s\r", iErr.theErr, gErrorString );
  548.         printf("Solution: %s\r", gSolutionString );
  549.     }
  550.     else
  551.     {
  552.         contextPtr->theRequestRef = ourRequestRef;
  553.         contextPtr->theRequestDataPtr = ourAsyncInfo;
  554.         contextPtr->lookupFinished = false;
  555.         
  556.         serviceList = NSLMakeNewServicesList( service );    // we can pass a comma delimited cstring here (ie "http,ftp")
  557.         
  558.         // now we need to create a NSLTypedDataPtr which holds teh serviceList info as well as an attribute if we wish
  559.         if ( serviceList != NULL )
  560.         {
  561.             iErr.theErr = NSLMakeServicesRequestPB( serviceList, &newDataPtr );    // we can also pass an attribute if we want to get more specific
  562.             NSLDisposeServicesList( serviceList );                            // we are done with this, free this memory!        
  563.         }
  564.         
  565.         // set the values of ourAsyncInfo pb
  566.         ourAsyncInfo->maxSearchTime = 0;        // no max search time
  567.         ourAsyncInfo->alertInterval = 0;         // no alert interval
  568.         ourAsyncInfo->alertThreshold = 1;        // make alert threshold every item...
  569.  
  570.         if ( iErr.theErr == noErr )
  571.             iErr = NSLStartServicesLookup( ourRequestRef, neighborhood, newDataPtr, ourAsyncInfo );
  572.  
  573.         if ( iErr.theErr == noErr )
  574.         {
  575.             while ( !contextPtr->lookupFinished )
  576.             {
  577.                 YieldToAnyThread();                            // its important to have a call to YieldToAnyThread in your main event loop
  578.                                                             // which is what we are simulating here...
  579.                 SystemTask();
  580.             }
  581.         }
  582.         
  583.         NSLFreeTypedDataPtr( newDataPtr );                    // dispose this
  584.     }
  585.     
  586.     NSLFreeNeighborhood( neighborhood );                    // make sure we free up this memory
  587.     
  588.     if ( buffer )
  589.         DisposePtr(buffer);
  590. }
  591.  
  592.  
  593. // the code below is provided as an example, but won't work here because we don't have an event loop
  594. // that calls YieldToAnyThread.
  595. void TestStandardRegisterURL(void)
  596. {
  597.     char                url[1024];
  598.     UInt16                index = 0;
  599.     NSLError            regError;
  600.     char                c;
  601.     
  602.     printf( "Please Type in the url you want to register then hit return\r" );
  603.     scanf("%c", &c );
  604.     
  605.     while ( c != '\r' && c != '\n' && index < sizeof(url)-1 )
  606.     {
  607.         url[index++] = c;
  608.         scanf("%c", &c );
  609.     };
  610.     
  611.     url[index] = '\0';        // null terminate this
  612.     
  613.     regError = NSLStandardRegisterURL( url, nil );        // we aren't going to specify a neighborhood to register in, leave it up to the plugins
  614.     
  615.     if ( regError.theErr )
  616.     {
  617.         NSLErrorToString( regError, gErrorString, gSolutionString );
  618.         printf("Error #%ld: %s\r", regError.theErr, gErrorString );
  619.         printf("Solution: %s\r", gSolutionString );
  620.     }
  621.     else
  622.         printf("URL registered");
  623. }
  624.  
  625. void TestStandardDeregisterURL(void)
  626. {
  627.     char                url[1024];
  628.     UInt16                index = 0;
  629.     NSLError            regError;
  630.     char                c;
  631.     
  632.     printf( "Please Type in the url you want to register then hit return\r" );
  633.     scanf("%c", &c );
  634.     
  635.     while ( c != '\r' && c != '\n' && index < sizeof(url)-1 )
  636.     {
  637.         url[index++] = c;
  638.         scanf("%c", &c );
  639.     };
  640.     
  641.     url[index] = '\0';        // null terminate this
  642.     
  643.     regError = NSLStandardDeregisterURL( url, nil );        // we aren't going to specify a neighborhood to deregister in, leave it up to the plugins
  644.     
  645.     if ( regError.theErr )
  646.     {
  647.         NSLErrorToString( regError, gErrorString, gSolutionString );
  648.         printf("Error #%ld: %s\r", regError.theErr, gErrorString );
  649.         printf("Solution: %s\r", gSolutionString );
  650.     }
  651.     else
  652.         printf("URL deregistered");
  653. }
  654.  
  655.