-#!/usr/bin/env python
+#!/usr/bin/python
# Copyright 2003-2005 Gentoo Foundation
# Distributed under the terms of the GNU General Public License v2
# $Header: $
+from __future__ import with_statement
###############################################################################
# Meta:
###############################################################################
# Python imports:
+
import sys
import os, stat
import re
# findDistfiles: find all obsolete distfiles.
# XXX: what about cvs ebuilds? i should install some to see where it goes...
def findDistfiles( \
+ myoptions, \
exclude_dict={}, \
destructive=False,\
fetch_restricted=False, \
package_names=False, \
time_limit=0, \
- size_limit=0):
+ size_limit=0,):
# this regexp extracts files names from SRC_URI. It is not very precise,
# but we don't care (may return empty strings, etc.), since it is fast.
file_regexp = re.compile('([a-zA-Z0-9_,\.\-\+\~]*)[\s\)]')
except KeyError: continue
del pkg_list
- # create a dictionary of files which should be deleted
+ # create a dictionary of files which should be deleted
+ if not (os.path.isdir(distdir)):
+ eerror("%s does not appear to be a directory." % distdir, myoptions['nocolor'])
+ eerror("Please set DISTDIR to a sane value.", myoptions['nocolor'])
+ eerror("(Check your /etc/make.conf and environment).", myoptions['nocolor'])
+ exit(1)
for file in os.listdir(distdir):
filepath = os.path.join(distdir, file)
try: file_stat = os.stat(filepath)
# XXX: packages are found only by symlinks. Maybe i should also return .tbz2
# files from All/ that have no corresponding symlinks.
def findPackages( \
+ myoptions, \
exclude_dict={}, \
destructive=False, \
time_limit=0, \
package_names=False):
clean_dict = {}
- # create a full package dictionnary
+ # create a full package dictionary
+
+ if not (os.path.isdir(pkgdir)):
+ eerror("%s does not appear to be a directory." % pkgdir, myoptions['nocolor'])
+ eerror("Please set PKGDIR to a sane value.", myoptions['nocolor'])
+ eerror("(Check your /etc/make.conf and environment).", myoptions['nocolor'])
+ exit(1)
for root, dirs, files in os.walk(pkgdir):
if root[-3:] == 'All': continue
for file in files:
del clean_dict[mycpv]
continue
if portage.cpv_getkey(mycpv) in cp_all:
- # exlusion because of --package-names
+ # exlusion because of --package-names
del clean_dict[mycpv]
return clean_dict
"Do you want to delete this " \
+ file_type+"?"):
# non-interactive mode or positive answer.
- # For each file,...
+ # For each file, try to delete the file and clean it out
+ # of Packages metadata file
+ if action == 'packages':
+ metadata = portage.getbinpkg.PackageIndex()
+ with open(os.path.join(pkgdir, 'Packages')) as metadata_file:
+ metadata.read(metadata_file)
for file in clean_dict[mykey]:
# ...get its size...
filesize = 0
except: eerror("Could not read size of "\
+file, myoptions['nocolor'])
# ...and try to delete it.
- try: os.unlink(file)
- except: eerror("Could not delete "+file, \
- myoptions['nocolor'])
+ try:
+ os.unlink(file)
+ except:
+ eerror("Could not delete "+file, \
+ myoptions['nocolor'])
# only count size if successfully deleted
- else: clean_size += filesize
+ else:
+ clean_size += filesize
+ if action == 'packages':
+ metadata.packages[:] = [p for p in metadata.packages if 'CPV' in p and p['CPV'] != file]
+
+ if action == 'packages':
+ with open(os.path.join(pkgdir, 'Packages'), 'w') as metadata_file:
+ metadata.write(metadata_file)
+
# return total size of deleted or to delete files
return clean_size
einfo("Building file list for "+action+" cleaning...", \
myoptions['nocolor'])
if action == 'packages':
- clean_dict = findPackages( \
+ clean_dict = findPackages(
+ myoptions, \
exclude_dict=exclude_dict, \
destructive=myoptions['destructive'], \
package_names=myoptions['package-names'], \
time_limit=myoptions['time-limit'])
else:
clean_dict = findDistfiles( \
+ myoptions, \
exclude_dict=exclude_dict, \
destructive=myoptions['destructive'], \
fetch_restricted=myoptions['fetch-restricted'], \
local current_desc
local args
local -i foundone=0
- local IFS
+ local OIFS="$IFS"
args=("${@:-*}")
echo "$desc"
# get list of installed packages matching this USE flag.
IFS=$'\n'
- packages=($(equery -q -C hasuse -i "${1}" | awk '{ print $(NF-1) }'))
+ packages=($(equery -q -C hasuse -i "${1}" | awk '{ print $(NF-1) }' | sort))
foundone+=${#packages[@]}
printf "\nInstalled packages matching this USE flag: "
if [ ${foundone} -gt 0 ]; then
# exit status of equery instead of a subshell and pipe to wc -l
if [ $(equery -q -C list -i -e "${pkg}" | wc -l) -gt 0 ]; then
foundone=1
+ IFS="$OIFS"
get_flagstatus "${flag}"
+ IFS=': '
printf "%s (%s):\n%s\n\n" "${flag}" "${pkg}" "${desc#- }"
fi
done < <(grep ":${1} *-" "${descdir}/use.local.desc")
if [ ${foundone} -lt 1 ]; then
echo "no matching entries found"
fi
+ IFS="$OIFS"
}
# show a list of all currently active flags and where they are activated
except ImportError:
from output import *
-from getopt import getopt,GetoptError
+from getopt import getopt, GetoptError
__program__ = "glsa-check"
__author__ = "Marius Mauch <genone@gentoo.org>"
# sanity checking
if len(args) <= 0:
sys.stderr.write("no option given: what should I do ?\n")
- mode="help"
+ mode = "HELP"
elif len(args) > 1:
sys.stderr.write("please use only one command per call\n")
- mode = "help"
+ mode = "HELP"
else:
# in what mode are we ?
args = args[0]
except GetoptError, e:
sys.stderr.write("unknown option given: ")
sys.stderr.write(str(e)+"\n")
- mode = "help"
+ mode = "HELP"
# we need a set of glsa for most operation modes
if len(params) <= 0 and mode in ["fix", "test", "pretend", "dump", "inject", "mail"]:
sys.stderr.write("\nno GLSA given, so we'll do nothing for now. \n")
sys.stderr.write("If you want to run on all GLSA please tell me so \n")
sys.stderr.write("(specify \"all\" as parameter)\n\n")
- mode = "help"
+ mode = "HELP"
elif len(params) <= 0 and mode == "list":
params.append("new")
# show help message
-if mode == "help":
- sys.stderr.write("\nSyntax: glsa-check <option> [glsa-list]\n\n")
+if mode == "help" or mode == "HELP":
+ msg = "Syntax: glsa-check <option> [glsa-list]\n\n"
for m in optionmap:
- sys.stderr.write(m[0] + "\t" + m[1] + " \t: " + m[-1] + "\n")
+ msg += m[0] + "\t" + m[1] + " \t: " + m[-1] + "\n"
for o in m[2:-1]:
- sys.stderr.write("\t" + o + "\n")
- sys.stderr.write("\nglsa-list can contain an arbitrary number of GLSA ids, \n")
- sys.stderr.write("filenames containing GLSAs or the special identifiers \n")
- sys.stderr.write("'all', 'new' and 'affected'\n")
- sys.exit(1)
+ msg += "\t" + o + "\n"
+ msg += "\nglsa-list can contain an arbitrary number of GLSA ids, \n"
+ msg += "filenames containing GLSAs or the special identifiers \n"
+ msg += "'all', 'new' and 'affected'\n"
+ if mode == "help":
+ sys.stdout.write(msg)
+ sys.exit(0)
+ else:
+ sys.stderr.write("\n" + msg)
+ sys.exit(1)
# we need root priviledges for write access
if mode in ["fix", "inject"] and os.geteuid() != 0:
- sys.stderr.write("\nThis tool needs root access to "+mode+" this GLSA\n\n")
+ sys.stderr.write(__program__ + ": root access is needed for \""+mode+"\" mode\n")
sys.exit(2)
# show version and copyright information
fd1.write("... ")
else:
for pkg in myglsa.packages.keys():
- mylist = vardb.match(portage.dep_getkey(pkg))
+ mylist = vardb.match(portage.dep_getkey(str(pkg)))
if len(mylist) > 0:
pkg = color(" ".join(mylist))
fd1.write(" " + pkg + " ")
fd1.write(")")
if list_cve:
fd1.write(" "+(",".join([r[:13] for r in myglsa.references if r[:4] in ["CAN-", "CVE-"]])))
- fd1.write("\n")
+ fd1.write("\n")
return 0
if mode == "list":
exitcode >>= 8
if exitcode:
sys.exit(exitcode)
+ if len(mergelist):
+ sys.stdout.write("\n")
myglsa.inject()
elif mode == "pretend":
sys.stdout.write("Checking GLSA "+myid+"\n")
sys.stdout.write(" " + pkg + " (" + oldver + ")\n")
else:
sys.stdout.write("Nothing to do for this GLSA\n")
+ sys.stdout.write("\n")
elif mode == "inject":
sys.stdout.write("injecting " + myid + "\n")
myglsa.inject()
- sys.stdout.write("\n")
sys.exit(0)
# test is a bit different as Glsa.test() produces no output
# color doesn't make any sense for mail
nocolor()
- if glsaconfig.has_key("PORTAGE_ELOG_MAILURI"):
+ if "PORTAGE_ELOG_MAILURI" in glsaconfig:
myrecipient = glsaconfig["PORTAGE_ELOG_MAILURI"].split()[0]
else:
myrecipient = "root@localhost"
- if glsaconfig.has_key("PORTAGE_ELOG_MAILFROM"):
+ if "PORTAGE_ELOG_MAILFROM" in glsaconfig:
myfrom = glsaconfig["PORTAGE_ELOG_MAILFROM"]
else:
myfrom = "glsa-check"
eerror "I was instructed to rm '$@'"
die 1 "Refusing to delete anything before changing to temporary directory."
}
+: <<'EW'
##
# GNU find has -executable, but if our users' finds do not have that flag
# we emulate it with this function. Also emulates -writable and -readable.
fi
find "$@"
}
+EW
print_usage() {
cat << EOF
# Replace whitespace with linebreaks, normalize repeated '/' chars, and sort -u
# (If any libs have whitespace in their filenames, someone needs punishment.)
clean_var() {
- awk 'BEGIN {RS="[[:space:]]"}
+ gawk 'BEGIN {RS="[[:space:]]"}
/-\*/ {exit}
/[^[:space:]]/ {gsub(/\/\/+/, "/"); print}' | sort -u
}
findMask="${findMask[@]/#/-o -path }"
findMask="( ${findMask#-o } ) -prune -o"
fi
- # TODO: Check this
- find ${SEARCH_DIRS[@]} $findMask -type f \( -executable -o \
+ # TODO: Check this -- afaict SEARCH_DIRS isn't an array, so this should just be $SEARCH_DIRS?
+ find ${SEARCH_DIRS[@]} $findMask -type f \( -perm -u+x -o -perm -g+x -o -perm -o+x -o \
-name '*.so' -o -name '*.so.*' -o -name '*.la' \) -print 2> /dev/null |
sort -u > "$FILES_FILE" ||
die $? "find failed to list binary files (This is a bug.)"
fi
elif [[ $SEARCH_BROKEN ]]; then
# Look for broken .la files
+ la_SEARCH_DIRS="$SEARCH_DIRS"
+ la_search_dir=""
+ la_broken=""
+ la_lib=""
for depend in $(
- awk -F"[=']" '/^dependency_libs/{
- gsub("^-[^[:space:]]*", "", $3);
- gsub("[[:space:]]-[^[:space:]]*", "", $3);
+ gawk -F"[=']" '/^dependency_libs/{
print $3
}' "$target_file"
); do
if [[ $depend = /* && ! -e $depend ]]; then
echo "obj $target_file" >> "$BROKEN_FILE"
echo_v " broken $target_file (requires $depend)"
+ elif [[ $depend = -[LR]/* ]]; then
+ if ! [[ $'\n'${la_SEARCH_DIRS}$'\n' == *$'\n'${depend#-?}$'\n'* ]]; then
+ la_SEARCH_DIRS+=$'\n'"${depend#-?}"
+ fi
+ elif [[ $depend = "-l"* ]]; then
+ la_lib="lib${depend#-l}"
+ la_broken="yes"
+ IFS=$'\n'
+ for la_search_dir in $la_SEARCH_DIRS; do
+ if [[ -e ${la_search_dir}/${la_lib}.so || -e ${la_search_dir}/${la_lib}.a ]]; then
+ la_broken="no"
+ fi
+ done
+ IFS="$OIFS"
+ if [[ $la_broken = yes ]]; then
+ echo "obj $target_file" >> "$BROKEN_FILE"
+ echo_v " broken $target_file (requires $depend)"
+ fi
fi
done
+ unset la_SEARCH_DIRS la_search_dir la_broken la_lib
fi
[[ $VERBOSE ]] &&
progress $((++i)) $numFiles $target_file ||
done < <(
# Regexify LD_LIBRARY_MASK. Exclude it from the search.
LD_LIBRARY_MASK="${LD_LIBRARY_MASK//$'\n'/|}"
- awk -v ldmask="(${LD_LIBRARY_MASK//./\\\.})" '
+ gawk -v ldmask="(${LD_LIBRARY_MASK//./\\\.})" '
/no version information available/ && $0 !~ ldmask {
gsub(/[()]/, "", $NF)
if (seen[$NF]++) next
ewarn "The broken files are:"
while read filename junk; do
[[ $junk = *none* ]] && ewarn " $filename"
- done < "$OWNERS_FILE" | awk '!s[$0]++' # (omit dupes)
+ done < "$OWNERS_FILE" | gawk '!s[$0]++' # (omit dupes)
fi
}
##
einfo 'Build finished correctly. Removing temporary files...'
einfo
einfo 'You can re-run revdep-rebuild to verify that all libraries and binaries'
- einfo 'are fixed. If some inconsistency remains, it can be orphaned file, deep'
- einfo 'dependency, binary package or specially evaluated library.'
+ einfo 'are fixed. Possible reasons for remaining inconsistencies include:'
+ einfo ' orphaned files'
+ einfo ' deep dependencies'
+ einfo " packages installed outside of portage's control"
+ einfo ' specially-evaluated libraries'
if [[ -r "$OWNERS_FILE" && -s "$OWNERS_FILE" ]]; then
show_unowned_files
fi
def _do_complex_lookup(query, query_opts):
"""Find matches for a query which is a regex or includes globbing."""
+ # pylint: Too many branches (18/12)
+ # pylint: disable-message=R0912
result = []
if query_opts["includeInstalled"]:
def do_lookup(query, query_opts):
"""A high-level wrapper around gentoolkit package-finder functions.
- @todo: equery modules to move to do_lookup: c,m,u,w
-
@type query: str
@param query: pkg, cat/pkg, pkg-ver, cat/pkg-ver, atom or regex
@type query_opts: dict
def split_query(query):
- """Split a query, using either.
+ """Split a query into category, name, version and revision.
- @see: split_atom, gentoolkit.split_package_name
+ @type query: str
@param query: pkg, cat/pkg, pkg-ver, cat/pkg-ver, atom or regex
@rtype: tuple
@return: (category, pkg_name, version, revision)
"""
if not self._db:
self._db = portage.dblink(
- category,
+ self.category,
"%s-%s" % (self.name, self.fullversion),
settings["ROOT"],
settings