home *** CD-ROM | disk | FTP | other *** search
/ Celestin Apprentice 4 / Apprentice-Release4.iso / Source Code / Libraries / MacTCP Library 1.1 / Library / LowLevel ƒ / Source ƒ / DNR.c next >
Encoding:
C/C++ Source or Header  |  1995-12-04  |  9.8 KB  |  433 lines  |  [TEXT/SPM ]

  1. /*
  2.     DNR.c
  3.     
  4.     C routines to implement the domain name resolving functions.
  5.     
  6.     Some portions © Apple Computer.
  7.     
  8.     01/30/94 dn - Created.
  9.     12/04/95 dn - Prep'd for Apprentice 4
  10. */
  11.  
  12. #include <Gestalt.h>
  13. #include <Folders.h>
  14. #include <Traps.h>
  15.  
  16. #include <MyTCPIncludes.h>
  17.  
  18. Handle            gMacDNRcode=(Handle)0L;                // the DNR code resource’s handle
  19. UniversalProcPtr    gMacDNRentry=(UniversalProcPtr)0L;    // the DNR code entry point
  20.  
  21. /* Local Constants */
  22. #define _kDefaultHostFilename "\pHosts"
  23.  
  24. /* Local Prototypes */
  25. OSErr BuildHostFile(StringPtr filename,short vRefNum,long dirId);
  26. OSErr SearchFolderForDNRP(OSType targetType,OSType targetCreator,short vRefNum, long dirID);
  27. OSErr OpenTheDNR(void);
  28.  
  29. /*
  30.     OpenResolver
  31.     
  32.     Makes the resolver available for the other DNR routines.  This routine must be called before any of
  33.     the other DNR routines.
  34. */
  35. OSErr OpenResolver(StringPtr fileName){
  36.     short    vRefNum;
  37.     short    refnum;
  38.     long        dirID;
  39.     short    fRef;
  40.     OSErr    rc;
  41.     
  42.     // is the resolver already there?    
  43.     if (gMacDNRentry)
  44.         return noErr;
  45.  
  46.     // open the MacTCP driver to get DNR resources
  47.     refnum = (short)OpenTheDNR();
  48.     // Ignore any errors because the resource may be installed in the system file (Mac 512k's).
  49.     
  50.     // load the DNR resource package
  51.     gMacDNRcode = GetIndResource('dnrp', 1);
  52.     if (gMacDNRcode==(Handle)0){
  53.         rc=ResError();
  54.         return rc;
  55.     }
  56.     
  57.     DetachResource(gMacDNRcode);
  58.  
  59.     if (refnum != -1){ // i.e. if it's not the system folder...
  60.         CloseWD(refnum);
  61.         CloseResFile(refnum);
  62.     }
  63.     
  64.     // lock the DNR resource since it cannot be relocated while opened
  65.     MoveHHi((Handle)gMacDNRcode);
  66.     HLock((Handle)gMacDNRcode);
  67.     
  68.     gMacDNRentry = (UniversalProcPtr)*gMacDNRcode;
  69.     
  70.     if (fileName!=(StringPtr)0){
  71.         if (fileName[0]==0){
  72.             // then we were passed an empty string
  73.             // pretend it is the null string (because it is in reality)
  74.             
  75.             fileName=(StringPtr)0;
  76.         }
  77.     }
  78.     
  79.     // if the filename is null...
  80.     if (fileName==(StringPtr)0){
  81.         /*
  82.             Then the resolver is going to try to use the hosts file in the system
  83.             folder.  We will check to see if it is there; if not, we are going to create
  84.             it...
  85.         */
  86.         
  87.         GetSystemFolder(&vRefNum, &dirID);
  88.         
  89.         // try to open the file...
  90.         rc = HOpen(vRefNum,dirID,_kDefaultHostFilename,fsRdPerm,&fRef);
  91.         
  92.         switch (rc) {
  93.             case noErr:    // the file exists...
  94.                 FSClose(fRef);
  95.                 break;
  96.             case fnfErr:    // the file doesn't exist, create one...
  97.                 BuildHostFile(_kDefaultHostFilename,vRefNum,dirID);
  98.                 break;
  99.         }
  100.     }
  101.     
  102.     // convert the name to a C string temporarily...
  103.     if (fileName!=(StringPtr)NULL)
  104.         MyP2CStr(fileName);
  105.     
  106.     // ask the DNR resource to open the resolver
  107.     rc = CallOpenResolverProc((OpenResolverUPP)gMacDNRentry,OPENRESOLVER,(char*)fileName);
  108.     
  109.     // quick convert the name back...
  110.     if (fileName!=(StringPtr)NULL)
  111.         MyC2PStr((char*)fileName);
  112.     
  113.     if (rc != noErr) {
  114.         HUnlock((Handle)gMacDNRcode);            // problem with open resolver, flush DNR resource
  115.         DisposeHandle((Handle)gMacDNRcode);
  116.         gMacDNRcode = NULL;
  117.         gMacDNRentry = NULL;
  118.         return dnrNoResolver;            // signal failure of DNR
  119.     }
  120.     return noErr;
  121. }
  122.  
  123. /*
  124.     CloseResolver
  125.     
  126.     Closes the resolver.  Do not make any more resolver calls unless the resolver is opened again.
  127. */
  128. OSErr CloseResolver(){
  129.     if (gMacDNRentry ==(UniversalProcPtr)NULL)
  130.         return dnrNoResolver;
  131.  
  132.     // call CloseResolver function in DNR
  133.     CallCloseResolverProc((CloseResolverUPP)gMacDNRentry,CLOSERESOLVER);
  134.  
  135.     // release the DNR code resource
  136.     HUnlock((Handle)gMacDNRcode);
  137.     DisposeHandle((Handle)gMacDNRcode);
  138.     gMacDNRcode = (Handle)NULL;
  139.     gMacDNRentry = (UniversalProcPtr)NULL;
  140.     
  141.     return noErr;
  142. }
  143.  
  144. /*
  145.     StrToAddr
  146.     
  147.     Converts a host name string to an address.  (ASYNCHRONOUS CALL)
  148. */
  149. OSErr StrToAddr(char* hostName,HostInfoPtr host,HostInfoUPP hiproc,char* userDataPtr){
  150.     if (gMacDNRentry == (UniversalProcPtr)0)
  151.         return dnrNoResolver;
  152.     
  153.     return CallStrToAddrProc((StrToAddrUPP)gMacDNRentry,STRTOADDR,hostName,host,hiproc,userDataPtr);
  154. }
  155.  
  156. /*
  157.     AddrToStr
  158.     
  159.     Convert an address to it's string equivalent.  (SYNCHRONOUS CALL)
  160. */
  161. OSErr AddrToStr(ip_addr addr, char* str){
  162.     if (gMacDNRentry == (UniversalProcPtr)0)
  163.         return dnrNoResolver;
  164.     
  165.     CallAddrToStrProc((AddrToStrUPP)gMacDNRentry,ADDRTOSTR,addr,str);
  166.     
  167.     return noErr;
  168. }
  169.  
  170. /*
  171.     EnumCache
  172.     
  173.     Enumerates through the cache of addresses internal to the resolver. (ASYNCHRONOUS CALL)
  174. */
  175. OSErr EnumCache(EnumUPP eproc,char* userDataPtr){
  176.     if (gMacDNRentry==(UniversalProcPtr)0)
  177.         return dnrNoResolver;
  178.     
  179.     return CallEnumCacheProc((EnumCacheUPP)gMacDNRentry,ENUMCACHE,eproc,userDataPtr);
  180. }
  181.  
  182. /*
  183.     AddrToName
  184.     
  185.     Convert an address to it's name equivalent. (ASYNCHRONOUS CALL)
  186. */
  187. OSErr AddrToName(ip_addr addr,HostInfoPtr host,HostInfoUPP hiproc,char* userDataPtr){
  188.     if (gMacDNRentry==(UniversalProcPtr)0)
  189.         return dnrNoResolver;
  190.     
  191.     return CallAddrToNameProc((AddrToNameUPP)gMacDNRentry,ADDRTONAME,addr,host,hiproc,userDataPtr);
  192. }
  193.  
  194. /*
  195.     HInfo
  196.     
  197.     Get Host Information. (cpu type and os type) (ASYNCHRONOUS CALL)
  198. */
  199. OSErr HInfo(char* hostName,ReturnPtr ret,ReturnRecUPP rproc,char* userDataPtr){
  200.     if (gMacDNRentry==(UniversalProcPtr)0)
  201.         return dnrNoResolver;
  202.     
  203.     return CallHInfoProc((HInfoUPP)gMacDNRentry,HINFO,hostName,ret,rproc,userDataPtr);
  204. }
  205.  
  206. /*
  207.     MXInfo
  208.     
  209.     Get Host Mailer Info.  (postmaster's mail address) (ASYNCHRONOUS CALL)
  210. */
  211. OSErr MXInfo(char* hostName,ReturnPtr ret,ReturnRecUPP rproc,char* userDataPtr){
  212.     if (gMacDNRentry==(UniversalProcPtr)0)
  213.         return dnrNoResolver;
  214.     
  215.     return CallMXInfoProc((MXInfoUPP)gMacDNRentry,MXINFO,hostName,ret,rproc,userDataPtr);
  216. }
  217.  
  218. /*
  219.     OpenTheDNR
  220.     
  221.     Opens the resource file containing the DNR.
  222. */
  223. OSErr OpenTheDNR(){
  224.     short    refnum;
  225.     short    vRefNum;
  226.     long        dirID;
  227.     
  228.     // first search Control Panels for MacTCP 1.1 or greater
  229.     GetCPanelFolder(&vRefNum, &dirID);
  230.     refnum = SearchFolderForDNRP('cdev', 'ztcp', vRefNum, dirID);
  231.     if (refnum != fnfErr)
  232.         return refnum;
  233.     
  234.     // next search System Folder for MacTCP 1.0.x
  235.     GetSystemFolder(&vRefNum, &dirID);
  236.     refnum = SearchFolderForDNRP('cdev', 'mtcp', vRefNum, dirID);
  237.     if (refnum != fnfErr)
  238.         return refnum;
  239.  
  240.     // finally, search Control Panels for MacTCP 1.0.x
  241.     GetCPanelFolder(&vRefNum, &dirID);
  242.     refnum = SearchFolderForDNRP('cdev', 'mtcp', vRefNum, dirID);
  243.     if (refnum != fnfErr)
  244.         return refnum;
  245.     
  246.     return fnfErr;
  247. }
  248.  
  249. /*
  250.     SearchFolderForDNRP
  251.     
  252.     Search a designated folder for a file with the given type/creator and containing the 'dnrp' resource.
  253. */
  254. OSErr SearchFolderForDNRP(OSType targetType,OSType targetCreator,short vRefNum, long dirID){
  255.     HParamBlockRec    fi;
  256.     Str255            filename;
  257.     short            refnum;
  258.     
  259.     // initialize our search mechanism
  260.     fi.fileParam.ioCompletion = nil;
  261.     fi.fileParam.ioNamePtr = filename;
  262.     fi.fileParam.ioVRefNum = vRefNum;
  263.     fi.fileParam.ioDirID = dirID;
  264.     fi.fileParam.ioFDirIndex = 1;
  265.     
  266.     // keep looking till we run out of files
  267.     while (PBHGetFInfo(&fi, false) == noErr) {
  268.     
  269.         // scan the folder for files that match our type & creator
  270.         if (fi.fileParam.ioFlFndrInfo.fdType == targetType &&
  271.             fi.fileParam.ioFlFndrInfo.fdCreator == targetCreator) {
  272.  
  273.             // type/creator match, look for the resource
  274.             refnum = HOpenResFile(vRefNum, dirID, filename, fsRdPerm);
  275.             if (GetIndResource('dnrp', 1) == NULL)
  276.                 CloseResFile(refnum);
  277.             else
  278.                 return refnum;
  279.         }
  280.  
  281.         // no match or no resource, try next file in folder
  282.         fi.fileParam.ioFDirIndex++;
  283.         fi.fileParam.ioDirID = dirID;                // PBHGetFInfo() clobbers ioDirID
  284.     }
  285.     return fnfErr;                                    // nothing found
  286. }
  287.  
  288. /*
  289.     BuildHostFile
  290.     
  291.     This function will create a host file and copy the information stored from the resources into 
  292.     the new host file.
  293.     
  294. */
  295. OSErr BuildHostFile(StringPtr filename,short vRefNum,long dirId){
  296.     OSErr err;
  297.     Handle tH;
  298.     short fref;
  299.     long len;
  300.     
  301.     // first try to create the file...
  302.     err=HCreate(vRefNum, dirId,filename,kHostFileCreatorType,'TEXT');
  303.     
  304.     if (err!=noErr)
  305.         return err;
  306.     
  307.     // the file has been created...
  308.     
  309.     // now try to get the text resource...
  310.     tH=GetResource('TEXT',30004);
  311.     
  312.     if (tH==(Handle)0L)
  313.         return ResError();
  314.     
  315.     HLock(tH);
  316.     
  317.     len=SizeResource(tH);
  318.     
  319.     // Got the text, open the file
  320.     err=HOpenDF(vRefNum,dirId,filename,fsWrPerm,&fref);
  321.     
  322.     if (err!=noErr)
  323.         goto ExitFromBuildHostFile;
  324.     
  325.     // got the file, write the text...
  326.     err=FSWrite(fref,&len,*tH);
  327.     
  328.     // all done...
  329.     FSClose(fref);
  330.     
  331. ExitFromBuildHostFile:
  332.     HUnlock(tH);
  333.     
  334.     ReleaseResource(tH);
  335.     
  336.     return err;
  337. }
  338.  
  339. /*
  340.     GetSystemFolder
  341.  
  342.     Return the ID of the current system folder.
  343. */
  344. OSErr GetSystemFolder (short *vRefNumP, long *dirIDP){
  345.     SysEnvRec    info;
  346.     long            wdProcID;
  347.     
  348.     SysEnvirons(1, &info);
  349.     if (GetWDInfo(info.sysVRefNum, vRefNumP, dirIDP, &wdProcID) != noErr) {
  350.         *vRefNumP = 0;
  351.         *dirIDP = 0;
  352.     }
  353. }
  354.  
  355. /*
  356.     GetCPanelFolder
  357.  
  358.     Return the ID of the current “Control Panels” folder.
  359. */
  360. OSErr GetCPanelFolder (short *vRefNumP, long *dirIDP){
  361.     Boolean    hasFolderMgr = false;
  362.     long        feature;
  363.     
  364.     // see if we have the Folder Manager available    
  365.     if (TrapAvailable((short) _Gestalt))
  366.         if (Gestalt(gestaltFindFolderAttr, &feature) == noErr)
  367.             hasFolderMgr = TRUE;
  368.  
  369.     if (!hasFolderMgr) {
  370.         // return the system folder because we are obviously running on system 6 or less when there
  371.         // was no control panels folder.
  372.         
  373.         return GetSystemFolder(vRefNumP, dirIDP);
  374.     } else {
  375.         OSErr err;
  376.         
  377.         err=FindFolder(kOnSystemDisk, kControlPanelFolderType,kDontCreateFolder, vRefNumP, dirIDP);
  378.         
  379.         if (err!= noErr) {
  380.             *vRefNumP = 0;
  381.             *dirIDP = 0;
  382.             
  383.             return err;
  384.         }
  385.     }
  386.     return noErr;
  387. }
  388.  
  389. /*
  390.     NumToolboxTraps
  391.     
  392.     Returns the number of toolbox traps.
  393. */
  394. short NumToolboxTraps(){
  395.     if (NGetTrapAddress(_InitGraf, ToolTrap) == NGetTrapAddress(0xAA6E, ToolTrap))
  396.         return(0x0200);
  397.     else
  398.         return(0x0400);
  399. }
  400.  
  401. /*
  402.     GetTrapType
  403.     
  404.     Returns the type of the specified trap.
  405. */
  406. TrapType GetTrapType(short theTrap){
  407.     if ((theTrap & TrapMask) > 0)
  408.         return(ToolTrap);
  409.     else
  410.         return(OSTrap);
  411. }
  412.  
  413. /*
  414.     TrapAvailable
  415.     
  416.     Is the specified trap available?
  417. */
  418. Boolean TrapAvailable(short theTrap){
  419.     TrapType    tType;
  420.     
  421.     tType = GetTrapType(theTrap);
  422.     if (tType == ToolTrap)
  423.         theTrap = theTrap & 0x07FF;
  424.         
  425.     if (theTrap >= NumToolboxTraps())
  426.         theTrap = _Unimplemented;
  427.     
  428.     return (NGetTrapAddress(theTrap, tType) !=
  429.             NGetTrapAddress(_Unimplemented, ToolTrap));
  430. }
  431.  
  432.  
  433.