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