-
Notifications
You must be signed in to change notification settings - Fork 62
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
eva_tools: add a variant of 'eva_switch_system', which doesn't rely o…
…n discovery
- Loading branch information
Showing
1 changed file
with
237 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,237 @@ | ||
#! /bin/sh | ||
# SPDX-License-Identifier: GPL-2.0-or-later | ||
# check if incompatible shell is used, this will cause issues, so we rather exit | ||
if ! ( printf "\n" | read -u 0 2>/dev/null ); then | ||
echo "wrong shell interpreter" 1>&2 | ||
exit 1 | ||
fi | ||
# | ||
[ ${#1} -eq 0 -o ${#2} -ne 0 ] && echo "Calling: $0 <ip address of the box>" 2>&1 && exit 1 | ||
# | ||
# some constants to be changed, if needed | ||
# | ||
box_ip="$1" | ||
box_port=21 | ||
box_user=adam2 | ||
box_pass=adam2 | ||
passive_ftp="P@SW" | ||
[ ${#TMP} -eq 0 ] && TMP=/tmp | ||
tmpdir=$TMP/tmp_$(date +%s)_$$ | ||
writefifo=$tmpdir/write | ||
readfifo=$tmpdir/read | ||
storefifo=$tmpdir/store | ||
outstream=7 | ||
instream=8 | ||
upstream=9 | ||
logstream=3 | ||
logfile=eva_switch_system_no_discovery.log | ||
# | ||
# helper functions | ||
# | ||
read_ftp_response() | ||
{ | ||
local line=" -" rc=0 instream="$1" log="$2" lines="" | ||
while read -u $instream -r line; do | ||
[ ! -z "$log" ] && echo "$line" >&$log | ||
number="${line:0:3}" | ||
number="${number//[0-9]/}" | ||
if [ ${#number} -eq 0 -a "${line:3:1}" == " " ]; then | ||
if [ ${#lines} -gt 0 ]; then | ||
echo -e "$lines\n$line" | ||
else | ||
echo "$line" | ||
fi | ||
break | ||
fi | ||
lines="$(echo -e "$lines${lines:+\n}$line")" | ||
done | ||
return $rc | ||
} | ||
write_ftp_command() | ||
{ | ||
local outstream="$2" cmd="$1" log="$3" | ||
[ ! -z "$log" ] && echo "$cmd" >&$log | ||
echo "$cmd" >&$outstream | ||
} | ||
login_to_box() | ||
{ | ||
local instream="$1" outstream="$2" log="$3" lines=0 | ||
write_ftp_command "USER $box_user" $outstream $log | ||
while [ $lines -lt 10 ]; do | ||
line="$(read_ftp_response $instream $log)" | ||
ec="${line:0:3}" | ||
if [ x"$ec" == x"331" ]; then | ||
write_ftp_command "PASS $box_pass" $outstream $log | ||
else | ||
if [ x"$ec" == x"230" ]; then | ||
return 0 | ||
elif [ x"$ec" == x"530" ]; then | ||
return 1 | ||
fi | ||
fi | ||
lines=$(( lines++ )) | ||
done | ||
} | ||
get_environment_value() | ||
{ | ||
local instream="$1" outstream="$2" log="$3" lines=0 name="$4" | ||
write_ftp_command "GETENV $name" $outstream $log | ||
lines="$(read_ftp_response $instream $log)" | ||
echo "$lines" | while read line; do | ||
if [ "${line:0:3}" == "200" ]; then | ||
echo "$lines" | sed -e "s|\r||" | sed -n -e "s|^$name *\(.*\)\$|\1|p" | ||
return 0 | ||
fi | ||
done | ||
return $? | ||
} | ||
set_environment_value() | ||
{ | ||
local instream="$1" outstream="$2" log="$3" lines=0 name="$4" value="$5" | ||
if [ ${#value} -gt 0 ]; then | ||
write_ftp_command "SETENV $name $value" $outstream $log | ||
else | ||
write_ftp_command "UNSETENV $name" $outstream $log | ||
fi | ||
line="$(read_ftp_response $instream $log)" | ||
ec="${line:0:3}" | ||
[ x"$ec" == x"200" ] && return 0 || return 1 | ||
} | ||
# | ||
# check, if "mkfifo" and "nc" are present and usable | ||
# | ||
mkfifo 2>/dev/null | ||
if [ $? -eq 127 ]; then | ||
echo "Missing usable 'mkfifo' command." | ||
exit 1 | ||
fi | ||
command -v nc 2>/dev/null 1>&2 | ||
if [ $? -ne 0 ]; then | ||
echo "Missing any 'nc' command, it's needed for network communication and the OpenBSD version is required." | ||
exit 1 | ||
fi | ||
# there's no unique identity for the BSD version, so we check for GNU version here | ||
nc -V 2>/dev/null | grep -q GNU | ||
if [ $? -eq 0 ]; then | ||
echo "Found GNU version of 'nc' command, but the OpenBSD version is required." | ||
exit 1 | ||
fi | ||
# | ||
# build redirections for FTP with "nc" | ||
# | ||
mkdir -p $tmpdir | ||
mkfifo $writefifo | ||
rc=$? | ||
if [ $rc -ne 0 ]; then | ||
echo "Error $rc creating write fifo $writefifo." | ||
rm -r $tmpdir | ||
exit 1 | ||
fi | ||
mkfifo $readfifo | ||
rc=$? | ||
if [ $rc -ne 0 ]; then | ||
echo "Error $rc creating read fifo $readfifo." | ||
rm $writefifo | ||
rm -r $tmpdir | ||
exit 1 | ||
fi | ||
mkfifo $storefifo | ||
rc=$? | ||
if [ $rc -ne 0 ]; then | ||
echo "Error $rc creating upload fifo $storefifo." | ||
rm $writefifo | ||
rm $readfifo | ||
rm -r $tmpdir | ||
exit 1 | ||
fi | ||
eval "exec $outstream<>$writefifo" | ||
rc=$? | ||
if [ $rc -ne 0 ]; then | ||
echo "Error $rc connecting write fifo to output stream." | ||
rm $writefifo | ||
rm $readfifo | ||
rm $storefifo | ||
rm -r $tmpdir | ||
exit 1 | ||
fi | ||
eval "exec $instream<>$readfifo" | ||
rc=$? | ||
if [ $rc -ne 0 ]; then | ||
echo "Error $rc connecting read fifo to input stream." | ||
eval "exec $outstream>&-" | ||
rm $writefifo | ||
rm $readfifo | ||
rm $storefifo | ||
rm -r $tmpdir | ||
exit 1 | ||
fi | ||
eval "exec $logstream<>$logfile" | ||
rc=$? | ||
if [ $rc -ne 0 ]; then | ||
echo "Error $rc connecting log stream to log file." | ||
eval "exec $instream>&-" | ||
eval "exec $outstream>&-" | ||
rm $writefifo | ||
rm $readfifo | ||
rm $storefifo | ||
rm -r $tmpdir | ||
exit 1 | ||
fi | ||
# | ||
# now open a connection to the box | ||
# | ||
nc $box_ip $box_port <&$outstream >&$instream 2>/dev/null & | ||
control_connection=$! | ||
data_connection="" | ||
line="$(read_ftp_response $instream $logstream)" | ||
ec="${line:0:3}" | ||
if [ x"$ec" == x"220" ]; then | ||
login_to_box $instream $outstream $logstream | ||
if [ $? -eq 0 ]; then | ||
write_ftp_command "SYST" $outstream $logstream | ||
line="$(read_ftp_response $instream $logstream)" | ||
ec="${line:0:3}" | ||
if [ x"$ec" == x"215" ]; then | ||
syst=$(echo "$line" | sed -n -e "s/.*\(AVM EVA\).*/\1/p") | ||
if [ ${#syst} -ne 0 ]; then | ||
echo "Found AVM bootloader: ${line:4}" | ||
current=$(get_environment_value $instream $outstream $logstream "linux_fs_start") | ||
if [ $? -eq 0 ]; then | ||
echo "Current system selected: $current" | ||
new=$(( ( current + 1 ) % 2 )) | ||
echo "New system selected: $new" | ||
set_environment_value $instream $outstream $logstream "linux_fs_start" "$new" | ||
if [ $? -eq 0 ]; then | ||
echo "New value set, rebooting the device ..." | ||
write_ftp_command "REBOOT" $outstream $logstream | ||
fi | ||
fi | ||
else | ||
echo "Unexpected system found: ${line:4}" | ||
fi | ||
fi | ||
else | ||
echo "Login failed." | ||
fi | ||
else | ||
echo "Error connecting to FRITZ!Box boot loader." | ||
fi | ||
if [ ${#data_connection} -ne 0 ]; then | ||
if [ -d /proc/$data_connection ]; then | ||
kill $data_connection 2>/dev/null & | ||
wait $data_connection 2>/dev/null | ||
fi | ||
fi | ||
if [ ${#control_connection} -ne 0 ]; then | ||
if [ -d /proc/$control_connection ]; then | ||
kill $control_connection 2>/dev/null & | ||
wait $control_connection 2>/dev/null | ||
fi | ||
fi | ||
eval "exec $logstream>&-" | ||
eval "exec $instream>&-" | ||
eval "exec $outstream>&-" | ||
rm $writefifo | ||
rm $readfifo | ||
rm -r $tmpdir | ||
exit 1 |