You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

292 lines
6.4 KiB

#!/bin/bash
#######################################
# Inspiration from bug #34921
# Thanks to Paul Varner
# Distributed under the GPL v2
# Written by John Mylchreest (johnm@gentoo.org)
# Copyright Gentoo Linux
if [[ `id -u` != 0 ]]; then
echo "This application must be ran as root."
exit 1
fi
R_VERSION="0.5"
R_MODULES="${ROOT}/var/lib/module-rebuild/moduledb"
R_PORTAGEQ="`which portageq 2>/dev/null`"
if [[ -z ${R_PORTAGEQ} ]]; then
echo "** FATAL: Unable to find portageq."
exit 1
fi
R_PORTDIR=`${R_PORTAGEQ} portdir`
R_VDBPATH=`${R_PORTAGEQ} vdb_path`
R_OPTION_X=0;
R_OPTION_C=0;
package_valid() {
local package=${1}
[[ -z ${package} ]] && return 1
[[ -z ${package/*\/*} ]] && return 0 || return 1
}
package_valid_strict() {
local package=${1}
package_valid ${package} && [[ -z ${package%%*-[0-9]*} ]] && return 0 || return 1
}
package_exists() {
local package=${1}
package=${package%-[0-9]*}
if $(${R_PORTAGEQ} has_version / ${package}); then
return 0
else
return 1
fi
}
db_module_exists() {
local line package=${1}
for line in `<${R_MODULES}`; do
[[ -z ${line/*${package}*} ]] && return 0
done
return 1
}
db_module_toggle() {
local package=${1} toggleto=${2} togglefrom line
if db_module_exists ${package}; then
line=`grep ${package} ${R_MODULES}`
togglefrom=${line#*:}
togglefrom=${togglefrom/:*}
if [[ -z ${toggleto} ]]; then
[[ ${togglefrom} = 0 ]] && toggleto=1 || toggleto=0
fi
echo "** Setting ${package}; rebuild=${toggleto}."
sed -i -e "s:\(.\:\)\([01]\)\(\:${package}\):\1${toggleto}\3:g" ${R_MODULES}
else
echo "** ${package} not found in moduledb."
fi
}
db_module_add() {
local package=${1}
if db_module_exists ${package}; then
echo -e "${C_BOLD}** Module already exists in moduledb.${C_NORM}"
db_module_toggle ${package} 1
return 0
else
if package_exists ${package}; then
echo -e "${C_BOLD}${C_GREEN}** Adding ${package} to moduledb.${C_NORM}"
echo "m:1:${package}" >> ${R_MODULES}
return 0
else
echo -e "${C_RED}** Unable to locate an available ebuild for ${package}.${C_NORM}"
echo "** Please manually emerge ${package} first."
fi
fi
return 1
}
db_module_del() {
local package=${1}
if db_module_exists ${package}; then
echo "** Removing ${package} from moduledb."
sed -ie "/.*${package/\//\\/}.*/d" ${R_MODULES}
return 0
else
echo "** ${package} not found in moduledb."
return 1
fi
}
db_module_list() {
local line auto pkg a=0 b=0
for line in `<${R_MODULES}`; do
mode=${line:0:1}
pkg=${line#*:}
auto=${pkg/:*}
pkg=${pkg/*:}
if [[ ${R_OPTION_X} == 1 ]]; then
pkg=${pkg%-[0-9]*}
package_valid ${pkg}
else
package_valid_strict ${pkg} && pkg="=${pkg}"
fi
if [[ ${auto} = 1 ]]; then
tomerge[${a}]=${pkg}
a=$((${a} + 1))
else
toignore[${b}]=${pkg}
b=$((${b} + 1))
fi
done
pkg="${tomerge[@]}${toignore[@]}"
if [[ -z ${pkg} ]]; then
echo -e "${C_BOLD}${C_RED}** There are no known modules. Quitting.${C_NORM}"
exit 1
fi
if [[ -n ${tomerge[@]} ]]; then
echo -e "${C_BOLD}${C_GREEN}** Packages which I will emerge are:${C_NORM}"
for pkg in ${tomerge[@]}; do
echo -e "\t${pkg}"
done
fi
if [[ -n ${toignore[@]} ]]; then
echo -e "${C_BOLD}${C_GREEN}** Packages which I will ignore are:${C_NORM}"
for pkg in ${toignore[@]}; do
echo -e "\t${pkg}"
done
fi
}
db_module_populate() {
local i x=0 pkg version list pad
# Lets find them all
# chances are we will get a few dupes in here.
version=`uname -r`
for pkg in `grep -i /lib/modules/${version}/.*o ${R_VDBPATH}/*/*/CONTENTS`; do
pad=""; x=0;
if [[ -z ${pkg//${R_VDBPATH}*} ]]; then
for((i=0;i<=${#pkg};i++)); do
[[ ${pkg:${i}:1} = / ]] && x=$((${x} + 1));
[[ ${x} == 4 ]] || [[ ${x} == 5 ]] && pad="${pad}${pkg:${i}:1}";
done
# Remove any dupes
list=${list//${pad:1}}
list="${list} ${pad:1}"
fi
done
for pkg in ${list}; do
db_module_add ${pkg};
done
}
db_module_merge() {
local i pkg
echo -e "${C_BOLD}** Preparing to merge modules:${C_NORM}"
db_module_list >/dev/null
if [[ -z ${tomerge[@]} ]]; then
echo -e "${C_BOLD}${C_RED}** No packages to merge. Quitting.${C_NORM}"
exit 1
fi
echo -e "${C_BOLD}${C_GREEN}** Packages which I will emerge are:"${C_NORM}
for pkg in ${tomerge[@]}; do
echo -e "\t${pkg}"
done
for((i=1;i<6;i++)); do
echo -en "${C_BOLD}${C_RED}$((6 - ${i})) ${C_NORM}"
sleep 1
done
echo
emerge --oneshot --nodeps ${tomerge[@]}
}
phelp() {
cat << EOF
module-rebuild [options] action [category/package]
Version: ${R_VERSION}
Where options are:
-X - Emerge based on package names,
not exact versions.
-C - Disable all coloured output.
Where action is one of:
add - Add package to moduledb.
del - Delete a package from moduledb.
toggle - Toggle auto-rebuild of Package.
list - List packages to auto-rebuild.
rebuild - Rebuild packages.
populate - Populate the database with any
packages which currently install
drivers into the running kernel.
EOF
}
check_validity() {
local package=${1} strict=${2:-0} ret=1
[[ ${strict} = 0 ]] && package_valid ${package} && ret=0
[[ ${strict} = 1 ]] && package_valid_strict ${package} && ret=0
if [[ ${ret} != 0 ]]; then
echo "** Please pass the fully qualified package. For example:"
echo "** media-video/nvidia-kernel-1.0.7174"
exit 1
fi
}
while getopts "XC" options; do
case ${options} in
X) R_OPTION_X='1';;
C) R_OPTION_C='1';;
*) phelp; exit 1;;
esac
done
if [[ ${R_OPTION_C} == 0 ]]; then
C_BOLD='\e[1m'
C_NORM='\e[0m'
C_GREEN='\e[32m'
C_RED='\e[31m'
else
C_BOLD=''
C_NORM=''
C_GREEN=''
C_RED=''
fi
x=0
for i in ${@:${OPTIND}}; do
if [[ ${i:0:1} != - ]]; then
R_PARAMS[${x}]=${i}
x=$((${x} + 1))
fi
done
unset i x
# If the moduledb doesnt exist, lets populate it automatically.
if [[ ! -f ${R_MODULES} ]]; then
echo -e "${C_BOLD}${C_RED}No moduledb found...${C_NORM}"
[[ ! -d ${ROOT}/var/lib/module-rebuild/ ]] && \
echo -e "${C_BOLD}Creating moduledb state directory.${C_NORM}"; \
mkdir -p ${ROOT}/var/lib/module-rebuild/
echo -e "${C_BOLD}Populating moduledb...${C_NORM}"
touch ${R_MODULES}
R_PARAMS[0]=populate
fi
case ${R_PARAMS[0]} in
add) check_validity ${R_PARAMS[1]} 1; db_module_add ${R_PARAMS[1]};;
del) check_validity ${R_PARAMS[1]}; db_module_del ${R_PARAMS[1]};;
toggle) check_validity ${R_PARAMS[1]}; db_module_toggle ${R_PARAMS[1]};;
list) db_module_list;;
rebuild) db_module_merge;;
populate) db_module_populate;;
*) phelp; exit 1;;
esac