summaryrefslogtreecommitdiffstats
path: root/deluge/plugins/Blocklist/deluge_blocklist/peerguardian.py
diff options
context:
space:
mode:
Diffstat (limited to 'deluge/plugins/Blocklist/deluge_blocklist/peerguardian.py')
-rw-r--r--deluge/plugins/Blocklist/deluge_blocklist/peerguardian.py66
1 files changed, 66 insertions, 0 deletions
diff --git a/deluge/plugins/Blocklist/deluge_blocklist/peerguardian.py b/deluge/plugins/Blocklist/deluge_blocklist/peerguardian.py
new file mode 100644
index 0000000..b5fb181
--- /dev/null
+++ b/deluge/plugins/Blocklist/deluge_blocklist/peerguardian.py
@@ -0,0 +1,66 @@
+#
+# Copyright (C) 2007 Steve 'Tarka' Smith (tarka@internode.on.net)
+#
+# This file is part of Deluge and is licensed under GNU General Public License 3.0, or later, with
+# the additional special exception to link portions of this program with the OpenSSL library.
+# See LICENSE for more details.
+#
+
+import gzip
+import logging
+import socket
+from struct import unpack
+
+log = logging.getLogger(__name__)
+
+
+class PGException(Exception):
+ pass
+
+
+# Incrementally reads PeerGuardian blocklists v1 and v2.
+# See http://wiki.phoenixlabs.org/wiki/P2B_Format
+class PGReader:
+ def __init__(self, filename):
+ log.debug('PGReader loading: %s', filename)
+
+ try:
+ with gzip.open(filename, 'rb') as _file:
+ self.fd = _file
+ except OSError:
+ log.debug('Blocklist: PGReader: Incorrect file type or list is corrupt')
+
+ # 4 bytes, should be 0xffffffff
+ buf = self.fd.read(4)
+ hdr = unpack('l', buf)[0]
+ if hdr != -1:
+ raise PGException(_('Invalid leader') + ' %d' % hdr)
+
+ magic = self.fd.read(3)
+ if magic != 'P2B':
+ raise PGException(_('Invalid magic code'))
+
+ buf = self.fd.read(1)
+ ver = ord(buf)
+ if ver != 1 and ver != 2:
+ raise PGException(_('Invalid version') + ' %d' % ver)
+
+ def __next__(self):
+ # Skip over the string
+ buf = -1
+ while buf != 0:
+ buf = self.fd.read(1)
+ if buf == '': # EOF
+ return False
+ buf = ord(buf)
+
+ buf = self.fd.read(4)
+ start = socket.inet_ntoa(buf)
+
+ buf = self.fd.read(4)
+ end = socket.inet_ntoa(buf)
+
+ return (start, end)
+
+ def close(self):
+ self.fd.close()