#!/usr/bin/env python # verify.py Version 0.1 2009-10-18 # # under the WTFPL. see http://sam.zoy.org/wtfpl/ # # DO WHAT THE FUCK YOU WANT TO PUBLIC LICENSE # Version 2, December 2004 # # Copyright (C) 2006 solsTiCe d'Hiver # Everyone is permitted to copy and distribute verbatim or modified # copies of this license document, and changing it is allowed as long # as the name is changed. # # DO WHAT THE FUCK YOU WANT TO PUBLIC LICENSE # TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION # # 0. You just DO WHAT THE FUCK YOU WANT TO. '''a python script that compare the files in a package tarball and the files installed on the system: It reports changed files, missing files''' import tarfile import hashlib from sys import argv, exit, stderr from os.path import exists, basename DB = '/var/lib/pacman' # TODO: use logging module ? def error(s): stderr.write('Error: %s\n' % s) def warning(s): stderr.write('Warning: %s\n' % s) def getpkgname(pkgfile): '''return package name from its pkgfilename''' pkg = basename(pkgfile.rstrip('.pkg.tar.gz')) pkg = pkg[:pkg.rfind('-')] return pkg def ispkginstalled(pkgfile): '''return wether or not a package is installed''' pkg = getpkgname(pkgfile) return exists('/'.join([DB, 'local', pkg])) def checkpkg(pkgfile): '''check if the installed files of a package have changed compared to the files in the package tarball''' missing = 0 changed = 0 md5s = md5pkg(pkgfile) for filename,md5 in md5s.items(): ff = '/' + filename if exists(ff): with open(ff) as g: if hashlib.md5(g.read()).hexdigest() != md5: warning('%s has changed' % filename) changed += 1 else: warning('%s has not been found' % ff) missing += 1 return (len(md5s), changed, missing) def md5pkg(pkgfile): '''return a dictionary of filename and md5 of the package''' tf = tarfile.open(pkgfile, 'r') md5s = {} for ti in tf: if ti.isfile() and ti.name not in ('.PKGINFO', '.INSTALL', '.CHANGELOG'): f = tf.extractfile(ti) md5s[ti.name] = hashlib.md5(f.read()).hexdigest() f.close() tf.close() return md5s if __name__ == '__main__': try: for pkg in argv[1:]: if not exists(pkg): error('%s not found' % pkg) continue if not ispkginstalled(pkg): error('%s is not installed' % basename(pkg.rstrip('.pkg.tar.gz'))) continue (n,c,m) = checkpkg(pkg) print '%s: %d files, %d changed, %d missing' % (getpkgname(pkg), n, c, m) except KeyboardInterrupt: pass