Fix automatic sys.path insertions so that they're relative instead of absolute hard...
[portage.git] / bin / archive-conf
1 #!/usr/bin/python
2 # Copyright 1999-2006 Gentoo Foundation
3 # Distributed under the terms of the GNU General Public License v2
4 # $Id$
5
6 #
7 # archive-conf -- save off a config file in the dispatch-conf archive dir
8 #
9 #  Written by Wayne Davison <gentoo@blorf.net> with code snagged from
10 #  Jeremy Wohl's dispatch-conf script and the portage chkcontents script.
11 #
12
13 import os, sys
14 try:
15     import portage
16 except ImportError:
17         from os import path as osp
18         sys.path.insert(0, osp.join(osp.dirname(osp.dirname(__file__)), "pym"))
19     import portage
20
21 import dispatch_conf
22
23 FIND_EXTANT_CONTENTS  = "find %s -name CONTENTS"
24
25 MANDATORY_OPTS  = [ 'archive-dir' ]
26
27 try:
28     import fchksum
29     def perform_checksum(filename): return fchksum.fmd5t(filename)
30 except ImportError:
31     import md5
32     def md5_to_hex(md5sum):
33         hexform = ""
34         for ix in xrange(len(md5sum)):
35             hexform = hexform + "%02x" % ord(md5sum[ix])
36         return hexform.lower()
37     
38     def perform_checksum(filename):
39         f = open(filename, 'rb')
40         blocksize=32768
41         data = f.read(blocksize)
42         size = 0L
43         sum = md5.new()
44         while data:
45             sum.update(data)
46             size = size + len(data)
47             data = f.read(blocksize)
48         return (md5_to_hex(sum.digest()),size)
49
50 def archive_conf():
51     args = []
52     content_files = []
53     md5_match_hash = {}
54
55     options = portage.dispatch_conf.read_config(MANDATORY_OPTS)
56
57     for conf in sys.argv[1:]:
58         if not os.path.isabs(conf):
59             conf = os.path.abspath(conf)
60         args += [ conf ]
61         md5_match_hash[conf] = ''
62
63     # Find all the CONTENT files in VDB_PATH.
64     content_files += os.popen(FIND_EXTANT_CONTENTS % (portage.root+portage.VDB_PATH)).readlines()
65
66     # Search for the saved md5 checksum of all the specified config files
67     # and see if the current file is unmodified or not.
68     try:
69         todo_cnt = len(args)
70         for file in content_files:
71             file = file.rstrip()
72             try:
73                 contents = open(file, "r")
74             except IOError, e:
75                 print >> sys.stderr, 'archive-conf: Unable to open %s: %s' % (file, e)
76                 sys.exit(1)
77             lines = contents.readlines()
78             for line in lines:
79                 items = line.split()
80                 if items[0] == 'obj':
81                     for conf in args:
82                         if items[1] == conf:
83                             stored = items[2].lower()
84                             real = perform_checksum(conf)[0].lower()
85                             if stored == real:
86                                 md5_match_hash[conf] = conf
87                             todo_cnt -= 1
88                             if todo_cnt == 0:
89                                 raise "Break"
90     except "Break":
91         pass
92
93     for conf in args:
94         archive = os.path.join(options['archive-dir'], conf.lstrip('/'))
95         if options['use-rcs'] == 'yes':
96             portage.dispatch_conf.rcs_archive(archive, conf, md5_match_hash[conf], '')
97             if md5_match_hash[conf]:
98                 portage.dispatch_conf.rcs_archive_post_process(archive)
99         else:
100             portage.dispatch_conf.file_archive(archive, conf, md5_match_hash[conf], '')
101             if md5_match_hash[conf]:
102                 portage.dispatch_conf.file_archive_post_process(archive)
103
104 # run
105 if len(sys.argv) > 1:
106     archive_conf()
107 else:
108     print >> sys.stderr, 'Usage: archive-conf /CONFIG/FILE [/CONFIG/FILE...]'