update-alternatives 4.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194
  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. set -e
  21. # admin dir
  22. ad="$OPKG_OFFLINE_ROOT/usr/lib/opkg/alternatives"
  23. usage() {
  24. echo "update-alternatives: $*
  25. Usage: update-alternatives --install <link> <name> <path> <priority>
  26. update-alternatives --remove <name> <path>
  27. update-alternatives --help
  28. <link> is the link pointing to the provided path (ie. /usr/bin/foo).
  29. <name> is the name in $ad/alternatives (ie. foo)
  30. <path> is the name referred to (ie. /usr/bin/foo-extra-spiffy)
  31. <priority> is an integer; options with higher numbers are chosen.
  32. " >&2
  33. exit 2
  34. }
  35. quit() {
  36. echo "update-alternatives: $*" >&2
  37. exit 2
  38. }
  39. register_alt() {
  40. [ $# -lt 2 ] && return 1
  41. local name="$1"
  42. local link="$2"
  43. if [ ! -d $ad ]; then
  44. mkdir -p $ad
  45. fi
  46. if [ -e "$ad/$name" ]; then
  47. local olink=`head -n 1 $ad/$name`
  48. if [ "$link" != "$olink" ]; then
  49. echo "update-alternatives: Error: cannot register alternative $name to $link since it is already registered to $olink" >&2
  50. return 1
  51. fi
  52. else
  53. echo "$link" > "$ad/$name"
  54. fi
  55. return 0
  56. }
  57. protect_slashes() {
  58. sed -e 's/\//\\\//g'
  59. }
  60. protect_special_character() {
  61. sed -e 's/\[/\\\[/g'
  62. }
  63. remove_alt() {
  64. [ $# -lt 2 ] && return 1
  65. local name="$1"
  66. local path="$2"
  67. [ ! -f $ad/$name ] && return 0
  68. path=`echo $path | protect_slashes | protect_special_character`
  69. sed -ne "/^$path\>.*/!p" $ad/$name > $ad/$name.new
  70. mv $ad/$name.new $ad/$name
  71. }
  72. add_alt() {
  73. [ $# -lt 3 ] && return 1
  74. local name="$1"
  75. local path="$2"
  76. local priority="$3"
  77. remove_alt $name $path
  78. echo "$path $priority" >> $ad/$name
  79. }
  80. find_best_alt() {
  81. [ $# -lt 1 ] && return 1
  82. [ ! -f $ad/$name ] && return 0
  83. link=$OPKG_OFFLINE_ROOT`head -n 1 $ad/$name`
  84. prio=`sed -ne "1!p" $ad/$name | sed -e "s/\(.*\) \(.*\)/\2 \1/g" | sort -nr | head -n 1 | sed 's/ [^ ]*$//'`
  85. if [ -z "$prio" ]; then
  86. echo "update-alternatives: removing $link as no more alternatives exist for it"
  87. rm $ad/$name
  88. if [ -L $link ]; then
  89. rm $link
  90. fi
  91. return 0
  92. fi
  93. ## Find last line with highest priority.
  94. path=`grep "${prio}$" $ad/$name | tail -n 1 | sed 's/ [^ ]*$//'`
  95. if [ ! -e $link -o -L $link ]; then
  96. local link_dir=`dirname $link`
  97. if [ ! -d $link_dir ]; then
  98. mkdir -p $link_dir
  99. fi
  100. ln -snf $path $link
  101. echo "update-alternatives: Linking $link to $path"
  102. else
  103. echo "update-alternatives: Error: not linking $link to $path since $link exists and is not a link"
  104. return 1
  105. fi
  106. return 0
  107. }
  108. do_install() {
  109. if [ $# -lt 4 ]; then
  110. usage "--install needs <link> <name> <path> <priority>"
  111. fi
  112. local link="$1"
  113. local name="$2"
  114. local path="$3"
  115. local priority="$4"
  116. path=`echo $path | sed 's|/\+|/|g'`
  117. # This is a bad hack, but I haven't thought of a cleaner solution yet...
  118. [ -n "$OPKG_OFFLINE_ROOT" ] && path=`echo $path | sed "s|^$OPKG_OFFLINE_ROOT/*|/|"`
  119. register_alt $name $link
  120. add_alt $name $path $priority
  121. find_best_alt $name
  122. }
  123. do_remove() {
  124. if [ $# -lt 2 ]; then
  125. usage "--remove needs <name> <path>"
  126. fi
  127. local name="$1"
  128. local path="$2"
  129. path=`echo $path | sed 's|/\+|/|g'`
  130. # This is a bad hack, but I haven't thought of a cleaner solution yet...
  131. [ -n "$OPKG_OFFLINE_ROOT" ] && path=`echo $path | sed "s|^$OPKG_OFFLINE_ROOT/*|/|"`
  132. remove_alt $name $path
  133. find_best_alt $name
  134. }
  135. ###
  136. # update-alternatives "main"
  137. ###
  138. while [ $# -gt 0 ]; do
  139. arg="$1"
  140. shift
  141. case $arg in
  142. --help)
  143. usage "help:"
  144. exit 0
  145. ;;
  146. --install)
  147. do_install $*
  148. exit $?
  149. ;;
  150. --remove)
  151. do_remove $*
  152. exit $?
  153. ;;
  154. *)
  155. usage "unknown argument \`$arg'"
  156. ;;
  157. esac
  158. done
  159. usage "at least one of --install or --remove must appear"
  160. exit 0