/* This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2, or (at your option) any later version. */ #include "Python.h" #include "pymemcompat.h" #include #include #include #include #include #include static PyObject *ErrorObject; static PyObject *NotReadyError; static PyObject *LocalError; static PyObject *RemoteError, *RemoteFailureError, *RemoteTempError, *RemoteConfigError; static PyObject *QueryError; static PyObject *PermanentError, *NXDomainError, *NoDataError; /* ----------------------------------------------------- */ /* Declarations for objects of type ADNS_State */ typedef struct { PyObject_HEAD adns_state state; } ADNS_Stateobject; staticforward PyTypeObject ADNS_Statetype; /* ---------------------------------------------------------------- */ /* Declarations for objects of type ADNS_Query */ typedef struct { PyObject_HEAD ADNS_Stateobject *s; adns_query query; PyObject *answer; PyObject *exc_type; PyObject *exc_value; PyObject *exc_traceback; } ADNS_Queryobject; staticforward PyTypeObject ADNS_Querytype; /* ---------------------------------------------------------------- */ typedef struct { char *name; int value; } _constant_class; static _constant_class adns_iflags[] = { { "noenv", adns_if_noenv }, { "noerrprint", adns_if_noerrprint }, { "noserverwarn", adns_if_noserverwarn }, { "debug", adns_if_debug }, { "logpid", adns_if_logpid }, { "noautosys", adns_if_noautosys }, { "eintr", adns_if_eintr }, { "nosigpipe", adns_if_nosigpipe }, { "checkc_entex", adns_if_checkc_entex }, { "checkc_freq", adns_if_checkc_freq }, { NULL, 0 }, }; static _constant_class adns_qflags[] = { { "search", adns_qf_search }, { "usevc", adns_qf_usevc }, { "owner", adns_qf_owner }, { "quoteok_query", adns_qf_quoteok_query }, { "quoteok_cname", adns_qf_quoteok_cname }, { "quoteok_anshost", adns_qf_quoteok_anshost }, { "quotefail_cname", adns_qf_quotefail_cname }, { "cname_loose", adns_qf_cname_loose }, { "cname_forbid", adns_qf_cname_forbid }, { "internalmask", adns__qf_internalmask }, { NULL, 0 }, }; static _constant_class adns_rr[] = { { "typemask", adns_rrt_typemask }, { "deref", adns__qtf_deref }, { "mail822", adns__qtf_mail822 }, { "unknown", adns_r_unknown }, { "none", adns_r_none }, { "A", adns_r_a }, { "NSraw", adns_r_ns_raw }, { "NS", adns_r_ns }, { "CNAME", adns_r_cname }, { "SOAraw", adns_r_soa_raw }, { "SOA", adns_r_soa }, { "PTRraw", adns_r_ptr_raw }, { "PTR", adns_r_ptr }, { "HINFO", adns_r_hinfo }, { "MXraw", adns_r_mx_raw }, { "MX", adns_r_mx }, { "TXT", adns_r_txt }, { "RPraw", adns_r_rp_raw }, { "RP", adns_r_rp }, { "SRVraw", adns_r_srv_raw }, { "SRV", adns_r_srv }, { "ADDR", adns_r_addr }, { NULL, 0 } }; static _constant_class adns_s[] = { { "ok", adns_s_ok }, { "nomemory", adns_s_nomemory }, { "unknownrrtype", adns_s_unknownrrtype }, { "systemfail", adns_s_systemfail }, { "max_localfail", adns_s_max_localfail }, { "timeout", adns_s_timeout }, { "allservfail", adns_s_allservfail }, { "norecurse", adns_s_norecurse }, { "invalidresponse", adns_s_invalidresponse }, { "unknownformat", adns_s_unknownformat }, { "max_remotefail", adns_s_max_remotefail }, { "rcodeservfail", adns_s_rcodeservfail }, { "rcodeformaterror", adns_s_rcodeformaterror }, { "rcodenotimplemented", adns_s_rcodenotimplemented }, { "rcoderefused", adns_s_rcoderefused }, { "rcodeunknown", adns_s_rcodeunknown }, { "max_tempfail", adns_s_max_tempfail }, { "inconsistent", adns_s_inconsistent }, { "prohibitedcname", adns_s_prohibitedcname }, { "answerdomaininvalid", adns_s_answerdomaininvalid }, { "answerdomaintoolong", adns_s_answerdomaintoolong }, { "invaliddata", adns_s_invaliddata }, { "max_misconfig", adns_s_max_misconfig }, { "querydomainwrong", adns_s_querydomainwrong }, { "querydomaininvalid", adns_s_querydomaininvalid }, { "querydomaintoolong", adns_s_querydomaintoolong }, { "max_misquery", adns_s_max_misquery }, { "nxdomain", adns_s_nxdomain }, { "nodata", adns_s_nodata }, { "max_permfail", adns_s_max_permfail }, { NULL, 0 } }; static PyObject * interpret_addr( adns_rr_addr *v ) { PyObject *o; o = Py_BuildValue("is", v->addr.inet.sin_family, inet_ntoa(v->addr.inet.sin_addr)) ; return o; } static PyObject * interpret_hostaddr( adns_rr_hostaddr *hostaddr ) { PyObject *o, *addrs; if (hostaddr->naddrs == -1) { addrs = Py_None; Py_INCREF(addrs); } else { int i; addrs = PyTuple_New(hostaddr->naddrs); for (i=0; inaddrs; i++) { adns_rr_addr *v = hostaddr->addrs+i; PyTuple_SET_ITEM(addrs,i,interpret_addr(v)); } } o = Py_BuildValue("siO", hostaddr->host, hostaddr->astatus, addrs); Py_DECREF(addrs); return o; } static PyObject * interpret_answer( adns_answer *answer ) { PyObject *o, *rrs; int i; adns_rrtype t = answer->type & adns_rrt_typemask; adns_rrtype td = answer->type & adns__qtf_deref; rrs = PyTuple_New(answer->nrrs); if (!rrs) return NULL; for (i=0; inrrs; i++) { PyObject *a = NULL; switch (t) { case adns_r_a: if (td) { a = interpret_addr((answer->rrs.addr+i)); } else { struct in_addr *v = answer->rrs.inaddr+i; a = Py_BuildValue("s", inet_ntoa(*v)); } break; case adns_r_hinfo: { adns_rr_intstrpair *v = \ answer->rrs.intstrpair+i; a = Py_BuildValue("s#s#", v->array[0].str, v->array[0].i, v->array[1].str, v->array[1].i); } break; case adns_r_mx_raw: if (td) { adns_rr_inthostaddr *v = \ answer->rrs.inthostaddr+i; o = interpret_hostaddr(&v->ha); a = Py_BuildValue("iO", v->i, o); Py_DECREF(o); } else { adns_rr_intstr *v = answer->rrs.intstr+i; a = Py_BuildValue("is", v->i, v->str); } break; case adns_r_ptr_raw: case adns_r_cname: { char *(*v) = answer->rrs.str+i; a = PyString_FromString(*v); } break; case adns_r_txt: { PyObject *txt; int array_len = 0; int ai; adns_rr_intstr *(*s) = answer->rrs.manyistr+i; while ((*s)[array_len].i != -1) array_len++; if (!(a = PyTuple_New(array_len))) break; for (ai = 0; ai < array_len; ai++) { txt = PyString_FromStringAndSize((*s)[ai].str, (*s)[ai].i); if (!txt) { Py_DECREF(a); a = NULL; break; } PyTuple_SET_ITEM(a, ai, txt); } } break; case adns_r_ns_raw: if (td) { a = interpret_hostaddr(answer->rrs.hostaddr+i); } else { char *(*v) = answer->rrs.str+i; a = PyString_FromString(*v); } break; case adns_r_soa_raw: { adns_rr_soa *v = answer->rrs.soa+i; a = Py_BuildValue("sslllll", v->mname, v->rname, v->serial, v->refresh, v->retry, v->expire, v->minimum); } break; case adns_r_rp: { adns_rr_strpair *v = answer->rrs.strpair+i; a = Py_BuildValue("ss", v->array[0], v->array[1]); } break; case adns_r_srv_raw: if (td) { adns_rr_srvha *v = answer->rrs.srvha+i; o = interpret_hostaddr(&v->ha); a = Py_BuildValue("iiiO", v->priority, v->weight, v->port, o); Py_DECREF(o); } else { adns_rr_srvraw *v = answer->rrs.srvraw+i; a = Py_BuildValue("iiis", v->priority, v->weight, v->port, v->host); } break; default: a = Py_None; Py_INCREF(a); } if (!a) { Py_DECREF(rrs); return NULL; } PyTuple_SET_ITEM(rrs, i, a); } o = Py_BuildValue("isiO", (int) answer->status, answer->cname, answer->expires, rrs); Py_DECREF(rrs); return o ; } static char adns_exception__doc__[] = \ "exception(s)\n\ \n\ Checks the status code of an answer and raises an exception if necessary.\n"; static PyObject* adns_exception( PyObject *self, PyObject *args ) { PyObject *e, *m; adns_status status; if (!PyArg_ParseTuple(args, "i", &status)) return NULL; switch (status) { case adns_s_ok: Py_INCREF(Py_None); return Py_None; case adns_s_nomemory: return PyErr_NoMemory(); case adns_s_unknownrrtype: case adns_s_systemfail: e = LocalError; break; case adns_s_timeout: case adns_s_allservfail: case adns_s_norecurse: case adns_s_invalidresponse: case adns_s_unknownformat: e = RemoteFailureError; break; case adns_s_rcodeservfail: case adns_s_rcodeformaterror: case adns_s_rcodenotimplemented: case adns_s_rcoderefused: case adns_s_rcodeunknown: e = RemoteTempError; break; case adns_s_inconsistent: case adns_s_prohibitedcname: case adns_s_answerdomaininvalid: case adns_s_invaliddata: e = RemoteConfigError; case adns_s_querydomainwrong: case adns_s_querydomaininvalid: case adns_s_querydomaintoolong: e = QueryError; break; case adns_s_nxdomain: e = NXDomainError; break; case adns_s_nodata: e = NoDataError; break; default: e = ErrorObject; } if (!(m=Py_BuildValue("is", status, adns_strerror((adns_status) status)))) return NULL; PyErr_SetObject(e, m); Py_DECREF(m); return NULL; } /* ---------------------------------------------------------------- */ static char ADNS_State_synchronous__doc__[] = "s.synchronous(name,type[,flags]\n\ \n\ Perform a query on name synchronously for RR type, returning the answer.\n\ Answers returned as (status, cname, expires, rrs).\n\ rrs is an n-tuple, each element is a RR. Format varies by\n\ RR and query.\n" ; static PyObject * ADNS_State_synchronous( ADNS_Stateobject *self, PyObject *args ) { char *owner; adns_rrtype type = 0; adns_queryflags flags = 0; adns_answer *answer_r; int r; PyObject *o; if (!PyArg_ParseTuple(args, "si|i", &owner, &type, &flags)) return NULL; Py_BEGIN_ALLOW_THREADS; r = adns_synchronous(self->state, owner, type, flags, &answer_r); Py_END_ALLOW_THREADS; if (r) { PyErr_SetString(ErrorObject, strerror(r)); return NULL; } o = interpret_answer(answer_r); free(answer_r); return o; } static char ADNS_State_submit__doc__[] = "s.submit(name,type[,flags])\n\ \n\ Submit a query. Returns a ADNS_Query object.\n" ; static ADNS_Queryobject *newADNS_Queryobject(ADNS_Stateobject *state); static PyObject * ADNS_State_submit( ADNS_Stateobject *self, PyObject *args ) { char *owner; adns_rrtype type = 0; adns_queryflags flags = 0; int r; ADNS_Queryobject *o; if (!PyArg_ParseTuple(args, "si|i", &owner, &type, &flags)) return NULL; o = newADNS_Queryobject(self); Py_BEGIN_ALLOW_THREADS; r = adns_submit(self->state, owner, type, flags, o, &o->query); Py_END_ALLOW_THREADS; if (r) { PyErr_SetString(ErrorObject, strerror(r)); return NULL; } return (PyObject *) o; } static char ADNS_State_submit_reverse__doc__[] = "s.submit_reverse(name,type[,flags])\n\ \n\ Submit a query. Returns a ADNS_Query object.\n\ flags must specify some kind of PTR query." ; static PyObject * ADNS_State_submit_reverse( ADNS_Stateobject *self, PyObject *args ) { char *owner; struct sockaddr_in addr; adns_rrtype type = 0; adns_queryflags flags = 0; int r; ADNS_Queryobject *o; if (!PyArg_ParseTuple(args, "si|i", &owner, &type, &flags)) return NULL; r = inet_aton(owner, (struct in_addr *) &(addr.sin_addr)); if (!r) { PyErr_SetString(ErrorObject, "invalid IP address"); return NULL; } addr.sin_family = AF_INET; o = newADNS_Queryobject(self); Py_BEGIN_ALLOW_THREADS; r = adns_submit_reverse(self->state, (struct sockaddr *)&addr, type, flags, o, &o->query); Py_END_ALLOW_THREADS; if (r) { PyErr_SetString(ErrorObject, strerror(r)); return NULL; } return (PyObject *) o; } static char ADNS_State_submit_reverse_any__doc__[] = "s.submit_reverse_any(name,zone,type[,flags])\n\ \n\ Submit a query. Returns a ADNS_Query object.\n\ zone is in-addr.arpa., etc.\n\ flags must specify some kind of PTR query." ; static PyObject * ADNS_State_submit_reverse_any( ADNS_Stateobject *self, PyObject *args ) { char *owner, *zone; struct sockaddr_in addr; adns_rrtype type = 0; adns_queryflags flags = 0; int r; ADNS_Queryobject *o; if (!PyArg_ParseTuple(args, "ssi|i", &owner, &zone, &type, &flags)) return NULL; r = inet_aton(owner, &(addr.sin_addr)); if (!r) { PyErr_SetString(ErrorObject, "invalid IP address"); return NULL; } addr.sin_family = AF_INET; o = newADNS_Queryobject(self); Py_BEGIN_ALLOW_THREADS; r = adns_submit_reverse_any(self->state, (struct sockaddr *)&addr, zone, type, flags, o, &o->query); Py_END_ALLOW_THREADS; if (r) { PyErr_SetString(ErrorObject, strerror(r)); return NULL; } return (PyObject *) o; } static char ADNS_State_allqueries__doc__[] = "s.allqueries()\n\ \n\ Returns a list of all pending queries.\n" ; static PyObject * ADNS_State_allqueries( ADNS_Stateobject *self, PyObject *args ) { ADNS_Queryobject *o; adns_query q; PyObject *l; if (!PyArg_ParseTuple(args, "")) return NULL; if (!(l = PyList_New(0))) return NULL; for (adns_forallqueries_begin(self->state); (q = adns_forallqueries_next(self->state, (void *)&o)); ) { if (PyList_Append(l, (PyObject *) o)) { Py_DECREF(l); return NULL; } } return l; } static char ADNS_State_select__doc__[] = "s.select(timeout=0)\n\ \n\ Like the select() system call, except it works only on\n\ pending queries, i.e. internally it does:\n\ 1) adns_beforeselect\n\ 2) select\n\ 3) adns_afterselect\n" ; static PyObject * ADNS_State_select( ADNS_Stateobject *self, PyObject *args ) { fd_set rfds, wfds, efds; int r, maxfd=0; double ft = 0; struct timeval **tv_mod, tv_buf, now, timeout; struct timezone tz; if (!PyArg_ParseTuple(args, "|d", &ft)) return NULL; timeout.tv_sec = (int) ft; timeout.tv_usec = (int) ((ft - timeout.tv_sec) * 1e6); tv_mod = NULL; if (gettimeofday(&now, &tz)) return PyErr_SetFromErrno(ErrorObject); FD_ZERO(&rfds); FD_ZERO(&wfds); FD_ZERO(&efds); adns_beforeselect(self->state, &maxfd, &rfds, &wfds, &efds, tv_mod, &tv_buf, &now); Py_BEGIN_ALLOW_THREADS; r = select(maxfd, &rfds, &wfds, &efds, &timeout); Py_END_ALLOW_THREADS; if (r == -1) return PyErr_SetFromErrno(ErrorObject); if (gettimeofday(&now, &tz)) return PyErr_SetFromErrno(ErrorObject); adns_afterselect(self->state, maxfd, &rfds, &wfds, &efds, &now); Py_INCREF(Py_None); return Py_None; } static char ADNS_State_completed__doc__[] = "s.allqueries()\n\ \n\ Returns a list of all completed queries.\n" ; static PyObject * ADNS_State_completed( ADNS_Stateobject *self, PyObject *args ) { adns_answer *answer_r; int r; ADNS_Queryobject *o, *o2; adns_query q; PyObject *l; if (!(l = ADNS_State_select(self, args))) return NULL; Py_DECREF(l); if (!(l = PyList_New(0))) return NULL; for (adns_forallqueries_begin(self->state); (q = adns_forallqueries_next(self->state, (void *)&o)); ) { r = adns_check(self->state, &q, &answer_r, (void *) &o2); if (r) { if (r == EWOULDBLOCK) continue; else { PyErr_SetString(ErrorObject, strerror(r)); PyErr_Fetch(&(o->exc_type), &(o->exc_value), &(o->exc_traceback)); continue; } } assert(o == o2); o->answer = interpret_answer(answer_r); free(answer_r); o->query = NULL; if (PyList_Append(l, (PyObject *) o)) { Py_DECREF(l); return NULL; } } return l; } static char ADNS_State_globalsystemfailure__doc__[] = "" ; static PyObject * ADNS_State_globalsystemfailure( ADNS_Stateobject *self, PyObject *args ) { if (!PyArg_ParseTuple(args, "")) return NULL; adns_globalsystemfailure(self->state); Py_INCREF(Py_None); return Py_None; } static struct PyMethodDef ADNS_State_methods[] = { {"synchronous", (PyCFunction)ADNS_State_synchronous, METH_VARARGS, ADNS_State_synchronous__doc__}, {"submit", (PyCFunction)ADNS_State_submit, METH_VARARGS, ADNS_State_submit__doc__}, {"submit_reverse", (PyCFunction)ADNS_State_submit_reverse, METH_VARARGS, ADNS_State_submit_reverse__doc__}, {"submit_reverse_any", (PyCFunction)ADNS_State_submit_reverse_any, METH_VARARGS, ADNS_State_submit_reverse_any__doc__}, {"allqueries", (PyCFunction)ADNS_State_allqueries, METH_VARARGS, ADNS_State_allqueries__doc__}, {"completed", (PyCFunction)ADNS_State_completed, METH_VARARGS, ADNS_State_completed__doc__}, {"select", (PyCFunction)ADNS_State_select, METH_VARARGS, ADNS_State_select__doc__}, {"globalsystemfailure", (PyCFunction)ADNS_State_globalsystemfailure, METH_VARARGS, ADNS_State_globalsystemfailure__doc__}, {NULL, NULL} /* sentinel */ }; /* ---------- */ static PyObject * ADNS_State_getattr( ADNS_Stateobject *self, char *name ) { /* XXXX Add your own getattr code here */ return Py_FindMethod(ADNS_State_methods, (PyObject *)self, name); } static ADNS_Stateobject * newADNS_Stateobject(void) { ADNS_Stateobject *self; self = PyObject_New(ADNS_Stateobject, &ADNS_Statetype); if (self == NULL) return NULL; self->state = NULL; return self; } static void ADNS_State_dealloc(ADNS_Stateobject *self) { Py_BEGIN_ALLOW_THREADS; adns_finish(self->state); Py_END_ALLOW_THREADS; Py_INCREF(Py_None); PyObject_Del(self); } static char ADNS_Statetype__doc__[] = "Contains state information for adns session." ; static PyTypeObject ADNS_Statetype = { PyObject_HEAD_INIT(&PyType_Type) 0, /*ob_size*/ "ADNS_State", /*tp_name*/ sizeof(ADNS_Stateobject), /*tp_basicsize*/ 0, /*tp_itemsize*/ /* methods */ (destructor)ADNS_State_dealloc, /*tp_dealloc*/ (printfunc)0, /*tp_print*/ (getattrfunc)ADNS_State_getattr, /*tp_getattr*/ (setattrfunc)0, /*tp_setattr*/ (cmpfunc)0, /*tp_compare*/ (reprfunc)0, /*tp_repr*/ 0, /*tp_as_number*/ 0, /*tp_as_sequence*/ 0, /*tp_as_mapping*/ (hashfunc)0, /*tp_hash*/ (ternaryfunc)0, /*tp_call*/ (reprfunc)0, /*tp_str*/ /* Space for future expansion */ 0L,0L,0L,0L, ADNS_Statetype__doc__ /* Documentation string */ }; /* End of code for ADNS_State objects */ /* -------------------------------------------------------- */ static char ADNS_Query_check__doc__[] = "answer = q.check()\n\ \n\ Check for an answer. Return value same as for\n\ s.synchronous.\n" ; static PyObject * ADNS_Query_check( ADNS_Queryobject *self, PyObject *args ) { adns_answer *answer_r; int r; PyObject *o2=(PyObject *)self; if (!PyArg_ParseTuple(args, "")) return NULL; if (self->exc_type) { PyErr_Restore(self->exc_type, self->exc_value, self->exc_traceback); self->exc_type = self->exc_value = self->exc_traceback = NULL; return NULL; } if (self->answer) goto ret_answer; if (!(self->query)) { PyErr_SetString(ErrorObject, "query invalidated"); return NULL; } r = adns_check(self->s->state, &self->query, &answer_r, (void *) &o2); if (r) { if (r == EWOULDBLOCK) PyErr_SetString(NotReadyError, strerror(r)); else { PyErr_SetString(ErrorObject, strerror(r)); self->query = NULL; } return NULL; } assert(o2 == (PyObject *) self); self->answer = interpret_answer(answer_r); self->query = NULL; free(answer_r); ret_answer: Py_INCREF(self->answer); return self->answer; } static char ADNS_Query_wait__doc__[] = "answer=q.wait()\n\ \n\ Wait for an answer. Return value same as for\n\ s.synchronous.\n" ; static PyObject * ADNS_Query_wait( ADNS_Queryobject *self, PyObject *args ) { adns_answer *answer_r; int r; PyObject *o2=(PyObject *)self; if (!PyArg_ParseTuple(args, "")) return NULL; if (self->exc_type) { PyErr_Restore(self->exc_type, self->exc_value, self->exc_traceback); self->exc_type = self->exc_value = self->exc_traceback = NULL; return NULL; } if (self->answer) goto ret_answer; if (!(self->query)) { PyErr_SetString(ErrorObject, "query invalidated"); return NULL; } Py_BEGIN_ALLOW_THREADS; r = adns_wait(self->s->state, &self->query, &answer_r, (void *) &o2); Py_END_ALLOW_THREADS; if (r) { if (r == EWOULDBLOCK) PyErr_SetString(NotReadyError, strerror(r)); else { PyErr_SetString(ErrorObject, strerror(r)); self->query = NULL; } return NULL; } assert(o2 == (PyObject *) self); self->answer = interpret_answer(answer_r); self->query = NULL; free(answer_r); ret_answer: Py_INCREF(self->answer); return self->answer; } static char ADNS_Query_cancel__doc__[] = "q.cancel()\n\ \n\ Cancel a pending query.\n" ; static PyObject * ADNS_Query_cancel( ADNS_Queryobject *self, PyObject *args ) { if (!PyArg_ParseTuple(args, "")) return NULL; if (!(self->query)) { PyErr_SetString(ErrorObject, "query invalidated"); return NULL; } Py_BEGIN_ALLOW_THREADS; adns_cancel(self->query); Py_END_ALLOW_THREADS; Py_INCREF(Py_None); self->query = NULL; return Py_None; } static struct PyMethodDef ADNS_Query_methods[] = { {"check", (PyCFunction)ADNS_Query_check, METH_VARARGS, ADNS_Query_check__doc__}, {"wait", (PyCFunction)ADNS_Query_wait, METH_VARARGS, ADNS_Query_wait__doc__}, {"cancel", (PyCFunction)ADNS_Query_cancel, METH_VARARGS, ADNS_Query_cancel__doc__}, {NULL, NULL} /* sentinel */ }; /* ---------- */ static PyObject * ADNS_Query_getattr( ADNS_Queryobject *self, char *name ) { /* XXXX Add your own getattr code here */ return Py_FindMethod(ADNS_Query_methods, (PyObject *)self, name); } static ADNS_Queryobject * newADNS_Queryobject(ADNS_Stateobject *state) { ADNS_Queryobject *self; self = PyObject_New(ADNS_Queryobject, &ADNS_Querytype); if (self == NULL) return NULL; Py_INCREF(state); self->s = state; self->query = NULL; self->answer = NULL; self->exc_type = NULL; self->exc_value = NULL; self->exc_traceback = NULL; return self; } static void ADNS_Query_dealloc(ADNS_Queryobject *self) { Py_DECREF(self->s); Py_XDECREF(self->answer); Py_XDECREF(self->exc_type); Py_XDECREF(self->exc_value); Py_XDECREF(self->exc_traceback); PyObject_Del(self); } static char ADNS_Querytype__doc__[] = "A query currently being processed by adns." ; static PyTypeObject ADNS_Querytype = { PyObject_HEAD_INIT(&PyType_Type) 0, /*ob_size*/ "ADNS_Query", /*tp_name*/ sizeof(ADNS_Queryobject), /*tp_basicsize*/ 0, /*tp_itemsize*/ /* methods */ (destructor)ADNS_Query_dealloc, /*tp_dealloc*/ (printfunc)0, /*tp_print*/ (getattrfunc)ADNS_Query_getattr, /*tp_getattr*/ (setattrfunc)0, /*tp_setattr*/ (cmpfunc)0, /*tp_compare*/ (reprfunc)0, /*tp_repr*/ 0, /*tp_as_number*/ 0, /*tp_as_sequence*/ 0, /*tp_as_mapping*/ (hashfunc)0, /*tp_hash*/ (ternaryfunc)0, /*tp_call*/ (reprfunc)0, /*tp_str*/ /* Space for future expansion */ 0L,0L,0L,0L, ADNS_Querytype__doc__ /* Documentation string */ }; /* End of code for ADNS_Query objects */ /* -------------------------------------------------------- */ static char adns_init__doc__[] = "s=adns.init([initflags,debugfileobj=stderr,configtext=''])\n\ \n\ Initialize an ADNS_State object, which contains state information\n\ used internally by adns." ; int _file_converter( PyObject *obj, FILE **f ) { *f = PyFile_AsFile(obj); return (*f != NULL); } static PyObject * adns__init( PyObject *self, /* Not used */ PyObject *args ) { adns_initflags flags = 0; int status; FILE *diagfile = NULL; char *configtext = NULL; ADNS_Stateobject *s; if (!PyArg_ParseTuple(args, "|iO&s", &flags, _file_converter, &diagfile, &configtext)) return NULL; if (!(s = newADNS_Stateobject())) return NULL; if (configtext) status = adns_init_strcfg(&s->state, flags, diagfile, configtext); else status = adns_init(&s->state, flags, diagfile); if (status) { PyErr_SetFromErrno(ErrorObject); ADNS_State_dealloc(s); return NULL; } return (PyObject *) s; } /* List of methods defined in the module */ static struct PyMethodDef adns_methods[] = { {"init", (PyCFunction)adns__init, METH_VARARGS, adns_init__doc__}, {"exception",(PyCFunction)adns_exception, METH_VARARGS, adns_exception__doc__}, {NULL, (PyCFunction)NULL, 0, NULL} /* sentinel */ }; /* Initialization function for the module (*must* be called initadns) */ static char adns_module_documentation[] = "" ; static PyObject * _new_exception( PyObject *dict, char *name, PyObject *base ) { PyObject *v; char longname[256]; sprintf(longname, "adns.%s", name); if ((v = PyErr_NewException(longname, base, NULL)) == NULL) return NULL; if (PyDict_SetItemString(dict, name, v)) return NULL; return v; } static int _new_constant_class( PyObject *mdict, char *type, _constant_class *table ) { PyObject *d, *c, *v; int i; /* XXX This leaks memory if it fails, but then the whole module fails to import, so probably no big deal */ if (!(d = PyDict_New())) goto error; for (i = 0; table[i].name; i++) { if (!(v = PyInt_FromLong((long)table[i].value))) goto error; if (PyDict_SetItemString(d, table[i].name, v)) goto error; } if (!(c = PyClass_New(NULL,d,PyString_InternFromString(type)))) goto error; if (PyDict_SetItemString(mdict, type, c)) goto error; return 0; error: Py_XDECREF(d); return -1; } void initadns(void) { PyObject *m, *d; /* Create the module and add the functions */ m = Py_InitModule4("adns", adns_methods, adns_module_documentation, (PyObject*)NULL,PYTHON_API_VERSION); /* Add some symbolic constants to the module */ d = PyModule_GetDict(m); ErrorObject = _new_exception(d, "Error", PyExc_StandardError); NotReadyError = _new_exception(d, "NotReady", ErrorObject); LocalError = _new_exception(d, "LocalError", ErrorObject); RemoteError = _new_exception(d, "RemoteError", ErrorObject); RemoteFailureError = _new_exception(d, "RemoteFailureError", RemoteError); RemoteTempError = _new_exception(d, "RemoteTempError", RemoteError); RemoteConfigError = _new_exception(d, "RemoteConfigError", RemoteError); QueryError = _new_exception(d, "QueryError", ErrorObject); PermanentError = _new_exception(d, "PermanentError", ErrorObject); NXDomainError = _new_exception(d, "NXDomain", PermanentError); NoDataError = _new_exception(d, "NoData", PermanentError); /* XXXX Add constants here */ _new_constant_class(d, "iflags", adns_iflags); _new_constant_class(d, "qflags", adns_qflags); _new_constant_class(d, "rr", adns_rr); _new_constant_class(d, "status", adns_s); /* Check for errors */ if (PyErr_Occurred()) Py_FatalError("can't initialize module adns"); }