]> asedeno.scripts.mit.edu Git - PuTTY.git/blob - dnr.c
Removing one bug, and hunting another
[PuTTY.git] / dnr.c
1 /*      
2
3         File:           DNR.c 
4         
5         Contains:       DNR library for MPW
6
7         Copyright:      © 1989-1995 by Apple Computer, Inc., all rights reserved
8
9         Version:        Technology:                     Networking
10                                 Package:                        Use with MacTCP 2.0.6 and the Universal
11                                                                         Interfaces 2.1b1        
12                 
13         Change History (most recent first):
14                 <3>      1/23/95        rrk     implemented use of universal procptrs
15                                                                 Changed selector name HINFO to HXINFO
16                                                                 due to conflict of name in MacTCP header
17                                                                 Removed use of TrapAvailable and exchanged
18                                                                 for the TrapExists call.
19                                                                 Changed symbol codeHandle to gDNRCodeHndl
20                                                                 Changed symbol dnr to gDNRCodePtr
21         Further modifications by Steve Falkenburg, Apple MacDTS 8/91
22         Modifications by Jim Matthews, Dartmouth College, 5/91
23
24         
25 */
26
27 #ifndef __OSUTILS__
28 #include <OSUtils.h>
29 #endif
30
31 #ifndef __ERRORS__
32 #include <Errors.h>
33 #endif
34
35 #ifndef __FILES__
36 #include <Files.h>
37 #endif
38
39 #ifndef __RESOURCES__
40 #include <Resources.h>
41 #endif
42
43 #ifndef __MEMORY__
44 #include <Memory.h>
45 #endif
46
47 #ifndef __TRAPS__
48 #include <Traps.h>
49 #endif
50
51 #ifndef __GESTALT__
52 #include <Gestalt.h>
53 #endif
54
55 #ifndef __FOLDERS__
56 #include <Folders.h>
57 #endif
58
59 #ifndef __TOOLUTILS__
60 #include <ToolUtils.h>
61 #endif
62
63
64 #ifndef __MACTCP__
65 #include "MacTCP.h"
66 #endif
67
68 #ifndef __ADDRESSXLATION__
69 #include "AddressXlation.h"
70 #endif
71
72 // think C compatibility stuff
73
74 #ifndef _GestaltDispatch
75 #define _GestaltDispatch        _Gestalt
76 #endif
77
78
79 /* RRK Modification 1/95 - commenting out the following defines as they are
80         defined in the DNRCalls.h header file
81 */
82
83 void GetSystemFolder(short *vRefNumP, long *dirIDP);
84 void GetCPanelFolder(short *vRefNumP, long *dirIDP);
85 short SearchFolderForDNRP(long targetType, long targetCreator, short vRefNum, long dirID);
86 short OpenOurRF(void);
87 short   NumToolboxTraps(void);
88 TrapType        GetTrapType(short theTrap);
89 Boolean TrapExists(short theTrap);
90
91 static Handle                   gDNRCodeHndl = nil;
92 static ProcPtr                  gDNRCodePtr = nil;
93
94 /*      Check the bits of a trap number to determine its type. */
95
96 /* InitGraf is always implemented (trap $A86E).  If the trap table is big
97 ** enough, trap $AA6E will always point to either Unimplemented or some other
98 ** trap, but will never be the same as InitGraf.  Thus, you can check the size
99 ** of the trap table by asking if the address of trap $A86E is the same as
100 ** $AA6E. */
101
102 /* #pragma segment UtilMain */
103 short   NumToolboxTraps(void)
104 {
105         if (NGetTrapAddress(_InitGraf, ToolTrap) == NGetTrapAddress(0xAA6E, ToolTrap))
106                 return(0x200);
107         else
108                 return(0x400);
109 }
110
111 /* #pragma segment UtilMain */
112 TrapType        GetTrapType(short theTrap)
113 {
114         /* OS traps start with A0, Tool with A8 or AA. */
115         if ((theTrap & 0x0800) == 0)                                    /* per D.A. */
116                 return(OSTrap);
117         else
118                 return(ToolTrap);
119 }
120
121 Boolean TrapExists(short theTrap)
122 {
123         TrapType        theTrapType;
124
125         theTrapType = GetTrapType(theTrap);
126         if ((theTrapType == ToolTrap) && ((theTrap &= 0x07FF) >= NumToolboxTraps()))
127                 theTrap = _Unimplemented;
128
129         return(NGetTrapAddress(_Unimplemented, ToolTrap) != NGetTrapAddress(theTrap, theTrapType));
130 }
131
132 void GetSystemFolder(short *vRefNumP, long *dirIDP)
133 {
134         SysEnvRec info;
135         long wdProcID;
136         
137         SysEnvirons(1, &info);
138         if (GetWDInfo(info.sysVRefNum, vRefNumP, dirIDP, &wdProcID) != noErr) 
139         {
140                 *vRefNumP = 0;
141                 *dirIDP = 0;
142         }
143 }
144
145 void GetCPanelFolder(short *vRefNumP, long *dirIDP)
146 {
147         Boolean hasFolderMgr = false;
148         long feature;
149         
150         if (TrapExists(_GestaltDispatch)) if (Gestalt(gestaltFindFolderAttr, &feature) == noErr) hasFolderMgr = true;
151         if (!hasFolderMgr) 
152         {
153                 GetSystemFolder(vRefNumP, dirIDP);
154                 return;
155         }
156         else 
157         {
158                 if (FindFolder(kOnSystemDisk, kControlPanelFolderType, kDontCreateFolder, vRefNumP, dirIDP) != noErr) 
159                 {
160                         *vRefNumP = 0;
161                         *dirIDP = 0;
162                 }
163         }
164 }
165         
166 /* SearchFolderForDNRP is called to search a folder for files that might 
167         contain the 'dnrp' resource */
168 short SearchFolderForDNRP(long targetType, long targetCreator, short vRefNum, long dirID)
169 {
170         HParamBlockRec fi;
171         Str255 filename;
172         short refnum;
173         
174         fi.fileParam.ioCompletion = nil;
175         fi.fileParam.ioNamePtr = filename;
176         fi.fileParam.ioVRefNum = vRefNum;
177         fi.fileParam.ioDirID = dirID;
178         fi.fileParam.ioFDirIndex = 1;
179         
180         while (PBHGetFInfo(&fi, false) == noErr) 
181         {
182                 /* scan system folder for driver resource files of specific type & creator */
183                 if (fi.fileParam.ioFlFndrInfo.fdType == targetType &&
184                         fi.fileParam.ioFlFndrInfo.fdCreator == targetCreator) 
185                 {
186                         /* found the MacTCP driver file? */
187                         refnum = HOpenResFile(vRefNum, dirID, filename, fsRdPerm);
188                         if (GetIndResource('dnrp', 1) == NULL)
189                                 CloseResFile(refnum);
190                         else
191                                 return refnum;
192                 }
193                 /* check next file in system folder */
194                 fi.fileParam.ioFDirIndex++;
195                 fi.fileParam.ioDirID = dirID;   /* PBHGetFInfo() clobbers ioDirID */
196         }
197         return(-1);
198 }       
199
200 /* OpenOurRF is called to open the MacTCP driver resources */
201
202 short OpenOurRF(void)
203 {
204         short refnum;
205         short vRefNum;
206         long dirID;
207         
208         /* first search Control Panels for MacTCP 1.1 */
209         GetCPanelFolder(&vRefNum, &dirID);
210         refnum = SearchFolderForDNRP('cdev', 'ztcp', vRefNum, dirID);
211         if (refnum != -1) return(refnum);
212                 
213         /* next search System Folder for MacTCP 1.0.x */
214         GetSystemFolder(&vRefNum, &dirID);
215         refnum = SearchFolderForDNRP('cdev', 'mtcp', vRefNum, dirID);
216         if (refnum != -1) return(refnum);
217                 
218         /* finally, search Control Panels for MacTCP 1.0.x */
219         GetCPanelFolder(&vRefNum, &dirID);
220         refnum = SearchFolderForDNRP('cdev', 'mtcp', vRefNum, dirID);
221         if (refnum != -1) return(refnum);
222                 
223         return -1;
224 }       
225
226
227 OSErr OpenResolver(char *fileName)
228 {
229         short                   refnum;
230         OSErr                   rc;
231         
232         if (gDNRCodePtr != nil)
233                 /* resolver already loaded in */
234                 return(noErr);
235                 
236         /* open the MacTCP driver to get DNR resources. Search for it based on
237            creator & type rather than simply file name */       
238         refnum = OpenOurRF();
239
240         /* ignore failures since the resource may have been installed in the 
241            System file if running on a Mac 512Ke */
242            
243         /* load in the DNR resource package */
244         gDNRCodeHndl = GetIndResource('dnrp', 1);
245         if (gDNRCodeHndl == nil)
246         {
247                 /* can't open DNR */
248                 return(ResError());
249         }
250         
251         DetachResource(gDNRCodeHndl);
252         if (refnum != -1) 
253         {
254                 CloseResFile(refnum);
255         }
256                 
257         /* lock the DNR resource since it cannot be reloated while opened */
258         MoveHHi(gDNRCodeHndl);
259         HLock(gDNRCodeHndl);
260         
261         gDNRCodePtr = (ProcPtr)*gDNRCodeHndl;
262         
263         /* call open resolver */
264         // RRK modification 1/95 use CallOpenResolverProc define to call UPP
265         
266         rc = CallOpenResolverProc((OpenResolverUPP)gDNRCodePtr, OPENRESOLVER,
267                                   fileName);
268         if (rc != noErr) 
269         {
270                 /* problem with open resolver, flush it */
271                 HUnlock(gDNRCodeHndl);
272                 DisposeHandle(gDNRCodeHndl);
273                 gDNRCodePtr = nil;
274         }
275         return(rc);
276 }
277
278
279 OSErr CloseResolver(void)
280 {
281         
282         if (gDNRCodePtr == nil)
283                 /* resolver not loaded error */
284                 return(notOpenErr);
285                 
286         /* call close resolver */
287         // RRK modification 1/95 use CallCloseResolverProc define to call UPP
288         // (void) (*dnr)(CLOSERESOLVER);
289
290         CallCloseResolverProc((CloseResolverUPP)gDNRCodePtr, CLOSERESOLVER);
291         
292         /* release the DNR resource package */
293         HUnlock(gDNRCodeHndl);
294         DisposeHandle(gDNRCodeHndl);
295         gDNRCodePtr = nil;
296         return(noErr);
297 }
298
299         // RRK modification 1/95 declare parameter resultProc to be of type 
300         // ResultProcUPP instead of a long
301         
302 OSErr StrToAddr(char *hostName, struct hostInfo *rtnStruct, 
303                         ResultUPP resultproc, Ptr userDataPtr)
304 {
305         if (gDNRCodePtr == nil)
306                 /* resolver not loaded error */
307                 return(notOpenErr);
308                 
309         // RRK modification 1/95 use CallStrToAddrProc define to call UPP
310         // return((*dnr)(STRTOADDR, hostName, rtnStruct, resultproc, userDataPtr));
311                         
312         return (CallStrToAddrProc((StrToAddrUPP)gDNRCodePtr, STRTOADDR, hostName, rtnStruct, resultproc, userDataPtr));
313 }
314         
315 OSErr AddrToStr(unsigned long addr, char *addrStr)
316 {
317         OSErr   err;
318         if (gDNRCodePtr == nil)
319                 /* resolver not loaded error */
320                 return(notOpenErr);
321                 
322         // RRK modification 1/95 use CallAddrToStrProc define to call UPP
323         // (*dnr)(ADDRTOSTR, addr, addrStr);
324         
325         err = CallAddrToStrProc((AddrToStrUPP)gDNRCodePtr, ADDRTOSTR, addr, addrStr);
326         return(noErr);
327 }
328         
329 OSErr EnumCache(EnumResultUPP resultproc, Ptr userDataPtr)
330 {
331
332         if (gDNRCodePtr == nil)
333                 /* resolver not loaded error */
334                 return(notOpenErr);
335                 
336         // RRK modification 1/95 use CallEnumCacheProc define to call UPP
337         // return((*dnr)(ENUMCACHE, resultproc, userDataPtr));
338
339         return (CallEnumCacheProc((EnumCacheUPP)gDNRCodePtr, ENUMCACHE, resultproc, userDataPtr));
340 }
341         
342         
343 OSErr AddrToName(unsigned long addr, struct hostInfo *rtnStruct, 
344                         ResultUPP resultproc, Ptr userDataPtr)
345 {
346         if (gDNRCodePtr == nil)
347                 /* resolver not loaded error */
348                 return(notOpenErr);
349                 
350         // RRK modification 1/95 use CallAddrToNameProc define to call UPP
351         // return((*dnr)(ADDRTONAME, addr, rtnStruct, resultproc, userDataPtr));
352
353         return(CallAddrToNameProc((AddrToNameUPP)gDNRCodePtr, ADDRTONAME, addr, rtnStruct, resultproc, userDataPtr));
354 }
355
356
357 extern OSErr HInfo(char *hostName, struct returnRec *returnRecPtr, 
358                         ResultProc2UPP resultProc, Ptr userDataPtr)
359 {
360         if (gDNRCodePtr == nil)
361                 /* resolver not loaded error */
362                 return(notOpenErr);
363                 
364         // RRK modification 1/95 use CallHInfoProc define to call UPP
365         // return((*dnr)(HINFO, hostName, returnRecPtr, resultProc, userDataPtr));
366
367         return(CallHInfoProc((HInfoUPP)gDNRCodePtr, HXINFO, hostName, returnRecPtr, resultProc, userDataPtr));
368
369 }
370         
371 extern OSErr MXInfo(char *hostName, struct returnRec *returnRecPtr, 
372                         ResultProc2UPP resultProc, Ptr userDataPtr)
373 {
374         if (gDNRCodePtr == nil)
375                 /* resolver not loaded error */
376                 return(notOpenErr);
377                 
378         // RRK modification 1/95 use CallHInfoProc define to call UPP
379         // return((*dnr)(MXINFO, hostName, returnRecPtr, resultProc, userDataPtr));
380
381         return(CallMXInfoProc((MXInfoUPP)gDNRCodePtr, MXINFO, hostName, returnRecPtr, resultProc, userDataPtr));
382
383 }       /* removed ; (causes syntax err in Think C 5.0 */
384