summaryrefslogtreecommitdiff
blob: 7fa76ee1433ec646bba8893c8d0d690a2ff6d769 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
#!/usr/bin/python -O
# Copyright 1999-2004 Gentoo Foundation
# Distributed under the terms of the GNU General Public License v2
# $Header: /local/data/ulm/cvs/history/var/cvsroot/gentoo-src/portage/bin/fixvardbentries,v 1.4 2004/10/11 04:01:00 jstubbs Exp $

import os
import sys

def fix_entries(path):
	path += "/"
	
	# Find the ebuild
	contents = os.listdir(path)
	ebuild = None
	for fn in contents:
		if fn[-7:] == ".ebuild":
			ebuild = fn
			break
	if ebuild is None:
		print "missing ebuild in",path
		return
	
	# Read it
	ebuildfile = open(path+ebuild)
	orig = ebuildfile.readlines()
	ebuildfile.close()
	
	# Quickly check it
	if "\1" not in " ".join(orig):
		return False
	
	# Read the original environment
	if "environment.bz2" in contents:
		os.system("bzip2 -dk "+path+"environment.bz2")
	elif "environment" in contents:
		os.system("bzip2 -zk "+path+"environment")
	else:
		print "environement.bz2 missing!"
		print "Please find and remove ^A occurences manually"
		print "or replace the ebuild with one from your portage"
		print "tree as a last resort."
		return False
	try:
		envfile = open(path+"environment")
	except SystemExit, e:
		raise  # this needs to be propogated
	except:
		print "environment.bz2 corrupt!"
		print "There is no way to fix this ebuild automatically."
		print "Try editing the ebuild to remove any ^A occurrences,"
		print 'possible replacing them with `"`, or copy an ebuild'
		print "of the same version (if possible) from the portage tree."
		print
		return False
	lines = envfile.readlines()
	envfile.close()
	os.remove(path+"environment")
	
	# Parse it
	env = {}
	for line in lines:
		line = " ".join(line.split())
		values = line.split("=")
		if len(values) == 1:
			break
		key = values[0]
		value = "=".join(values[1:])
		if value and value[0] == "$":
			value = value[1:]
		if value and value[0] == "'":
			value = value[1:-1]
		value = value.replace("\\n","\n")
		value = value.replace("\\t","\t")
		env[key] = value
	
	# Revert the *DEPEND files to their originals
	for key in ["DEPEND","RDEPEND","PDEPEND"]:
		if not env.has_key(key):
			env[key] = ""
		f = open(path+key, "w")
		f.write(env[key])
		f.close()
	
	# Check and fix unbalanced quotes
	quotecount = 0
	for l in orig:
		quotecount += l.count('"')
	if (quotecount % 2):
		for x in range(len(orig)-1,-1,-1):
			if "\1" in orig[x]:
				for y in range(len(orig[x])-1,-1,-1):
					if orig[x][y]=="\1":
                                                orig[x] = orig[x][:y] + '"' + orig[x][y+1:]
						break
				break
	
	# Replace *DEPEND in the ebuild with their originals
	fixed = []
	x=0
	while x != len(orig):
		for key in ["DEPEND","RDEPEND","PDEPEND"]:
			if orig[x].startswith(key):
				quotes = 0
				while quotes != 2:
					if x >= len(orig):
						print "Definate bug"
						print "Please attach ebuild",ebuild,"to bug 46096"
						print
						return False
					if not orig[x]:
						print "Possible bug - if the original ebuild you see both DEPEND and RDEPEND"
						print "in the following but the 'fixed' ebuild doesn't have both then please"
						print "attach",ebuild,"to bug 46096 with the following output:"
						print orig
						print
						continue
					quotes += orig[x].count('"')
					if quotes == 2:
						break
					if quotes > 2:
						print "Unfixable ebuild",ebuild
						print "Please attach it to bug 46906"
						print
						return False
					x += 1
				fixed += [key+'="'+env[key]+'"\n']
				x += 1
				break
		if x != len(orig):
			fixed += orig[x]
			x += 1
	ebuildfile = open(path+ebuild,"w")
	ebuildfile.writelines(fixed)
	ebuildfile.close()
	
	if "\1" in " ".join(fixed):
		print "Partially Fixed... see below"
	else:
		print "Fixed"

	return True


vardb = "/var/db/pkg/"
changed = False
for cat in os.listdir(vardb):
	if os.path.isdir(vardb+cat):
		for pkg in os.listdir(vardb+cat):
			if pkg[0] != "-" and os.path.isdir(vardb+cat+"/"+pkg):
				changed = (changed or fix_entries(vardb+cat+"/"+pkg))

if changed:
	
	print "Any ebuilds that were partially fixed can not be fixed any further"
	print "by this script or possible any other. Unmerging the package will"
	print "more than likely work. If it doesn't, however, try editing the"
	print "ebuild to leave only the pkg_prerm and pkg_postrm functions (if"
	print "they exist) or copying an ebuild - even of a different version -"
	print "from the main portage tree."

	import portage
	if portage.mtimedb.has_key("updates"):
		del portage.mtimedb["updates"]

else:
	print "No corruption found!"