Grant wrote:
>>>>> What do you guys think of this?  Do you know of a good cruft removal 
>>>>> script?
>>>>>
>>>>>           
>>>> Yep, there's quite good one in gentoo itself.
>>>>
>>>> Basically, you'll need to write a short config for it, consisting of
>>>> lines like "cruft name", "cruft src uri" and a few more lines if you'll
>>>> need to pass some extra parameters to configure/make/install.
>>>> It'll build the package in a sandbox, then transfer it to destination,
>>>> memorizing every change it did and preventing collisions and config
>>>> overwrites.
>>>>
>>>> Just put that config script into an ebuild file and use portage to
>>>> build it - as simple as it gets ;)
>>>>
>>>>         
>>> I suppose you and Jesus are right, but what about cruft removal?  Are
>>> you saying Gentoo is 100% cruft-free?  I've got a lot of junk in /etc
>>> and especially ~/.*
>>>
>>> - Grant
>>>
>>>
>>>
>>>       
> [snip]
>   
>> You have to clean out /etc and home directories yourself.
>>     
>
> Exactly.  Nothing to help me along?  I'll check out qfile, but I'm
> surprised there isn't a good script for this.
>
> I'm the only one interested in a filesystem audit?
>
> - Grant
>
>
>   
>> Portage does do a good job of removing all the other files tho.  If it
>> puts it there, it will remove it if you unmerge a package.
>>
>> Dale
>>     
>
>
>   

There is a script on the forums that is supposed to clean out /etc.  I
am attaching a copy of it.  I have no idea if it still works or if it
will completely destroy your system.  I would search for the thread or
go through the script to make sure it doesn't mess up something.

I do wish there was a option for cleaning out /etc but then again, that
could be dangerous too. 

Dale

:-)  :-) 
 #!/bin/bash

VERSION=3.11

###########################
# etcportclean
# Isaac Chanin, 2005
#
# Refer to 'etcportclean --help' for information.
#
# This code is not copyrighted and is in the public domain.
# It comes with no warranty of any kind, explicit or otherwise.
###########################

# Exit codes
SUCCESS=0
NOT_ROOT=10
BAD_ARGS=20
WORLD_CHECK_FAIL=30
SANITY_CHECK_FAIL=31
DUPLICATE_FAIL=40
DUPLICATE_WARN=41
NO_FILES=50
MISSING_DEPENDENCY=51
CANNOT_DOWNLOAD=60
BAD_HASH=61

# Directory where portage files are kept
FILES_DIR="/etc/portage"

# Where etcportclean is on the web
WEB=users.wpi.edu/~chanin/scripts/etcportclean

# Files we (optionally) look at
files=( "package.keywords" "package.unmask" "package.mask" "package.use" 
"package.cflags" "package.cxxflags" "package.ldflags" )

# Messages about files
messages=( "unnecessary keywords" "needlessly unmasked packages" "needlessly 
masked packages" "unnecessary use flags" "repeat cflags" "repeat cxxflags" 
"repeat ldflags" )

# Generally needed progs
neededprogs=( "sed" "awk" "grep" "egrep" "sort" "uniq" "tail" "head" "xargs" )

if [ "$UID" -ne 0 ] ; then
        echo "You must be root to run this script."
        exit $NOT_ROOT
fi

function usage()
{
        echo "etcportclean v$VERSION - clean, check and stabilize 
$FILES_DIR/package.*"
        echo
        echo "  usage:"
        echo "  $prog [flags]"
        echo
        echo "  Flags may be any of:"
        echo "   -cNNNNNNN, -rN, -wN, -dN, -v[N], -V[N], -u[N]"
        echo "  Where N is either 0 or 1."
        echo
        echo "  -c Check: This flag allows you to indicate, on the command 
line, which"
        echo "  files you would like to check.  The order is as follows 
(package.):"
        echo "  `echo "${fil...@]}" | sed 's/\ /\n/g' | awk -F . '{ print $2 " 
" }' | xargs`."
        echo "  So, for example, -c0011000 would check ${files[2]} and 
${files[3]}."
        echo "  Defaults to asking the user (unless the file does not exist.)"
        echo
        echo "  -r Remove: This flag allows you to toggle automatic removal of 
unnecessary"
        echo "  entries.  It only affects keywords, unmask, and mask checking.  
The others do"
        echo "  not have any automatic removal mechanism. Defaults to asking 
the user, if"
        echo "  there is anything to remove."
        echo
        echo "  -w World Check: This flag allows you to turn 'emerge -puD 
world' checking on"
        echo "  or off.  It defaults to on if you are checking any of keywords 
unmask or mask."
        echo "  NOTE: Turning off 'emerge -puD world' checking may cause 
etcportclean to miss"
        echo "  lines that could otherwise be removed. Defaults to on."
        echo
        echo "  -d Duplicate Check: This flag allows you to turn duplicate 
checking on or off."
        echo "  It does not affect use, cflags, cxxflags or ldflags duplicate 
checking."
        echo "  NOTE: For certain exotic configurations you may have to turn 
off duplicate"
        echo "  checking.  One example would be if you have multiple accepted 
keywords for"
        echo "  a single package.  Defaults to on."
        echo
        echo "  -v Verbose: This flag makes etcportclean verbose about what it 
is doing.  If"
        echo "  you find what you think is a bug, try to get some more 
information by using"
        echo "  this or -V.  Defaults to off."
        echo
        echo "  -V Very Verbose: This flag makes etcportclean even more verbose 
(implies -v)."
        echo "  This was added mainly so I could find bugs.  If you like tons 
of useless"
        echo "  output you may find it useful also. Defaults to off."
        echo
        echo "  -u Update: This flag has etcportclean check for a new version 
and"
        echo "  automatically update if a new version is found.  It requires 
sha1sum and wget"
        echo "  with https support (to get the hash file.)  Defaults to off."
        echo
        echo "  etcportclean also allows you to specify a section in keywords, 
unmask or mask"
        echo "  where it will not check.  This can be useful if you want to 
always use the"
        echo "  testing version of a package.  In order to use this feature 
simply place a"
        echo "  comment with the word 'Keep' somewhere in the file.  
etcportclean will then"
        echo "  not look above that point in the file for normal checks.  The 
lines above the"
        echo "  'Keep line' may still trigger duplicate or other warnings, 
however."
        echo
        exit $BAD_ARGS
}

# Prompt a yes or no question
function readyesno
{
        local message=$1
        unset yesno
        while [ -z "`echo "$yesno" | egrep -i "^(yes|y|no|n)$"`" ]
        do
                echo "$1 (yes/no)"
                read yesno
        done
        if [ -n "`echo "$yesno" | egrep -i "^(yes|y)$"`" ] ; then
                return 1
        else
                return 0
        fi
}

# Checks that an emerge didn't get completely incorrect results because of a 
masked package.
function checksanity
{
        local emergelist="$1"
        local msg="$2"
        local file=$3
        if [[ "$VERBOSE" ]] ; then echo "Checking for emerge sanity over 
$file..." ; fi
        # If we get a 'masked notice' instead of a ebuild list
        if [ -n "`echo "$emergelist" | grep "^.*\ satisfy\ .*\.$"`" ]
        then
                mv -f $file.bak.keep $file 2>/dev/null
                echo "Sanity check failed for $file, there appears to be a 
masking/existence problem."
                echo "$msg"
                exit $SANITY_CHECK_FAIL
        fi
        if [[ "$VERBOSE" ]] ; then echo "Emerge sanity confirmed." ; fi
}

# Make sure we get the output we're going to be looking for from 'emerge -puD 
world'
function checkworld
{
        if [[ "$VERBOSE" ]] ; then echo "Checking emerge -puD world for 
expected results..." ; fi
        if [ -n "`emerge -puD world | egrep "\[ebuild\ [A-Z\ ]{6}\]"`" ]
        then
                echo "'emerge -puD world' gives output containing ebuilds on 
your machine."
                echo "etcportclean relies upon 'emerge -puD world' not changing 
any packages. It is"
                echo "recommended that you 'emerge -uD world' and take any 
other needed actions so"
                echo "'emerge -puD world' does not list any ebuilds before 
using this script. If"
                echo "you do not, scans will not produce incorrect results, but 
may not be able to"
                echo "find everything that is removable."
                if readyesno "Would you like to continue?"
                then
                        exit $WORLD_CHECK_FAIL
                fi
        elif [[ "$VERBOSE" ]] ; then
                echo "emerge -puD world produced expected results."
        fi
}

# Check for duplicate package lines in a package.* file
function checkrdups
{
        local file=$1

        if [[ "$VERBOSE" ]] ; then echo "Checking for duplicate package lines 
in $file..." ; fi

        declare -a seenpkgs
        local dindex=0
        local seen=0

        # This could probably use getpkgs
        for i in `cat $file | awk '{ print $1 }' | sed 's/[~><=]//g' | sed 
's/^\(.*\/.*\)-[0-9]\{1,\}.*$/\1/g' | grep ^[A-Za-z][^\ ]*[A-Za-z]$ | sort | 
xargs`
        do
                seen=0
                if [[ "$VV" ]] ; then echo "Looking at $i..." ; fi
                for j in ${seenpk...@]}
                do
                        # Check for duplicate package lines
                        if [[ "$j" == "$i" ]] ; then
                                seen=1
                                echo "Duplicate line for $i in $file.  May want 
to do something about it."
                                break
                        fi
                done
                if [[ "$seen" == "0" ]] ; then
                        seenpkgs[$dindex]=$i
                        let "dindex++"
                        # Check if category exists if this is a category line
                        if [ -n "`echo $file | grep flag`" -a -z "`echo $i | 
grep \/`" ] ; then
                                if ! [ -d "/usr/portage/$i" ] ; then
                                        echo "$i is in $file but does not seem 
to exist in portage."
                                fi
                        fi
                fi
        done
}

# Check for duplicate modifiers in a package. file (not for package.use)
function checkdups
{
        local file=$1

        if [[ "$VERBOSE" ]] ; then echo "Checking for duplicates in $file..." ; 
fi
        
        # Array of modifiers for one package
        declare -a npkgflgs
        
        # Look through each package's modifiers
        getflags $file
        for i in "${fla...@]}"
        do
                i="`echo $i | sed 's/@/\ /g'`"
                if [[ "$VV" ]] ; then echo "Looking at $i..." ; fi
                # If there is more than one modifier
                if [ -n "`echo "$i" | awk '{ print $3 }'`" ]
                then
                        # Extract package
                        local pkg="`echo "$i" | awk '{ print $1 }' | awk -F / 
'{ print $1 "\\\\/" $2 }'`"
                        # Extract package's modifiers
                        local npkgflgs=( `echo $i | sed -e 's/\ /\n/g' -e 
'/^$/d' -e "s/$pkg\n//g" | sort | uniq | xargs` )
                        # Find where the package's lines are in $file
                        local olines="`egrep -n "$pkg(\ |\-[0-9])" $file | grep 
-v '^[\ ]*#.*' | sed 's/\(.*\)#.*/\1/g' | awk -F : '{ print $1 }' | xargs`"
                        if [ -n "`echo "$olines" | grep '[0-9]'`" ] ; then
                                echo "$file has duplicate lines for `echo "$i" 
| awk '{ print $1 }'`."
                                echo "The offending lines are $olines."
                                echo "The conflicting flags are ${npkgfl...@]}."
                                echo "You may run the script with the -d0 flag 
if you know what you're doing."
                                echo "(Read --help for a bit more information.)"
                                if [[ "${#npkgfl...@]}" > 1 ]] ; then
                                        echo "You MUST fix this in order to use 
this script!"
                                        exit $DUPLICATE_FAIL
                                else
                                        echo "You SHOULD fix this, though it is 
valid and won't affect this script."
                                        if readyesno "Would you like to 
continue?"
                                        then
                                                exit $DUPLICATE_WARN
                                        fi
                                fi
                        fi
                fi
        done
        if [[ "$VV" ]] ; then echo ; fi
}

# Gets package modifiers from a file.  Moves all modifiers to one package line.
function getflags
{
        local file=$1
        if [[ "$VERBOSE" ]] ; then echo "Getting package modifiers from 
$file..." ; fi
        flags=( `egrep "^([a-z]|(<|>|=|~))+.+/[A-z]+.+$" $file | sed -e 
's/^\(.*\/[_A-z0-9\-]*\)[^\ ]*\(.*\)/\1\2/' -e 's/\-[0-9]\ /\ /g' | awk 
'{i=$1;$1="";a[i]=a[i]$0}END{for(i in a)print i a[i]}' | sort | sed -e 
's/\(.*\)#.*/\1/g' -e 's/\ /\@/g' | xargs` )
}

# Gets category modifers from a file.  Moves all modifiers to one category line.
function getflags4cats
{
        local file=$1
        if [[ "$VERBOSE" ]] ; then echo "Getting category modifers from 
$file..." ; fi
        flags=( `egrep "^[a-z]+[^/]*$" $file | awk 
'{i=$1;$1="";a[i]=a[i]$0}END{for(i in a)print i a[i]}' | sort | sed -e 
's/\(.*\)#.*/\1/g' -e 's/\ /\@/g' | xargs` )
}

# Gets packages from a package.* file.
function getpkgs
{
        local file=$1
        if [[ "$VERBOSE" ]] ; then echo "Getting packages from $file..." ; fi
        # Work around if there is no 'Keep' section in the file
        if [ -n "`grep Keep $file`" ] ; then
                local tv="`cat $file | sed -n '/.*Keep.*/,$p'`"
        else
                local tv="`cat $file`"
        fi
        # Array of packages listed in $file
        packages=( `echo "$tv" | egrep -v "^[\ ]*#.*" | awk '{ print $1 }' | 
egrep "^([a-z]|(<|>|=|~))+.+/[A-z]+.+$" | sed -e 's/^[=|<|>]*\(.*\)$/\1/g' -e 
's/^\(.*\)-[0-9]\{1,\}.*$/\1/g' | sort | uniq | xargs` )
}

# Gets categories from a package.* file.
function getcats
{
        local file=$1
        if [[ "$VERBOSE" ]] ; then echo "Getting categories from $file..." ; fi
        # Array of categories listed in $file
        categories=( `tac $file | egrep -v "^[\ ]*#.*" | awk '{ print $1 }' | 
egrep "^[a-z]+[^/]*$" | sort | uniq | xargs` )
}

# Sets s to a flag's antiflag
function antiflag
{
        flag=$1
        if [ -n "`echo "$flag" | grep '^\-[^\ ]+$'`" ] ; then
                s="`echo "$j" | sed 's/\-\([^\ ]*\)/\1/g'`"
        else
                s="`echo "$j" | sed 's/\([^\ ]*\)/\\\-\1/g'`"
        fi
}

# Check the flags of a file for sanity, requires dupport, temparr, and dindex
function checkflags
{
        local file=$1
        local package=$2
        local flag=$3
        local remgroup=$4

        if [[ "$VV" ]] ; then echo "Checking flag $flag..." ; fi

        if [ -n "`echo "$remgroup" | grep 'ebuild'`" ] ; then
                userg=1
        else
                userg=0
        fi

        # Check if flag is needed
        if [[ "$userg" == 1 ]] ; then
                if [[ "$VV" ]] ; then echo "Checking if $flag is already 
implied..." ; fi
                local jj="`echo "$flag" | sed 's/^[\-]\{0,1\}\(.*\)$/\1\\\*/g'`"
                if [ -n "`echo "$remgroup" | grep "\[ebuild\ " | grep $package 
| sed 's/^\[ebuild\ \([A-Z\ ]*\)\ \]\ .*/\1/g' | grep [NU]`" ] ; then
                        if [[ "$VERBOSE" ]] ; then echo "Cannot determine 
status of $flag for $package." ; fi
                else
                        if [ -z "`echo $remgroup | egrep $jj`" ] ; then echo 
"For package $package flag $flag may be removed." ; fi
                fi
        fi
        # Get flag's anti-flag
        antiflag "$flag"
        # Check if anti-flag is set as well
        if [ -n "`echo "${tempa...@]}" | egrep "(^$s|\ $s\ |\ $s$)"`" ] ; then
                local olines="`grep -n "$package" $file.bak.keep | awk -F : '{ 
print $1 }' | xargs`"
                echo "Conflicting flag $flag for $package in $file on line(s) 
$olines."
        fi
        # Check for duplicate flags
        local escj=`echo "$flag" | sed 's/\-/\\\-/g'`
        local goon=0
        for k in "${duppo...@]}"
        do
                if [[ "$VV" ]] ; then echo "Comp: $k v. $flag" ; fi
                if [[ "$k" == "$flag" ]] ; then local goon=1 ; fi
        done
        if [[ "$VV" ]] ; then echo "Setting Reapeats[$dindex] to $flag." ; fi
        dupport[dindex]="$flag"
        let "dindex++"
        if [ "$goon" -eq "1" ]
        then
                local olines="`grep -n "$package" $file.bak.keep | grep "$escj" 
| awk -F : '{ print $1 }' | xargs`"
                echo "Duplicate flag $flag for $package in $file on line(s) 
$olines."
        fi
}

# Checks individual flags for each package in package.use or package.c*flags.
# It does not offer an option to remove them if they are not needed.
function othercheck
{
        unset packages
        local file=$1
        # Stores per-package useflags
        declare -a temparr
        # Stores duplicate reported useflags
        declare -a dupport

        cd $FILES_DIR
        echo
        checkrdups $file
        getpkgs $file
        getcats $file
        getflags $file
        local index=0
        dindex=0
        if [[ "$file" == "package.use" ]] ; then local usef=1 ; fi

        # For determining if package is installed
        if [[ "$VERBOSE" ]] ; then echo "Checking for masking/existence 
problems over $file..." ; fi
        local emerges="`emerge -p \`echo "${packag...@]}"\``"
        local mpkg="`echo $emerges | grep 'satisfy\ .*\.' | awk -F \\\" '{ 
print $2 }'`"
        checksanity "$emerges" "Please confirm that $mpkg exists and is not 
masked." $file
        local emerges="`echo "$emerges" | grep "\[ebuild\ "`"
        mv -f $file $file.bak.keep

        echo "Checking for unnecessary entries in $file..."
        echo

        # For each package
        if [[ "$VERBOSE" ]] ; then echo "Looking at packages..." ; fi
        for i in "${packag...@]}"
        do
                if [[ "$VV" ]] ; then echo "Looking at $i..." ; fi
                # Check if package is installed
                if [ -z "`echo "$emerges" | egrep \"[B\ ]N\ [A-Z\ ]{3}\]\ 
$i\"`" ]
                then
                        if [[ "$VV" ]] ; then echo "Package seems to be 
installed..." ; fi
                        # Get package's emerge -pv string
                        if [[ "$usef" == 1 ]] ; then local empvs="`emerge -pv 
"$i"`" ; fi
                        # Extract flags into an array
                        temparr=( `echo "${flags[index]}" | sed -e 's/\@/\ /g' 
-e 's/^[^\ ]* \(.*\)$/\1/g'` )
                        # For each flag of that package
                        dindex=0
                        dupport=()
                        for j in "${tempa...@]}"
                        do
                                if [[ "$j" != "--param" ]] ; then checkflags 
"$file" "$i" "$j" "$empvs" ; fi
                        done
                        unset temparr
                else
                        echo "$i is in $file but is not installed."
                fi
                let "index++"
                if [[ "$VV" ]] ; then echo ; fi
        done
        local index=0
        # For each category (for package.*flags files)
        getflags4cats $file.bak.keep
        if [[ "$VERBOSE" ]] ; then echo "Looking at categories..." ; fi
        for i in "${categori...@]}"
        do
                if [[ "$VV" ]] ; then echo "Looking at $i..." ; fi
                temparr=( `echo "${flags[index]}" | sed -e 's/\@/\ /g' -e 
's/^[^\ ]* \(.*\)$/\1/g'` )
                dindex=0
                dupport=()
                for j in "${tempa...@]}"
                do
                        if [[ "$j" != "--param" ]] ; then checkflags "$file" 
"$i" "$j" ; fi
                done
                let "index++"
                unset temparr
        done
        mv -f $file.bak.keep $file
}

# Finds unnecessary entries and (optionally) removes them (for all but 
package.use/*flags)
function nonusecheck
{
        unset packages remove
        local file=$1
        local auto=$2
        local checkdup=$3

        echo
        cd $FILES_DIR
        checkrdups $file
        if [[ "$checkdup" != 0 ]] ; then checkdups $file ; fi
        getpkgs $file
        echo "Checking for unnecessary entries in $file..."
        echo
        
        mv -f $file $file.bak.keep
        declare -a remove
        declare -a iversions
        local index=1

        # Find obvious downgrades
        if [[ "$VERBOSE" ]] ; then echo "Checking for obvious cases..." ; echo 
; fi
        local obvious="`emerge -puD world | egrep "\[ebuild[\ ]{5}UD\]"`"

        # For each package in the file
        for i in "${packag...@]}"
        do
                cat $file.bak.keep | grep -v "$i" > $file
                i="`echo "$i" | sed 's/^[^a-z]*\([a-z].*\)$/\1/g'`"
                if [[ "$VV" ]] ; then echo "Looking at $i..." ; fi
                # If it's in obvious, its line is necessary
                if [ -z "`echo "$obvious" | grep $i`" ]
                then
                        if [[ "$VV" ]] ; then echo "Passed obvious check..." ; 
fi
                        # What we get when we try to emerge it without its line
                        local raw=`emerge -p "$i"`
                        local es=`echo "$raw" | grep "\[ebuild\ " | grep "$i"`
                        if [ -n "$es" ]
                        then
                                if [[ "$VV" ]] ; then echo "Passed verioning 
check..." ; fi
                                local continu=1
                                # Make sure package is a candidate for slotting 
before bothering with check
                                if [ -n "`echo "$es" | sed 's/^\[ebuild\ 
\([^]]*\)].*/\1/g' | grep 'S'`" ]
                                then
                                        if [[ "$VV" ]] ; then echo "Package 
looks to be a slot candidate..." ; fi
                                        # Vars for working with slotted packages
                                        local category="`echo "$es" | sed 
's/^.*\ \(.*\)\/.*$/\1/g'`"
                                        local version="`echo "$es" | sed 
's/^.*-\([0-9]\{1,\}[^\ ]*\)\(.*$\|$\)/\1/g'`"
                                        local package="`echo "$es" | sed 
's/^.*\/\(.*\)-[0-9]\{1,\}.*$/\1/g'`"
                                        local iversions=( `ls 
/var/db/pkg/$category/ | sed 's/\ /\n/g' | grep "$package" | sed 
's/^.*-\([0-9]\{1,\}.*\)$/\1/g' | xargs` )
                                        if [[ "$VV" ]] ; then echo "Cat: 
$category, Ver: $version, Pak: $package, Ivers: ${iversio...@]}" ; fi
                                        # Make sure that we are not just 
emerging an already installed slotted version
                                        local where=0
                                        local this=0
                                        for j in "${iversio...@]}"
                                        do
                                                let "where++"
                                                if [[ "$j" == "$version" ]] ; 
then this=$where ; fi
                                        done
                                        if [ $where -gt $this ] ; then
                                                local continu=0
                                                if [[ "$VV" ]] ; then echo 
"Failed slot check ($where > $this)." ; fi
                                        else
                                                if [[ "$VV" ]] ; then echo 
"Passed slot check ($where <= $this)..." ; fi
                                        fi
                                elif [[ "$VV" ]]
                                then
                                        echo "Passed slot check (implcity)..."
                                fi
                                # If we would get the same version without the 
keyword/unmasking or if the package
                                # is not installed.  We cannot group these 
emerges because of masking problems.
                                if [ -n "`echo "$es" | egrep \"(\ [B\ ]\ R[F\ 
]{3}]|\ [B\ ]N[\ ]{4}\]|o\ satisfy)\"`" ]
                                then
                                        remove[index]=$i
                                        let "index++"
                                        if [ "$continu" -eq "1" -a -n "`echo 
"$es" | egrep \"(\ [B\ ]\ R[F\ ]{3}]|o\ satisfy)\"`" ] ; then
                                                echo "$i in $file is 
unnecessary."
                                        elif [ -z "`echo "$es" | egrep \"(\ [B\ 
]\ R[F\ ]{3}]|o\ satisfy)\"`" ] ; then
                                                echo "$i is in $file but is not 
installed."
                                        fi
                                elif [ "$continu" -eq "1" ] ; then
                                        if [[ "$VV" ]] ; then echo "Failed 
change check." ; fi
                                fi
                                
                        elif [ -n "`echo "$raw" | grep "$i" | grep 'no\ 
ebuilds\ to\ satisfy\ .*\.'`" ] ; then
                                remove[index]=$i
                                let "index++"
                                echo "$i in $file does not seem to exist in 
portage."
                        else
                                if [[ "$VV" ]] ; then echo "Failed versioning 
check." ; fi
                                # Check masked packages to see if they're 
actually installed or not
                                local es="`echo "$raw" | grep '\ could\ 
satisfy\ ' | grep "$i" | sed 's/^.*\"\(.*\)\".*$/\1/g' | head -n 1 | sed 
's/^.*\ \(.*\/.*\)-[0-9]\{1,\}.*$/\1/g'`"
                                if [ -n "$es" ]
                                then
                                        local installed="`emerge -p unmerge 
"$es" | grep "Couldn't find $es"`"
                                fi
                                if [ -n "$installed" ] ; then
                                        echo "$i is in $file but is not 
installed."
                                        remove[index]=$i
                                        let "index++"
                                fi
                                unset installed
                        fi
                elif [[ "$VV" ]] ; then
                        echo "Failed obvious check."
                fi
                if [[ "$VV" ]] ; then echo ; fi
        done
        doremfunc $file $auto
}

# Prompts (or automatically) removes unnecessary entries from a file.  It looks
# in $remove to find unnecessary packages.  Best not used on package.use/*flags.
function doremfunc
{
        local file=$1
        local auto=$2
        
        # If there was anything to remove ask about removing it
        if [ "${#remo...@]}" -gt 0 ]
        then
                # Handle automation
                if [ -z "$auto" ] ; then
                        echo
                        readyesno "Remove the unnecessary entries?"
                        local yesno=$?
                else
                        yesno=$auto
                fi
                
                # If they want to remove entries from this file
                if [ "$yesno" -eq 1 ]
                then
                        if [[ "$VERBOSE" ]] ; then echo "Removing entries from 
$file..." ; fi
                        # Move file, and get some backups in case sed chokes
                        mv -f $file.bak.keep $file
                        cp -f $file $file.bak
                        
                        # Remove each package's line from file
                        result="`cat $file`"
                        for i in "${remo...@]}"
                        do
                                if [[ "$VV" ]] ; then echo "Removing $i..." ; fi
                                # Get around sed not liking /'s
                                i=`echo "$i" | awk -F / '{ print $1 "\\\\/" $2 
}'`
                                result="`echo "$result" | sed "/$i/d"`"
                        done
                        echo "$result" > $file
                        
                        # Get lines in orginal file
                        local lines="`wc \"$file.bak\" | awk '{ print $1 }'`"
                        # If file is 0 bytes and orginal was longer than 1 
lines use backup
                        if [ `ls -l $file | awk '{ print $5 }'` -eq 0 -a 
"$lines" -gt 1 ] ; then
                                echo "There was an error while removing 
unnecessary entries."
                                echo "The backup file for $file has been 
restored."
                                mv -f $file.bak $file
                        else
                                echo "Unnecessary entries successfully removed."
                                rm -f $file.bak
                        fi
                else
                        # If they don't want to auto-remove
                        mv -f $file.bak.keep $file
                fi
        fi
        
        # If there was nothing to remove
        if [ -f "$file.bak.keep" ] ; then
                mv -f $file.bak.keep $file
        fi
}

# Check that neededprogs exist
function checkprogs
{
        for i in "${neededpro...@]}"
        do
                if [[ "$VV" ]] ; then echo "Checking for usability of $i" ; fi
                if [ -n "`which $i | grep "\ no\ $i\ in"`" ] ; then
                        echo "$i is required to use etcportclean.  Please 
install it or add it to your path."
                        exit $MISSING_DEPENDENCY
                fi
        done
}

# Check for an updated version of etcportclean
function update
{
        neededprogs=( "wget" "sha1sum" )
        checkprogs
        quiet="-q"

        if [[ "$VERBOSE" ]] ; then
                quiet=""
                echo "Downloading most recent version of etcportclean..."
        fi
        wget $quiet -t 2 -T 10 -O /tmp/etcportclean.tmp http://$WEB
        wget $quiet -t 2 -T 10 -O /tmp/etcportclean.sha1 http://$WEB.sha1
        if [ -s /tmp/etcportclean.tmp -a -s /tmp/etcportclean.sha1 ] ; then
                if [[ "$VV" ]] ; then echo "Both sha1 and new version 
downloaded successfully." ; fi
        else
                echo "Could not download the most recent etcportclean.  You 
could try getting it"
                echo "manually at $WEB, or try -u again later."
                echo
                rm -f /tmp/etcportclean.*
                exit $CANNOT_DOWNLOAD
        fi
        if [[ "$VERBOSE" ]] ; then echo "Checking hashes..." ; fi
        local localhash="`sha1sum /tmp/etcportclean.tmp | awk '{ print $1 }'`"
        local webhash="`cat /tmp/etcportclean.sha1 | grep etcportclean | awk '{ 
print $1 }'`"
        if [[ "$localhash" != "$webhash" ]]
        then
                echo "WARNING: Incorrect hash found!  The new version of 
etcportclean"
                echo "may have been tampered with.  Cannot auto-update."
                echo
                exit $BAD_HASH
        fi
        if [[ "$VERBOSE" ]] ; then echo "Checking versions..." ; fi
        chmod +x /tmp/etcportclean.tmp
        local dlversion="`/tmp/etcportclean.tmp --help | head -n 1 | sed 
's/^.*\([0-9]\{1\}\.[0-9]\{2\}\)\ .*$/\1/g'`"
        local thisversion="`$0 --help | head -n 1 | sed 
's/^.*\([0-9]\{1\}\.[0-9]\{2\}\)\ .*$/\1/g'`"
        if [[ "$dlversion" > "$thisversion" ]]
        then
                echo "Updating etcportclean ($thisversion to $dlversion)..."
                mv -f /tmp/etcportclean.tmp $0
                rm -f /tmp/etcportclean.sha1
                echo "Etcportclean successfully updated."
                echo
                exit $SUCCESS
        else
                rm -f /tmp/etcportclean.*
                echo "You already have the most recent ($thisversion) version 
of etcportclean."
                echo
                exit $SUCCESS
        fi
}

# Array of answers for which files to check
declare -a ynarray

# Parse command-line arguments
prog=$0
checkworldifnull=1
for i in "$@"
do
        iend=`echo "$i" | tail -c-2`
        case `echo "$i" | head -c2` in
                -v) # Verbose
                        if [[ "$iend" == "1" || "$iend" == "v" ]] ; then 
VERBOSE=1 ; fi
                ;;
                -V) # Very verbose
                        if [[ "$iend" == "1" || "$iend" == "V" ]] ; then
                                VV=1
                                VERBOSE=1
                        fi
                ;;
                -d) # Duplicate check (for all but package.use)
                        checkdup=$iend
                ;;
                -r) # Automatic removal
                        autorem=$iend
                ;;
                -u) # Update
                        if [[ "$iend" == "1" || "$iend" == "u" ]] ; then 
doupdate=1 ; fi
                ;;
                -w) # Emerge -puD world check
                        let "checkworldifnull--"
                        if [ -z $iend -o `echo "$i" | tail -c-2` -eq 1 ] ; then 
checkworld ; fi
                ;;
                -c) # Look at (keywords,unmask,mask,use,cflags,cxxflags,ldflags)
                        declare -a checkarr
                        for j in `seq 0 $((${#fil...@]}-1))`
                        do
                                let "k=j+1"
                                checkarr[j]=`echo "$i" | rev | head -c-3 | rev 
| cut -c$k`
                        done
                ;;
                *) usage ;;
        esac
done

# Make sure all needed programs are found
checkprogs

# Update if requested
if [[ "$doupdate" == 1 ]] ; then update ; fi

# Ask for which files they want to look at
index=0
for i in "${fil...@]}"
do
        # Only bother with asking if the file exists
        if [ -f "$FILES_DIR/$i" ]
        then
                # ...and they didn't specify a choice on the command line
                if [ -z "${checkarr[$index]}" ] ; then
                        readyesno "Check $i for ${messages[$index]}?"
                        result="$?"
                elif [[ "${checkarr[$index]}" == "0" || "${checkarr[$index]}" 
== "1" ]] ; then
                        result="${checkarr[$index]}"
                else
                        usage
                fi
                ynarray[index]=$result
        fi
        let "index++" 
done

# Check 'emerge -puD world' if no preference was indicated and they're looking
# at more than just package.use
if [ $checkworldifnull -eq 1 ]
then
        if [ ${ynarray[0]} -eq 1 -o ${ynarray[1]} -eq 1 -o ${ynarray[2]} -eq 1 
] ; then checkworld ; fi
fi

# Look at selected files
any=0
where=0
for i in "${fil...@]}"
do
        # If they said yes
        if [[ "${ynarray[$where]}" == 1 ]]
        then
                any=1
                # Package.(use|cflags|cxxflags|ldflags) special case
                if [[ "$i" != "package.keywords" && "$i" != "package.unmask" && 
"$i" != "package.mask" ]] ; then
                        othercheck "$i" "$autorem" "$checkdup"
                else
                        nonusecheck "$i" "$autorem" "$checkdup"
                fi
        fi
        let "where++"
done

# If they said 'no' to all the questions, or they don't have any of the files
if [ "$any" -eq 0 ]
then
        echo 
        echo "You must have at least one of:"
        for i in "${fil...@]}"
        do
                echo "  $FILES_DIR/$i"
        done
        echo "in order to use this script."
        exit $NO_FILES
fi

echo 
echo "Done."
exit $SUCCESS

Reply via email to