#!/usr/bin/python -O # arch-tag: c2d62f90-d585-4f81-b92b-8588b9238e58 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: 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!"