#!/usr/bin/python
# Copyright 1999-2006 Gentoo Foundation
# Distributed under the terms of the GNU General Public License v2
# $Id: archive-conf 5597 2007-01-12 08:19:46Z antarus $

#
# 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.
#

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 = 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 "Break"
    except "Break":
        pass

    for conf in args:
        archive = os.path.join(options['archive-dir'], conf.lstrip('/'))
        if options['use-rcs'] == 'yes':
            dispatch_conf.rcs_archive(archive, conf, md5_match_hash[conf], '')
            if md5_match_hash[conf]:
                dispatch_conf.rcs_archive_post_process(archive)
        else:
            dispatch_conf.file_archive(archive, conf, md5_match_hash[conf], '')
            if md5_match_hash[conf]:
                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...]'
