summaryrefslogtreecommitdiff
blob: e8c419ba317a722f502fe39b9e16cd1ec7168434 (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
# 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 $
cvs_id_string="$Id: portage_contents.py,v 1.3.2.1 2005/01/16 02:35:33 carpaski Exp $"[5:-2]

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