#!/bin/sh
#
# $XORP: xorp/utils/xrl_shell_lib.sh,v 1.7 2006/04/28 01:02:14 pavlin Exp $
#
#
# Library of functions to sent XRL and process the result.
#
#set -x
CALLXRL="../libxipc/call_xrl"
XRL_VARIABLE_SEPARATOR="\&"
#
# Test if the return result of an XRL contains a particular variable
#
# Usage: has_xrl_variable <xrl_result> <xrl_variable:xrl_type>
#
# Return 0 if the XRL contains the variable, otherwise return 1.
#
has_xrl_variable()
{
if [ $# -lt 2 ] ; then
echo "Usage: $0 <xrl_result> <xrl_variable:xrl_type>"
exit 1
fi
_xrl_result="$1"
_xrl_variable_xrl_type="$2"
echo "${_xrl_result}" | \
awk -F"${XRL_VARIABLE_SEPARATOR}" -v xrl_variable_xrl_type="${_xrl_variable_xrl_type}" '
# AWK CODE STARTS
# XXX: do NOT put single quotas in the awk code below, otherwise
# it may not work!!
#
# The code assumes that in the command line there are the following options:
# -F"${XRL_VARIABLE_SEPARATOR}"
# to specify the XRL variable separator (e.g, "\&")
#
# -v xrl_variable_xrl_type="${_xrl_variable_xrl_type}"
# to specify the variable name and type
BEGIN {
found = 0;
}
{
for (i = 1; i <= NF; i++) {
j = split($i, a, "=");
if (j < 1) {
continue;
}
if (a[1] == xrl_variable_xrl_type) {
found = 1; # FOUND
break;
}
}
}
END {
if (found) {
exit 0;
} else {
exit 1;
}
}
# AWK CODE END
'
return $?
}
#
# Get the value of an variable from an XRL.
#
# Usage: get_xrl_variable_value <xrl_result> <xrl_variable:xrl_type>
#
# Return the XRL variable value.
#
get_xrl_variable_value()
{
if [ $# -lt 2 ] ; then
echo "Usage: $0 <xrl_result> <xrl_variable:xrl_type>"
exit 1
fi
_xrl_result="$1"
_xrl_variable_xrl_type="$2"
echo "${_xrl_result}" | \
awk -F"${XRL_VARIABLE_SEPARATOR}" -v xrl_variable_xrl_type="${_xrl_variable_xrl_type}" '
# AWK CODE STARTS
# XXX: do NOT put single quotas in the awk code below, otherwise
# it may not work!!
#
# Assume that there is in the command line
# -F"${XRL_VARIABLE_SEPARATOR}"
# to specify the XRL variable separator (e.g, "\&")
#
# -v xrl_variable_xrl_type="${_xrl_variable_xrl_type}"
# to specify the variable name and type
BEGIN {
found = 0;
value = "";
}
{
for (i = 1; i <= NF; i++) {
j = split($i, a, "=");
if (j < 1) {
continue;
}
if (a[1] == xrl_variable_xrl_type) {
if (j >= 0) {
# Non-empty value
found = 1;
# Concatenate the result in case it was a list
value = "";
for (k = 2; k <= j; k++) {
value = value "" a[k];
if (k < j)
value = value "=";
}
} else {
# Empty value
found = 1;
}
break; # FOUND
}
}
}
END {
print value;
if (found) {
exit 0;
} else {
exit 1; # NOT FOUND: shound NOT happen!
}
}
# AWK CODE END
'
}
#
# Split the value of an XRL variable of type ":list" into a list of values
# separated by space.
#
# Usage: split_xrl_list_values <xrl_list_variable> <xrl_list_values_type>
#
# Return the list of values separated by space.
#
split_xrl_list_values()
{
if [ $# -lt 2 ] ; then
echo "Usage: $0 <xrl_list_variable> <xrl_list_values_type>"
exit 1
fi
_xrl_variable="$1"
_xrl_list_values_type="$2"
# Separate the values with space
_list_separator=",:${_xrl_list_values_type}="
_tmp_result=`echo "${_xrl_variable}" | awk -F"${_list_separator}" '{for (i = 1; i <= NF; i++) {printf("%s", $i); if (i < NF) printf(" "); }}'`
# Get rid of the first value-type prefix
_list_separator=":${_xrl_list_values_type}="
echo "${_tmp_result}" | awk -F"${_list_separator}" '{for (i = 1; i <= NF; i++) {printf("%s", $i);}}'
}
#
# Test the return result of an XRL whether the XRL has succeeded.
#
# Usage: test_xrl_result <xrl_result> <xrl_variable:xrl_type> <test-operator> <test-value>
#
# Return 0 if no error, otherwise return 1.
#
test_xrl_result()
{
if [ $# -lt 4 ] ; then
echo "Usage: $0 <xrl_result> <xrl_variable:xrl_type> <test-operator> <test-value>"
exit 1
fi
_xrl_result="$1"
_xrl_variable_xrl_type="$2"
_test_operator="$3"
_test_value="$4"
if [ "X${_xrl_variable_xrl_type}" = "X" ] ; then
# Nothing to test for
return 0
fi
if [ "X${_test_operator}" = "X" ] ; then
_error="missing <test-operator> argument"
echo "ERROR: ${_error}"
return 1
fi
if [ "X${_test_value}" = "X" ] ; then
_error="missing <test-value> argument"
echo "ERROR: ${_error}"
return 1
fi
# Test if the variable was returned
has_xrl_variable "${_xrl_result}" "${_xrl_variable_xrl_type}"
if [ $? -ne 0 ] ; then
_error="cannot find variable type '${_xrl_variable_xrl_type}' inside return string '${_xrl_result}'"
echo "ERROR: ${_error}"
return 1
fi
# Get the return value
_xrl_variable_value=`get_xrl_variable_value "${_xrl_result}" "${_xrl_variable_xrl_type}"`
# Test the return value
if [ "X${_xrl_variable_value}" = "X" ] ; then
_error="cannot find variable value-type '${_xrl_variable_xrl_type}' inside return string '${_xrl_result}'"
echo "ERROR: ${_error}"
return 1
fi
if [ "${_xrl_variable_value}" "${_test_operator}" "${_test_value}" ] ; then
return 0
else
_error="return variable value of '${_xrl_variable_xrl_type}' is '${_xrl_variable_value}', but expected is '${_test_operator} ${_test_value}' inside return string '${_xrl_result}'"
echo "ERROR: ${_error}"
return 1
fi
}
#
# Print the XRL return result
#
# Usage: print_xrl_result [<xrl_result> [<<xrl_variable:xrl_type> | all> ...]]
#
# Options: <xrl_result> The result returned from the XRL.
#
# <<xrl_variable:xrl_type> | all> A list of XRL return variable names
# whose return value to print. If the keyword 'all' is used, the
# return value of all return variables will be print.
# Note: this option can be repeated.
#
# Return 0 if no error, otherwise return 1.
#
print_xrl_result()
{
if [ $# -lt 1 ] ; then
return 0 # Nothing to print
fi
_xrl_result="$1"
shift
while [ $# -gt 0 ] ; do
_print_xrl_variable_xrl_type="$1"
if [ "X${_print_xrl_variable_xrl_type}" != "X" ] ; then
if [ "X${_print_xrl_variable_xrl_type}" = "Xall" ] ; then
# Print all result
echo "${_xrl_result}"
else
_print_xrl_variable_value=`get_xrl_variable_value "${_xrl_result}" "${_print_xrl_variable_xrl_type}"`
if [ "X${_print_xrl_variable_value}" != "X" ] ; then
echo ${_print_xrl_variable_xrl_type}=${_print_xrl_variable_value}
else
_error="${_print_xrl_variable_xrl_type}: NOT FOUND"
echo "ERROR: ${_error}"
return 1
fi
fi
fi
shift
done
return 0
}
#
# Call an XRL.
#
# If necessary to test the return value, keep calling the XRL until success.
#
# Usage: call_xrl_wrapper [-r <max-repeat-number>] [-p <<xrl_variable:xrl_type> | all>] <XRL> [<xrl_variable:xrl_type> <test-operator> <test-value>]
#
# Options: -r <max-repeat-number> The maximum number of tries to call the
# XRL before giving up. If the value is 0, then the XRL will be
# called until success. If this option is omitted, the default
# is to try only once.
#
# -p <<xrl_variable:xrl_type> | all> The XRL return variable name
# whose return value to print. If '-p all' is used, the return
# value of all return variables will be print.
# Note: this option can be repeated more than once.
#
# Return 0 if no error, otherwise return 1.
#
# Example:
# MFEA_TARGET="MFEA_4"
# mfea_enable_vif()
# {
# echo "mfea_enable_vif" $*
# XRL="finder://${MFEA_TARGET}/mfea/0.1/enable_vif?vif_name:txt=$1"
# call_xrl_wrapper -r 0 ${XRL} fail:bool = false
# }
#
#
# XXX: there is latency of 1 second between repeated XRL calls.
#
call_xrl_wrapper()
{
if [ $# -lt 1 ] ; then
echo "Usage: $0 [-r <max-repeat-number>] [-p <<xrl_variable:xrl_type> | all>] <XRL> [<xrl_variable:xrl_type> <test-operator> <test-value>]"
exit 1
fi
_max_repeat_number=1 # Default value: try only once
_print_list_xrl_variable_xrl_type=""
while [ $# -gt 0 ] ; do
case "$1" in
-r ) # [-r <max-repeat-number>]
if [ $# -lt 2 ] ; then
echo "Usage: call_xrl_wrapper [-r <max-repeat-number>] <<xrl_variable:xrl_type> | all>] <XRL> [<xrl_variable:xrl_type> <test-operator> <test-value>]"
exit 1
fi
shift
_max_repeat_number=$1
;;
-p ) # [-p <<xrl_variable:xrl_type> | all>]
if [ $# -lt 2 ] ; then
echo "Usage: call_xrl_wrapper [-r <max-repeat-number>] <<xrl_variable:xrl_type> | all>] <XRL> [<xrl_variable:xrl_type> <test-operator> <test-value>]"
exit 1
fi
shift
_print_list_xrl_variable_xrl_type="${_print_list_xrl_variable_xrl_type} $1"
;;
* ) # Default case
break
;;
esac
shift
done
if [ $# -lt 1 ] ; then
echo "Usage: call_xrl_wrapper [-r <max-repeat-number>] <<xrl_variable:xrl_type> | all>] <XRL> [<xrl_variable:xrl_type> <test-operator> <test-value>]"
exit 1
fi
_xrl="$1"
# Note: the values below may be empty
_xrl_variable_xrl_type="$2"
_test_operator="$3"
_test_value="$4"
if [ "X${_xrl_variable_xrl_type}" != "X" ] ; then
if [ "X${_test_operator}" = "X" ] ; then
echo "ERROR: missing <test-operator> argument"
exit 1
fi
if [ "X${_test_value}" = "X" ] ; then
echo "ERROR: missing <test-value> argument"
exit 1
fi
fi
# Initialize the iterator
if [ "${_max_repeat_number}" -eq 0 ] ; then
_iter=-1
else
_iter=0
fi
while [ true ] ; do
_xrl_result=`"${CALLXRL}" "${_xrl}"`
_ret_value=$?
if [ ${_ret_value} -ne 0 ] ; then
_error="failure calling '${CALLXRL} ${_xrl}'"
echo "ERROR: ${_error}"
fi
if [ ${_ret_value} -eq 0 -a "X${_test_operator}" != "X" -a "X${_test_value}" != "X" ] ; then
test_xrl_result "${_xrl_result}" "${_xrl_variable_xrl_type}" "${_test_operator}" "${_test_value}"
_ret_value=$?
fi
if [ ${_ret_value} -eq 0 ] ; then
print_xrl_result ${_xrl_result} ${_print_list_xrl_variable_xrl_type}
_ret_value=$?
if [ ${_ret_value} -ne 0 ] ; then
_error="failure printing '${_print_list_xrl_variable_xrl_type}'"
echo "ERROR: ${_error}"
else
# OK
break;
fi
fi
if [ "${_max_repeat_number}" -ne 0 ] ; then
_iter=$((${_iter}+1))
fi
if [ ${_iter} -ge ${_max_repeat_number} ] ; then
echo "ERROR: reached maximum number of trials. Giving-up..."
return 1
fi
echo "Trying again..."
sleep 1
done
return 0
}
# Local Variables:
# mode: shell-script
# sh-indentation: 4
# End:
syntax highlighted by Code2HTML, v. 0.9.1