[Oval-commits] r156 - in trunk/oval-server: . OvalServer dba dsa2oval dsaSync src
Pavel Vinogradov
blaze-guest at alioth.debian.org
Mon Aug 20 04:31:31 UTC 2007
Author: blaze-guest
Date: 2007-08-20 04:31:31 +0000 (Mon, 20 Aug 2007)
New Revision: 156
Added:
trunk/oval-server/OvalServer/
trunk/oval-server/OvalServer/OvalHttpServer.py
trunk/oval-server/dba/
trunk/oval-server/dba/dba.py
trunk/oval-server/dsa2oval/
trunk/oval-server/dsa2oval/convertor.py
trunk/oval-server/dsa2oval/definition/
trunk/oval-server/dsa2oval/parser/
trunk/oval-server/dsaSync/
trunk/oval-server/dsaSync/directory.py
trunk/oval-server/dsaSync/ftp.py
trunk/oval-server/dsaSync/http.py
trunk/oval-server/dsaSync/sync.py
Removed:
trunk/oval-server/OvalServer/OvalHttpServer.py
trunk/oval-server/OvalServer/OvalHttpServer.pyc
trunk/oval-server/dba/dba.py
trunk/oval-server/dsa2oval/convertor.py
trunk/oval-server/dsa2oval/definition/
trunk/oval-server/dsa2oval/parser/
trunk/oval-server/dsaSync/DsaUpdater.py
trunk/oval-server/dsaSync/DsaUpdater.pyc
trunk/oval-server/dsaSync/dirUpdater.py
trunk/oval-server/dsaSync/ftpUpdater.py
trunk/oval-server/dsaSync/httpUpdater.py
trunk/oval-server/src/OvalServer/
trunk/oval-server/src/dba/
trunk/oval-server/src/dsa2oval/
trunk/oval-server/src/dsaSync/
Log:
Move modules to project root
Copied: trunk/oval-server/OvalServer (from rev 140, trunk/oval-server/src/OvalServer)
Deleted: trunk/oval-server/OvalServer/OvalHttpServer.py
===================================================================
--- trunk/oval-server/src/OvalServer/OvalHttpServer.py 2007-08-16 05:37:44 UTC (rev 140)
+++ trunk/oval-server/OvalServer/OvalHttpServer.py 2007-08-20 04:31:31 UTC (rev 156)
@@ -1,83 +0,0 @@
-import SimpleHTTPServer, BaseHTTPServer
-from OpenSSL import SSL
-import os, sys, socket
-import xml.dom.ext
-
-def ls (path):
- import xml.dom.minidom
-
- doc = xml.dom.minidom.Document ()
- root = doc.createElement (os.path.split(path)[1])
-
- for file in os.listdir (path):
- if os.path.isdir ('%s/%s' % (path, file)):
- node = doc.createElement('dir')
- node.appendChild (doc.createTextNode(file))
- root.appendChild (node)
-
- if os.path.isfile ("%s/%s" % (path, file)):
- node = doc.createElement('file')
- node.appendChild (doc.createTextNode(file))
- root.appendChild (node)
-
- return root
-
-class HttpRequestHandler (SimpleHTTPServer.SimpleHTTPRequestHandler):
-
- workdir = '/home/blaze/tmp/oval/server'
-
- def do_QUIT (self):
- """send 200 OK response, and set server.stop to True"""
- self.send_response(200)
- self.end_headers()
- self.server.stop = True
-
- def do_GET (self):
- try:
- #Add check for ../../ names
- if self.path.endswith('.xml'):
- f = open (self.workdir + os.sep + 'definitions' + os.sep + self.path)
- self.send_response(200)
- self.send_header('Content-type', 'text/xml')
- self.end_headers()
- self.wfile.write(f.read())
- f.close()
- return
- else:
- self.send_response(200)
- self.send_header('Content-type', 'text/xml')
- self.end_headers()
- xml.dom.ext.PrettyPrint (ls(self.workdir + os.sep + 'definitions'), self.wfile)
- return
- except IOError:
- self.send_error(404, 'File Not Found: %s' % self.path)
-
-class HttpsRequestHandler (HttpRequestHandler):
- """http request handler with QUIT stopping the server"""
- def setup(self):
- self.connection = self.request
- self.rfile = socket._fileobject(self.request, "rb", self.rbufsize)
- self.wfile = socket._fileobject(self.request, "wb", self.wbufsize)
-
-class OvalHttpServer (BaseHTTPServer.HTTPServer):
- def serve_forever (self):
- """Handle one request at a time until stopped."""
- self.stop = False
- while not self.stop:
- self.handle_request()
-
-class OvalHttpsServer (OvalHttpServer):
- """http server that reacts to self.stop flag"""
-
- def __init__ (self, server_address, HandlerClass):
- BaseHTTPServer.HTTPServer.__init__(self, server_address, HandlerClass)
- ctx = SSL.Context(SSL.SSLv23_METHOD)
- #server.pem's location (containing the server private key and
- #the server certificate).
- fpem = '/home/blaze/tmp/oval/server/cfg/server.pem'
- ctx.use_privatekey_file (fpem)
- ctx.use_certificate_file(fpem)
- self.socket = SSL.Connection(ctx, socket.socket(self.address_family,
- self.socket_type))
- self.server_bind()
- self.server_activate()
Copied: trunk/oval-server/OvalServer/OvalHttpServer.py (from rev 155, trunk/oval-server/src/OvalServer/OvalHttpServer.py)
===================================================================
--- trunk/oval-server/OvalServer/OvalHttpServer.py (rev 0)
+++ trunk/oval-server/OvalServer/OvalHttpServer.py 2007-08-20 04:31:31 UTC (rev 156)
@@ -0,0 +1,96 @@
+import SimpleHTTPServer, BaseHTTPServer
+from OpenSSL import SSL
+import os, sys, socket
+import xml.dom.ext
+import logging
+
+def ls (path):
+ import xml.dom.minidom
+
+ doc = xml.dom.minidom.Document ()
+ root = doc.createElement (os.path.split(path)[1])
+
+ for file in os.listdir (path):
+ if os.path.isdir ('%s/%s' % (path, file)):
+ node = doc.createElement('dir')
+ node.appendChild (doc.createTextNode(file))
+ root.appendChild (node)
+
+ if os.path.isfile ("%s/%s" % (path, file)):
+ node = doc.createElement('file')
+ node.appendChild (doc.createTextNode(file))
+ root.appendChild (node)
+
+ return root
+
+class HttpRequestHandler (SimpleHTTPServer.SimpleHTTPRequestHandler):
+
+ workdir = '/home/blaze/tmp/oval/server'
+
+ def do_QUIT (self):
+ """send 200 OK response, and set server.stop to True"""
+ self.send_response(200)
+ self.end_headers()
+ self.server.stop = True
+
+ def do_GET (self):
+ self.server.logger.info ('httpServer: Process GET %s' % self.path)
+
+ try:
+ #Add check for ../../ names
+ if self.path.endswith('.xml'):
+ f = open (self.workdir + os.sep + 'definitions' + os.sep + self.path)
+ self.send_response(200)
+ self.send_header('Content-type', 'text/xml')
+ self.end_headers()
+ self.wfile.write(f.read())
+ f.close()
+ return
+ else:
+ self.send_response(200)
+ self.send_header('Content-type', 'text/xml')
+ self.end_headers()
+ xml.dom.ext.PrettyPrint (ls(self.workdir + os.sep + 'definitions'), self.wfile)
+ return
+ except IOError:
+ self.send_error(404, 'File Not Found: %s' % self.path)
+
+class HttpsRequestHandler (HttpRequestHandler):
+ """http request handler with QUIT stopping the server"""
+ def setup(self):
+ self.connection = self.request
+ self.rfile = socket._fileobject(self.request, "rb", self.rbufsize)
+ self.wfile = socket._fileobject(self.request, "wb", self.wbufsize)
+
+class OvalHttpServer (BaseHTTPServer.HTTPServer):
+
+ def __init__(self, conf, handler, logger = None):
+ BaseHTTPServer.HTTPServer.__init__ (self, conf, handler)
+ if logger:
+ self.logger = logger
+ else:
+ self.logger = logging.basicConfig
+
+ def serve_forever (self):
+ """Handle one request at a time until stopped."""
+ self.logger.info ('httpServer: Start request handling')
+
+ self.stop = False
+ while not self.stop:
+ self.handle_request()
+
+class OvalHttpsServer (OvalHttpServer):
+ """http server that reacts to self.stop flag"""
+
+ def __init__ (self, server_address, HandlerClass):
+ BaseHTTPServer.HTTPServer.__init__(self, server_address, HandlerClass)
+ ctx = SSL.Context(SSL.SSLv23_METHOD)
+ #server.pem's location (containing the server private key and
+ #the server certificate).
+ fpem = '/home/blaze/tmp/oval/server/cfg/server.pem'
+ ctx.use_privatekey_file (fpem)
+ ctx.use_certificate_file(fpem)
+ self.socket = SSL.Connection(ctx, socket.socket(self.address_family,
+ self.socket_type))
+ self.server_bind()
+ self.server_activate()
Deleted: trunk/oval-server/OvalServer/OvalHttpServer.pyc
===================================================================
(Binary files differ)
Copied: trunk/oval-server/dba (from rev 143, trunk/oval-server/src/dba)
Deleted: trunk/oval-server/dba/dba.py
===================================================================
--- trunk/oval-server/src/dba/dba.py 2007-08-17 14:52:53 UTC (rev 143)
+++ trunk/oval-server/dba/dba.py 2007-08-20 04:31:31 UTC (rev 156)
@@ -1,78 +0,0 @@
-from pysqlite2 import dbapi2 as db
-
-class dba:
-
- __dbStruct = """
- drop table if exists agents;
- create table agents(
- agentID int primary key,
- agentName varchar(255),
- agentStatus smallint,
- agentTimestamp datetime
- );
-
- drop table if exists vulnerabilities;
- create table vulnerabilities(
- vulnID int primary key,
- vulnDSA int,
- vulnLocation carchar(255),
- vulnTimestamp datetime
- );
-
- drop table if exists affected;
- create table affected(
- id int primary key,
- agentID int,
- vulnDSA int,
- vulnTimestamp datetime,
- status smallint
- );"""
-
- __dbPath = None
- __conn = None
- cursor = None
-
- def __init__ (self, dbpath):
- self.__dbPath = dbpath
- self.__conn = db.connect(self.__dbPath)
- self.cursor = self.__conn.cursor()
-
- def getCursor(self):
- if self.__conn:
- if self.cursor:
- return self.cursor
- else:
- self.cursor = self.__conn.cursor()
-
- def __initDB(self):
- self.cursor.executescript(self.__dbStruct)
-
- def updateDSA(self, dsa, location, timestamp):
- self.cursor.execute ('SELECT vulnID FROM vulnerabilities WHERE vulnDSA = %d' % dsa)
- if self.cursor.fetchall():
- self.cursor.execute ('UPDATE vulnerabilities set vulnLocation = \'%s\', vulnTimestamp = \'%s\' WHERE vulnDSA = %d' % (location, timestamp, dsa))
- self.__conn.commit()
- else:
- self.__insertDSA(dsa, location, timestamp)
-
- def __insertDSA(self, dsa, location, timestamp):
- self.cursor.execute ('INSERT INTO vulnerabilities (vulnDSA, vulnLocation, vulnTimestamp) VALUES (%d, \'%s\', \'%s\')' % (dsa, location, timestamp))
- self.__conn.commit()
-
- def addAgent(self, agentName):
- self.cursor.execute ('SELECT agentID FROM agents WHERE agentName = \'%s\'' % agentName)
- if self.cursor.fetchall():
- raise AgentAlreadyExistExiption
- else:
- self.cursor.execute ('INSERT INTO agents (agentName, agentTimestamp) VALUES (\'%s\', \'%s\')' %
- (agentName, '22'))
-
- def getDSAreport (self):
- self.cursor.execute ('SELECT vulnDSA, vulnTimestamp from vulnerabilities;')
- return (self.cursor.fetchall())
-
-if __name__ == "__main__":
- sql = dba('/tmp/oval-server.db')
- sql.updateDSA (111, '/tmp/111', '1')
- #sql.updateDSA (112, '/tmp/111', '3')
- print sql.getDSAreport()
\ No newline at end of file
Copied: trunk/oval-server/dba/dba.py (from rev 155, trunk/oval-server/src/dba/dba.py)
===================================================================
--- trunk/oval-server/dba/dba.py (rev 0)
+++ trunk/oval-server/dba/dba.py 2007-08-20 04:31:31 UTC (rev 156)
@@ -0,0 +1,96 @@
+from pysqlite2 import dbapi2 as db
+
+class dbaNotInitialized(Exception):
+ pass
+
+class dba:
+
+ __dbStruct = """
+ drop table if exists agents;
+ create table agents(
+ agentID int primary key,
+ agentName varchar(255),
+ agentStatus smallint,
+ agentTimestamp datetime
+ );
+
+ drop table if exists vulnerabilities;
+ create table vulnerabilities(
+ vulnID int primary key,
+ vulnDSA int,
+ vulnLocation carchar(255),
+ vulnTimestamp datetime
+ );
+
+ drop table if exists affected;
+ create table affected(
+ id int primary key,
+ agentID int,
+ vulnDSA int,
+ vulnTimestamp datetime,
+ status smallint
+ );"""
+
+ __dbPath = None
+ __conn = None
+ cursor = None
+
+ def __init__ (self, dbpath):
+ self.__dbPath = dbpath
+ self.__conn = db.connect(self.__dbPath)
+ self.__conn.isolation_level = None
+ self.cursor = self.__conn.cursor()
+ #Chech if tables exists
+ try:
+ self.cursor.execute ("""SELECT name FROM sqlite_master
+ WHERE type=\'table\'
+ ORDER BY name;""")
+ if not self.cursor.fetchall():
+ raise dbaNotInitialized ()
+ except dbaNotInitialized:
+ self.__initDB()
+
+ def getCursor(self):
+ if self.__conn:
+ if self.cursor:
+ return self.cursor
+ else:
+ self.cursor = self.__conn.cursor()
+
+ def __initDB(self):
+ self.cursor.executescript(self.__dbStruct)
+
+ def updateDSA(self, dsa, location, timestamp):
+ self.cursor.execute ('SELECT vulnID FROM vulnerabilities WHERE vulnDSA = %d' % dsa)
+ if self.cursor.fetchall():
+ self.cursor.execute ('UPDATE vulnerabilities set vulnLocation = \'%s\', vulnTimestamp = \'%s\' WHERE vulnDSA = %d' % (location, timestamp, dsa))
+ else:
+ self.__insertDSA(dsa, location, timestamp)
+
+ def __insertDSA(self, dsa, location, timestamp):
+ self.cursor.execute ('INSERT INTO vulnerabilities (vulnDSA, vulnLocation, vulnTimestamp) VALUES (%d, \'%s\', \'%s\')' % (dsa, location, timestamp))
+
+ def addAgent(self, agentName):
+ self.cursor.execute ('SELECT agentID FROM agents WHERE agentName = \'%s\'' % agentName)
+ if self.cursor.fetchall():
+ raise AgentAlreadyExistExiption
+ else:
+ self.cursor.execute ('INSERT INTO agents (agentName, agentTimestamp) VALUES (\'%s\', \'%s\')' %
+ (agentName, '22'))
+
+ def getDSAreport (self):
+ self.cursor.execute ('SELECT vulnDSA, vulnTimestamp, vulnLocation from vulnerabilities;')
+ return (self.cursor.fetchall())
+
+ def makeDefList (self, agentID):
+ self.cursor.execute (
+ """SELECT vulnLocation FROM vulnerabilities
+ LEFT JOIN affected
+ ON vulnerabilities.vulnDSA = affected.vulnDSA
+ WHERE vulnerabilities.vulnTimestamp > affected.vulnTimestamp OR affected.vulnTimestamp IS NULL;
+ """)
+ return self.cursor.fetchall()
+
+if __name__ == "__main__":
+ sql = dba('/tmp/oval-server.db')
+ print sql.makeDefList(1)
\ No newline at end of file
Copied: trunk/oval-server/dsa2oval (from rev 140, trunk/oval-server/src/dsa2oval)
Deleted: trunk/oval-server/dsa2oval/convertor.py
===================================================================
--- trunk/oval-server/src/dsa2oval/convertor.py 2007-08-16 05:37:44 UTC (rev 140)
+++ trunk/oval-server/dsa2oval/convertor.py 2007-08-20 04:31:31 UTC (rev 156)
@@ -1,53 +0,0 @@
-import os
-import sys
-import definition.generator
-from parser import wml
-from parser import dsa
-
-class Dsa2Oval:
-
- inputDir = None
- outputDir = None
- dsaref = {}
-
- def __init__ (self, input, output):
- self.inputDir = input
- self.outputDir = output
-
- def parsedir (self, directory, postfix):
- for file in os.listdir(directory):
-
- path = '%s/%s' % (directory, file)
- if os.access(path, os.R_OK) and os.path.isdir (path) and not os.path.islink (path) and file[0] != '.':
- parsedirs (path, postfix)
-
- if os.access(path, os.R_OK) and file.endswith(postfix) and file[0] != '.' and file[0] != '#':
- result = dsa.parseFile (path)
- if result:
- if self.dsaref.has_key (result[0]):
- for (k, v) in result[1].iteritems():
- self.dsaref[result[0]][k] = v
- else:
- self.dsaref[result[0]] = result[1]
-
- if os.access(path, os.R_OK) and file.endswith(".wml") and file[0] != '.' and file[0] != '#':
- result = wml.parseFile(path)
- if result:
- if self.dsaref.has_key (result[0]):
- for (k, v) in result[1].iteritems():
- self.dsaref[result[0]][k] = v
- else:
- self.dsaref[result[0]] = result[1]
-
- def storeresult (self):
- import xml.dom.ext
-
- for line in self.dsaref.items():
- file = open (self.outPath+os.sep+line[0]+'.xml', 'w')
- xml.dom.ext.PrettyPrint (definition.generator.createOVALDefinitions({line[0]:line[1]}), file)
- file.close()
-
-if __name__ == '__main__':
- conv = Dsa2Oval ('/home/blaze/tmp/oval/server/dsa', '/home/blaze/tmp/oval/server/definitions')
- conv.parsedir (conv.inPath, 'data')
- conv.storeresult()
\ No newline at end of file
Copied: trunk/oval-server/dsa2oval/convertor.py (from rev 155, trunk/oval-server/src/dsa2oval/convertor.py)
===================================================================
--- trunk/oval-server/dsa2oval/convertor.py (rev 0)
+++ trunk/oval-server/dsa2oval/convertor.py 2007-08-20 04:31:31 UTC (rev 156)
@@ -0,0 +1,92 @@
+import os
+import sys
+import xml.dom.ext
+from definition import generator
+from parser import wml
+from parser import dsa
+
+class Dsa2Oval:
+
+ inputDir = None
+ outputDir = None
+ dsaref = {}
+
+ def __init__ (self, input, output):
+ self.inputDir = input
+ self.outputDir = output
+
+ def parsedir (self, directory, postfix):
+ for file in os.listdir(directory):
+
+ path = '%s/%s' % (directory, file)
+ if os.access(path, os.R_OK) and os.path.isdir (path) and not os.path.islink (path) and file[0] != '.':
+ parsedirs (path, postfix)
+
+ if os.access(path, os.R_OK) and file.endswith(postfix) and file[0] != '.' and file[0] != '#':
+ result = dsa.parseFile (path)
+ if result:
+ if self.dsaref.has_key (result[0]):
+ for (k, v) in result[1].iteritems():
+ self.dsaref[result[0]][k] = v
+ else:
+ self.dsaref[result[0]] = result[1]
+
+ if os.access(path, os.R_OK) and file.endswith(".wml") and file[0] != '.' and file[0] != '#':
+ result = wml.parseFile(path)
+ if result:
+ if self.dsaref.has_key (result[0]):
+ for (k, v) in result[1].iteritems():
+ self.dsaref[result[0]][k] = v
+ else:
+ self.dsaref[result[0]] = result[1]
+
+ def createDefList (self, files):
+ for file in files:
+ datafile = file[0]
+ (path, ext) = os.path.splitext(datafile)
+ wmlfile = '.'.join((path, 'wml'))
+
+ #Parse data file
+ result = dsa.parseFile (datafile)
+ if result:
+ if self.dsaref.has_key (result[0]):
+ for (k, v) in result[1].iteritems():
+ self.dsaref[result[0]][k] = v
+ else:
+ self.dsaref[result[0]] = result[1]
+
+ #Parse wml file
+ result = wml.parseFile(wmlfile)
+ if result:
+ if self.dsaref.has_key (result[0]):
+ for (k, v) in result[1].iteritems():
+ self.dsaref[result[0]][k] = v
+ else:
+ self.dsaref[result[0]] = result[1]
+
+ return generator.createOVALDefinitions(self.dsaref)
+
+ def storeresult (self):
+
+ for line in self.dsaref.items():
+ file = open (self.outPath+os.sep+line[0]+'.xml', 'w')
+ xml.dom.ext.PrettyPrint (generator.createOVALDefinitions({line[0]:line[1]}), file)
+ file.close()
+
+ def saveOvalDef (self, path):
+ if path != 'stdout':
+ file = open (path, 'w')
+ xml.dom.ext.PrettyPrint (generator.createOVALDefinitions(self.dsaref), file)
+ file.close()
+ else:
+ xml.dom.ext.PrettyPrint (generator.createOVALDefinitions(self.dsaref))
+
+if __name__ == '__main__':
+ conv = Dsa2Oval ('/home/blaze/tmp/oval/server/dsa', '/home/blaze/tmp/oval/server/definitions')
+ from dba import dba
+ db = dba.dba('/tmp/oval-server.db')
+ files = db.makeDefList(1)
+ data = conv.createDefList(files)
+ conv.saveOvalDef('stdout')
+# conv.parsedir (conv.inPath, 'data')
+# conv.storeresult()
\ No newline at end of file
Copied: trunk/oval-server/dsa2oval/definition (from rev 155, trunk/oval-server/src/dsa2oval/definition)
Copied: trunk/oval-server/dsa2oval/parser (from rev 155, trunk/oval-server/src/dsa2oval/parser)
Copied: trunk/oval-server/dsaSync (from rev 141, trunk/oval-server/src/dsaSync)
Deleted: trunk/oval-server/dsaSync/DsaUpdater.py
===================================================================
--- trunk/oval-server/src/dsaSync/DsaUpdater.py 2007-08-16 05:40:02 UTC (rev 141)
+++ trunk/oval-server/dsaSync/DsaUpdater.py 2007-08-20 04:31:31 UTC (rev 156)
@@ -1,29 +0,0 @@
-from datetime import datetime
-from stat import *
-import os
-
-class DsaUpdater:
-
- dsaSource = None
- dsaStorage = None
- actual = None
-
- def __init__ (self, source, storage):
- self.dsaSource = source
- self.dsaStorage =storage
- self.__getLastUpdateDate()
-
- def __getLastUpdateDate (self):
- time = datetime(1990, 1, 1, 00, 00, 00)
-
- if (os.access(self.dsaStorage, os.R_OK)):
- for path in os.listdir(self.dsaStorage):
- mtime = datetime.fromtimestamp(os.stat(self.dsaStorage+os.sep+path)[ST_MTIME])
- if mtime > time:
- time = mtime
- else:
- os.mkdir(self.dsaStorage)
- self.actual = time
-
- def syncronize (self):
- pass
\ No newline at end of file
Deleted: trunk/oval-server/dsaSync/DsaUpdater.pyc
===================================================================
(Binary files differ)
Deleted: trunk/oval-server/dsaSync/dirUpdater.py
===================================================================
--- trunk/oval-server/src/dsaSync/dirUpdater.py 2007-08-16 05:40:02 UTC (rev 141)
+++ trunk/oval-server/dsaSync/dirUpdater.py 2007-08-20 04:31:31 UTC (rev 156)
@@ -1,53 +0,0 @@
-from DsaUpdater import DsaUpdater
-from datetime import datetime
-from stat import *
-import os
-
-class dirUpdater(DsaUpdater):
-
- result = []
- def cmpdir (self, directory):
-
- for file in os.listdir(directory):
- path = '%s/%s' % (directory, file)
-
- mtime = datetime.fromtimestamp(os.stat(path)[ST_MTIME])
- if mtime > self.actual:
-
- if os.access(path, os.R_OK) and os.path.isdir (path) and not os.path.islink (path) and file[0] != '.':
- self.cmpdir (path)
-
- if os.access(path, os.R_OK) and (file.endswith('.data') or file.endswith('.wml')) and file[0] != '.' and file[0] != '#':
- self.result.append (path)
-
- def syncfile (self, dir, file):
- from shutil import copyfile
-
- if dir:
- path = self.dsaStorage + os.sep + dir
-
- if os.access(path, os.W_OK) and os.path.isdir (path):
- copyfile ('%s/%s/%s' % (self.dsaSource, dir, file), path+os.sep+file)
- else:
- os.mkdir(path)
- self.syncfile(dir, file)
- else:
- copyfile ('%s/%s' % (self.dsaSource, file), self.dsaStorage)
-
- def syncdirs (self):
- for path in self.result:
- file = path[len(self.dsaSource)+1:]
- (dir, file) = os.path.split(file)
- self.syncfile (dir, file)
-
- def sync(self):
- self.cmpdir (self.dsaSource)
- print self.result
- if self.result:
- self.syncdirs ()
-
-if __name__ == '__main__':
- upd = dirUpdater('/home/blaze/tmp/oval/server/dsa', '/tmp/dsa')
- upd.sync()
-
-
\ No newline at end of file
Copied: trunk/oval-server/dsaSync/directory.py (from rev 155, trunk/oval-server/src/dsaSync/directory.py)
===================================================================
--- trunk/oval-server/dsaSync/directory.py (rev 0)
+++ trunk/oval-server/dsaSync/directory.py 2007-08-20 04:31:31 UTC (rev 156)
@@ -0,0 +1,62 @@
+from sync import DsaSync
+from datetime import datetime
+from shutil import copy2
+from stat import *
+import os
+
+class dirSync(DsaSync):
+
+ result = []
+
+ def cmpdir (self, directory):
+ self.logger.debug ('directorySync: sync dir %s' % directory)
+
+ for file in os.listdir(directory):
+ path = '%s/%s' % (directory, file)
+
+ mtime = datetime.fromtimestamp(os.stat(path)[ST_MTIME])
+ if mtime > self.actual:
+ #self.logger.debug ('Check %s newwer then %s for %s' % (mtime, self.actual, path))
+ if os.access(path, os.R_OK) and os.path.isdir (path) and not os.path.islink (path) and file[0] != '.':
+ self.cmpdir (path)
+
+ if os.access(path, os.R_OK) and (file.endswith('.data') or file.endswith('.wml')) and file[0] != '.' and file[0] != '#':
+ self.result.append (path)
+
+ def syncfile (self, dir, file):
+ DsaSync.syncfile (self, dir, file)
+
+ if dir:
+ path = self.dsaStorage + os.sep + dir
+
+ if os.access(path, os.W_OK) and os.path.isdir (path):
+ copy2 ('%s/%s/%s' % (self.dsaSource, dir, file), path+os.sep+file)
+ else:
+ os.mkdir(path)
+ self.syncfile(dir, file)
+ else:
+ copy2 ('%s/%s' % (self.dsaSource, file), self.dsaStorage+os.sep+file)
+
+ def syncdirs (self):
+ #Move this function to parrent
+ for path in self.result:
+ file = path[len(self.dsaSource)+1:]
+ (dir, file) = os.path.split(file)
+ self.syncfile (dir, file)
+ self.logger.info('directorySync: synced %d files' % len(self.result))
+
+ def sync(self):
+ #Move this function to parrent
+ self.result = []
+ self.getLastUpdateDate()
+ self.logger.info('Syncing %s with %s' % (self.dsaStorage, self.dsaSource))
+
+ self.cmpdir (self.dsaSource)
+ if self.result:
+ self.syncdirs ()
+ else:
+ self.logger.info('directorySync: no files to sync')
+
+if __name__ == '__main__':
+ upd = dirSync('/home/blaze/tmp/oval/server/dsa', '/tmp/dsa')
+ upd.sync()
\ No newline at end of file
Copied: trunk/oval-server/dsaSync/ftp.py (from rev 155, trunk/oval-server/src/dsaSync/ftp.py)
===================================================================
--- trunk/oval-server/dsaSync/ftp.py (rev 0)
+++ trunk/oval-server/dsaSync/ftp.py 2007-08-20 04:31:31 UTC (rev 156)
@@ -0,0 +1,132 @@
+from sync import DsaSync
+from datetime import datetime
+from ftplib import FTP
+import os, re, logging
+
+logging.basicConfig()
+
+class ftpConnectException (Exception):
+ pass
+
+class ftpSync(DsaSync):
+
+ host = 'ftp://server'
+ dirs = []
+ result = []
+ conn = None
+ curdir = '/'
+ curfile = None
+
+ month = {'Jan' : 1, 'Feb' : 2, 'Mar' : 3, 'Apr' : 4, 'May' : 5, 'Jun' : 6,
+ 'Jul' : 7, 'Aug' : 8, 'Sep' : 9, 'Oct' : 10, 'Nov' : 11, 'Dec' : 12}
+
+ def __init__ (self, source, storage, server, logger):
+ DsaSync.__init__(self, source, storage, logger)
+ try:
+ self.host = server
+ self.conn = FTP(self.host)
+ self.conn.login()
+ self.curdir = '/'
+ except Exception:
+ raise ftpConnectException
+
+ def __parse(self, line):
+ mtime = None
+ type = None
+
+ #year = 2007, in this case LIST return time instead of year
+ patern = re.compile(r'[drxr\- ]+(\d) *\d+ *\d+ *\d+ (\w+) (\d+) (\d+:\d+) (.*)')
+ result = patern.search(line)
+ if result:
+ type = result.groups()[0]
+ month = self.month[result.groups()[1]]
+ day = int(result.groups()[2])
+ (hour, min) = result.groups()[3].split(':')
+ file = result.groups()[4]
+ mtime = datetime(2007, month, day, int(hour), int(min), 0)
+ else:
+ #year != 2007
+ patern = re.compile(r'[drxr\- ]+(\d) *\d+ *\d+ *\d+ (\w+) (\d+) *(\d+) (.*)')
+ result = patern.search(line)
+ if result:
+ type = result.groups()[0]
+ month = self.month[result.groups()[1]]
+ day = int(result.groups()[2])
+ year = int(result.groups()[3])
+ file = result.groups()[4]
+ mtime = datetime(year, month, day, 12, 12, 0)
+ if mtime:
+ if mtime > self.actual:
+ if type == '1':
+ self.result.append(self.curdir+os.sep+file)
+ else:
+ if type == '3':
+ self.dirs.append(file)
+ else:
+ self.logger.critical('Unknown file type: %s' % type)
+ else:
+ self.logger.debug('Bad line format: %s' % line)
+
+ def __writer (self, data):
+ file = open (self.curfile, 'w')
+ file.write(data)
+ file.close()
+
+ def cmpdir (self):
+ self.logger.debug ('ftpSync: sync dir %s' % self.dirs)
+
+ self.dirs = []
+ self.conn.cwd(self.curdir)
+ self.conn.retrlines('LIST', self.__parse)
+
+ if self.dirs:
+ dirs = self.dirs[:]
+ for dir in dirs:
+ self.curdir += '/%s' % dir
+ self.cmpdir()
+ self.conn.cwd('../')
+ self.curdir = os.path.split(self.curdir)[0]
+
+ def syncfile (self, dir, file):
+ DsaSync.syncfile (self, dir, file)
+
+ if dir:
+ path = self.dsaStorage + os.sep + dir
+
+ if os.access(path, os.W_OK) and os.path.isdir (path):
+ self.curfile = '%s/%s/%s' % (self.dsaStorage, dir, file)
+ self.conn.retrbinary('RETR %s' % (self.dsaSource+os.sep+dir+os.sep+file), self.__writer)
+ else:
+ os.mkdir(path)
+ self.syncfile(dir, file)
+ else:
+ self.curfile = self.dsaStorage+os.sep+file
+ self.conn.retrbinary('RETR %s' % (self.dsaSource + os.sep+file), self.__writer)
+
+ def syncdirs (self):
+ #Move this function to parrent
+ for path in self.result:
+ file = path[len(self.dsaSource)+1:]
+ (dir, file) = os.path.split(file)
+ self.syncfile (dir, file)
+ self.logger.info('directorySync: synced %d files' % len(self.result))
+
+ def sync(self):
+ #Move this function to parrent
+ self.result = []
+ self.getLastUpdateDate()
+ self.logger.info('Syncing %s with ftp://%s%s' % (self.dsaStorage, self.host, self.dsaSource))
+ self.curdir = self.dsaSource
+
+ self.cmpdir ()
+ if self.result:
+ self.syncdirs ()
+ else:
+ self.logger.info('directorySync: no files to sync')
+
+if __name__ == '__main__':
+ try:
+ upd = ftpSync('/debian/dsa', '/tmp/dsa', 'server')
+ upd.sync()
+ except ftpConnectException:
+ logging.critical('Ftp server not available.')
\ No newline at end of file
Deleted: trunk/oval-server/dsaSync/ftpUpdater.py
===================================================================
--- trunk/oval-server/src/dsaSync/ftpUpdater.py 2007-08-16 05:40:02 UTC (rev 141)
+++ trunk/oval-server/dsaSync/ftpUpdater.py 2007-08-20 04:31:31 UTC (rev 156)
@@ -1,127 +0,0 @@
-from DsaUpdater import DsaUpdater
-from datetime import datetime
-from ftplib import FTP
-import os, re, logging
-
-logging.basicConfig()
-
-class ftpConnectException (Exception):
- pass
-
-class ftpUpdater(DsaUpdater):
-
- host = 'ftp://server'
- dirs = []
- result = []
- ftp = None
- curdir = '/'
- curfile = None
-
- month = {'Jan' : 1, 'Feb' : 2, 'Mar' : 3, 'Apr' : 4, 'May' : 5, 'Jun' : 6,
- 'Jul' : 7, 'Aug' : 8, 'Sep' : 9, 'Oct' : 10, 'Nov' : 11, 'Dec' : 12}
-
- def __init__ (self, source, storage, server):
- DsaUpdater.__init__(self, source, storage)
- try:
- self.host = server
- self.ftp = FTP(self.host)
- self.ftp.login()
- self.curdir = '/'
- except Exception:
- raise ftpConnectException
-
- def __parse(self, line):
- mtime = None
- type = None
-
- #year = 2007, in this case LIST return time instead of year
- patern = re.compile(r'[drxr\- ]+(\d) *\d+ *\d+ *\d+ (\w+) (\d+) (\d+:\d+) (.*)')
- result = patern.search(line)
- if result:
- type = result.groups()[0]
- month = self.month[result.groups()[1]]
- day = int(result.groups()[2])
- (hour, min) = result.groups()[3].split(':')
- file = result.groups()[4]
- mtime = datetime(2007, month, day, int(hour), int(min), 0)
- else:
- #year != 2007
- patern = re.compile(r'[drxr\- ]+(\d) *\d+ *\d+ *\d+ (\w+) (\d+) *(\d+) (.*)')
- result = patern.search(line)
- if result:
- type = result.groups()[0]
- month = self.month[result.groups()[1]]
- day = int(result.groups()[2])
- year = int(result.groups()[3])
- file = result.groups()[4]
- mtime = datetime(year, month, day, 12, 12, 0)
- if mtime:
- logging.critical ('File %s with mtime %s vs %s' % (file, mtime, self.actual))
- if mtime > self.actual:
- if type == '1':
- self.result.append(self.curdir+os.sep+file)
- else:
- if type == '3':
- self.dirs.append(file)
- else:
- logging.critical('Unknown file type: %s' % type)
- else:
- logging.critical('Bad line format: %s' % line)
-
- def __writer (self, data):
- file = open (self.curfile, 'w')
- file.write(data)
- file.close()
-
- def cmpdir (self):
-
- self.dirs = []
- logging.critical('LIST %s' % self.curdir)
- self.ftp.cwd(self.curdir)
- self.ftp.retrlines('LIST', self.__parse)
-
- if self.dirs:
- dirs = self.dirs[:]
- for dir in dirs:
- self.curdir += '/%s' % dir
- self.cmpdir()
- self.ftp.cwd('../')
- self.curdir = os.path.split(self.curdir)[0]
-
- def syncfile (self, dir, file):
-
- if dir:
- path = self.dsaStorage + os.sep + dir
-
- if os.access(path, os.W_OK) and os.path.isdir (path):
- self.curfile = '%s/%s/%s' % (self.dsaStorage, dir, file)
- logging.critical('sync %s' % (path+os.sep+file))
- self.ftp.retrbinary('RETR %s' % (self.dsaSource+os.sep+dir+os.sep+file), self.__writer)
- else:
- os.mkdir(path)
- logging.critical('sync dir %s' % path)
- self.syncfile(dir, file)
- else:
- self.curfile = self.dsaStorage+os.sep+file
- self.ftp.retrbinary('RETR %s' % (self.dsaSource + os.sep+file), self.__writer)
-
- def syncdirs (self):
- for path in self.result:
- file = path[len(self.dsaSource)+1:]
- (dir, file) = os.path.split(file)
- self.syncfile (dir, file)
-
- def sync(self):
- logging.critical('Syncing %s with ftp://%s%s' % (self.dsaStorage, self.host, self.dsaSource))
- self.curdir = self.dsaSource
- self.cmpdir ()
-
- if self.result:
- self.syncdirs ()
-
-if __name__ == '__main__':
- try:
- upd = ftpUpdater('/debian/dsa', '/tmp/dsa', 'server')
- upd.sync()
- except ftpConnectException:
- logging.critical('Ftp server not available.')
\ No newline at end of file
Copied: trunk/oval-server/dsaSync/http.py (from rev 155, trunk/oval-server/src/dsaSync/http.py)
===================================================================
--- trunk/oval-server/dsaSync/http.py (rev 0)
+++ trunk/oval-server/dsaSync/http.py 2007-08-20 04:31:31 UTC (rev 156)
@@ -0,0 +1,134 @@
+from sync import DsaSync
+from datetime import datetime
+import os, re
+import httplib
+
+class httpConnectException (Exception):
+ pass
+
+class httpSync(DsaSync):
+
+ host = 'htttp://server'
+ conn = None
+
+ dirs = []
+ result = []
+
+ curdir = '/'
+ curfile = None
+
+ month = {'Jan' : 1, 'Feb' : 2, 'Mar' : 3, 'Apr' : 4, 'May' : 5, 'Jun' : 6,
+ 'Jul' : 7, 'Aug' : 8, 'Sep' : 9, 'Oct' : 10, 'Nov' : 11, 'Dec' : 12}
+
+ def __init__ (self, source, storage, server, logger):
+ DsaSync.__init__(self, source, storage, logger)
+ try:
+ self.host = server
+ self.conn = httplib.HTTPConnection(self.host)
+ except Exception:
+ raise httpConnectException
+
+ def __parse(self, data):
+ mtime = None
+ type = None
+
+ paternDIR = re.compile(r'<td><a href="\d+/">(\d+/)</a></td>.*>(\d+)\-(\w+)\-(\d+) (\d+:\d+) *</td>')
+ paternFILE = re.compile(r'<td><a href="[\w\d\.\-]+">(dsa\-\d+\.(wml|data))</a></td>.*>(\d+)\-(\w+)\-(\d+) (\d+:\d+) *</td>')
+
+ for line in data.split('\n'):
+ mtime = None
+ type = None
+
+ result = paternDIR.search(line)
+ if result:
+ type = 'dir'
+ file = result.groups()[0]
+ day = int(result.groups()[1])
+ month = self.month[result.groups()[2]]
+ year = int(result.groups()[3])
+ (hour, min) = result.groups()[4].split(':')
+ mtime = datetime(year, month, day, int(hour), int(min), 0)
+ else:
+ result = paternFILE.search(line)
+ if result:
+ type = 'file'
+ file = result.groups()[0]
+ day = int(result.groups()[2])
+ month = self.month[result.groups()[3]]
+ year = int(result.groups()[4])
+ (hour, min) = result.groups()[5].split(':')
+ mtime = datetime(year, month, day, int(hour), int(min), 0)
+
+ if mtime:
+ if mtime > self.actual:
+ if type == 'file':
+ self.result.append(self.curdir+os.sep+file)
+ else:
+ if type == 'dir':
+ self.dirs.append(file)
+ else:
+ self.logger.critical('Unknown file type: %s' % type)
+ else:
+ self.logger.debug('Bad line format: %s' % line)
+
+ def __writer (self, data):
+ file = open (self.curfile, 'w')
+ file.write(data)
+ file.close()
+
+ def cmpdir (self):
+ self.logger.debug ('httpSync: sync dir %s' % self.dirs)
+
+ self.dirs = []
+ logging.critical('LIST %s' % self.curdir)
+ self.conn.request('GET',self.curdir)
+ self.__parse(self.conn.getresponse().read())
+
+ if self.dirs:
+ dirs = self.dirs[:]
+ for dir in dirs:
+ self.curdir += '/%s' % dir
+ self.cmpdir()
+ self.curdir = os.path.split(self.curdir)[0]
+ self.curdir = os.path.split(self.curdir)[0]
+
+ def syncfile (self, dir, file):
+
+ DsaSync.syncfile(self, dir, file)
+
+ if dir:
+ path = self.dsaStorage + os.sep + dir
+
+ if os.access(path, os.W_OK) and os.path.isdir (path):
+ self.curfile = '%s/%s/%s' % (self.dsaStorage, dir, file)
+ self.conn.request('GET', '%s' % (self.dsaSource+os.sep+dir+os.sep+file))
+ data = self.conn.getresponse().read()
+ self.__writer(data)
+ else:
+ os.mkdir(path)
+ self.syncfile(dir, file)
+ else:
+ self.curfile = self.dsaStorage+os.sep+file
+ self.conn.request('GET', '%s' % (self.dsaSource+os.sep+file))
+ data = self.conn.getresponse().read()
+ self.__writer(data)
+
+ def sync(self):
+ #Move this function to parrent
+ self.result = []
+ self.getLastUpdateDate()
+ self.logger.info('Syncing %s with http://%s%s' % (self.dsaStorage, self.host, self.dsaSource))
+ self.curdir = self.dsaSource
+
+ self.cmpdir ()
+ if self.result:
+ self.syncdirs ()
+ else:
+ self.logger.info('directorySync: no files to sync')
+
+if __name__ == '__main__':
+ try:
+ upd = httpSync('/~blaze/debian/dsa/', '/tmp/dsa', 'server')
+ upd.sync()
+ except httpConnectException:
+ logging.critical('Http server not available.')
\ No newline at end of file
Deleted: trunk/oval-server/dsaSync/httpUpdater.py
===================================================================
--- trunk/oval-server/src/dsaSync/httpUpdater.py 2007-08-16 05:40:02 UTC (rev 141)
+++ trunk/oval-server/dsaSync/httpUpdater.py 2007-08-20 04:31:31 UTC (rev 156)
@@ -1,138 +0,0 @@
-from DsaUpdater import DsaUpdater
-from datetime import datetime
-import os, re, logging
-import httplib
-
-logging.basicConfig()
-
-class httpConnectException (Exception):
- pass
-
-class httpUpdater(DsaUpdater):
-
- host = 'htttp://server'
- conn = None
-
- dirs = []
- result = []
-
- curdir = '/'
- curfile = None
-
- month = {'Jan' : 1, 'Feb' : 2, 'Mar' : 3, 'Apr' : 4, 'May' : 5, 'Jun' : 6,
- 'Jul' : 7, 'Aug' : 8, 'Sep' : 9, 'Oct' : 10, 'Nov' : 11, 'Dec' : 12}
-
- def __init__ (self, source, storage, server):
- DsaUpdater.__init__(self, source, storage)
- try:
- self.host = server
- self.conn = httplib.HTTPConnection(self.host)
- except Exception:
- raise httpConnectException
-
- def __parse(self, data):
- mtime = None
- type = None
-
- paternDIR = re.compile(r'<td><a href="\d+/">(\d+/)</a></td>.*>(\d+)\-(\w+)\-(\d+) (\d+:\d+) *</td>')
- paternFILE = re.compile(r'<td><a href="[\w\d\.\-]+">(dsa\-\d+\.(wml|data))</a></td>.*>(\d+)\-(\w+)\-(\d+) (\d+:\d+) *</td>')
-
- for line in data.split('\n'):
- mtime = None
- type = None
-
- result = paternDIR.search(line)
- if result:
- type = 'dir'
- file = result.groups()[0]
- day = int(result.groups()[1])
- month = self.month[result.groups()[2]]
- year = int(result.groups()[3])
- (hour, min) = result.groups()[4].split(':')
- mtime = datetime(year, month, day, int(hour), int(min), 0)
- else:
- result = paternFILE.search(line)
- if result:
- type = 'file'
- file = result.groups()[0]
- day = int(result.groups()[2])
- month = self.month[result.groups()[3]]
- year = int(result.groups()[4])
- (hour, min) = result.groups()[5].split(':')
- mtime = datetime(year, month, day, int(hour), int(min), 0)
-
- if mtime:
- logging.critical ('%s %s with mtime %s vs %s' % (type, file, mtime, self.actual))
- if mtime > self.actual:
- if type == 'file':
- self.result.append(self.curdir+os.sep+file)
- else:
- if type == 'dir':
- self.dirs.append(file)
- else:
- logging.critical('Unknown file type: %s' % type)
- else:
- pass
- #logging.critical('Bad line format: %s' % line)
-
- def __writer (self, data):
- file = open (self.curfile, 'w')
- file.write(data)
- file.close()
-
- def cmpdir (self):
-
- self.dirs = []
- logging.critical('LIST %s' % self.curdir)
- self.conn.request('GET',self.curdir)
- self.__parse(self.conn.getresponse().read())
-
- if self.dirs:
- dirs = self.dirs[:]
- for dir in dirs:
- self.curdir += '/%s' % dir
- self.cmpdir()
- self.curdir = os.path.split(self.curdir)[0]
- self.curdir = os.path.split(self.curdir)[0]
-
- def syncfile (self, dir, file):
-
- if dir:
- path = self.dsaStorage + os.sep + dir
-
- if os.access(path, os.W_OK) and os.path.isdir (path):
- self.curfile = '%s/%s/%s' % (self.dsaStorage, dir, file)
- logging.critical('sync %s' % (path+os.sep+file))
- self.conn.request('GET', '%s' % (self.dsaSource+os.sep+dir+os.sep+file))
- data = self.conn.getresponse().read()
- self.__writer(data)
- else:
- os.mkdir(path)
- logging.critical('sync dir %s' % path)
- self.syncfile(dir, file)
- else:
- self.curfile = self.dsaStorage+os.sep+file
- self.conn.request('GET', '%s' % (self.dsaSource+os.sep+file))
- data = self.conn.getresponse().read()
- self.__writer(data)
-
- def syncdirs (self):
- for path in self.result:
- file = path[len(self.dsaSource):]
- (dir, file) = os.path.split(file)
- self.syncfile (dir, file)
-
- def sync(self):
- logging.critical('Syncing %s with http://%s%s' % (self.dsaStorage, self.host, self.dsaSource))
- self.curdir = self.dsaSource
- self.cmpdir ()
-
- if self.result:
- self.syncdirs ()
-
-if __name__ == '__main__':
- try:
- upd = httpUpdater('/~blaze/debian/dsa/', '/tmp/dsa', 'server')
- upd.sync()
- except httpConnectException:
- logging.critical('Http server not available.')
\ No newline at end of file
Copied: trunk/oval-server/dsaSync/sync.py (from rev 155, trunk/oval-server/src/dsaSync/sync.py)
===================================================================
--- trunk/oval-server/dsaSync/sync.py (rev 0)
+++ trunk/oval-server/dsaSync/sync.py 2007-08-20 04:31:31 UTC (rev 156)
@@ -0,0 +1,49 @@
+from datetime import datetime
+import logging
+from stat import *
+import re
+import os
+
+class DsaSync:
+
+ def __init__ (self, source, storage, logger = None):
+ self.dsaSource = source
+ self.dsaStorage =storage
+ if logger:
+ self.logger = logger
+ else:
+ self.logger = logging.basicConfig
+ self.getLastUpdateDate()
+
+ def getLastUpdateDate (self):
+ time = datetime(1990, 1, 1, 00, 00, 00)
+
+ if (os.access(self.dsaStorage, os.R_OK)):
+ for path in os.listdir(self.dsaStorage):
+ mtime = datetime.fromtimestamp(os.stat(self.dsaStorage+os.sep+path)[ST_MTIME])
+ if mtime > time and os.path.isfile(path):
+ time = mtime
+ else:
+ os.mkdir(self.dsaStorage)
+ self.actual = time
+ self.logger.debug('dsaSync: actual set to %s' % self.actual)
+
+ def syncfile (self, dir, file):
+ from dba import dba
+ db = dba.dba ('/tmp/oval-server.db')
+
+ if dir:
+ path = self.dsaStorage + os.sep + dir + os.sep + file
+ else:
+ path = self.dsaSource+os.sep+file
+ pattern = re.compile(r'dsa\-(\d{1,5})\.data')
+ result = pattern.search (file)
+ if result:
+ db.updateDSA(int(result.groups()[0]), path, datetime.now().strftime('%Y-%m-%d %H:%M'))
+
+ def syncdirs (self):
+ for path in self.result:
+ file = path[len(self.dsaSource):]
+ (dir, file) = os.path.split(file)
+ self.syncfile (dir, file)
+ self.logger.info('directorySync: synced %d files' % len(self.result))
\ No newline at end of file
More information about the Oval-commits
mailing list