home *** CD-ROM | disk | FTP | other *** search
/ Garbo / Garbo.cdr / mac / source / clintsrc.sit / TCPNameToAddr.c < prev    next >
Text File  |  1990-01-29  |  6KB  |  218 lines

  1. /*
  2.     TCPNameToAddr(hostName,timeOut,hostFile) -- Return a list of alternative addresses for the host
  3.         name specified. If the name can't be resolved locally, go ask a name server. If it can't be resolved
  4.         within timeOut ticks, give up. The hostFile parameter gives the file name of a local name table
  5.         file. The last two parameters are optional. timeOut defaults to 1800. hostFile defaults to none.
  6.  
  7.     To compile and link this file using Macintosh Programmer's Workshop,
  8.  
  9.         c -b TCPNameToAddr.p
  10.         link -m ENTRYPOINT -o "TCP XCMD Example" -rt XFCN=7870 -sn Main=TCPNameToAddr ╢
  11.             TCPNameToAddr.c.o "{Libraries}HyperXLib.o" "{Libraries}Interface.o" "{CLibraries}CInterface.o" ╢
  12.             "{CLibraries}StdCLib.o"
  13.  
  14.     ⌐ Copyright 1989 by Apple Computer, Inc.
  15.  
  16.     Initial coding 3/89 by Harry R. Chesley.
  17.     
  18.     Un-XCMD'ed 10/89 by Greg Anderson
  19. */
  20.  
  21. #include <OSUtils.h>
  22. #include <Errors.h>
  23. #include <Files.h>
  24. #include <Resources.h>
  25. #include <Memory.h>
  26. #include <Events.h>
  27. #include <HyperXCmd.h>
  28. #include <String.h>
  29. #include "MacTCPCommonTypes.h"
  30.  
  31. /* DNR resource function IDs. */
  32. #define OPENRESOLVER 1
  33. #define CLOSERESOLVER 2
  34. #define STRTOADDR 3
  35. #define    ADDRTOSTR 4
  36. #define    ENUMCACHE 5
  37. #define ADDRTONAME 6
  38.  
  39. /* Default time-out. */
  40. #define DEFAULTTICK 3600
  41. /* Minimum time-out (to fix bug in MacTCP). */
  42. #define MINTICK 2400
  43.  
  44. /* Number of addresses returned by DNR. */
  45. #define NUM_ALT_ADDRS    4
  46.  
  47. /* DNR return structure. */
  48. typedef struct hostInfo {
  49.     int    rtnCode;                                            /* Result code. */
  50.     char cname[255];                                        /* Standard name. */
  51.     unsigned long addr[NUM_ALT_ADDRS];        /* Addresses. */
  52. };
  53.  
  54. typedef OSErr (*OSErrProcPtr)();
  55.  
  56. short NameToAddr(host_name,inet_addr,timeout)
  57.     char        *host_name;
  58.     long        *inet_addr,
  59.                 timeout;
  60. {
  61.     Handle codeHndl;                /* DNR code resource handle. */
  62.     OSErrProcPtr dnr;                /* Pointer to code resource. */
  63.     SysEnvRec info;                    /* System info record (to find the system volume). */
  64.     HParamBlockRec fi;                /* Parameter block (to find the MacTCP file). */
  65.     Str255 filename;                /* File name (for MacTCP file search). */
  66.     char str[256];                    /* Scratch string. */
  67.     short refnum;                    /* Resource file refnum. */
  68.     OSErr rc;                        /* Result code return. */
  69.     struct hostInfo rtnStruct;        /* Answer from DNR. */
  70.     struct hostInfo cacheFltRtn;    /* Place to return the answer if there's a cache fault. */
  71.     long lastTick;                    /* When to time-out. */
  72.     pascal void resultProc();
  73.  
  74.     short ntaErr = 0;                /* GA  NameToAdr error */
  75.     
  76.     *inet_addr = 0;    /* GA */
  77.     *filename = 0; /* GA */
  78.     
  79.     /* Get the system volume. */
  80.     SysEnvirons(1, &info);
  81.  
  82.     /* Prepare to scan for the MacTCP file (where we'll find the DNR code resource). */
  83.     fi.fileParam.ioCompletion = nil;
  84.     fi.fileParam.ioNamePtr = &filename;
  85.     fi.fileParam.ioVRefNum = info.sysVRefNum;
  86.     fi.fileParam.ioDirID = 0;
  87.     fi.fileParam.ioFDirIndex = 1;
  88.     refnum = -1;
  89.     /* Scan for MacTCP file. */
  90.     while (PBHGetFInfo(&fi, false) == noErr) {
  91.         /* scan system folder for driver resource files of specific type & creator */
  92.         if (fi.fileParam.ioFlFndrInfo.fdType == 'cdev' &&
  93.             fi.fileParam.ioFlFndrInfo.fdCreator == 'mtcp') {
  94.             /* Found the MacTCP driver file. */
  95.             SetVol(nil,fi.fileParam.ioVRefNum);
  96.             refnum = OpenResFile(&filename);
  97.             break;
  98.         };
  99.         /* Check next file in system folder. */
  100.         fi.fileParam.ioFDirIndex++;
  101.         fi.fileParam.ioDirID = 0;
  102.     };
  103.     
  104.     /* Ignore failures since the resource may have been installed in the 
  105.        System file if running on a Mac 512Ke. */
  106.        
  107.     /* Load in the DNR resource package. */
  108.     codeHndl = GetIndResource('dnrp', 1);
  109.     if (codeHndl == nil) {
  110.         if (refnum != -1) CloseResFile(refnum);
  111.         /* errAbort(paramPtr,"ñññ couldn't open resource ñññ"); */
  112.         return(-1);
  113.     };
  114.     DetachResource(codeHndl);
  115.     if (refnum != -1) CloseResFile(refnum);
  116.         
  117.     /* Lock the DNR resource so it cannot be relocated while opened. */
  118.     HLock(codeHndl);
  119.     dnr = (OSErrProcPtr) *codeHndl;
  120.     if( !dnr ) return( -2 );            /* GA -- just checking */
  121.     
  122.     /* Call open resolver. */
  123.     *str = 0;    /* Fill in path/filename of HOST file here */
  124.     
  125.     /***
  126.      ***   THIS CALL OFTEN DIES UNDER MULTIFINDER!!!  Out of Mr. Memory error.
  127.      ***/
  128.     rc = (*dnr)(OPENRESOLVER, str);
  129.     /***/
  130.     
  131.     if (rc != noErr) {
  132.         /* Problem with open resolver, flush it. */
  133.         HUnlock(codeHndl);
  134.         DisposHandle(codeHndl);
  135.         /* errAbort(paramPtr,"ñññ domain name resolver failed ñññ"); */
  136.         return(-2);
  137.     };
  138.  
  139.     /* Get the address. */
  140.     strcpy(str,host_name); 
  141.     cacheFltRtn.rtnCode = 1;
  142.     rc = (*dnr)(STRTOADDR, str, &rtnStruct, resultProc, &cacheFltRtn);
  143.  
  144.     /* If we couldn't get it right away, wait for it. */
  145.     if (rc == cacheFault)
  146.     {
  147.         /* GA */
  148.         if( timeout == 0 ) timeout = DEFAULTTICK;
  149.         if( timeout < MINTICK ) timeout = MINTICK;
  150.         lastTick = TickCount() + timeout;
  151.         
  152.         /**** XCMD version:
  153.         if ((paramPtr->paramCount < 2) || (paramPtr->params[1] == nil)) lastTick = TickCount() + DEFAULTTICK;
  154.         else if (**paramPtr->params[1] == 0) lastTick = TickCount() + DEFAULTTICK;
  155.         else {
  156.             ZeroToPas(paramPtr,*(paramPtr->params[1]),str);
  157.             if ((lastTick = StrToNum(paramPtr,str)) > MINTICK) lastTick = MINTICK;
  158.             lastTick = lastTick + TickCount();
  159.         };
  160.         ******/
  161.         while ((TickCount() < lastTick) && (cacheFltRtn.rtnCode > 0));
  162.         rtnStruct = cacheFltRtn;
  163.     } else rtnStruct.rtnCode = rc;
  164.  
  165.     /* Check if we got it OK or not. */
  166.     if (rtnStruct.rtnCode == noErr)
  167.     {
  168.         *inet_addr = rtnStruct.addr[0];    /* GA */
  169.         
  170.         /* We did, so build the result string. */
  171.         /**** Don't return a string
  172.         for (i = 0; i < NUM_ALT_ADDRS; i++) {
  173.             if (rtnStruct.addr[i] == 0) break;
  174.             if (i > 0) strcat(resultStr,",");
  175.             NumToStr(paramPtr,rtnStruct.addr[i],str);
  176.             p2cstr(str);
  177.             strcat(resultStr,str);
  178.         };
  179.         *****/
  180.         /* Make the handle to return. */
  181.         /****** Only needed in XCMD
  182.         resultHand = NewHandle((long) strlen(resultStr)+1);
  183.         if (resultHand != nil) {
  184.             strcpy(*resultHand,resultStr);
  185.             paramPtr->returnValue = resultHand;
  186.         } else errAbort(paramPtr,"ñññ couldn't make result string ñññ");
  187.         *******/
  188.     }
  189.     else if (rtnStruct.rtnCode == 1)
  190.     {
  191.         /* errAbort("ñññ time-out ñññ"); */
  192.         ntaErr = -3;
  193.     }
  194.     else
  195.     {
  196.         /* errAbort(paramPtr,"ñññ couldn't get address ñññ"); */
  197.         ntaErr = -4;
  198.     }
  199.  
  200.     /* Call close resolver. */
  201.     (void) (*dnr)(CLOSERESOLVER);
  202.  
  203.     /* Release the DNR resource package. */
  204.     HUnlock(codeHndl);
  205.     DisposHandle(codeHndl);
  206.     
  207.     return( ntaErr );
  208. }
  209.  
  210. /* Async routine called when name is found from name server. We just copy the result
  211.     and let the main loop process it. */
  212.     
  213. pascal void resultProc(struct hostInfo *hostInfoPtr, struct hostInfo *userDataPtr)
  214.  
  215. {
  216.     *userDataPtr = *hostInfoPtr;
  217. }
  218.