# -*-eselect-*- vim: ft=eselect # Copyright 2005-2014 Gentoo Foundation # Distributed under the terms of the GNU GPL version 2 or later DESCRIPTION="Manage the /usr/src/linux symlink" MAINTAINER="eselect@gentoo.org" # sort function for kernel versions, to be used in a pipe sort_kernel_versions() { local vsort="sort --version-sort" # Test if our sort supports the --version-sort option # (should be GNU sort, since the kernel module is GNU/Linux specific) ${vsort} /dev/null || vsort=sort # We sort kernel versions as follows: # 1. Run sed to prepend the version string by the numeric version # and an additional rank indicator that is 0 for release candidates # or 1 otherwise. After this step we have, for example: # 2.6.29 1 linux-2.6.29 # 2.6.29 0 linux-2.6.29-rc8 # 2. sort --version-sort # 3. Run sed again to remove the prepended keys from step 1. sed -e 's/^\(linux-\)\?\([[:digit:].]\+\)[-_]rc/\2 0 &/' \ -e 't;s/^\(linux-\)\?\([[:digit:].]\+\)/\2 1 &/' \ | LC_ALL=C ${vsort} | sed 's/.* //' } # find a list of kernel symlink targets find_targets() { local f for f in "${EROOT}"/usr/src/linux-[[:digit:]]*; do [[ -f ${f}/Makefile ]] && basename "${f}" done | sort_kernel_versions } # remove the kernel symlink remove_symlink() { rm "${EROOT}/usr/src/linux" } # set the kernel symlink set_symlink() { local target=$1 if is_number "${target}"; then local targets=( $(find_targets) ) target=${targets[target-1]} fi if [[ -z ${target} ]]; then die -q "Target \"$1\" doesn't appear to be valid!" elif [[ -f ${EROOT}/usr/src/${target}/Makefile ]]; then ln -s "${target}" "${EROOT}/usr/src/linux" elif [[ -f ${EROOT}/usr/src/linux-${target}/Makefile ]]; then ln -s "linux-${target}" "${EROOT}/usr/src/linux" else die -q "Target \"$1\" doesn't appear to be valid!" fi } ### show action ### describe_show() { echo "Show the current kernel symlink" } do_show() { write_list_start "Current kernel symlink:" if [[ -L ${EROOT}/usr/src/linux ]]; then local kernel=$(canonicalise "${EROOT}/usr/src/linux") write_kv_list_entry "${kernel%/}" "" [[ -f ${kernel}/Makefile ]] \ || write_warning_msg "Symlink target doesn't appear to be valid!" else write_kv_list_entry "(unset)" "" fi } ### list action ### describe_list() { echo "List available kernel symlink targets" } do_list() { local i targets=( $(find_targets) ) write_list_start "Available kernel symlink targets:" for (( i = 0; i < ${#targets[@]}; i++ )); do [[ ${targets[i]} = \ $(basename "$(canonicalise "${EROOT}/usr/src/linux")") ]] \ && targets[i]=$(highlight_marker "${targets[i]}") done write_numbered_list -m "(none found)" "${targets[@]}" } ### set action ### describe_set() { echo "Set a new kernel symlink target" } describe_set_parameters() { echo "" } describe_set_options() { echo "target : Target name or number (from 'list' action)" } do_set() { [[ -z $1 ]] && die -q "You didn't tell me what to set the symlink to" [[ $# -gt 1 ]] && die -q "Too many parameters" if [[ -L ${EROOT}/usr/src/linux ]]; then # existing symlink remove_symlink || die -q "Couldn't remove existing symlink" set_symlink "$1" || die -q "Couldn't set a new symlink" elif [[ -e ${EROOT}/usr/src/linux ]]; then # we have something strange die -q "${EROOT}/usr/src/linux exists but is not a symlink" else set_symlink "$1" || die -q "Couldn't set a new symlink" fi }