mirror of
https://github.com/pocopico/tinycore-redpill.git
synced 2025-09-15 12:51:13 +08:00
1480 lines
50 KiB
Bash
1480 lines
50 KiB
Bash
#!/bin/sudo bash
|
|
|
|
#. ./rploader.sh
|
|
|
|
###### VARIABLES
|
|
|
|
HOMEPATH="/home/tc"
|
|
TEMPPAT="${HOMEPATH}/temppat"
|
|
CONFIGFILES="${HOMEPATH}/redpill-load/config"
|
|
PATCHEXTRACTOR="${HOMEPATH}/patch-extractor"
|
|
THISURL="index.sh"
|
|
BUILDLOG="/home/tc/html/buildlog.txt"
|
|
USERCONFIGFILE="/home/tc/user_config.json"
|
|
|
|
############################################
|
|
|
|
function pagehead() {
|
|
|
|
cat <<EOF
|
|
<!DOCTYPE html>
|
|
<html lang="en">
|
|
<head>
|
|
<meta charset="utf-8">
|
|
<title>Bootstrap, from Twitter</title>
|
|
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
|
<meta name="description" content="">
|
|
<meta name="author" content="">
|
|
|
|
<!-- Le styles -->
|
|
<link href="assets/css/bootstrap.css" rel="stylesheet">
|
|
<style>
|
|
body {
|
|
padding-top: 60px; /* 60px to make the container go all the way to the bottom of the topbar */
|
|
}
|
|
</style>
|
|
<link href="assets/css/bootstrap-responsive.css" rel="stylesheet">
|
|
|
|
|
|
<!-- HTML5 shim, for IE6-8 support of HTML5 elements -->
|
|
<!--[if lt IE 9]>
|
|
<script src="assets/js/html5shiv.js"></script>
|
|
<![endif]-->
|
|
|
|
<!-- Fav and touch icons -->
|
|
<link rel="apple-touch-icon-precomposed" sizes="144x144" href="assets/ico/apple-touch-icon-144-precomposed.png">
|
|
<link rel="apple-touch-icon-precomposed" sizes="114x114" href="assets/ico/apple-touch-icon-114-precomposed.png">
|
|
<link rel="apple-touch-icon-precomposed" sizes="72x72" href="assets/ico/apple-touch-icon-72-precomposed.png">
|
|
<link rel="apple-touch-icon-precomposed" href="assets/ico/apple-touch-icon-57-precomposed.png">
|
|
<link rel="shortcut icon" href="assets/ico/favicon.png">
|
|
</head>
|
|
|
|
<body>
|
|
|
|
EOF
|
|
}
|
|
|
|
function selectmodel() {
|
|
|
|
cat <<EOF
|
|
<form id="myform" method=POST action="/${THISURL}?action=build">
|
|
<select id="mymodel" name="mymodel">
|
|
EOF
|
|
echo "<option value=\"'Please Select Model\">Select Model</option>"
|
|
#for model in `getPlatforms`
|
|
for model in $(ls ${CONFIGFILES} | grep -v comm | sed -e 's/\///'); do
|
|
echo "<option value=\"'$model\">$model</option>"
|
|
done
|
|
cat <<EOF
|
|
</select>
|
|
</form>
|
|
<div id="output"></div>
|
|
EOF
|
|
|
|
}
|
|
|
|
function selectversion() {
|
|
|
|
cat <<EOF
|
|
<form id="myversion" method=POST action="/${THISURL}?action=build&mymodel=$MODEL&myversion=$VERSION">
|
|
<label for="mymodel">Model</label>
|
|
<input id="mymodel" name="mymodel" value="$MODEL" required readonly/>
|
|
<label for="myversion">Version</label>
|
|
<select id="myversion" name="myversion">
|
|
EOF
|
|
echo "<option value=\"'Please Select OS Version\">Select version</option>"
|
|
for version in $(ls ${CONFIGFILES}/$MODEL/ | grep -v comm | sed -e 's/\///'); do
|
|
echo "<option value=\"'$version\">$version</option>"
|
|
done
|
|
cat <<EOF
|
|
</select>
|
|
<input id="mymodel" name="mymodel" value="$MODEL" hidden required />
|
|
|
|
</form>
|
|
<div id="output"></div>
|
|
EOF
|
|
|
|
}
|
|
|
|
function urldecode {
|
|
local url_encoded="${1//+/ }"
|
|
printf '%b' "${url_encoded//%/\\x}"
|
|
}
|
|
|
|
function pagebody() {
|
|
cat <<EOF
|
|
|
|
<div class="navbar navbar-inverse bg-dark navbar-fixed-top">
|
|
<div class="navbar-inner">
|
|
<div class="container">
|
|
<button type="button" class="btn btn-navbar" data-toggle="collapse" data-target=".nav-collapse">
|
|
<span class="icon-bar"></span>
|
|
</button>
|
|
<a class="brand" href="${THISURL}?action=none">TinyCore RedPill</a>
|
|
<div class="nav-collapse collapse">
|
|
<ul class="nav">
|
|
<li><a href="/${THISURL}?action=build">Build</a></li>
|
|
<li class="nav-item dropdown">
|
|
<a class="nav-link dropdown-toggle" href="#" id="navbarDropdownMenuLink" data-toggle="dropdown" aria-haspopup="true" aria-expanded="false">
|
|
Additional Actions
|
|
</a>
|
|
<ul class="dropdown-menu">
|
|
<li><a class=" dropdown-item" href="${THISURL}?action=backuploader">Backup Loader</a></li>
|
|
<li><a class=" dropdown-item" href="${THISURL}?action=cleanloader">Clean Loader </a></li>
|
|
<li><a class=" dropdown-item" href="${THISURL}?action=backuploader">Another action</a><li>
|
|
<hr class="dropdown-divider">
|
|
<li><a class="dropdown-item" href="#">Something else here</a></li>
|
|
</ul>
|
|
</li>
|
|
<li><a href="https://github.com/pocopico/tinycore-redpill">Tinycore Redpill Repo</a></li>
|
|
<li><a href="https://xpenology.com/forum/topic/53817-redpill-tinycore-loader/">Contact</a></li>
|
|
</ul>
|
|
|
|
</div><!--/.nav-collapse -->
|
|
</div>
|
|
</div>
|
|
</div>
|
|
<div class="container">
|
|
|
|
<h1>TinyCore Redpill, Version $(version)</h1>
|
|
|
|
EOF
|
|
}
|
|
|
|
function pagefooter() {
|
|
cat <<EOF
|
|
</div> <!-- /container -->
|
|
|
|
<!-- Le javascript
|
|
================================================== -->
|
|
<!-- Placed at the end of the document so the pages load faster -->
|
|
<script type="text/javascript" src="https://ajax.googleapis.com/ajax/libs/jquery/1.9.0/jquery.min.js"></script>
|
|
<script src="https://cdn.jsdelivr.net/gh/xcash/bootstrap-autocomplete@v2.3.7/dist/latest/bootstrap-autocomplete.min.js"></script>
|
|
<script src="https://cdnjs.cloudflare.com/ajax/libs/Chart.js/3.9.1/chart.min.js"></script>
|
|
|
|
|
|
<script src="assets/js/bootstrap-transition.js"></script>
|
|
<script src="assets/js/bootstrap-alert.js"></script>
|
|
<script src="assets/js/bootstrap-modal.js"></script>
|
|
<script src="assets/js/bootstrap-dropdown.js"></script>
|
|
<script src="assets/js/bootstrap-scrollspy.js"></script>
|
|
<script src="assets/js/bootstrap-tab.js"></script>
|
|
<script src="assets/js/bootstrap-tooltip.js"></script>
|
|
<script src="assets/js/bootstrap-popover.js"></script>
|
|
<script src="assets/js/bootstrap-button.js"></script>
|
|
<script src="assets/js/bootstrap-collapse.js"></script>
|
|
<script src="assets/js/bootstrap-carousel.js"></script>
|
|
<script src="assets/js/bootstrap-typeahead.js"></script>
|
|
|
|
|
|
<script>
|
|
\$(document).ready(function() {
|
|
\$('#myform').val("$MODEL");
|
|
\$('#mymodel').change( function() {
|
|
\$('#myform').submit();
|
|
\$.ajax({ // create an AJAX call...
|
|
data: \$(this).serialize(), // get the form data
|
|
type: \$(this).attr('method'), // GET or POST
|
|
url: \$(this).attr('action'), // the file to call
|
|
success: function(response) { // on success..
|
|
\$('#output').html(response); // update the DIV
|
|
}
|
|
});
|
|
return false; // cancel original event to prevent form submitting
|
|
});
|
|
\$('#myversion').val("$VERSION");
|
|
\$('#myversion').change( function() {
|
|
\$('#myversion').submit();
|
|
\$.ajax({ // create an AJAX call...
|
|
data: \$(this).serialize(), // get the form data
|
|
type: \$(this).attr('method'), // GET or POST
|
|
url: \$(this).attr('action'), // the file to call
|
|
success: function(response) { // on success..
|
|
\$('#output').html(response); // update the DIV
|
|
}
|
|
});
|
|
return false; // cancel original event to prevent form submitting
|
|
});
|
|
});
|
|
|
|
function onModelChange() {
|
|
var x = document.getElementById("myModel").value;
|
|
document.getElementById("model").innerHTML = "You selected: " + x;
|
|
}
|
|
|
|
\$('#mybuild input[id=model]').val(input.model).prop('readonly', true);
|
|
|
|
|
|
</script>
|
|
<p id="model"></p>
|
|
|
|
EOF
|
|
|
|
chartinit
|
|
[ "$action" = "build" ] && readlog
|
|
|
|
cat <<EOF
|
|
|
|
</body>
|
|
</html>
|
|
EOF
|
|
|
|
}
|
|
|
|
function serialgen() {
|
|
|
|
[ ! -z "$GATEWAY_INTERFACE" ] && shift 0 || shift 1
|
|
|
|
[ "$2" == "realmac" ] && let keepmac=1 || let keepmac=0
|
|
|
|
if [ "$1" = "DS3615xs" ] || [ "$1" = "DS3617xs" ] || [ "$1" = "DS916+" ] || [ "$1" = "DS918+" ] || [ "$1" = "DS920+" ] || [ "$1" = "DS3622xs+" ] || [ "$1" = "FS6400" ] || [ "$1" = "DVA3219" ] || [ "$1" = "DVA3221" ] || [ "$1" = "DS1621+" ] || [ "$1" = "DVA1622" ] || [ "$1" = "DS2422+" ] || [ "$1" = "RS4021xs+" ] || [ "$1" = "FS6400" ] || [ "$1" = "SA6400" ]; then
|
|
serial="$(generateSerial $1)"
|
|
mac="$(generateMacAddress $1)"
|
|
realmac=$(ifconfig eth0 | head -1 | awk '{print $NF}')
|
|
echo "Serial Number for Model = $serial"
|
|
echo "Mac Address for Model $1 = $mac "
|
|
[ $keepmac -eq 1 ] && echo "Real Mac Address : $realmac"
|
|
[ $keepmac -eq 1 ] && echo "Notice : realmac option is requested, real mac will be used"
|
|
|
|
if [ -z "$GATEWAY_INTERFACE" ]; then
|
|
|
|
echo "Should i update the user_config.json with these values ? [Yy/Nn]"
|
|
read answer
|
|
else
|
|
answer="y"
|
|
fi
|
|
|
|
if [ -n "$answer" ] && [ "$answer" = "Y" ] || [ "$answer" = "y" ]; then
|
|
# sed -i "/\"sn\": \"/c\ \"sn\": \"$serial\"," user_config.json
|
|
json="$(jq --arg var "$serial" '.extra_cmdline.sn = $var' $USERCONFIGFILE)" && echo -E "${json}" | jq . >$USERCONFIGFILE
|
|
|
|
if [ $keepmac -eq 1 ]; then
|
|
macaddress=$(echo $realmac | sed -s 's/://g')
|
|
else
|
|
macaddress=$(echo $mac | sed -s 's/://g')
|
|
fi
|
|
|
|
json="$(jq --arg var "$macaddress" '.extra_cmdline.mac1 = $var' $USERCONFIGFILE)" && echo -E "${json}" | jq . >$USERCONFIGFILE
|
|
# sed -i "/\"mac1\": \"/c\ \"mac1\": \"$macaddress\"," user_config.json
|
|
else
|
|
echo "OK remember to update manually by editing $USERCONFIGFILE file"
|
|
fi
|
|
else
|
|
echo "Error : $1 is not an available model for serial number generation. "
|
|
echo "Available Models : DS3615xs DS3617xs DS916+ DS918+ DS920+ DS3622xs+ FS6400 DVA3219 DVA3221 DS1621+ DVA1622 SA6400"
|
|
fi
|
|
|
|
}
|
|
|
|
function beginArray() {
|
|
|
|
case $1 in
|
|
DS3615xs)
|
|
permanent="LWN"
|
|
serialstart="1130 1230 1330 1430"
|
|
;;
|
|
DS3617xs)
|
|
permanent="ODN"
|
|
serialstart="1130 1230 1330 1430"
|
|
;;
|
|
DS916+)
|
|
permanent="NZN"
|
|
serialstart="1130 1230 1330 1430"
|
|
;;
|
|
DS918+)
|
|
permanent="PDN"
|
|
serialstart="1780 1790 1860 1980"
|
|
;;
|
|
DS920+)
|
|
permanent="SBR"
|
|
serialstart="2030 2040 20C0 2150"
|
|
;;
|
|
DS3622xs+)
|
|
permanent="SQR"
|
|
serialstart="2030 2040 20C0 2150"
|
|
;;
|
|
DS1621+)
|
|
permanent="S7R"
|
|
serialstart="2080"
|
|
;;
|
|
FS6400)
|
|
permanent="PSN"
|
|
serialstart="1960"
|
|
;;
|
|
SA6400)
|
|
permanent="PSN"
|
|
serialstart="1960"
|
|
;;
|
|
DVA3219)
|
|
permanent="RFR"
|
|
serialstart="1930 1940"
|
|
;;
|
|
DVA3221)
|
|
permanent="SJR"
|
|
serialstart="2030 2040 20C0 2150"
|
|
;;
|
|
DVA1622)
|
|
permanent="SJR"
|
|
serialstart="2030 2040 20C0 2150"
|
|
;;
|
|
DS2422+)
|
|
permanent="S7R"
|
|
serialstart="2080"
|
|
;;
|
|
RS4021xs+)
|
|
permanent="SQR"
|
|
serialstart="2030 2040 20C0 2150"
|
|
;;
|
|
esac
|
|
|
|
}
|
|
|
|
function random() {
|
|
|
|
printf "%06d" $(($RANDOM % 30000 + 1))
|
|
|
|
}
|
|
function randomhex() {
|
|
val=$(($RANDOM % 255 + 1))
|
|
echo "obase=16; $val" | bc
|
|
}
|
|
|
|
function generateRandomLetter() {
|
|
for i in a b c d e f g h j k l m n p q r s t v w x y z; do
|
|
echo $i
|
|
done | sort -R | tail -1
|
|
}
|
|
|
|
function generateRandomValue() {
|
|
for i in 0 1 2 3 4 5 6 7 8 9 a b c d e f g h j k l m n p q r s t v w x y z; do
|
|
echo $i
|
|
done | sort -R | tail -1
|
|
}
|
|
|
|
function toupper() {
|
|
echo $1 | tr '[:lower:]' '[:upper:]'
|
|
}
|
|
|
|
function generateMacAddress() {
|
|
#toupper "Mac Address: 00:11:32:$(randomhex):$(randomhex):$(randomhex)"
|
|
printf '00:11:32:%02X:%02X:%02X' $((RANDOM % 256)) $((RANDOM % 256)) $((RANDOM % 256))
|
|
|
|
}
|
|
|
|
function generateSerial() {
|
|
|
|
beginArray $1
|
|
|
|
case $1 in
|
|
|
|
DS3615xs)
|
|
serialnum="$(echo "$serialstart" | tr ' ' '\n' | sort -R | tail -1)$permanent"$(random)
|
|
;;
|
|
DS3617xs)
|
|
serialnum="$(echo "$serialstart" | tr ' ' '\n' | sort -R | tail -1)$permanent"$(random)
|
|
;;
|
|
DS916+)
|
|
serialnum="$(echo "$serialstart" | tr ' ' '\n' | sort -R | tail -1)$permanent"$(random)
|
|
;;
|
|
DS918+)
|
|
serialnum="$(echo "$serialstart" | tr ' ' '\n' | sort -R | tail -1)$permanent"$(random)
|
|
;;
|
|
FS6400)
|
|
serialnum="$(echo "$serialstart" | tr ' ' '\n' | sort -R | tail -1)$permanent"$(random)
|
|
;;
|
|
SA6400)
|
|
serialnum="$(echo "$serialstart" | tr ' ' '\n' | sort -R | tail -1)$permanent"$(random)
|
|
;;
|
|
DS920+)
|
|
serialnum=$(toupper "$(echo "$serialstart" | tr ' ' '\n' | sort -R | tail -1)$permanent"$(generateRandomLetter)$(generateRandomValue)$(generateRandomValue)$(generateRandomValue)$(generateRandomValue)$(generateRandomLetter))
|
|
;;
|
|
DS3622xs+)
|
|
serialnum=$(toupper "$(echo "$serialstart" | tr ' ' '\n' | sort -R | tail -1)$permanent"$(generateRandomLetter)$(generateRandomValue)$(generateRandomValue)$(generateRandomValue)$(generateRandomValue)$(generateRandomLetter))
|
|
;;
|
|
DS1621+)
|
|
serialnum=$(toupper "$(echo "$serialstart" | tr ' ' '\n' | sort -R | tail -1)$permanent"$(generateRandomLetter)$(generateRandomValue)$(generateRandomValue)$(generateRandomValue)$(generateRandomValue)$(generateRandomLetter))
|
|
;;
|
|
DVA3219)
|
|
serialnum=$(toupper "$(echo "$serialstart" | tr ' ' '\n' | sort -R | tail -1)$permanent"$(generateRandomLetter)$(generateRandomValue)$(generateRandomValue)$(generateRandomValue)$(generateRandomValue)$(generateRandomLetter))
|
|
;;
|
|
DVA3221)
|
|
serialnum=$(toupper "$(echo "$serialstart" | tr ' ' '\n' | sort -R | tail -1)$permanent"$(generateRandomLetter)$(generateRandomValue)$(generateRandomValue)$(generateRandomValue)$(generateRandomValue)$(generateRandomLetter))
|
|
;;
|
|
DVA1622)
|
|
serialnum=$(toupper "$(echo "$serialstart" | tr ' ' '\n' | sort -R | tail -1)$permanent"$(generateRandomLetter)$(generateRandomValue)$(generateRandomValue)$(generateRandomValue)$(generateRandomValue)$(generateRandomLetter))
|
|
;;
|
|
DS2422+)
|
|
serialnum=$(toupper "$(echo "$serialstart" | tr ' ' '\n' | sort -R | tail -1)$permanent"$(generateRandomLetter)$(generateRandomValue)$(generateRandomValue)$(generateRandomValue)$(generateRandomValue)$(generateRandomLetter))
|
|
;;
|
|
RS4021xs+)
|
|
serialnum=$(toupper "$(echo "$serialstart" | tr ' ' '\n' | sort -R | tail -1)$permanent"$(generateRandomLetter)$(generateRandomValue)$(generateRandomValue)$(generateRandomValue)$(generateRandomValue)$(generateRandomLetter))
|
|
;;
|
|
esac
|
|
|
|
echo $serialnum
|
|
|
|
}
|
|
|
|
function buildform() {
|
|
|
|
json=$(jq --arg var "$MODEL" '.general.model = $var' $USERCONFIGFILE) && echo -E "${json}" | jq . >$USERCONFIGFILE
|
|
json=$(jq --arg var "$VERSION" '.general.version = $var' $USERCONFIGFILE) && echo -E "${json}" | jq . >$USERCONFIGFILE
|
|
|
|
serialgen "$MODEL" | awk -F= '{print $2}' | sed -e 'N;s/\n/ /' | read serial macaddress
|
|
serialgen "$MODEL" >/dev/null
|
|
|
|
cat <<EOF
|
|
<form id="mybuild" action="/${THISURL}" method="POST">
|
|
<label for="mymodel">Model</label>
|
|
<input id="mymodel" name="mymodel" value="$MODEL" required readonly/>
|
|
<label for="myversion">Version</label>
|
|
<input id="myversion" name="myversion" value="$VERSION" required readonly />
|
|
<label for="serial">Serial</label>
|
|
<input id="serial" name="serial" value="$serial" required />
|
|
<label for="macaddress">Macaddress</label>
|
|
<input id="macaddress" name="macaddress" value="$macaddress" required />
|
|
<label class="form-check-label" for="addexts">Automatically add extensions)</label>
|
|
<input class="form-check-input" type="checkbox" name="addexts" id="addexts" value="auto" checked>
|
|
<label class="form-check-label" for="withfriend">With Friend</label>
|
|
<input class="form-check-input" type="checkbox" name="withfriend" id="withfriend" value="withfriend" checked>
|
|
<input id="action" name="action" value="build" hidden required />
|
|
<input id="buildit" name="buildit" value="yes" hidden required />
|
|
<label for="extracmdline">Extra Command Line Options (e.g SataPortMap, DiskIdxMap etc</label>
|
|
<textarea id="extracmdline" name="extracmdline" value=" "> </textarea>
|
|
|
|
<br><br><button type="submit">Build</button>
|
|
|
|
</form>
|
|
EOF
|
|
checkcached
|
|
|
|
}
|
|
|
|
function checkcached() {
|
|
|
|
patfile="$(find /mnt/sdb3/auxfiles/ | grep -i $OS_ID)"
|
|
#patfile="/mnt/${tcrppart}/auxfiles/sa6400_42962.pat"
|
|
|
|
[ -z "$patfile" ] && patfile="$(find /home/tc/html/ | grep -i $OS_ID)"
|
|
|
|
if [ ! -z "$patfile" ] && [ -f "$patfile" ]; then
|
|
iscached="yes"
|
|
echo "PATFILE for ${MODEL}_${VERSION} is CACHED as file ${patfile}" >>${BUILDLOG}
|
|
else
|
|
iscached="no"
|
|
echo "PATFILE for ${MODEL}_${VERSION} is NOT CACHED" >>${BUILDLOG}
|
|
fi
|
|
|
|
}
|
|
|
|
function getpost() {
|
|
echo ""
|
|
}
|
|
|
|
function startover() {
|
|
|
|
echo "<button type=\"button\" class=\"btn btn-primary btn-lg btn-block\" onclick="window.location.href=\'/${THISURL}\'">START OVER</button>"
|
|
|
|
}
|
|
|
|
function getcontent() {
|
|
|
|
echo "<details>"
|
|
echo "<summary>$1</summary>"
|
|
echo "<pre>$($@)"
|
|
echo "</pre></details>"
|
|
|
|
}
|
|
|
|
function wecho() {
|
|
echo "<br>$@"
|
|
}
|
|
|
|
function recho() {
|
|
|
|
#printf "<div class=\"d-inline p-2 bg-primary text-white\">$@</div>"
|
|
printf "<pre>$@</pre>"
|
|
|
|
}
|
|
|
|
function getvars() {
|
|
|
|
ln -s /lib /lib64
|
|
|
|
tcrppart="$(mount | grep -i optional | grep cde | awk -F / '{print $3}' | uniq | cut -c 1-3)3"
|
|
tcrpdisk="$(mount | grep -i optional | grep cde | awk -F / '{print $3}' | uniq | cut -c 1-3)"
|
|
local_cache="/mnt/${tcrppart}/auxfiles"
|
|
GETTIME=$(curl -v --silent https://google.com/ 2>&1 | grep Date | sed -e 's/< Date: //')
|
|
INTERNETDATE=$(date +"%d%m%Y" -d "$GETTIME")
|
|
LOCALDATE=$(date +"%d%m%Y")
|
|
|
|
OS_ID=$(cat ${CONFIGFILES}/$MODEL/$VERSION/config.json | jq -r -e ' .os .id')
|
|
PAT_URL=$(cat ${CONFIGFILES}/$MODEL/$VERSION/config.json | jq -r -e ' .os .pat_url')
|
|
PAT_SHA=$(cat ${CONFIGFILES}/$MODEL/$VERSION/config.json | jq -r -e ' .os .sha256')
|
|
ZIMAGE_SHA=$(cat ${CONFIGFILES}/$MODEL/$VERSION/config.json | jq -r -e '.files .zlinux .sha256')
|
|
RD_SHA=$(cat ${CONFIGFILES}/$MODEL/$VERSION/config.json | jq -r -e '.files .ramdisk .sha256')
|
|
RAMDISK_PATCH=$(cat ${CONFIGFILES}/$MODEL/$VERSION/config.json | jq -r -e ' .patches .ramdisk')
|
|
SYNOINFO_PATCH=$(cat ${CONFIGFILES}/$MODEL/$VERSION/config.json | jq -r -e ' .synoinfo')
|
|
RAMDISK_COPY=$(cat ${CONFIGFILES}/$MODEL/$VERSION/config.json | jq -r -e ' .extra .ramdisk_copy')
|
|
SYNOINFO_USER=$(cat $USERCONFIGFILE | jq -r -e ' .synoinfo')
|
|
RD_COMPRESSED=$(cat ${CONFIGFILES}/$MODEL/$VERSION/config.json | jq -r -e ' .extra .compress_rd')
|
|
redpillextension="https://github.com/pocopico/rp-ext/raw/main/redpill/rpext-index.json"
|
|
FILENAME="${OS_ID}.pat"
|
|
|
|
mount ${tcrppart}
|
|
mount ${tcrpdisk}1
|
|
mount ${tcrpdisk}2
|
|
|
|
|
|
#wecho "tcrppart : $tcrppart local_cache : $local_cache INTERNETDATE : $INTERNETDATE \ LOCALDATE : $LOCALDATE
|
|
#OS_ID : $OS_ID PAT_URL : $PAT_URL PAT_SHA : $PAT_SHA \
|
|
#ZIMAGE_SHA : $ZIMAGE_SHA RD_SHA : $RD_SHA RAMDISK_PATCH : $RAMDISK_PATCH \
|
|
#SYNOINFO_PATCH : $SYNOINFO_PATCH RAMDISK_COPY : $RAMDISK_COPY SYNOINFO_USER : $SYNOINFO_USER \
|
|
#RD_COMPRESSED : $RD_COMPRESSED redpillextension : $redpillextension FILENAME : $FILENAME "
|
|
|
|
}
|
|
|
|
function checkextractor() {
|
|
|
|
if [ -d /mnt/${tcrppart}/auxfiles/patch-extractor ] && [ -f /mnt/${tcrppart}/auxfiles/patch-extractor/synoarchive.nano ]; then
|
|
extractorcached="yes"
|
|
else
|
|
extractorcached="no"
|
|
fi
|
|
|
|
}
|
|
|
|
function downloadextractor() {
|
|
|
|
mkdir -p ${PATCHEXTRACTOR}/
|
|
|
|
cd ${PATCHEXTRACTOR}/
|
|
|
|
curl --insecure --location https://global.download.synology.com/download/DSM/release/7.0.1/42218/DSM_DS3622xs%2B_42218.pat --output ${HOMEPATH}/oldpat.tar.gz
|
|
#[ -f ${HOMEPATH}/oldpat.tar.gz ] && tar -C${temp_folder} -xf ${HOMEPATH}/oldpat.tar.gz rd.gz
|
|
|
|
tar xvf ../oldpat.tar.gz hda1.tgz
|
|
tar xf hda1.tgz usr/lib
|
|
tar xf hda1.tgz usr/syno/sbin
|
|
|
|
mkdir -p ${PATCHEXTRACTOR}/lib/
|
|
|
|
cp usr/lib/libicudata.so* ${PATCHEXTRACTOR}/lib
|
|
cp usr/lib/libicui18n.so* ${PATCHEXTRACTOR}/lib
|
|
cp usr/lib/libicuuc.so* ${PATCHEXTRACTOR}/lib
|
|
cp usr/lib/libjson.so* ${PATCHEXTRACTOR}/lib
|
|
cp usr/lib/libboost_program_options.so* ${PATCHEXTRACTOR}/lib
|
|
cp usr/lib/libboost_locale.so* ${PATCHEXTRACTOR}/lib
|
|
cp usr/lib/libboost_filesystem.so* ${PATCHEXTRACTOR}/lib
|
|
cp usr/lib/libboost_thread.so* ${PATCHEXTRACTOR}/lib
|
|
cp usr/lib/libboost_coroutine.so* ${PATCHEXTRACTOR}/lib
|
|
cp usr/lib/libboost_regex.so* ${PATCHEXTRACTOR}/lib
|
|
cp usr/lib/libapparmor.so* ${PATCHEXTRACTOR}/lib
|
|
cp usr/lib/libjson-c.so* ${PATCHEXTRACTOR}/lib
|
|
cp usr/lib/libsodium.so* ${PATCHEXTRACTOR}/lib
|
|
cp usr/lib/libboost_context.so* ${PATCHEXTRACTOR}/lib
|
|
cp usr/lib/libsynocrypto.so* ${PATCHEXTRACTOR}/lib
|
|
cp usr/lib/libsynocredentials.so* ${PATCHEXTRACTOR}/lib
|
|
cp usr/lib/libboost_iostreams.so* ${PATCHEXTRACTOR}/lib
|
|
cp usr/lib/libsynocore.so* ${PATCHEXTRACTOR}/lib
|
|
cp usr/lib/libicuio.so* ${PATCHEXTRACTOR}/lib
|
|
cp usr/lib/libboost_chrono.so* ${PATCHEXTRACTOR}/lib
|
|
cp usr/lib/libboost_date_time.so* ${PATCHEXTRACTOR}/lib
|
|
cp usr/lib/libboost_system.so* ${PATCHEXTRACTOR}/lib
|
|
cp usr/lib/libsynocodesign.so.7* ${PATCHEXTRACTOR}/lib
|
|
cp usr/lib/libsynocredential.so* ${PATCHEXTRACTOR}/lib
|
|
cp usr/lib/libjson-glib-1.0.so* ${PATCHEXTRACTOR}/lib
|
|
cp usr/lib/libboost_serialization.so* ${PATCHEXTRACTOR}/lib
|
|
cp usr/lib/libmsgpackc.so* ${PATCHEXTRACTOR}/lib
|
|
|
|
cp -r usr/syno/sbin/synoarchive ${PATCHEXTRACTOR}/
|
|
|
|
sudo rm -rf usr
|
|
sudo rm -rf ../oldpat.tar.gz
|
|
sudo rm -rf hda1.tgz
|
|
|
|
curl --silent --location https://github.com/pocopico/tinycore-redpill/blob/develop/tools/xxd?raw=true --output xxd
|
|
|
|
chmod +x xxd
|
|
|
|
./xxd synoarchive | sed -s 's/000039f0: 0300/000039f0: 0100/' | ./xxd -r >synoarchive.nano
|
|
./xxd synoarchive | sed -s 's/000039f0: 0300/000039f0: 0a00/' | ./xxd -r >synoarchive.smallpatch
|
|
./xxd synoarchive | sed -s 's/000039f0: 0300/000039f0: 0000/' | ./xxd -r >synoarchive.system
|
|
|
|
chmod +x synoarchive.*
|
|
|
|
[ ! -d /mnt/${tcrppart}/auxfiles/patch-extractor ] && mkdir -p /mnt/${tcrppart}/auxfiles/patch-extractor
|
|
|
|
cp -rf ${PATCHEXTRACTOR}/lib /mnt/${tcrppart}/auxfiles/patch-extractor/
|
|
cp -rf ${PATCHEXTRACTOR}/synoarchive.* /mnt/${tcrppart}/auxfiles/patch-extractor/
|
|
|
|
## get list of available pat versions from
|
|
#curl --silent https://archive.synology.com/download/Os/DSM/ | grep "/download/Os/DSM/7" | awk '{print $2}' | awk -F\/ '{print $5}' | sed -s 's/"//g'
|
|
## Get the selected update pats for your platform/version
|
|
#curl --silent https://archive.synology.com/download/Os/DSM/7.1-42661-3 | grep href | grep apollolake | awk '{print $2}'
|
|
## Select URL
|
|
#curl --silent https://archive.synology.com/download/Os/DSM/7.1-42661-2 | grep href | grep apollolake | awk '{print $2}' | awk -F= '{print $2}'
|
|
## URL
|
|
#url=$(curl --silent https://archive.synology.com/download/Os/DSM/7.1-42661-3 | grep href | grep geminilake | awk '{print $2}' | awk -F= '{print $2}' | sed -s 's/"//g')
|
|
|
|
#curl --location $url -O
|
|
|
|
#patfile=$(echo $url | awk -F/ '{print $9}')
|
|
|
|
mkdir -p temp && cd temp
|
|
|
|
if [ -d /mnt/${tcrppart}/auxfiles/patch-extractor ] && [ -f /mnt/${tcrppart}/auxfiles/patch-extractor/synoarchive.nano ]; then
|
|
LD_LIBRARY_PATH=/mnt/${tcrppart}/auxfiles/patch-extractor/lib /mnt/${tcrppart}/auxfiles/patch-extractor/synoarchive.nano -xvf ${PATCHEXTRACTOR}/$patfile
|
|
else
|
|
wecho "Extractor not found"
|
|
fi
|
|
## Extract ramdisk
|
|
|
|
flashfile=$(ls flashupdate*s2*)
|
|
|
|
tar xvf $flashfile && tar xvf content.txz
|
|
|
|
mkdir -p rd.temp
|
|
cd rd.temp && unlzma -c ../rd.gz | cpio -idm
|
|
etc/VERSION
|
|
|
|
}
|
|
|
|
function getstaticmodule() {
|
|
|
|
#SYNOMODEL="$(echo $MODEL | sed -s 's/+/p/g' | tr '[:upper:]' '[:lower:]')_${REVISION}"
|
|
SYNOMODEL="$(echo $OS_ID | sed -s 's/+/p/g' | tr '[:upper:]' '[:lower:]')"
|
|
|
|
cd ${HOMEPATH}
|
|
|
|
wecho "Removing any old redpill.ko modules"
|
|
[ -f ${HOMEPATH}/redpill.ko ] && rm -f ${HOMEPATH}/redpill.ko
|
|
|
|
extension=$(curl --insecure --silent --location "$redpillextension")
|
|
|
|
wecho "Looking for redpill for : $SYNOMODEL"
|
|
|
|
#release=`echo $extension | jq -r '.releases .${SYNOMODEL}_{$TARGET_REVISION}'`
|
|
release=$(echo $extension | jq -r -e --arg SYNOMODEL $SYNOMODEL '.releases[$SYNOMODEL]')
|
|
files=$(curl --insecure --silent --location "$release" | jq -r '.files[] .url')
|
|
|
|
for file in $files; do
|
|
wecho "Getting file $file"
|
|
curl --insecure --silent -O $file
|
|
if [ -f redpill*.tgz ]; then
|
|
wecho "Extracting module"
|
|
tar xf redpill*.tgz
|
|
rm redpill*.tgz
|
|
strip --strip-debug redpill.ko
|
|
fi
|
|
done
|
|
|
|
if [ -f ${HOMEPATH}/redpill.ko ] && [ -n $(strings ${HOMEPATH}/redpill.ko | grep -i $MODEL) ]; then
|
|
wecho "Copying redpill.ko module to ramdisk"
|
|
cp ${HOMEPATH}/redpill.ko ${TEMPPAT}/rd.temp/usr/lib/modules/rp.ko
|
|
else
|
|
wecho "Module does not contain platorm information for ${MODEL}"
|
|
fi
|
|
|
|
[ -f ${TEMPPAT}/rd.temp/usr/lib/modules/rp.ko ] && wecho "Redpill module is in place"
|
|
|
|
}
|
|
|
|
function testarchive() {
|
|
|
|
archive="$1"
|
|
archiveheader="$(od -bc ${archive} | head -1 | awk '{print $3}')"
|
|
|
|
case ${archiveheader} in
|
|
105)
|
|
wecho "${archive}, is a Tar file"
|
|
isencrypted="no"
|
|
return 0
|
|
;;
|
|
255)
|
|
wecho "File ${archive}, is encrypted"
|
|
isencrypted="yes"
|
|
return 1
|
|
;;
|
|
213)
|
|
wecho "File ${archive}, is a compressed tar"
|
|
isencrypted="no"
|
|
;;
|
|
*)
|
|
wecho "Could not determine if file ${archive} is encrypted or not, maybe corrupted"
|
|
ls -ltr ${archive}
|
|
wecho ${archiveheader}
|
|
exit 99
|
|
;;
|
|
esac
|
|
|
|
}
|
|
|
|
function _set_conf_kv() {
|
|
# Delete
|
|
if [ -z "$2" ]; then
|
|
sed -i "$3" -e "s/^$1=.*$//"
|
|
return 0
|
|
fi
|
|
|
|
# Replace
|
|
if grep -q "^$1=" "$3"; then
|
|
sed -i "$3" -e "s\"^$1=.*\"$1=\\\"$2\\\"\""
|
|
return 0
|
|
fi
|
|
|
|
# Add if doesn't exist
|
|
echo "$1=\"$2\"" >>$3
|
|
}
|
|
|
|
function downloadpat() {
|
|
|
|
checkcached
|
|
|
|
if [ "$iscached" = "yes" ]; then
|
|
echo "Found cached PAT file $patfile"
|
|
cp $patfile ./$FILENAME
|
|
return
|
|
fi
|
|
|
|
if [ ! -f $FILENAME ]; then
|
|
wecho "Downloading PAT file $FILENAME for MODEL=$MODEL, Version=$VERSION, SHA256=$PAT_SHA"
|
|
curl --insecure --silent "$PAT_URL" --output "$FILENAME" | tee -a ${BUILDLOG}
|
|
|
|
[ "$(sha256sum $FILENAME | awk '{print $1}')" = "$PAT_SHA" ] && wecho "File downloaded and matches expected sha256sum" || wecho "Error downloaded file is corrupted"
|
|
else
|
|
wecho "$(sha256sum $FILENAME | awk '{print $1}')" = "$PAT_SHA"
|
|
wecho "File $FILENAME is already downloaded"
|
|
return
|
|
if [ "$(sha256sum $FILENAME | awk '{print $1}')" = "$PAT_SHA" ]; then
|
|
wecho "File downloaded and matches expected sha256sum"
|
|
else
|
|
wecho "Error downloaded file is corrupted stopping process. Remove file $FILENAME and try again"
|
|
#rm -f $FILENAME
|
|
exit 99
|
|
|
|
fi
|
|
fi
|
|
|
|
}
|
|
|
|
function downloadtools() {
|
|
|
|
wecho "Downloading tools"
|
|
|
|
[ ! -d ${HOMEPATH}/tools ] && mkdir -p ${HOMEPATH}/tools
|
|
cd ${HOMEPATH}/tools
|
|
for FILE in bspatch bzImage-to-vmlinux.sh calc_run_size.sh crc32 dtc kexec ramdisk-patch.sh vmlinux-to-bzImage.sh xxd zimage-patch.sh kpatch zImage_template.gz; do
|
|
[ ! -f ${HOMEPATH}/tools/$FILE ] && curl --silent --insecure --location "https://raw.githubusercontent.com/pocopico/tinycore-redpill/develop/tools/${FILE}" -O
|
|
chmod +x $FILE
|
|
done
|
|
|
|
cd ${HOMEPATH}
|
|
|
|
}
|
|
|
|
function extractpat() {
|
|
|
|
FILENAME="$1"
|
|
mkdir -p $TEMPPAT
|
|
|
|
if [ "$isencrypted" = "yes" ]; then
|
|
checkextractor && [ "$extractorcached" = "yes" ] && wecho "Extractor Cached, proceeding..."
|
|
wecho "Extracting encrypted PAT file $FILENAME"
|
|
[ ! -d ${TEMPPAT} ] && mkdir -p ${TEMPPAT}
|
|
|
|
LD_LIBRARY_PATH=/mnt/${tcrppart}/auxfiles/patch-extractor/lib /mnt/${tcrppart}/auxfiles/patch-extractor/synoarchive.system -C ${TEMPPAT} -xf $FILENAME
|
|
else
|
|
wecho "Extracting unencrypted PAT file $FILENAME to $TEMPPAT"
|
|
tar xf $FILENAME -C ${TEMPPAT}
|
|
fi
|
|
|
|
[ ! -f ${TEMPPAT}/VERSION ] && echo "FAILED to extract" && exit 99
|
|
[ -f ${TEMPPAT}/VERSION ] && . ${TEMPPAT}/VERSION && wecho "Extracted PAT file, VERSION Found : ${major}.${minor}.${micro}_${buildnumber}"
|
|
extractedzImagesha="$(sha256sum ${TEMPPAT}/zImage | awk '{print $1}')"
|
|
extractedrdsha="$(sha256sum ${TEMPPAT}/rd.gz | awk '{print $1}')"
|
|
wecho "zImage sha256sum : $extractedzImagesha" && json=$(jq --arg var "${extractedzImagesha}" '.general.zimghash = $var' $USERCONFIGFILE) && echo -E "${json}" | jq . >$USERCONFIGFILE
|
|
wecho "rd sha256sum : $extractedrdsha" && json=$(jq --arg var "${extractedrdsha}" '.general.rdhash = $var' $USERCONFIGFILE) && echo -E "${json}" | jq . >$USERCONFIGFILE
|
|
|
|
}
|
|
|
|
function patchkernel() {
|
|
|
|
wecho "Patching Kernel"
|
|
${HOMEPATH}/tools/bzImage-to-vmlinux.sh ${TEMPPAT}/zImage ${TEMPPAT}/vmlinux >log 2>&1 >/dev/null
|
|
${HOMEPATH}/tools/kpatch ${TEMPPAT}/vmlinux ${TEMPPAT}/vmlinux-mod >log 2>&1 >/dev/null
|
|
${HOMEPATH}/tools/vmlinux-to-bzImage.sh ${TEMPPAT}/vmlinux-mod ${TEMPPAT}/zImage-dsm >/dev/null
|
|
|
|
[ -f ${TEMPPAT}/zImage-dsm ] && wecho "Kernel Patched, sha256sum : $(sha256sum ${TEMPPAT}/zImage-dsm)"
|
|
|
|
}
|
|
|
|
function cleanbuild() {
|
|
|
|
wecho "Cleaning build directory"
|
|
rm -rf ${TEMPPAT}
|
|
|
|
}
|
|
|
|
function addextensions() {
|
|
|
|
cd $HOMEPATH/
|
|
|
|
# extadd URL PLATFORM
|
|
BUILDMODEL="$(echo $MODEL | tr '[:upper:]' '[:lower:]')"
|
|
platform_selected="$(jq -s '.[0].build_configs=(.[1].build_configs + .[0].build_configs | unique_by(.id)) | .[0]' custom_config_jun.json custom_config.json | jq ".build_configs[] | select(.id==\"${BUILDMODEL}-${VERSION}\")")"
|
|
EXTENSIONS="$(echo $platform_selected | jq -r -e '.add_extensions[]' | grep json | awk -F: '{print $1}' | sed -s 's/"//g')"
|
|
EXTENSIONS_SOURCE_URL="$(echo $platform_selected | jq -r -e '.add_extensions[]' | grep json | awk '{print $2}' | sed -e 's/,//g' -e 's/"//g')"
|
|
BUILDVERSION="$(echo $VERSION | awk -F- '{print $2}')"
|
|
|
|
wecho "PLATFORM SELECTED : $platform_selected"
|
|
wecho "EXTENSIONS_SOURCE_URL : $EXTENSIONS_SOURCE_URL"
|
|
|
|
wecho "Adding extensions for ${BUILDMODEL}_${BUILDVERSION}"
|
|
|
|
for EXT in $EXTENSIONS_SOURCE_URL; do
|
|
wecho "Adding required extension $EXT for ${BUILDMODEL}_${BUILDVERSION}"
|
|
wecho "extadd $EXT ${BUILDMODEL}_${BUILDVERSION}"
|
|
|
|
$HOMEPATH/include/extmgr.sh extadd $EXT "${BUILDMODEL}_${BUILDVERSION}"
|
|
|
|
done
|
|
|
|
$HOMEPATH/include/listmodules.sh "${BUILDMODEL}_${BUILDVERSION}"
|
|
|
|
wecho "Processing extensions"
|
|
$HOMEPATH/include/extmgr.sh processexts "${BUILDMODEL}_${BUILDVERSION}"
|
|
|
|
}
|
|
|
|
function patchramdisk() {
|
|
|
|
addextensions
|
|
|
|
temprd="${TEMPPAT}/rd.temp/"
|
|
wecho "Patching RamDisk"
|
|
wecho "Extracting ramdisk to $temprd"
|
|
|
|
[ ! -d $temprd ] && mkdir -p $temprd && cd $temprd && xz -dc <"${TEMPPAT}/rd.gz" | cpio -idm >/dev/null 2>&1
|
|
[ -f ${TEMPPAT}/rd.temp/VERSION ] && ${TEMPPAT}/rd.temp/VERSION
|
|
wecho "Extracted ramdisk VERSION : ${major}.${minor}.${micro}_${buildnumber}"
|
|
PATCHES="$(echo $RAMDISK_PATCH | jq . | sed -s 's/@@@COMMON@@@/\/home\/tc\/redpill-load\/config\/_common/' | grep config | sed -s 's/"//g' | sed -s 's/,//g')"
|
|
|
|
wecho "Patches to be applied : $PATCHES"
|
|
|
|
cd $temprd
|
|
for patch in $PATCHES; do
|
|
wecho "Applying patch $patch in dir $PWD"
|
|
patch -p1 <$patch
|
|
done
|
|
|
|
wecho "Applying model synoinfo patches"
|
|
|
|
while IFS=":" read KEY VALUE; do
|
|
echo "Key :$KEY Value: $VALUE"
|
|
_set_conf_kv $KEY $VALUE $temprd/etc/synoinfo.conf
|
|
done <<<$(echo $SYNOINFO_PATCH | jq . | grep ":" | sed -s 's/"//g' | sed -s 's/,//g')
|
|
|
|
wecho "Applying user synoinfo settings"
|
|
|
|
while IFS=":" read KEY VALUE; do
|
|
echo "Key :$KEY Value: $VALUE"
|
|
_set_conf_kv $KEY $VALUE $temprd/etc/synoinfo.conf
|
|
done <<<$(echo $SYNOINFO_USER | jq . | grep ":" | sed -s 's/"//g' | sed -s 's/,//g')
|
|
|
|
wecho "Copying extra ramdisk files "
|
|
|
|
while IFS=":" read SRC DST; do
|
|
echo "Source :$SRC Destination : $DST"
|
|
cp -f $SRC $DST
|
|
done <<<$(echo $RAMDISK_COPY | jq . | grep "COMMON" | sed -s 's/"//g' | sed -s 's/,//g' | sed -s 's/@@@COMMON@@@/\/home\/tc\/redpill-load\/config\/_common/')
|
|
|
|
#wecho "Adding precompiled redpill module"
|
|
#getstaticmodule
|
|
|
|
cd $HOMEPATH
|
|
$HOMEPATH/include/extmgr.sh createcustominitfile "${BUILDMODEL}_${BUILDVERSION}"
|
|
cd $temprd
|
|
cp -rpf $HOMEPATH/customtemp/* .
|
|
|
|
# Reassembly ramdisk
|
|
wecho "Reassempling ramdisk"
|
|
if [ "${RD_COMPRESSED}" == "true" ]; then
|
|
(cd "${temprd}" && find . | cpio -o -H newc -R root:root | xz -9 --format=lzma >"${TEMPPAT}/initrd-dsm") >/dev/null 2>&1 >/dev/null
|
|
else
|
|
(cd "${temprd}" && find . | cpio -o -H newc -R root:root >"${TEMPPAT}/initrd-dsm") >/dev/null 2>&1
|
|
fi
|
|
[ -f ${TEMPPAT}/initrd-dsm ] && wecho "Patched ramdisk created $(ls -l ${TEMPPAT}/initrd-dsm)"
|
|
|
|
wecho "Copying files to ${tcrppart}"
|
|
|
|
cp -f $HOMEPATH/custom.gz /mnt/${tcrppart}/
|
|
cp -f ${TEMPPAT}/zImage-dsm /mnt/${tcrppart}/
|
|
cp -f ${TEMPPAT}/initrd-dsm /mnt/${tcrppart}/
|
|
|
|
cp -f ${TEMPPAT}/zImage /mnt/${tcrppart}1/
|
|
cp -f ${TEMPPAT}/rd.gz /mnt/${tcrppart}1/
|
|
cp -f $HOMEPATH/custom.gz /mnt/${tcrppart}1/
|
|
|
|
cp -f ${TEMPPAT}/zImage /mnt/${tcrppart}2/
|
|
cp -f ${TEMPPAT}/rd.gz /mnt/${tcrppart}2/
|
|
|
|
|
|
rm -rf $HOMEPATH/html/$patfile
|
|
rm -rf $HOMEPATH/temppat
|
|
|
|
|
|
}
|
|
|
|
json_get_keys() {
|
|
local -n __json_return=$3
|
|
|
|
local out
|
|
out=$(/usr/local/bin/jq -r -e ".${2}|keys_unsorted|.[]" "${1}" 2>&1)
|
|
if [ $? -ne 0 ]; then
|
|
wecho "Failed extract K=>V pairs from %s:.%s\n\n%s" "${1}" "${2}" "${out}"
|
|
fi
|
|
|
|
readarray -t __json_return <<<"${out}"
|
|
}
|
|
|
|
read_kv_to_array() {
|
|
# kv_pair used dynamically in kv_extractor
|
|
# shellcheck disable=SC2034
|
|
local -n __json_kv_pairs=$3
|
|
local kv_extractor='.'"${2}"'|to_entries|map("[\(.key|@sh)]=\(.value|@sh) ")|"__json_kv_pairs=(" + add + ")"'
|
|
|
|
local out
|
|
out=$(/usr/local/bin/jq -r -e "${kv_extractor}" "${1}" 2>&1)
|
|
if [ $? -ne 0 ]; then
|
|
wecho "Failed extract K=>V pairs from %s:.%s\n\n%s" "${1}" "${2}" "${out}"
|
|
fi
|
|
|
|
# if you get a useless BASH error "invalid arithmetic operator" here check the variable you've passed (it must be -A)
|
|
eval "$out"
|
|
}
|
|
|
|
read_ordered_kv() {
|
|
local -n __json_keys=$3
|
|
local -n __json_values=$4
|
|
json_get_keys "${1}" "${2}" __json_keys
|
|
read_kv_to_array "${1}" "${2}" __json_values # we can reuse code to read k=>v pairs as we need them anyway
|
|
}
|
|
# Finds the token in file and replaces it with an arbitrary string
|
|
#
|
|
# This is slightly stupid because it uses a temporary file, but even our senior sed magician gave up. PRs welcomed.
|
|
#
|
|
# Args: $1 file to modify | $2 token | $3 text to insert
|
|
|
|
replace_token_with_text() {
|
|
local temp_file="${1}.tmp_ins_frag"
|
|
wecho "Replacing \"%s\" with text from %s in %s" "${2}" "${temp_file}" "${1}"
|
|
|
|
echo "${3}" >"${temp_file}"
|
|
if [ $? -ne 0 ]; then
|
|
wecho "Failed to create temp file %s" "${temp_file}"
|
|
fi
|
|
|
|
local out
|
|
out=$(sed -e "/${2}/ {" -e "r ${temp_file}" -e 'd' -e '}' -i "${1}" 2>&1)
|
|
if [ $? -ne 0 ]; then
|
|
wecho "Failed to replace %s in file %s with contents of %s\n\n%s" "${2}" "${1}" "${temp_file}" "${out}"
|
|
fi
|
|
rm -f "${temp_file}" || wecho "Failed to remove temp file %s" "${temp_file}"
|
|
}
|
|
|
|
json_noe() {
|
|
if [ "$1" == "null" ] || [ -z "$1" ]; then
|
|
return 0
|
|
else
|
|
return 1
|
|
fi
|
|
}
|
|
|
|
json_get_field() {
|
|
local field_val
|
|
field_val=$(/usr/local/bin/jq -e -r ".$2" "$1")
|
|
# "1 if the last output value was either false or null"
|
|
if [ $? -le 1 ]; then
|
|
echo $field_val
|
|
return 0
|
|
fi
|
|
|
|
if [ "${3:-'0'}" != 1 ]; then
|
|
wecho "Field \"$2\" doesn't existing in $1"
|
|
fi
|
|
}
|
|
|
|
json_get_array_values() {
|
|
local field_val
|
|
field_val=$(/usr/local/bin/jq -e -r ".${2} | .[]" "${1}")
|
|
local jq_exit=$?
|
|
|
|
# "1 if the last output value was either false or null", 4 if it was empty... we hate it
|
|
if [[ jq_exit -le 1 ]] || [[ jq_exit -eq 4 ]]; then
|
|
echo "${field_val}"
|
|
return 0
|
|
fi
|
|
|
|
if [ "${3:-'0'}" != 1 ]; then
|
|
wecho "Field \"$2\" doesn't existing in $1"
|
|
fi
|
|
}
|
|
|
|
expand_var_path() {
|
|
local -n __vars_map=$2
|
|
local file_path="${1}"
|
|
|
|
if [[ "${1}" == /* ]]; then
|
|
: #noop, absolute paths don't need any modifications
|
|
elif [[ "${1}" != @@@* ]]; then
|
|
# since path doesn't begin with a variable we just assume the default
|
|
file_path="${__vars_map["@@@_DEF_@@@"]}/${file_path}"
|
|
else
|
|
local var_value
|
|
for var_name in "${!__vars_map[@]}"; do
|
|
var_value="${__vars_map[$var_name]}"
|
|
file_path="${file_path/${var_name}/${var_value}}"
|
|
done
|
|
fi
|
|
|
|
wecho "Resolved path '${1}' to '${file_path}'"
|
|
echo "${file_path}"
|
|
}
|
|
|
|
function getcmdline() {
|
|
|
|
# Generates GRUB config file from a config structure
|
|
#
|
|
# - The main config file is expected to have .grub root key
|
|
# - The user config is expected to have extra_cmdline key
|
|
#
|
|
# Args:
|
|
# $1 main JSON config
|
|
# $2 user config
|
|
# $3 reference to a map of K=>V pairs with variables, see expand_var_path()
|
|
# $4 GRUB config destination file path
|
|
|
|
local menu_entries_txt
|
|
local -n _path_map=$3
|
|
|
|
# First get user cmdline overrides
|
|
wecho "Reading user extra_cmdline entries"
|
|
local -A extra_cmdline
|
|
read_kv_to_array "${2}" 'extra_cmdline' extra_cmdline
|
|
if [[ -v ${extra_cmdline['sn']} ]]; then wecho "User configuration (%s) doesn't contain unique extra_cmdline.sn" "${2}"; fi
|
|
if [[ -v ${extra_cmdline['vid']} ]]; then wecho "User configuration (%s) doesn't contain extra_cmdline.vid" "${2}"; fi
|
|
if [[ -v ${extra_cmdline['pid']} ]]; then wecho "User configuration (%s) doesn't contain extra_cmdline.pid" "${2}"; fi
|
|
if [[ -v ${extra_cmdline['mac1']} ]]; then wecho "User configuration (%s) doesn't contain at least one MAC (extra_cmdline.mac1)" "${2}"; fi
|
|
|
|
# First generate menu entries
|
|
wecho "Generating GRUB menu entries"
|
|
local entries_names
|
|
json_get_keys "${1}" 'grub.menu_entries' entries_names
|
|
|
|
# Cmdline is constructed by applying, in order, options from the follownig sources
|
|
# - platform config.json => .grub.base_cmdline
|
|
# - platform config.json => .grub.menu_entries.<entry name>.cmdline
|
|
# - user_config.json => .grub.menu_entries.<entry name>.extra_cmdline
|
|
|
|
local -A base_cmdline
|
|
wecho "Reading base cmdline"
|
|
read_kv_to_array "${1}" "grub.base_cmdline" base_cmdline
|
|
|
|
local -A entry_cmdline
|
|
local -A final_cmdline
|
|
local -a menu_entries_arr
|
|
local entry_cmdline_txt
|
|
for entry_name in "${entries_names[@]}"; do
|
|
wecho "Processing entry \"%s\"" "${entry_name}"
|
|
|
|
final_cmdline=()
|
|
# Bash doesn't have any sensible way of merging or even copying associative arrays... FML
|
|
# See https://stackoverflow.com/a/8881121
|
|
for base_cmdl_key in "${!base_cmdline[@]}"; do final_cmdline[$base_cmdl_key]=${base_cmdline[$base_cmdl_key]}; done
|
|
|
|
wecho "Applying entry cmdline"
|
|
read_kv_to_array "${1}" "grub.menu_entries[\"${entry_name}\"].cmdline" entry_cmdline # read entry CMDLINE
|
|
for entry_cmdl_key in "${!entry_cmdline[@]}"; do
|
|
wecho "Replacing base cmdline \"%s\" value \"%s\" with entry value \"%s\"" \
|
|
"${entry_cmdl_key}" "${final_cmdline[entry_cmdl_key]:-<not set>}" "${entry_cmdline[$entry_cmdl_key]}"
|
|
final_cmdline[$entry_cmdl_key]=${entry_cmdline[$entry_cmdl_key]}
|
|
done
|
|
|
|
wecho "Applying user extra_cmdline"
|
|
for user_cmdl_key in "${!extra_cmdline[@]}"; do
|
|
wecho "Replacing previous cmdline \"%s\" value \"%s\" with user value \"%s\"" \
|
|
"${user_cmdl_key}" "${final_cmdline[$user_cmdl_key]:-<not set>}" "${extra_cmdline[$user_cmdl_key]}"
|
|
final_cmdline[$user_cmdl_key]=${extra_cmdline[$user_cmdl_key]}
|
|
done
|
|
|
|
# Build the final cmdline for the entry
|
|
# There are more tricks in BASH 5.1 for printing but not on v4.3 which is standard on Debian 8 (needed for old GCC)
|
|
entry_cmdline_txt=''
|
|
for cmdline_key in "${!final_cmdline[@]}"; do
|
|
if json_noe "${final_cmdline[$cmdline_key]}"; then
|
|
entry_cmdline_txt+="${cmdline_key} "
|
|
else
|
|
entry_cmdline_txt+="${cmdline_key}=${final_cmdline[$cmdline_key]} "
|
|
fi
|
|
done
|
|
wecho "Generated cmdline for entry: %s" "${entry_cmdline_txt}"
|
|
|
|
# Now we can actually assemble the entry
|
|
menu_entries_txt+="menuentry '${entry_name}' {"$'\n'
|
|
read_ordered_kv "${1}" "grub.menu_entries[\"${entry_name}\"].options" entry_options_keys entry_options_vals
|
|
|
|
readarray -t menu_entries_arr <<<"$(json_get_array_values "${1}" "grub.menu_entries[\"${entry_name}\"].options")"
|
|
for entry in "${menu_entries_arr[@]}"; do
|
|
menu_entries_txt+=$'\t'"${entry/@@@CMDLINE@@@/${entry_cmdline_txt}}"$'\n'
|
|
done
|
|
menu_entries_txt+='}'$'\n'$'\n'
|
|
done
|
|
|
|
wecho "Generated all menu entries:\n%s" "${menu_entries_txt}"
|
|
|
|
wecho "Assembling final grub config in %s" "${4}"
|
|
local template
|
|
template=$(json_get_field "${1}" 'grub.template')
|
|
wecho "$(expand_var_path "${template}" _path_map)" "${4}"
|
|
replace_token_with_text "${4}" '@@@MENU_ENTRIES@@@' "${menu_entries_txt}"
|
|
|
|
}
|
|
|
|
function build() {
|
|
|
|
#window.open("index.sh&monitor");
|
|
|
|
wecho "Starting build"
|
|
wecho "Buildling loader for $model, $version, with serial number : $serial and macaddress : $macaddress"
|
|
wecho "extracommans : $extracmdline"
|
|
|
|
getvars
|
|
|
|
cleanbuild
|
|
testarchive $FILENAME
|
|
checkextractor
|
|
checkcached
|
|
|
|
[ "$isencrypted" = "yes" ] && [ "$extractorcached" = "no" ] && downloadextractor
|
|
|
|
extractpat "$FILENAME"
|
|
|
|
[ "$extractedzImagesha" = "$ZIMAGE_SHA" ] && wecho "zImage sha256sum matches expected sha256sum, patching kernel" && patchkernel || wecho "zImage does not match sha256sum : $extractedzImagesha"
|
|
[ "$extractedrdsha" = "$RD_SHA" ] && wecho "ramdisk sha256sum matches expected sha256sum, patching kernel" && patchramdisk || wecho "rd.gz does not match sha256sum : $extractedrdsha"
|
|
|
|
[ -n "${extracmdline}" ] && wecho "Extra User built defined command line parameters ${extracmdline}"
|
|
|
|
while IFS="=" read KEY VALUE; do
|
|
#wecho "User cmdline Key :$KEY Value: $VALUE"
|
|
#_set_conf_kv $KEY $VALUE $USERCONFIGFILE
|
|
#wecho "Debug : ${KEY} : $(json_has_field '$USERCONFIGFILE' '.extra_cmdline.$KEY')"
|
|
if [ ! -z $KEY ] && [ ! -z $VALUE ]; then
|
|
/usr/local/bin/jq -e -r ".extra_cmdline.${KEY}|select(0)" "$USERCONFIGFILE" >/dev/null 2>&1 >/dev/null
|
|
rtncode=$?
|
|
if [ $rtncode -eq 0 ]; then
|
|
#wecho "Field exists, updating"
|
|
json=$(jq --arg var "${VALUE}" ".extra_cmdline.${KEY}"' = $var' $USERCONFIGFILE) && echo -E "${json}" | jq . >$USERCONFIGFILE
|
|
else
|
|
#wecho "Field does not exist, adding "
|
|
json=$(jq ".extra_cmdline +={\"${KEY}\":\"$VALUE\"}" $USERCONFIGFILE) && echo -E "${json}" | jq . >$USERCONFIGFILE
|
|
fi
|
|
fi
|
|
done <<<$(echo $extracmdline | sed -s 's/ /\n/g')
|
|
|
|
wecho "Clearing and testing $USERCONFIGFILE"
|
|
json=$(cat $USERCONFIGFILE | sed -s 's/\\r//g' | jq .) && echo -E "${json}" | jq . >$USERCONFIGFILE
|
|
|
|
wecho "Building CMD Line"
|
|
|
|
USB_LINE=$(getcmdline ${CONFIGFILES}/$MODEL/$VERSION/config.json $USERCONFIGFILE 2>&1 | grep linux | head -1 | cut -c 16-999)
|
|
SATA_LINE=$(getcmdline ${CONFIGFILES}/$MODEL/$VERSION/config.json $USERCONFIGFILE 2>&1 | grep linux | tail -1 | cut -c 16-999)
|
|
|
|
wecho "Updating user_config with serial : $serial and macaddress : $macaddress"
|
|
json="$(jq --arg var "$serial" '.extra_cmdline.sn = $var' $USERCONFIGFILE)" && echo -E "${json}" | jq . >$USERCONFIGFILE
|
|
json="$(jq --arg var "$macaddress" '.extra_cmdline.mac1 = $var' $USERCONFIGFILE)" && echo -E "${json}" | jq . >$USERCONFIGFILE
|
|
|
|
wecho "Updated user_config with USB Command Line : $USB_LINE"
|
|
json=$(jq --arg var "${USB_LINE}" '.general.usb_line = $var' $USERCONFIGFILE) && echo -E "${json}" | jq . >$USERCONFIGFILE
|
|
wecho "Updated user_config with SATA Command Line : $SATA_LINE"
|
|
json=$(jq --arg var "${SATA_LINE}" '.general.sata_line = $var' $USERCONFIGFILE) && echo -E "${json}" | jq . >$USERCONFIGFILE
|
|
|
|
wecho "Copying $USERCONFIGFILE to boot partition"
|
|
cp -f $USERCONFIGFILE /mnt/${tcrppart}/
|
|
[ "$(sha256sum $USERCONFIGFILE | awk '{print $1}')" = "$(sha256sum /mnt/${tcrppart}/user_config.json | awk '{print $1}')" ] && wecho "File copied succesfully" || wecho "User config file is corrupted "
|
|
|
|
}
|
|
|
|
function chartinit() {
|
|
|
|
tcrppart="$(mount | grep -i optional | grep cde | awk -F / '{print $3}' | uniq | cut -c 1-3)3"
|
|
freemem=$(free | grep Mem | awk '{print $4/$2*100}')
|
|
usedmem=$(free | grep Mem | awk '{print $3/$2*100}')
|
|
cpuload=$(cat /proc/stat | grep cpu | tail -1 | awk '{print ($5*100)/($2+$3+$4+$5+$6+$7+$8+$9+$10)}' | awk '{print "CPU Usage: " 100-$1}')
|
|
freehomespace=$(df -k /home/tc/ | grep root | awk '{print $4/$2*100}')
|
|
usedhomespace=$(df -k /home/tc/ | grep root | awk '{print $3/$2*100}')
|
|
freetcrpspace=$(df -k /mnt/$tcrppart | grep sd | awk '{print $4/$2*100}')
|
|
usedtcrpspace=$(df -k /mnt/$tcrppart | grep sd | awk '{print $3/$2*100}')
|
|
|
|
cat <<EOF
|
|
<script>
|
|
|
|
// chart colors
|
|
var colors = ['#007bff','#28a745','#333333','#c3e6cb','#dc3545','#6c757d'];
|
|
/* donut charts */
|
|
var donutOptions = {
|
|
cutoutPercentage: 85,
|
|
legend: {position:'bottom', padding:5, labels: {pointStyle:'circle', usePointStyle:true}}
|
|
};
|
|
|
|
|
|
// Home
|
|
var chDonutData1 = {
|
|
labels: ['Home space % Free', 'Home space % Used'],
|
|
datasets: [
|
|
{ backgroundColor: colors.slice(0,3), borderWidth: 0, data: [$freehomespace, $usedhomespace] }
|
|
]
|
|
};
|
|
|
|
var chDonutData2 = {
|
|
labels: ['TCRP space % Free', 'TCRP space % Used'],
|
|
datasets: [
|
|
{ backgroundColor: colors.slice(0,3), borderWidth: 0, data: [$freetcrpspace, $usedtcrpspace] }
|
|
]
|
|
};
|
|
|
|
var chDonutData3 = {
|
|
labels: ['Mem % Free', 'Mem % Used'],
|
|
datasets: [
|
|
{ backgroundColor: colors.slice(0,3), borderWidth: 0, data: [$freemem, $usedmem] }
|
|
]
|
|
};
|
|
|
|
|
|
var chDonut1 = document.getElementById("chDonut1");
|
|
if (chDonut1) {
|
|
new Chart(chDonut1, {
|
|
type: 'doughnut',
|
|
data: chDonutData1,
|
|
options: donutOptions
|
|
});
|
|
}
|
|
|
|
var chDonut2 = document.getElementById("chDonut2");
|
|
if (chDonut2) {
|
|
new Chart(chDonut2, {
|
|
type: 'doughnut',
|
|
data: chDonutData2,
|
|
options: donutOptions
|
|
});
|
|
}
|
|
|
|
|
|
var chDonut3 = document.getElementById("chDonut3");
|
|
if (chDonut3) {
|
|
new Chart(chDonut3, {
|
|
type: 'doughnut',
|
|
data: chDonutData3,
|
|
options: donutOptions
|
|
});
|
|
}
|
|
|
|
|
|
</script>
|
|
|
|
EOF
|
|
|
|
}
|
|
|
|
function loaderstatus() {
|
|
|
|
#wecho "Current used Space in /home/tc is:$(du -sh /home/tc)"
|
|
|
|
cat <<EOF
|
|
|
|
<table class="table table-dark mx-auto w-auto">
|
|
<thead>
|
|
<tr>
|
|
<th scope="col">Home Space</th>
|
|
<th scope="col">TCRP Partition Space</th>
|
|
<th scope="col">Memory</th>
|
|
</tr>
|
|
</thead>
|
|
<tbody>
|
|
<tr>
|
|
<td><div class="col-md-4 py-1">
|
|
<div class="card">
|
|
<div class="card-body">
|
|
<canvas id="chDonut1" ></canvas>
|
|
</div>
|
|
</div>
|
|
</div></td>
|
|
<td> <div class="col-md-4 py-1">
|
|
<div class="card">
|
|
<div class="card-body">
|
|
<canvas id="chDonut2" ></canvas>
|
|
</div>
|
|
</div>
|
|
</div></td>
|
|
<td> <div class="col-md-4 py-1">
|
|
<div class="card">
|
|
<div class="card-body">
|
|
<canvas id="chDonut3" ></canvas>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</td>
|
|
</tr>
|
|
|
|
</tbody>
|
|
</table>
|
|
|
|
EOF
|
|
|
|
}
|
|
|
|
function readlog() {
|
|
|
|
cat <<EOF
|
|
<h3>Build output log</h3>
|
|
<div class="pre-scrollable bg-dark">
|
|
<pre id="containerDiv"></pre>
|
|
</div>
|
|
<script>
|
|
|
|
var containerDiv = document.getElementById('containerDiv');
|
|
|
|
function getLog() {
|
|
\$.ajax({
|
|
url: 'buildlog.txt',
|
|
dataType: 'text',
|
|
success: function(text) {
|
|
\$("#containerDiv").text(text);
|
|
setTimeout(getLog, 1000); // refresh every 1 seconds
|
|
}
|
|
})
|
|
}
|
|
|
|
getLog();
|
|
|
|
</script>
|
|
|
|
EOF
|
|
|
|
#"Range" : "bytes="+byteRead+"-"
|
|
|
|
}
|
|
|
|
#. ${HOMEPATH}/rploader.sh >/dev/null
|
|
|
|
[ -z "$POST_STRING" -a "$REQUEST_METHOD" = "POST" -a ! -z "$CONTENT_LENGTH" ] && read -n $CONTENT_LENGTH POST_STRING
|
|
|
|
OIFS=$IFS
|
|
IFS='=&'
|
|
parm_get=($QUERY_STRING)
|
|
parm_post=($POST_STRING)
|
|
IFS=$OIFS
|
|
|
|
declare -A get
|
|
declare -A post
|
|
|
|
for ((i = 0; i < ${#parm_get[@]}; i += 2)); do
|
|
get[${parm_get[i]}]=$(urldecode ${parm_get[i + 1]})
|
|
done
|
|
|
|
for ((i = 0; i < ${#parm_post[@]}; i += 2)); do
|
|
post[${parm_post[i]}]=$(urldecode ${parm_post[i + 1]})
|
|
done
|
|
|
|
if [ -z "$GATEWAY_INTERFACE" ]; then
|
|
echo "This is meant to run under CGI or to include functions in other scripts"
|
|
else
|
|
|
|
echo "Gateway is : $GATEWAY_INTERFACE"
|
|
pagehead
|
|
pagebody
|
|
|
|
#echo "QUERY : $QUERY_STRING"
|
|
#echo "POST : $POST_STRING"
|
|
#echo "<br>INITIAL PAGE, REQUEST : $REQUEST_METHOD"
|
|
|
|
if [ "$REQUEST_METHOD" = "GET" ]; then
|
|
MODEL="$(echo ${get[mymodel]} | sed -s "s/'//g")"
|
|
VERSION="$(echo ${get[myversion]} | sed -s "s/'//g")"
|
|
action="$(echo "${get[action]}" | sed -s "s/'//g")"
|
|
elif [ "$REQUEST_METHOD" = "POST" ]; then
|
|
if [ -z "$(echo ${post[mymodel]} | sed -s "s/'//g")" ]; then
|
|
MODEL="$(echo "${get[mymodel]}" | sed -s "s/'//g")"
|
|
else
|
|
MODEL="$(echo "${post[mymodel]}" | sed -s "s/'//g")"
|
|
fi
|
|
VERSION="$(echo "${post[myversion]}" | sed -s "s/'//g")"
|
|
REVISION="$(echo "${VERSION}" | awk -F- '{print $2}')"
|
|
serial="$(echo "${post[serial]}" | sed -s "s/'//g")"
|
|
macaddress="$(echo "${post[macaddress]}" | sed -s "s/'//g")"
|
|
if [ -z "$(echo ${post[action]} | sed -s "s/'//g")" ]; then
|
|
action="$(echo "${get[action]}" | sed -s "s/'//g")"
|
|
else
|
|
action="$(echo "${post[action]}" | sed -s "s/'//g")"
|
|
fi
|
|
#action="$(echo "${post[action]}" | sed -s "s/'//g")"
|
|
extracmdline="$(
|
|
echo "${post[extracmdline]}" | sed -s "s/'//g" | sed -s 's/ /\n/g' | sed -s 's/%3D/=/g'
|
|
)"
|
|
buildit="$(echo "${post[buildit]}" | sed -s "s/'//g")"
|
|
|
|
fi
|
|
|
|
#wecho "POST STRING : $POST_STRING : Action = $action" | tee -a buildlog.log
|
|
#echo "<br>REQUEST METHOD $REQUEST_METHOD , MODEL : $MODEL , VERSION : $VERSION"
|
|
#echo "<br>Serial : $serial , MAC : $macaddress , Buildit : $buildit"
|
|
#echo "<br>Build VARS : MODEL :$MODEL VERSION: $VERSION SN: $serial MAC: $macaddress BUILDIT: $buildit"
|
|
|
|
[ "$action" == "backuploader" ] && wecho "Backing up loader " && result=$(yes | ${HOMEPATH}/rploader.sh backuploader) && recho "$result" | tee -a ${BUILDLOG}
|
|
[ "$action" == "listplatforms" ] && wecho "Listing available platforms" && result=$(listmods) && recho "$result" | tee -a buildlog.log
|
|
[ "$action" == "cleanloader" ] && wecho "Cleaning loader home space" && result=$(${HOMEPATH}/rploader.sh clean) && recho "$result" | tee -a ${BUILDLOG}
|
|
[ "$action" == "none" ] && loaderstatus
|
|
|
|
if [ "$action" == "build" ]; then
|
|
echo "Clearing log file" >${BUILDLOG}
|
|
|
|
getvars
|
|
|
|
if [ ! -z "$MODEL" ] && [ ! -z "$VERSION" ] && [ ! -z "$serial" ] && [ ! -z "$macaddress" ] && [ ! -z "$buildit" ]; then
|
|
echo "<br>Building loader for model, $MODEL and software version, $VERSION<br>" | tee -a ${BUILDLOG}
|
|
|
|
downloadtools | tee -a ${BUILDLOG}
|
|
|
|
downloadpat | tee -a ${BUILDLOG}
|
|
|
|
build | tee -a ${BUILDLOG}
|
|
|
|
#result="$(cd ${HOMEPATH} && ./rploader.sh build v1000-7.1.0-42661 withfriend)"
|
|
#recho "$result" | tee -a buildlog.log
|
|
|
|
startover
|
|
|
|
fi
|
|
|
|
if [ -z "$MODEL" ]; then
|
|
|
|
selectmodel
|
|
|
|
elif [ -z "$VERSION" ]; then
|
|
selectversion
|
|
fi
|
|
|
|
if [ ! -z "$MODEL" ] && [ ! -z "$VERSION" ] && [ -z "$serial" ] && [ -z "$macaddress" ] && [ -z "$buildit" ]; then
|
|
|
|
#selectversion
|
|
#echo "<br></h1>Selected Model = $MODEL <br> Selected Version = $VERSION</h1><br>"
|
|
|
|
buildform
|
|
startover
|
|
fi
|
|
|
|
fi
|
|
|
|
pagefooter
|
|
fi
|