#!/bin/bash # useflag v0.2 # 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 , (c) 2002 run_name=`basename $0` use_desc="/usr/portage/profiles/use.desc" make_conf_dir="/etc" make_conf="${make_conf_dir}/make.conf" make_temp="/tmp/use.make.conf" use_cache_parent="/var/cache" use_cache_dir="${use_cache_parent}/use_desc" use_cache="${use_cache_dir}/use.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 local get_make_out=`grep "USE=\"" $make_conf | grep -v "#" | \ cut -d "\"" -f2 -s` # 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. do_get_avail() { grep -v "#" $use_desc | cut -d " " -f1 | tr '\n' ' ' } # Get depreciated flags. # parm1 = flag to check for depreciation # 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 } # 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 cat $make_conf | \ sed -e "s/${old_use}/${use_write}/" > $make_temp # Race condition cp $make_temp $make_conf rm $make_temp echo 0 else echo 1 fi } # The main section of the script # desc: # This is the feature for getting USE descriptions. if [ "$1" = "desc" ]; then if [ -r $use_desc ]; then for flag in ${@:2}; do do_get_desc $flag done else echo "!!! Could not read $use_desc." echo "!!! 'emerge rsync' and try again." exit 1 fi # show: # This is the feature for showing the contents of the USE variable. elif [ "$1" = "show" ]; then if [ -r $make_conf ]; then do_get_make dashes else echo "!!! Could not read from $make_conf" echo "!!! Verify that you have read access to this file." exit 1 fi # del: # This is the feature for removing a USE flag. elif [ "$1" = "del" ]; then if [ -r $make_conf ]; then make_use=`do_get_make dashes` else echo "!!! Could not read $make_conf" echo "!!! Verify that you have read access to this file." exit 1 fi for flag in ${@:2}; do changes="1" make_use=`do_use_rm $flag $make_use` done if [ "$changes" != "0" ]; then write_succ=`do_write_make $make_use` if [ "$write_succ" != "0" ]; then echo "!!! Could not write to $make_conf" echo "!!! Got root?" exit 1 fi fi # add: # This is the feature for explicitly enabling or disabling a USE flag. elif [ "$1" = "add" ]; then if [ -r $make_conf ]; then make_use=`do_get_make dashes` else echo "!!! Could not read $make_conf" echo "!!! Verify that you have read access to this file." exit 1 fi for flag in ${@:2}; do changes="1" make_use=`do_use_add $flag $make_use` done if [ "$changes" != "0" ]; then write_succ=`do_write_make $make_use` if [ "$write_succ" != "0" ]; then echo "!!! Could not write to $make_conf" echo "!!! Got root?" exit 1 fi fi # update: # This is the feature to update your USE by removing depreciated flags and # handling new flags. elif [ "$1" = "update" ]; then if [ -r $make_conf ]; then # Get our USE but strip leading dashes make_use=`do_get_make nodashes` else echo "!!! Could not read $make_conf" echo "!!! Verify that you have read access to this file." exit 1 fi if [ -r $use_desc ]; then use_avail=`do_get_avail` else echo "!!! Could not read $use_desc" echo "!!! Verify that you have read access to this file." exit 1 fi # First we check for depreciated flags. echo "..::[USE-UPDATE]::.." echo echo "Your USE variable currently looks like this:" echo echo `do_get_make dashes` echo echo echo "*** Checking for depreciated 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 make_use=`do_get_make dashes` if [ "$flag_depr" = "" ]; then echo "!!! No depreciated flags were found." else echo "The following USE flags appear to be depreciated:" echo "$flag_depr" echo echo -n "Would you like to remove them? " echo -n "[y]es, [n]o, [i]ndividually : " while [ "$luser_input" = "" ]; do read luser_input case $luser_input in "y" | "Y") changes="1" for flag in $flag_depr; do make_use=`do_use_rm $flag $make_use` done echo echo -n "*** All depreciated flags were " echo "removed." ;; "n" | "N") echo echo "*** No flags were removed." ;; "i" | "I") for flag in $flag_depr; do echo -n "$flag appears to be " echo -n "depreciated. Remove it? " echo -n "[y/n] : " 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") ;; *) luser_yn="" ;; esac done done echo echo -n "*** All depreciated flags " echo "processed." ;; *) luser_input="" ;; esac done 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 [ -r $use_cache ]; then use_old=`cat $use_cache` echo "$use_avail" > $use_cache elif [ -w $use_cache_parent ]; then mkdir -p $use_cache_dir echo "$use_avail" > $use_cache use_old="" else echo "!!! Could not create $use_cache" echo "!!! Got root?" exit 1 fi make_cand=`do_get_make nodashes` for flag in $use_avail; do new_cand="${new_cand}`do_get_depr $flag $make_cand`" done 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 "Enter (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 write_succ=`do_write_make $make_use` if [ "$write_succ" != "0" ]; then echo "!!! Could not write $make_conf" echo "!!! Got root?" exit 1 fi fi echo echo echo "..::[Script Complete]::.." # help: # This displays the documentation elif [ "$1" = "help" ]; then echo "$run_name documentation:" echo echo "$run_name can be run with the following paramters:" echo "help, show, desc, add, del, update" echo echo echo "$run_name help" echo "This will display the extended help information that you are" echo "currently looking at. This is TFM." echo echo echo "$run_name show" echo "This will echo the raw contents of the USE variable as defined" echo "in make.conf. The echoed output will not show the USE=" echo echo echo "$run_name desc [flag] ..." echo "This will display a description of the flags listed on the" echo "command line. The flags should be seperated by spaces and" echo "should not contain leading dashes. If a flag does not exist or" echo "has no description, you will be told such. Ex: " echo echo "\$ $run_name desc icc X" echo "icc - Use the Intel C++ Compiler if the package supports it" echo "X - Adds support for XFree86" echo echo echo "$run_name add [[-]flag] ..." echo "This will add one or more flags to your USE variable defined in" echo "make.conf. It will not check to see if a flag exists in" echo "use.desc. This allows you to add flags that are not described." echo "If a flag already exists, it will be replaced. If a flag is" echo "replaced, the new flag will appear at the end of your USE" echo "variable. A leading dash can be added to explicitly disable a" echo "flag in your USE variable. For example, if your USE variable" echo "reads:" echo echo "USE=\"alsa gnome gtk -imap oss\"" echo echo "and you execute:" echo echo "# $run_name add -alsa icc imap" echo echo "then your USE variable will read:" echo echo "USE=\"gnome gtk oss -alsa icc imap\"" echo echo echo "$run_name del [[-]flag] ..." echo "This will delete one or more flags from your USE variable" echo "defined in make.conf. The dash is optional. A flag will be" echo "removed regardless of whether it has a dash either on the" echo "command line or in make.conf. For example, if your USE variable" echo "reads:" echo echo "USE=\"gnome gtk oss -alsa icc -imap\"" echo echo "and you execute:" echo echo "# $run_name del -gtk oss imap" echo echo "then your USE variable will read:" echo echo "USE=\"gnome -alsa icc\"" echo echo echo "$run_name update" echo "This will interactively update your USE variable as defined in" echo "make.conf to reflect changes in use.desc. First, it will check" echo "for depreciated USE flags by searching your USE variable for" echo "flags that no longer appear in use.desc. You will then be" echo "presented with several options for handling these flags. Next," echo "use.desc will be searched for new flags that have become" echo "available. The first time you run it, you will be presented" echo "with several options for handling all flags that are not in your" echo "USE variable. This can be useful when creating a USE variable" echo "from scratch on a new machine. From then on, you will only be" echo "prompted when new flags appear in use.desc." echo echo "Note: You need an existing USE variable defined in make.conf in" echo "order for this tool to work. The USE variable may be empty. If" echo "the USE variable is commented out, this tool will not function." echo # Display USAGE statement for unhandled parameters else echo "Usage:" echo echo "$run_name help" echo "Prints the manual for this utility." echo echo "$run_name show" echo "Prints the contents of your USE variable." echo echo "$run_name desc [flag] ..." echo "Prints descriptions of USE flags." echo echo "$run_name add [[-]flag] ..." echo "Adds the specified flag(s) to your USE variable." echo echo "$run_name del [[-]flag] ..." echo "Removes the specified flag(s) from your USE variable." echo echo "$run_name update" echo -n "Updates your USE variable based on the latest changes to " echo "use.desc" exit 1 fi exit 0