/usr/share/pyshared/twisted/names/hosts.py is in python-twisted-names 11.1.0-1.
This file is owned by root:root, with mode 0o644.
The actual contents of the file can be viewed below.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 | # -*- test-case-name: twisted.names.test.test_hosts -*-
# Copyright (c) Twisted Matrix Laboratories.
# See LICENSE for details.
"""
hosts(5) support.
"""
from twisted.names import dns
from twisted.persisted import styles
from twisted.python import failure
from twisted.python.filepath import FilePath
from twisted.internet import defer
from twisted.internet.abstract import isIPAddress
from twisted.names import common
def searchFileForAll(hostsFile, name):
"""
Search the given file, which is in hosts(5) standard format, for an address
entry with a given name.
@param hostsFile: The name of the hosts(5)-format file to search.
@type hostsFile: L{FilePath}
@param name: The name to search for.
@type name: C{str}
@return: C{None} if the name is not found in the file, otherwise a
C{str} giving the address in the file associated with the name.
"""
results = []
try:
lines = hostsFile.getContent().splitlines()
except:
return results
name = name.lower()
for line in lines:
idx = line.find('#')
if idx != -1:
line = line[:idx]
if not line:
continue
parts = line.split()
if name.lower() in [s.lower() for s in parts[1:]]:
results.append(parts[0])
return results
def searchFileFor(file, name):
"""
Grep given file, which is in hosts(5) standard format, for an address
entry with a given name.
@param file: The name of the hosts(5)-format file to search.
@param name: The name to search for.
@type name: C{str}
@return: C{None} if the name is not found in the file, otherwise a
C{str} giving the address in the file associated with the name.
"""
addresses = searchFileForAll(FilePath(file), name)
if addresses:
return addresses[0]
return None
class Resolver(common.ResolverBase, styles.Versioned):
"""
A resolver that services hosts(5) format files.
"""
persistenceVersion = 1
def upgradeToVersion1(self):
# <3 exarkun
self.typeToMethod = {}
for (k, v) in common.typeToMethod.items():
self.typeToMethod[k] = getattr(self, v)
def __init__(self, file='/etc/hosts', ttl = 60 * 60):
common.ResolverBase.__init__(self)
self.file = file
self.ttl = ttl
def _aRecords(self, name):
"""
Return a tuple of L{dns.RRHeader} instances for all of the IPv4
addresses in the hosts file.
"""
return tuple([
dns.RRHeader(name, dns.A, dns.IN, self.ttl,
dns.Record_A(addr, self.ttl))
for addr
in searchFileForAll(FilePath(self.file), name)
if isIPAddress(addr)])
def _aaaaRecords(self, name):
"""
Return a tuple of L{dns.RRHeader} instances for all of the IPv6
addresses in the hosts file.
"""
return tuple([
dns.RRHeader(name, dns.AAAA, dns.IN, self.ttl,
dns.Record_AAAA(addr, self.ttl))
for addr
in searchFileForAll(FilePath(self.file), name)
if not isIPAddress(addr)])
def _respond(self, name, records):
"""
Generate a response for the given name containing the given result
records, or a failure if there are no result records.
@param name: The DNS name the response is for.
@type name: C{str}
@param records: A tuple of L{dns.RRHeader} instances giving the results
that will go into the response.
@return: A L{Deferred} which will fire with a three-tuple of result
records, authority records, and additional records, or which will
fail with L{dns.DomainError} if there are no result records.
"""
if records:
return defer.succeed((records, (), ()))
return defer.fail(failure.Failure(dns.DomainError(name)))
def lookupAddress(self, name, timeout=None):
"""
Read any IPv4 addresses from C{self.file} and return them as L{Record_A}
instances.
"""
return self._respond(name, self._aRecords(name))
def lookupIPV6Address(self, name, timeout=None):
"""
Read any IPv4 addresses from C{self.file} and return them as L{Record_A}
instances.
"""
return self._respond(name, self._aaaaRecords(name))
# Someday this should include IPv6 addresses too, but that will cause
# problems if users of the API (mainly via getHostByName) aren't updated to
# know about IPv6 first.
lookupAllRecords = lookupAddress
|