#!/bin/bash # Copyright megabaks # Distributed under the terms of the GNU General Public License v3 or later ############################################################################ ################ portage functions ######################################### if [[ -f "/lib/gentoo/functions.sh" ]]; then source /lib/gentoo/functions.sh else source /usr/lib*/portage/bin/isolated-functions.sh fi ############################################################################ ################ colors #################################################### green="\033[01;32m" red="\033[01;31m" restore="\033[00m" contrast="\033[1m" underline="\033[4m" ############################################################################ ################ init ###################################################### PKGDB="/var/db/pkg" BRDIR="/var/lib/portconf" PORT_ETC="/etc/portage" WORLD="/var/lib/portage/world" ARCH="$(eix --print DEFAULT_ARCH)" [[ -f "/etc/portconf.conf" ]] && . /etc/portconf.conf COUNT="${COUNT:-10}" ############################################################################ ################ ignore #################################################### [[ -n "${IGNORE_CATEGORY}" ]] && IGNORE_CATEGORY="$(sed -e '/^$/d' -e 's/$/\/.*/g' <<< "`tr "[:space:]" $'\n' <<< "${IGNORE_CATEGORY}"`")" [[ -n "${IGNORE_PN}" ]] && IGNORE_PN="$(sed -e '/^$/d' -e 's/^/.*\//g' <<< "`tr "[:space:]" $'\n' <<< "${IGNORE_PN}"`")" IGNORE="${IGNORE_CATEGORY} ${IGNORE_PN}" IGNORE="$(sed -e '/^$/d' <<< "${IGNORE}")" IGNORE="${IGNORE:-'Hello, LOR! :3'}" ############################################################################ ################ sort_passed_uses ########################################## sort_passed_uses(){ for opt in ${1};do opt="${opt//\*/\\*}" uses="$(tr "[:space:]" $'\n' <<< ${uses} | grep -v -e "^${opt#-}$" -e "^\-${opt#-}$" | tr $'\n' " ")" uses+=" $(tr "[:space:]" $'\n' <<< ${1} | grep -e "^${opt#-}$" -e "^\-${opt#-}$" | tail -n1)" unset opt done echo ${uses} unset uses } ############################################################################ ################ profile ################################################### profile() { local use path [[ -f "${1}/make.defaults" ]] && . "${1}/make.defaults" use="$USE" if [[ -f "${1}/parent" ]]; then for path in `cat ${1}/parent`;do use="$use $(profile "${1}/$path")" done fi echo $use } [[ -h "/etc/make.profile" ]] && pre_profile="$(profile `readlink -f /etc/make.profile`)" [[ -h "/etc/portage/make.profile" ]] && pre_profile="$(profile `readlink -f /etc/portage/make.profile`)" profile_uses="$(sort_passed_uses "${pre_profile}")" PROFILE="$(tr "[:space:]" $'\n' <<< ${profile_uses})" ############################################################################ ################ all_use_all_profiles ###################################### all_use_all_profiles(){ for target in `eselect --brief profile list`;do profile_uses="$(profile "${PORTDIR}/profiles/${target}")" USEs="$(sort_passed_uses "${profile_uses}")" echo -e "\n${green}${target}${restore}: "${USEs} | fold -s -w `tput cols` unset USEs done } ############################################################################ ################ profile_use ############################################### profile_use(){ PS3=`echo -e "${contrast}Choose number:${restore} "` select target in `eselect --brief profile list`;do profile_uses="$(profile "${PORTDIR}/profiles/${target}")" USEs="$(sort_passed_uses "${profile_uses}")" echo -e "\n${green}${target}${restore}: "${USEs} | fold -s -w `tput cols` unset USEs break done } ############################################################################ ################ current_profile ########################################### current_profile(){ if [[ -h "/etc/make.profile" ]];then target="$(readlink /etc/make.profile | sed 's|.*/profiles/||')" else target="$(readlink /etc/portage/make.profile | sed 's|.*/profiles/||')" fi profile_uses="$(profile "${PORTDIR}/profiles/${target}")" USEs="$(sort_passed_uses "${PROFILE}")" echo -e "${green}${target}${restore}: "${USEs} | fold -s -w `tput cols` unset USEs } ############################################################################ ################ make.conf ################################################# [[ -f "/etc/make.conf" ]] && makefile="/etc/make.conf" [[ -f "${PORT_ETC}/make.conf" ]] && makefile="${PORT_ETC}/make.conf" . "${makefile}" 2>/dev/null MAKE_USES="${USE}" unset USE PORTDIR="${PORTDIR:-/usr/portage}" ############################################################################ ################ timestamp ################################################# timestamp(){ stat -c %Y ${*} 2>/dev/null | sort | tail -n1 } ############################################################################ ################ repo fix ################################################## repo_fix(){ if [[ -n "${PORTDIR_OVERLAY}" ]];then for path in ${PORTDIR_OVERLAY};do local_categories="$(ls -d1 ${path}/{*-*,virtual} 2>/dev/null | sed -e "s|${path}/||g" | sort -u)" portage_categoties="$(cat ${PORTDIR}/profiles/categories)" if [[ -n "$(grep -v "${portage_categoties}" <<< "${local_categories}")" ]];then if [[ ! -f "${path}/profiles/categories" ]];then [[ ! -d "${path}/profiles" ]] && mkdir "${path}/profiles" && tmp_categories+=" ${path}/profiles" echo -e "Creating temporary 'categories': ${path}" echo "${local_categories}" >> "${path}/profiles/categories" tmp_categories+=" ${path}/profiles/categories" fi fi done fi } ############################################################################ ################ rm repo fix ############################################### rm_repo_fix(){ if [[ -n "${tmp_categories}" ]];then for tmp_category in ${tmp_categories};do rm -rf "${tmp_category}" done fi } ############################################################################ ################ eix check ################################################# eix_check(){ if [[ -n "$(eix --version 2>/dev/null)" ]];then echo -e "${underline}Creating new temporary cache.${restore}" repo_fix eix_cache="$(mktemp)" chown portage:portage "${eix_cache}" 2>/dev/null export EIX_CACHEFILE="${eix_cache}" export OVERLAY_CACHE_METHOD="parse|ebuild*" eix-update else echo -e "${green}app-portage/eix${restore} ${red}not installed!${restore}" eend 1 2>/dev/null exit 1 fi rm_repo_fix } ############################################################################ ################ eix check method ########################################## eix_method(){ if [[ -n "$(eix --version 2>/dev/null)" ]];then if [[ "$(eix --print OVERLAY_CACHE_METHOD)" != "parse|ebuild*" ]];then [[ -n "${yes}" ]] && eix_check echo -ne "\n${red}!default 'OVERLAY_CACHE_METHOD'${restore}${contrast} Create temporary cache?${restore} [${green}Yes${restore}/${red}No${restore}] "; while read x;do case ${x} in Yes | YES | yes | Y | y | "" ) eix_check break;; No | NO | no | N | n ) break;; * ) echo -ne "Sorry, response '${x}' not understood. [${green}Yes${restore}/${red}No${restore}] " continue;; esac done fi else echo -e "${green}app-portage/eix${restore} ${red}not installed!${restore}" eend 1 2>/dev/null exit 1 fi } ############################################################################ ################ backup #################################################### backup(){ [[ -d "${BRDIR}" ]] || mkdir -p "${BRDIR}" tarballs="$(ls -1 --color=never ${BRDIR})" oldest="$(head -n1 <<< "${tarballs}")" newest="$(tail -n1 <<< "${tarballs}")" count="$( wc -l <<< "${tarballs}")" count="${count:-0}" if [[ -f "/etc/make.conf" ]];then etc_update="$(timestamp ${PORT_ETC}/{*,*/*,*/*/*,*/*/*/*} /etc/make.conf)" else etc_update="$(timestamp ${PORT_ETC}/{*,*/*,*/*/*,*/*/*/*})" fi portconf_update="$(timestamp ${BRDIR}/*)" portconf_update="${portconf_update:-0}" if (( "${etc_update}" > "${portconf_update}" ));then if (( "${count}" >= "${COUNT}" ));then rm "${BRDIR}/${oldest}" fi echo -e "/etc/portage backup: ${green}creating${restore}..." name="${BRDIR}/portage_$(date +%g.%m.%d-%H:%M).tar.bz2" if [[ -f "/etc/make.conf" ]];then tar -jcf "${name}" -C /etc/ portage make.conf else tar -jcf "${name}" -C /etc/ portage fi eend $? 2>/dev/null else echo -e "/etc/portage backups: ${green}already up-to-date${restore}" eend $? 2>/dev/null fi } ############################################################################ ################ world_backup ############################################## world_backup(){ world_dir="${BRDIR}/world" [[ -d "${world_dir}" ]] || mkdir -p "${world_dir}" tarballs="$(ls -1 --color=never ${world_dir})" oldest="$(head -n1 <<< "${tarballs}")" newest="$(tail -n1 <<< "${tarballs}")" count="$( wc -l <<< "${tarballs}")" count="${count:-0}" world_update="$(timestamp ${WORLD})" portconf_update="$(timestamp ${world_dir}/*)" portconf_update="${portconf_update:-0}" if (( "${world_update}" > "${portconf_update}" ));then if (( "${count}" >= "${COUNT}" ));then rm "${world_dir}/${oldest}" fi echo -e "world backup: ${green}creating${restore}..." name="${world_dir}/world_$(date +%g.%m.%d-%H:%M).tar.bz2" tar -jcf "${name}" -C ${WORLD%world} world eend $? 2>/dev/null else echo -e "world backups: ${green}already up-to-date${restore}" eend $? 2>/dev/null fi } ############################################################################ ################ restore ################################################### restore(){ tarballs="$(ls -1 --color=never ${1}/*.bz2)" tarballs="${tarballs//${1}\/}" tarballs="${tarballs//.tar.bz2/}" tarballs="${tarballs//${2}_/}" PS3=`echo -e "${contrast}Choose number:${restore} "` echo -e "${contrast}Available backups${restore}:" select answer in ${tarballs};do echo -e "Rolling back ${3} to the state ${green}${answer}${restore}" [[ -n "${5}" ]] && rm -rf ${5} tar -xf "${1}/${2}_${answer}.tar.bz2" -C ${4} 2>/dev/null eend $? 2>/dev/null break done } ############################################################################ ################ etc_restore ############################################### etc_restore(){ restore "${BRDIR}" "portage" "${PORT_ETC}" "/etc/" "${PORT_ETC}/*" } ############################################################################ ################ world_restore ############################################# world_restore(){ restore "${BRDIR}/world" "world" "${WORLD}" "${WORLD%world}" } ############################################################################ ################ diff_ask ################################################## diff_ask(){ my_diff="$(diff ${1} ${2} | grep --color=never "[[:digit:]][a-z][[:digit:]]")" if [[ -n "${my_diff}" ]];then while read subj;do old_num="$(tr ',' ' ' <<< "${subj%[a-z]*}")" [[ "$(wc -w <<< "${old_num}")" == "2" ]] && old_num="$(seq ${old_num})" new_num="$(tr ',' ' ' <<< "${subj#*[a-z]}")" [[ "$(wc -w <<< "${new_num}")" == "2" ]] && new_num="$(seq ${new_num})" action="$(grep -o "[a-z]" <<< "${subj}")" if [[ "${action}" == "a" ]];then for num in ${new_num};do [[ "${num}" != "0" ]] && full_diff+="${num}^#+#${green}`sed -n "${num}p" "${2}"`${restore}#"$'\n' done elif [[ "${action}" == "d" ]];then for num in ${old_num};do [[ "${num}" != "0" ]] && full_diff+="${num}^#-#${red}`sed -n "${num}p" "${1}"`${restore}#"$'\n' done elif [[ "${action}" == "c" ]];then for num in ${old_num};do [[ "${num}" != "0" ]] && full_diff+="${num}^#-#${red}`sed -n "${num}p" "${1}"`${restore}#"$'\n' done for num in ${new_num};do [[ "${num}" != "0" ]] && full_diff+="${num}^#+#${green}`sed -n "${num}p" "${2}"`${restore}#"$'\n' done fi done <<< "${my_diff}" echo -e "\n${contrast}Changes for ${green}${1}${restore}:${restore}" echo "###############################################" echo -e "${full_diff%\\n}" | column -s \^ -t echo "###############################################" if [[ -z "${yes}" && -z "${PRETEND}" ]];then echo -ne "${contrast}Apply changes?${restore} [${green}Yes${restore}/${red}No${restore}] "; while read x;do case ${x} in Yes | YES | yes | Y | y | "" ) if [[ "${UID}" == "0" ]];then mv "${2}" "${1}" 2>/dev/null chmod 0644 "${1}" else echo -e "you are ${red}!root${restore} ---> go away!" exit 1 fi unset full_diff return 0 break;; No | NO | no | N | n ) unset full_diff rm "${2}" 2>/dev/null return 0 break;; * ) echo -ne "Sorry, response '${x}' not understood. [${green}Yes${restore}/${red}No${restore}] " continue;; esac done elif [[ -n "${yes}" && -z "${PRETEND}" ]];then mv "${2}" "${1}" 2>/dev/null chmod 0644 "${1}" unset full_diff return 0 elif [[ -z "${yes}" && -n "${PRETEND}" ]];then unset full_diff rm "${2}" 2>/dev/null return 0 break fi fi rm "${2}" 2>/dev/null return 0 } ############################################################################ ################ remove_ask ################################################ remove_ask(){ if [[ -z "${yes}" && -z "${PRETEND}" ]];then echo -ne "${contrast}Remove${restore} ${green}${1}${restore}${contrast}?${restore} [${green}Yes${restore}/${red}No${restore}] " while read x;do case ${x} in Yes | YES | yes | Y | y | "" ) rm -rf ${1} 2>/dev/null break;; No | NO | no | N | n ) break;; * ) echo -ne "Sorry, response '${x}' not understood. [${green}Yes${restore}/${red}No${restore}] " continue;; esac done eend $? 2>/dev/null elif [[ -n "${yes}" && -z "${PRETEND}" ]];then echo -e "${contrast}Removing${restore} ${green}${1}${restore}" rm -rf ${1} 2>/dev/null eend $? 2>/dev/null elif [[ -z "${yes}" && -n "${PRETEND}" ]];then eend 0 2>/dev/null fi } ############################################################################ ################ sort_packages ############################################# sort_uniq_files(){ for package in `find ${PORT_ETC}/ -type f \! -name '*~' \! -name '*.bak' | grep "/package\."`;do tmp_sort="$(mktemp)" echo -e "${underline}Sorting${restore} ${contrast}${package#${PORT_ETC}/}${restore}" all_atoms="$(awk '{print $1}' "${package}" | grep -v "^#"| sort -u)" while read atom;do opts="$(grep "^${atom//\*/\\*} " "${package}" | uniq | cut -d" " -f2-)" echo "${atom} ${opts//$'\n'/ }" >> "${tmp_sort}" done <<< "${all_atoms}" sed -e '/^$/d' -e 's/[ \t]*$//' -i ${tmp_sort} sort -u "${tmp_sort}" -o "${tmp_sort}" 2>/dev/null diff_ask "${package}" "${tmp_sort}" eend $? 2>/dev/null done } ############################################################################ ################ file or dir... ############################################ file_or_dir(){ local founded for i in ${1};do founded+=" $(ls -d1 ${PORT_ETC}/${i} 2>/dev/null)" done if [[ -z "${founded}" ]];then echo -e "${underline}${2}${restore}${contrast}${PORT_ETC}/${1}${restore}: No such file or directory${restore}" eend 1 2>/dev/null return 1 fi for target in ${founded};do if [[ -f "${target}" ]];then file="${target}" if [[ -s ${file} ]];then echo -e "${underline}${2}${restore} ${contrast}${file#${PORT_ETC}/}${restore}" ${3};${4};${5};${6};${7}; else echo -e "${underline}Empty file${restore} ${contrast}${file}${restore}" remove_ask "${file}" eend $? 2>/dev/null fi elif [[ -d "${target}" ]];then for f in `find ${target} -type f \! -name '*~' \! -name '*.bak'`;do file="${f}" if [[ -s ${file} ]];then echo -e "${underline}${2}${restore} ${contrast}${file#${PORT_ETC}/}${restore}" ${3};${4};${5};${6};${7}; else echo -e "${underline}Empty file${restore} ${contrast}${file}${restore}" remove_ask "${file}" eend $? 2>/dev/null continue fi done fi done } ############################################################################ ################ rm_comments ############################################### rm_comments(){ no_newline(){ tmp_file="$(mktemp)" cp "${file}" "${tmp_file}" sed -e "s|^#.*||g" -e '/^$/d' -i ${tmp_file} diff_ask "${file}" "${tmp_file}" eend $? 2>/dev/null } file_or_dir "package.*" "Checking comments:" "no_newline" || return 1 } ############################################################################ ################ rm_all_comments ########################################### rm_all_comments(){ no_newline_inline(){ tmp_file="$(mktemp)" cp "${file}" "${tmp_file}" sed -e "s|#.*||g" -e 's/[ \t]*$//' -e '/^$/d' -i ${tmp_file} diff_ask "${file}" "${tmp_file}" eend $? 2>/dev/null } file_or_dir "package.*" "Checking comments:" "no_newline_inline" || return 1 } ############################################################################ ################ sort_uses ################################################# sort_uses(){ tmp_file="$(mktemp)" striped="$(mktemp)" PACKAGES="$(awk '{print $1}' ${file} | grep -v '^#.*' | uniq)" for atom in ${PACKAGES};do comment="$(grep "${atom}[[:space:]].*#" "${file}" | cut -d\# -f2-)" for option in \ "$(grep "^${atom//\*/\\*}[[:space:]]" ${file} | sed -e "s|${atom//\*/\\*} ||" -e "s|#.*${comment}||" | tr "[:space:]" $'\n' | uniq | tr $'\n' " ")";do atom_opts+="${option}" done uses="$(sort_passed_uses "${atom_opts}")" uses="$(sed -e "s|^- | |g" -e "s| -- ||g" -e "s| - | |g" <<< ${uses})" if [[ -n "${comment}" ]];then echo "${atom} ${uses} #${comment}" >> "${tmp_file}" else echo "${atom} ${uses}" >> "${tmp_file}" fi unset atom atom_opts option options uses comment done cp "${tmp_file}" "${striped}" 2>/dev/null while read atom opt;do [[ -z "${opt}" ]] && sed -e "s|^${atom} ||" -i "${striped}" 2>/dev/null unset atom opt done < "${tmp_file}" sed -e 's/[ \t]*$//' -e '/^$/d' -e 's| | |g' -e "s| - | |g" -i "${striped}" 2>/dev/null sort -u "${striped}" -o "${striped}" 2>/dev/null rm "${tmp_file}" 2>/dev/null diff_ask "${file}" "${striped}" eend $? 2>/dev/null } 2>/dev/null ############################################################################ ################ package.use ############################################### sort_use_file(){ file_or_dir "package.use" "Sorting use flags in" "set -f" "sort_uses" "set +f" || return 1 } ############################################################################ ################ stupid_keyword ############################################ stupid_keywords(){ unset ACCEPT_KEYWORDS local ACCEPT_KEYWORDS="$(eix --print ACCEPT_KEYWORDS)" for KEY in ${ACCEPT_KEYWORDS};do while read satom lkeys;do comment="$(cut -d\# -f2- <<< "${lkeys}")" lkeys="${lkeys%%#*}" lkeys="${lkeys%% }" out_keys="$(tr ' ' $'\n' <<< "${lkeys}")" #### wildcards pcategory="${satom%%/*}" pcategory="$(tr -d "<>=~" <<< "${pcategory}")" parent_keys="$(grep -e "${pcategory}/\*" -e "\*/\*" "${1}" | sed 's|^.* ||' | sort -u)" #### /wildcards if [[ "${satom}" != "${pcategory}/*" && "${satom}" != "*/*" ]];then for key in ${lkeys};do for pkey in ${parent_keys};do if [[ "${key}" == "${KEY}" || ${key} == "${pkey}" ]];then echo -e "Twice defined keyword ${red}${key}${restore}:\t${green}${satom}${restore}" out_keys="$(grep -v "`printf ${key}`" <<< "${out_keys}")" fi done done fi out_keys="$(tr $'\n' ' ' <<< "${out_keys}")" out_keys="${out_keys% }" if [[ "${lkeys}" != "${out_keys}" ]];then if [[ -n "${out_keys% }" ]];then if [[ -n "${comment}" ]];then string="$(grep "^${satom} ${lkeys} .*#${comment}$" "${1}")" fixed_string="${satom} ${out_keys% } #${comment}" else string="$(grep "^${satom} ${lkeys}$" "${1}")" fixed_string="${satom} ${out_keys}" fi else string="$(grep "^${satom} ${lkeys}.*$" "${1}")" fixed_string="" fi sed -e "s|^${string//\*/\\*}$|${fixed_string}|" -e '/^$/d' -i "${2}" || echo fail 525 fi done < "${1}" done } ############################################################################ ################ sort_keys ################################################# sort_keys(){ tmp_file="$(mktemp)" striped="$(mktemp)" PACKAGES="$(awk '{print $1}' ${file} | grep -v '^#.*' | uniq)" for atom in ${PACKAGES};do comment="$(grep "${atom}[[:space:]].*#" "${file}" | cut -d\# -f2-)" for option in \ "$(grep "^${atom//\*/\\*}[[:space:]]" ${file} | sed -e "s|${atom//\*/\\*} ||" -e "s|#.*${comment}||" | tr "[:space:]" $'\n' | uniq | tr $'\n' " ")";do atom_opts+="${option}" done keys="$(sort_passed_uses "${atom_opts}")" keys="$(sed -e "s|^- | |g" -e "s| -- ||g" -e "s| - | |g" <<< ${keys})" keys="${keys:-"~${ARCH}"}" if [[ -n "${comment}" ]];then echo "${atom} ${keys} #${comment}" >> "${tmp_file}" else echo "${atom} ${keys}" >> "${tmp_file}" fi unset atom atom_opts option options keys comment done cp "${tmp_file}" "${striped}" 2>/dev/null while read atom opt;do [[ -z "${opt}" ]] && sed -e "s|^${atom}[ \t]$|${atom} ~${ARCH}|;s|^${atom}$|${atom} ~${ARCH}|" -i "${striped}" 2>/dev/null unset atom opt done < "${tmp_file}" sed -e 's/[ \t]*$//' -e '/^$/d' -e 's| | |g' -e "s| - | |g" -i "${striped}" 2>/dev/null sort -u "${striped}" -o "${striped}" 2>/dev/null cp "${striped}" "${tmp_file}" stupid_keywords "${tmp_file}" "${striped}" rm "${tmp_file}" 2>/dev/null diff_ask "${file}" "${striped}" eend $? 2>/dev/null } #2>/dev/null ############################################################################ ################ one_keyword ############################################### sort_keywords(){ keys(){ tmp_file="$(mktemp)" striped="$(mktemp)" atoms="$(awk '{print $1}' "${file}" | sort -u)" while read atom;do comment="$(grep "${atom}[[:space:]].*#" "${file}" | cut -d\# -f2-)" keyword="$(grep "${atom}[[:space:]]" ${file} | sed -e "s|${atom} ||" -e "s|#.*${comment}||" |\ tr "[:space:]" $'\n' | sed '/^$/d' | tail -n1)" keyword="${keyword:-"~${ARCH}"}" if [[ -n "${comment}" ]];then echo "${atom} ${keyword} #${comment}" >> "${tmp_file}" else echo "${atom} ${keyword}" >> "${tmp_file}" fi done <<< "${atoms}" sort -u "${tmp_file}" -o "${tmp_file}" 2>/dev/null cp "${tmp_file}" "${striped}" stupid_keywords "${striped}" "${tmp_file}" rm "${striped}" diff_ask "${file}" "${tmp_file}" eend $? 2>/dev/null } file_or_dir "package.keywords package.accept_keywords" "Sorting keywords in" "keys" || return 1 } ############################################################################ ################ uniq_keyword ############################################## uniq_keywords(){ file_or_dir "package.keywords package.accept_keywords" "Sorting keywords in" "set -f" "sort_keys" "set +f" || return 1 } ############################################################################ ################ not_installed ############################################# installed(){ installed="$(qlist -ICSec "${category}/${pn}" | awk '{print $2}')" if [[ -n "${installed}" ]];then installed_vers="$(awk -F \: '{print $1}' <<< "${installed}")" installed_min_ver="$(head -n1 <<< "${installed_vers}")" installed_max_ver="$(tail -n1 <<< "`grep -v 9999 <<< "${installed_vers}"`")" installed_live_ver="$(tail -n1 <<< "`grep 9999 <<< "${installed_vers}"`")" installed_slots="$(awk -F \: '{print $2}' <<< "${installed}")" #::repo check full_vers="$(qlist -ICev "${category}/${pn}" | sed "s|${category}/${pn}-||g")" (( "$(wc -l <<< "${full_vers}")" '>' "1" )) if [[ -n "${defined_repo}" ]];then for ver in ${full_vers};do all_vers+=" ${PKGDB}/${category}/${pn}-${ver}/repository" done grep -qe "^${defined_repo}$" ${all_vers} || unset installed unset all_vers fi [[ "${installed_slots}" == "0" ]] && unset installed_slots fi } not_if(){ atoms="$(awk '{print $1}' <<< "`grep -v "^#" < ${package}`")" [[ -n "${IGNORE}" ]] && atoms="$(grep -v "${IGNORE}" <<< "${atoms}")" echo -e "${underline}Checking${restore} ${contrast}$package${restore}" if [[ -n "${atoms}" ]];then while read atom;do #::repo check if grep -q "::" <<< "${atom}";then defined_repo="${atom##*::}" else unset defined_repo fi [[ -n "${defined_repo}" ]] && atom="${atom%%::${defined_repo}}" while read category pn ver rev slot;do sw="$(grep -o "[<>=~]" <<< "${category}" | tr -d $'\n')" category="${category##${sw}}" [[ "${category}" == "(null)" || "${pn}" == "(null)" ]] && continue if [[ -n "${rev}" ]] && [[ -z "${slot}" ]] && `grep -q \: <<< "${rev}"`;then slot="${rev}" unset rev fi slot="${slot#:}" pn="${pn%:}" installed; if [[ -z "${installed}" ]];then if [[ -n "${defined_repo}" ]];then echo -e "${red}Not installed${restore} ${green}${category}/${pn}::${underline}${defined_repo}${restore}" else echo -e "${red}Not installed${restore} ${green}${category}/${pn}${restore}" fi sed -e "s|.*\<${category}/${pn}\>.*||" -e '/^$/d' -i "${tmp_package}" 2>/dev/null eend $? 2>/dev/null fi done <<< `qatom "${atom}"` done <<< "${atoms}" fi } force_not_installed(){ for package in `find ${PORT_ETC}/package* -type f \! -name '*~' \! -name '*.bak'`;do if [[ -s "${package}" && -n "$(grep -v "^#" < "${package}")" ]];then tmp_package="$(mktemp)" cp "${package}" "${tmp_package}" if ! `grep -q "\.mask" <<< "${package}"`;then not_if; eend $? 2>/dev/null fi diff_ask "${package}" "${tmp_package}" else pack="${package%/*}" echo -e "${underline}Empty file${restore} ${contrast}${pack}${restore}" remove_ask "${package}" eend $? 2>/dev/null fi done for x in `find ${PORT_ETC}/package* -type f`;do if [[ ! -s "${x}" ]];then echo -e "${underline}Empty file${restore} ${contrast}${x}${restore}" remove_ask "${x}" eend $? 2>/dev/null fi done } ############################################################################ ################ package.env conf ########################################## package_env_conf(){ all_confs="$(find ${PORT_ETC}/env/ -maxdepth 1 -type f)" all_confs="${all_confs//${PORT_ETC////\/}\/env\//}" check_env_conf(){ atoms="$(sed 's/^[ \t]*//;s/[ \t]*$//;/^#/d;/^$/d;' < ${file} | awk '{print $1}')" while read line;do line="$(sed 's/^[ \t]*//;s/[ \t]*$//' <<< "${line%%#*}")" for atom in ${atoms};do USED_ENV+=" ${line#${atom} }" done done < "${file}" USED_ENV="$(tr ' ' $'\n' <<< "${USED_ENV}")" for conf in ${all_confs};do if ! grep -q "^${conf}$" <<< "${USED_ENV}";then echo -e "Unused conf: ${red}${conf}${restore}" remove_ask "${PORT_ETC}/env/${conf}" eend $? 2>/dev/null fi done } file_or_dir "package.env" "Checking unused configs in" "check_env_conf" || return 1 } ############################################################################ ################ package.env ############################################### package_env(){ package_env_def(){ tmp_file="$(mktemp)" cp "${file}" "${tmp_file}" while read line;do xline="$(sed 's/^[ \t]*//;s/[ \t]*$//' <<< "${line%%#*}")" atom="${xline%% *}" all_confs="${xline#${atom} }" for conf in ${all_confs};do if [[ -f "${PORT_ETC}/env/${conf}" ]];then IGNORE+=$'\n'"${conf}" else echo -e "Defined conf not exists: ${red}${conf}${restore}" new_line=$(grep -v "^${conf}$" <<< "$(tr ' ' $'\n' <<< "${line}")" | tr $'\n' ' ') new_line="$(sed 's/^[ \t]*//;s/[ \t]*$//' <<< "${new_line}")" sed "s|${line}|${new_line}|" -i "${tmp_file}" line="${new_line}" fi done done < "${file}" diff_ask "${file}" "${tmp_file}" eend $? 2>/dev/null } file_or_dir "package.env" "Checking defined configs in" "package_env_def" || return 1 } ############################################################################ ################ env not_installed ######################################### env_not_installed(){ echo -e "${underline}Looking not installed in${restore} ${contrast}${PORT_ETC}/env${restore}" for x in "env" "env.d";do files="$(find ${PORT_ETC}/${x}/ -mindepth 2 -maxdepth 2 -type f \! -name '*~' \! -name '*.bak' 2>/dev/null| cut -d\/ -f5-)" [[ -n "${IGNORE}" ]] && files="$(grep -v "${IGNORE}" <<< "${files}")" dirs="$(find ${PORT_ETC}/${x}/ -type d 2>/dev/null)" [[ -n "${IGNORE}" ]] && dirs="$(grep -v "${IGNORE}" <<< "${dirs}")" [[ -n "${files}" || -n "${dirs}" ]] || break while read file;do atom="$(qatom "${file}")" atom="$(sed -e '/^$/d' <<< "${atom}")" while read category pn ver rev slot;do [[ "${category}" == "(null)" || "${pn}" == "(null)" ]] && continue [[ "${ver}" == "(null)" ]] && ver="${ver//(null)/}" if [[ -n "${rev}" ]] && ! `grep -q \: <<< "${rev}"`;then full_ver="${ver}-${rev}" else full_ver="${ver}" fi [[ -n "${rev}" && -z "${slot}" ]] && grep -q \: <<< "${rev}" && slot="${rev}" slot="${slot#:}" if [[ -z "${ver}" && -z "${slot}" ]];then if ! ls -d1 ${PKGDB}/${category}/${pn}-[0-9]* &>/dev/null;then echo -e "${red}Not installed${restore} ${green}${category}/${pn}${restore}" RM+="${PORT_ETC}/${x}/${file}%" eend $? 2>/dev/null fi fi if [[ -n "${ver}" && -z "${slot}" ]] ;then if ! ls -d1 ${PKGDB}/${category}/${pn}-${full_ver} &>/dev/null;then echo -e "${red}Not installed${restore} ${green}${category}/${pn}-${full_ver}${restore}" RM+="${PORT_ETC}/${x}/${file}%" eend $? 2>/dev/null fi fi if [[ -z "${ver}" && -n "${slot}" ]] ;then if [[ -z "$(cat ${PKGDB}/${category}/${pn}-[0-9]*/SLOT 2>/dev/null | grep ${slot})" ]];then echo -e "${red}Not installed${restore} ${green}${category}/${pn}:${slot}${restore}" RM+="${PORT_ETC}/${x}/${file}%" eend $? 2>/dev/null fi fi done <<< "${atom}" done <<< "${files}" IFS="%" for target in ${RM%\%};do remove_ask "${target}" done IFS=$'\n' for target in ${dirs};do [[ -z "`ls ${target}`" ]] && remove_ask "${target}" done unset IFS done eend $? 2>/dev/null } ############################################################################ ################ incorrect uses ############################################ invalid_uses(){ set -f FULL="${PROFILE} ${MAKE_USES}" for opt in ${FULL};do GLOBAL+=" $(echo ${FULL} | tr "[:space:]" $'\n' | grep -e "^${opt#-}$" -e "^\-${opt#-}$" | tail -n1)" done GLOBAL="$(echo ${GLOBAL} | tr "[:space:]" $'\n' | sort -u)" ############################################################################ check_uses(){ echo -e "${underline}Checking use flags in${restore} ${contrast}${file#${PORT_ETC}/}${restore}:" ##### eix env ##### export OVERLAYS_LIST="no" export FORMAT='' export USEONLY=' ' #### just count tput sc tput civis while read category pn ver slot;do tput el tput el1 echo -ne "["; printf "% ${chars}d" $((count--));echo -ne " ]" "atoms left" 2>/dev/null tput rc prepare(){ while read string;do struse="${string#${category}/${pn}}" struse="$(tr "[:space:]" $'\n' <<< ${struse})" usefxd="$(sed -e "s|^${trash#-}$||" -e "s|^\-${trash#-}$||" -e '/^$/d' <<< "${struse}")" usefxd="$(tr $'\n' " " <<< "${usefxd}")" usefxd="$(sed -e 's| - | |g' -e 's/[ -]*$//' <<< ${usefxd})" strfxd="${category}/${pn} ${usefxd}" sed -e "s|^${category}/${pn}[[:space:]].*${trash#-}.*|$strfxd|" -i ${tmp_file} 2>/dev/null eend $? 2>/dev/null done <<< "${strings}" } prepare_similar(){ while read string;do struse="${string#${category}/${pn}}" struse="$(tr "[:space:]" $'\n' <<< ${struse})" usefxd="$(sed -e "s|^${use#-}$|${similar_use}|" -e "s|^\-${use#-}$|\-${similar_use}|" -e '/^$/d' <<< "${struse}")" usefxd="$(tr $'\n' " " <<< "${usefxd}")" usefxd="$(sed -e 's| - | |g' -e 's/[ -]*$//' <<< ${usefxd})" strfxd="${category}/${pn} ${usefxd}" sed -e "s|^${category}/${pn}[[:space:]].*${use#-}.*|$strfxd|" -i ${tmp_file} 2>/dev/null eend $? 2>/dev/null done <<< "${strings}" } ALL_USE=" $(eix -e "${category}/${pn}")" || continue ALL_USE="$(sed -e 's| +| |g;s| -| |g;s|(+)||g;s|(-)||g' <<< "${ALL_USE}" | tr "[:space:]" $'\n' | sort -u | sed -e '/^$/d')" LOCAL="$(grep "\<${category}/${pn}\> " "${file}" | cut -d" " -f2- | sed -e "s|#.*||g" | tr "[:space:]" $'\n' | sort -u)" USES="$(sed -e 's|^-||g' <<< "${LOCAL}")" for use in ${USES};do if ! grep -q "^${use}$" <<< "${ALL_USE}" && [[ "${use}" != "*" ]];then for agrep_opt in 1 2 3 B;do for use_opt in "${use}" "^${use}" "${use}$" "^${use}$";do similar_use="$(agrep -${agrep_opt} "${use_opt}" 2>/dev/null <<< "${ALL_USE}")" [[ -n "${similar_use}" ]] && (( $(wc -l <<< "${similar_use}") '==' 1 )) && break done [[ -n "${similar_use}" ]] && (( $(wc -l <<< "${similar_use}") '==' 1 )) && break [[ -z "${similar_use}" ]] || (( $(wc -l <<< "${similar_use}") '>' 1 )) && similar_use="" done if [[ -z "${similar_use}" ]];then grep -q " ${use}\>" <<< "${incorrect_use}" || incorrect_use="${incorrect_use} ${use}" else strings="$(grep "^${category}/${pn}[[:space:]].*\<${use}\>" ${tmp_file})" echo -e "${category}/${pn}: ${red}${use} ---> ${green}${similar_use}${restore}" prepare_similar; incorrect_use="${incorrect_use// ${similar_use}/}" fi else incorrect_use="${incorrect_use// ${use}/}" fi if grep -q "^${use}$" <<< "${GLOBAL}" && grep -q "^${use}$" <<< "${LOCAL}";then global_use="${global_use} ${use}" elif grep -q "^\-${use}$" <<< "${GLOBAL}" && grep -q "^\-${use}$" <<< "${LOCAL}";then global_use="${global_use} -${use}" incorrect_use="${incorrect_use// ${use}/}" fi done incorrect_use="$(echo ${incorrect_use} | tr "[:space:]" $'\n' | sed -e 's| | |g' -e '/^ $/d' -e '/^$/d' | sort -u)" global_use="$(echo ${global_use} | tr "[:space:]" $'\n' | sed -e 's| | |g' -e '/^ $/d' -e '/^$/d' | sort -u)" if [[ -n "${incorrect_use}" ]];then while read trash;do echo -e "Invalid use: ${green}${category}/${pn}${restore}: ${red}${trash}${restore}" strings="$(grep "^${category}/${pn}[[:space:]].*\<${trash}\>" ${tmp_file})" prepare; done <<< "${incorrect_use}" fi if [[ -n "${global_use}" ]];then while read trash;do echo -e "Global use: ${green}${category}/${pn}${restore}: ${red}${trash}${restore}" strings="$(grep "^${category}/${pn}[[:space:]].*\<${trash#-}\>" ${tmp_file})" prepare; done <<< "${global_use}" fi unset ALL_USE LOCAL USES incorrect_use global_use use done <<< "`[[ -n "${atoms}" ]] && echo -e "${atoms}"`" while read atom opt;do if [[ -n "${atom}" ]] && [[ -z "${opt}" ]];then echo -e "Removing atom: ${green}${atom}${restore}" sed -e "s|^${atom} *$||" -e '/^$/d' -i "${tmp_file}" 2>/dev/null eend $? 2>/dev/null fi done <<< "$([[ -n "${IGNORE}" ]] && grep -v "${IGNORE}" < "${file}" || cat "${file}")" while read atom opt;do if [[ -n "${atom}" ]] && [[ -z "${opt}" ]];then echo -e "Removing atom: ${green}${atom}${restore}" sed -e "s|^${atom} *$||" -e '/^$/d' -i "${tmp_file}" 2>/dev/null eend $? 2>/dev/null fi done <<< "$([[ -n "${IGNORE}" ]] && grep -v "${IGNORE}" < "${tmp_file}" || cat "${tmp_file}")" eend $? 2>/dev/null unset FORMAT USEONLY } if [[ -f "${PORT_ETC}/package.use" ]];then file="${PORT_ETC}/package.use" tmp_file="$(mktemp)" cp "${file}" "${tmp_file}" if [[ -n "${IGNORE}" ]];then content="$(awk '{print $1}' ${file} | tr -d "<>=~" | sed -e 's|^#.*||g' | grep -v "${IGNORE}")" [[ -n "${content}" ]] && atoms="$(qatom ${content})" else content="$(awk '{print $1}' ${file} | tr -d "<>=~" | sed -e 's|^#.*||g')" [[ -n "${content}" ]] && atoms="$(qatom ${content})" fi count="$(wc -l <<< "${atoms}")" ((count--)) chars="$(wc -m <<< "${count}")" check_uses; tput el; tput cnorm; diff_ask "${file}" "${tmp_file}" [[ ! -s "${file}" ]] && remove_ask "${file}" elif [[ -d "${PORT_ETC}/package.use" ]];then for f in `find ${PORT_ETC}/package.use/ -type f \! -name '*~' \! -name '*.bak'`;do if [[ -s "${f}" ]];then file="${f}" tmp_file="$(mktemp)" cp "${file}" "${tmp_file}" if [[ -n "${IGNORE}" ]];then content="$(awk '{print $1}' ${file} | tr -d "<>=~" | sed -e 's|^#.*||g' | grep -v "${IGNORE}")" [[ -n "${content}" ]] && atoms="$(qatom ${content})" else content="$(awk '{print $1}' ${file} | tr -d "<>=~" | sed -e 's|^#.*||g')" [[ -n "${content}" ]] && atoms="$(qatom ${content})" fi count="$(wc -l <<< "${atoms}")" ((count--)) chars="$(wc -m <<< "${count}")" check_uses; tput cnorm diff_ask "${file}" "${tmp_file}" [[ ! -s "${file}" ]] && remove_ask "${file}" else echo -e "${underline}Removing empty file${restore} ${contrast}${f}${restore}" rm ${f} 2>/dev/null eend $? 2>/dev/null continue fi done fi tput cnorm set +f } ############################################################################ ################ incorrect uses in make.conf ############################### make_conf_use() { defined_flags="$(grep "${1}=\".*\"" ${makefile})" defined_flags="${defined_flags:-"$(sed -ne "/${1}=\"/,/\"/p" ${makefile})"}" echo "${defined_flags}" } hell_parser(){ sed -e 's|[[:space:]]| |g' -e :a -e '/\\$/N; s/\\\n//; ta' | \ cut -d\" -f2 | tr "[[:space:]]" $'\n' | sed '/^$/d;s|^-||g' | sort -u } invalid_uses_make(){ set -f echo -e "${underline}Checking use flags in${restore} ${contrast}${makefile}${restore}" tmp_file="$(mktemp)" cp "${makefile}" "${tmp_file}" vars_in_USE="$(make_conf_use USE | hell_parser | grep '\$' | tr -d '${}')" real_uses="$(eix --print-all-useflags | sed 's|^[-+]||g;s|^(+)||g' | sort -u)" for var in ${vars_in_USE} USE;do sub_uses="$(make_conf_use ${var} | hell_parser | grep -v '\$')" for use in ${sub_uses};do if ! grep -q "^${use}$" <<< "${real_uses}" && [[ "${use}" != "*" ]];then echo -ne "Invalid use ${contrast} ${var}: ${red}${use}${restore}" | column -t invalid_uses+=" ${use}" fi done done if [[ -n "${invalid_uses}" ]];then for iuse in ${invalid_uses};do line="$(grep "\<${iuse}\>" ${tmp_file})" fixed_line="$(sed "s|[- \t]${iuse}||" <<< "${line}")" sed -e "s|${line%\\}|${fixed_line%\\}|" -i "${tmp_file}" done fi diff_ask "${makefile}" "${tmp_file}" set +f } ############################################################################ ################ not_found ################################################# not_found(){ echo -e "${underline}Checking invalid entries${restore}..." TRASH="$(LANG=en eix -Ttc 2>/dev/null)" for package in $(ls -d1 ${PORT_ETC}/package* | grep -v -e "~" -e "\.bak" -e "\.old");do incorrect="$(echo -e "${TRASH}" | tr $'\n' "%" | sed -e "s|.*${package}:||" -e 's|--.*||' -e 's|No.*||'|\ tr "%" $'\n' | sed -e '/^$/d' | grep -v "${IGNORE}")" if [[ -n "${incorrect}" && -f "${package}" ]];then tmp_package="$(mktemp)" cp "${package}" "${tmp_package}" echo -e "${underline}Removing incorrect from${restore} ${contrast}${package}${restore}:" while read line;do echo -e "${red}Incorrect:${restore} ${line}" line="${line//'*'/\*}" [[ -n "${line}" ]] && sed -e "s|$line||" -e 's/[ \t]*$//' -e '/^$/d' -i ${tmp_package} 2>/dev/null eend $? 2>/dev/null done <<< "${incorrect}" diff_ask "${package}" "${tmp_package}" elif [[ -n "${incorrect}" && -d "${package}" ]];then echo -e "${underline}Removing incorrect from${restore} ${contrast}${package}${restore}:" IFS=$'\n' for line in ${incorrect};do for file in `grep -RH "${line//'*'/\*}" "${package}"/ | awk -F \: '{print $1}'`;do tmp_file="$(mktemp)" cp "${file}" "${tmp_file}" echo -e "${red}Incorrect:${restore} ${line}" [[ -n "${line}" ]] && sed -e "s|${line//'*'/\*}||" -e 's/[ \t]*$//' -e '/^$/d' -i ${tmp_file} diff_ask "${file}" "${tmp_file}" eend $? 2>/dev/null done done unset IFS fi done INVALID="$(LANG=en eix -Ttc 2>&1 | grep "Invalid.*\'.*\'" | grep -v '\.\.\.' | sort -u)" IFS=$'\n' for string in ${INVALID};do [[ -z "${string}" ]] && break file="$(awk -F ':' '{print $1}' <<< "${string}")" file="${file##* }" file="${file//[[:space:]]/}" line="$( awk -F ':' '{print $2}' <<< "${string}")" line="${line//\'/}" echo -e "${red}Incorrect:${restore} ${line}" line="${line//'*'/\*}" line="${line#[[:space:]]}" INVALID_FOUNDED+="${line}"$'\n' if [[ -n "${line}" && -f "${file}" ]];then tmp_file="$(mktemp)" cp "${file}" "${tmp_file}" [[ -n "${line}" ]] && sed -e "s|`echo $line`$||" -e 's|[ \t]| |' -e '/^[ \t]$/d' -e '/^$/d' -i ${tmp_file} diff_ask "${file}" "${tmp_file}" elif [[ -n "${line}" && -d "${file}" ]];then for package in `grep -RH "${line//'*'/\*}" "${file}"/ | awk -F \: '{print $1}'`;do tmp_package="$(mktemp)" cp "${package}" "${tmp_package}" echo -e "${red}Incorrect:${restore} ${line}" [[ -n "${line}" ]] && sed -e "s|${line//'*'/\*}||" -e 's/[ \t]*$//' -e '/^$/d' -i ${tmp_package} diff_ask "${package}" "${tmp_package}" eend $? 2>/dev/null done fi eend $? 2>/dev/null done unset IFS ##### don't quote it! ##### if [[ -n "${INVALID_FOUNDED}" ]];then invalid=$(emerge --version 2>&1 | sed -e '/--- Invalid atom in /!d' -e 's|--- Invalid atom in ||g;s|:||' |\ grep -v "${INVALID_FOUNDED}") else invalid=$(emerge --version 2>&1 | sed -e '/--- Invalid atom in /!d' -e 's|--- Invalid atom in ||g;s|:||') fi broken_files="$(awk '{print $1}' <<< "${invalid}" | sort -u)" invalid_lines(){ tmp_file="$(mktemp)" cp "${file}" "${tmp_file}" set -f tlines="$(grep "^${file} " <<< "${invalid}" | sed "s|${file} ||g")" while read line;do sed -e "s|^`printf ${line}`.*$||;s|^${line//\*/\\*}.*$||" -e 's|[ \t]| |;/^[ \t]$/d;/^$/d' -i "${tmp_file}" done <<< "${tlines}" diff_ask "${file}" "${tmp_file}" set +f } if [[ -n "${invalid}" ]];then for bad_file in ${broken_files};do file_or_dir "${bad_file#${PORT_ETC}/}" "Founded invalid lines in" "invalid_lines" done fi unset invalid broken_files } ############################################################################ ################ profile's uses in make.conf ############################### use_makeconf(){ echo -e "${underline}Checking use flags in${restore} ${contrast}${makefile##/etc*/}${restore}" USE="$(echo -e "${MAKE_USES}" | tr "[:space:]" $'\n' | sort -u | sed -e '/^$/d')" tmp_file="$(mktemp)" cp "${makefile}" "${tmp_file}" while read use;do flag="${use#-}" if [[ -n ${flag} ]];then if grep -q "^${flag}$" <<< "${USE}" && grep -q "^${flag}$" <<< "${PROFILE}";then echo -e "Twice defined: ${red}${use}${restore}" sed -e "s|[^[:punct:]]\<${flag}\>||g" -i ${tmp_file} elif grep -q "^\-${flag}$" <<< "${USE}" && grep -q "^\-${flag}$" <<< "${PROFILE}";then echo -e "Twice defined: ${red}-${use}${restore}" sed -e "s|[^[:punct:]]\-\<${flag}\>||g" -i ${tmp_file} fi fi done <<< "${PROFILE}" diff_ask "${makefile}" "${tmp_file}" eend $? 2>/dev/null } ############################################################################ ################ empty files ############################################### empty_files(){ echo -e "${underline}Looking empty files${restore}" for target in `find ${PORT_ETC} -type f`;do [[ ! -s "${target}" || -z "$(grep -v "^#" < "${target}")" ]] && remove_ask "${target}" done eend 0 2>/dev/null } ############################################################################ ################ backup files ############################################## backup_files(){ echo -e "${underline}Looking backup files${restore}" for target in `find ${PORT_ETC} -type f \( -name "*~" -o -name "*.bak" -o -name "*.old" \)`;do remove_ask "${target}" done eend 0 2>/dev/null } ############################################################################ ################ package.* files 2 dirs #################################### f_to_d(){ while read package;do if [[ -f "${package}" ]];then echo -e "${underline}Processing${restore}: ${contrast}${package##*/}${restore}" tmp_file="$(mktemp)" mv ${package} ${tmp_file} 2>/dev/null sed -e 's|^#.*||g' -i "${tmp_file}" dir="${PORT_ETC}/${package##*/}" mkdir "${dir}" while read line;do set -f atom="$(awk '{print $1}' <<< "${line}")" category="$(awk '{print $1}' <<< `qatom ${atom}`)" if [[ "${category}" != "(null)" ]];then category="$(tr -d "<>=~" <<< "${category}" )" [[ "${category}" == "*" ]] && category="all_categories" echo "${line}" >> "${dir}/${category}" fi done < "${tmp_file}" set +f eend $? 2>/dev/null rm "${tmp_file}" 2>/dev/null elif [[ -d "${package}" ]];then echo -e "${underline}Skipping ${red}directory${restore}: ${contrast}${package##*/}${restore}" eend $? 2>/dev/null fi done <<< "`ls -d1 ${PORT_ETC}/package* | grep -v "~"`" } ############################################################################ ################ package.* dirs 2 files #################################### d_to_f(){ while read package;do if [[ -d "${package}" ]];then echo -e "${underline}Processing${restore}: ${contrast}${package##*/}${restore}" tmp_file="$(mktemp)" file="${PORT_ETC}/${package##*/}" touch "${file}" for subfile in `find "${package}" -type f \! -name '*~' \! -name '*.bak' | sort`;do while read line;do echo "${line}" >> "${tmp_file}" done < "${subfile}" done rm -rf "${package}" 2>/dev/null mv "${tmp_file}" "${package}" 2>/dev/null chmod 0644 "${package}" eend $? 2>/dev/null rm "${tmp_file}" 2>/dev/null elif [[ -f "${package}" ]];then echo -e "${underline}Skipping ${red}file${restore}: ${contrast}${package##*/}${restore}" eend $? 2>/dev/null fi done <<< "`ls -d1 ${PORT_ETC}/package* | grep -v "~"`" } ############################################################################ ################ version diff ############################################## ver_diff(){ check="$(versionsort ${1} ${2} 2>/dev/null | tail -n1)" [[ "${check}" == "${1}" && "${check}" != "${2}" ]] && echo 1 # ${1} > ${2} [[ "${check}" == "${2}" && "${check}" != "${1}" ]] && echo 2 # ${2} > ${1} [[ "${check}" == "${1}" && "${check}" == "${2}" ]] && echo 0 # ${1} = ${2} } ############################################################################ ################ version between ########################################### ver_btwn(){ for between in ${3};do if [[ "$(ver_diff "${1}" "${between}")" == "1" && "$(ver_diff "${2}" "${between}")" == "2" ]];then echo "1" # we have one_or_more version between ${1} and ${2} break fi done } ############################################################################ package_envs(){ for atom in ${1};do while read category pn ver rev slot;do sw="$(grep -o "[<>=~]" <<< "${category}" | tr -d $'\n')" category="${category##${sw}}" [[ "${category}" == "(null)" || "${pn}" == "(null)" ]] && continue if [[ -n "${rev}" && -z "${slot}" ]] && grep -q \: <<< "${rev}";then slot="${rev}" unset rev fi slot="${slot#:}" pn="${pn%:}" echo "${sw} ${category} ${pn} ${ver} ${rev:-(null)} ${slot:-(null)} ${file}" done <<< `qatom "${atom}"` done } ############################################################################ ################ mask/unmask trash ######################################### all_mask_trash(){ pre_mask_trash(){ masked="$(awk '{print $1}' ${file} | grep -v '^#.*')" MASKED+="$(package_envs "${masked}")"$'\n' } file_or_dir "package.mask" "Preparing atoms in" "pre_mask_trash" || return 1 pre_unmask_trash(){ unmasked="$(awk '{print $1}' ${file} | grep -v '^#.*')" UNMASKED+="$(package_envs "${unmasked}")"$'\n' } file_or_dir "package.unmask" "Preparing atoms in" "pre_unmask_trash" || return 1 } mask_trash(){ slot_output(){ if [[ "${mslot}" != "(null)" ]];then echo -e "${red}Incorrect${restore}: ${mcategory}/${mpn}:${mslot}" else echo -e "${red}Incorrect${restore}: ${mcategory}/${mpn}" fi TRASH+="${mfile} ${mcategory}/${mpn}"$'\n' unset msw mcategory mpn mver mrev mslot mfile usw ucategory upn uver urev uslot ufile continue } non_slot_output(){ echo -e "${red}Incorrect${restore}: ${msw}${mcategory}/${mpn}-${mver}" TRASH+="${mfile} ${msw}${mcategory}/${mpn}-${mver}"$'\n' unset msw mcategory mpn mver mrev mslot mfile usw ucategory upn uver urev uslot ufile continue } all_mask_trash || return 1 ###### m->masked; u->unmasked while read msw mcategory mpn mver mrev mslot mfile;do while read usw ucategory upn uver urev uslot ufile;do [[ "${mrev}" == "(null)" ]] && unset mrev || mver="${mver}-${mrev}" [[ "${urev}" == "(null)" ]] && unset urev || uver="${uver}-${urev}" [[ "${mver}" == "(null)" ]] && unset mver [[ "${uver}" == "(null)" ]] && unset uver if [[ -n "${mver}" || -n "${uver}" ]];then export OVERLAYS_LIST="no" export VERSIONONLY=' ' export FORMAT='' versions="$(eix -e "${mcategory}/${mpn}")" oldest="$(awk '{print $1}' <<< "${versions}")" fi if [[ -n "${mver}" && -n "${uver}" ]];then versions_diff="$(ver_diff "${mver}" "${uver}")" versions_btwn="$(ver_btwn "${uver}" "${mver}" "${versions}")" fi if [[ "${msw}" != "(null)" ]];then if [[ "${usw}" == "(null)" && "${uslot}" == "(null)" ]];then non_slot_output elif [[ "${msw}" == ">" || "${msw}" == ">=" ]];then if [[ "${usw}" == ">" || "${usw}" == ">=" ]];then if [[ "${versions_diff}" != "1" && -z "${versions_btwn}" ]];then non_slot_output fi fi elif [[ "${msw}" == "<" || "${msw}" == "<=" ]];then if [[ "${usw}" == "<" || "${usw}" == "<=" ]];then if [[ "${versions_diff}" != "1" ]];then non_slot_output fi fi fi else if [[ "${mslot}" == "${uslot}" ]];then if [[ "${usw}" == ">=" || "${usw}" == ">" ]];then if [[ "$(ver_diff "${uver}" "${oldest}")" != "1" ]];then slot_output fi elif [[ "${usw}" == "<" && "$(ver_diff "${uver}" "${oldest}")" == "1" ]];then slot_output elif [[ "${usw}" == "<=" && "$(ver_diff "${uver}" "${oldest}")" != "1" ]];then slot_output elif [[ "${usw}" == "(null)" ]];then slot_output fi fi fi done <<< "$(grep " ${mcategory} ${mpn} " <<< "${UNMASKED}")" done <<< "${MASKED}" files="$(awk '{print $1}' <<< "${TRASH}" | sort -u | sed '/^$/d')" for target in ${files};do if [[ -f "${target}" ]];then tmp_file="$(mktemp)" cp "${target}" "${tmp_file}" incorrect="$(grep ${target} <<< "${TRASH}" | sed -e "s|${target} ||g")" for trash_atom in ${incorrect};do sed -e "s|^${trash_atom}.*||" -e '/^$/d' -e 's/[ \t]*$//' -i "${tmp_file}" done diff_ask "${target}" "${tmp_file}" fi done unset TRASH OVERLAYS_LIST VERSIONONLY FORMAT MASKED UNMASKED versions oldest versions_diff versions_btwn } ############################################################################ ################ looking trash ############################################# remove_trash(){ tmp_file="$(mktemp)" cp "${file}" "${tmp_file}" for atom in `eix -Tc#`;do lines="$(grep "${atom}" "${file}")" while read line;do entry="$(qatom "$(tr -d '<>=~#' <<< "${line}")" | awk '{print $1,$2}' | tr ' ' '/')" if [[ "${atom}" == "${entry}" ]];then if ! eix -qe --installed-masked "${entry}";then if `eix -Iqe ${atom}`;then echo -e "stupid entry: ${green}${line}${restore}" else echo -e "stupid entry (${red}!${restore}installed): ${green}${line}${restore}" fi sed -e "s|${line}||" -e '/^$/d' -i "${tmp_file}" break fi fi done <<< "${lines}" done diff_ask "${file}" "${tmp_file}" eend $? 2>/dev/null } ############################################################################ ################ stupid unmask ############################################# stupid_unmask(){ export REDUNDANT_IF_IN_UNMASK="all" export REDUNDANT_IF_IN_MASK="no" export TEST_FOR_NONEXISTENT="true" export REDUNDANT_IF_UNMASK_NO_CHANGE="all" file_or_dir "package.unmask" "Checking stupid unmasks:" "remove_trash" || return 1 unset REDUNDANT_IF_IN_UNMASK REDUNDANT_IF_IN_MASK TEST_FOR_NONEXISTENT REDUNDANT_IF_UNMASK_NO_CHANGE } ############################################################################ ################ stupid mask/unmask uses ################################### sort_uniq_mask_use(){ if [[ -d "${PORT_ETC}/profile" || -h "${PORT_ETC}/profile" ]];then for package in `find ${PORT_ETC}/profile -type f \! -name '*~' \! -name '*.bak' -name "use.stable.mask" -or -name "use.mask"`;do tmp_sort="$(mktemp)" echo -e "${underline}Sorting${restore} ${contrast}${package#${PORT_ETC}/}${restore}" masked_uses="$(grep -v "^#" "${package}")" sort_passed_uses "${masked_uses}" | tr "[:space:]" $'\n' > ${tmp_sort} diff_ask "${package}" "${tmp_sort}" eend $? 2>/dev/null done fi } profile_masked_uses() { file="${1}/${2}" if [[ -f "${file}" ]];then all_uses+="$(grep "^[^#].*$" "${file}")"$'\n' fi if [[ -f "${1}/parent" ]]; then for path in $(cat ${1}/parent);do profile_masked_uses "${1}/${path}" "${2}" done fi } mask_files() { if grep -q "~" <<< "$(eix --print ACCEPT_KEYWORDS)";then echo "use.mask" else echo "use.mask use.stable.mask" fi } use_mask() { [[ -h "/etc/make.profile" ]] && makeprof="/etc/make.profile" [[ -h "/etc/portage/make.profile" ]] && makeprof="/etc/portage/make.profile" for target in $(mask_files);do profile_masked_uses "$(readlink -f ${makeprof})" "${target}" done sort_passed_uses "${all_uses} " | tr "[:space:]" $'\n' } etc_profile_use_mask() { if [[ -f "${PORT_ETC}/profile/use.mask" ]];then orig_file="${PORT_ETC}/profile/use.mask" else return 1 fi tmp_file="$(mktemp)" cp "${orig_file}" "${tmp_file}" while read use;do if grep -q "^${use/-/\-}$" <<< "$(use_mask)";then if grep -q "^-" <<< "${use}";then echo -e "Twice unmasked: ${red}${use}${restore}" sed -e "s|^${use}.*||" -e '/^$/d' -e 's/[ \t]*$//' -i "${tmp_file}" else echo -e "Twice masked: ${red}${use}${restore}" sed -e "s|^${use}.*||" -e '/^$/d' -e 's/[ \t]*$//' -i "${tmp_file}" fi else if grep -q "^-" <<< "${use}";then echo -e "Stupid unmask: ${red}${use}${restore}" sed -e "s|^${use}.*||" -e '/^$/d' -e 's/[ \t]*$//' -i "${tmp_file}" fi fi done < "${orig_file}" diff_ask "${orig_file}" "${tmp_file}" } check_use_masked() { for target in $(mask_files);do file_or_dir "profile/${target}" "Checking masked uses:" "etc_profile_use_mask" || return 1 done } ############################################################################ ################ regen_world ############################################### regen_world(){ tmp_world="$(mktemp)" ex_world="$(mktemp)" emerge_log="$(mktemp)" mv "${WORLD}" "${ex_world}" installed="$(qlist -CI | sort -u)" echo "${installed}" > "${WORLD}" echo -e "Calculating dependencies" pre_pre="$(emerge -eopd --columns --with-bdeps=y world 2>"${emerge_log}" || exit 1)" if [[ $? == 1 ]];then mv "${ex_world}" "${WORLD}" cat "${emerge_log}" rm "${tmp_world}" "${emerge_log}" echo -e "\n${red}ERROR!!!${restore} exit\n" exit 1 else rm "${emerge_log}" fi pretend="$(grep -v "blocks" <<< "${pre_pre}" | awk '/^\[/ {print $4}')" && eend 0 2>/dev/null pretend+="$(qlist -CI `emerge -epO system | awk '/\[/ {print $4}'`)"$'\n' for atom in ${installed};do if ! grep -q "^${atom}$" <<< "${pretend}" && ! grep -q ".*-libs/" <<< "${atom}" && ! grep -q "virtual/" <<< "${atom}";then echo "${atom}" >> "${tmp_world}" echo -e "world++: ${green}${atom}${restore}" fi done cp "${tmp_world}" "${WORLD}" PS3=`echo -e "${contrast}Choose package which you want save:${restore} "` choose_target(){ select target in ${pretend};do echo "=${target}" break done } add_in_world(){ notrash_pkgs+=" $(choose_target)" for tp in ${notrash_pkgs};do pretend="$(sed -e "s|^${tp#=}$||" -e '/^$/d' <<< "${pretend}")" done } ask(){ pretend="$(emerge -pc | grep 'All selected packages:' | sed 's|.*:||1' | tr ' ' $'\n')" echo -e "\n${pretend// /$'\n'}" if [[ -n "$(sed '/^$/d' <<< "${pretend}")" ]];then echo -ne "\n${contrast}Would you like save some packages?${restore} [${green}Yes${restore}/${red}No${restore}] " while read x;do [[ -z "$(sed '/^$/d' <<< "${pretend}")" ]] && break case ${x} in Yes | YES | yes | Y | y | "" ) add_in_world; while [[ -z "${enough}" && "$(echo "${pretend// /$'\n'}" | sed '/^$/d' | wc -l)" != "0" ]];do echo -ne "${contrast}More?${restore} [${green}Yes${restore}/${red}No${restore}] " while read y;do case ${y} in Yes | YES | yes | Y | y | "" ) add_in_world; break;; No | NO | no | N | n ) enough="1" break;; * ) echo -ne "Sorry, response '${y}' not understood. [${green}Yes${restore}/${red}No${restore}] " continue;; esac done done break;; No | NO | no | N | n ) break;; * ) echo -ne "Sorry, response '${x}' not understood. [${green}Yes${restore}/${red}No${restore}] " continue;; esac done [[ -n "$(sed '/^$/d' <<< "${notrash_pkgs}")" ]] && emerge -Own ${notrash_pkgs} else return 0 fi } for t in 1 2;do [[ "${t}" == "1" ]] && echo -e "\nemerge -pc: ${green}check...${restore}" [[ "${t}" == "2" ]] && echo -e "\nemerge -pc: ${green}recheck...${restore}" ask unset enough done cp "${WORLD}" "${tmp_world}" cp "${ex_world}" "${WORLD}" diff_ask "${WORLD}" "${tmp_world}" rm "${ex_world}" eend $? 2>/dev/null echo -e "\n${green}Result${restore}:" cat "${WORLD}" } ############################################################################ ################ unused repo and dep-cache ################################# overlays(){ ########## repo over layman layman_path="$(awk '/storage[[:space:]].*:/ {print $3}' /etc/layman/layman.cfg)" source "${layman_path}/make.conf" 2>/dev/null layman_pkgdir="$(tr '[[:space:]]' $'\n' <<< "${PORTDIR_OVERLAY}" | sed '/^$/d')" for repo_dir in ${layman_pkgdir};do [[ -f "${repo_dir}/profiles/repo_name" ]] && repo_name="$(cat "${repo_dir}/profiles/repo_name")" repo_name="${repo_name:-${repo_dir##*/}}" layman_overlays+="${repo_dir} ${repo_name}"$'\n' done all_overlays="${layman_overlays}" ######### repo over PORTDIR_OVERLAY ----> used by portage local PORTDIR_OVERLAY="$(eix --print PORTDIR_OVERLAY)" portage_pkdir="${PORTDIR_OVERLAY}" unset PORTDIR_OVERLAY for repo_dir in ${portage_pkdir};do [[ -f "${repo_dir}/profiles/repo_name" ]] && repo_name="$(cat "${repo_dir}/profiles/repo_name")" repo_name="${repo_name:-${repo_dir##*/}}" portage_overlays+="${repo_dir} ${repo_name}"$'\n' done all_overlays+="${portage_overlays}" all_overlays="$(sort -u <<< "${all_overlays}" | sed '/^$/d')" ######## parent_repo for installed packages echo "Checking installed packages..." tput sc tput civis for i in ${PKGDB}/*/*/repository;do tput el tput el1 output="${i#${PKGDB}/}" output="${output%/repository}" echo -n "${output}" tput rc used_repos+="$(grep -sv '^gentoo$' "${i}")"$'\n' done tput el tput cnorm used_repos="$(sort -u <<< "${used_repos%$'\n'}")" for repo in ${used_repos};do repo_path="$(grep " ${repo}$" <<< "${portage_overlays}" | awk '{print $1}')" if [[ -d "${repo_path}" ]];then ######## checking symlinks in repo for x in `find "${repo_path}" -type l`;do target="$(readlink ${x})" if [[ -e "${target}" || -e "${x%/*}/${target}" ]];then good_links+="${target}"$'\n' else bad_links+="${repo} ${x}"$'\n' fi done else TRASH_REPO+="repo '${green}${repo}${restore}' used, but not exists in \${PORTDIR_OVERLAY}"$'\n' continue fi done ####### checking layman_overlays: used by links or not while read path name;do if grep -q "^${path}" <<< "${good_links%$'\n'}";then link_used+="${path} ${name}"$'\n' else link_unused+="${path} ${name}"$'\n' fi done <<< "${layman_overlays%$'\n'}" ####### looking unused layman repo: by portage, by symlinks while read path name;do if ! grep -q " ${name}$" <<< "${link_used}" && ! grep -q "^${name}$" <<< "${used_repos}";then grep -q " ${name}$" <<< "${layman_overlays}" && UNUSED+="${name}"$'\n' fi done <<< "${all_overlays%$'\n'}" UNUSED="$(sort -u <<< "${UNUSED}")" if [[ -n "${bad_links}" ]];then echo "broken symlinks:" echo "${bad_links}" echo -ne "\n${contrast}Would you like remove?${restore} [${green}Yes${restore}/${red}No${restore}] " while read z;do case ${z} in Yes | YES | yes | Y | y | "" ) for symlink in $(awk '{print $2}' <<< "${bad_links%$'\n'}");do rm -v "${symlink}" eend $? 2>/dev/null done break;; No | NO | no | N | n ) break;; * ) echo -ne "Sorry, response '${z}' not understood. [${green}Yes${restore}/${red}No${restore}] " continue;; esac done fi choose_target(){ PS3=`echo -e "${contrast}Choose repo which you want save:${restore} "` select target in ${UNUSED};do echo "${target}" break done } ask(){ [[ -n "${UNUSED}" ]] && echo -e "Unused repos:\n${UNUSED}" if [[ -n "$(sed '/^$/d' <<< "${UNUSED}")" ]];then echo -ne "\n${contrast}Would you like save some repo(s)?${restore} [${green}Yes${restore}/${red}No${restore}] " while read x;do [[ -z "$(sed '/^$/d' <<< "${UNUSED}")" ]] && break case ${x} in Yes | YES | yes | Y | y | "" ) UNUSED="$(grep -v "^$(choose_target)$" <<< "${UNUSED}")" while [[ -z "${enough}" && "$(echo "${UNUSED// /$'\n'}" | sed '/^$/d' | wc -l)" != "0" ]];do echo -ne "${contrast}More?${restore} [${green}Yes${restore}/${red}No${restore}] " while read y;do case ${y} in Yes | YES | yes | Y | y | "" ) UNUSED="$(grep -v "^$(choose_target)$" <<< "${UNUSED}")" break;; No | NO | no | N | n ) enough="1" break;; * ) echo -ne "Sorry, response '${y}' not understood. [${green}Yes${restore}/${red}No${restore}] " continue;; esac done done break;; No | NO | no | N | n ) break;; * ) echo -ne "Sorry, response '${x}' not understood. [${green}Yes${restore}/${red}No${restore}] " continue;; esac done else return 0 fi } fix_deps(){ DEP_PATH="/var/cache/edb/dep" unset TRASH for dep_path in `find ${DEP_PATH} -type d`;do repo_path="$(sed "s|${DEP_PATH}||" <<< "${dep_path}")" dep_file="${dep_path}.sqlite" if [[ -n "${repo_path}" ]];then if [[ ! -d "${repo_path}" ]];then TRASH+="${dep_path} " [[ -f "${dep_file}" ]] && TRASH+="${dep_file} " elif [[ -d "${repo_path}" && ! "$(ls -A ${repo_path})" ]];then TRASH+="${dep_path} " [[ -f "${dep_file}" ]] && TRASH+="${dep_file} " elif [[ -d "${repo_path}" && ! "$(ls -A ${dep_path})" && ! -f "${dep_file}" ]];then TRASH+="${dep_path} " elif [[ -d "${repo_path}" && "$(ls -A ${dep_path})" && -f "${dep_file}" ]];then file_stamp="$(timestamp "${dep_file}")" path_stamp="$(timestamp ${dep_path}/*)" if [[ -n "${file_stamp}" && -n "${path_stamp}" ]] && (( "${file_stamp}" > "${path_stamp}" ));then TRASH+="${dep_path}/* " elif [[ -n "${file_stamp}" && -n "${path_stamp}" ]] && (( "${file_stamp}" < "${path_stamp}" ));then TRASH+="${dep_file} " fi fi fi done if [[ -n "${TRASH}" ]];then echo "${TRASH}" else stop="true" fi } ask for repo in ${UNUSED};do layman -d "${repo}" done echo -e "\n${TRASH_REPO}" echo "dep-cache:" while [[ -z "${stop}" ]];do trash="$(fix_deps)" if [[ -n "${trash}" ]];then echo -e "$(tr ' ' $'\n' <<< "${trash% }" | sed "s|^|removing:\\${green}|;s|$|\\${restore}|")" rm -rf ${trash} 2>/dev/null || echo failed && exit 1 else break fi done echo "done" eend 0 2>/dev/null } ############################################################################ ################ help ###################################################### help_pc(){ echo -e \ "Usage: portconf [OPTION] [OPTION]…[OPTION] available OPTIONS: ${contrast}Common${restore} -rc, --regen-cache: Create and use temporary eix-cache and some fix for overlays. ${red}Highly recommend!${restore} -b, --backup: Create backup for current /etc/portage state. -r, --restore: Rolling up /etc/portage to one of available states. -s, --sort: Sort entries alphabetically, --use-sort, --keyword-uniq. -y, --yes: Auto answer (Yes). -p, --pretend: Check only. -h, -h, -?, h, --help: This help. ${contrast}\${USE}${restore} -us, --use-sort: Sort useflags. Remove doubles and preserve only last defined state (on/off). -ui, --use-invalid: Delete invalid or twice global-defined useflags. -um, --use-make: Delete profile defined useflags from make.conf. -sup,--stupid-use-profile: Delete incorrect or twice masked/unmasked useflags. -uf, --use-full: An analog '-us -ui -um -sup'. ${contrast}\${KEYWORDS}${restore}: -ku, --keyword-uniq: Like '-us', but for keywords. -ko, --keyword-one: Save only latest defined keyword. ${contrast}Trash${restore}: -t, --trash: Delete not_founded/not_installed entries, empty/backup/unused files. -ft, --force-trash: Delete all not_installed entries.(exclude package.mask file/dir) -sm, --stupid-mask: Remove incorrect masked atoms. -sum, --stupid-unmask: Remove incorrect unmasked atoms. -c, --rm-comments: Delete lines starting with comment. -ac, --rm-all-comments: Delete all comments. -f, --full: An analog '-s -t -uf -ku -sm -sum' ${contrast}Converting${restore}: -f2d, --files-2-dirs: Converting package.* files to directories(comments will be removed). -d2f, --dirs-2-files: Converting package.* dirs to files. ${contrast}Profile${restore}: -apu, --all-profiles-use: List \${USE} defined in profiles. -pu, --profiles-use: List \${USE} of profile. -cpu, --current-profile-use: \${USE} of current profile. ${contrast}World${restore}: -wb, --world-backup: Create backup for current world file state. -wr, --world-restore: Rolling up world file to one of available states. -wg, --world-regen: Regen(cleanup) the world file.(backup: auto) ${contrast}Overlays${restore}: -fr, --fix-repos: Remove unused overlays and dep-cache. OPTIONS must be separated by SPACE." } ############################################################################ ################ run_it #################################################### eix_dep_keys="--use-invalid -ui --use-make -um --use-full -uf --trash -t --force-trash -ft --full -f" opts=" ${PORTCONF_DEFAULT_OPTS} ${@}" grep -q -e " \--yes\>" -e " \-y\>" <<< " ${opts}" && yes="1" grep -q -e " \--pretend\>" -e " \-p\>" <<< " ${opts}" && PRETEND="1" opts="$(sed -e 's| --yes\>||g;s| -y\>||g' -e 's| --pretend\>||g;s| -p\>||g' <<< " ${opts}")" if grep -q "${eix_dep_keys//\-/\\-}" <<< "${opts}";then if grep -q -e " \--regen-cache\>" -e " \-rc\>" <<< " ${opts}";then eix_check opts="$(sed -e 's| --regen-cache\>||g;s| -rc\>||g' -e '/^[ \t]$/d' <<< " ${opts}")" else eix_method fi else opts="$(sed -e 's| --regen-cache\>||g;s| -rc\>||g' -e '/^[ \t]$/d' <<< " ${opts}")" fi [[ -z "${@}" || -z "${opts}" ]] && help_pc for OPT in ${opts};do case "${OPT}" in --backup | -b ) backup;; --restore | -r ) etc_restore;; --sort | -s ) backup; sort_use_file; uniq_keywords; sort_uniq_files; sort_uniq_mask_use;; --use-sort | -us ) backup; sort_use_file;; --use-invalid | -ui ) backup; invalid_uses; invalid_uses_make; [[ -n "${eix_cache}" ]] && rm "${eix_cache}" && unset eix_cache EIX_CACHEFILE;; --use-make | -um ) backup; use_makeconf;; --stupid-use-profile | -sup ) backup; sort_uniq_mask_use; check_use_masked;; --use-full | -uf ) backup; sort_use_file; sort_uniq_mask_use; invalid_uses; invalid_uses_make; use_makeconf; check_use_masked; [[ -n "${eix_cache}" ]] && rm "${eix_cache}" && unset eix_cache EIX_CACHEFILE;; --keyword-one | -ko ) backup; sort_keywords;; --keyword-uniq | -ku ) backup; uniq_keywords;; --trash | -t ) backup; not_found; package_env_conf; package_env; env_not_installed; empty_files; backup_files; [[ -n "${eix_cache}" ]] && rm "${eix_cache}" && unset eix_cache EIX_CACHEFILE;; --stupid-mask | -sm ) backup; mask_trash;; --stupid-unmask | -sum ) backup; stupid_unmask;; --force-trash | -ft ) backup; not_found; package_env_conf; package_env; env_not_installed; force_not_installed; empty_files; backup_files; [[ -n "${eix_cache}" ]] && rm "${eix_cache}" && unset eix_cache EIX_CACHEFILE;; --rm-comments | -c ) backup; rm_comments;; --rm-all-comments | -ac ) backup; rm_all_comments;; --full | -f ) backup; sort_uniq_files; not_found; package_env_conf; package_env; env_not_installed; sort_use_file; sort_uniq_mask_use; invalid_uses; invalid_uses_make; use_makeconf; check_use_masked; uniq_keywords; mask_trash; stupid_unmask; empty_files; backup_files; [[ -n "${eix_cache}" ]] && rm "${eix_cache}" && unset eix_cache EIX_CACHEFILE;; --files-2-dirs | -f2d ) backup; f_to_d;; --dirs-2-files | -d2f ) backup; d_to_f;; --all-profiles-use | -apu ) all_use_all_profiles;; --profiles-use | -pu ) profile_use;; --current-profile-use | -cpu ) current_profile;; --world-backup | -wb ) world_backup;; --world-restore | -wr ) world_restore;; --world-regen | -wg ) world_backup; regen_world;; --fix-repos | -fr ) overlays;; --help | -h | -? | h ) help_pc;; esac done