File: util.py

package info (click to toggle)
python-iptables 0.13.0-1
  • links: PTS, VCS
  • area: main
  • in suites: buster
  • size: 584 kB
  • sloc: python: 2,758; makefile: 93; ansic: 77
file content (121 lines) | stat: -rw-r--r-- 3,301 bytes parent folder | download
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
import re
import os
import sys
import ctypes
import ctypes.util
from distutils.sysconfig import get_python_lib
from itertools import product
from subprocess import Popen, PIPE
from sys import version_info
try:
    from sysconfig import get_config_var
except ImportError:
    def get_config_var(name):
        if name == 'SO':
            return '.so'
        raise Exception('Not implemented')


def _insert_ko(modprobe, modname):
    p = Popen([modprobe, modname], stderr=PIPE)
    p.wait()
    return (p.returncode, p.stderr.read(1024))


def _load_ko(modname):
    # only try to load modules on kernels that support them
    if not os.path.exists("/proc/modules"):
        return (0, None)

    # this will return the full path for the modprobe binary
    modprobe = "/sbin/modprobe"
    try:
        proc = open("/proc/sys/kernel/modprobe")
        modprobe = proc.read(1024)
    except:
        pass
    if modprobe[-1] == '\n':
        modprobe = modprobe[:-1]
    return _insert_ko(modprobe, modname)


# Load a kernel module. If it is already loaded modprobe will just return 0.
def load_kernel(name, exc_if_failed=False):
    rc, err = _load_ko(name)
    if rc:
        if not err:
            err = "Failed to load the %s kernel module." % (name)
        if err[-1] == "\n":
            err = err[:-1]
        if exc_if_failed:
            raise Exception(err)


def _do_find_library(name):
    if '/' in name:
        try:
            return ctypes.CDLL(name, mode=ctypes.RTLD_GLOBAL)
        except Exception:
            return None
    p = ctypes.util.find_library(name)
    if p:
        lib = ctypes.CDLL(p, mode=ctypes.RTLD_GLOBAL)
        return lib

    # probably we have been installed in a virtualenv
    try:
        lib = ctypes.CDLL(os.path.join(get_python_lib(), name),
                          mode=ctypes.RTLD_GLOBAL)
        return lib
    except:
        pass

    for p in sys.path:
        try:
            lib = ctypes.CDLL(os.path.join(p, name), mode=ctypes.RTLD_GLOBAL)
            return lib
        except:
            pass
    return None


def _find_library(*names):
    if version_info >= (3, 3):
        ext = get_config_var("EXT_SUFFIX")
    else:
        ext = get_config_var('SO')
    try:
        triplet = get_config_var('MULTIARCH')
    except:
        triplet = ''
    if triplet in ext:
        triplet = None
    else:
        triplet = '.' + triplet
    for name in names:
        libnames = [name, "lib" + name, name + ext, "lib" + name + ext]
        if triplet:
            libnames += [name + triplet + ext, "lib" + name + triplet + ext]
        libdir = os.environ.get('IPTABLES_LIBDIR', None)
        if libdir is not None:
            libdirs = libdir.split(':')
            libs = [os.path.join(*p) for p in product(libdirs, libnames)]
            libs.extend(libnames)
        else:
            libs = libnames
        for n in libs:
            while os.path.islink(n):
                n = os.path.realpath(n)
            lib = _do_find_library(n)
            if lib is not None:
                yield lib


def find_library(*names):
    for lib in _find_library(*names):
        major = 0
        m = re.search(r"\.so\.(\d+).?", lib._name)
        if m:
            major = int(m.group(1))
        return lib, major
    return None, None