2 # Copyright 1999-2004 Gentoo Foundation
3 # Distributed under the terms of the GNU General Public License v2
4 # $Header: /var/cvsroot/gentoo-src/portage/bin/fix-db.py,v 1.8 2004/10/11 04:01:00 jstubbs Exp $
7 sys.path = ["/usr/lib/portage/pym"]+sys.path
11 from portage import lockfile,unlockfile,VDB_PATH,root
14 mylog = open("/var/log/emerge_fix-db.log", "a")
23 def fix_global_counter(value):
24 myf = open("/var/cache/edb/counter")
26 myf.write(str(newvalue))
36 real_counter = long(open("/var/cache/edb/counter").read())
38 raise # This needs to be propogated
40 writemsg("ERROR: Real counter is invalid.\n")
43 vardbdir = root+VDB_PATH+"/"
44 for cat in os.listdir(vardbdir):
45 catdir = vardbdir+cat+"/"
46 if not os.path.isdir(catdir):
47 writemsg("Invalid file: '%s'\n" % catdir[:-1])
49 for pkg in os.listdir(catdir):
50 pkgdir = catdir+pkg+"/"
53 if not os.path.isdir(catdir):
54 writemsg("Invalid file: '%s'\n" % pkgdir)
59 pkgdirlist = os.listdir(pkgdir)
61 writemsg("ERROR: Package directory is empty for '%s'\n" % catpkg)
62 writemsg(" Deleting this directory. Remerge if you want it back.\n")
67 if "CONTENTS" not in pkgdirlist:
68 bad[catpkg] += ["CONTENTS is missing"]
70 writemsg("ERROR: Contents file is missing from the package directory.\n")
71 writemsg(" '%s' is corrupt and should be deleted.\n" % catpkg)
74 for line in open(pkgdir+"CONTENTS").readlines():
75 mysplit = line.split()
76 if mysplit[0] == "obj":
78 times[catpkg] = long(mysplit[-1])
80 raise # This needs to be propogated
83 bad[catpkg] += ["CONTENTS is corrupt"]
84 writemsg("ERROR: Corrupt CONTENTS file in '%s'\n" % catpkg)
85 writemsg(" This package should be deleted.\n")
87 if times[catpkg] == None:
88 times[catpkg] = os.stat(pkgdir+"CONTENTS")[ST_MTIME]
90 if "COUNTER" not in pkgdirlist:
91 bad[catpkg] += ["COUNTER is missing"]
92 writemsg("ERROR: COUNTER file missing from '%s'.\n" % catpkg)
96 counters[catpkg] = long(open(pkgdir+"COUNTER").read().strip())
97 if counters[catpkg] > real_counter:
98 writemsg("ERROR: Global counter is lower than the '%s' COUNTER." % catpkg)
99 real_counter = fix_global_counter(counters[catpkg])
100 except SystemExit, e:
101 raise # This needs to be propogated
103 bad[catpkg] += ["COUNTER is corrupt"]
104 counters[catpkg] = -1
106 if "SLOT" not in pkgdirlist:
107 writemsg("ERROR: SLOT file missing from '%s'.\n" % catpkg)
108 writemsg(" RE-MERGE this exact package version or unmerge and remerge.\n")
109 bad[catpkg] += ["SLOT is missing"]
111 myslot = open(pkgdir+"SLOT").read()
112 if myslot and myslot[-1]=="\n":
113 #writemsg("WARN: SLOT file has a newline. '%s'\n" % catpkg)
116 bad[catpkg] += ["SLOT is empty"]
117 writemsg("ERROR: SLOT file is empty for '%s'.\n" % catpkg)
118 writemsg(" RE-MERGE this exact package version or unmerge and remerge it.\n")
119 elif re.search("[^-a-zA-Z0-9\._]", myslot):
120 bad[catpkg] += ["SLOT is corrupt"]
121 writemsg("ERROR: SLOT file is corrupt for '%s'.\n" % catpkg)
122 writemsg(" RE-MERGE this exact package version or unmerge and remerge it.\n")
123 elif myslot.strip() != myslot:
124 writemsg("WARN: SLOT file has invalid characters. '%s'\n" % catpkg)
125 bad[catpkg] += ["SLOT is invalid"]
133 for catpkg in bad.keys():
137 for x in bad[catpkg]:
138 mystr += " "+str(x)+"\n"
140 if bad[catpkg] == ["CONTENTS is missing", "SLOT is missing"]:
141 writemsg("%s: (possibly injected)\n%s\n" % (green(catpkg), mystr))
142 actions[catpkg] = ["ignore"]
143 elif bad[catpkg] == ["SLOT is empty"]:
144 writemsg("%s: (old package) []\n%s\n" % (yellow(catpkg), mystr))
145 actions[catpkg] = ["remerge"]
147 writemsg("%s: (damaged/invalid) []\n%s\n" % (red(catpkg), mystr))
148 actions[catpkg] = ["merge exact"]
150 if (len(sys.argv) > 1) and (sys.argv[1] == "--fix"):
151 writemsg("These are only directions, at the moment.")
152 for catpkg in actions.keys():
153 action = actions[catpkg]
154 writemsg("We will now '%s' '%s'..." % (action, catpkg))
157 #writemsg("Run with '--fix' to attempt automatic correction.")