cli: enforce argument to upgrade command
[project/opkg-lede.git] / utils / update-alternatives.in
1 #!/bin/sh
2 # update-alternatives
3 #
4 # Copyright (C) 2001 Carl D. Worth
5 #
6 # This program was inspired by the Debian update-alternatives program
7 # which is Copyright (C) 1995 Ian Jackson. This version of
8 # update-alternatives is command-line compatible with Debian's for a
9 # subset of the options, (only --install, --remove, and --help)
10 #
11 # This program is free software; you can redistribute it and/or modify
12 # it under the terms of the GNU General Public License as published by
13 # the Free Software Foundation; either version 2, or (at your option)
14 # any later version.
15 #
16 # This program is distributed in the hope that it will be useful,
17 # but WITHOUT ANY WARRANTY; without even the implied warranty of
18 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
19 # GNU General Public License for more details.
20
21 set -e
22
23 # admin dir
24 ad="$OPKG_OFFLINE_ROOT@opkglibdir@/opkg/alternatives"
25
26 usage() {
27 echo "update-alternatives: $*
28
29 Usage: update-alternatives --install <link> <name> <path> <priority>
30 update-alternatives --remove <name> <path>
31 update-alternatives --help
32 <link> is the link pointing to the provided path (ie. /usr/bin/foo).
33 <name> is the name in $ad/alternatives (ie. foo)
34 <path> is the name referred to (ie. /usr/bin/foo-extra-spiffy)
35 <priority> is an integer; options with higher numbers are chosen.
36 " >&2
37 exit 2
38 }
39
40 quit() {
41 echo "update-alternatives: $*" >&2
42 exit 2
43 }
44
45 register_alt() {
46 [ $# -lt 2 ] && return 1
47 local name="$1"
48 local link="$2"
49
50 if [ ! -d $ad ]; then
51 mkdir -p $ad
52 fi
53
54 if [ -e "$ad/$name" ]; then
55 local olink=`head -n 1 $ad/$name`
56 if [ "$link" != "$olink" ]; then
57 echo "update-alternatives: Error: cannot register alternative $name to $link since it is already registered to $olink" >&2
58 return 1
59 fi
60 else
61 echo "$link" > "$ad/$name"
62 fi
63
64 return 0
65 }
66
67 protect_slashes() {
68 sed -e 's/\//\\\//g'
69 }
70
71 remove_alt() {
72 [ $# -lt 2 ] && return 1
73 local name="$1"
74 local path="$2"
75
76 [ ! -f $ad/$name ] && return 0
77
78 path=`echo $path | protect_slashes`
79 sed -ne "/^$path\>.*/!p" $ad/$name > $ad/$name.new
80 mv $ad/$name.new $ad/$name
81 }
82
83 add_alt() {
84 [ $# -lt 3 ] && return 1
85 local name="$1"
86 local path="$2"
87 local priority="$3"
88 remove_alt $name $path
89 echo "$path $priority" >> $ad/$name
90 }
91
92 find_best_alt() {
93 [ $# -lt 1 ] && return 1
94 [ ! -f $ad/$name ] && return 0
95
96 link=$OPKG_OFFLINE_ROOT/`head -n 1 $ad/$name`
97
98 prio=`sed -ne "1!p" $ad/$name | sed -e "s/\(.*\) \(.*\)/\2 \1/g" | sort -nr | head -n 1 | sed 's/ [^ ]*$//'`
99 if [ -z "$prio" ]; then
100 echo "update-alternatives: removing $link as no more alternatives exist for it"
101 rm $ad/$name
102 if [ -L $link ]; then
103 rm $link
104 fi
105 return 0
106 fi
107
108 ## Find last line with highest priority.
109 path=`grep "${prio}$" $ad/$name | tail -n 1 | sed 's/ [^ ]*$//'`
110
111 if [ ! -e $link -o -L $link ]; then
112 local link_dir=`dirname $link`
113 if [ ! -d $link_dir ]; then
114 mkdir -p $link_dir
115 fi
116 if [ -h $link -a -d $link ]; then
117 # If $link exists and the target is a directory,
118 # 'ln -sf $path $link' doesn't replace the link to
119 # that directory, it creates new link inside.
120 echo "update-alternatives: Removing $link".
121 rm -f $link
122 fi
123 ln -sf $path $link
124 echo "update-alternatives: Linking $link to $path"
125 else
126 echo "update-alternatives: Error: not linking $link to $path since $link exists and is not a link"
127 return 1
128 fi
129
130 return 0
131 }
132
133 do_install() {
134 if [ $# -lt 4 ]; then
135 usage "--install needs <link> <name> <path> <priority>"
136 fi
137 local link="$1"
138 local name="$2"
139 local path="$3"
140 local priority="$4"
141
142 path=`echo $path | sed 's|/\+|/|g'`
143
144 # This is a bad hack, but I haven't thought of a cleaner solution yet...
145 [ -n "$OPKG_OFFLINE_ROOT" ] && path=`echo $path | sed "s|^$OPKG_OFFLINE_ROOT/*|/|"`
146
147 register_alt $name $link
148 add_alt $name $path $priority
149 find_best_alt $name
150 }
151
152 do_remove() {
153 if [ $# -lt 2 ]; then
154 usage "--remove needs <name> <path>"
155 fi
156 local name="$1"
157 local path="$2"
158
159 path=`echo $path | sed 's|/\+|/|g'`
160
161 # This is a bad hack, but I haven't thought of a cleaner solution yet...
162 [ -n "$OPKG_OFFLINE_ROOT" ] && path=`echo $path | sed "s|^$OPKG_OFFLINE_ROOT/*|/|"`
163
164 remove_alt $name $path
165 find_best_alt $name
166 }
167
168 ###
169 # update-alternatives "main"
170 ###
171
172 while [ $# -gt 0 ]; do
173 arg="$1"
174 shift
175
176 case $arg in
177 --help)
178 usage "help:"
179 exit 0
180 ;;
181 --install)
182 do_install $*
183 exit $?
184 ;;
185 --remove)
186 do_remove $*
187 exit $?
188 ;;
189 *)
190 usage "unknown argument \`$arg'"
191 ;;
192 esac
193 done
194
195 usage "at least one of --install or --remove must appear"
196
197 exit 0