+ me._in.close()
+ while not me._done: M.select()
+ if me._idmap:
+ raise Exception('adnshost failed to process all the requests')
+
+ def _hostline(me, line):
+ """Handle a host line from the resolver."""
+
+ ## Parse the line into fields.
+ (id, nrrs, stty, stocde, stmsg, owner, cname, ststr), _ = \
+ M.split(line, quotep = True)
+ id, nrrs = int(id), int(nrrs)
+
+ ## Find the right record.
+ host = me._idmap[id]
+ if stty != 'ok': host.failed(ststr)
+
+ ## Stash away the canonical name of the host.
+ host.name = cname == '$' and owner or cname
+
+ ## If there are no record lines to come, then remove this record from the
+ ## list of outstanding jobs. Otherwise, switch to the handler for record
+ ## lines.
+ if not nrrs:
+ del me._idmap[id]
+ else:
+ me._outline.lineproc = me._rrline
+ me._nrrs = nrrs
+ me._outhost = host
+
+ def _rrline(me, line):
+ """Handle a record line from the resolver."""
+
+ ## Parse the line into fields.
+ ww, _ = M.split(line, quotep = True)
+ owner, type, af = ww[:3]
+
+ ## If this is an address record, and it looks like an interesting address
+ ## type, then stash the address.
+ if type == 'A' and (af == 'INET' or af == 'INET6'):
+ me._outhost.addaddr(af, ww[3])
+
+ ## Update the parser state. If there are no more records for this job
+ ## then mark the job as done and switch back to expecting a host line.
+ me._nrrs -= 1
+ if not me._nrrs:
+ me._outline.lineproc = me._hostline
+ del me._idmap[me._outhost.id]
+ me._outhost = None
+
+## Select a bulk resolver. If `adnshost' exists then we might as well use
+## it.
+BulkResolver = BresBulkResolver
+try:
+ p = SUB.Popen(['adnshost', '--version'],
+ stdin = SUB.PIPE, stdout = SUB.PIPE, stderr = SUB.PIPE)
+ _out, _err = p.communicate()
+ st = p.wait()
+ if st == 0: BulkResolver = AdnsBulkResolver
+except OSError:
+ pass