X-Git-Url: http://dolda2000.com/gitweb/?p=ldd.git;a=blobdiff_plain;f=ldd%2Fdn.py;fp=ldd%2Fdn.py;h=17becac44103cb9e07ac3e881b79028642a5d5f8;hp=0000000000000000000000000000000000000000;hb=769e7ed964e3720cf25825dd5390af5fb0bf4851;hpb=2e783944bffb349dff8667dab0ba0c48b21c9504 diff --git a/ldd/dn.py b/ldd/dn.py new file mode 100644 index 0000000..17becac --- /dev/null +++ b/ldd/dn.py @@ -0,0 +1,131 @@ +# ldd - DNS implementation in Python +# Copyright (C) 2006 Fredrik Tolf +# +# 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 of the License, or +# (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program; if not, write to the Free Software +# Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +class DNNotIn(Exception): + def __init__(self, a, b): + self.a = a + self.b = b + + def __str__(self): + return str(self.a) + " not in " + str(self.b) + +class domainname: + "A class for abstract representations of domain names" + + def __init__(self, parts, rooted): + self.parts = parts + self.rooted = rooted + + def __repr__(self): + ret = "" + if len(self.parts) > 0: + for p in self.parts[:-1]: + ret = ret + p + '.' + ret = ret + self.parts[-1] + if self.rooted: + ret = ret + '.' + return ret + + def __add__(self, y): + if self.rooted: + raise Exception("cannot append to a rooted domain name") + return(domainname(self.parts + y.parts, y.rooted)) + + def __getitem__(self, y): + return domainname([self.parts[y]], self.rooted and (y == -1 or y == len(self.parts) - 1)) + + def __getslice__(self, i, j): + return domainname(self.parts[i:j], self.rooted and j >= len(self.parts)) + + def __len__(self): + return len(self.parts) + + def __eq__(self, y): + if type(y) == str: + y = fromstring(y) + if self.rooted != y.rooted: + return False + if len(self.parts) != len(y.parts): + return False + for i in range(len(self.parts)): + if self.parts[i].lower() != y.parts[i].lower(): + return False + return True + + def __ne__(self, y): + return not self.__eq__(y) + + def __contains__(self, y): + if len(self) > len(y): + return False + if len(self) == 0: + return self.rooted == y.rooted + return y[-len(self):] == self + + def __sub__(self, y): + if self not in y: + raise DNNotIn(self, y) + return self[:len(self) - len(y)] + + def __hash__(self): + ret = 0 + for part in self.parts: + ret = ret ^ hash(part) + if self.rooted: + ret = ret ^ -1 + return ret + + def canonwire(self): + ret = "" + for p in self.parts: + ret += chr(len(p)) + ret += p.lower() + ret += chr(0) + return ret + +class DNError(Exception): + emptypart = 1 + illegalchar = 2 + def __init__(self, kind): + self.kind = kind + def __str__(self): + return {1: "empty part", + 2: "illegal character"}[self.kind] + +def fromstring(name): + parts = [] + if name == ".": + return domainname([], True) + if name == "": + return domainname([], False) + while name.find('.') >= 0: + cur = name.find('.') + if cur == 0: + raise DNError(DNError.emptypart) + part = name[:cur] + for c in part: + if ord(c) < 33: + raise DNError(DNError.illegalchar) + parts.append(part) + name = name[cur + 1:] + if len(name) > 0: + parts.append(name) + rooted = False + else: + rooted = True + return domainname(parts, rooted) +