[Python-modules-commits] r13150 - in packages/pyclamd/trunk (4 files)
rainct-guest at users.alioth.debian.org
rainct-guest at users.alioth.debian.org
Sat May 29 22:58:40 UTC 2010
Date: Saturday, May 29, 2010 @ 22:58:34
Author: rainct-guest
Revision: 13150
* debian/control:
- Swap Maintainer/Uploader fields.
- Bump Standards-Version from 3.7.3 to 3.8.4.
* debian/copyright:
- Replace "(C)" with "?\194?\169".
* pyclamd.py:
- Change exceptions from strings to classes, for python2.6+ compatibility;
thanks to Julien Danjou for reporting (Closes: #576694).
Added:
packages/pyclamd/trunk/pyclamd.py
Modified:
packages/pyclamd/trunk/debian/changelog
packages/pyclamd/trunk/debian/control
packages/pyclamd/trunk/debian/copyright
Modified: packages/pyclamd/trunk/debian/changelog
===================================================================
--- packages/pyclamd/trunk/debian/changelog 2010-05-29 19:52:25 UTC (rev 13149)
+++ packages/pyclamd/trunk/debian/changelog 2010-05-29 22:58:34 UTC (rev 13150)
@@ -1,7 +1,14 @@
pyclamd (0.1.1-2) UNRELEASED; urgency=low
[ Siegfried-Angel Gevatter Pujals ]
- * Swap Maintainer/Uploader fields.
+ * debian/control:
+ - Swap Maintainer/Uploader fields.
+ - Bump Standards-Version from 3.7.3 to 3.8.4.
+ * debian/copyright:
+ - Replace "(C)" with "©".
+ * pyclamd.py:
+ - Change exceptions from strings to classes, for python2.6+ compatibility;
+ thanks to Julien Danjou for reporting (Closes: #576694).
[ Sandro Tosi ]
* debian/control
Modified: packages/pyclamd/trunk/debian/control
===================================================================
--- packages/pyclamd/trunk/debian/control 2010-05-29 19:52:25 UTC (rev 13149)
+++ packages/pyclamd/trunk/debian/control 2010-05-29 22:58:34 UTC (rev 13150)
@@ -8,7 +8,7 @@
Vcs-Browser: http://svn.debian.org/viewsvn/python-modules/packages/pyclamd/trunk/
Build-Depends: cdbs, debhelper (>= 5)
Build-Depends-Indep: python-support (>= 0.5.3)
-Standards-Version: 3.7.3
+Standards-Version: 3.8.4
Package: python-pyclamd
Architecture: all
Modified: packages/pyclamd/trunk/debian/copyright
===================================================================
--- packages/pyclamd/trunk/debian/copyright 2010-05-29 19:52:25 UTC (rev 13149)
+++ packages/pyclamd/trunk/debian/copyright 2010-05-29 22:58:34 UTC (rev 13150)
@@ -10,7 +10,7 @@
Copyright:
- Copyright (C) 2006 Alexandre Norman <norman at xael.org>
+ Copyright © 2006 Alexandre Norman <norman at xael.org>
License:
@@ -27,5 +27,5 @@
On Debian systems, the complete text of the GNU General Public
License can be found in /usr/share/common-licenses/GPL.
-The Debian packaging is (C) 2008, Siegfried-Angel Gevatter Pujals (RainCT)
+The Debian packaging is © 2008, Siegfried-Angel Gevatter Pujals (RainCT)
<rainct at ubuntu.com> and is licensed under the GPL, see `/usr/share/common-licenses/GPL'.
Added: packages/pyclamd/trunk/pyclamd.py
===================================================================
--- packages/pyclamd/trunk/pyclamd.py (rev 0)
+++ packages/pyclamd/trunk/pyclamd.py 2010-05-29 22:58:34 UTC (rev 13150)
@@ -0,0 +1,464 @@
+
+# -*- coding: utf-8 -*-
+
+"""
+pyclamd.py - v0.1.1 - 2006.07.15
+
+Author : Alexandre Norman - norman at xael.org
+Licence : GPL
+
+Usage :
+
+
+ # Init the connexion to clamd, either :
+ # Network
+ pyclamd.init_network_socket('localhost', 3310)
+ # Unix local socket
+ #pyclamd.init_unix_socket('/var/run/clamav/clamd.ctl')
+
+ # Get Clamscan version
+ print pyclamd.version()
+
+ # Scan a buffer
+ print pyclamd.scan_stream(pyclamd.EICAR)
+
+ # Scan a file
+ print pyclamd.scan_file('/tmp/test.vir')
+
+
+Test strings :
+^^^^^^^^^^^^
+>>> try:
+... init_unix_socket('/var/run/clamav/clamd.ctl')
+... except ScanError:
+... init_network_socket('localhost', 3310)
+...
+>>> ping()
+True
+>>> version()[:6]=='ClamAV'
+True
+>>> scan_stream(EICAR)
+{'stream': 'Eicar-Test-Signature FOUND'}
+>>> open('/tmp/EICAR','w').write(EICAR)
+>>> scan_file('/tmp/EICAR')
+{'/tmp/EICAR': 'Eicar-Test-Signature'}
+>>> contscan_file('/tmp/EICAR')
+{'/tmp/EICAR': 'Eicar-Test-Signature'}
+>>> import os
+>>> os.remove('/tmp/EICAR')
+
+"""
+
+############################################################################
+
+
+# Module defined Exceptions
+global BufferTooLong
+global ScanError
+class BufferTooLong(Exception): pass
+class ScanError(Exception): pass
+
+
+# Some global variables
+global use_socket
+global clamd_HOST
+global clamd_PORT
+global clamd_SOCKET
+global EICAR
+
+# Default values for globals
+use_socket = None
+clamd_SOCKET = "/var/run/clamav/clamd.ctl"
+clamd_HOST='127.0.0.1'
+clamd_PORT=3310
+
+# Eicar test string (encoded for skipping virus scanners)
+EICAR = 'WDVPIVAlQEFQWzRcUFpYNTQoUF4pN0NDKTd9JEVJQ0FSLVNUQU5E'.decode('base64') \
+ +'QVJELUFOVElWSVJVUy1URVNU\nLUZJTEUhJEgrSCo=\n'.decode('base64')
+
+
+############################################################################
+
+import socket
+import types
+import string
+
+############################################################################
+
+def init_unix_socket(filename="/var/run/clamav/clamd.ctl"):
+ """
+ Init pyclamd to use clamd unix local socket
+
+ filename (string) : clamd file for local unix socket
+
+ return : Nothing
+
+ May raise :
+ - TypeError : if filename is not a string
+ - ValueError : if filename does not allow to ping the server
+ """
+ global use_socket
+ global clamd_HOST
+ global clamd_PORT
+ global clamd_SOCKET
+
+ if type(filename)!=types.StringType:
+ raise TypeError, 'filename should be a string not "%s"' % filename
+
+ use_socket = "UNIX"
+ clamd_SOCKET = filename
+
+ ping()
+ return
+
+############################################################################
+
+def init_network_socket(host='127.0.0.1', port=3310):
+ """
+ Init pyclamd to use clamd network socket
+
+ host (string) : clamd server adresse
+ port (int) : clamd server port
+
+ return : Nothing
+
+ May raise :
+ - TypeError : if host is not a string or port is not an int
+ - ValueError : if the server can not be pingged
+ """
+ global use_socket
+ global clamd_HOST
+ global clamd_PORT
+ global clamd_SOCKET
+
+
+ if type(host)!=types.StringType:
+ raise TypeError, 'host should be a string not "%s"' % host
+
+ if type(port)!=types.IntType:
+ raise TypeError, 'port should be an integer not "%s"' % port
+
+ use_socket = "NET"
+ clamd_HOST = host
+ clamd_PORT = port
+
+ ping()
+ return
+
+############################################################################
+
+def ping():
+ """
+ Send a PING to the clamav server, which should reply
+ by a PONG.
+
+ return : True if the server replies to PING
+
+ May raise :
+ - ScanError : if the server do not reply by PONG
+ """
+ global use_socket
+ global clamd_HOST
+ global clamd_PORT
+ global clamd_SOCKET
+
+ global ScanError
+
+ s = __init_socket__()
+
+ try:
+ s.send('PING')
+ result = s.recv(20000)
+ s.close()
+ except:
+ raise ScanError, 'Could not ping clamd server'
+
+
+ if result=='PONG\n':
+ return True
+ else:
+ raise ScanError, 'Could not ping clamd server'
+
+
+############################################################################
+
+def version():
+ """
+ Get Clamscan version
+
+ return : (string) clamscan version
+
+ May raise :
+ - ScanError : in case of communication problem
+ """
+ global use_socket
+ global clamd_HOST
+ global clamd_PORT
+ global clamd_SOCKET
+
+ s = __init_socket__()
+
+ s.send('VERSION')
+ result = s.recv(20000).strip()
+ s.close()
+ return result
+
+############################################################################
+
+def reload():
+ """
+ Force Clamd to reload signature database
+
+ return : (string) "RELOADING"
+
+ May raise :
+ - ScanError : in case of communication problem
+ """
+ global use_socket
+ global clamd_HOST
+ global clamd_PORT
+ global clamd_SOCKET
+
+ s = __init_socket__()
+
+ s.send('RELOAD')
+ result = s.recv(20000).strip()
+ s.close()
+ return result
+
+############################################################################
+
+def shutdown():
+ """
+ Force Clamd to shutdown and exit
+
+ return : nothing
+
+ May raise :
+ - ScanError : in case of communication problem
+ """
+ global use_socket
+ global clamd_HOST
+ global clamd_PORT
+ global clamd_SOCKET
+
+ s = __init_socket__()
+
+ s.send('SHUTDOWN')
+ result = s.recv(20000)
+ s.close()
+ return
+
+
+############################################################################
+
+def scan_file(file):
+ """
+ Scan a file or directory given by filename and stop on virus
+
+ file (string) : filename or directory (MUST BE ABSOLUTE PATH !)
+
+ return either :
+ - (dict) : {filename1: "virusname"}
+ - None if no virus found
+
+ May raise :
+ - ScanError : in case of communication problem
+ """
+ global use_socket
+ global clamd_HOST
+ global clamd_PORT
+ global clamd_SOCKET
+
+ global ScanError
+
+ s = __init_socket__()
+
+ s.send('SCAN %s' % file)
+ result='...'
+ dr={}
+ while result!='':
+ result = s.recv(20000)
+ if len(result)>0:
+ filenm = string.join(result.strip().split(':')[:-1])
+ virusname = result.strip().split(':')[-1].strip()
+ if virusname[-5:]=='ERROR':
+ raise ScanError, virusname
+ elif virusname[-5:]=='FOUND':
+ dr[filenm]=virusname[:-6]
+ s.close()
+ if dr=={}:
+ return None
+ else:
+ return dr
+
+############################################################################
+
+def contscan_file(file):
+ """
+ Scan a file or directory given by filename
+
+ file (string) : filename or directory (MUST BE ABSOLUTE PATH !)
+
+ return either :
+ - (dict) : {filename1: "virusname", filename2: "virusname"}
+ - None if no virus found
+
+ May raise :
+ - ScanError : in case of communication problem
+ """
+ global use_socket
+ global clamd_HOST
+ global clamd_PORT
+ global clamd_SOCKET
+
+ global ScanError
+
+ s = __init_socket__()
+
+ s.send('CONTSCAN %s' % file)
+ result='...'
+ dr={}
+ while result!='':
+ result = s.recv(20000)
+ if len(result)>0:
+ filenm = string.join(result.strip().split(':')[:-1])
+ virusname = result.strip().split(':')[-1].strip()
+ if virusname[-5:]=='ERROR':
+ raise ScanError, virusname
+ elif virusname[-5:]=='FOUND':
+ dr[filenm]=virusname[:-6]
+ s.close()
+ if dr=={}:
+ return None
+ else:
+ return dr
+
+############################################################################
+
+def scan_stream(buffer):
+ """
+ Scan a buffer
+
+ buffer (string) : buffer to scan
+
+ return either :
+ - (dict) : {filename1: "virusname"}
+ - None if no virus found
+
+ May raise :
+ - BufferTooLong : if the buffer size exceeds clamd limits
+ - ScanError : in case of communication problem
+ """
+ global use_socket
+ global clamd_HOST
+ global clamd_PORT
+ global clamd_SOCKET
+
+
+ global BufferTooLong
+ global ScanError
+
+
+ s = __init_socket__()
+
+ s.send('STREAM')
+ port = int(s.recv(200).strip().split(' ')[1])
+ n=socket.socket(socket.AF_INET, socket.SOCK_STREAM)
+ n.connect((clamd_HOST, port))
+
+ sended = n.send(buffer)
+ n.close()
+
+ if sended<len(buffer):
+ raise BufferTooLong
+
+ result='...'
+ dr={}
+ while result!='':
+ result = s.recv(20000)
+ if len(result)>0:
+ filenm = result.strip().split(':')[0]
+ virusname = result.strip().split(':')[1].strip()
+ if virusname[-5:]=='ERROR':
+ raise ScanError, virusname
+ elif virusname!='OK':
+ dr[filenm]=virusname
+ s.close()
+ if dr=={}:
+ return None
+ else:
+ return dr
+
+
+
+############################################################################
+
+def __init_socket__():
+ """
+ This is for internal use
+ """
+ global use_socket
+ global clamd_HOST
+ global clamd_PORT
+ global clamd_SOCKET
+
+ global ScanError
+
+
+ if use_socket=="UNIX":
+ s=socket.socket(socket.AF_UNIX, socket.SOCK_STREAM)
+ try:
+ s.connect(clamd_SOCKET)
+ except socket.error:
+ raise ScanError, 'Could not reach clamd using unix socket (%s)' % (clamd_SOCKET)
+ elif use_socket=="NET":
+ s=socket.socket(socket.AF_INET, socket.SOCK_STREAM)
+ try:
+ s.connect((clamd_HOST, clamd_PORT))
+ except socket.error:
+ raise ScanError, 'Could not reach clamd using network (%s, %s)' % (clamd_HOST, clamd_PORT)
+ else:
+ raise ScanError, 'Could not reach clamd : connexion not initialised'
+
+ return s
+
+
+############################################################################
+
+def __non_regression_test__():
+ """
+ This is for internal use
+ """
+ import doctest
+ doctest.testmod()
+ return
+
+
+############################################################################
+
+
+# MAIN -------------------
+if __name__ == '__main__':
+
+
+ __non_regression_test__()
+
+ import os
+ import sys
+
+## import doctest
+## doctest.testmod()
+ sys.exit(0)
+
+
+ # Print autodoc
+ if sys.argv[0].find(os.path.sep)==-1:
+ os.system("pydoc ./"+sys.argv[0])
+ else:
+ os.system("pydoc "+sys.argv[0])
+ sys.exit(0)
+
+
+
+#<EOF>######################################################################
More information about the Python-modules-commits
mailing list