blob: 8a866aa6b8dc374da22fc0274b099f6a36be0b26 [file] [log] [blame]
#
# Licensed to the Apache Software Foundation (ASF) under one
# or more contributor license agreements. See the NOTICE file
# distributed with this work for additional information
# regarding copyright ownership. The ASF licenses this file
# to you under the Apache License, Version 2.0 (the
# "License"); you may not use this file except in compliance
# with the License. You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing,
# software distributed under the License is distributed on an
# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
# KIND, either express or implied. See the License for the
# specific language governing permissions and limitations
# under the License.
#
from sys import argv
from os import popen
from os import popen4
from os import spawnl
from os.path import isdir
from os.path import walk
from os.path import split
from os.path import splitext
from os.path import exists
from tempfile import mkdtemp
from os.path import join
from os import listdir
from os import rmdir
from os import makedirs
from shutil import rmtree
import md5
import sha
class UserAbortError(Exception):
def __str__(self):
return "Aborted by user. Bye."
def matchExtension(file, dir, extension):
matches = []
extension = '.' + extension.lower()
for element in listdir(dir):
root, ext = splitext(element)
if extension == ext.lower() and root == file:
matches.append(element)
return matches
def printMatches(file, dir, extension):
matches = matchExtension(file, dir, extension)
for match in matches:
matchFile = open(join(dir,match), 'r')
text = matchFile.read();
matchFile.close()
print text
def untgz(file, dir):
popen("tar -xzf " + file + " -C " + dir)
def unzip(file, dir):
popen("unzip -d " + dir + " " + file)
def checkSums(filename, dir):
file = open(join(dir, filename), 'r')
contents = file.read()
file.close()
md5sum = md5.new()
md5sum.update(contents)
print "MD5:"
print md5sum.hexdigest()
printMatches(filename, dir, "MD5")
shaSum = sha.new()
shaSum.update(contents)
print "SHA1:"
print shaSum.hexdigest()
printMatches(filename, dir, "SHA")
printMatches(filename, dir, "SHA1")
def checkSignature(filename, dir, gpgCommand):
file = join(dir, filename)
signatureFile = file + '.asc'
if not(exists(signatureFile)):
signatureFile = file + '.sig'
if not(exists(signatureFile)):
print "SIGNATURE IS MISSING"
command = gpgCommand + ' --verify ' + signatureFile + ' ' + file
input, output = popen4(command)
print output.read()
def rat(file, dir, uncompress, ratCommand, baseReportDirectory):
if baseReportDirectory == None:
reportdir = mkdtemp()
else:
reportdir = join(baseReportDirectory, file.replace('.', '_'))
if exists(reportdir):
rmtree(reportdir)
makedirs(reportdir)
uncompress(join(dir, file), reportdir)
command = ratCommand + " " + reportdir
input, output = popen4(command)
out = output.read()
if not baseReportDirectory == None:
f = open(join(baseReportDirectory, file + '.rat'), 'w')
f.write(out)
f.close()
print out
def checkArchive(file, dir, uncompress, ratCommand, gpgCommand, baseReportDirectory):
print "."
print "."
print "."
print "###################################################"
print "Checking ", file
checkSums(file, dir)
checkSignature(file, dir, gpgCommand)
rat(file, dir, uncompress, ratCommand, baseReportDirectory)
print "###################################################"
print "."
print "."
print "."
def checkFile(file, dir, ratCommand, gpgCommand, baseReportDirectory):
'''Checks the given file'''
if file.endswith('.jar'):
print "Checking jar ", file
checkArchive(file, dir, lambda a,b:unzip(a,b), ratCommand, gpgCommand, baseReportDirectory)
elif file.endswith('.zip'):
print "Checking zip ", file
checkArchive(file, dir, lambda a,b:unzip(a,b), ratCommand, gpgCommand, baseReportDirectory)
elif file.endswith('.tar.gz') or file.endswith('.tgz'):
print "Checking tgz ", file
checkArchive(file, dir, lambda a,b:untgz(a,b), ratCommand, gpgCommand, baseReportDirectory)
def ignoreDirectory(dir):
'''Is this directory to be ignored?'''
if dir == "":
return False
else:
head, tail = split(dir)
if tail.startswith('.') and not(tail.startswith('..')):
return True
elif tail == "":
return False
else:
return ignoreDirectory(head)
def checkDirectory(ratCommand, gpgCommand, dir, files, baseReportDir, check=lambda a,b,c,d: lambda x: checkFile(x,a,b,c,d)):
'''Checks a directory'''
if not(ignoreDirectory(dir)):
print 'Checking directory ', dir
map(check(dir, ratCommand, gpgCommand, baseReportDir), files)
def walkDirectories(base, ratCommand, gpgCommand, baseReportDir = None, f=lambda a,b,c,d,e: checkDirectory(a,b,c,d,e)):
'''Traverses directories under base and executes checks'''
print 'Starting traversal at ', base
walk(base, lambda dummy, dir, files: f(ratCommand, gpgCommand, dir, files, baseReportDir), None)
def enterRatCommand(rat = None):
'''If necessary, prompts user for an acceptable Rat command'''
if rat == None:
try:
rat = raw_input("Please enter Rat command (including path): ")
except EOFError:
raise UserAbortError()
if rat == "":
print "Rat command is required"
rat = enterRatCommand()
ratResult = popen(rat).close()
if not(ratResult == None):
print "Cannot execute " + rat
rat = enterRatCommand()
return rat
def enterBaseDirectory(base = None):
'''If necessary prompts user for an acceptable base directory'''
if base == None:
try:
base = raw_input("Please enter base directory for recursive traversal: ")
except EOFError:
raise UserAbortError()
if not(isdir(base)):
print "'" + base + "' is not a directory."
base = enterBaseDirectory()
return base
def enterGPGCommand(gpgCommand = None):
'''If necessary prompts user for the command used to test signatures'''
if gpgCommand == None:
try:
gpgCommand = raw_input("GnuPG is required. Please enter GPG command: ")
except EOFError:
raise UserAbortError()
result = popen(gpgCommand + " --version").close()
if not(result == None):
print "Cannot execute " + gpgCommand
rat = enterGPGCommand()
return gpgCommand
def getRatCommand():
'''Gets an acceptable value for the Rat command'''
if len(argv) == 1:
ratCommand = enterRatCommand()
else:
ratCommand = enterRatCommand(argv[1])
return ratCommand
def getBaseDirectory():
'''Gets an acceptable value for the base directory'''
if len(argv) < 3:
base = enterBaseDirectory()
else:
base = enterBaseDirectory(argv[2])
return base
def getGPGCommand():
'''Gets an acceptable value for the command used to test signatures'''
if len(argv) < 5:
gpgCommand = enterGPGCommand('gpg')
else:
gpgCommand = enterGPGCommand(argv[4])
return gpgCommand
def getBaseReportDirectory():
if len(argv) < 4:
return None
else:
return argv[3]
def checkArgs(f=lambda a,b,c,d: walkDirectories(a, b, c, d)):
'''Prompts user for arguments missing from the command line. Check argument values.'''
try:
ratCommand = getRatCommand()
base = getBaseDirectory()
gpgCommand = getGPGCommand()
baseReportDirectory = getBaseReportDirectory()
f(base, ratCommand, gpgCommand, baseReportDirectory)
except UserAbortError, e:
print '\n'
print e
checkArgs()