#!/usr/bin/haserl --shell=/bin/bash  --upload-limit=32768 --upload-dir=/tmp
<%# upload limit: 32Mb %>
<%

## SuperGlue project | http://superglue.it | 2014-2015 | GPLv3
## http://git.superglue.it/superglue/serverfiles
##
## admin2.cgi - control panel for Superglue personal server
## 
## example POST request:
## curl --data-urlencode 'key=value' http://host/uri
##
## returns: 200 (+ output of operation) on success
##          406 (+ error message in debug mode) on error

readonly _WWW='/www'
readonly _PWDFILE="/opt/lib/htpasswd"
readonly _HOSTPSK='/opt/lib/host.psk'
readonly _TMP='/tmp'
readonly _LOG="${_WWW}/log/admin.log"
readonly _SCRIPTS='/opt/lib/scripts'
readonly _DEBUG=1
readonly _IFS=$IFS

err() {
  _ERR="$?"
  [[ "$_ERR" -gt 0 ]] || return 0
  logThis "$1"
  headerPrint "${2:='400'}"
  exit "$_ERR"
} 

logThis() {
  [[ "$_DEBUG" -gt 0 ]] || return 0
  local _TYPE='I'
  [[ "$_ERR" -eq 0 ]] || _TYPE='E'
  local _TIME; printf -v _TIME '%(%Y-%m-%d %H:%M:%S)T' -1
  printf '%b\n' "$_TIME: [$_TYPE] ${@} " >> "$_LOG"
  [[ "$_DEBUG" -le 1 ]] || printf '%b\n' "[verbose] $_TYPE ${1}"
  return $_ERR
}

headerPrint() {
  case "$1" in
    200|'') printf '%s\r\n' 'Status: 200 OK';;
    301) printf '%b' "Status: 301 Moved Permanently\r\nLocation: ${HTTP_REFERER:=$2}\r\n";;
    302) printf '%s\r\n' 'Status: 302 Found' "Location: $2";;
    403) printf '%b' 'Status: 403 Forbidden\r\n';;
    405) printf '%b' 'Status: 405 Method Not Allowed\r\n';;
    406) printf '%b' 'Status: 406 Not Acceptable\r\n';;
      *) printf '%b' 'Status: 400 Bad Request\r\n';;
  esac
  printf '%b' 'Content-Type: text/html\r\n\r\n';
}

## faster echo
_echo() {
  printf "%s\r\n" "${*}"
}

urlDec() {
  local value=${*//+/%20}
  for part in ${value//%/ \\x}; do
    printf "%b%s" "${part:0:4}" "${part:4}"
  done
}

## only useful for debugging (remove?)
setQueryVars() {
  if [[ "$_DEBUG" -gt 0 ]]; then
    _VARS=( ${!POST_*} )
    local v
    for v in ${_VARS[@]}; do
      logThis "$v=${!v}"
    done
  fi
}

getQueryFile() {
  local _UPLD="${HASERL_fwupload_path##*/}"
  logThis "'multipart': decoding stream"
  mv "$_TMP/$_UPLD" "$_TMP/fwupload.bin" 2>/dev/null || _ERR=$?
  if [[ $_ERR -gt 0 ]]; then
    showMesg 'Firmware upload has failed' '60' 'Reboot your Superglue server and try again'
  fi
}

validIp() {
  local _IP=$1
  local _RET=1
  if [[ $_IP =~ ^[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}$ ]]; then
    OIFS=$IFS
    IFS='.'
    _IP=($_IP)
    IFS=$OIFS
    [[ ${_IP[0]} -le 255 && ${_IP[1]} -le 255 && ${_IP[2]} -le 255 && ${_IP[3]} -le 255 ]]
    _RET=$?
  fi
  return $_RET
}

pwdChange() {
  local _USER='admin'
  local _REALM='superglue'
  [[ -e $_PWDFILE ]] || showMesg 'Password file not found'
  [[ -z "${POST_pwd##$POST_pwdd}" ]] || showMesg 'Passwords did not match'
  [[ ${#POST_pwd} -ge 6 ]] || showMesg 'Password must be at least 6 characters long'
  local _HASH=$(printf '%s' "$_USER:$_REALM:${POST_pwd}" | md5sum | cut -b -32) &&
  printf '%b' "${POST_pwd}\n${POST_pwd}\n" | passwd root &&
  printf '%b' "$_USER:$_REALM:$_HASH\n" > $_PWDFILE &&
  showMesg 'Password is changed' '2' ||
  showMesg 'Password change failed!' '5'
}

lanAddr() {
  logThis "new LAN addr is: $POST_lanipaddr"
  validIp $POST_lanipaddr || showMesg 'Not valid network address'
  doUci set lanipaddr $POST_lanipaddr &&
  doUci commit network &&
  dtach -n -zE $_SCRIPTS/net-restart.sh &>/dev/null &&
  showMesg 'New network address is set' '30' "Your server is now accessible under <a href='http://superglue.local/admin'>http://superglue.local/admin</a>" ||
  showMesg 'Setting network address failed'
}

wanSet() {
  if [[ ! -z $POST_wanifname ]]; then
    ## eth and wlan wan cases are different!
    ## eth wan requires:
    ##   config interface 'wan'
    ##     option proto 'dhcp'
    ##     option ifname 'eth0'
    ##
    ## wlan wan requires:
    ##   config interface 'wan'
    ##     option proto 'dhcp' (and no 'option ifname' specified!)

    logThis "wan.ifname=$POST_wanifname"
    if [[ $POST_wanifname == 'eth0' ]]; then
      doUci set wanifname $POST_wanifname
      doUci set wanwifacedis '1'
    elif [[ $POST_wanifname == 'wlan1' ]]; then
      doUci set wanifname ''
      doUci set wanwifacedis ''
    fi
    if [[ $POST_wanproto == 'dhcp' ]]; then
      doUci set wanproto dhcp
      doUci set wanipaddr ''
      doUci set wanmask ''
      doUci set wangw ''
      doUci set wandns ''
    elif [[ $POST_wanproto == 'static' ]]; then
      logThis "wan.ipaddr=$POST_wanipaddr"
      validIp $POST_wanipaddr || showMesg 'Our IP address is not valid' '3' 'make sure to use correct address notation'
      validIp $POST_wangw || showMesg 'Gateway is not a valid IP address' '3' 'make sure to use correct address notation'
      validIp $POST_wandns || showMesg 'DNS is not a valid IP address' '3' 'make sure to use correct address notation'
      doUci set wanproto static
      doUci set wanipaddr $POST_wanipaddr
      doUci set wanmask '255.255.255.0' ## fix me
      doUci set wangw $POST_wangw
      doUci set wandns $POST_wandns
    fi

    if [[ $POST_wanifname == 'wlan1' ]]; then
      ssidChange || showMesg 'wanSet: Wireless configuration failed'
    else
      doUci commit network &&
      doUci commit wireless &&
      dtach -n -zE $_SCRIPTS/net-restart.sh &>/dev/null
    fi
    _ERR=$?
    [[ $_ERR -eq 0 ]] &&
    showMesg 'Internet connection is being configured' '25' 'check your Internet connection on completion' ||
    showMesg 'Configuring Internet connection failed' '5'
  fi
}

ssidChange() {
  ## check for iface
  [[ $POST_iface =~ ^('wan'|'lan')$ ]] || showMesg 'Error changing wireless settings' '5' 'unknown or unconfigured interface'
  logThis "$POST_iface is being set"

  _p=$POST_iface

  ## default enc for now
  local _enc='psk2'
  if [[ $POST_iface == 'wan' ]]; then
    local _mode='sta'
    local _ssid="${POST_wanssid}"
    local _key="${POST_wankey}"
  else 
    local _mode='ap'
    local _ssid="${POST_lanssid}"
    local _key="${POST_lankey}"
  fi

  #logThis "ssid: $_ssid [$_mode], key: $_key [$_enc]"
  #logThis $POST_wanssid

  [[ ${#_ssid} -ge 3 ]] || showMesg 'SSID must be at least 3 characters long'

  doUci set $_p'ssid' "${_ssid}"

  if [[ -z $_key ]]; then
    ## if key is empty set encryption to none and remove key
    doUci set $_p'key' && doUci set $_p'enc' 'none'
    _ERR=$?
  else
    [[ ${#_key} -ge 8 ]] || showMesg 'Passphrase must be at least 8 characters long'
    doUci set $_p'key' "${_key}" && doUci set $_p'enc' "${_enc}"
  fi
  [[ $_ERR -eq 0 ]] || showMesg 'ssidChange: Wireless configuration failed'
  if [[ $POST_iface == 'lan' ]]; then
    if [[ "$(doUci get lanipaddr)" !=  "${POST_lanipaddr}" ]]; then
      logThis 'local IP was changed'
      lanAddr
    fi
  fi

  doUci commit wireless
  _ERR=$?

  [[ $_ERR -eq 0 ]] &&
  dtach -n -zE $_SCRIPTS/net-restart.sh &>/dev/null ||
  showMesg 'Wireless configuration failed' '5'

  [[ $POST_iface == 'lan' ]] && 
  showMesg 'Local network configuration is progress' '30' 'check your connection on completion' || return 0
  ## in this case wanSet() handles success message
}

showMesg() {
  local _RET=$?
  local _MSG=$1
  local _TIMEOUT=$2
  local _SUBMSG=$3
  ## if set, global _ERR value prevails 
  [[ $_ERR -gt $_RET ]] && _RET=$_ERR
  _MSG=${_MSG:='Configuration'}
  _TIMEOUT=${_TIMEOUT:='5'}
  _SUBMSG="${_SUBMSG} <span id='timeout'>${_TIMEOUT}</span> seconds to get ready.."
  if [[ $_RET -gt 0 ]]; then
    local _TYPE='ERROR: '
    headerPrint 406
  else
    local _TYPE='OK: '
    headerPrint 200
  fi
  htmlHead "<meta http-equiv='refresh' content='${_TIMEOUT};url=http://${HTTP_HOST}/admin'>"
  _echo "<body>
  <h1>Superglue control panel</h1>
  <img src='http://${HTTP_HOST}/resources/img/superglueLogo.png' class='logo'>
  <hr>
  <h2 style='display:inline'>$_TYPE $_MSG</h2>
  <span style='display:block'>$_SUBMSG</span>
  <hr>
  </body>
  <script type='text/javascript'>(function(e){var t=document.getElementById(e);var n=t.innerHTML;var r=setInterval(function(){if(n==0){t.innerHTML='0';clearInterval(r);return}t.innerHTML=n;n--},1e3)})('timeout')
  </script>
  </html>"
  exit $_RET
}

updateFw() {
  local _FWFILE="${_TMP}/fwupload.bin"
  _OUT="$(sysupgrade -T $_FWFILE 2>&1)" ||
  { _ERR=$?; rm -rf $_FWFILE; showMesg 'This is not a firmware!' '3' "$_OUT"; }
  [[ $POST_fwreset == 'on' ]] && { _FWRESET='-n'; logThis 'fw reset requested'; }
  ## using dtach to prevent sysupgrade getting killed
  dtach -n -zE sysupgrade $_FWRESET $_FWFILE 2>&1 &&
  showMesg 'Firmware update is in progress..' '120' 'DO NOT INTERRUPT!' ||
  { _ERR=$?; rm -rf $_FWFILE; showMesg 'Firmware update failed..' '3'; }
}

usbInit() {
  . $_SCRIPTS/usb-part.sh
  _OUT="$(usbPart)" && 
  showMesg 'USB storage initialization is completed' '30' ||
  showMesg "USB init failed!\n$_OUT"
#  logThis 'usb init..'
}

rebootNow() {
  logThis "reboot: now!"
#  reboot
  reboot -d 3 || reboot -f
  showMesg 'Rebooting..' '60'
}

upTime() {
  local _T="$(uptime)" &&
  { headerPrint 200; printf '%b' "$_T\n"; exit 0; } ||
  headerPrint 406
}

iwScan() {
  . $_SCRIPTS/iw-scan.sh
  headerPrint 200
  iwScan
  exit 0
}

findUsbstor() {
  local _P='/sys/block/'
  local _D _DEV
  for _D in ${_P}sd*; do
    _DEV=$(readlink -f ${_D}/device)
    if [[ ${_DEV/usb} != $_DEV ]]; then
      _USBDEV="/dev/${_D/$_P}"
    fi
  done
  [[ $_USBDEV ]] || return 1
}

storageInfo() {
  if mountpoint -q $_WWW; then
    IFS=$'\n' _STOR=( $(df -h $_WWW) ) IFS=$_IFS
    _STOR=( ${_STOR[1]} )
  else
    return 1
  fi
}

swapInfo() {
  IFS=$'\n' _SWAP=( $(swapon -s) ) IFS=$_IFS
  if [[ ${_SWAP[1]} ]]; then
    IFS=$'\t' _SWAP=( ${_SWAP[1]} ) IFS=$_IFS
    ## for the lack of floats add trailing 0
    ## divide by 1023 and split last digit by a period
    _SWAP[1]="$((${_SWAP[1]}0/1023))"
    _SWAP[1]="${_SWAP[1]%?}.${_SWAP[1]/??}M"
  else
    unset _SWAP
    return 1
  fi
}

trimSpaces() {
  local v="$*"
  v="${v#"${v%%[![:space:]]*}"}"
  v="${v%"${v##*[![:space:]]}"}"
  return "$v"
}

sgDdns() {
  [[ $POST_sgddnsdomain && $POST_sgddnssubdomain ]] || showMesg 'All values must be set!'
  [[ ! "$POST_sgddnssubdomain" =~ [^a-zA-Z0-9$] ]] || showMesg 'Invalid domain name'
  [[ ! "$POST_sgddnsupdateurl" == '' ]] || showMesg 'Invalid update URL'

  local _CLIENT _DOMAIN _JSON _UPDATEURL _MSG _HTTPCODE _x

  [[ -r $_HOSTPSK ]] || showMesg 'Local PSK is not available'

  ## produce md5 hash from client PSK
  hashClient() {
    local _L
    while read -r _L; do
      printf "%s" ${_L%%[\#\-]*}
    done < $_HOSTPSK | md5sum
  }

  read -r _CLIENT _x < <(hashClient)
  logThis "sgvpn client hash: $_CLIENT"

  _UPDATEURL="$POST_sgddnsupdateurl"

  doUci set sgddnssubdomain "${POST_sgddnssubdomain,,}" &&
  doUci set sgddnsdomain "${POST_sgddnsdomain,,}" &&
  doUci set sgddnsclient "$_CLIENT" &&
  doUci set sgddnsurl "$_UPDATEURL" &&
  doUci set sgddnsenable '1' || showMesg 'Error setting DDNS configuration'
  doUci commit dyndns

  ## attempt first update to check if domain is available and everything checks out
  IFS=$'\t'; read -r _MSG _HTTPCODE < <($_SCRIPTS/dyndns-update.sh); IFS=$_IFS
  $_MSG="${_MSG:='Unknown error'}"

  logThis "sgvpn check: $_MSG"

  if [[ ! $_HTTPCODE == 200 ]]; then
    _ERR=1
    logThis 'error in dns update, disabling configuration'
    doUci set sgddnsdomain ''
    doUci set sgddnssubdomain ''
    doUci set sgddnsclient ''
    doUci set sgddnsurl ''
    doUci set sgddnsenable '0'
    doUci commit dyndns
    showMesg "$_MSG" '10'
  fi

   showMesg 'Domain configuration is in progress..' '10' 'Your address will become available right away'
}

sgOpenvpn() {
  logThis "enabling SG openvpn"
  if [[ $(doUci get sgopenvpnenable) == '0' ]]; then
    doUci set sgopenvpnenable '1' &&
    /etc/init.d/openvpn start &&
    showMesg 'VPN service enabled' '5'
  else
    doUci set sgopenvpnenable '0' &&
    /etc/init.d/openvpn stop &&
    showMesg 'VPN service disabled' '5'
  fi
  
  showMesg 'VPN configuration failed' '5' 'make sure your device is online'
  
}

showMesg2() {
  local _MSG=$1
  local _TIMEOUT=$2
  local _SUBMSG=$3
  _MSG=${_MSG:='Configuration'}
  _TIMEOUT=${_TIMEOUT:='5'}
  _SUBMSG="${_SUBMSG} <span id='timeout'>${_TIMEOUT}</span> seconds to get ready.."
  headerPrint 200
  htmlHead 
#  htmlHead "<meta http-equiv='refresh' content='${_TIMEOUT};url=http://${HTTP_HOST}/admin'>"
  _echo "<body>
  <h1>Superglue control panel</h1>
  <img src='http://${HTTP_HOST}/resources/img/superglueLogo.png' class='logo'>
  <hr>
  <h2 style='display:inline'>$_MSG</h2>
  <span style='display:block'>$_SUBMSG</span>
  <hr>
  </body>
  <script type='text/javascript'>(function(e){var t=document.getElementById(e);var n=t.innerHTML;var r=setInterval(function(){if(n==0){t.innerHTML='0';clearInterval(r);return}t.innerHTML=n;n--},1e3)})('timeout')
  </script>
  </html>"
  
}


testRun() {
  logThis 'starting test '
  showMesg2 'Running test'
  sleep 2; logThis 'running test'; sleep 5
#  printf '%s' "Location: /admin/error/\r\n"
#  printf '%b' "Status: 301 Moved Permanently\r\nLocation: http://${HTTP_HOST}/admin/error\r\n"
#  exit
  headerPrint '302' "http://${HTTP_HOST}/admin/error"
#  exit  
#  showMesg 'Test run' 
}

doUci() {
  local _CMD=''
  local _ARG=''
  case $1 in
    get|set|commit) _CMD=$1;;
          *) logThis 'bad UCI command'; headerPrint 405; echo 'bad UCI command'; exit 1 ;;
  esac

  case $2 in
    lanssid) _ARG='wireless.@wifi-iface[0].ssid';;
    lanenc) _ARG='wireless.@wifi-iface[0].encryption';;
    lankey) _ARG='wireless.@wifi-iface[0].key';;
    wanwifacedis) _ARG='wireless.@wifi-iface[1].disabled';;
    wanssid) _ARG='wireless.@wifi-iface[1].ssid';;
    wanenc) _ARG='wireless.@wifi-iface[1].encryption';;
    wankey) _ARG='wireless.@wifi-iface[1].key';;
    lanipaddr) _ARG='network.lan.ipaddr';;
    wanifname) _ARG='network.wan.ifname';;
    wanproto) _ARG='network.wan.proto';;
    wanipaddr) _ARG='network.wan.ipaddr';;
    wanmask) _ARG='network.wan.netmask';;
    wangw) _ARG='network.wan.gateway';;
    wandns) _ARG='network.wan.dns';;
    sgddnsenable) _ARG='dyndns.superglue.enable';;
    sgddnsurl) _ARG='dyndns.superglue.updateurl';;
    sgddnsclient) _ARG='dyndns.superglue.client';;
    sgddnssubdomain) _ARG='dyndns.superglue.subdomain';;
    sgddnsdomain) _ARG='dyndns.superglue.domain';;
    sgopenvpnenable) _ARG='openvpn.superglue.enable';;
    *) if [[ $_CMD == 'commit' ]]; then
        _ARG=$2
       else 
        logThis "bad UCI entry: $2"
        _ERR=1
        showMesg 'bad UCI entry'
       fi ;;
  esac

  if [[ $_CMD == 'get' ]]; then
    if [ ! -z $_ARG ]; then
      /sbin/uci -q get $_ARG || return $?
    fi
  fi

  if [[ $_CMD == 'set' ]]; then
    local _VAL=$3
    if [ -z $_VAL ]; then
      logThis "empty $_ARG value, removing record"
      /sbin/uci delete $_ARG || ( echo "uci delete $_ARG: error"; exit 1; )
    fi

    if [ ! -z $_ARG ]; then
      logThis "setting $_ARG value"
      /sbin/uci set $_ARG=$_VAL || ( echo "uci set $_ARG: error"; exit 1; )
    fi
  fi

  if [[ $_CMD == 'commit' ]]; then
    /sbin/uci commit $_ARG || echo "uci commit $_ARG: error"
  fi
}


## call with argument to inject additional lines
## ie: htmlhead "<meta http-equiv='refresh' content='2;URL=http://${HTTP_REFERER}'>"

htmlHead() {
_echo "<!-- obnoxious code below, keep your ports tight -->
<!doctype html>
<html>
<head>
<meta http-equiv='Content-Type' content='text/html; charset=UTF-8' />
<meta http-equiv='Cache-Control' content='no-cache, no-store, must-revalidate' />
<meta http-equiv='Pragma' content='no-cache' />
<meta http-equiv='Expires' content='0' />
<link rel='icon' href='http://${HTTP_HOST}/resources/img/favicon.ico' type='image/x-icon' />
<title>Superglue | Control panel</title>
<link rel='stylesheet' type='text/css' href='http://${HTTP_HOST}/resources/admin/admin.css' />
$@
</head>"
}

footerBody() {
_echo "</body>
<script type='text/javascript' src='http://${HTTP_HOST}/resources/admin/admin.js'></script>
</html>"
}

if [[ "${REQUEST_METHOD^^}" == "POST" ]]; then
  [[ $CONTENT_LENGTH -gt 0 ]] || err 'content length is zero, 301 back to referer' '301'
  case "${CONTENT_TYPE^^}" in 
    APPLICATION/X-WWW-FORM-URLENCODED*) setQueryVars;;
                  MULTIPART/FORM-DATA*) getQueryFile;;
                                     *) _ERR=1; _OUT='this is not a post';;
  esac

  case $REQUEST_URI in
                *pwdchange) pwdChange;;
               *ssidchange) ssidChange;;
                  *lanaddr) lanAddr;;
                 *updatefw) updateFw;;
                  *usbinit) usbInit;;
                *rebootnow) rebootNow;;
                      *wan) wanSet;;
                   *uptime) upTime;;
                   *iwscan) iwScan;;
                   *sgddns) sgDdns;;
                    *sgvpn) sgOpenvpn;;
                  *testrun) testRun;;
                         *) logThis 'bad action'; headerPrint 405; 
                            echo 'no such thing'; exit 1;;
  esac
fi

## if URL is not (just) /admin
#if [[ "${REQUEST_METHOD^^}" == "GET" ]]; then
  if [[ "${REQUEST_URI/\/admin\//}" ]]; then
   headerPrint '301' '/admin/' 
  fi
#fi

headerPrint '200'
htmlHead

read sgver < /etc/superglue_version
read devmod < /etc/superglue_model
read openwrt < /etc/openwrt_version

. /opt/lib/scripts/jshn-helper.sh

## this does not work when iface isn't configured
IFS=','
wan=( $(ifaceStat wan) )
IFS=$_IFS

sgvpn=$(doUci get sgopenvpnenable)
ddomain=$(doUci get sgddnsdomain)
dsubdomain=$(doUci get sgddnssubdomain)
wanifname=${wan[3]}
wanproto=$(doUci get wanproto)
wanipaddr=${wan[0]}
wangw=${wan[2]}
wandns=${wan[5]}
wanuptime=${wan[4]}
wanssid=$(doUci get wanssid)
wankey=$(doUci get wankey)
%>

<body>
  <h1>Superglue control panel</h1>
  <img src='http://<% _echo "${HTTP_HOST}" %>/resources/img/superglueLogo.png' class='logo'>

<section class='inert'>
  <span style='display:block;'><% printf "System version: %s | Device: %s | OpenWRT: %s" "$sgver" "$devmod" "$openwrt" %></span>
  <span style='display:block;' id='uptime'><% uptime %></span>
</section>

<section>
  <h2>Test run</h2>
  <form method='post' action='/admin/testrun' name='test' class='elem' id='wanconf'>
  <input type='hidden' name='testrun' value='go' class='inline'>
  <input type='submit' value='Run' class='inline'>
  </form>
</section>

<section>
  <h2>Internet connection</h2>
  <form method='post' action='/admin/wan' name='wan' class='elem' id='wanconf'>
  <div style='display:inline-flex'>
  <div style='display:inline-block;'>
  <select name='wanifname' id='wanifname' style='display:block'>
  <option value='eth0' id='eth' <% ( [[ $wanifname =~ ('eth') ]] && _echo 'selected' ) %> >Wired (WAN port)</option>
  <option value='wlan1' id='wlan' <% ( [[ $wanifname =~ ('wlan') ]] && _echo 'selected' ) %> >Wireless (WiFi)</option>
  </select>
  <fieldset id='wanwifi' <% ( [[ $wanifname =~ ('wlan') ]] && _echo "class='show elem'" || _echo "class='hide elem'" ) %>>
    
  <select name='wanssid' id='wanssid' class='elem' style='display:block'>
  <% if [[ -z $wanssid ]]; then
    _echo "<option id='scan' disabled>select a network..</option>"
  else
    _echo "<option id=$wanssid selected>$wanssid</option>"
  fi %>
  </select>
  <input type='password' name='wankey' placeholder='passphrase' value='<% _echo $wankey %>'>

  </fieldset>

  <span class='help'>help</span>
  </div>

  <div style='display:inline-block;'>
  <select name='wanproto' id='wanproto' style='display:block'>
  <option value='dhcp' name='dhcp' id='dhcp' <% ([[ "$wanproto" == 'dhcp' ]] && _echo 'selected') %>>Automatic (DHCP)</option>
  <option value='static' name='stat' id='stat' <% ([[ "$wanproto" == 'static' ]] && _echo 'selected') %>>Manual (Static IP)</option>
  </select>
  <fieldset id='wanaddr' class='elem'>
  <input type='text' name='wanipaddr' id='wanipaddr' value='<% _echo $wanipaddr %>' <% ( [[ $wanproto =~ ('dhcp') ]] && _echo "readonly" ) %> placeholder='ip address'>
  <input type='text' name='wangw' id='wangw' value='<% _echo $wangw %>' <% ( [[ $wanproto =~ ('dhcp') ]] && _echo "readonly" ) %> placeholder='gateway/router'>
  <input type='text' name='wandns' id='wandns' value='<% _echo $wandns %>' <% ( [[ $wanproto =~ ('dhcp') ]] && _echo "readonly" ) %> placeholder='dns server'>
  </fieldset>
  </div>
  </div>
  <div>
  <input type='hidden' name='iface' value='wan' class='inline'>
  <input type='submit' id='wansubmit' value='Apply' class='inline'>
  </form>
  <form method='post' action='/admin/sgvpn' class='inline'>
  <input type='hidden' name='sgvpn' value='toggle' class='inline'>
  <input type='submit' value='<% [[ "$sgvpn" == '1' ]] && _echo 'Disable Superglue VPN service' || _echo 'Enable Superglue VPN service' %>' class='inline'>
  </form>
  </div>
<span class='help'>help</span>
</section>


<section>
  <h2>Domain name</h2>
   <form method='post' action='/admin/sgddns' name='sgddns' id='sgddns'>
     <div style='display:inline-flex'>
      <div style='display:inline-block;'>
        <input type='text' name='sgddnssubdomain' placeholder='domain name' value='<% _echo $dsubdomain %>' class='inline'>
      </div>
      <div style='display:inline-block;'>
        <select name='sgddnsdomain' class='inline'>
          <option value='spgl.it' <% [[ "$ddomain" == 'spgl.it' ]] && _echo 'selected' %>>.spgl.it</option>
          <option value='spgl.cc' <% [[ "$ddomain" == 'spgl.cc' ]] && _echo 'selected' %>>.spgl.cc</option>
          <option value='superglue.it' <% [[ "$ddomain" == 'superglue.it' ]] && _echo 'selected' %>>.superglue.it</option>
      </select>
      </div>
    </div>
    <input type='submit' name='submit' value="Apply">
    <input type='hidden' name='sgddnsupdateurl' value='https://superglue.it/ddns/update'>
  </form>
</section>

<section>
<h2>Local wireless network</h2>
<form method='post' action='/admin/ssidchange'>
  <div style='display:inline-flex'>
  <div style='display:inline-block;'>
    <input type='text' name='lanssid' value='<% doUci get lanssid %>'>
    <input type='password' name='lankey' value='<% doUci get lankey %>'>
  </div>
  <div style='display:inline-block;'>
    <input type='text' name='lanipaddr' value='<% doUci get lanipaddr %>'>
    <input type='hidden' name='iface' value='lan'>
  </div>
  </div>
    <input type='submit' value='Apply' data-wait='Configuring..'>  
</form>
  <span class='help'>help</span>
</section>

<section>
<h2>USB storage</h2>
<% if findUsbstor; then %>

  <% if storageInfo; then %>
    <div>File storage: <% _echo "${_STOR[2]} used, ${_STOR[3]} available" %></div>
    <div>Swap: <% swapInfo && _echo "${_SWAP[1]}" || _echo '<b>n/a</b>' %></div>
  <% else %>
    <div>USB storage device must be initialized</div>
    <form method='post' action='/admin/usbinit'>
    <input type='hidden' name='dev' value='<% _echo $_USBDEV %>'>
    <input type='submit' value='Initialize'>
    </form>
  <% fi %>

<% else %>

  <div><h3>USB storage device not found!</h3>Please check and try again</div>

<% fi %>

<span class='help'>help</span>
</section>

<section>
<h2>Change password</h2>
<form method='post' action='/admin/pwdchange'>
  <div style='display:inline-flex'>
  <div style='display:inline-block;'>
    <input type='text' name='usr' value='admin' readonly>
  </div>
  <div style='display:inline-block;'>
    <input type='password' name='pwd' placeholder='password' value=''>
    <input type='password' name='pwdd' placeholder='password again' value=''>
  </div>
  </div>
    <input type='submit' value='Apply'>
</form>
<span class='help'>help</span>
</section>


<section>
  <h2>Update firmware</h2>
  <form method='post' action='/admin/updatefw' enctype='multipart/form-data'>
  <div id='uploadbox'>
    <input id='uploadfile' placeholder='Select a file..' class='elem' disabled='disabled'>
    <input id='uploadbtn' class='elem' name='fwupload' type='file'>
  </div>
  <div style='display:inline-block;'>
    <input type='checkbox' name='fwreset' id='fw-resetbox' />
    <label for='fw-resetbox'>Reset all settings</label>
  </div>
  <input type='submit' value='Upload' data-wait='Uploading, do NOT interrupt!'>
  </form>
  <span class='help'>help</span>
</section>

<section>
  <h2></h2>
  <form action='/admin/rebootnow' method='post' class='inline'>
    <input type='hidden' name='reboot' value='now' class='inline'>
    <input type='submit' value='Reboot' class='inline'>
  </form>

  <form method='post' action='http://logout@<% _echo ${HTTP_HOST} %>/admin' class='inline'>
    <input type='submit' value='Logout' class='inline'>
  </form>
</section>

<div style='height:200px' name='big-spacer'></div>

<section>
  <h2>Under the hood</h2>
  <h4>Memory</h4>
  <pre><% free %></pre>
  <hr>
  <h4>Storage</h4>
  <pre><% df -h %></pre>
  <hr>
  <h4>Recent log entries</h4>
  <pre><% tail -n10 /www/log/*.log %></pre>
  <hr>
  <h4>Environment</h4>
  <pre><% env %></pre>
  <hr>
</section>

<%
footerBody
exit 0
%>