Download
jcs
/subtext
/dnr.c
(View History)
jcs dnr: Don't require a pointer to a pointer for DNSResolveName | Latest amendment: 488 on 2023-04-26 |
1 | /* |
2 | * DNR.c - DNR library for MPW |
3 | * |
4 | * (c) Copyright 1988 by Apple Computer. All rights reserved |
5 | * |
6 | * Modifications by Jim Matthews, Dartmouth College, 5/91 |
7 | */ |
8 | |
9 | #include <OSUtils.h> |
10 | #include <Files.h> |
11 | #include <Folders.h> |
12 | #include <GestaltEqu.h> |
13 | #include <Traps.h> |
14 | |
15 | #include "AddressXlation.h" |
16 | #include "tcp.h" |
17 | |
18 | #define OPENRESOLVER 1 |
19 | #define CLOSERESOLVER 2 |
20 | #define STRTOADDR 3 |
21 | #define ADDRTOSTR 4 |
22 | #define ENUMCACHE 5 |
23 | #define ADDRTONAME 6 |
24 | #define HINFO 7 |
25 | #define MXINFO 8 |
26 | |
27 | TrapType GetTrapType(unsigned long theTrap); |
28 | Boolean TrapAvailable(unsigned long trap); |
29 | void GetSystemFolder(short *vRefNumP, long *dirIDP); |
30 | void GetCPanelFolder(short *vRefNumP, long *dirIDP); |
31 | short SearchFolderForDNRP(long targetType, long targetCreator, |
32 | short vRefNum, long dirID); |
33 | short OpenOurRF(void); |
34 | |
35 | Handle dnr = nil; |
36 | |
37 | TrapType |
38 | GetTrapType(unsigned long theTrap) |
39 | { |
40 | if (BitAnd(theTrap, 0x0800) > 0) |
41 | return (ToolTrap); |
42 | |
43 | return (OSTrap); |
44 | } |
45 | |
46 | Boolean |
47 | TrapAvailable(unsigned long trap) |
48 | { |
49 | TrapType trapType = ToolTrap; |
50 | unsigned long numToolBoxTraps; |
51 | |
52 | if (NGetTrapAddress(_InitGraf, ToolTrap) == |
53 | NGetTrapAddress(0xAA6E, ToolTrap)) |
54 | numToolBoxTraps = 0x200; |
55 | else |
56 | numToolBoxTraps = 0x400; |
57 | |
58 | trapType = GetTrapType(trap); |
59 | if (trapType == ToolTrap) { |
60 | trap = BitAnd(trap, 0x07FF); |
61 | if (trap >= numToolBoxTraps) |
62 | trap = _Unimplemented; |
63 | } |
64 | |
65 | return (NGetTrapAddress(trap, trapType) != |
66 | NGetTrapAddress(_Unimplemented, ToolTrap)); |
67 | } |
68 | |
69 | void |
70 | GetSystemFolder(short *vRefNumP, long *dirIDP) |
71 | { |
72 | SysEnvRec info; |
73 | long wdProcID; |
74 | |
75 | SysEnvirons(1, &info); |
76 | if (GetWDInfo(info.sysVRefNum, vRefNumP, dirIDP, &wdProcID) != noErr) { |
77 | *vRefNumP = 0; |
78 | *dirIDP = 0; |
79 | } |
80 | } |
81 | |
82 | void |
83 | GetCPanelFolder(short *vRefNumP, long *dirIDP) |
84 | { |
85 | Boolean hasFolderMgr = false; |
86 | long feature; |
87 | |
88 | if (TrapAvailable(_GestaltDispatch) && |
89 | Gestalt(gestaltFindFolderAttr, &feature) == noErr) |
90 | hasFolderMgr = true; |
91 | |
92 | if (!hasFolderMgr) { |
93 | GetSystemFolder(vRefNumP, dirIDP); |
94 | return; |
95 | } |
96 | |
97 | if (FindFolder(kOnSystemDisk, kControlPanelFolderType, |
98 | kDontCreateFolder, vRefNumP, dirIDP) != noErr) { |
99 | *vRefNumP = 0; |
100 | *dirIDP = 0; |
101 | } |
102 | } |
103 | |
104 | /* |
105 | * SearchFolderForDNRP is called to search a folder for files that might |
106 | * contain the 'dnrp' resource |
107 | */ |
108 | short |
109 | SearchFolderForDNRP(long targetType, long targetCreator, short vRefNum, |
110 | long dirID) |
111 | { |
112 | HParamBlockRec fi; |
113 | Str255 filename; |
114 | short refnum; |
115 | |
116 | fi.fileParam.ioCompletion = nil; |
117 | fi.fileParam.ioNamePtr = (StringPtr)&filename; |
118 | fi.fileParam.ioVRefNum = vRefNum; |
119 | fi.fileParam.ioDirID = dirID; |
120 | fi.fileParam.ioFDirIndex = 1; |
121 | |
122 | while (PBHGetFInfo(&fi, false) == noErr) { |
123 | /* scan system folder for driver resource files of specific type & creator */ |
124 | if (fi.fileParam.ioFlFndrInfo.fdType == targetType && |
125 | fi.fileParam.ioFlFndrInfo.fdCreator == targetCreator) { |
126 | /* found the MacTCP driver file? */ |
127 | refnum = HOpenResFile(vRefNum, dirID, filename, fsRdPerm); |
128 | if (Get1IndResource('dnrp', 1)) |
129 | return refnum; |
130 | CloseResFile(refnum); |
131 | } |
132 | |
133 | /* check next file in system folder */ |
134 | fi.fileParam.ioFDirIndex++; |
135 | fi.fileParam.ioDirID = dirID; /* PBHGetFInfo() clobbers ioDirID */ |
136 | } |
137 | return -1; |
138 | } |
139 | |
140 | /* OpenOurRF is called to open the MacTCP driver resources */ |
141 | short |
142 | OpenOurRF(void) |
143 | { |
144 | short refnum; |
145 | short vRefNum; |
146 | long dirID; |
147 | |
148 | /* first search Control Panels for MacTCP 1.1 */ |
149 | GetCPanelFolder(&vRefNum, &dirID); |
150 | refnum = SearchFolderForDNRP('cdev', 'ztcp', vRefNum, dirID); |
151 | if (refnum != -1) |
152 | return (refnum); |
153 | |
154 | /* next search System Folder for MacTCP 1.0.x */ |
155 | GetSystemFolder(&vRefNum, &dirID); |
156 | refnum = SearchFolderForDNRP('cdev', 'mtcp', vRefNum, dirID); |
157 | if (refnum != -1) |
158 | return (refnum); |
159 | |
160 | /* finally, search Control Panels for MacTCP 1.0.x */ |
161 | GetCPanelFolder(&vRefNum, &dirID); |
162 | refnum = SearchFolderForDNRP('cdev', 'mtcp', vRefNum, dirID); |
163 | if (refnum != -1) |
164 | return (refnum); |
165 | |
166 | return -1; |
167 | } |
168 | |
169 | OSErr |
170 | OpenResolver(char *fileName) |
171 | { |
172 | short refnum; |
173 | OSErr rc; |
174 | |
175 | if (dnr != nil) |
176 | /* resolver already loaded in */ |
177 | return (noErr); |
178 | |
179 | /* |
180 | * Open the MacTCP driver to get DNR resources. Search for it based on |
181 | * creator & type rather than simply file name. |
182 | */ |
183 | refnum = OpenOurRF(); |
184 | |
185 | /* |
186 | * Ignore failures since the resource may have been installed in the |
187 | * System file if running on a Mac 512Ke. |
188 | */ |
189 | |
190 | /* load in the DNR resource package */ |
191 | ResrvMem(16000L); /* s-dorner@uiuc.edu, 9/5/91 */ |
192 | dnr = Get1IndResource('dnrp', 1); |
193 | if (dnr == nil) { |
194 | /* can't open DNR */ |
195 | return (ResError()); |
196 | } |
197 | |
198 | DetachResource(dnr); |
199 | if (refnum != -1) { |
200 | CloseWD(refnum); |
201 | CloseResFile(refnum); |
202 | } |
203 | |
204 | /* lock the DNR resource since it cannot be relocated while opened */ |
205 | MoveHHi(dnr); |
206 | HLock(dnr); |
207 | |
208 | /* call open resolver */ |
209 | rc = ((OpenResolverProcPtr)*dnr)(OPENRESOLVER, fileName); |
210 | if (rc != noErr) { |
211 | /* problem with open resolver, flush it */ |
212 | HUnlock(dnr); |
213 | DisposHandle(dnr); |
214 | dnr = nil; |
215 | } |
216 | |
217 | return (rc); |
218 | } |
219 | |
220 | OSErr |
221 | CloseResolver(void) |
222 | { |
223 | if (dnr == nil) |
224 | /* resolver not loaded error */ |
225 | return (notOpenErr); |
226 | |
227 | /* call close resolver */ |
228 | (void)((CloseResolverProcPtr)*dnr)(CLOSERESOLVER); |
229 | |
230 | /* release the DNR resource package */ |
231 | HUnlock(dnr); |
232 | DisposHandle(dnr); |
233 | dnr = nil; |
234 | |
235 | return (noErr); |
236 | } |
237 | |
238 | OSErr |
239 | StrToAddr(char *hostName, struct hostInfo *rtnStruct, |
240 | ResultProcPtr resultproc, char *userDataPtr) |
241 | { |
242 | OSErr err; |
243 | |
244 | if (dnr == nil) |
245 | /* resolver not loaded error */ |
246 | return (notOpenErr); |
247 | |
248 | err = ((StrToAddrProcPtr)*dnr)(STRTOADDR, hostName, rtnStruct, |
249 | resultproc, userDataPtr); |
250 | return err; |
251 | } |
252 | |
253 | OSErr |
254 | AddrToStr(unsigned long addr, char *addrStr) |
255 | { |
256 | if (dnr == nil) |
257 | /* resolver not loaded error */ |
258 | return (notOpenErr); |
259 | |
260 | (void)((AddrToStrProcPtr)*dnr)(ADDRTOSTR, addr, addrStr); |
261 | return (noErr); |
262 | } |
263 | |
264 | OSErr |
265 | EnumCache(EnumResultProcPtr enumResultProc, char *userDataPtr) |
266 | { |
267 | if (dnr == nil) |
268 | /* resolver not loaded error */ |
269 | return (notOpenErr); |
270 | |
271 | return ((EnumCacheProcPtr)*dnr)(ENUMCACHE, enumResultProc, |
272 | userDataPtr); |
273 | } |
274 | |
275 | OSErr |
276 | AddrToName(ip_addr addr, struct hostInfo *hostInfoPtr, |
277 | ResultProcPtr resultProc, char *userDataPtr) |
278 | { |
279 | if (dnr == nil) |
280 | /* resolver not loaded error */ |
281 | return (notOpenErr); |
282 | |
283 | return ((AddrToNameProcPtr)*dnr)(ADDRTONAME, addr, hostInfoPtr, |
284 | resultProc, userDataPtr); |
285 | } |
286 | |
287 | #if 0 |
288 | OSErr |
289 | HInfo(char *hostName, struct returnRec *returnRecPtr, long resultProc, |
290 | char *userDataPtr) |
291 | { |
292 | if (dnr == nil) |
293 | /* resolver not loaded error */ |
294 | return (notOpenErr); |
295 | |
296 | return ((*dnr)(HINFO, hostName, returnRecPtr, resultProc, userDataPtr)); |
297 | } |
298 | |
299 | OSErr |
300 | MXInfo(char *hostName, struct returnRec *returnRecPtr, long resultProc, |
301 | char *userDataPtr) |
302 | { |
303 | if (dnr == nil) |
304 | /* resolver not loaded error */ |
305 | return (notOpenErr); |
306 | |
307 | return ((*dnr)(MXINFO, hostName, returnRecPtr, resultProc, userDataPtr)); |
308 | } |
309 | #endif |
310 | |
311 | OSErr |
312 | DNSResolveName(char *name, unsigned long *ipAddress, void (*yielder)(void)) |
313 | { |
314 | OSErr osErr; |
315 | struct hostInfo aHostInfo; |
316 | volatile int done = 0; |
317 | |
318 | osErr = OpenResolver(nil); |
319 | if (osErr) |
320 | return osErr; |
321 | |
322 | osErr = StrToAddr(name, &aHostInfo, (ResultProcPtr)StrToAddrMarkDone, |
323 | (char *)&done); |
324 | |
325 | if (osErr == cacheFault) { |
326 | /* StrToAddrMarkDone will set done when DNS resolution finishes */ |
327 | while (!done) { |
328 | if (yielder) |
329 | yielder(); |
330 | else |
331 | SystemTask(); |
332 | } |
333 | } |
334 | |
335 | if ((aHostInfo.rtnCode == noErr) || (aHostInfo.rtnCode == cacheFault)) { |
336 | /* use the first IP address for this host */ |
337 | *ipAddress = aHostInfo.addr[0]; |
338 | osErr = noErr; |
339 | } else |
340 | osErr = aHostInfo.rtnCode; |
341 | |
342 | /* leave resolver open for faster lookups in the future */ |
343 | |
344 | return osErr; |
345 | } |