# Copyright 1999-2009 Gentoo Foundation # Distributed under the terms of the GNU General Public License v2 # $Id: $ DESCRIPTION="Manage /bin/sh (POSIX shell) implementations" MAINTAINER="gentoo@mgorny.alt.pl" VERSION="0.1" # Based on work of Erik Hahn; bug #214817 ## Functions ## # find a list of sh symlink targets, best first find_targets() { local t for t in \ bash \ dash \ zsh \ posh \ ; do if [[ -x "${ROOT}"/bin/${t} ]]; then echo ${t} fi done } # set the sh symlink set_symlinks() { local target="${1}" targets [[ ! -L "${ROOT}"/bin/sh && -e "${ROOT}"/bin/sh ]] && \ die -q "/bin/sh is not a symlink!" if is_number "${target}" && [[ ${target} -ge 1 ]]; then targets=( $(find_targets) ) target=${targets[$(( ${target} - 1 ))]} fi if [[ -x "${ROOT}"/bin/${target} ]]; then local tmpf="${ROOT}"/bin/sh.new # we could use 'ln -f' to directly replace the symlink # but 'mv' is an atomic operation so it should be more fault-proof ln -s "${target}" "${tmpf}" || \ die -q "Unable to create temporary symlink" if ! mv "${tmpf}" "${ROOT}"/bin/sh; then rm -f "${tmpf}" # cleanup die -q "Unable to replace /bin/sh symlink with ${target}" fi else die -q "Target '${target}' doesn't appear to be valid!" fi } ### show action ### describe_show() { echo "Show the current POSIX shell implementation" } do_show() { [[ -z "${@}" ]] || die -q "Too many parameters" write_list_start "Current POSIX shell implementation:" if [[ -L "${ROOT}/bin/sh" ]]; then write_kv_list_entry "$(basename $(canonicalise ${ROOT}/bin/sh))" "" elif [[ -e "${ROOT}/bin/sh" ]]; then write_kv_list_entry "(not a symlink)" "" else write_kv_list_entry "(unset)" "" fi } ### list action ### describe_list() { echo "List available POSIX shell implementations" } do_list() { [[ -z "${@}" ]] || die -q "Too many parameters" local i targets targets=( $(find_targets) ) if [[ -n ${targets[@]} ]]; then for (( i = 0; i < ${#targets[@]}; i++ )) ; do [[ ${targets[${i}]} == $(basename $(canonicalise ${ROOT}/bin/sh)) ]] && \ targets[${i}]="${targets[${i}]} $(highlight '*')" done write_list_start "Available POSIX shell implementations:" write_numbered_list "${targets[@]}" else write_kv_list_entry "(none found)" "" fi } ### set action ### describe_set() { echo "Set a new POSIX shell implementation" } describe_set_options() { echo "target : Target name or number (from 'list' action)" } describe_set_parameters() { echo "" } do_set() { if [[ -z "${1}" ]]; then die -q "Not enough parameters" elif [[ -n "${2}" ]]; then die -q "Too many parameters" else set_symlinks "${1}" fi } ### update action ### describe_update() { echo "Automatically update the POSIX shell implementation" } describe_update_options() { echo "--if-unset : Do not override existing implementation" } do_update() { [[ -z "${1}" || ( -z "${2}" && "${1}" == "--if-unset" ) ]] || \ die -q "Usage error" [[ "${1}" == "--if-unset" && -L "${ROOT}"/bin/sh && -x "${ROOT}"/bin/sh ]] && \ return set_symlinks 1 } # vim: set syn=sh :