# -*-eselect-*- vim: ft=eselect # Copyright 1999-2013 Gentoo Foundation # Distributed under the terms of the GNU General Public License v2 or later # $Id: $ DESCRIPTION="Switch between sysvinit implementations" MAINTAINER="lxnay@gentoo.org" VERSION="0.1" # Directory where sysvinit implementations are supposed to be found. # The directory name is going to become the target name. INITS_DIR="${EROOT}/%INITS_DIR%" # Directory where symlinks are created INIT_DIR="${EROOT}/%INIT_DIR%" # Executables expected to be found in ${INITS_DIR}// INIT_PARTS=( %INIT_PARTS% ) # File that contains the name of the currently running # sysvinit, that will be used by /sbin/init.d/exec.sh # to redirect the command calls to the old sysvinit # implementation (which is now in lame duck), after # a successful set. RUNNING_INIT="${EROOT}/run/running.sysvinit" find_targets() { local d= local dname= local legit= for d in "${INITS_DIR}/"*; do [[ ! -d "${d}" ]] && continue legit=1 for part in "${INIT_PARTS[@]}"; do [[ ! -x "${d}/${part}" ]] && { legit=0; break; } done [[ ${legit} == 0 ]] && continue dname=$(basename "${d}") echo "${dname}" done } set_init() { local target="${1}" if is_number "${target}"; then local targets=( $(find_targets) ) target=${targets[target-1]} fi local target_dir="${INITS_DIR}/${target}" [[ -z "${target}" || ! -d "${target_dir}" ]] \ && die -q "Target \"${target}\" doesn't appear to be valid!" if [ ! -e "${RUNNING_INIT}" ]; then echo "$(get_init)" > "${RUNNING_INIT}.tmp" || \ die "Cannot create ${RUNNING_INIT}.tmp" mv -n "${RUNNING_INIT}.tmp" "${RUNNING_INIT}" || \ die "Cannot create ${RUNNING_INIT}" fi echo "Setting the sysvinit implementation to ${target}" local s d part for part in "${INIT_PARTS[@]}"; do s="${target_dir}/${part}" d="${INIT_DIR}/${part}" ln -sf "${s#${INIT_DIR}/}" "${d}.tmp" || \ { rm -f "${d}.tmp"; die "Cannot create symlink: ${d}.tmp" } mv "${d}.tmp" "${d}" || die "Cannot mv symlink: ${d}.tmp" done } get_init() { local init= local init_link= local init_link_dir= local init_bn= init="${INIT_DIR}/${INIT_PARTS[0]}" [[ ! -L "${init}" ]] && return 1 init_link=$(readlink "${init}") [[ -z "${init_link}" ]] && return 1 init_link_dir=$(dirname "${init_link}") [[ -z "${init_link_dir}" ]] && return 1 init_bn=$(basename "${init_link_dir}") echo ${init_bn} } describe_show() { echo "Show the current sysvinit implementation" } describe_show_options() { echo "--quiet : only print the actual sysvinit implementation" echo "--silent : same as --quiet" } do_show() { local quiet= local init= while [[ $# -gt 0 ]]; do case ${1##--} in quiet|silent) quiet="1" ;; esac shift done init=$(get_init) [[ -z "${quiet}" ]] && write_list_start "Current :" if [[ -n "${init}" ]]; then if [[ -n "${quiet}" ]]; then echo "${init}" else write_kv_list_entry "${init}" "" fi else if [[ -z "${quiet}" ]]; then write_kv_list_entry "(unset)" "" fi fi } ### list action ### describe_list() { echo "List available sysvinit implementations" } describe_list_options() { echo "--quiet : only print the actual sysvinit implementation" echo "--silent : same as --quiet" } do_list() { local quiet= local i= local init=$(get_init) local targets=( $(find_targets) ) while [[ $# -gt 0 ]]; do case ${1##--} in quiet|silent) quiet="1" ;; esac shift done [[ -z "${quiet}" ]] && \ write_list_start "Available sysvinit implementations:" for (( i = 0; i < ${#targets[@]}; i++ )); do if [[ -z "${quiet}" ]]; then [[ "${targets[i]}" == "${init}" ]] && \ targets[i]=$(highlight_marker "${targets[i]}") else echo "${targets[i]}" fi done [[ -z "${quiet}" ]] && \ write_numbered_list -m "(none found)" "${targets[@]}" } describe_set() { echo "Set a new sysvinit implementation" } describe_set_parameters() { echo "" } describe_set_options() { echo "target : Target name or number (from 'list' action)" echo "--use-old : use the old value if target is already set" } do_set() { local use_old= local target="${1}" while [[ $# -gt 0 ]]; do case ${1##--} in use-old) use_old="1" ;; esac shift done [[ -z "${target}" ]] && \ die -q "You didn't tell me what to set the symlink to" [[ ${#} -gt 1 ]] && die -q "Too many parameters" if [[ "${use_old}" = "1" ]]; then old_target=$(get_init) target="${old_target:-${target}}" fi set_init "${target}" || die -q "Couldn't set a new symlink" }