#!/bin/sh usage() { cat <:: EOF exit 1 } errmsg() { echo "$0: $@" >&2 } uci_() { $UCI ${UCI_CONFIG_DIR:+-c $UCI_CONFIG_DIR} "$@" } check_path() { local path="${IPKG_INSTROOT}$1" [ -L "$path" -o ! -e "$path" ] || { errmsg "$0: $path exists and is not an symbolic file" exit 1 } } update_path() { local path="$1" local found_section found_altpath local found_prio=-1 found_prio_altpath local IFS cur altpath config_load opkg config_foreach find_path alternatives "$prio" "$path" if [ -n "$found_prio_altpath" ]; then IFS=:; set -- $found_prio_altpath; altpath=$2; IFS="$oIFS" cur="$(readlink -f "$path")" if [ "$cur" != "$altpath" ]; then errmsg "link $path -> $altpath" ln -sf "$altpath" "${IPKG_INSTROOT}$path" fi elif [ -n "$found_section" ]; then errmsg "remove empty alternatives section for $path" uci_ delete "opkg.$found_section" uci_ commit opkg rm -f "${IPKG_INSTROOT}$path" fi } find_altpath() { local cfgaltpath="$1" local cfg="$2" local prio="$3" local altpath="$4" local cfgprio cfgaltpath_ local oIFS="$IFS"; IFS=:; set -- $cfgaltpath; cfgprio="$1"; cfgaltpath_="$2"; IFS="$oIFS" if [ "$cfgaltpath_" = "$altpath" ]; then found_altpath="$cfgaltpath" fi if [ "$cfgprio" -gt "$found_prio" ]; then found_prio="$cfgprio" found_prio_altpath="$cfgaltpath" fi } find_path() { local cfg="$1" local prio="$2" local path="$3" local altpath="$4" local cfgpath config_get cfgpath "$cfg" path [ "$cfgpath" = "$path" ] || return found_section="$cfg" config_list_foreach "$cfg" altpath find_altpath "$cfg" "$prio" "$altpath" } cmd_update() { local spec="$1" local prio path altpath local oIFS="$IFS" local found_section found_altpath local found_prio=-1 found_prio_altpath IFS=:; set -- $spec; IFS="$oIFS" prio="$1" path="$2" altpath="$3" check_path "$path" if [ ! -e "${IPKG_INSTROOT}$altpath" ]; then errmsg "$altpath does not exist" return 1 fi config_load opkg config_foreach find_path alternatives "$prio" "$path" "$altpath" if [ -z "$found_section" ]; then found_section="$(uci_ add opkg alternatives)" uci_ set opkg.$found_section.path=$path fi if [ -n "$found_altpath" ]; then if [ "$found_altpath" != "$prio:$altpath" ]; then # update priority uci_ del_list opkg.$found_section.altpath=$found_altpath uci_ add_list opkg.$found_section.altpath=$prio:$altpath fi else uci_ add_list opkg.$found_section.altpath=$prio:$altpath fi uci_ commit opkg update_path "$path" } cmd_remove() { local spec="$1" local prio path altpath local oIFS="$IFS" local found_section found_altpath local found_prio=-1 found_prio_altpath IFS=:; set -- $spec; IFS="$oIFS" prio="$1" path="$2" altpath="$3" check_path "$path" config_load opkg config_foreach find_path alternatives "$prio" "$path" "$altpath" if [ -n "$found_section" -a -n "$found_altpath" ]; then uci_ del_list opkg.$found_section.altpath=$found_altpath uci_ commit opkg update_path "$path" else errmsg "spec $spec not found" fi } . ${IPKG_INSTROOT}/lib/functions.sh UCI="${UCI:-/sbin/uci}" UCI_STATE_DIR="${IPKG_INSTROOT}/var/state" ARG_CMD= ARG_SPEC= while [ "$#" -gt 0 ]; do case "$1" in update|remove) ARG_CMD="$1" shift ;; --spec) ARG_SPEC="$2"; shift 2 ;; *) usage ;; esac done [ -n "$ARG_CMD" -a -n "$ARG_SPEC" ] || usage cmd_$ARG_CMD "$ARG_SPEC"