chiark / gitweb /
debian/copyright, .mailmap: Convert to machine-readable format.
[mLib-python] / bres.pyx
1 ### -*-pyrex-*-
2 ###
3 ### Background name resolution
4 ###
5 ### (c) 2005 Straylight/Edgeware
6 ###
7
8 ###----- Licensing notice ---------------------------------------------------
9 ###
10 ### This file is part of the Python interface to mLib.
11 ###
12 ### mLib/Python is free software; you can redistribute it and/or modify
13 ### it under the terms of the GNU General Public License as published by
14 ### the Free Software Foundation; either version 2 of the License, or
15 ### (at your option) any later version.
16 ###
17 ### mLib/Python is distributed in the hope that it will be useful,
18 ### but WITHOUT ANY WARRANTY; without even the implied warranty of
19 ### MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
20 ### GNU General Public License for more details.
21 ###
22 ### You should have received a copy of the GNU General Public License
23 ### along with mLib/Python; if not, write to the Free Software Foundation,
24 ### Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
25
26 cdef class SelResolve:
27   """Abstract superclass for background name resolution."""
28   cdef bres_client r
29   cdef int _activep
30   cdef _resolved
31   cdef _failed
32   def __init__(me, *hunoz, **hukairz):
33     raise TypeError, 'abstract class'
34   def __dealloc__(me):
35     if me._activep:
36       me._dead()
37       bres_abort(&me.r)
38   property activep:
39     """BR.activep: is lookup still waiting?"""
40     def __get__(me):
41       return _tobool(me._activep)
42   def kill(me):
43     """BR.kill(): cancel in-progress lookup"""
44     if not me._activep:
45       raise ValueError, 'already dead'
46     me._dead()
47     bres_abort(&me.r)
48     return me
49   cdef _dead(me):
50     me._activep = 0
51     me.dead()
52   def dead(me):
53     """BR.dead(): called when lookup completes or is cancelled"""
54     pass
55   property resolvedproc:
56     """BR.resolvedproc -> FUNC: call FUNC(NAME, ALIASES, ADDRS) when ok"""
57     def __get__(me):
58       return me._resolved
59     def __set__(me, proc):
60       me._resolved = _checkcallable(proc, 'resolved proc')
61     def __del__(me):
62       me._resolved = None
63   property failedproc:
64     """BR.failedproc -> FUNC: call FUNC() when lookup fails"""
65     def __get__(me):
66       return me._failed
67     def __set__(me, proc):
68       me._failed = _checkcallable(proc, 'failed proc')
69     def __del__(me):
70       me._failed = None
71   def resolved(me, name, aliases, addrs):
72     """BR.resolved(NAME, ALIASES, ADDRS): called when lookup completes"""
73     return _maybecall(me._resolved, (name, aliases, addrs))
74   def failed(me):
75     """BR.failed(): called when lookup fails"""
76     return _maybecall(me._failed, ())
77
78 cdef class SelResolveByName (SelResolve):
79   """
80   Resolve a hostname to an IP address, asynchronously.
81
82   SelResolveByName(NAME, [resolvedproc = None], [failedproc = None])
83
84   Calls RESOLVEDPROC(NAME, ALIASES, ADDRS) on success, or FAILEDPROC() on
85   failure.
86   """
87   def __cinit__(me, char *name, resolvedproc = None, failedproc = None,
88               *hunoz, **hukairz):
89     me._resolved = _checkcallable(resolvedproc, 'resolved proc')
90     me._failed = _checkcallable(failedproc, 'failed proc')
91     me._activep = 1
92     bres_byname(&me.r, name, _resfunc, <void *>me)
93   def __init__(me, name, resolvedproc = None, failedproc = None):
94     pass
95
96 cdef class SelResolveByAddr (SelResolve):
97   """
98   Resolve an IPv4 address to a hostname, asynchronously.
99
100   SelResolveByAddr(ADDR, [resolvedproc = None], [failedproc = None])
101
102   Calls RESOLVEDPROC(NAME, ALIASES, ADDRS) on success, or FAILEDPROC() on
103   failure.
104   """
105   def __cinit__(me, char *addr, resolvedproc = None, failedproc = None,
106               *hunoz, **hukairz):
107     cdef in_addr ia
108     if not inet_aton(addr, &ia):
109       raise TypeError, 'bad IP address'
110     me._resolved = _checkcallable(resolvedproc, 'resolved proc')
111     me._failed = _checkcallable(failedproc, 'failed proc')
112     me._activep = 1
113     bres_byaddr(&me.r, ia, _resfunc, <void *>me)
114   def __init__(me, addr, resolvedproc = None, failedproc = None):
115     pass
116
117 cdef void _resfunc(hostent *h, void *arg):
118   cdef SelResolve r
119   cdef int i
120   r = <SelResolve>arg
121   r._dead()
122   if h is NULL:
123     r.failed()
124   else:
125     alias = []
126     addr = []
127     i = 0
128     while h.h_aliases[i]:
129       alias.append(h.h_aliases[i])
130       i = i + 1
131     i = 0
132     while h.h_addr_list[i]:
133       addr.append(inet_ntoa((<in_addr *>h.h_addr_list[i])[0]))
134       i = i + 1
135     r.resolved(h.h_name, alias, addr)
136
137 bres_exec(NULL)
138 bres_init(&_sel)
139
140 ###----- That's all, folks --------------------------------------------------