root/trunk/twisted/names/hosts.py

Revision 29594, 2.0 KB (checked in by exarkun, 2 months ago)

Merge close-hosts-4540

Author: fijal, exarkun
Reviewer: mwh, jonathanj, exarkun
Fixes: #4540

Explicitly close the hosts file in twisted.names.hosts.searchFileFor, rather
than relying on reference counting to do it for us in a timely manner. This
improves behavior on PyPy and other runtimes without reference counting.

Line 
1# Copyright (c) 2001-2010 Twisted Matrix Laboratories.
2# See LICENSE for details.
3
4"""
5hosts(5) support.
6"""
7
8from twisted.names import dns
9from twisted.persisted import styles
10from twisted.python import failure
11from twisted.internet import defer
12
13from twisted.names import common
14
15
16def searchFileFor(file, name):
17    """
18    Grep given file, which is in hosts(5) standard format, for an address
19    entry with a given name.
20
21    @param file: The name of the hosts(5)-format file to search.
22
23    @param name: The name to search for.
24    @type name: C{str}
25
26    @return: C{None} if the name is not found in the file, otherwise a
27        C{str} giving the address in the file associated with the name.
28    """
29    try:
30        fp = open(file)
31    except:
32        return None
33    try:
34        lines = fp.readlines()
35    finally:
36        fp.close()
37    for line in lines:
38        idx = line.find('#')
39        if idx != -1:
40            line = line[:idx]
41        if not line:
42            continue
43        parts = line.split()
44        if name.lower() in [s.lower() for s in parts[1:]]:
45            return parts[0]
46    return None
47
48
49
50class Resolver(common.ResolverBase, styles.Versioned):
51    """A resolver that services hosts(5) format files."""
52    #TODO: IPv6 support
53
54    persistenceVersion = 1
55
56    def upgradeToVersion1(self):
57        # <3 exarkun
58        self.typeToMethod = {}
59        for (k, v) in common.typeToMethod.items():
60            self.typeToMethod[k] = getattr(self, v)
61
62
63    def __init__(self, file='/etc/hosts', ttl = 60 * 60):
64        common.ResolverBase.__init__(self)
65        self.file = file
66        self.ttl = ttl
67
68
69    def lookupAddress(self, name, timeout = None):
70        res = searchFileFor(self.file, name)
71        if res:
72            return defer.succeed([
73                (dns.RRHeader(name, dns.A, dns.IN, self.ttl, dns.Record_A(res, self.ttl)),), (), ()
74            ])
75        return defer.fail(failure.Failure(dns.DomainError(name)))
76
77
78    # When we put IPv6 support in, this'll need a real impl
79    lookupAllRecords = lookupAddress
Note: See TracBrowser for help on using the browser.