# portage_contents.py -- (Persistent) Contents File Management # Copyright 1998-2004 Gentoo Foundation # Distributed under the terms of the GNU General Public License v2 # $Id: /var/cvsroot/gentoo-src/portage/pym/portage_contents.py,v 1.3.2.1 2005/01/16 02:35:33 carpaski Exp $ import os,string,types,sys,copy import portage_exception import portage_const #import gettext #gettext_t = gettext.translation('portage.contents', portage_const.LOCALE_DATA_PATH) #_ = gettext_t.ugettext def _(mystr): return mystr FILES_KEY = "\0FILES\0" OWNER_KEY = "\0OWNER\0" def ContentsHandler(filename): infile = open(filename) myfiles = [] mydirs = [] mylines = infile.readlines() infile.close() for line in mylines: if line[-1] == '\n': line = line[:-1] parts = string.split(line) mytype = parts[0] mytarget = None if mytype in ["dir","dev","fif"]: mypath = string.join(parts[1:]) elif mytype == "obj": mypath = string.join(parts[1:-2]) elif mytype == "sym": sl = string.join(parts[1:-1]) sl = string.split(sl, " -> ") mypath = sl[0] mytarget = sl[1] else: print _("Unknown type:"),mytype if mytype in ["dir"]: mydirs.append(mypath) else: myfiles.append(mypath) mydirs.sort() myfiles.sort() return myfiles,mydirs class PathLookupTable: """Creates a temporary lookup table for paths from files.""" def __init__(self,dbname): #if not self.validLocation(dbname): # raise portage_exception.InvalidLocation, dbname #self.base = copy.deepcopy(dbname) self.files = [] self.pathtree = {} def addFromFile(self, filename, handler): if type(handler) != types.FunctionType: raise portage_exception.IncorrectParameter, _("Handler of type '%(type)s' not 'function'") % {"type": type(handler)} filelist,dirlist = handler(filename) filestat = os.stat(filename) if type(filelist) != types.ListType: raise portage_exception.InvalidDataType, _("%(handler)s returned an invalid file list") % {"handler": handler.__name__} if type(dirlist) != types.ListType: raise portage_exception.InvalidDataType, _("%(handler)s returned an invalid directory list") % {"handler": handler.__name__} for x in filelist: if not x: continue x = os.path.normpath(x) if len(x) > 1: if x[:2] == "//": x = x[1:] if type(x) != types.StringType: raise portage_exception.InvalidDataType, _("%(handler)s returned an invalid subelement in dataset") % {"handler": handler.__name__} xs = string.split(x, "/") self.addFilePath(xs,filename) for x in dirlist: if not x: continue x = os.path.normpath(x) if len(x) > 1: if x[:2] == "//": x = x[1:] if type(x) != types.StringType: raise portage_exception.InvalidDataType, _("%(handler)s returned an invalid subelement in dataset") % {"handler": handler.__name__} xs = string.split(x, "/") self.addDirectoryPath(xs,filename) def addDirectoryPath(self,split_path, owner): pt = self.pathtree for x in split_path: if x not in pt.keys(): pt[x] = {FILES_KEY:{},OWNER_KEY:[]} if owner not in pt[x][OWNER_KEY]: pt[x][OWNER_KEY].append(owner[:]) pt = pt[x] return pt def addFilePath(self,split_path, owner): pt = self.addDirectoryPath(split_path[:-1], owner) if split_path[-1] not in pt[FILES_KEY]: pt[FILES_KEY][split_path[-1][:]] = [] if owner not in pt[FILES_KEY][split_path[-1][:]]: pt[FILES_KEY][split_path[-1][:]].append(owner[:]) def whoProvides(self,path): if type(path) != types.StringType: raise portage_exception.InvalidData, _("Path passed is not a string: %(path)s") % {"path": path} x = os.path.normpath(path) if x[0:2] == '//': x = x[1:] xs = x.split("/") pt = self.pathtree final_dir = xs.pop(-1) for subpath in xs: if subpath in pt.keys(): pt = pt[subpath] owners = [] if final_dir in pt[FILES_KEY]: for x in pt[FILES_KEY][final_dir]: if x not in owners: owners.append(x[:]) if final_dir in pt: for x in pt[final_dir][OWNER_KEY]: if x not in owners: owners.append(x[:]) return owners def test(): import os plt = PathLookupTable("spork") for x in os.listdir("/var/db/pkg"): for y in os.listdir("/var/db/pkg/"+x): c_path = "/var/db/pkg/"+x+"/"+y+"/CONTENTS" if os.path.exists(c_path): plt.addFromFile(c_path, ContentsHandler) print "/bin/bash:", plt.whoProvides("/bin/bash") print "/var/spool:", plt.whoProvides("/var/spool") print "/etc/init.d", plt.whoProvides("/etc/init.d") return plt