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