| #!/usr/bin/python |
| # Copyright 1999-2006 Gentoo Foundation |
| # Distributed under the terms of the GNU General Public License v2 |
| |
| # |
| # archive-conf -- save off a config file in the dispatch-conf archive dir |
| # |
| # Written by Wayne Davison <gentoo@blorf.net> with code snagged from |
| # Jeremy Wohl's dispatch-conf script and the portage chkcontents script. |
| # |
| |
| from __future__ import print_function |
| |
| import 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 |
| |
| from portage import os |
| 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 range(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 = 0 |
| 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 % |
| (os.path.join(portage.settings['EROOT'], 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 as e: |
| print('archive-conf: Unable to open %s: %s' % (file, e), file=sys.stderr) |
| 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('Usage: archive-conf /CONFIG/FILE [/CONFIG/FILE...]', file=sys.stderr) |