#!/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