diff options
Diffstat (limited to 'bin/fix-db.py')
-rwxr-xr-x | bin/fix-db.py | 175 |
1 files changed, 175 insertions, 0 deletions
diff --git a/bin/fix-db.py b/bin/fix-db.py new file mode 100755 index 000000000..d185580fa --- /dev/null +++ b/bin/fix-db.py @@ -0,0 +1,175 @@ +#!/usr/bin/python +# Copyright 1999-2004 Gentoo Foundation +# Distributed under the terms of the GNU General Public License v2 +# $Header: /var/cvsroot/gentoo-src/portage/bin/fix-db.py,v 1.8 2004/10/11 04:01:00 jstubbs Exp $ + +import os,sys,re +sys.path = ["/usr/lib/portage/pym"]+sys.path + +from stat import * +from output import * +from portage import lockfile,unlockfile,VDB_PATH,root + + +mylog = open("/var/log/emerge_fix-db.log", "a") +def writemsg(msg): + if msg[-1] != '\n': + msg += "\n" + sys.stderr.write(msg) + sys.stderr.flush() + mylog.write(msg) + mylog.flush() + +def fix_global_counter(value): + myf = open("/var/cache/edb/counter") + newvalue = value+1000 + myf.write(str(newvalue)) + myf.flush() + myf.close() + return newvalue + +bad = {} +counters = {} +times = {} + +try: + real_counter = long(open("/var/cache/edb/counter").read()) +except SystemExit, e: + raise # This needs to be propogated +except: + writemsg("ERROR: Real counter is invalid.\n") + real_counter = 0 + +vardbdir = root+VDB_PATH+"/" +for cat in os.listdir(vardbdir): + catdir = vardbdir+cat+"/" + if not os.path.isdir(catdir): + writemsg("Invalid file: '%s'\n" % catdir[:-1]) + continue + for pkg in os.listdir(catdir): + pkgdir = catdir+pkg+"/" + catpkg = cat+"/"+pkg + + if not os.path.isdir(catdir): + writemsg("Invalid file: '%s'\n" % pkgdir) + continue + + bad[catpkg] = [] + + pkgdirlist = os.listdir(pkgdir) + if not pkgdirlist: + writemsg("ERROR: Package directory is empty for '%s'\n" % catpkg) + writemsg(" Deleting this directory. Remerge if you want it back.\n") + os.rmdir(pkgdir) + del bad[catpkg] + continue + + if "CONTENTS" not in pkgdirlist: + bad[catpkg] += ["CONTENTS is missing"] + times[catpkg] = -1 + writemsg("ERROR: Contents file is missing from the package directory.\n") + writemsg(" '%s' is corrupt and should be deleted.\n" % catpkg) + else: + times[catpkg] = None + for line in open(pkgdir+"CONTENTS").readlines(): + mysplit = line.split() + if mysplit[0] == "obj": + try: + times[catpkg] = long(mysplit[-1]) + except SystemExit, e: + raise # This needs to be propogated + except: + times[catpkg] = -1 + bad[catpkg] += ["CONTENTS is corrupt"] + writemsg("ERROR: Corrupt CONTENTS file in '%s'\n" % catpkg) + writemsg(" This package should be deleted.\n") + break + if times[catpkg] == None: + times[catpkg] = os.stat(pkgdir+"CONTENTS")[ST_MTIME] + + if "COUNTER" not in pkgdirlist: + bad[catpkg] += ["COUNTER is missing"] + writemsg("ERROR: COUNTER file missing from '%s'.\n" % catpkg) + counters[catpkg] = -1 + else: + try: + counters[catpkg] = long(open(pkgdir+"COUNTER").read().strip()) + if counters[catpkg] > real_counter: + writemsg("ERROR: Global counter is lower than the '%s' COUNTER." % catpkg) + real_counter = fix_global_counter(counters[catpkg]) + except SystemExit, e: + raise # This needs to be propogated + except: + bad[catpkg] += ["COUNTER is corrupt"] + counters[catpkg] = -1 + + if "SLOT" not in pkgdirlist: + writemsg("ERROR: SLOT file missing from '%s'.\n" % catpkg) + writemsg(" RE-MERGE this exact package version or unmerge and remerge.\n") + bad[catpkg] += ["SLOT is missing"] + else: + myslot = open(pkgdir+"SLOT").read() + if myslot and myslot[-1]=="\n": + #writemsg("WARN: SLOT file has a newline. '%s'\n" % catpkg) + myslot = myslot[:-1] + if not myslot: + bad[catpkg] += ["SLOT is empty"] + writemsg("ERROR: SLOT file is empty for '%s'.\n" % catpkg) + writemsg(" RE-MERGE this exact package version or unmerge and remerge it.\n") + elif re.search("[^-a-zA-Z0-9\._]", myslot): + bad[catpkg] += ["SLOT is corrupt"] + writemsg("ERROR: SLOT file is corrupt for '%s'.\n" % catpkg) + writemsg(" RE-MERGE this exact package version or unmerge and remerge it.\n") + elif myslot.strip() != myslot: + writemsg("WARN: SLOT file has invalid characters. '%s'\n" % catpkg) + bad[catpkg] += ["SLOT is invalid"] + + if not bad[catpkg]: + del bad[catpkg] + + +actions = {} +writemsg("\n\n") +for catpkg in bad.keys(): + bad[catpkg].sort() + + mystr = "" + for x in bad[catpkg]: + mystr += " "+str(x)+"\n" + + if bad[catpkg] == ["CONTENTS is missing", "SLOT is missing"]: + writemsg("%s: (possibly injected)\n%s\n" % (green(catpkg), mystr)) + actions[catpkg] = ["ignore"] + elif bad[catpkg] == ["SLOT is empty"]: + writemsg("%s: (old package) []\n%s\n" % (yellow(catpkg), mystr)) + actions[catpkg] = ["remerge"] + else: + writemsg("%s: (damaged/invalid) []\n%s\n" % (red(catpkg), mystr)) + actions[catpkg] = ["merge exact"] + +if (len(sys.argv) > 1) and (sys.argv[1] == "--fix"): + writemsg("These are only directions, at the moment.") + for catpkg in actions.keys(): + action = actions[catpkg] + writemsg("We will now '%s' '%s'..." % (action, catpkg)) + #if action == +else: + #writemsg("Run with '--fix' to attempt automatic correction.") + pass + + + + + + + + + + + + + + + + + |