#!/bin/sh # update-alternatives # # Copyright (C) 2001 Carl D. Worth # # This program was inspired by the Debian update-alternatives program # which is Copyright (C) 1995 Ian Jackson. This version of # update-alternatives is command-line compatible with Debian's for a # subset of the options, (only --install, --remove, and --help) # # This program is free software; you can redistribute it and/or modify # it under the terms of the GNU General Public License as published by # the Free Software Foundation; either version 2, or (at your option) # any later version. # # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. set -e # admin dir ad="$OPKG_OFFLINE_ROOT/usr/lib/opkg/alternatives" usage() { echo "update-alternatives: $* Usage: update-alternatives --install update-alternatives --remove update-alternatives --help is the link pointing to the provided path (ie. /usr/bin/foo). is the name in $ad/alternatives (ie. foo) is the name referred to (ie. /usr/bin/foo-extra-spiffy) is an integer; options with higher numbers are chosen. " >&2 exit 2 } quit() { echo "update-alternatives: $*" >&2 exit 2 } register_alt() { [ $# -lt 2 ] && return 1 local name="$1" local link="$2" if [ ! -d $ad ]; then mkdir -p $ad fi if [ -e "$ad/$name" ]; then local olink=`head -n 1 $ad/$name` if [ "$link" != "$olink" ]; then echo "update-alternatives: Error: cannot register alternative $name to $link since it is already registered to $olink" >&2 return 1 fi else echo "$link" > "$ad/$name" fi return 0 } protect_slashes() { sed -e 's/\//\\\//g' } remove_alt() { [ $# -lt 2 ] && return 1 local name="$1" local path="$2" [ ! -f $ad/$name ] && return 0 path=`echo $path | protect_slashes` sed -ne "/^$path\>.*/!p" $ad/$name > $ad/$name.new mv $ad/$name.new $ad/$name } add_alt() { [ $# -lt 3 ] && return 1 local name="$1" local path="$2" local priority="$3" remove_alt $name $path echo "$path $priority" >> $ad/$name } find_best_alt() { [ $# -lt 1 ] && return 1 [ ! -f $ad/$name ] && return 0 link=$OPKG_OFFLINE_ROOT/`head -n 1 $ad/$name` prio=`sed -ne "1!p" $ad/$name | sed -e "s/\(.*\) \(.*\)/\2 \1/g" | sort -nr | head -n 1 | sed 's/ [^ ]*$//'` if [ -z "$prio" ]; then echo "update-alternatives: removing $link as no more alternatives exist for it" rm $ad/$name if [ -L $link ]; then rm $link fi return 0 fi ## Find last line with highest priority. path=`grep "${prio}$" $ad/$name | tail -n 1 | sed 's/ [^ ]*$//'` if [ ! -e $link -o -L $link ]; then local link_dir=`dirname $link` if [ ! -d $link_dir ]; then mkdir -p $link_dir fi if [ -h $link -a -d $link ]; then # If $link exists and the target is a directory, # 'ln -sf $path $link' doesn't replace the link to # that directory, it creates new link inside. echo "update-alternatives: Removing $link". rm -f $link fi ln -sf $path $link echo "update-alternatives: Linking $link to $path" else echo "update-alternatives: Error: not linking $link to $path since $link exists and is not a link" return 1 fi return 0 } do_install() { if [ $# -lt 4 ]; then usage "--install needs " fi local link="$1" local name="$2" local path="$3" local priority="$4" path=`echo $path | sed 's|/\+|/|g'` # This is a bad hack, but I haven't thought of a cleaner solution yet... [ -n "$OPKG_OFFLINE_ROOT" ] && path=`echo $path | sed "s|^$OPKG_OFFLINE_ROOT/*|/|"` register_alt $name $link add_alt $name $path $priority find_best_alt $name } do_remove() { if [ $# -lt 2 ]; then usage "--remove needs " fi local name="$1" local path="$2" path=`echo $path | sed 's|/\+|/|g'` # This is a bad hack, but I haven't thought of a cleaner solution yet... [ -n "$OPKG_OFFLINE_ROOT" ] && path=`echo $path | sed "s|^$OPKG_OFFLINE_ROOT/*|/|"` remove_alt $name $path find_best_alt $name } ### # update-alternatives "main" ### while [ $# -gt 0 ]; do arg="$1" shift case $arg in --help) usage "help:" exit 0 ;; --install) do_install $* exit $? ;; --remove) do_remove $* exit $? ;; *) usage "unknown argument \`$arg'" ;; esac done usage "at least one of --install or --remove must appear" exit 0