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
|
"""Python libknot interface."""
import ctypes
import sys
class KnotLookup(ctypes.Structure):
"""Libknot lookup return structure."""
_fields_ = [('id', ctypes.c_int), ('name', ctypes.c_char_p)]
class KnotRdataDescriptor(ctypes.Structure):
"""Rdata descriptor structure."""
_fields_ = [('block_types', ctypes.c_int * 8), ('name', ctypes.c_char_p)]
class Knot(object):
"""Basic libknot interface."""
LIBKNOT = None
LIBKNOT_VERSION = "@libknot_SOVERSION@"
RCODE_NAMES = None
STRERROR = None
RDATA_DESC = None
@classmethod
def __init__(cls, path: str = None) -> None:
"""Loads shared libknot library.
An explicit library path can be specified.
"""
if cls.LIBKNOT:
return
if path is None:
version = ""
try:
version = ".%u" % int(cls.LIBKNOT_VERSION)
except Exception:
pass
if sys.platform == "darwin":
path = "libknot%s.dylib" % version
else:
path = "libknot.so%s" % version
cls.LIBKNOT = ctypes.cdll.LoadLibrary(path)
cls.RCODE_NAMES = (KnotLookup * 32).in_dll(cls.LIBKNOT, "knot_rcode_names")
cls.STRERROR = cls.LIBKNOT.knot_strerror
cls.STRERROR.restype = ctypes.c_char_p
cls.STRERROR.argtypes = [ctypes.c_int]
cls.RDATA_DESC = cls.LIBKNOT.knot_get_rdata_descriptor
cls.RDATA_DESC.restype = ctypes.POINTER(KnotRdataDescriptor)
cls.RDATA_DESC.argtypes = [ctypes.c_ushort]
@classmethod
def rclass_str(cls, rclass: int) -> str:
"""Returns RRCLASS in text form."""
if (rclass == 1):
return "IN"
elif (rclass == 3):
return "CH"
elif (rclass == 254):
return "NONE"
elif (rclass == 255):
return "ANY"
else:
return "CLASS%i" % rclass
@classmethod
def rtype_str(cls, rtype: int) -> str:
"""Returns RRTYPE in text form."""
descr = cls.RDATA_DESC(rtype).contents.name
if descr:
return descr.decode()
else:
return "TYPE%i" % rtype
@classmethod
def rcode_str(cls, rcode: int) -> str:
"""Returns RCODE in text form."""
for item in cls.RCODE_NAMES:
if item.name and item.id == rcode:
return item.name.decode()
return "RCODE%i" % rcode
|