#!/usr/bin/python # Copyright 1999-2006 Gentoo Foundation # Distributed under the terms of the GNU General Public License v2 # $Id$ # # archive-conf -- save off a config file in the dispatch-conf archive dir # # Written by Wayne Davison with code snagged from # Jeremy Wohl's dispatch-conf script and the portage chkcontents script. # import os, sys try: import portage except ImportError: from os import path as osp sys.path.insert(0, osp.join(osp.dirname(osp.dirname(osp.realpath(__file__))), "pym")) import portage import dispatch_conf FIND_EXTANT_CONTENTS = "find %s -name CONTENTS" MANDATORY_OPTS = [ 'archive-dir' ] try: import fchksum def perform_checksum(filename): return fchksum.fmd5t(filename) except ImportError: import md5 def md5_to_hex(md5sum): hexform = "" for ix in xrange(len(md5sum)): hexform = hexform + "%02x" % ord(md5sum[ix]) return hexform.lower() def perform_checksum(filename): f = open(filename, 'rb') blocksize=32768 data = f.read(blocksize) size = 0L sum = md5.new() while data: sum.update(data) size = size + len(data) data = f.read(blocksize) return (md5_to_hex(sum.digest()),size) def archive_conf(): args = [] content_files = [] md5_match_hash = {} options = portage.dispatch_conf.read_config(MANDATORY_OPTS) for conf in sys.argv[1:]: if not os.path.isabs(conf): conf = os.path.abspath(conf) args += [ conf ] md5_match_hash[conf] = '' # Find all the CONTENT files in VDB_PATH. content_files += os.popen(FIND_EXTANT_CONTENTS % (portage.root+portage.VDB_PATH)).readlines() # Search for the saved md5 checksum of all the specified config files # and see if the current file is unmodified or not. try: todo_cnt = len(args) for file in content_files: file = file.rstrip() try: contents = open(file, "r") except IOError, e: print >> sys.stderr, 'archive-conf: Unable to open %s: %s' % (file, e) sys.exit(1) lines = contents.readlines() for line in lines: items = line.split() if items[0] == 'obj': for conf in args: if items[1] == conf: stored = items[2].lower() real = perform_checksum(conf)[0].lower() if stored == real: md5_match_hash[conf] = conf todo_cnt -= 1 if todo_cnt == 0: raise StopIteration() except StopIteration: pass for conf in args: archive = os.path.join(options['archive-dir'], conf.lstrip('/')) if options['use-rcs'] == 'yes': portage.dispatch_conf.rcs_archive(archive, conf, md5_match_hash[conf], '') if md5_match_hash[conf]: portage.dispatch_conf.rcs_archive_post_process(archive) else: portage.dispatch_conf.file_archive(archive, conf, md5_match_hash[conf], '') if md5_match_hash[conf]: portage.dispatch_conf.file_archive_post_process(archive) # run if len(sys.argv) > 1: archive_conf() else: print >> sys.stderr, 'Usage: archive-conf /CONFIG/FILE [/CONFIG/FILE...]'