Lines 7160-7165
Link Here
|
7160 |
This class provides an interface to the installed package database |
7160 |
This class provides an interface to the installed package database |
7161 |
At present this is implemented as a text backend in /var/db/pkg. |
7161 |
At present this is implemented as a text backend in /var/db/pkg. |
7162 |
""" |
7162 |
""" |
|
|
7163 |
|
7164 |
import re |
7165 |
_normalize_needed = re.compile(r'//|^[^/]|.+/$') |
7166 |
|
7163 |
def __init__(self, cat, pkg, myroot, mysettings, treetype=None, |
7167 |
def __init__(self, cat, pkg, myroot, mysettings, treetype=None, |
7164 |
vartree=None): |
7168 |
vartree=None): |
7165 |
""" |
7169 |
""" |
Lines 7293-7299
Link Here
|
7293 |
mylines=myc.readlines() |
7297 |
mylines=myc.readlines() |
7294 |
myc.close() |
7298 |
myc.close() |
7295 |
null_byte = "\0" |
7299 |
null_byte = "\0" |
7296 |
contents_file = os.path.join(self.dbdir, "CONTENTS") |
7300 |
normalize_needed = self._normalize_needed |
|
|
7301 |
myroot = self.myroot |
7302 |
if myroot == os.path.sep: |
7303 |
myroot = None |
7297 |
pos = 0 |
7304 |
pos = 0 |
7298 |
for line in mylines: |
7305 |
for line in mylines: |
7299 |
pos += 1 |
7306 |
pos += 1 |
Lines 7307-7314
Link Here
|
7307 |
# we do this so we can remove from non-root filesystems |
7314 |
# we do this so we can remove from non-root filesystems |
7308 |
# (use the ROOT var to allow maintenance on other partitions) |
7315 |
# (use the ROOT var to allow maintenance on other partitions) |
7309 |
try: |
7316 |
try: |
7310 |
mydat[1] = normalize_path(os.path.join( |
7317 |
if normalize_needed.match(mydat[1]): |
7311 |
self.myroot, mydat[1].lstrip(os.path.sep))) |
7318 |
mydat[1] = normalize_path(mydat[1]) |
|
|
7319 |
if not mydat[1].startswith(os.path.sep): |
7320 |
mydat[1] = os.path.sep + mydat[1] |
7321 |
if myroot: |
7322 |
mydat[1] = os.path.join(myroot, mydat[1].lstrip(os.path.sep)) |
7312 |
if mydat[0]=="obj": |
7323 |
if mydat[0]=="obj": |
7313 |
#format: type, mtime, md5sum |
7324 |
#format: type, mtime, md5sum |
7314 |
pkgfiles[" ".join(mydat[1:-2])]=[mydat[0], mydat[-1], mydat[-2]] |
7325 |
pkgfiles[" ".join(mydat[1:-2])]=[mydat[0], mydat[-1], mydat[-2]] |
Lines 7712-7720
Link Here
|
7712 |
|
7723 |
|
7713 |
def isowner(self,filename,destroot): |
7724 |
def isowner(self,filename,destroot): |
7714 |
""" |
7725 |
""" |
7715 |
Check if filename is a new file or belongs to this package |
7726 |
Check if a file belongs to this package. This may |
7716 |
(for this or a previous version) |
7727 |
result in a stat call for the parent directory of |
7717 |
|
7728 |
every installed file, since the inode numbers are |
|
|
7729 |
used to work around the problem of ambiguous paths |
7730 |
caused by symlinked directories. The results of |
7731 |
stat calls are cached to optimize multiple calls |
7732 |
to this method. |
7733 |
|
7718 |
@param filename: |
7734 |
@param filename: |
7719 |
@type filename: |
7735 |
@type filename: |
7720 |
@param destroot: |
7736 |
@param destroot: |
Lines 7731-7753
Link Here
|
7731 |
if pkgfiles and destfile in pkgfiles: |
7747 |
if pkgfiles and destfile in pkgfiles: |
7732 |
return True |
7748 |
return True |
7733 |
if pkgfiles: |
7749 |
if pkgfiles: |
|
|
7750 |
# Use stat rather than lstat since we want to follow |
7751 |
# any symlinks to the real parent directory. |
7752 |
parent_path = os.path.dirname(destfile) |
7734 |
try: |
7753 |
try: |
7735 |
mylstat = os.lstat(destfile) |
7754 |
parent_stat = os.stat(parent_path) |
7736 |
except EnvironmentError, e: |
7755 |
except EnvironmentError, e: |
7737 |
if e.errno != errno.ENOENT: |
7756 |
if e.errno != errno.ENOENT: |
7738 |
raise |
7757 |
raise |
7739 |
del e |
7758 |
del e |
7740 |
return True |
7759 |
return False |
7741 |
if self._contents_inodes is None: |
7760 |
if self._contents_inodes is None: |
7742 |
self._contents_inodes = set() |
7761 |
self._contents_inodes = {} |
|
|
7762 |
parent_paths = set() |
7743 |
for x in pkgfiles: |
7763 |
for x in pkgfiles: |
|
|
7764 |
p_path = os.path.dirname(x) |
7765 |
if p_path in parent_paths: |
7766 |
continue |
7767 |
parent_paths.add(p_path) |
7744 |
try: |
7768 |
try: |
7745 |
lstat = os.lstat(x) |
7769 |
s = os.stat(p_path) |
7746 |
self._contents_inodes.add((lstat.st_dev, lstat.st_ino)) |
|
|
7747 |
except OSError: |
7770 |
except OSError: |
7748 |
pass |
7771 |
pass |
7749 |
if (mylstat.st_dev, mylstat.st_ino) in self._contents_inodes: |
7772 |
else: |
7750 |
return True |
7773 |
inode_key = (s.st_dev, s.st_ino) |
|
|
7774 |
# Use lists of paths in case multiple |
7775 |
# paths reference the same inode. |
7776 |
p_path_list = self._contents_inodes.get(inode_key) |
7777 |
if p_path_list is None: |
7778 |
p_path_list = [] |
7779 |
self._contents_inodes[inode_key] = p_path_list |
7780 |
if p_path not in p_path_list: |
7781 |
p_path_list.append(p_path) |
7782 |
p_path_list = self._contents_inodes.get( |
7783 |
(parent_stat.st_dev, parent_stat.st_ino)) |
7784 |
if p_path_list: |
7785 |
basename = os.path.basename(destfile) |
7786 |
for p_path in p_path_list: |
7787 |
x = os.path.join(p_path, basename) |
7788 |
if x in pkgfiles: |
7789 |
return True |
7751 |
|
7790 |
|
7752 |
return False |
7791 |
return False |
7753 |
|
7792 |
|
Lines 7979-7989
Link Here
|
7979 |
print "Searching all installed packages for file collisions..." |
8018 |
print "Searching all installed packages for file collisions..." |
7980 |
print "Press Ctrl-C to Stop" |
8019 |
print "Press Ctrl-C to Stop" |
7981 |
print |
8020 |
print |
7982 |
""" Note: The isowner calls result in a stat call for *every* |
|
|
7983 |
single installed file, since the inode numbers are used to work |
7984 |
around the problem of ambiguous paths caused by symlinked files |
7985 |
and/or directories. Though it is slow, it is as accurate as |
7986 |
possible.""" |
7987 |
found_owner = False |
8021 |
found_owner = False |
7988 |
for cpv in self.vartree.dbapi.cpv_all(): |
8022 |
for cpv in self.vartree.dbapi.cpv_all(): |
7989 |
cat, pkg = catsplit(cpv) |
8023 |
cat, pkg = catsplit(cpv) |
Lines 8037-8051
Link Here
|
8037 |
" Add \"collision-protect\" to FEATURES in make.conf" + \ |
8071 |
" Add \"collision-protect\" to FEATURES in make.conf" + \ |
8038 |
" if you would like the merge to abort in cases like this." |
8072 |
" if you would like the merge to abort in cases like this." |
8039 |
if self.settings.get("PORTAGE_QUIET") != "1": |
8073 |
if self.settings.get("PORTAGE_QUIET") != "1": |
8040 |
msg += " If you have determined that one or more of the" + \ |
8074 |
msg += " You can use a command such as" + \ |
8041 |
" files actually belong to another installed package then" + \ |
8075 |
" \\`portageq owners / <filename>\\` to identify the" + \ |
8042 |
" go to http://bugs.gentoo.org and report it as a bug." + \ |
8076 |
" installed package that owns a file. If portageq" + \ |
8043 |
" Be sure to identify both this package and the other" + \ |
8077 |
" reports that only one package owns a file then do NOT" + \ |
8044 |
" installed package in the bug report. Use a command such" + \ |
8078 |
" file a bug report. A bug report is only useful if it" + \ |
8045 |
" as \\`equery belongs <filename>\\` to identify the" + \ |
8079 |
" identifies at least two or more packages that are known" + \ |
8046 |
" installed package that owns a file. Do NOT file a bug" + \ |
8080 |
" install the same file(s). If a collision occurs and you" + \ |
8047 |
" without reporting exactly which two packages install" + \ |
8081 |
" can not explain where the file came from then you" + \ |
8048 |
" the same file(s)." |
8082 |
" should simply ignore the collision since there is not" + \ |
|
|
8083 |
" enough information to determine if a real problem" + \ |
8084 |
" exists. Please do NOT file a bug report at" + \ |
8085 |
" http://bugs.gentoo.org unless you report exactly which" + \ |
8086 |
" two packages install the same file(s). Once again," + \ |
8087 |
" please do NOT file a bug report unless you have" + \ |
8088 |
" completely understood the above message." |
8049 |
|
8089 |
|
8050 |
self.settings["EBUILD_PHASE"] = "preinst" |
8090 |
self.settings["EBUILD_PHASE"] = "preinst" |
8051 |
cmd = "source '%s/isolated-functions.sh' ; " % PORTAGE_BIN_PATH |
8091 |
cmd = "source '%s/isolated-functions.sh' ; " % PORTAGE_BIN_PATH |