summaryrefslogtreecommitdiff
path: root/trunk/src
diff options
context:
space:
mode:
Diffstat (limited to 'trunk/src')
-rw-r--r--trunk/src/change/AUTHORS5
-rw-r--r--trunk/src/change/ChangeLog3
-rw-r--r--trunk/src/change/README20
-rw-r--r--trunk/src/change/change344
-rw-r--r--trunk/src/change/change.10
-rw-r--r--trunk/src/dep-clean/AUTHORS0
-rw-r--r--trunk/src/dep-clean/ChangeLog0
-rw-r--r--trunk/src/dep-clean/README0
-rw-r--r--trunk/src/dep-clean/dep-clean266
-rw-r--r--trunk/src/dep-clean/dep-clean.1187
-rw-r--r--trunk/src/emerge-rsync/AUTHORS0
-rw-r--r--trunk/src/emerge-rsync/ChangeLog0
-rw-r--r--trunk/src/emerge-rsync/README0
-rwxr-xr-xtrunk/src/emerge-rsync/emerge-rsync52
-rw-r--r--trunk/src/emerge-webrsync/AUTHORS0
-rw-r--r--trunk/src/emerge-webrsync/ChangeLog0
-rw-r--r--trunk/src/emerge-webrsync/README0
-rw-r--r--trunk/src/emerge-webrsync/emerge-webrsync62
-rw-r--r--trunk/src/epm/AUTHORS0
-rw-r--r--trunk/src/epm/ChangeLog0
-rw-r--r--trunk/src/epm/README0
-rw-r--r--trunk/src/epm/epm421
-rw-r--r--trunk/src/etc-update/AUTHORS0
-rw-r--r--trunk/src/etc-update/ChangeLog0
-rw-r--r--trunk/src/etc-update/README0
-rw-r--r--trunk/src/pkg-clean/AUTHORS0
-rw-r--r--trunk/src/pkg-clean/ChangeLog0
-rw-r--r--trunk/src/pkg-clean/README0
-rw-r--r--trunk/src/pkg-clean/pkg-clean100
-rw-r--r--trunk/src/pkg-size/AUTHORS0
-rw-r--r--trunk/src/pkg-size/ChangeLog0
-rw-r--r--trunk/src/pkg-size/README0
-rw-r--r--trunk/src/pkg-size/pkg-size52
-rw-r--r--trunk/src/portage-statistics/AUTHORS0
-rw-r--r--trunk/src/portage-statistics/ChangeLog2
-rw-r--r--trunk/src/portage-statistics/README0
-rw-r--r--trunk/src/portage-statistics/histogram.awk14
-rwxr-xr-xtrunk/src/portage-statistics/pst-author-coverage12
-rwxr-xr-xtrunk/src/portage-statistics/pst-package-count9
-rwxr-xr-xtrunk/src/portage-statistics/pst-total-coverage7
-rw-r--r--trunk/src/qpkg/AUTHORS0
-rw-r--r--trunk/src/qpkg/ChangeLog0
-rw-r--r--trunk/src/qpkg/README0
-rw-r--r--trunk/src/qpkg/qpkg473
-rw-r--r--trunk/src/qpkg/qpkg.1110
-rw-r--r--trunk/src/useflag/AUTHORS0
-rw-r--r--trunk/src/useflag/ChangeLog0
-rw-r--r--trunk/src/useflag/README0
-rw-r--r--trunk/src/useflag/useflag610
-rw-r--r--trunk/src/useflag/useflag.169
50 files changed, 2818 insertions, 0 deletions
diff --git a/trunk/src/change/AUTHORS b/trunk/src/change/AUTHORS
new file mode 100644
index 0000000..fc3af19
--- /dev/null
+++ b/trunk/src/change/AUTHORS
@@ -0,0 +1,5 @@
+Dan Armak <danarmak@gentoo.org>
+ - Basic idea
+ - Initial version
+Karl Trygve Kalleberg <karltk@gentoo.org>
+ - Gentoolkit-specific changes
diff --git a/trunk/src/change/ChangeLog b/trunk/src/change/ChangeLog
new file mode 100644
index 0000000..6002078
--- /dev/null
+++ b/trunk/src/change/ChangeLog
@@ -0,0 +1,3 @@
+2002-08-09 Karl Trygve Kalleberg <karltk@gentoo.org>:
+ * Reformatted usage to work with 80 columns
+ * Now loads ~/.gentoo/gentool-env instead of ~/.change
diff --git a/trunk/src/change/README b/trunk/src/change/README
new file mode 100644
index 0000000..bda1842
--- /dev/null
+++ b/trunk/src/change/README
@@ -0,0 +1,20 @@
+Package : change
+Version : 0.2.4
+Author : See AUTHORS
+
+MOTIVATION
+
+Maintaing Gentoo's ChangeLog files in the Portage Tree is a tedious affair.
+Many of the details are well-defined enough for a tool to do. change is this
+tool.
+
+MECHANICS
+
+change can create a ChangeLog, add entries to the ChangeLog file, scan for
+updated files.
+
+
+IMPROVEMENTS
+
+For improvements, send a mail to karltk@gentoo.org or make out a bug at
+bugs.gentoo.org and assign it to me.
diff --git a/trunk/src/change/change b/trunk/src/change/change
new file mode 100644
index 0000000..da2e91b
--- /dev/null
+++ b/trunk/src/change/change
@@ -0,0 +1,344 @@
+#! /bin/bash
+
+# Copyright 1999-2002 Gentoo Technologies, Inc.
+# Distributed under the terms of the GNU General Public License v2
+# Author: Dan Armak <danarmak@gentoo.org>
+# $Header: $
+
+eval `grep PORTDIR= /etc/make.globals`
+eval `grep PORTDIR= /etc/make.conf`
+[ -z "$PORTDIR" ] && PORTDIR="/usr/portage"
+
+# register temp files (we delete them in the end)
+TMPMESSAGE=`tempfile -p change` || cleanup 1
+TMPHEADER=`tempfile -p change` || cleanup 1
+TMPENTRY=`tempfile -p change` || cleanup 1
+TMPOLDLOG=`tempfile -p change` || cleanup 1
+TMPCHANGELOG=`tempfile -p change` || cleanup 1
+
+# get user info from config file - $AUTHORNAME and $AUTHOREMAIL
+init() {
+ . ~/.gentoo/gentool-env || return 1
+}
+
+print_about() {
+
+ echo "change v 0.2.4 - A Gentoo ChangeLog editor."
+ echo "Author Dan Armak <danarmak@gentoo.org>"
+}
+
+print_usage() {
+
+ echo "Usage:
+change <package list> [-shv] [-m|--message msg] [-f|--message-file file]
+ [-a|--authorname name] [-l|--authormail mail]
+ [-n|--new-version ver] [-o|--output dest]
+
+<package list>: List of packages whose changelogs are to be edited. All
+changelogs edited in one run will be added the same log message.
+
+Acceptable formats: Example:
+category/package kde-base/kdebase
+path to package dir kdebase || ../../kdebase
+path to changelog file portage/kde-base/kdebase/ChangeLog
+
+Note that you must use -g for changelog files outside $PORTDIR.
+
+-m, --message \"msg\" Use log message \"msg\", do not open editor.
+-f, --message-file <file> Use contents of <file> as log message, do not open
+ editor.
+-a, --authorname \"name\" Use \"name\" (e.g. Dan Armak) in log.
+-l, --authormail \"email\" Use \"email\" (e.g. danarmak@gentoo.org) in log.
+-n, --new-version \"ver\" Add a line about a new version number \"ver\" to
+ the log.
+-g, --generate Create a new changelog file if one does not exist.
+ This option must come before the list of affected
+ changelog files. Incidentally, this option also
+ enables you to work with a changelog file outside
+ $PORTDIR.
+ You must use it every time you edit such a file.
+ However, change won't be able to figure out the
+ category and package names of your changelog file
+ and those parts will be missing. (FIXME!)
+-o, --output \"file\" Save new changelog in file \"file\".
+ Default is the the same file we're changing (i.e.
+ no backup).
+-s, --stdout Print new changelog to stdout (disables saving to
+ file). This suppresses the usual info messages.
+-c, --changed-files List of changed files (goes into entry header).
+ Default is to simply say \"ChangeLog :\". Multiple
+ -c options can be given.
+-h, --help Print this usage information.
+-v, --version Print a short about line and the version number and
+ exit.
+
+See also the mandatory config file ~/.gentoo/gentool-env (the gentool-env man
+page contains a template).
+"
+
+}
+
+# parse command line parameters
+# this function should be called before all others (e.g. before init())
+# or else it might stomp on some settings
+parse_params() {
+
+ # at least one parameter required - changelog to process
+ if [ -z "$1" ]; then
+ echo "At least one parameter is required."
+ print_about
+ print_usage
+ cleanup 1
+ fi
+
+ while [ -n "$1" ]; do
+
+ # note: with parameters that come in two pieces (i.e. -m foo)
+ # we identify the first one, grab the second one from $2 and
+ # shift an extra time
+ case "$1" in
+
+ # optional log message, if defined then we won't launch $EDITOR
+ # comes in explicit string and file reference variations
+ -m | --message)
+ MESSAGE="$2"
+ shift
+ ;;
+ -f | --message-file)
+ cp $2 $TMPMESSAGE
+ shift
+ ;;
+
+ # general settings (usually set in .change)
+ -a | --authorname)
+ AUTHORNAME="$2"
+ shift
+ ;;
+ -l | --authormail)
+ AUTHOREMAIL="$2"
+ shift
+ ;;
+
+ # add a line about a new version (starting with *) to the changelog
+ # to add the line but no changelog info, call with -n -m ""
+ -n | --new-version)
+ NEWVERSION="$2"
+ shift
+ ;;
+
+ # create a new changelog file
+ -g | --generate)
+ GENERATE=true
+ ;;
+
+ # output redirection. default (if $OUTPUT isn't set) is to change the
+ # specified changelog file.
+ # illegal if more than one changelog file/package is specified.
+ -o | --output)
+ OUTPUT="$2"
+ shift
+ ;;
+ # redirect output to stdout - can be combined with -o
+ -s | --stdout)
+ STDOUT="true"
+ OUTPUT="/dev/null"
+ ;;
+
+ # list of files changed (second part inclosed in quotes!)
+ -c | --changed-files)
+ CHANGED="$CHANGED $2"
+ shift
+ ;;
+
+ # request for version/usage information etc
+ -h | --help)
+ print_about
+ print_usage
+ cleanup 0
+ ;;
+ -v | --version)
+ print_about
+ cleanup 0
+ ;;
+
+ # everything else we couldn't identify. most of it is packages/files to work on.
+ *)
+ for x in "$MYPORTDIR/$1/ChangeLog" "$PORTDIR/$1/ChangeLog" "$PWD/$1/ChangeLog" "$PWD/$1"; do
+ if [ -f "$x" ]; then
+ FILES="$FILES $x"
+ shift # because by calling continue we skip the shift at the end of the case block
+ continue 2 # next while iteration
+ fi
+ done
+ # if we haveb't detected a changelog file, maybe we need to create one
+ if [ -n "$GENERATE" ]; then
+ for x in "$PWD/$1" "$1" "$MYPORTDIR/$1" "$PORTDIR/$1"; do
+ if [ -d "$x" ]; then
+ touch $x/ChangeLog
+ FILES="$FILES $x/ChangeLog"
+ shift # because by calling continue we skip the shift at the end of the case block
+ continue 2 # next while iteration
+ fi
+ done
+ fi
+
+ echo "!!! Error: unrecognized option: $1"
+ echo
+ print_usage
+ cleanup 1
+
+ ;;
+
+ esac
+
+ shift
+ done
+
+ if [ -z "$FILES" ]; then
+ echo "No changelog path or package name passed, mandatory parameter missing."
+ echo
+ print_usage
+ cleanup 1
+ fi
+
+}
+
+# get the log message
+get_msg() {
+
+ if [ -n "`cat $TMPMESSAGE`" ]; then
+ echo "Using message-on-file."
+ elif [ -n "$MESSAGE" ]; then
+ echo "$MESSAGE" > $TMPMESSAGE
+ else # [ -z "$MESSAGE" ]
+
+ echo > $TMPMESSAGE
+ echo "Please enter changelog. You can leave this line, it will be automatically removed." >> $TMPMESSAGE
+ $EDITOR $TMPMESSAGE
+ cp $TMPMESSAGE ${TMPMESSAGE}2
+ sed -e '/Please enter changelog. You can leave this line, it will be automatically removed./ D' \
+ ${TMPMESSAGE}2 > $TMPMESSAGE
+ rm ${TMPMESSAGE}2
+
+ fi
+
+ # break up into 80-character columns (actually 78 chars because we'll
+ # add two spaces to every line)
+ cp $TMPMESSAGE ${TMPMESSAGE}2
+ fmt -s -w 78 ${TMPMESSAGE}2 > $TMPMESSAGE
+ rm ${TMPMESSAGE}2
+
+ # add two spaces to the beginning of every line of the message.
+ # do this separately from the sed in the else section above
+ # because it should be executed for the if and elif sections too.
+ cp $TMPMESSAGE ${TMPMESSAGE}2
+ sed -e 's:^: :g' ${TMPMESSAGE}2 > $TMPMESSAGE
+ rm ${TMPMESSAGE}2
+
+}
+
+# get list of files and wrap it in the following manner:
+# 1 item on the first list and upto 80 chars on every other.
+# also adds 2 spaces to the beginning of every line but the first.
+wrap_list() {
+
+ echo -n $1
+ shift
+
+ while [ -n "$1" ]; do
+ if [ -n "$LIST" ]; then
+ LIST="$LIST, $1"
+ else
+ echo ,
+ LIST=$1
+ fi
+ shift
+ done
+ LIST="$LIST :"
+
+ echo $LIST | fmt -s -w 78 | sed -e 's:^: :g' -
+
+}
+
+# do the actual work on te changelog file passed as $1
+process() {
+
+ # figure out category and package names
+ name=${1//${PORTDIR}\/}
+ name=${name//${MYPORTDIR}\/}
+ name=${name//\/ChangeLog}
+
+ OLDIFS="$IFS"
+ IFS="/"
+ for x in $name; do
+ if [ -z "$CATEGORY" ]; then
+ CATEGORY="$x"
+ else
+ PACKAGE="$x"
+ fi
+ done
+ IFS="$OLDIFS"
+
+ # create header
+ echo \
+"# ChangeLog for $CATEGORY/$PACKAGE
+# Copyright 2002 Gentoo Technologies, Inc.; Distributed under the GPL
+# \$Header: \$
+" > $TMPHEADER
+
+ # create entry line
+ if [ -n "$NEWVERSION" ]; then
+ echo "*$PACKAGE-$NEWVERSION (`date '+%d %b %Y'`)" > $TMPENTRY
+ echo >> $TMPENTRY
+ fi
+
+ echo -n " `date "+%d %b %Y"`; ${AUTHORNAME} <${AUTHOREMAIL}> " >> $TMPENTRY
+ [ -z "$CHANGED" ] && CHANGED="ChangeLog "
+ wrap_list $CHANGED >> $TMPENTRY
+
+ echo >> $TMPENTRY
+
+ # get the original changelog, minus the old header
+ sed -e "
+/# ChangeLog for $CATEGORY\/$PACKAGE/ D
+/# Copyright 2002 Gentoo Technologies, Inc.; Distributed under the GPL/ D
+/^# \$Header:/ D" $1 > $TMPOLDLOG
+
+ # join everything together
+ cat $TMPHEADER $TMPENTRY $TMPMESSAGE $TMPOLDLOG > $TMPCHANGELOG
+
+ # various output options
+ if [ -n "$OUTPUT" ]; then
+ cp $TMPCHANGELOG $OUTPUT
+ [ -z "$STDOUT" ] && echo "New changelog saved in $OUTPUT."
+ else
+ cp $TMPCHANGELOG $1
+ [ -z "$STDOUT" ] && echo "Original changelog $1 replaced."
+ fi
+
+ if [ -n "$STDOUT" ]; then
+ cat $TMPCHANGELOG
+ fi
+
+}
+
+# pass exit code to this function
+cleanup() {
+
+ rm -f $TMPMESSAGE $TMPHEADER $TMPENTRY $TMPCHANGELOG $TMPOLDLOG
+
+ exit $1
+
+}
+
+parse_params "${@}"
+
+init
+
+get_msg
+
+for x in $FILES; do
+ process $x
+done
+
+cleanup 0
diff --git a/trunk/src/change/change.1 b/trunk/src/change/change.1
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/trunk/src/change/change.1
diff --git a/trunk/src/dep-clean/AUTHORS b/trunk/src/dep-clean/AUTHORS
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/trunk/src/dep-clean/AUTHORS
diff --git a/trunk/src/dep-clean/ChangeLog b/trunk/src/dep-clean/ChangeLog
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/trunk/src/dep-clean/ChangeLog
diff --git a/trunk/src/dep-clean/README b/trunk/src/dep-clean/README
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/trunk/src/dep-clean/README
diff --git a/trunk/src/dep-clean/dep-clean b/trunk/src/dep-clean/dep-clean
new file mode 100644
index 0000000..9bb3871
--- /dev/null
+++ b/trunk/src/dep-clean/dep-clean
@@ -0,0 +1,266 @@
+#!/bin/bash
+#Shows unrequired packages and missing dependencies.
+#Author: Jerry Haltom <ssrit@larvalstage.net>
+
+PROG=`basename ${0}`
+
+tmp="/tmp/$$"
+rm -rf ${tmp} > /dev/null 2>&1
+mkdir ${tmp} > /dev/null 2>&1
+
+declare -i i
+
+set -- `getopt -n ${PROG} -o N,R,U,I,v,C,h -l needed,removed,unneeded,interactive,verbose,nocolor,help -- ${*/ --/};[ $? != 0 ] && echo "y"`
+
+while [ ${#} -gt 0 ]
+do
+ a=${1}
+ shift
+ case "${a}" in
+
+ -I|--interactive)
+ interactive=y
+ ;;
+
+ -N|--needed)
+ needed=y
+ ;;
+
+ -U|--unneeded)
+ unneeded=y
+ ;;
+
+ -R|--removed)
+ removed=y
+ ;;
+
+ -v|--verbose)
+ verb=y
+ ;;
+
+ -C|--nocolor)
+ nocolor=y
+ ;;
+
+ -h|--help)
+ usage=y
+ ;;
+
+ --)
+ [ ${1} ] && usage=y && broke=y
+ break
+ ;;
+
+ *)
+ usage=y
+ broke=y
+ echo "FIXME - OPTION PARSING - ${a}"
+ break
+ ;;
+
+ esac
+done
+
+if [ ! ${needed} ] && [ ! ${unneeded} ] && [ ! ${removed} ]; then
+ needed=y
+ unneeded=y
+ removed=y
+fi
+
+#Set up colors
+if [ ! "${nocolor}" ]; then
+ NO="\x1b[0;0m"
+ BR="\x1b[0;01m"
+ CY="\x1b[36;01m"
+ GR="\x1b[32;01m"
+ RD="\x1b[31;01m"
+ YL="\x1b[33;01m"
+ BL="\x1b[34;01m"
+elif [ ! ${verb} ] && (
+ ( [ ${needed} ] && [ ${unneeded} ] ) ||
+ ( [ ${unneeded} ] && [ ${removed} ] ) ||
+ ( [ ${removed} ] && [ ${needed} ] )
+ ); then
+ NEED=" N"
+ UNNE=" U"
+ REMO=" R"
+fi
+
+if [ `whoami` != "root" ]
+then
+ echo -e "${RD}Only root can run ${PROG}${NO}"
+ rm -rf ${tmp}
+ exit 1
+fi
+
+if [ ${usage} ]; then
+ echo -e "${BR}GenToolKit's Dependency Checker!
+${NO}Displays packages that are installed but which none
+of the packages in world or system depend on, and
+displays packages which are depended on by world or
+system, but are not currently installed.
+
+${BR}USAGE:
+ ${BL}${PROG}${YL} [${NO}options${YL}]${NO}
+ ${BL}${PROG}${GR} --help${NO}
+
+${BR}OPTIONS:
+ ${GR}-U, --unneeded${NO} display unneeded packages that are installed (${GR}green${NO})
+ ${GR}-N, --needed${NO} display needed packages that are not installed (${RD}red${NO})
+ ${GR}-R, --removed${NO} display installed packages not in portage (${YL}yellow${NO})
+
+ ${GR}-I, --interactive${NO} interactively modify world file before proceeding
+ ${GR}-C, --nocolor${NO} output without color, if necessary, package types are
+ noted with ${GR}U, N${NO} and ${GR}R${NO} respectively
+ ${GR}-v, --verbose${NO} be more verbose
+
+${BR}NOTES:
+ ${GR}*${NO} If this script is run on a system that is not up-to-date or which hasn't
+ been cleaned (with '${BL}emerge -c${NO}') recently, the output may be deceptive.
+ ${GR}*${NO} If the same package name appears in all three categories, then it is
+ definitely time to update that package and then run '${BL}emerge -c${NO}'.
+ ${GR}*${NO} The ${GR}-U, -N${NO} and ${GR}-R${NO} options may be combined, defaults to ${GR}-UNR${NO}"
+ rm -rf ${tmp} > /dev/null 2>&1
+ [ ${broke} ] && exit 1 || exit 0
+fi
+
+X="\([^/]*\)"
+
+#Retrieve currently merged packages.
+[ ${verb} ] && \
+echo -e "${CY}Retrieving currently merged packages.${NO}"
+find /var/db/pkg -name '*.ebuild' | \
+ sed -e "s:/var/db/pkg/::" \
+ -e "s:${X}/${X}/${X}:\1/\2:" | \
+ sort | uniq >> ${tmp}/current
+
+[ ${verb} ] && \
+echo -e "${CY}"`cat ${tmp}/current | wc -l` "currently merged packages.${NO}"
+[ ${verb} ] && \
+echo -e
+
+#Retrieve system packages and add to image.
+[ ${verb} ] && \
+echo -e "${CY}Retrieving system packages.${NO}"
+emerge system -eup | \
+ grep ebuild | \
+ sed -e "s:^.*] ::" \
+ -e "s: to /::" | \
+ sort | uniq \
+ > ${tmp}/system
+# -e "s:-r[0-9]*::" \
+# -e "s:-[0-9].*::" | \
+
+[ ${verb} ] && \
+echo -e "${CY}"`cat ${tmp}/system | wc -l 2> /dev/null` "packages contained in system.${NO}"
+[ ${verb} ] && \
+echo -e
+
+#Create local copy of world and ask user to verify it.
+[ ${verb} ] && \
+echo -e "${CY}Preparing world file.${NO}"
+cp /var/cache/edb/world ${tmp}/world
+
+[ ${interactive} ] && \
+${EDITOR} ${tmp}/world
+
+[ ${verb} ] && \
+echo -e "${CY}"`cat ${tmp}/world | wc -l` "packages contained in world.${NO}"
+[ ${verb} ] && \
+echo -e
+
+#Retrieve world packages and dependencies and add to image.
+[ ${verb} ] && \
+echo -e "${CY}Listing world and total dependencies.${NO}"
+
+qpkg -I -nc -vv | \
+ grep ebuild | \
+ fgrep "`cat ${tmp}/world`" | \
+ cut -f5,6 -d"/" > ${tmp}/world.all
+
+cat ${tmp}/world.all | sed -e s:$:xxx: | \
+ fgrep "`find /usr/portage/ -iname '*.ebuild'|cut -f4,6 -d/ | \
+ sed -e s:\\.ebuild:xxx:`" | \
+ sed -e "s:^:\\\=:" -e "s:xxx::" > ${tmp}/world.new
+
+sort ${tmp}/world.new | uniq | \
+ xargs emerge -eup | tee ${tmp}/log | \
+ grep ebuild | \
+ sed -e "s:^.*] :: ; s: to /::" > ${tmp}/image.unsorted
+
+depends=`cat ${tmp}/image.unsorted|wc -l`
+
+if [ ${depends} -lt "2" ]; then
+ echo -e "${RD}There appears to be an unresolved dependency in your world file."
+ echo -e "Please check for masking errors or other world file issues,"
+ echo -e "and then try again."
+ echo -e
+ echo -e "The following is the emerge output for your reference:${NO}"
+ cat ${tmp}/log
+ rm -rf ${tmp} > /dev/null 2>&1
+ exit 1
+fi
+
+cat ${tmp}/system >> ${tmp}/image.unsorted
+
+#Cleanup image
+sort ${tmp}/image.unsorted | uniq > ${tmp}/image
+
+[ ${verb} ] && \
+echo -e "${CY}"`cat ${tmp}/image | wc -l` "packages contained in final image.${NO}"
+
+#Determine packages that exist in current but not in image.
+#These packages are safe to clean up.
+if [ ${unneeded} ]; then
+ [ ${verb} ] && \
+ echo -e
+ [ ${verb} ] && \
+ echo -e "${CY}These packages have no other packages depending on them.${NO}"
+ i=0
+ for pkg in `cat ${tmp}/current`; do
+ if [ "`cat ${tmp}/image | grep -x ${pkg} | wc -l`" -eq "0" ]; then
+ echo -e "${GR}${pkg}${CY}${UNNE}${NO}"
+ i=${i}+1
+ fi
+ done
+ [ ${verb} ] && \
+ echo -e "${CY}Total of ${i} unneeded packages.${NO}"
+fi
+
+#Determine packages that exist in image but not in current.
+#These packages should be added.
+if [ ${needed} ]; then
+ [ ${verb} ] && \
+ echo -e
+ [ ${verb} ] && \
+ echo -e "${CY}These packages are depended upon but are not present on the system.${NO}"
+ i=0
+ for pkg in `cat ${tmp}/image`; do
+ if [ "`cat ${tmp}/current | grep -x ${pkg} | wc -l`" -eq "0" ]; then
+ echo -e "${RD}${pkg}${CY}${NEED}${NO}"
+ i=${i}+1
+ fi
+ done
+ [ ${verb} ] && \
+ echo -e "${CY}Total of ${i} needed packages.${NO}"
+fi
+
+#Determine packages that are installed but not currently in portage
+if [ ${removed} ]; then
+ [ ${verb} ] && \
+ echo -e
+ [ ${verb} ] && \
+ echo -e "${CY}These packages are installed but not in the portage tree.${NO}"
+ cat ${tmp}/current | sed -e s:$:xxx: | \
+ fgrep -v "`find /usr/portage/ -iname '*.ebuild'|cut -f4,6 -d/ | \
+ sed -e s:\\\.ebuild:xxx:`" | \
+ sed -e "s:xxx:${CY}${REMO}${YL}:" > ${tmp}/world
+ echo -ne "${YL}"
+ cat ${tmp}/world
+ echo -ne "${NO}"
+ [ ${verb} ] && \
+ echo -e "${CY}Total of" `cat ${tmp}/world|wc -l` "removed packages.${NO}"
+fi
+
+rm -rf ${tmp} > /dev/null 2>&1
+
diff --git a/trunk/src/dep-clean/dep-clean.1 b/trunk/src/dep-clean/dep-clean.1
new file mode 100644
index 0000000..5e46c10
--- /dev/null
+++ b/trunk/src/dep-clean/dep-clean.1
@@ -0,0 +1,187 @@
+.\" Automatically generated by Pod::Man version 1.15
+.\" Thu Jul 18 15:59:55 2002
+.\"
+.\" Standard preamble:
+.\" ======================================================================
+.de Sh \" Subsection heading
+.br
+.if t .Sp
+.ne 5
+.PP
+\fB\\$1\fR
+.PP
+..
+.de Sp \" Vertical space (when we can't use .PP)
+.if t .sp .5v
+.if n .sp
+..
+.de Ip \" List item
+.br
+.ie \\n(.$>=3 .ne \\$3
+.el .ne 3
+.IP "\\$1" \\$2
+..
+.de Vb \" Begin verbatim text
+.ft CW
+.nf
+.ne \\$1
+..
+.de Ve \" End verbatim text
+.ft R
+
+.fi
+..
+.\" Set up some character translations and predefined strings. \*(-- will
+.\" give an unbreakable dash, \*(PI will give pi, \*(L" will give a left
+.\" double quote, and \*(R" will give a right double quote. | will give a
+.\" real vertical bar. \*(C+ will give a nicer C++. Capital omega is used
+.\" to do unbreakable dashes and therefore won't be available. \*(C` and
+.\" \*(C' expand to `' in nroff, nothing in troff, for use with C<>
+.tr \(*W-|\(bv\*(Tr
+.ds C+ C\v'-.1v'\h'-1p'\s-2+\h'-1p'+\s0\v'.1v'\h'-1p'
+.ie n \{\
+. ds -- \(*W-
+. ds PI pi
+. if (\n(.H=4u)&(1m=24u) .ds -- \(*W\h'-12u'\(*W\h'-12u'-\" diablo 10 pitch
+. if (\n(.H=4u)&(1m=20u) .ds -- \(*W\h'-12u'\(*W\h'-8u'-\" diablo 12 pitch
+. ds L" ""
+. ds R" ""
+. ds C` ""
+. ds C' ""
+'br\}
+.el\{\
+. ds -- \|\(em\|
+. ds PI \(*p
+. ds L" ``
+. ds R" ''
+'br\}
+.\"
+.\" If the F register is turned on, we'll generate index entries on stderr
+.\" for titles (.TH), headers (.SH), subsections (.Sh), items (.Ip), and
+.\" index entries marked with X<> in POD. Of course, you'll have to process
+.\" the output yourself in some meaningful fashion.
+.if \nF \{\
+. de IX
+. tm Index:\\$1\t\\n%\t"\\$2"
+..
+. nr % 0
+. rr F
+.\}
+.\"
+.\" For nroff, turn off justification. Always turn off hyphenation; it
+.\" makes way too many mistakes in technical documents.
+.hy 0
+.if n .na
+.\"
+.\" Accent mark definitions (@(#)ms.acc 1.5 88/02/08 SMI; from UCB 4.2).
+.\" Fear. Run. Save yourself. No user-serviceable parts.
+.bd B 3
+. \" fudge factors for nroff and troff
+.if n \{\
+. ds #H 0
+. ds #V .8m
+. ds #F .3m
+. ds #[ \f1
+. ds #] \fP
+.\}
+.if t \{\
+. ds #H ((1u-(\\\\n(.fu%2u))*.13m)
+. ds #V .6m
+. ds #F 0
+. ds #[ \&
+. ds #] \&
+.\}
+. \" simple accents for nroff and troff
+.if n \{\
+. ds ' \&
+. ds ` \&
+. ds ^ \&
+. ds , \&
+. ds ~ ~
+. ds /
+.\}
+.if t \{\
+. ds ' \\k:\h'-(\\n(.wu*8/10-\*(#H)'\'\h"|\\n:u"
+. ds ` \\k:\h'-(\\n(.wu*8/10-\*(#H)'\`\h'|\\n:u'
+. ds ^ \\k:\h'-(\\n(.wu*10/11-\*(#H)'^\h'|\\n:u'
+. ds , \\k:\h'-(\\n(.wu*8/10)',\h'|\\n:u'
+. ds ~ \\k:\h'-(\\n(.wu-\*(#H-.1m)'~\h'|\\n:u'
+. ds / \\k:\h'-(\\n(.wu*8/10-\*(#H)'\z\(sl\h'|\\n:u'
+.\}
+. \" troff and (daisy-wheel) nroff accents
+.ds : \\k:\h'-(\\n(.wu*8/10-\*(#H+.1m+\*(#F)'\v'-\*(#V'\z.\h'.2m+\*(#F'.\h'|\\n:u'\v'\*(#V'
+.ds 8 \h'\*(#H'\(*b\h'-\*(#H'
+.ds o \\k:\h'-(\\n(.wu+\w'\(de'u-\*(#H)/2u'\v'-.3n'\*(#[\z\(de\v'.3n'\h'|\\n:u'\*(#]
+.ds d- \h'\*(#H'\(pd\h'-\w'~'u'\v'-.25m'\f2\(hy\fP\v'.25m'\h'-\*(#H'
+.ds D- D\\k:\h'-\w'D'u'\v'-.11m'\z\(hy\v'.11m'\h'|\\n:u'
+.ds th \*(#[\v'.3m'\s+1I\s-1\v'-.3m'\h'-(\w'I'u*2/3)'\s-1o\s+1\*(#]
+.ds Th \*(#[\s+2I\s-2\h'-\w'I'u*3/5'\v'-.3m'o\v'.3m'\*(#]
+.ds ae a\h'-(\w'a'u*4/10)'e
+.ds Ae A\h'-(\w'A'u*4/10)'E
+. \" corrections for vroff
+.if v .ds ~ \\k:\h'-(\\n(.wu*9/10-\*(#H)'\s-2\u~\d\s+2\h'|\\n:u'
+.if v .ds ^ \\k:\h'-(\\n(.wu*10/11-\*(#H)'\v'-.4m'^\v'.4m'\h'|\\n:u'
+. \" for low resolution devices (crt and lpr)
+.if \n(.H>23 .if \n(.V>19 \
+\{\
+. ds : e
+. ds 8 ss
+. ds o a
+. ds d- d\h'-1'\(ga
+. ds D- D\h'-1'\(hy
+. ds th \o'bp'
+. ds Th \o'LP'
+. ds ae ae
+. ds Ae AE
+.\}
+.rm #[ #] #H #V #F C
+.\" ======================================================================
+.\"
+.IX Title "DEP-CLEAN 1"
+.TH DEP-CLEAN 1 "Copyright 2002 Gentoo Technologies, Inc." "2002-07-18" "GenToolKit's Dependency Checker!"
+.UC
+.SH "NAME"
+dep-clean \- Shows unrequired packages and missing dependencies.
+.SH "SYNOPSIS"
+.IX Header "SYNOPSIS"
+.Vb 1
+\& dep-clean [-RUNICv]
+.Ve
+.SH "DESCRIPTION"
+.IX Header "DESCRIPTION"
+dep-clean displays extraneous, missing or extra packages. Extra packages are those in which are not a part of the portage tree (/usr/portage). It does \s-1NOT\s0 modify the system in any way.
+.SH "OPTIONS"
+.IX Header "OPTIONS"
+.Ip "\-N, \-\-needed" 4
+.IX Item "-N, --needed"
+Display needed packages that are not installed. (red) (default)
+.Ip "\-R, \-\-removed" 4
+.IX Item "-R, --removed"
+Display installed packages not in portage. (yellow) (default)
+.Ip "\-U, \-\-unneeded" 4
+.IX Item "-U, --unneeded"
+Display unneeded packages that are installed. (green) (default)
+.Ip "\-I, \-\-interactive" 4
+.IX Item "-I, --interactive"
+Interactively modify world file before proceeding.
+.Ip "\-C, \-\-nocolor" 4
+.IX Item "-C, --nocolor"
+Output without color. Package types will be noted with R, U and N.
+.Ip "\-v, \-\-verbose" 4
+.IX Item "-v, --verbose"
+Be more verbose.
+.SH "NOTES"
+.IX Header "NOTES"
+.Ip "" 4
+If this script is run on a system that is not up-to-date or which hasn't been cleaned (with 'emerge \-c') recently, the output may be deceptive.
+.Ip "" 4
+If the same package name appears in all three categories, then it is definitely time to update that package and then run 'emerge \-c'.
+.Ip "" 4
+The \-U, \-N and \-R options may be combined, default is \-UNR
+.SH "AUTHORS"
+.IX Header "AUTHORS"
+Jerry Haltom <ssrit at larvalstage dot net> (dep-clean)
+.br
+Brandon Low <lostlogic at gentoo dot org> (dep-clean)
+.PP
+Paul Belt <gaarde at users dot sourceforge dot net> (man page)
diff --git a/trunk/src/emerge-rsync/AUTHORS b/trunk/src/emerge-rsync/AUTHORS
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/trunk/src/emerge-rsync/AUTHORS
diff --git a/trunk/src/emerge-rsync/ChangeLog b/trunk/src/emerge-rsync/ChangeLog
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/trunk/src/emerge-rsync/ChangeLog
diff --git a/trunk/src/emerge-rsync/README b/trunk/src/emerge-rsync/README
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/trunk/src/emerge-rsync/README
diff --git a/trunk/src/emerge-rsync/emerge-rsync b/trunk/src/emerge-rsync/emerge-rsync
new file mode 100755
index 0000000..224b548
--- /dev/null
+++ b/trunk/src/emerge-rsync/emerge-rsync
@@ -0,0 +1,52 @@
+#!/bin/sh
+BASE=/var/cache
+USE_COLORS=yes
+
+# end user configuration section
+. /etc/make.globals
+BEFORE=$BASE/ebuild-rsync.before
+AFTER=$BASE/ebuild-rsync.after
+NEW=$BASE/ebuild-rsync.new
+REMOVED=$BASE/ebuild-rsync.removed
+
+if [ "$USE_COLORS" == "yes" ]; then
+ RED="\033[;31m"
+ GREEN="\033[;32m"
+ NORMAL="\033[m"
+fi
+
+function portagetree () {
+ find $PORTDIR -type d -mindepth 2 -maxdepth 2
+}
+
+# do it
+portagetree >$BEFORE
+emerge $@ rsync
+portagetree >$AFTER
+diff $BEFORE $AFTER | grep ">" | sed "s/> //g" > $NEW
+diff $BEFORE $AFTER | grep "<" | sed "s/< //g" > $REMOVED
+
+# cleanup
+rm $BEFORE $AFTER
+
+# display new ebuilds
+if ! diff -q $NEW /dev/null >/dev/null; then
+ echo
+ echo New ebuilds:
+ for i in $(cat $NEW); do
+ DESCRIPTION="$i/*.ebuild ${RED}does not exist$NORMAL"
+ EBUILD=$(ls $i/*.ebuild --sort=time 2>/dev/null | head -n 1)
+ [ -z "$EBUILD" ] || . $EBUILD
+ echo -e $GREEN${i##$PORTDIR/}$NORMAL: $DESCRIPTION
+ done
+fi
+
+# display removed ebuilds
+if ! diff -q $REMOVED /dev/null >/dev/null; then
+ echo
+ echo Removed ebuilds:
+ for i in $(cat $REMOVED); do
+ echo -e $RED${i##$PORTDIR/}$NORMAL
+ done
+fi
+
diff --git a/trunk/src/emerge-webrsync/AUTHORS b/trunk/src/emerge-webrsync/AUTHORS
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/trunk/src/emerge-webrsync/AUTHORS
diff --git a/trunk/src/emerge-webrsync/ChangeLog b/trunk/src/emerge-webrsync/ChangeLog
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/trunk/src/emerge-webrsync/ChangeLog
diff --git a/trunk/src/emerge-webrsync/README b/trunk/src/emerge-webrsync/README
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/trunk/src/emerge-webrsync/README
diff --git a/trunk/src/emerge-webrsync/emerge-webrsync b/trunk/src/emerge-webrsync/emerge-webrsync
new file mode 100644
index 0000000..af3e89b
--- /dev/null
+++ b/trunk/src/emerge-webrsync/emerge-webrsync
@@ -0,0 +1,62 @@
+#! /bin/sh
+
+# Copyright(c) 2002 Gentoo Technologies, Inc.
+# Author: Karl Trygve Kalleberg <karltk@gentoo.org>
+# Rewritten from the old, Perl-based emerge-webrsync script
+
+. /etc/make.conf
+
+syncpath="/var/tmp/emerge-webrsync"
+
+if [ ! -d $syncpath ] ; then
+ mkdir -p $syncpath
+fi
+
+cd $syncpath
+
+found=0
+attempts=0
+download=1
+wgetops=-q
+
+if [ "$1" == "-n" ] ; then
+ download=0
+fi
+
+sync_local() {
+ echo Syncing local tree...
+ tar jxf $file
+ rm -f $file
+ rsync -av . /usr
+ rm -rf portage
+}
+
+echo "Fetching most recent snapshot"
+
+while (( $attempts < 40 )) ; do
+
+ day=`date -d "-$attempts day" +"%d"`
+ month=`date -d "-$attempts day" +"%m"`
+ year=`date -d "-$attempts day" +"%Y"`
+
+ file="portage-${year}${month}${day}.tar.bz2"
+
+ if [ -f $file ] && [ $download == 0 ] ; then
+ sync_local
+ exit 0
+ fi
+
+ for i in $GENTOO_MIRRORS ; do
+ url="${i}/snapshots/$file"
+ rm -f $file
+ if (wget $wgetops $url) ; then
+ sync_local
+ exit 0
+ fi
+ done
+ attempts=$[attempts+1]
+done
+
+rm -rf portage
+
+exit 1
diff --git a/trunk/src/epm/AUTHORS b/trunk/src/epm/AUTHORS
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/trunk/src/epm/AUTHORS
diff --git a/trunk/src/epm/ChangeLog b/trunk/src/epm/ChangeLog
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/trunk/src/epm/ChangeLog
diff --git a/trunk/src/epm/README b/trunk/src/epm/README
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/trunk/src/epm/README
diff --git a/trunk/src/epm/epm b/trunk/src/epm/epm
new file mode 100644
index 0000000..408f312
--- /dev/null
+++ b/trunk/src/epm/epm
@@ -0,0 +1,421 @@
+#!/usr/bin/perl -wI.
+# $Id$
+
+use Getopt::Long;
+#use epm;
+
+# Global vars
+my $verbose = 0;
+my $dbpath = '/var/db/pkg';
+my $pkgregex =
+ '^(.+?)'. # name
+ '-(\d+(?:\.\d+)*\w*)'. # version, eg 1.23.4a
+ '((?:(?:_alpha|_beta|_pre|_rc)\d*)?)'. # special suffix
+ '((?:-r\d+)?)$'; # revision, eg r12
+my $root = '/';
+my %opt = (
+ 'dbpath' => \$dbpath,
+ 'root' => \$root,
+ 'v' => \$verbose,
+);
+my $exitcode = 0;
+
+##############################################
+#
+# UTILITY FUNCTIONS
+#
+##############################################
+sub verb {
+ print STDERR map "-- $_\n", @_ if $verbose;
+}
+
+sub vverb {
+ print STDERR map "-- $_\n", @_ if $verbose > 1;
+}
+
+##############################################
+#
+# QUERY MODE
+#
+##############################################
+sub query {
+ verb "query mode";
+ verb "actually Verify mode" if $opt{'V'};
+
+ # Implied -l similar to rpm
+ $opt{'dump'} and $opt{'l'} = 1;
+ $opt{'d'} and $opt{'l'} = 1;
+ $opt{'c'} and $opt{'l'} = 1;
+
+ # @dgrps contains a list of all the groups at dbpath
+ # @dpkgs contains a list of all the packages at dbpath/@dgrps
+ # %dpkggrp contains a mapping of pkg=>grp
+ # %dnampkg contains a mapping of nam=>@pkg (libxml=>[libxml-1.8.13])
+ # @pkgs is the list of packages being queried
+ # %dfilepkg is a mapping of filename=>@pkg
+ my (@dgrps, @dpkgs, %dpkggrp, %dnampkg, @pkgs);
+
+ # Read all groups in the db (except for virtual)
+ opendir D, $dbpath or
+ die "epm: Database not found at $dbpath\n";
+ @dgrps = grep {-d "$dbpath/$_" && !/^\./ && $_ ne 'virtual'} readdir D;
+ closedir D;
+ verb "read ".@dgrps." groups from $dbpath"; vverb @dgrps;
+
+ # Read all pkgs in the db
+ for my $g (@dgrps) {
+ opendir D, "$dbpath/$g" or
+ die "epm: Error reading directory $dbpath/$g\n";
+ my @dp = grep {-d "$dbpath/$g/$_" && !/^\./} readdir D;
+ verb "read ".@dp." pkgs in group $g"; vverb @dp;
+ @dpkggrp{@dp} = ($g) x @dp;
+ push @dpkgs, @dp;
+ }
+ vverb "package to group associations:";
+ vverb map " $_ => $dpkggrp{$_}", keys %dpkggrp;
+
+ # Create association of names => pkgs
+ for my $p (@dpkgs) {
+ $p =~ /$pkgregex/o || $dpkggrp{$p} eq 'virtual' ||
+ die "epm: Could't parse name/version/suffix/rev from $p";
+ # $2, $3, $4 aren't used right now, but they're in the regex
+ # for the sake of completeness.
+ push @{$dnampkg{$1}}, $p;
+ }
+
+ # File-based query
+ if ($opt{'f'}) {
+ # Search through CONTENTS for elements in ARGV. Building an
+ # index would be bad because it would be HUGE.
+ for my $a (@ARGV) {
+ my $found = 0;
+ # Trim trailing slashes from directories
+ $a =~ s#/*$##;
+ # TODO: If it's a relative pathname, then figure out
+ # the full pathname
+ if ($a !~ m#^/#) { }
+ # TODO: stat the file here so that we can determine later
+ # what package the file currently belongs to
+ for my $p (@dpkgs) {
+ my ($CONTENTS, @files);
+ $CONTENTS = "$dbpath/$dpkggrp{$p}/$p/CONTENTS";
+ unless (-s $CONTENTS) {
+ verb "skipping empty/nonexistent $CONTENTS";
+ next;
+ }
+ open F, "<$CONTENTS" or die "epm: Can't open $CONTENTS\n";
+ @files = <F>;
+ close F;
+ # Check this list of files for the current query
+ for my $f (@files) {
+ $f = (split ' ', $f)[1];
+ next unless $f eq $a;
+ $found = 1;
+ # If not doing -qlf, then print the package name
+ unless ($opt{'l'}) {
+ # If doing -qGf, then include the group name
+ print $opt{'G'} ? "$dpkggrp{$p}/$p\n" : "$p\n";
+ }
+ push @pkgs, $p;
+ }
+ }
+ unless ($found) {
+ print "file $a is not owned by any package\n";
+ $exitcode = 1;
+ }
+ }
+ # Clear out ARGV so queries below don't get confused
+ @ARGV = ();
+ }
+
+ # Group-based query
+ # Note that if -qfg specified, then rpm prioritizes -qf over -qg,
+ # so we do too.
+ elsif ($opt{'g'}) {
+ for my $a (@ARGV) {
+ verb "checking for packages in group $a";
+ my @l = grep $dpkggrp{$_} eq $a, @dpkgs;
+ vverb "packages in group $a:";
+ vverb " ", join "\n ", @l;
+ unless (@l) {
+ print "group $a does not contain any packages\n";
+ $exitcode = 1;
+ }
+ push @pkgs, @l;
+ }
+ # Clear out ARGV so queries below don't get confused
+ @ARGV = ();
+ }
+
+ # Package-based query (how does this work with emerge?)
+ if ($opt{'p'}) {
+ die "epm: Sorry, package-based query not yet supported\n";
+ }
+
+ # Query on all packages
+ if ($opt{'a'}) {
+ die "epm: extra arguments given for query of all packages\n" if @ARGV;
+ @pkgs = @dpkgs;
+ }
+ elsif (@pkgs) {
+ # must have been populated by, for instance, -qf
+ }
+ else {
+ for my $a (@ARGV) {
+ if ($a =~ /$pkgregex/o) {
+ verb "$a matches pkgregex";
+ vverb "name=$1, version=$2, suffix=$3, revision=$4";
+ push @pkgs, $a;
+ next;
+ }
+ if (defined $dnampkg{$a}) {
+ verb "$a found in dnampkg";
+ vverb @{$dnampkg{$a}};
+ push @pkgs, @{$dnampkg{$a}};
+ next;
+ }
+ print "package $a is not installed\n";
+ next;
+ }
+ }
+
+ # Do a file listing of the requested packages
+ if ($opt{'l'}) {
+ for my $p (@pkgs) {
+ my $CONTENTS = "$dbpath/$dpkggrp{$p}/$p/CONTENTS";
+ open F, "<$CONTENTS" || die "epm: Can't open $CONTENTS\n";
+ my @files = <F>;
+ close F;
+ # Trim @files if config files requested
+ if ($opt{'c'}) {
+ # Read in CONFIG_PROTECT from /etc/make.{global,conf}
+ my @CONFIG_PROTECT = split ' ',
+ `. /etc/make.globals;
+ . /etc/make.conf;
+ echo \$CONFIG_PROTECT`;
+ die "CONFIG_PROTECT is empty" unless @CONFIG_PROTECT;
+ my $confprotre = join '|', @CONFIG_PROTECT;
+ @files = grep {
+ (split ' ', $_)[1] =~ /^($confprotre)/o
+ } @files;
+ }
+ # Trim @files if doc files requested
+ if ($opt{'d'}) {
+ # We don't have a variable like CONFIG_PROTECT to work
+ # with, so just fake it... :-)
+ my $docre = '/usr/share/doc|/usr/share/man';
+ @files = grep {
+ (split ' ', $_)[1] =~ m/^($docre)/o
+ } @files;
+ }
+ # If this is a dump query, then print the entire array
+ if ($opt{'dump'}) {
+ print @files;
+ }
+ # Otherwise do some work so that intermediate directories
+ # aren't listed
+ else {
+ for (my $i=0; $i < @files; $i++) {
+ my ($f1) = $files[$i];
+ $f1 = (split ' ', $f1)[1];
+ if ($i < @files-1) {
+ my $f2 = $files[$i+1];
+ $f2 = (split ' ', $f2)[1];
+ vverb "Comparing $f1 to $f2";
+ next if $f2 =~ m#^\Q$f1\E/#;
+ }
+ print $f1, "\n";
+ }
+ }
+ }
+ }
+
+ # If not another type of listing, then simply list the packages
+ if (!$opt{'l'} && !$opt{'f'}) {
+ # If doing -qG, then include the group name
+ print map(($opt{'G'} ? "$dpkggrp{$_}/$_\n" : "$_\n"), @pkgs);
+ }
+}
+
+##############################################
+#
+# ERASE MODE
+#
+##############################################
+sub erase {
+ verb "erase mode";
+ verb "(testing)" if $opt{'test'};
+
+ # Catch empty command-line
+ die "epm: no packages given for uninstall\n" unless @ARGV;
+
+ # Must be root to erase; rpm just lets permissions slide but I don't
+ if ($> != 0) {
+ print STDERR "Must be root to remove packages from the system\n";
+ $exitcode = 1;
+ return;
+ }
+
+ # Erase everything listed on the command-line. Give an error
+ # message on bogus names, but continue anyway, a la rpm. Note
+ # that for epm, we require the group name...
+ for my $a (@ARGV) {
+ unless ($a =~ '/') {
+ print STDERR "error: $a does not contain group/ prefix\n";
+ $exitcode = 1;
+ next;
+ }
+ my $p = $a;
+ $p =~ s,^.*/,,; # remove the group
+ unless (-f "$dbpath/$a/$p.ebuild") {
+ print STDERR "error: package $a is not installed\n";
+ $exitcode = 1;
+ next;
+ }
+ my @cmd = ('ebuild', "$dbpath/$a/$p.ebuild", 'unmerge');
+ print STDERR join(" ", @cmd), "\n";
+ unless ($opt{'test'}) {
+ system @cmd;
+ die "epm: Fatal error running ebuild; aborting\n" if $?;
+ }
+ }
+}
+
+##############################################
+#
+# MAIN
+#
+##############################################
+
+# Syntax string for errors
+my $syntax = <<EOT;
+EPM version 0.1
+Copyright (C) 2001 - Aron Griffis
+This program may be freely redistributed under the terms of the GNU GPL
+
+Usage:
+ --help - print this message
+ *--version - print the version of rpm being used
+
+ All modes support the following arguments:
+ -v - be a little more verbose
+ -vv - be incredibly verbose (for debugging)
+
+ -q, --query - query mode
+ --dbpath <dir> - use <dir> as the directory for the database
+ --root <dir> - use <dir> as the top level directory
+ Package specification options:
+ -a, --all - query all packages
+ -f <file>+ - query package owning <file>
+ *-p <packagefile>+ - query (uninstalled) package <packagefile>
+ *--triggeredby <pkg> - query packages triggered by <pkg>
+ *--whatprovides <cap> - query packages which provide <cap> capability
+ *--whatrequires <cap> - query packages which require <cap> capability
+ -g <group>+ --group <group>+ - query packages in group <group>
+ Information selection options:
+ *-i, --info - display package information
+ -l - display package file list
+ -G, --showgroup - display group name in output (not in rpm)
+ -d - list only documentation files (implies -l)
+ -c - list only configuration files (implies -l)
+ --dump - show all verifiable information for each file
+ (must be used with -l, -c, or -d)
+ *--provides - list capabilities package provides
+ *-R, --requires - list package dependencies
+ *--scripts - print the various [un]install scripts
+
+ --erase <package>
+ -e <package> - erase (uninstall) package
+ *--allmatches - remove all packages which match <package>
+ (normally an error is generated if <package>
+ specified multiple packages)
+ --dbpath <dir> - use <dir> as the directory for the database
+ *--justdb - update the database, but do not modify the
+ filesystem
+ *--nodeps - do not verify package dependencies
+ *--noorder - do not reorder package installation to satisfy
+ dependencies
+ *--noscripts - do not execute any package specific scripts
+ *--notriggers - don't execute any scripts triggered by this
+ package
+ --root <dir> - use <dir> as the top level directory
+ --test - don't uninstall, but tell what would happen
+
+ -V, -y, --verify - verify a package installation using the same
+ package specification options as -q
+ --dbpath <dir> - use <dir> as the directory for the database
+ --root <dir> - use <dir> as the top level directory
+ --nodeps - do not verify package dependencies
+ --nomd5 - do not verify file md5 checksums
+ --nofiles - do not verify file attributes
+EOT
+
+# Allow bundling of options since rpm does
+Getopt::Long::Configure ("bundling");
+
+# Parse the options on the cmdline. Put the short versions first in
+# each optionstring so that the hash keys are created using the short
+# versions. For example, use 'q|query', not 'query|q'.
+my $result = GetOptions(
+ \%opt,
+ 'help', # help message
+ 'v+', # verbose, more v's for more verbosity
+
+ 'q|query', # query mode
+ 'dbpath=s', # use <dir> as the directory for the database
+ 'root=s', # use <dir> as the top level directory
+ # Package specification options:
+ 'a|all', # query all packages
+ 'f', # query package owning file(s)
+ 'p', # query (uninstalled) package
+ 'g|group', # query packages in group(s)
+ 'whatprovides', # query packages which provide capability
+ 'whatrequires', # query packages which require capability
+ # Information selection options:
+ 'i|info', # display package information
+ 'l', # display package file list
+ 'd', # list documentation files (implies -l)
+ 'c', # list configuration files (implies -l)
+ 'dump', # show all verifiable information for each file
+ # (must be used with -l, -c, or -d)
+ 'R|requires', # list package dependencies
+ 'scripts', # print the various [un]install scripts
+ 'G|showgroup', # include group name in output
+
+ 'e|erase', # erase mode
+ 'test', # don't uninstall, but tell what would happen
+
+ 'V|y|verify', # verify a package installation using the same
+ # package specification options as -q
+ 'nodeps', # do not verify package dependencies
+ 'nomd5', # do not verify file md5 checksums
+ 'nofiles', # do not verify file attributes
+);
+
+# Handle help message
+if ($opt{'help'}) { print $syntax; exit 0 }
+
+# Determine which mode we're running in; make sure it's valid.
+# (q)uery
+# (V)erify
+# (i)nstall
+# (U)pgrade
+# (e)rase
+# (b)uild
+# other
+if ((defined $opt{"q"} || 0) +
+ (defined $opt{"V"} || 0) +
+ (defined $opt{"i"} || 0) +
+ (defined $opt{"U"} || 0) +
+ (defined $opt{"e"} || 0) +
+ (defined $opt{"b"} || 0) != 1) {
+ die "One mode required, and only one mode allowed\n";
+}
+
+# Query mode
+if ($opt{'q'}) { query(); exit $exitcode }
+if ($opt{'V'}) { query(); exit $exitcode }
+if ($opt{'e'}) { erase(); exit $exitcode }
+
+# Other modes not implemented yet
+die "epm: Sorry, this mode isn't implemented yet. Check back later! :-)\n";
diff --git a/trunk/src/etc-update/AUTHORS b/trunk/src/etc-update/AUTHORS
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/trunk/src/etc-update/AUTHORS
diff --git a/trunk/src/etc-update/ChangeLog b/trunk/src/etc-update/ChangeLog
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/trunk/src/etc-update/ChangeLog
diff --git a/trunk/src/etc-update/README b/trunk/src/etc-update/README
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/trunk/src/etc-update/README
diff --git a/trunk/src/pkg-clean/AUTHORS b/trunk/src/pkg-clean/AUTHORS
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/trunk/src/pkg-clean/AUTHORS
diff --git a/trunk/src/pkg-clean/ChangeLog b/trunk/src/pkg-clean/ChangeLog
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/trunk/src/pkg-clean/ChangeLog
diff --git a/trunk/src/pkg-clean/README b/trunk/src/pkg-clean/README
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/trunk/src/pkg-clean/README
diff --git a/trunk/src/pkg-clean/pkg-clean b/trunk/src/pkg-clean/pkg-clean
new file mode 100644
index 0000000..e311f43
--- /dev/null
+++ b/trunk/src/pkg-clean/pkg-clean
@@ -0,0 +1,100 @@
+#!/usr/bin/python
+# vim: set ts=4 sw=4:
+# Copyright 2002 Gentoo Technologies, Inc.
+# Distributed under the terms of the GNU General Public License, v2 or later
+# Author: Leo Lipelis <aeoo@gentoo.org>
+# Author: Karl Trygve Kalleberg <karltk@gentoo.org>
+
+import commands
+import re
+import sys
+import string
+import time
+import os
+
+# constants for package tuples that are stored in pkg_hash
+PKG_TIME = 0 # number of seconds for ctime function
+PKG = 1 # package full path as accepted by ebuild
+PKG_NAME = 2 # package name as accepted by emerge
+
+(status, pkg_files) = commands.getstatusoutput(
+ "find /var/db/pkg -iname '*.ebuild' -printf '%T@ %p\n' | sort -n")
+
+pkg_file_list = pkg_files.splitlines()
+
+pkg_hash = {}
+for time_pkg_pair in pkg_file_list:
+ (pkg_time, pkg) = time_pkg_pair.split()
+ pkg_time = string.atoi(pkg_time)
+ # This covers developer trees with not-accepted categories
+ tmp_name = re.match(r'/var/db/pkg/(.*/.*)/.*', pkg)
+ if not tmp_name: continue
+ pkg_name = tmp_name.group(1)
+ tmp_core = re.match(r'(.*)-\d.*', pkg_name)
+ if not tmp_core: continue
+ pkg_core = tmp_core.group(1)
+ if pkg_hash.has_key(pkg_core):
+ pkg_hash[pkg_core].append((pkg_time, pkg, pkg_name))
+ else:
+ pkg_hash[pkg_core] = [(pkg_time, pkg, pkg_name)]
+
+total_len = len(pkg_hash.keys())
+curpkg = 0
+tmpname = os.tmpnam()
+assume_yes = 0
+
+if len(sys.argv) > 1:
+ if sys.argv[1] in ["-y", "--yes"]:
+ assume_yes = 1
+ elif sys.argv[1] in ["-h", "--help"]:
+ print """pkg-clean [options]
+
+-y, --yes Don't ask for individual confirmation before unmerging; assume yes.
+"""
+ sys.exit(0)
+
+for pkg_core in pkg_hash.keys():
+ print "Examining %s:" % (pkg_core)
+ if len(pkg_hash[pkg_core]) < 2:
+ continue
+ unmerged_indexes = []
+
+ curpkg += 1
+ choices = ""
+ idx = 1
+ for pkg_tuple in pkg_hash[pkg_core]:
+ choices += " %d \"%s %s\" 0" % \
+ (idx, time.ctime(pkg_tuple[PKG_TIME]),
+ pkg_tuple[PKG_NAME])
+ idx += 1
+
+ params = "dialog --separate-output --backtitle \"pkg-clean processing package %d of %d\" " % ( curpkg, total_len)
+ params += "--checklist \"Select which package(s) to unmerge\" 20 70 12" + choices
+ res = os.system(params + " 2> " + tmpname)
+ if res:
+ sys.exit(0)
+
+ ins = open(tmpname)
+ for j in ins.readlines():
+ idx = string.atoi(j)
+ if idx == 0:
+ break
+
+ full_path = pkg_hash[pkg_core][idx-1][PKG]
+ ebuild = string.replace(full_path, "/var/db/pkg/", "")
+
+ if not assume_yes:
+ params = "dialog --backtitle \"" + ebuild + "\" " + \
+ "--yesno \"Are you sure you want to unmerge " + ebuild + " ?\" 20 70"
+ res = os.system(params)
+ else:
+ res = 0
+
+ if res == 0:
+ (status, unmerge_out) = commands.getstatusoutput(
+ "ebuild %s unmerge" % (full_path))
+ print unmerge_out
+ time.sleep(2)
+ if status != 0:
+ sys.exit(status)
+ ins.close()
diff --git a/trunk/src/pkg-size/AUTHORS b/trunk/src/pkg-size/AUTHORS
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/trunk/src/pkg-size/AUTHORS
diff --git a/trunk/src/pkg-size/ChangeLog b/trunk/src/pkg-size/ChangeLog
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/trunk/src/pkg-size/ChangeLog
diff --git a/trunk/src/pkg-size/README b/trunk/src/pkg-size/README
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/trunk/src/pkg-size/README
diff --git a/trunk/src/pkg-size/pkg-size b/trunk/src/pkg-size/pkg-size
new file mode 100644
index 0000000..96cdff2
--- /dev/null
+++ b/trunk/src/pkg-size/pkg-size
@@ -0,0 +1,52 @@
+#!/bin/sh
+
+# Copyright(c) 2002, Gentoo Technologies, Inc
+# Author: Karl Trygve Kalleberg <karltk@gentoo.org>
+
+spec=$1
+
+name=`echo $1 | sed "s/\([^/]*\)\///"`
+category=`echo $1 | sed "s/\/.*//"`
+
+if [ "$category" == "$name" ] ; then
+ category=
+fi
+
+function tryfile() {
+ local foo
+ foo=/var/db/pkg/$1/CONTENTS
+ bar=`ls $foo 2> /dev/null`
+ for i in $bar ; do
+ if [ -f "$i" ] ; then
+ echo $i
+ break
+ fi
+ done
+}
+
+file=`tryfile "${category}/${name}"`
+if [ -z $file ] ; then
+ file=`tryfile "${category}/${name}*"`
+ if [ -z $file ] ; then
+ file=`tryfile "${category}*/${name}"`
+ if [ -z $file ] ; then
+ file=`tryfile "${category}*/${name}*"`
+ if [ -z $file ] ; then
+ echo "!!! Package resembling ${category}/${name} not found"
+ exit 1
+ fi
+ fi
+ fi
+fi
+
+pkgname=`echo $file | sed -e "s:\/var\/db\/pkg\/::" -e "s:\/CONTENTS::"`
+
+totals=`cat $file|grep "obj"|awk '{ print $2 }' | sed "s/ /\\ /" | xargs du -scb | grep total | cut -f 1`
+
+size=0
+for i in $totals ; do
+ size=$[size+i]
+done
+
+echo "$pkgname $size ($[size/1024]KB)"
+
diff --git a/trunk/src/portage-statistics/AUTHORS b/trunk/src/portage-statistics/AUTHORS
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/trunk/src/portage-statistics/AUTHORS
diff --git a/trunk/src/portage-statistics/ChangeLog b/trunk/src/portage-statistics/ChangeLog
new file mode 100644
index 0000000..b83850b
--- /dev/null
+++ b/trunk/src/portage-statistics/ChangeLog
@@ -0,0 +1,2 @@
+2002-03-22 Karl Trygve Kalleberg <karltk@gentoo.org>
+ * Threw away the coverage scripts, replaced with this.
diff --git a/trunk/src/portage-statistics/README b/trunk/src/portage-statistics/README
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/trunk/src/portage-statistics/README
diff --git a/trunk/src/portage-statistics/histogram.awk b/trunk/src/portage-statistics/histogram.awk
new file mode 100644
index 0000000..146f4e4
--- /dev/null
+++ b/trunk/src/portage-statistics/histogram.awk
@@ -0,0 +1,14 @@
+{
+ match($0, "<([A-Za-z0-9.-]+@[A-Za-z0-9.-]+)>")
+ val=substr($0, RSTART, RLENGTH)
+ arr[val]++
+ total++
+}
+
+END {
+ for (x in arr) {
+ printf("%35s: %-4d of %-4d (%-4.2f%)\n",x,arr[x],total,arr[x]*100/total)
+ mytot += arr[x]
+ }
+ printf("%35s: %-4d of %-4d (%-4.2f%)\n","TOTAL",mytot, total,mytot*100/total)
+} \ No newline at end of file
diff --git a/trunk/src/portage-statistics/pst-author-coverage b/trunk/src/portage-statistics/pst-author-coverage
new file mode 100755
index 0000000..6f7451a
--- /dev/null
+++ b/trunk/src/portage-statistics/pst-author-coverage
@@ -0,0 +1,12 @@
+#! /bin/sh
+
+if [ -z "$1" ] ; then
+ echo "Usage: $1 <author@site.tld>"
+ exit 1
+fi
+
+numebuilds=`find /usr/portage/ -name "*.ebuild" | wc -l`
+numebuildsfor=`find /usr/portage/ -name "*.ebuild" | xargs grep "$1" | wc -l`
+
+pct=`echo "scale=2 ; $numebuildsfor*100/$numebuilds" | bc`
+printf "%25s: %-4d of %-4d (%-4.2f)\n" $1 $numebuildsfor $numebuilds $pct
diff --git a/trunk/src/portage-statistics/pst-package-count b/trunk/src/portage-statistics/pst-package-count
new file mode 100755
index 0000000..f7e02e4
--- /dev/null
+++ b/trunk/src/portage-statistics/pst-package-count
@@ -0,0 +1,9 @@
+#! /bin/sh
+
+pcnt=`find /usr/portage/ -type f -name "*.ebuild" | sed "s/-[0-9].*//" | sort | uniq | wc -l`
+numebuilds=`find /usr/portage/ -type f -name "*.ebuild" | wc -l`
+numcat=`find /usr/portage/ -type d -name "*-*" -maxdepth 1 | wc -l`
+
+echo "Number of categories : $numcat"
+echo "Number of ebuilds : $numebuilds"
+echo "Unique packages : $pcnt"
diff --git a/trunk/src/portage-statistics/pst-total-coverage b/trunk/src/portage-statistics/pst-total-coverage
new file mode 100755
index 0000000..0da5c6e
--- /dev/null
+++ b/trunk/src/portage-statistics/pst-total-coverage
@@ -0,0 +1,7 @@
+#! /bin/sh
+
+
+find /usr/portage/ -name "*.ebuild" | \
+ xargs egrep -i "<[a-z]+@[a-z\.]+>" | \
+ awk -f /usr/share/gentoolkit/histogram.awk | \
+ sort -n +1 -r
diff --git a/trunk/src/qpkg/AUTHORS b/trunk/src/qpkg/AUTHORS
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/trunk/src/qpkg/AUTHORS
diff --git a/trunk/src/qpkg/ChangeLog b/trunk/src/qpkg/ChangeLog
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/trunk/src/qpkg/ChangeLog
diff --git a/trunk/src/qpkg/README b/trunk/src/qpkg/README
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/trunk/src/qpkg/README
diff --git a/trunk/src/qpkg/qpkg b/trunk/src/qpkg/qpkg
new file mode 100644
index 0000000..b409f09
--- /dev/null
+++ b/trunk/src/qpkg/qpkg
@@ -0,0 +1,473 @@
+#!/bin/sh
+#
+# qpkg - query portage package system for various information
+#
+# Copyright (c) Vitaly Kushneriuk <vitaly_kushneriuk@yahoo.com>
+# This program is distributed under the terms of GPL version 2.
+#
+# Maintainer: Brandon Low <lostlogic@gentoo.org>
+#
+# $Header$
+ID='$Id$'
+VERSION=0.`echo ${ID} | cut -d\ -f3`
+
+PROG=`basename ${0}`
+
+# Parse args
+verb=0
+group="*"
+while [ ${#} -gt 0 ]
+do
+ a=${1}
+ shift
+ case "${a}" in
+
+ -h|--help)
+ usage=y
+ break
+ ;;
+
+ -i|--info)
+ info=y
+ ;;
+
+ -d|--dups)
+ dups=y
+ inst=y
+ ;;
+
+ -q|--query-deps)
+ query=y
+ ;;
+
+ -s|--slot)
+ slot=y
+ ;;
+
+ -f|--find-file)
+ ffind=y
+ inst=y
+ ;;
+
+ -fp|--find-pattern)
+ ffind=y
+ fpat=y
+ inst=y
+ ;;
+
+ -I|--installed)
+ inst=y
+ ;;
+
+ -U|--uninstalled)
+ uninst=y
+ ;;
+
+ -g|--group)
+ group=$1
+ shift
+ ;;
+
+ -l|--list)
+ list=y
+ inst=y
+ ;;
+
+ -ct|--check-time|-tc|--time-check)
+ tcheck=y
+ inst=y
+ ;;
+
+ -cm|--check-md5|-mc|--md5-check)
+ mcheck=y
+ inst=y
+ ;;
+
+ -c|--check)
+ mcheck=y
+ tcheck=y
+ inst=y
+ ;;
+
+ -v|--verbose)
+ let $((verb++))
+ ;;
+
+ -vv)
+ let $((verb++))
+ let $((verb++))
+ ;;
+
+ -nc|--no-color|--nocolor|--no-colors|--nocolors)
+ nocolor=y
+ ;;
+
+ -*)
+ echo -e ${CY}${PROG}${NO}:${YL} Invalid option ${RD}$a 1>&2
+ usage=y
+ break
+ ;;
+ *)
+ if [ -n "${arg}" ]; then
+ echo -e ${CY}${PROG}: ${YL}Only one argument supported
+ usage=y
+ break
+ fi
+ arg=$a
+ ;;
+
+ esac
+done
+
+#This is a dumb way to handle things, take it out next time
+T="\t"
+
+#Set up colors
+if [ ! "${nocolor}" ]; then
+ NO="\x1b[0;0m"
+ BR="\x1b[0;01m"
+ CY="\x1b[36;01m"
+ RD="\x1b[31;01m"
+ GR="\x1b[32;01m"
+ YL="\x1b[33;01m"
+ BL="\x1b[34;01m"
+ STAR=" *"
+elif [ ! "${inst}" ] && [ ! "${uninst}" ]; then
+ STAR=" *"
+fi
+
+
+# check for option conflicts
+if [ "${inst}" -a "${uninst}" \
+ -o \( "${ffind}" -o "${list}" -o "${tcheck}" -o "${mcheck}" \) \
+ -a "${uninst}" ]; then
+ echo -e ${CY}${PROG}${NO}:${YL} conflicting options/modes${NO}
+ usage=y
+fi
+
+if [ "${usage}" ]; then
+ echo -e "${CY}${PROG} v. ${VERSION}${NO}
+
+${CY}${PROG}${NO} is GenToolKit's \"query package\" tool, using it, you can
+find packages owning files on your filesystem, check the integrity
+of installed packages, and do other queries against installed or
+uninstalled packages.
+
+${BR}Usage:
+${T}${CY}${PROG}${NO} [${BR}options${NO}] [${YL}pkgname${NO}] [${BL}-g${YL} group${NO}] [${BL}-f${YL} <file>${NO}|${BL}-fp${YL} <patern>${NO}]
+${T}${CY}${PROG}${NO} ${BL}--dups${NO} [${BL}--slot${NO}]
+${T}${CY}${PROG}${NO} ${BL}--help${NO}
+
+${BR}Duplicate Locating:
+ ${BL}-d, --dups${NO}${T}${T}print packages that have multiple versions installed
+ ${BL}-s, --slot${NO}${T}${T}make ${BL}-d${NO} SLOT only print dups of the same SLOT
+
+${BR}Package Selection:
+ ${BL}-f, --find-file${NO}${T}finds package that owns file <file>
+ ${BL}-fp, --find-pattern${NO}${T}finds to package that owns file matching *<pattern>*
+ ${BL}-I, --installed${NO}${T}Include${YL} only${NO} installed packages
+ ${BL}-U, --uninstalled${NO}${T}Include${YL} only${NO} uninstalled packages
+ ${BL}-g, --group${NO}${T}${T}Find by goup (can be combined with other searches)
+
+${BR}Information Selection:
+ ${BL}-l, --list${NO}${T}${T}List package content
+ ${BL}-i, --info${NO}${T}${T}Get package description and home page.
+ ${BL}-ct, --check-time${NO}
+ ${BL}-tc, --time-check${NO}${T}Verify package files timestamps
+ ${BL}-cm, --check-md5${NO}
+ ${BL}-mc, --md5-check${NO}${T}Verify package files md5
+ ${BL}-c, --check${NO}${T}${T}Verify mtimes${YL} and${NO} md5.
+ ${BL}-q, --query-deps${NO}${T}display all installed packages
+${T}${T}${T}depending on selected packages
+
+${BR}Operation Modifiers:
+ ${BL}-nc, --no-color${NO}${T}don't use colors
+ ${BL}-v, --verbose${NO}${T}Be more verbose [ can be repeated twise ]
+ ${BL}-vv${NO}${T}${T}${T}Same as ${BL}-v -v${NO}
+
+${YL}Notes${NO}:
+${YL}*${NO} ${BL}-f${NO}, ${BL}-fp, ${BL}-d${NO}, ${BL}-l${NO}, ${BL}-ct${NO}, ${BL}-cm${NO}, and ${BL}-c${NO} apply only to installed packages.
+${YL}*${NO} Short options may not be combined on the command-line, yet.
+${YL}*${NO} The operation of some flags has been changed by the
+ stripping of version numbers from some output to see
+ the version numbers play with ${BL}-v${NO} and ${BL}-vv${NO}.
+${YL}*${NO} When using${BL} -f${NO} with ${BL}-l${NO} or ${BL}--check.. -v${NO} options, only
+ matching files will be displayed, unless ${BL}-v${NO} is doubled,
+ (yet more verbose) or ${BL}-vv${NO} is used.
+
+
+${YL}Examples${NO}:
+ ${PROG} --dups print duplicates oldest first
+ ${PROG} --dups -v .. with versions
+ ${PROG} print list of installed packages
+ ${PROG} porta -I print versions of installed portage
+ ${PROG} porta -i .. + versions in portage tree + descriptions
+ and homepages
+ ${PROG} gawk -c -v check integrity all installed versions of gawk
+ the older will have \"damaged\" files.
+ ${PROG} -f /bin/ls print package(s) that own /bin/ls
+"
+ exit
+fi
+
+#For the --dups switch only
+if [ "${dups}" ]; then
+ #First dig out the list of packages with duplicates
+ find /var/db/pkg -iname "*${arg}*.ebuild" 2> /dev/null > /tmp/qpkg.lst
+ dups=`cat /tmp/qpkg.lst | cut -f7 -d/ |
+ sed -e 's:\.ebuild$::; s:-r[0-9]*$::; s:-[^-]*$::; /^$/d' |
+ sort |
+ uniq -d`
+
+ #Next get all the exact versions
+ duppak=`cat /tmp/qpkg.lst | fgrep "${dups}"`
+
+ #Now cut that down to the directory name so we can be smart
+ dirs=`sed -e 's:/[^/]*$::' /tmp/qpkg.lst`
+
+ #Go through each package's DB and create a sortable file
+ #to play with
+ declare -i defcount=`cat /var/cache/edb/counter`
+ for DIR in ${dirs}
+ do #Package COUNTER
+ NUM=`cat "${DIR}/COUNTER" 2> /dev/null`
+ [ -z "${NUM}" ] && NUM=defcount
+ #Package slot if requested
+ [ ${slot} ] && SLOT=`cat "${DIR}/SLOT"`
+ #Package fullname
+ PKG=`ls --color=no -1 ${DIR}/*.ebuild|cut -f5,7 -d"/"`
+ #Package basename
+ NAME=`echo "${PKG}"|sed -e 's:\.ebuild$::; s:-r[0-9]\+$::; s:-[0-9].*$::'`
+ echo "${NUM} ${PKG} ${NAME}${SLOT}"
+ #Finish loop, and sort that nice sortable file based on
+ #installation order, and then based on package basename
+ #bash hates me so I decided to use a temp file
+ done |sort -t" " -k3 -k1g,2|uniq -D -f2 > /tmp/qpkg.lst
+ duppak=`cat /tmp/qpkg.lst`
+ rm /tmp/qpkg.lst
+
+ #If max verbosity is set output with full path to each ebuild
+ if [ "${verb}" -gt 1 ]; then
+ echo -n "${duppak}"|cut -f2 -d" "| \
+ sed -e "s:^:${BL}/var/db/pkg/${BR}:" \
+ -e "s:\(/\)\([^/]*\)\(.ebuild\):\1${CY}\2${NO}\1\2\3:"
+
+ #If normal verbosity output package group, package name and package version
+ elif [ "${verb}" -gt 0 ]; then
+ echo -n "${duppak}"|cut -f2 -d" "| \
+ sed -e "s:\(^[^/]*/\)\(.*\)\(\.ebuild\):${BR}\1${CY}\2${NO}:"
+
+ #Otherwise just output package group and package name
+ else
+ echo -n "${duppak}"|cut -f2 -d" "| \
+ sed -e "s:-r[0-9]\+$::" \
+ -e "s:-[0-9].*$::" \
+ -e "s:\(^[^/]*/\)\(.*\):${BR}\1${CY}\2${NO}:"|uniq
+ fi
+ exit
+fi
+
+# get list of ebuilds to work on
+if [ "${ffind}" ]; then
+ # file find mode - list all ebuilds for
+ # package/CONTENTS containing <arg>
+ if [ "${fpat}" ]; then
+ dirs=`ls /var/db/pkg/${group}/*/CONTENTS \
+ | xargs grep -l "${arg}" \
+ | xargs --no-run-if-empty -n 1 dirname`
+ else
+ dirs=`ls /var/db/pkg/${group}/*/CONTENTS \
+ | xargs grep -l " ${arg}\( .*\)*$" \
+ | xargs --no-run-if-empty -n 1 dirname`
+ fi
+ ipak=`(
+ for d in ${dirs} -;do
+ [ "-" = "$d" ] && break
+ ls ${d}/*.ebuild
+ done)`
+else
+ # normal mode - list ebuilds for ebuild name containing <arg>
+
+ # installed packages
+ if [ ! "${uninst}" ]; then
+ ipak=`find /var/db/pkg/ -iname "*.ebuild" 2>/dev/null`
+ if [[ ${group} != "*" ]]; then
+ ipak=`echo ${ipak}|sed -e "s: :\n:g"|grep ${group}`
+ fi
+ if [ ${arg} ]; then
+ ipak=`echo ${ipak}|sed -e "s: :\n:g"|grep ${arg}`
+ fi
+ fi
+ # not installed packages (yet:-)
+ if [ ! "${inst}" ]; then
+ upak=`find /usr/portage/ -iname "*.ebuild" 2>/dev/null|grep -v --regex="/usr/portage/[^/]*\.ebuild"`
+ if [[ ${group} != "*" ]]; then
+ upak=`echo ${upak}|sed -e "s: :\n:g"|grep ${group}`
+ fi
+ if [ ${arg} ]; then
+ upak=`echo ${upak}|sed -e "s: :\n:g"|grep ${arg}`
+ fi
+ fi
+fi
+
+X="\([^/]*\)"
+
+for p in ${ipak} ${upak} -;do
+ [ "${p}" = "-" ] && break
+
+ # cut common prefix from ebuild name and mark installed/uninstalled packages
+ # Note: iii/uuu will be replaced by the pipe at the end
+ n=`echo $p | sed -e "s:^/var/db/pkg/${X}/${X}/${X}.ebuild:iii \1/\3:" \
+ -e "s:^/usr/portage/${X}/${X}/${X}\.ebuild:uuu \1/\3:"`
+ d=`dirname ${p}`
+ echo ${n}
+ if [ ${verb} -gt 1 ];then
+ echo "vvv ${p}"
+ fi
+
+ if [ "${info}" ]; then
+ home=`grep HOMEPAGE ${p}| cut -d\" -f2`
+ desc=`grep DESCRIPTION ${p}| cut -d\" -f2`
+ echo -e "${T}${BL}${desc}${NO} [ ${YL}${home}${NO} ]"
+ fi
+
+ if [ "${query}" ]; then
+ echo -e "${BL}DEPENDED ON BY:${NO}"
+ package="`echo ${n}|sed -e 's:-r[0-9]\+$::' \
+ -e 's:-[0-9].*$::' \
+ -e 's:^iii ::' \
+ -e 's:^uuu ::'`"
+ place="`echo ${n}|cut -f1 -d' '`"
+ [[ "${place}" == "iii" ]] && color="${GR}" || color="${RD}"
+ grep -R "${package}" /var/db/pkg/*/*/RDEPEND | \
+ cut -f5,6 -d"/" | sed -e "s:^:\t${color}:;s:$:${NO}:" | sort | uniq
+# gawk -F "/" '{printf("${place}\n\t%s/%s${NO}",$5,$6)}' | sort | uniq
+ fi
+
+ # cat package content, remove obj/sym/dir, md5 and mtime when not verbose
+ # display only match in file-find mode unless extra verbose
+ if [ "${list}" ]; then
+ echo -e ${BL}CONTENTS:${NO}
+
+ if [ ${verb} -gt 1 ]; then
+ cat ${d}/CONTENTS
+ else
+ if [ "${ffind}" ]; then
+ if [ "${fpat}" ]; then
+ grep "${arg}" $d/CONTENTS
+ else
+ grep " ${arg}\( .*\)*$" $d/CONTENTS
+ fi
+ else
+ cat $d/CONTENTS
+ fi |
+ if [ ${verb} -gt 0 ]; then
+ cat
+ else
+ sed -e "s:\(^obj \)\([^ ]*\)\(.*$\):\1${BR}\2${NO}:;
+ s:\(^sym \)\([^ ]*\)\( -> \)\([^ ]*\)\(.*$\):\1${CY}\2${NO}\3\4:;
+ s:\(^dir \)\([^ ]*\)\(.*$\):\1${YL}\2${NO}:"
+ fi
+ fi
+
+ echo
+
+ # check files mtime and md5, display summary at the end
+ elif [ "${tcheck}" -o "${mcheck}" ]; then
+ # counters
+ fe=0
+ fs=0
+ # read the CONTENTS file and check md5 and mtime if needed
+ # process only matching files in find-file mode unless extra verbose
+ cat ${d}/CONTENTS |
+ if [ "${ffind}" -a ${verb} -lt 2 ];then
+ if [ "${fpat}" ]; then
+ grep "${arg}"
+ else
+ grep " ${arg} "
+ fi
+ else
+ cat
+ fi |
+ (
+ while read -a line
+ do
+ fs=$((fs + 1))
+
+ unset md5
+ unset _md5
+ unset mtime
+ unset _mtime
+ unset err
+
+ name=${line[1]}
+
+ missing=
+ [ ! -e ${name} ] && missing=1
+
+ # colorize name and compute mtime/md5
+ if [ "obj" = ${line[0]} ]; then
+ [ -e ${name} ] && {
+ [ "${tcheck}" ] && mtime=${line[3]}
+ [ "${tcheck}" ] && _mtime=`date -r ${name} +%s`
+
+ [ "${mcheck}" ] && md5=${line[2]}
+ [ "${mcheck}" ] && _md5=`md5sum ${name}|cut -f1 -d" "`
+ }
+
+ name=${BR}${name}${NO}
+
+ elif [ "sym" = ${line[0]} ]; then
+ name=${CY}${name}${NO}
+
+ elif [ "dir" = ${line[0]} ]; then
+ name=${YL}${name}${NO}
+ fi
+
+ # compare
+ if [ "$missing" ]; then
+ err=1
+ name="${name} ${RD}!not exist!${NO}"
+ fi
+ if [ "${md5}" != "${_md5}" ]; then
+ #If the md5 fails the first time check it with
+ #everything changed to lowercase :-D
+ md5=`echo "${md5}"|tr A-Z a-z`
+ if [ "${md5}" != "${_md5}" ]; then
+ err=1
+ name="${name} ${RD}!md5!${NO}"
+ fi
+ fi
+ if [ "${mtime}" != "${_mtime}" ]; then
+ err=1
+ name="${name} ${RD}!mtime!${NO}"
+ fi
+
+ [ ${verb} -gt 1 ] && echo -e ${name}
+ [[ ${verb} -eq 1 ]] && [[ $err -eq 1 ]] && echo -e ${name}
+
+ fe=$((fe + err))
+ done
+ if [ "$fe" = "0" ]; then
+ echo -e ${YL}$fe${CY}/$fs${NO}
+ else
+ echo -e ${RD}$fe${CY}/$fs${NO}
+ fi
+ echo
+ )
+ fi
+
+done | (
+ if [ ! \( "${tcheck}" -o "${mcheck}" -o "${info}" -o "${list}" -o "${query}" -o ${verb} -gt 0 \) ]; then
+ sed -e "s:-r[0-9]\+$::" -e "s:-[0-9][^-]*$::"|sort -k2|uniq -1
+ elif [ ! \( "${tcheck}" -o "${mcheck}" -o "${info}" -o "${list}" -o "${query}" -o ${verb} -lt 2 \) ]; then
+ sort -k2|uniq -1
+ else
+ cat
+ fi | sed \
+ -e "s:^iii ${X}/${X}:${BR}\1/${CY}\2${STAR}${NO}:" \
+ -e "s:^uuu ${X}/${X}:${BR}\1/${YL}\2${NO}:" \
+ -e "s:^vvv \(.*\)$:${BL}\1${NO}:" \
+ -e "s:^obj ::;s:^sym ::;s:^dir ::"
+
+)
diff --git a/trunk/src/qpkg/qpkg.1 b/trunk/src/qpkg/qpkg.1
new file mode 100644
index 0000000..b9803b7
--- /dev/null
+++ b/trunk/src/qpkg/qpkg.1
@@ -0,0 +1,110 @@
+.TH "qpkg" "1" "1.6" "gentoolkit 0.1.11-r1" ""
+.SH "NAME"
+qpkg \- the "query package" tool for Gentoo Linux
+.SH "SYNOPSIS"
+.LP
+.B qpkg\fR [\fIoptions\fR] [\fIpkgname\fR] [\fI\-g group\fR]
+.br
+ [\fI\-f <file>\fR|\fI\-fp <pattern>\fR]
+.TP
+.B qpkg \fI\-\-dups\fR [\fI\-\-slot\fR]
+.TP
+.B qpkg \fI\-\-help\fR
+.SH "DESCRIPTION"
+qpkg is GenToolKit's "query package" tool, using it, you can find packages owning files on your filesystem, check the integrity of installed packages, and do other queries against installed or uninstalled packages.
+.SH "OPTIONS "
+.LP
+.I Duplicate Locating:
+.LP
+.B \-d, \-\-dups\fR print packages that have multiple
+.br
+ versions installed
+.br
+.B \-s, \-\-slot\fR make \-d SLOT only print dups of the
+.br
+ same SLOT
+.LP
+.I Package Selection:
+.LP
+.B \-f, \-\-find\-file\fR Finds package that owns file <file>
+.br
+.B \-fp, \-\-find\-pattern\fR Finds to package that owns file
+.br
+ matching *<pattern>*
+.br
+.B \-I, \-\-installed\fR Include only installed packages
+.br
+.B \-U, \-\-uninstalled\fR Include only uninstalled packages
+.br
+.B \-g, \-\-group\fR Find by goup (can be combined with
+.br
+ other searches)
+.LP
+.I Information Selection:
+.LP
+.B \-l, \-\-list\fR List package content
+.br
+.B \-i, \-\-info\fR Get package description and home page.
+.br
+.B \-ct, \-\-check\-time
+.br
+.B \-tc, \-\-time\-check\fR Verify package files timestamps
+.br
+.B \-cm, \-\-check\-md5
+.br
+.B \-mc, \-\-md5\-check\fR Verify package files md5
+.br
+.B \-c, \-\-check\fR Verify mtimes and md5.
+.br
+.B \-q, \-\-query\-deps\fR display all installed packages
+.br
+\fR depending on selected packages
+.LP
+.I Operation Modifiers:
+.LP
+.B \-nc, \-\-no\-color\fR Don't use colors
+.br
+.B \-v, \-\-verbose\fR Be more verbose [2 levels]
+.br
+.B \-vv\fR Same as \-v \-v
+.SH "NOTES"
+\fI\-f, \-fp, \-d, \-l, \-ct, \-cm, \fRand \fI\-c\fR apply only to installed packages.
+.br
+.TP
+Short options may not be combined on the command\-line, yet.
+.TP
+The operation of some flags has been changed in version 1.6 by the stripping of version numbers from some output to see the version numbers play with \fI\-v\fR and \fI\-vv\fR.
+.TP
+When using \fI\-f\fR with \fI\-l\fR or \fI\-\-check.. \-v\fR options, only matching files will be displayed, unless \fI\-v\fR is doubled, (yet more verbose), equivalent to \fI\-vv\fR.
+.SH "EXAMPLES"
+.LP
+.B qpkg \fI\-\-dups\fR print duplicates oldest first
+.br
+.B qpkg \fI\-\-dups \-v\fR.. with versions
+.br
+.B qpkg\fR print list of packages
+.br
+.B qpkg\fR porta \fI\-I\fR print versions of installed portage
+.br
+.B qpkg porta \fI\-i\fR .. + versions in portage tree +
+.br
+ descriptions and homepages
+.br
+.B qpkg gawk \fI\-c \-v\fR check integrity all installed versions
+.br
+ of gawk the older versions will have
+.br
+ "damaged" files.
+.br
+.B qpkg \fI\-f\fR /bin/ls print package(s) that own /bin/ls
+.SH "AUTHORS"
+Vitaly Kushneriuk <vitaly@gentoo.org>, 2002: qpkg
+.br
+Karl Trygve Kalleberg <karltk@gentoo.org>, 2002: man page
+.br
+Brandon Low <lostlogic@gentoo.org>, 2002: maintainance
+.SH "SEE ALSO"
+ebuild(5)
+.TP
+The \fI/usr/sbin/qpkg\fR script.
+.TP
diff --git a/trunk/src/useflag/AUTHORS b/trunk/src/useflag/AUTHORS
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/trunk/src/useflag/AUTHORS
diff --git a/trunk/src/useflag/ChangeLog b/trunk/src/useflag/ChangeLog
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/trunk/src/useflag/ChangeLog
diff --git a/trunk/src/useflag/README b/trunk/src/useflag/README
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/trunk/src/useflag/README
diff --git a/trunk/src/useflag/useflag b/trunk/src/useflag/useflag
new file mode 100644
index 0000000..fd4cc08
--- /dev/null
+++ b/trunk/src/useflag/useflag
@@ -0,0 +1,610 @@
+#!/bin/bash
+# useflag v0.3.1
+# Script to help users manage USE flags in Gentoo Linux
+#
+# Distributed under the terms of the GNU General Public License, v2 or later
+# Author: Michael Thompson <psionix@grandecom.net>, (c) 2002
+
+run_name=`basename $0`
+use_desc="/usr/portage/profiles/use.desc"
+make_conf_dir="/etc"
+make_conf="${make_conf_dir}/make.conf"
+# Home directory was chosen as the use of /tmp allows for symlink attacks
+make_temp="${HOME}/use.make.conf.tmp"
+use_cache_parent="/var/cache"
+use_cache_dir="${use_cache_parent}/use_desc"
+use_cache="${use_cache_dir}/use.cache"
+lock_cache="${use_cache_dir}/lock.cache"
+changes="0"
+
+
+# Get flag description
+# parm1 = Use flag to get description of
+do_get_desc() {
+ local parm1=$1
+ # Strip the comments and find the flag.
+ local out_get_desc=`grep -v "#" ${use_desc} | grep -w -e "${parm1} -"`
+ if [ "${out_get_desc}" = "" ]; then
+ local lcl_avail=`grep -v "#" ${use_desc} | cut -d ' ' -f1 | \
+ grep -w -e "${parm1}"`
+ if [ "${lcl_avail}" != "" ]; then
+ echo "${parm1} - No description available."
+ else
+ echo "!!! ${parm1} does not exist."
+ fi
+ else
+ echo "${out_get_desc}"
+ fi
+}
+
+# Get the contents of the USE variable
+# parm1 controls whether or not to include the '-' with each flag
+do_get_make() {
+ local parm1=$1
+ # Get the USE flags from make.conf
+ # using `source` now instead of brain-damaged grepping
+ source ${make_conf}
+ local get_make_out=${USE}
+ # If called with "nodashes", then strip the leading dashes
+ if [ "${parm1}" = "nodashes" ]; then
+ for tr_sucks in ${get_make_out}; do
+ if [ "${tr_sucks:0:1}" = "-" ]; then
+ local tr_out="${tr_out} ${tr_sucks:1}"
+ else
+ local tr_out="${tr_out} ${tr_sucks}"
+ fi
+ done
+ get_make_out="${tr_out}"
+ fi
+ echo "${get_make_out}"
+}
+
+# Yes, it's pointless. But it could be used more than once in the future
+# so it's a function.
+# Gets the master list of available USE flags from use.desc
+do_get_avail() {
+ grep -v "#" ${use_desc} | cut -d " " -f1 | tr '\n' ' '
+}
+
+# Get deprecated flags.
+# parm1 = flag to check for deprecation
+# parm2 = list of available flags
+do_get_depr() {
+ local parm1=$1
+ local parm2=${@:2}
+ # This next var can't be local
+ get_depr_tmp=`echo "${parm2}" | tr ' ' '\n' | grep -x -e "${parm1}"`
+ local ret_code=$?
+ if [ "${ret_code}" != "0" ]; then
+ echo "${parm1}" | tr '\n' ' '
+ fi
+}
+
+# Removes a USE flag from make.conf
+# parm1 = flag to remove
+# use_rm_out = list of available flags
+do_use_rm() {
+ local parm1=$1
+ local use_rm_out=${@:2}
+ # Strip matching USE flags. Yes, this is ugly, I know.
+ use_rm_out=`echo "${use_rm_out}" | tr ' ' '\n' | \
+ grep -x -v -e "${parm1}" | tr '\n' ' '`
+ # Also strip the inverse. Even uglier...
+ if [ "${parm1:0:1}" = "-" ]; then
+ use_rm_out=`echo "${use_rm_out}" | tr ' ' '\n' | \
+ grep -x -v -e "${parm1:1}" | tr '\n' ' '`
+ else
+ use_rm_out=`echo "${use_rm_out}" | tr ' ' '\n' | \
+ grep -x -v -e "-${parm1}" | tr '\n' ' '`
+ fi
+ echo "${use_rm_out}"
+}
+
+# Adds a USE flag to make.conf
+# parm1 = flag to add
+# use_add_out = list of available flags
+do_use_add() {
+ local parm1=$1
+ local use_add_out=${@:2}
+ # First strip existing flags (matching or inverse), then add.
+ # This is not the best way to do this. Better would be to replace a
+ # flag if it already exists. That turned out to be a real PITA.
+ # Maybe in a later version...
+ use_add_out=`do_use_rm ${parm1} ${use_add_out}`
+ use_add_out="${use_add_out} ${parm1}"
+ echo "${use_add_out}"
+}
+
+# Adds a flag to the locked flag cache
+# Pass list of flags to lock as parameter.
+do_lock_flags() {
+ local flag_list=$@
+ # Merge the new list of flags flags that are already locked.
+ if [ -r ${lock_cache} ]; then
+ local lock_old=`cat ${lock_cache}`
+ fi
+ flag_list="${lock_old} ${flag_list}"
+ # Remove duplicates.
+ echo "${flag_list}" | tr ' ' '\n' | sort | uniq | tr '\n' ' '
+}
+
+# Writes the list of locked flags to the cache file
+# Pass list of flags to write as parameter.
+do_write_lock() {
+ local write_flags=$@
+ if [ -r ${make_conf} ]; then
+ local make_prune=`do_get_make nodashes`
+ else
+ do_report_err ${make_conf} read
+ fi
+ # Be sure and remove any locked flags that no longer exist in USE.
+ for prune in ${write_flags}; do
+ local prune_test=`do_get_depr ${prune} ${make_prune}`
+ if [ "$prune_test" = "" ]; then
+ local new_cache="${prune} ${new_cache}"
+ fi
+ done
+ if [ -w ${use_cache_parent} ]; then
+ mkdir -p ${use_cache_dir}
+ chmod 700 ${use_cache_dir}
+ echo "${new_cache}" > ${lock_cache}
+ chmod 600 ${lock_cache}
+ else
+ do_report_err ${lock_cache} write
+ fi
+}
+
+# Writes new USE variable to make.conf
+# Pass new list of USE flags as parameter.
+do_write_make() {
+ local use_write="USE=\"$@\""
+ local old_use="USE=\"`do_get_make dashes`\""
+ if [ -w ${make_conf} ] && [ -w ${make_conf_dir} ]; then
+ local use_write="USE=\"$@\""
+ local old_use=`grep "USE=\"" ${make_conf} | grep -v "#"`
+ local start_line=`grep -n "USE=\"" ${make_conf} | \
+ grep -v "#" | cut -d ":" -f1`
+ if [ "${old_use:0-1}" != "\\" ]; then
+ sed -e "s/${old_use}/${use_write}/" ${make_conf} > \
+ ${make_temp}
+ else
+ sed -e "s/${old_use}\\/${use_write}/" ${make_conf} > \
+ ${make_temp}
+ fi
+ let start_line="${start_line} + 1"
+ if [ "${old_use:0-1}" != "\"" ]; then
+ del_line=`head -n ${start_line} ${make_temp} | \
+ tail -n 1`
+ until [ "${del_line:0-1}" != "\\" ]; do
+ let del_length="${#del_line} - 1"
+ del_line="${del_line:0:${del_length}}"
+ grep -v -w "${del_line}" ${make_temp} > \
+ ${make_temp}.2
+ mv ${make_temp}.2 ${make_temp}
+ del_line=`head -n ${start_line} \
+ ${make_temp} | tail -n 1`
+ done
+ let del_length="${#del_line} - 1"
+ del_line="${del_line:0:${del_length}}"
+ grep -v -x "${del_line}\"" ${make_temp} > \
+ ${make_temp}.2
+ mv ${make_temp}.2 ${make_temp}
+ fi
+ mv ${make_temp} ${make_conf}
+ else
+ do_report_err ${make_conf} write
+ fi
+}
+
+# Reports a read/write error and exits
+# parm1 = File to report on
+# parm2 = read, write, etc
+do_report_err() {
+ local parm1=$1
+ local parm2=$2
+ if [ "${parm2}" = "read" ]; then
+ echo "!!! Could not read ${parm1}"
+ echo -n "!!! Verify that file exists and that you have "
+ echo "appropriate permissions."
+ elif [ "${parm2}" = "write" ]; then
+ echo "!!! Could not write ${parm1}"
+ echo "!!! Got root?"
+ elif [ "${parm2}" = "nolock" ]; then
+ echo "!!! Could not read ${parm1}"
+ echo -n "!!! You have no locked flags or you have "
+ echo "insufficient permissions."
+ fi
+ exit 1
+}
+
+
+# The main section of the script
+# desc:
+# This is the feature for getting USE descriptions.
+if [ "$1" = "desc" ] || [ "$1" = "-i" ]; then
+ if [ -r ${use_desc} ]; then
+ for flag in ${@:2}; do
+ do_get_desc ${flag}
+ done
+ else
+ do_report_err ${use_desc} read
+ fi
+
+# show:
+# This is the feature for showing the contents of the USE variable.
+elif [ "$1" = "show" ] || [ "$1" = "-s" ]; then
+ if [ -r ${make_conf} ]; then
+ do_get_make dashes
+ else
+ do_report_err ${make_conf} read
+ fi
+
+# del:
+# This is the feature for removing a USE flag.
+elif [ "$1" = "del" ] || [ "$1" = "-d" ]; then
+ if [ -r ${make_conf} ]; then
+ make_use=`do_get_make dashes`
+ else
+ do_report_err ${make_conf} read
+ fi
+ for flag in ${@:2}; do
+ # Strip leading dashes.
+ if [ "${flag:0:1}" = "-" ]; then
+ flag="${flag:1}"
+ fi
+ del_test1=`do_get_depr ${flag} ${make_use}`
+ del_test2=`do_get_depr -${flag} ${make_use}`
+ if [ "${del_test1}" = "" ] || [ "${del_test2}" = "" ]; then
+ changes="1"
+ make_use=`do_use_rm ${flag} ${make_use}`
+ else
+ echo "!!! ${flag} is not in your USE variable."
+ fi
+ done
+ if [ "${changes}" != "0" ]; then
+ do_write_make ${make_use}
+ # Prune deleted USE flags from lock cache
+ lock_flags=`do_lock_flags $2`
+ do_write_lock ${lock_flags}
+ fi
+
+# add:
+# This is the feature for explicitly enabling or disabling a USE flag.
+elif [ "$1" = "add" ] || [ "$1" = "-a" ]; then
+ if [ -r ${make_conf} ]; then
+ make_use=`do_get_make dashes`
+ else
+ do_report_err ${make_conf} read
+ fi
+ for flag in ${@:2}; do
+ changes="1"
+ make_use=`do_use_add ${flag} ${make_use}`
+ done
+ if [ "${changes}" != "0" ]; then
+ do_write_make ${make_use}
+ fi
+
+# lock:
+# This is the feature to lock a deprecated USE flag to prevent removal
+elif [ "$1" = "lock" ] || [ "$1" = "-l" ]; then
+ if [ -r ${make_conf} ]; then
+ make_use=`do_get_make nodashes`
+ else
+ do_report_err ${make_conf} read
+ fi
+ for flag in ${@:2}; do
+ # Strip leading dashes.
+ if [ "${flag:0:1}" = "-" ]; then
+ flag="${flag:1}"
+ fi
+ lock_test=`do_get_depr ${flag} ${make_use}`
+ if [ "${lock_test}" = "" ]; then
+ lock_flags="${lock_flags} ${flag}"
+ else
+ echo "!!! ${flag} is not in your USE variable."
+ fi
+ done
+ lock_out=`do_lock_flags ${lock_flags}`
+ do_write_lock ${lock_out}
+
+# unlock:
+# This is the feature to unlock a deprecated USE flag to allow removal
+elif [ "$1" = "unlock" ] || [ "$1" = "-k" ]; then
+ if [ -r ${lock_cache} ]; then
+ lock_out=`cat ${lock_cache}`
+ else
+ do_report_err nolock
+ fi
+ for flag in ${@:2}; do
+ # Strip leading dashes.
+ if [ "${flag:0:1}" = "-" ]; then
+ flag="${flag:1}"
+ fi
+ lock_flag_check=`do_get_depr ${flag} ${lock_out}`
+ if [ "${lock_flag_check}" = "" ]; then
+ lock_out=`do_use_rm ${flag} ${lock_out}`
+ else
+ echo "!!! ${flag} is not a locked flag."
+ fi
+ done
+ do_write_lock ${lock_out}
+
+# showlock:
+# This feature prints a list of USE flags that have been locked
+elif [ "$1" = "showlock" ] || [ "$1" = "-w" ]; then
+ if [ -r ${lock_cache} ]; then
+ cat ${lock_cache}
+ else
+ do_report_err nolock
+ fi
+
+# update:
+# This is the feature to update your USE by removing deprecated flags and
+# handling new flags.
+elif [ "$1" = "update" ] || [ "$1" = "-u" ]; then
+ if [ -r ${make_conf} ]; then
+ # Get our USE but strip leading dashes
+ make_use=`do_get_make nodashes`
+ else
+ do_report_err ${make_conf} read
+ fi
+ # Get available USE flags from use.desc
+ if [ -r ${use_desc} ]; then
+ use_avail=`do_get_avail`
+ else
+ do_report_err ${use_desc} read
+ fi
+ # First we check for deprecated flags.
+ echo "Your USE variable currently looks like this:"
+ echo
+ echo `do_get_make dashes`
+ echo
+ # Print the list of locked flags if any exist.
+ if [ -r ${lock_cache} ]; then
+ lock_test=`cat ${lock_cache} | tr -d ' '`
+ if [ "${lock_test}" != "" ]; then
+ echo "The following flags are locked:"
+ cat ${lock_cache}
+ echo
+ fi
+ fi
+ echo
+ echo "*** Checking for deprecated USE flags ..."
+ echo
+ for check_flag in ${make_use}; do
+ depr_ret=`do_get_depr ${check_flag} ${use_avail}`
+ flag_depr="${flag_depr}${depr_ret}"
+ done
+ # Filter out locked flags
+ if [ -r ${lock_cache} ] && [ "${lock_test}" != "" ]; then
+ lock_list=`cat ${lock_cache}`
+ for check_locks in ${flag_depr}; do
+ lock_ret=`do_get_depr ${check_locks} ${lock_list}`
+ lock_out="${lock_out}${lock_ret}"
+ done
+ flag_depr="${lock_out}"
+ fi
+ make_use=`do_get_make dashes`
+ if [ "${flag_depr}" = "" ]; then
+ echo "!!! No deprecated flags were found."
+ else
+ echo "The following USE flags appear to be deprecated:"
+ echo "${flag_depr}"
+ echo
+ echo "How would you like to handle them?"
+ echo "1) Handle them individually"
+ echo "2) Remove all deprecated flags"
+ echo "3) Don't remove any deprecated flags"
+ echo "4) Lock all deprecated flags"
+ echo
+ echo -n "Type (1, 2, 3, or 4): "
+ while [ "${luser_input}" = "" ]; do
+ read luser_input
+ case ${luser_input} in
+ "2")
+ changes="1"
+ for flag in ${flag_depr}; do
+ make_use=`do_use_rm \
+ ${flag} ${make_use}`
+ done
+ echo
+ echo -n "*** All deprecated flags were "
+ echo "removed."
+ ;;
+ "3")
+ echo
+ echo "*** No flags were removed."
+ ;;
+ "1")
+ for flag in ${flag_depr}; do
+ echo -n "${flag} appears to be "
+ echo -n "deprecated. Remove it? "
+ echo -n "[Y]es/[N]o/[L]ock : "
+ luser_yn=""
+ while [ "${luser_yn}" = "" ]; do
+ read luser_yn
+ case ${luser_yn} in
+ "y" | "Y")
+ changes="1"
+ make_use=`do_use_rm \
+ ${flag} \
+ ${make_use}`
+ ;;
+ "n" | "N")
+ ;;
+ "l" | "L")
+ wlk="${flag} ${wlk}"
+ ;;
+ *)
+ luser_yn=""
+ ;;
+ esac
+ done
+ done
+ echo
+ echo -n "*** All deprecated flags "
+ echo "processed."
+ ;;
+ "4")
+ wlk="${flag_depr}"
+ echo
+ echo "*** All deprecated flags were locked."
+ ;;
+ *)
+ luser_input=""
+ ;;
+ esac
+ done
+ fi
+ if [ "${wlk}" != "" ]; then
+ do_write_lock ${wlk}
+ fi
+ # Now we check for new flags.
+ echo
+ echo
+ echo "*** Checking for new USE flags ..."
+ echo
+ # Load up our cached USE flags for comparison with use.desc
+ # Create the cache if it does not exist
+ if [ -w ${use_cache} ]; then
+ use_old=`cat ${use_cache}`
+ echo "${use_avail}" > ${use_cache}
+ chmod 600 ${use_cache}
+ elif [ -w ${use_cache_parent} ]; then
+ mkdir -p ${use_cache_dir}
+ chmod 700 ${use_cache_dir}
+ echo "${use_avail}" > ${use_cache}
+ chmod 600 ${use_cache}
+ use_old=""
+ else
+ do_report_err ${use_cache} write
+ fi
+ # Grab the contents of the USE variable.
+ make_cand=`do_get_make nodashes`
+ # Build a list of flags that do not exist in the USE variable.
+ for flag in ${use_avail}; do
+ new_cand="${new_cand}`do_get_depr ${flag} ${make_cand}`"
+ done
+ # Filter that list through the cached master list of flags.
+ for flag in ${new_cand}; do
+ new_flags="${new_flags}`do_get_depr ${flag} ${use_old}`"
+ done
+ if [ "${new_flags}" = "" ]; then
+ echo "!!! No new USE flags are available."
+ else
+ echo "The following new USE flags are available:"
+ echo "${new_flags}"
+ echo
+ echo "How would you like to handle them?"
+ echo "1) Handle them individually"
+ echo "2) Use Portage defaults (do not add to USE)"
+ echo "3) Explicitly enable all new flags"
+ echo "4) Explicitly disable all new flags"
+ echo
+ echo -n "Type (1, 2, 3, or 4): "
+ luser_input=""
+ while [ "${luser_input}" = "" ]; do
+ read luser_input
+ case ${luser_input} in
+ "1")
+ for h_flag in ${new_flags}; do
+ do_get_desc ${h_flag}
+ echo -n "How would you like to handle "
+ echo -n "${h_flag}? [e]nable, "
+ echo -n "[d]isable, [u]se default : "
+ luser_handle=""
+ while [ "${luser_handle}" = "" ]; do
+ read luser_handle
+ case ${luser_handle} in
+ "e" | "E")
+ changes="1"
+ make_use=`do_use_add \
+ ${h_flag} \
+ ${make_use}`
+ echo
+ ;;
+ "d" | "D")
+ changes="1"
+ make_use=`do_use_add \
+ "-${h_flag}" \
+ ${make_use}`
+ echo
+ ;;
+ "u" | "U")
+ echo
+ ;;
+ *)
+ luser_handle=""
+ ;;
+ esac
+ done
+ done
+ echo -n "*** All new flags have been "
+ echo "processed."
+ ;;
+ "2")
+ echo
+ echo -n "*** No new flags were added to "
+ echo "your USE."
+ ;;
+ "3")
+ changes="1"
+ for h_flag in ${new_flags}; do
+ make_use=`do_use_add ${h_flag} \
+ ${make_use}`
+ done
+ echo
+ echo -n "*** All new flags were enabled in "
+ echo "your USE."
+ ;;
+ "4")
+ changes="1"
+ for h_flag in ${new_flags}; do
+ make_use=`do_use_add \
+ "-${h_flag}" ${make_use}`
+ done
+ echo
+ echo -n "*** All new flags were disabled in "
+ echo "your USE."
+ ;;
+ *)
+ luser_input=""
+ ;;
+ esac
+ done
+ fi
+ # Write the changes if necessary.
+ if [ "${changes}" != "0" ]; then
+ do_write_make ${make_use}
+ # Prune any locked flags that do not exist in the USE variable
+ lock_prot=`do_lock_flags fakeflag`
+ do_write_lock ${lock_prot}
+ fi
+ echo
+ echo
+ echo "*** Script finished ..."
+
+# Display USAGE statement for unhandled parameters
+else
+ echo "Usage:"
+ echo " ${run_name} action [flag] [...]"
+ echo
+ echo "Actions:"
+ echo "-s, show Displays the contents of the USE variable."
+ echo "-i, desc Displays a description of one or more USE flags."
+ echo -n "-a, add Adds the specified flag(s) to the USE "
+ echo "variable."
+ echo -n "-d, del Deletes the specified flag(s) from "
+ echo "the USE variable."
+ echo "-l, lock Locks the specified flag(s) to prevent deprecation."
+ echo -n "-k, unlock Unlocks the specified flags to allow "
+ echo "deprecation."
+ echo "-w, showlock Displays a list of locked flags."
+ echo -n "-u, update Interactively updates the USE variable to "
+ echo "reflect changes"
+ echo " to use.desc."
+ echo
+ exit 1
+fi
+exit 0
+
diff --git a/trunk/src/useflag/useflag.1 b/trunk/src/useflag/useflag.1
new file mode 100644
index 0000000..d321861
--- /dev/null
+++ b/trunk/src/useflag/useflag.1
@@ -0,0 +1,69 @@
+.TH useflag "1" "May 2002" "gentoolkit"
+.SH NAME
+useflag \- manage and update Gentoo Linux USE flags
+.SH SYNOPSIS
+.B useflag
+\fIaction\fR [\fIflag\fR] [\fI...\fR]
+.SH DESCRIPTION
+The \fBuseflag\fR utility allows the user to manage Gentoo Linux USE flags through a simple command-line interface. It allows quick and easy, single-command manipulation of the USE variable defined in \fI/etc/make.conf\fR. It also simplifies the process of handling changes to the master list of USE flags defined in \fI/usr/portage/profile/use.desc\fR.
+.br
+
+It is important to note that a USE variable must exist in \fImake.conf\fR for this utility to work. Be sure that the USE variable is uncommented. It is OK for the USE variable to be empty. Please be sure to back up \fImake.conf\fR before using this utility for the first time.
+.PP
+.SH ACTIONS
+.TP
+\fBshow, -s\fR
+Displays the raw contents of the USE variable as defined in \fImake.conf\fR. The output contains only the flags themselves.
+.TP
+\fBdesc, -i [flag] ...\fR
+Displays a description of one or more USE flags specified on the command line. The flags should be seperated by spaces and should not contain leading dashes. Specifying a flag that does not exist returns a non-fatal error.
+.TP
+\fBadd, -a [[\-]flag] ...\fR
+Adds one or more specified flags to the USE variable defined in \fImake.conf\fR. The flags are appended to the USE variable exactly as they appear on the command line. If a specified flag already exists in the USE variable, it is removed before the new set of flags is appended. The utility removes existing flags regardless of whether they are in an enabled or disabled state, allowing the user to enable or disable a flag with a single command. The user may add flags that are not defined in the \fIuse.desc\fR master list.
+.TP
+\fBdel, -d [flag] ...\fR
+Deletes one or more specified flags from the USE variable defined in \fImake.conf\fR. The enabled/disabled state of a flag in the USE variable as well as any dashes prepended to flags on the command line is ignored. Attempting to delete a flag that is not in the USE variable returns a non-fatal error. When a flag is deleted from the USE variable using this utility, it is automatically unlocked.
+.TP
+\fBlock, -l [flag] ...\fR
+Locks one or more specified flags that exist in the USE variable defined in \fImake.conf\fR. Locked flags are not considered to be deprecated by the update function of this utility. This allows the user to avoid being queried by the utility about deprecated, undocumented, or custom flags that the user wishes to preserve when performing an update. A flag must exist in the USE variable in order to be locked. The enabled/disabled state of a flag in the USE variable as well as any dashes prepended to flags on the command line is ignored.
+.TP
+\fBunlock, -k [flag] ...\fR
+Unlocks one or more specified USE flags. This allows the update function to consider a flag deprecated if it no longer exists in the master list defined in \fIuse.desc\fR. Any dashes prepended to flags on the command line are ignored. Attempting to unlock flags that are not locked returns a non-fatal error.
+.TP
+\fBshowlock, -w\fR
+Displays the raw list of locked flags, seperated by spaces.
+.TP
+\fBupdate, -u\fR
+Interactively updates the USE variable defined in \fImake.conf\fR to reflect changes to the master list of USE flags defined in \fI use.desc\fR.
+.br
+
+First, the user is presented with the current raw contents of the USE variable. The user is also shown the list of locked flags if any exist.
+.br
+
+Next, the USE variable is searched for flags that do not appear in the master list. If any are found and they are not locked, then they are considered to be deprecated and are displayed to the user along with a list of options for handling them. The user may choose to remove all of the flags, remove none of the flags, lock all of the flags, or handle each flag individually.
+.br
+
+Last, the master list is searched for any new flags that have become available since the last time the update function was run, and these are displayed to the user. If this is the first time, then all flags not currently defined in the USE variable will be displayed. The user will then be presented with a list of options for handling these flags. The user may choose to add all of the new flags to the USE variable as enabled, add all of the new flags as disabled, use Portage defaults for all of the flags, or handle each flag individually.
+.SH FILES
+.TP
+\fI/etc/make.conf\fR
+Contains the USE variable that Portage uses to control build-time functionality.
+.TP
+\fI/usr/portage/profile/use.desc\fR
+Contains a master list of all documented USE flags along with their descriptions.
+.TP
+\fI/var/cache/use_desc/use.cache\fR
+Contains a cached list of flags from \fIuse.desc\fR. This prevents the user from being repeatedly queried about flags that exist in \fIuse.desc\fR but not in the USE variable. DO NOT EDIT THIS FILE MANUALLY.
+.TP
+\fI/var/cache/use_desc/lock.cache\fR
+Contains a list of USE flags that have been locked. DO NOT EDIT THIS FILE MANUALLY.
+.SH AUTHOR
+Michael Thompson <psionix@grandecom.net>, 2002
+.SH SEE ALSO
+ebuild(1), ebuild(5), emerge(1), make.conf(5).
+.TP
+See \fI/usr/share/doc/gentoolkit-<version>/\fR for documentation on other gentoolkit utilities.
+.SH TIPS
+.TP
+Deleting \fI/var/cache/use_desc/use.cache\fR will allow the utility to query about all flags not currently defined in the USE variable.
+