aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
Diffstat (limited to 'src/useflag/useflag')
-rw-r--r--src/useflag/useflag610
1 files changed, 610 insertions, 0 deletions
diff --git a/src/useflag/useflag b/src/useflag/useflag
new file mode 100644
index 0000000..fd4cc08
--- /dev/null
+++ b/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
+