Download
jcs
/wallops
/dnr.c
(View History)
jcs dnr: Consider a result of 0.0.0.0 a bad one | Latest amendment: 114 on 2024-09-17 |
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 <Folders.h> |
10 | #include "dnr.h" |
11 | #include "tcp.h" |
12 | #include "util.h" |
13 | |
14 | #define OPENRESOLVER 1 |
15 | #define CLOSERESOLVER 2 |
16 | #define STRTOADDR 3 |
17 | #define ADDRTOSTR 4 |
18 | #define ENUMCACHE 5 |
19 | #define ADDRTONAME 6 |
20 | #define HINFO 7 |
21 | #define MXINFO 8 |
22 | |
23 | short SearchFolderForDNRP(long targetType, long targetCreator, |
24 | short vRefNum, long dirID); |
25 | short OpenOurRF(void); |
26 | |
27 | Handle dnr = nil; |
28 | |
29 | /* |
30 | * SearchFolderForDNRP is called to search a folder for files that might |
31 | * contain the 'dnrp' resource |
32 | */ |
33 | short |
34 | SearchFolderForDNRP(long targetType, long targetCreator, short vRefNum, |
35 | long dirID) |
36 | { |
37 | HParamBlockRec fi; |
38 | Str255 filename; |
39 | short refnum; |
40 | |
41 | fi.fileParam.ioCompletion = nil; |
42 | fi.fileParam.ioNamePtr = (StringPtr)&filename; |
43 | fi.fileParam.ioVRefNum = vRefNum; |
44 | fi.fileParam.ioDirID = dirID; |
45 | fi.fileParam.ioFDirIndex = 1; |
46 | |
47 | while (PBHGetFInfo(&fi, false) == noErr) { |
48 | /* scan system folder for driver resource files of specific type & creator */ |
49 | if (fi.fileParam.ioFlFndrInfo.fdType == targetType && |
50 | fi.fileParam.ioFlFndrInfo.fdCreator == targetCreator) { |
51 | /* found the MacTCP driver file? */ |
52 | refnum = HOpenResFile(vRefNum, dirID, filename, fsRdPerm); |
53 | if (Get1IndResource('dnrp', 1)) |
54 | return refnum; |
55 | CloseResFile(refnum); |
56 | } |
57 | |
58 | /* check next file in system folder */ |
59 | fi.fileParam.ioFDirIndex++; |
60 | fi.fileParam.ioDirID = dirID; /* PBHGetFInfo() clobbers ioDirID */ |
61 | } |
62 | return -1; |
63 | } |
64 | |
65 | /* OpenOurRF is called to open the MacTCP driver resources */ |
66 | short |
67 | OpenOurRF(void) |
68 | { |
69 | short refnum; |
70 | short vRefNum; |
71 | long dirID; |
72 | |
73 | /* first search Control Panels for MacTCP 1.1 */ |
74 | GetSystemSubfolder(kControlPanelFolderType, false, &vRefNum, &dirID); |
75 | refnum = SearchFolderForDNRP('cdev', 'ztcp', vRefNum, dirID); |
76 | if (refnum != -1) |
77 | return (refnum); |
78 | |
79 | /* next search System Folder for MacTCP 1.0.x */ |
80 | GetSystemFolder(&vRefNum, &dirID); |
81 | refnum = SearchFolderForDNRP('cdev', 'mtcp', vRefNum, dirID); |
82 | if (refnum != -1) |
83 | return (refnum); |
84 | |
85 | /* finally, search Control Panels for MacTCP 1.0.x */ |
86 | GetSystemSubfolder(kControlPanelFolderType, false, &vRefNum, &dirID); |
87 | refnum = SearchFolderForDNRP('cdev', 'mtcp', vRefNum, dirID); |
88 | if (refnum != -1) |
89 | return (refnum); |
90 | |
91 | return -1; |
92 | } |
93 | |
94 | OSErr |
95 | OpenResolver(char *fileName) |
96 | { |
97 | short refnum; |
98 | OSErr rc; |
99 | |
100 | if (dnr != nil) |
101 | /* resolver already loaded in */ |
102 | return (noErr); |
103 | |
104 | /* |
105 | * Open the MacTCP driver to get DNR resources. Search for it based on |
106 | * creator & type rather than simply file name. |
107 | */ |
108 | refnum = OpenOurRF(); |
109 | |
110 | /* |
111 | * Ignore failures since the resource may have been installed in the |
112 | * System file if running on a Mac 512Ke. |
113 | */ |
114 | |
115 | /* load in the DNR resource package */ |
116 | ResrvMem(16000L); /* s-dorner@uiuc.edu, 9/5/91 */ |
117 | dnr = Get1IndResource('dnrp', 1); |
118 | if (dnr == nil) { |
119 | /* can't open DNR */ |
120 | return (ResError()); |
121 | } |
122 | |
123 | DetachResource(dnr); |
124 | if (refnum != -1) { |
125 | CloseWD(refnum); |
126 | CloseResFile(refnum); |
127 | } |
128 | |
129 | /* lock the DNR resource since it cannot be relocated while opened */ |
130 | MoveHHi(dnr); |
131 | HLock(dnr); |
132 | |
133 | /* call open resolver */ |
134 | rc = ((OpenResolverProcPtr)*dnr)(OPENRESOLVER, fileName); |
135 | if (rc != noErr) { |
136 | /* problem with open resolver, flush it */ |
137 | HUnlock(dnr); |
138 | DisposHandle(dnr); |
139 | dnr = nil; |
140 | } |
141 | |
142 | return (rc); |
143 | } |
144 | |
145 | OSErr |
146 | CloseResolver(void) |
147 | { |
148 | if (dnr == nil) |
149 | /* resolver not loaded error */ |
150 | return (notOpenErr); |
151 | |
152 | /* call close resolver */ |
153 | (void)((CloseResolverProcPtr)*dnr)(CLOSERESOLVER); |
154 | |
155 | /* release the DNR resource package */ |
156 | HUnlock(dnr); |
157 | DisposHandle(dnr); |
158 | dnr = nil; |
159 | |
160 | return (noErr); |
161 | } |
162 | |
163 | OSErr |
164 | StrToAddr(char *hostName, struct hostInfo *rtnStruct, |
165 | ResultProcPtr resultproc, char *userDataPtr) |
166 | { |
167 | OSErr err; |
168 | |
169 | if (dnr == nil) |
170 | /* resolver not loaded error */ |
171 | return (notOpenErr); |
172 | |
173 | err = ((StrToAddrProcPtr)*dnr)(STRTOADDR, hostName, rtnStruct, |
174 | resultproc, userDataPtr); |
175 | return err; |
176 | } |
177 | |
178 | OSErr |
179 | AddrToStr(unsigned long addr, char *addrStr) |
180 | { |
181 | if (dnr == nil) |
182 | /* resolver not loaded error */ |
183 | return (notOpenErr); |
184 | |
185 | (void)((AddrToStrProcPtr)*dnr)(ADDRTOSTR, addr, addrStr); |
186 | return (noErr); |
187 | } |
188 | |
189 | OSErr |
190 | EnumCache(EnumResultProcPtr enumResultProc, char *userDataPtr) |
191 | { |
192 | if (dnr == nil) |
193 | /* resolver not loaded error */ |
194 | return (notOpenErr); |
195 | |
196 | return ((EnumCacheProcPtr)*dnr)(ENUMCACHE, enumResultProc, |
197 | userDataPtr); |
198 | } |
199 | |
200 | OSErr |
201 | AddrToName(ip_addr addr, struct hostInfo *hostInfoPtr, |
202 | ResultProcPtr resultProc, char *userDataPtr) |
203 | { |
204 | if (dnr == nil) |
205 | /* resolver not loaded error */ |
206 | return (notOpenErr); |
207 | |
208 | return ((AddrToNameProcPtr)*dnr)(ADDRTONAME, addr, hostInfoPtr, |
209 | resultProc, userDataPtr); |
210 | } |
211 | |
212 | #if 0 |
213 | OSErr |
214 | HInfo(char *hostName, struct returnRec *returnRecPtr, long resultProc, |
215 | char *userDataPtr) |
216 | { |
217 | if (dnr == nil) |
218 | /* resolver not loaded error */ |
219 | return (notOpenErr); |
220 | |
221 | return ((*dnr)(HINFO, hostName, returnRecPtr, resultProc, userDataPtr)); |
222 | } |
223 | |
224 | OSErr |
225 | MXInfo(char *hostName, struct returnRec *returnRecPtr, long resultProc, |
226 | char *userDataPtr) |
227 | { |
228 | if (dnr == nil) |
229 | /* resolver not loaded error */ |
230 | return (notOpenErr); |
231 | |
232 | return ((*dnr)(MXINFO, hostName, returnRecPtr, resultProc, userDataPtr)); |
233 | } |
234 | #endif |
235 | |
236 | OSErr |
237 | DNSResolveName(char *name, unsigned long *ipAddress, void (*yielder)(void)) |
238 | { |
239 | OSErr osErr; |
240 | struct hostInfo aHostInfo; |
241 | volatile int done = 0; |
242 | |
243 | osErr = OpenResolver(nil); |
244 | if (osErr) |
245 | return osErr; |
246 | |
247 | osErr = StrToAddr(name, &aHostInfo, (ResultProcPtr)StrToAddrMarkDone, |
248 | (char *)&done); |
249 | |
250 | if (osErr == cacheFault) { |
251 | /* StrToAddrMarkDone will set done when DNS resolution finishes */ |
252 | while (!done) { |
253 | if (yielder) |
254 | yielder(); |
255 | else |
256 | SystemTask(); |
257 | } |
258 | } |
259 | |
260 | if (aHostInfo.rtnCode == cacheFault && aHostInfo.addr[0] == 0) |
261 | /* consider 0.0.0.0 a bad answer */ |
262 | aHostInfo.rtnCode = authNameErr; |
263 | |
264 | if ((aHostInfo.rtnCode == noErr) || (aHostInfo.rtnCode == cacheFault)) { |
265 | /* use the first IP address for this host */ |
266 | *ipAddress = aHostInfo.addr[0]; |
267 | osErr = noErr; |
268 | } else |
269 | osErr = aHostInfo.rtnCode; |
270 | |
271 | /* leave resolver open for faster lookups in the future */ |
272 | |
273 | return osErr; |
274 | } |