Added ref to Misc/NEWS file; added hint to run regen script on Linux.
[python/dscho.git] / Mac / Unsupported / mactcp / macdnrmodule.c
blobfe89e035edb8491d98e147d09a25618a5d797509
1 /***********************************************************
2 Copyright 1991-1995 by Stichting Mathematisch Centrum, Amsterdam,
3 The Netherlands.
5 All Rights Reserved
7 Permission to use, copy, modify, and distribute this software and its
8 documentation for any purpose and without fee is hereby granted,
9 provided that the above copyright notice appear in all copies and that
10 both that copyright notice and this permission notice appear in
11 supporting documentation, and that the names of Stichting Mathematisch
12 Centrum or CWI not be used in advertising or publicity pertaining to
13 distribution of the software without specific, written prior permission.
15 STICHTING MATHEMATISCH CENTRUM DISCLAIMS ALL WARRANTIES WITH REGARD TO
16 THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND
17 FITNESS, IN NO EVENT SHALL STICHTING MATHEMATISCH CENTRUM BE LIABLE
18 FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
19 WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
20 ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT
21 OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
23 ******************************************************************/
25 #include "allobjects.h"
26 #include "modsupport.h" /* For getargs() etc. */
28 #include "macglue.h"
29 #include <AddressXlation.h>
30 #include <Desk.h>
32 #ifndef HAVE_UNIVERSAL_HEADERS
33 #define ResultUPP ResultProcPtr
34 #define NewResultProc(x) (x)
35 #define ResultProc2UPP ResultProc2Ptr
36 #define NewResultProc2Proc(x) (x)
37 #endif
39 static object *ErrorObject;
41 /* ----------------------------------------------------- */
42 /* Declarations for objects of type MacTCP DNR Result */
44 /* Types of records we have */
45 #define DNR_ADDR 0
46 #define DNR_HINFO 1
47 #define DNR_MX 2
49 typedef struct {
50 OB_HEAD
51 int type; /* DNR_XXX */
52 int waiting; /* True while completion proc not called */
53 struct returnRec hinfo;
54 } dnrrobject;
56 staticforward typeobject Dnrrtype;
58 #define is_dnrrobject(v) ((v)->ob_type == &Dnrrtype)
60 /* ---------------------------------------------------------------- */
62 static pascal void
63 dnrr_done(rrp, udp)
64 struct hostInfo *rrp; /* Unused */
65 dnrrobject *udp;
67 if ( !udp->waiting ) {
68 printf("macdnr: dnrr_done: spurious completion call!\n");
69 return;
71 udp->waiting = 0;
72 DECREF(udp);
75 static int dnrwait(self)
76 dnrrobject *self;
78 while ( self->waiting ) {
79 if ( PyMac_Idle() )
80 return 0;
82 return 1;
85 static object *
86 dnrr_wait(self, args)
87 dnrrobject *self;
88 object *args;
90 if (!newgetargs(args, ""))
91 return NULL;
92 if ( !dnrwait(self) ) {
93 /* XXX An interrupt is pending -- is this correct? */
94 INCREF(None);
95 return None;
97 if ( self->hinfo.rtnCode ) {
98 PyErr_Mac(ErrorObject, self->hinfo.rtnCode);
99 return NULL;
101 INCREF(None);
102 return None;
105 static object *
106 dnrr_isdone(self, args)
107 dnrrobject *self;
108 object *args;
110 if (!newgetargs(args, ""))
111 return NULL;
112 return newintobject(!self->waiting);
115 static struct methodlist dnrr_methods[] = {
116 {"wait", (method)dnrr_wait, 1},
117 {"isdone", (method)dnrr_isdone, 1},
119 {NULL, NULL} /* sentinel */
122 /* ---------- */
124 static dnrrobject *
125 newdnrrobject(tp)
126 int tp;
128 dnrrobject *self;
130 self = NEWOBJ(dnrrobject, &Dnrrtype);
131 if (self == NULL)
132 return NULL;
133 self->type = tp;
134 self->waiting = 0;
135 memset(&self->hinfo, 0, sizeof(self->hinfo));
136 return self;
139 static void
140 dnrr_dealloc(self)
141 dnrrobject *self;
143 self->waiting = 0; /* Not really needed, since we incref for completion */
144 DEL(self);
147 /* Code to access structure members by accessing attributes */
149 #include "structmember.h"
151 #define OFF(x) offsetof(struct returnRec, x)
153 static struct memberlist dnrr_memberlist_addr[] = {
154 { "rtnCode", T_INT, OFF(rtnCode), RO},
155 { "cname", T_STRING_INPLACE, OFF(cname), RO},
156 { "ip0", T_UINT, OFF(rdata.addr[0]), RO},
157 { "ip1", T_UINT, OFF(rdata.addr[1]), RO},
158 { "ip2", T_UINT, OFF(rdata.addr[2]), RO},
159 { "ip3", T_UINT, OFF(rdata.addr[3]), RO},
160 {NULL} /* Sentinel */
163 static struct memberlist dnrr_memberlist_hinfo[] = {
164 { "rtnCode", T_INT, OFF(rtnCode), RO},
165 { "cname", T_STRING_INPLACE, OFF(cname), RO},
166 { "cpuType", T_STRING_INPLACE, OFF(rdata.hinfo.cpuType), RO},
167 { "osType", T_STRING_INPLACE, OFF(rdata.hinfo.osType), RO},
168 {NULL} /* Sentinel */
171 static struct memberlist dnrr_memberlist_mx[] = {
172 { "rtnCode", T_INT, OFF(rtnCode), RO},
173 { "cname", T_STRING_INPLACE, OFF(cname), RO},
174 { "preference", T_USHORT, OFF(rdata.mx.preference), RO},
175 { "exchange", T_STRING_INPLACE, OFF(rdata.mx.exchange), RO},
176 {NULL} /* Sentinel */
179 static struct memberlist *dnrr_mlists[3] = {
180 dnrr_memberlist_addr,
181 dnrr_memberlist_hinfo,
182 dnrr_memberlist_mx
185 static object *
186 dnrr_getattr(self, name)
187 dnrrobject *self;
188 char *name;
190 object *rv;
191 int tp;
193 rv = findmethod(dnrr_methods, (object *)self, name);
194 if ( rv ) return rv;
195 err_clear();
196 if ( self->waiting )
197 if ( !dnrwait(self) ) {
198 /* XXX An interrupt is pending -- is this correct? */
199 err_setstr(ErrorObject, "Resolver busy");
200 return NULL;
202 tp = self->type;
203 return getmember((char *)&self->hinfo, dnrr_mlists[tp], name);
207 static typeobject Dnrrtype = {
208 OB_HEAD_INIT(&Typetype)
209 0, /*ob_size*/
210 "MacTCP DNR Result", /*tp_name*/
211 sizeof(dnrrobject), /*tp_basicsize*/
212 0, /*tp_itemsize*/
213 /* methods */
214 (destructor)dnrr_dealloc, /*tp_dealloc*/
215 (printfunc)0, /*tp_print*/
216 (getattrfunc)dnrr_getattr, /*tp_getattr*/
217 (setattrfunc)0, /*tp_setattr*/
218 (cmpfunc)0, /*tp_compare*/
219 (reprfunc)0, /*tp_repr*/
220 0, /*tp_as_number*/
221 0, /*tp_as_sequence*/
222 0, /*tp_as_mapping*/
223 (hashfunc)0, /*tp_hash*/
226 /* End of code for MacTCP DNR Result objects */
227 /* -------------------------------------------------------- */
229 int dnr_is_open;
231 static int
232 opendnr(fn)
233 char *fn;
235 OSErr err;
237 if ( dnr_is_open ) return 1;
238 if ( (err=OpenResolver(fn)) ) {
239 PyErr_Mac(ErrorObject, err);
240 return 0;
242 dnr_is_open = 1;
243 return 1;
246 static object *
247 dnr_Open(self, args)
248 object *self; /* Not used */
249 object *args;
251 char *fn = NULL;
253 if (!newgetargs(args, "|s", &fn))
254 return NULL;
255 if ( dnr_is_open ) {
256 err_setstr(ErrorObject, "DNR already open");
257 return NULL;
259 if ( !opendnr(fn) )
260 return NULL;
261 INCREF(None);
262 return None;
265 static object *
266 dnr_Close(self, args)
267 object *self; /* Not used */
268 object *args;
270 OSErr err;
272 if (!newgetargs(args, ""))
273 return NULL;
274 dnr_is_open = 0;
275 if ( (err=CloseResolver()) ) {
276 PyErr_Mac(ErrorObject, err);
277 return NULL;
279 INCREF(None);
280 return None;
283 static object *
284 dnr_StrToAddr(self, args)
285 object *self; /* Not used */
286 object *args;
288 OSErr err;
289 char *hostname;
290 dnrrobject *rv;
291 ResultUPP cb_upp = NewResultProc(dnrr_done);
293 if (!newgetargs(args, "s", &hostname))
294 return NULL;
295 if ( !opendnr(NULL) )
296 return NULL;
297 if ( (rv=newdnrrobject(DNR_ADDR)) == NULL )
298 return NULL;
299 err = StrToAddr(hostname, (struct hostInfo *)&rv->hinfo, cb_upp, (char *)rv);
300 if ( err == cacheFault ) {
301 rv->waiting++;
302 INCREF(rv);
303 } else if ( err ) {
304 DECREF(rv);
305 PyErr_Mac(ErrorObject, err);
306 return NULL;
308 return (object *)rv;
311 static object *
312 dnr_AddrToName(self, args)
313 object *self; /* Not used */
314 object *args;
316 OSErr err;
317 unsigned long ipaddr;
318 dnrrobject *rv;
319 ResultUPP cb_upp = NewResultProc(dnrr_done);
321 if (!newgetargs(args, "l", &ipaddr))
322 return NULL;
323 if ( !opendnr(NULL) )
324 return NULL;
325 if ( (rv=newdnrrobject(DNR_ADDR)) == NULL )
326 return NULL;
327 err = AddrToName(ipaddr, (struct hostInfo *)&rv->hinfo, cb_upp, (char *)rv);
328 if ( err == cacheFault ) {
329 rv->waiting++;
330 INCREF(rv);
331 } else if ( err ) {
332 DECREF(rv);
333 PyErr_Mac(ErrorObject, err);
334 return NULL;
336 return (object *)rv;
339 static object *
340 dnr_AddrToStr(self, args)
341 object *self; /* Not used */
342 object *args;
344 OSErr err;
345 unsigned long ipaddr;
346 char ipname[16];
348 if (!newgetargs(args, "l", &ipaddr))
349 return NULL;
350 if ( !opendnr(NULL) )
351 return NULL;
352 if ( (err=AddrToStr(ipaddr, ipname)) ) {
353 PyErr_Mac(ErrorObject, err);
354 return NULL;
356 return newstringobject(ipname);
359 static object *
360 dnr_HInfo(self, args)
361 object *self; /* Not used */
362 object *args;
364 OSErr err;
365 char *hostname;
366 dnrrobject *rv;
367 ResultProc2UPP cb_upp = NewResultProc2Proc(dnrr_done);
369 if (!newgetargs(args, "s", &hostname))
370 return NULL;
371 if ( !opendnr(NULL) )
372 return NULL;
373 if ( (rv=newdnrrobject(DNR_HINFO)) == NULL )
374 return NULL;
375 err = HInfo(hostname, &rv->hinfo, cb_upp, (char *)rv);
376 if ( err == cacheFault ) {
377 rv->waiting++;
378 INCREF(rv);
379 } else if ( err ) {
380 DECREF(rv);
381 PyErr_Mac(ErrorObject, err);
382 return NULL;
384 return (object *)rv;
386 if (!newgetargs(args, ""))
387 return NULL;
388 INCREF(None);
389 return None;
392 static object *
393 dnr_MXInfo(self, args)
394 object *self; /* Not used */
395 object *args;
397 OSErr err;
398 char *hostname;
399 dnrrobject *rv;
400 ResultProc2UPP cb_upp = NewResultProc2Proc(dnrr_done);
402 if (!newgetargs(args, "s", &hostname))
403 return NULL;
404 if ( !opendnr(NULL) )
405 return NULL;
406 if ( (rv=newdnrrobject(DNR_MX)) == NULL )
407 return NULL;
408 err = MXInfo(hostname, &rv->hinfo, cb_upp, (char *)rv);
409 if ( err == cacheFault ) {
410 rv->waiting++;
411 INCREF(rv);
412 } else if ( err ) {
413 DECREF(rv);
414 PyErr_Mac(ErrorObject, err);
415 return NULL;
417 return (object *)rv;
420 /* List of methods defined in the module */
422 static struct methodlist dnr_methods[] = {
423 {"Open", dnr_Open, 1},
424 {"Close", dnr_Close, 1},
425 {"StrToAddr", dnr_StrToAddr, 1},
426 {"AddrToStr", dnr_AddrToStr, 1},
427 {"AddrToName", dnr_AddrToName, 1},
428 {"HInfo", dnr_HInfo, 1},
429 {"MXInfo", dnr_MXInfo, 1},
431 {NULL, NULL} /* sentinel */
435 /* Initialization function for the module (*must* be called initmacdnr) */
437 void
438 initmacdnr()
440 object *m, *d;
442 /* Create the module and add the functions */
443 m = initmodule("macdnr", dnr_methods);
445 /* Add some symbolic constants to the module */
446 d = getmoduledict(m);
447 ErrorObject = newstringobject("macdnr.error");
448 dictinsert(d, "error", ErrorObject);
449 #if 0
450 /* Not needed, after all */
451 #define CONST(name, value) o = newintobject(value); dictinsert(d, name, o);
452 CONST("ADDR", DNR_ADDR);
453 CONST("HINFO", DNR_HINFO);
454 CONST("MX", DNR_MX);
455 #endif
456 /* Check for errors */
457 if (err_occurred())
458 fatal("can't initialize module macdnr");