|
#!/bin/bash
|
|
|
|
ALLSCRIPTS="/etc/runvdr"
|
|
ACTIVESCRIPTS="/etc/runvdr/conf.d"
|
|
LINKREL="../"
|
|
|
|
#####################
|
|
# OSDServer helpers #
|
|
#####################
|
|
|
|
# convenient return values
|
|
true=0
|
|
false=1
|
|
|
|
function error() {
|
|
# Fatal error. Send quit command, close FIFO and terminate netcat
|
|
[ "${reply2xx[0]}" != 202 ] && SendCmd Quit
|
|
|
|
exec 3>&-
|
|
exec 4>&-
|
|
|
|
kill $pid
|
|
|
|
exit 1
|
|
}
|
|
|
|
function ConnectServer() {
|
|
# Connect to the OSDServer
|
|
|
|
# Set up temporary fifo and open as file descriptor 3 and 4
|
|
mkfifo --mode=700 /tmp/pipe-in$$ /tmp/pipe-out$$
|
|
exec 3<> /tmp/pipe-in$$
|
|
exec 4<> /tmp/pipe-out$$
|
|
rm /tmp/pipe-in$$ /tmp/pipe-out$$
|
|
|
|
# Connect to server using the fifo
|
|
{
|
|
netcat $1 $2
|
|
|
|
# In case of connection loss:
|
|
echo 499 disconnected
|
|
echo 202 Good Bye.
|
|
} <&3 >&4 &
|
|
pid=$!
|
|
|
|
# Sending to the server: use >&3
|
|
# Receive from the server: use <&4
|
|
}
|
|
|
|
|
|
function ReadReply() {
|
|
# Read a complete server reply until 2xx return code,
|
|
# and store replies in each category by number
|
|
reply2xx=()
|
|
reply3xx=()
|
|
reply4xx=()
|
|
reply5xx=()
|
|
reply6xx=()
|
|
|
|
while read -r code line <&4 ; do
|
|
if [ "$OSDSERVER_DEBUG" ] ; then echo "< $code $line" ; fi
|
|
# screen echo
|
|
|
|
case $code in
|
|
2*) IFS=$' \t\n\r' reply2xx=($code "$line")
|
|
;;
|
|
3*) IFS=$' \t\n\r' reply3xx=($code $line)
|
|
;;
|
|
4*) IFS=$' \t\n\r' reply4xx=($code "$line")
|
|
;;
|
|
5*) IFS=$' \t\n\r' reply5xx=($code "$line")
|
|
;;
|
|
6*) IFS=$' \t\n\r' reply6xx=($code "$line")
|
|
;;
|
|
esac
|
|
[ -n "${reply2xx[0]}" ] && break
|
|
done
|
|
|
|
[ -n "${reply4xx[0]}" ] && return $false
|
|
return $true
|
|
}
|
|
|
|
function SendCmd() {
|
|
# Send a command and read the reply
|
|
|
|
if [ "$OSDSERVER_DEBUG" ] ; then echo "> $*" ; fi
|
|
# screen echo
|
|
|
|
echo "$*" >&3
|
|
# network send
|
|
|
|
ReadReply
|
|
}
|
|
|
|
function IsEvent() {
|
|
# Helper to check reply for a certain event
|
|
|
|
[ "${reply3xx[0]}" != 300 ] && return $false
|
|
[ "${reply3xx[1]}" != "$1" ] && return $false
|
|
[ "${reply3xx[2]}" != "$2" ] && return $false
|
|
|
|
return $true
|
|
}
|
|
|
|
|
|
function QuoteString() {
|
|
# Quote arbitrary string for use in '' and ""
|
|
local str="${!1}"
|
|
|
|
str="${str//'\'/\\\\}"
|
|
str="${str//'\\'/\\\\}"
|
|
# work around bash bug: double quoted '\'
|
|
|
|
str="${str//\'/$'\\\''}"
|
|
# This is bogus, anyone knows something better to replace ' by \' ?
|
|
|
|
str="${str//\"/\\\"}"
|
|
str="${str//$'\r'/\\r}"
|
|
str="${str//$'\n'/\\n}"
|
|
str="${str//$'\t'/\\t}"
|
|
|
|
eval "$1=\$str"
|
|
}
|
|
|
|
function UnquoteString() {
|
|
# Unquote string
|
|
local str="${!1}"
|
|
|
|
str="${str//\\r/$'\r'}"
|
|
str="${str//\\n/$'\n'}"
|
|
str="${str//\\t/$'\t'}"
|
|
str="${str//\\\"/\"}"
|
|
str="${str//\\\'/\'}"
|
|
str="${str//\\\\/\\}"
|
|
|
|
eval "$1=\$str"
|
|
}
|
|
|
|
#########################
|
|
# runvdr-conf.d helpers #
|
|
#########################
|
|
|
|
function GetConfInfo() {
|
|
name=""
|
|
defaultprio=50
|
|
loaded=""
|
|
local tmp
|
|
|
|
if [ ! -f "$ALLSCRIPTS/$1" ] ; then
|
|
return 1
|
|
fi
|
|
while read -r line ; do
|
|
tmp="${line#\# Plugin name:}"
|
|
if [ "$tmp" != "$line" ] ; then
|
|
name="${tmp# }"
|
|
fi
|
|
tmp="${line#\# Default priority:}"
|
|
if [ "$tmp" != "$line" ] ; then
|
|
tmp="${tmp#\# Default priority:}"
|
|
while [ "${tmp# }" != "$tmp" ] ; do tmp="${tmp# }" ; done
|
|
while [ "${tmp% }" != "$tmp" ] ; do tmp="${tmp% }" ; done
|
|
if [ -z "${tmp#[0-9]}" ] ; then tmp="0$tmp" ; fi
|
|
if [ -z "${tmp#[0-9][0-9]}" ] ; then
|
|
defaultprio="$tmp"
|
|
fi
|
|
fi
|
|
done < "$ALLSCRIPTS/$1"
|
|
if [ -z "$name" ] ; then
|
|
return 1
|
|
fi
|
|
|
|
tmp=("$ACTIVESCRIPTS"/[0-9][0-9]"$1")
|
|
tmp="${tmp[0]}"
|
|
if [ -f "$tmp" ] ; then
|
|
tmp="${tmp:${#ACTIVESCRIPTS}+1}"
|
|
loaded="${tmp:0:2}"
|
|
fi
|
|
|
|
return 0
|
|
}
|
|
|
|
function GetAllConfInfo() {
|
|
local glob="*"
|
|
if [ "$1" ] ; then glob="$1" ; fi
|
|
confs=0
|
|
confs_short=()
|
|
confs_name=()
|
|
confs_defaultprio=()
|
|
confs_loaded=()
|
|
local i
|
|
for i in "$ALLSCRIPTS"/$glob ; do
|
|
i="${i:${#ALLSCRIPTS}+1}"
|
|
if [ -f "$ALLSCRIPTS/$i" ] && GetConfInfo "$i" ; then
|
|
confs_short[$confs]="$i"
|
|
confs_name[$confs]="$name"
|
|
confs_defaultprio[$confs]="$defaultprio"
|
|
confs_loaded[$confs]="$loaded"
|
|
let confs++
|
|
fi
|
|
done
|
|
}
|
|
|
|
|
|
function Command_Show() {
|
|
GetAllConfInfo "$1"
|
|
|
|
local i;
|
|
for ((i=0;i<confs;i++)) ; do
|
|
if [ $i -ne 0 ] ; then
|
|
echo
|
|
fi
|
|
echo "Plugin short name: ${confs_short[i]}"
|
|
echo "Plugin long name : ${confs_name[i]}"
|
|
echo "Default priority : ${confs_defaultprio[i]}"
|
|
echo "Loaded priority : ${confs_loaded[i]:---}"
|
|
done
|
|
}
|
|
|
|
function Command_Enable() {
|
|
short="$1"
|
|
if [ -z "$short" ] ; then
|
|
echo "Usage: $0 enable conf-name [--prio #]"
|
|
exit 1
|
|
fi
|
|
GetConfInfo "$short" || { echo "Unknown Plugin $short" >&2 ; exit 1 ; }
|
|
newloaded="$loaded"
|
|
if [ -z "$newloaded" ] ; then
|
|
newloaded="$defaultprio"
|
|
fi
|
|
|
|
if [ "$2" == "--prio" ] ; then
|
|
newloaded="$3"
|
|
while [ "${newloaded# }" != "$newloaded" ] ; do newloaded="${newloaded# }" ; done
|
|
while [ "${newloaded% }" != "$newloaded" ] ; do newloaded="${newloaded% }" ; done
|
|
if [ -z "${newloaded#[0-9]}" ] ; then newloaded="0$newloaded" ; fi
|
|
if [ "${newloaded#[0-9][0-9]}" ] ; then
|
|
echo "Not a valid priority: $3" >&2
|
|
exit 1
|
|
fi
|
|
fi
|
|
echo -n "Enabling $name"
|
|
mkdir -p "$ACTIVESCRIPTS"
|
|
if [ "$loaded" ] ; then
|
|
rm -f "$ACTIVESCRIPTS"/[0-9][0-9]"$short"
|
|
fi
|
|
ln -s "$LINKREL$short" "$ACTIVESCRIPTS/$newloaded$short"
|
|
echo "."
|
|
}
|
|
|
|
function Command_Disable() {
|
|
short="$1"
|
|
if [ -z "$short" ] ; then
|
|
echo "Usage: $0 disable conf-name"
|
|
exit 1
|
|
fi
|
|
GetConfInfo "$short" || { echo "Unknown Plugin $short" >&2 ; exit 1 ; }
|
|
if [ -z "$loaded" ] ; then
|
|
echo "$short is not loaded." >&2
|
|
exit 1
|
|
fi
|
|
echo -n "Disabling $name"
|
|
rm -f "$ACTIVESCRIPTS"/[0-9][0-9]"$short"
|
|
echo "."
|
|
}
|
|
|
|
function Osdserver_edit() {
|
|
local short="${confs_short[$1]}"
|
|
QuoteString short
|
|
local name="${confs_name[$1]}"
|
|
QuoteString name
|
|
local defaultprio="${confs_defaultprio[$1]}"
|
|
local loaded="${confs_loaded[$1]}"
|
|
local enable="Yes"
|
|
if [ -z "$loaded" ] ; then
|
|
enable="No"
|
|
loaded="$defaultprio"
|
|
fi
|
|
|
|
SendCmd "enterlocal" || return $false
|
|
# Preserve global variable space, so we can re-use 'menu'
|
|
|
|
SendCmd "menu=New Menu 'Edit $name'" || return $false
|
|
SendCmd "menu.SetColumns 15" || return $false
|
|
SendCmd "menu.EnableEvent keyOk close" || return $false
|
|
|
|
SendCmd "menu.AddNew OsdItem -unselectable 'Short name:\\t$short'" || return $false
|
|
|
|
SendCmd "menu.AddNew OsdItem -unselectable 'Long name:\\t$name'" || return $false
|
|
|
|
SendCmd "menu.AddNew OsdItem -unselectable 'Default priority:\\t$defaultprio'" || return $false
|
|
|
|
SendCmd "enable=menu.AddNew EditListItem 'Enabled' No Yes -SelectName '$enable'" || return $false
|
|
SendCmd "enable.SetCurrent" || return $false
|
|
|
|
SendCmd "prio=menu.AddNew EditIntItem 'Current priority' -min 0 -max 99 '$loaded'" || return $false
|
|
|
|
SendCmd "_focus.addsubmenu menu" || return $false
|
|
SendCmd "menu.Show" || return $false
|
|
|
|
while true; do
|
|
SendCmd "menu.SleepEvent" || return $false
|
|
|
|
if IsEvent menu keyOk ; then
|
|
SendCmd "enable.GetValue -name" || return $false
|
|
[ "${reply6xx[0]}" != 600 ] && return $false
|
|
enable="${reply6xx[1]}"
|
|
|
|
SendCmd "prio.GetValue" || return $false
|
|
[ "${reply5xx[0]}" != 500 ] && return $false
|
|
prio="${reply5xx[1]}"
|
|
|
|
if [ "$enable" == "Yes" ] ; then
|
|
Command_Enable "$short" --prio "$prio"
|
|
confs_loaded[$1]="$prio"
|
|
elif [ -n "${confs_loaded[$1]}" ] ; then
|
|
Command_Disable "$short"
|
|
confs_loaded[$1]=""
|
|
fi
|
|
|
|
SendCmd "menu.SendState osBack" || return $false
|
|
SendCmd "delete menu" || return $false
|
|
SendCmd "leavelocal" || return $false
|
|
|
|
return $true
|
|
fi
|
|
if IsEvent menu close ; then
|
|
SendCmd "delete menu" || return $false
|
|
SendCmd "leavelocal" || return $false
|
|
return $true
|
|
fi
|
|
done
|
|
}
|
|
|
|
function Osdserver_main() {
|
|
SendCmd "menu=New Menu 'Runvdr config'" || return $false
|
|
SendCmd "menu.SetColumns 5" || return $false
|
|
SendCmd "menu.EnableEvent close" || return $false
|
|
|
|
local i;
|
|
local min=0
|
|
local prio
|
|
until [ "$min" -ge 100 ] ; do
|
|
local nextmin=100
|
|
for ((i=0;i<confs;i++)) ; do
|
|
prio="${confs_defaultprio[i]}"
|
|
if [ -n "${confs_loaded[i]}" ] ; then prio=${confs_loaded[i]} ; fi
|
|
|
|
if [ "$prio" -eq "$min" ] ; then
|
|
SendCmd "conf$i=menu.AddNew OsdItem '${confs_loaded[i]:---}\t${confs_name[i]}'" || return $false
|
|
SendCmd "conf$i.EnableEvent keyOk" || return $false
|
|
fi
|
|
if [ "$prio" -gt "$min" -a "$prio" -lt "$nextmin" ] ; then
|
|
nextmin="$prio"
|
|
fi
|
|
done
|
|
min="$nextmin"
|
|
done
|
|
|
|
SendCmd "menu.Show" || return $false
|
|
|
|
while true ; do
|
|
SendCmd "menu.SleepEvent" || return $false
|
|
|
|
if IsEvent menu close ; then
|
|
return $true
|
|
fi
|
|
|
|
if [ "${reply3xx[1]:0:4}" == "conf" -a "${reply3xx[2]}" == "keyOk" ] ; then
|
|
i="${reply3xx[1]:4}"
|
|
Osdserver_edit "$i" || return $false
|
|
SendCmd "conf$i.SetText '${confs_loaded[i]:---}\t${confs_name[i]}'" || return $false
|
|
SendCmd "menu.Show" || return $false
|
|
fi
|
|
done
|
|
}
|
|
|
|
function Osdserver_connect() {
|
|
GetAllConfInfo
|
|
|
|
ConnectServer localhost 2010
|
|
# Connect to the server process
|
|
|
|
ReadReply || error
|
|
# Read server welcome
|
|
|
|
SendCmd "Version 0.1" || error
|
|
# Identify to server with protocol version
|
|
|
|
Osdserver_main || error
|
|
# Main menu
|
|
|
|
SendCmd Quit
|
|
# ... and good bye
|
|
|
|
exec 3>&-
|
|
exec 4>&-
|
|
# close FIFOs
|
|
}
|
|
|
|
function Command_Osdserver() {
|
|
if [ "$1" == "--debug" ] ; then
|
|
OSDSERVER_DEBUG=1
|
|
Osdserver_connect
|
|
else
|
|
Osdserver_connect </dev/null >/dev/null &
|
|
fi
|
|
}
|
|
|
|
if [ "$1" == "show" ] ; then
|
|
shift
|
|
Command_Show "$@"
|
|
elif [ "$1" == "enable" ] ; then
|
|
shift
|
|
Command_Enable "$@"
|
|
elif [ "$1" == "disable" ] ; then
|
|
shift
|
|
Command_Disable "$@"
|
|
elif [ "$1" == "osdserver" ] ; then
|
|
shift
|
|
Command_Osdserver "$@"
|
|
elif [ "$1" == "" -o "$1" == "help" ] ; then
|
|
cat << "ENDOFTEXT"
|
|
Supported commands:
|
|
runvdr-conf.d show [conf-name]
|
|
Show current config for one or all plugins
|
|
runvdr-conf.d enable conf-name [--prio #]
|
|
Enable a plugin
|
|
runvdr-conf.d disable conf-name
|
|
Disable a plugin
|
|
runvdr-conf.d osdserver
|
|
Launch osdserver interface
|
|
runvdr-conf.d help
|
|
This help
|
|
ENDOFTEXT
|
|
else
|
|
echo "Unknown command: $1" >&2
|
|
fi
|