#!/bin/bash # ############################################################################################## # # Project: Beabloo Hotspot # # Script: cgi to control the setup of networking and display properties # # Author : Oscar Herrera # Date : 2010-09-28 # Last Modif : 2011-02-28 # Change Log : 2010-09-28 --> First Version # : 2010-10-06 --> Some changes # : 2010-10-07 --> More changes # : 2010-10-18 --> Adding aspect ratio detection # : 2010-10-19 --> Check Post Data # : 2011-02-28 --> New Aspect Ratio function # : 2011-09-09 --> Fux bug with Submit Buttons # # Copyright (C) 2008 - 2010 Beabloo. All rights reserved. # ############################################################################################## # # # -------------------------------------------------------------------------------------------- # Variables # -------------------------------------------------------------------------------------------- DEFAULT_SETTINGS_FILE=/opt/www/cgi-bin/default_settings.lst SETTINGS_FILE=/opt/www/cgi-bin/current_settings.lst PENDING_SETTINGS_FILE=/opt/www/cgi-bin/changesToBeApplied.lst APPLY_CHANGES_SCRIPT=/opt/www/cgi-bin/applyChangesAtBootTime.sh LASTCHANGE="NONE" REBOOT_MESSAGE="YOU MUST REBOOT THE MACHINE FOR THE CHANGES TO TAKE EFFECT" RED_HTML="" GREEN_HTML="" BLUE_HTML="" YELLOW_HTML="" ORANGE_HTML="" NOCOLOR_HTML="" HTML_STYLE=" " TIME=`date '+%d/%b/%Y %H:%M:%S'` SERVER=10.10.10.10 PORT=17777 #SERVER=development.beabloo.com #PORT=80 # -------------------------------------------------------------------------------------------- # Functions # -------------------------------------------------------------------------------------------- parseParameters(){ i=1 end=false while [ "$end" = "false" ] do line=`echo ${QUERY_STRING} | cut -d'&' -f $i` if [ "$line" = "${QUERY_STRING}" -o "$line" = "" ] then end="true" fi var=`echo $line | cut -d'=' -f1` value=`echo $line | cut -d'=' -f2` value=`echo "$value" | sed 's/\([a-z]*\).*/\1/'` if [ "$var" != "" ] then eval $var="$value" fi i=`expr $i + 1` done } initContentType(){ echo "Content-type: text/html" echo "" echo "" } # FUNCTION TO VALIDATE IP ADDRESS function validIP() { local IP=${1} local STAT=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 ]] STAT=$? fi return ${STAT} } # DECODES AN URL-STRING # AN URL ENCODING HAS "+" INSTEAD OF SPACES # AND NO SPECIAL CHARACTERS BUT "%HEX%" function urlDec(){ # REPLACE +-spaces BY %20 (HEX) local VALUE=${*//+/%20} # SPLIT AT % PREPEND \x FOR PRINTF for PART in ${VALUE//%/ \\x}; do # OUTPUT DECODED CHAR printf "%b%s" "${PART:0:4}" "${PART:4}" done } # ENCODED AN URL-STRING # DOES THE SIMPLEST ENCODING: EVERYTHING IS ENCODED function urlEnc(){ for CHAR in $(echo -n $* | xxd -c 1 -p -u); do printf "%%%s" ${CHAR} done } # FOR ALL GIVEN QUERY STRINGS # PARSE THEM AND SET SHELL VARIABLES function setQueryVars(){ # ESCAPE * AS %2A local VARS=${*//\*/%2A} if [ -n "${VARS}" ] ; then SETTINGS="" ; fi # SPLIT AT & for VAR in ${VARS//&/ }; do # DECODE VALUE AFTER = local VALUE=$(urlDec "${VAR#*=}") # CHANGE \ TO \\ FOR LATER VALUE=${VALUE//\\/\\\\} # EVALUATE ASSIGNMENT eval "CGI_${VAR%=*}=\"${VALUE//\"/\\\"}\"" # HTML COMMENT echo "" # MAKING SETTINGS VARIABLE if [ "${VAR%=*}" != "action" ] ; then SETTINGS="${SETTINGS}\n${VAR%=*}=${VALUE//\"/\\\"}" fi done } getFileData(){ FILE="${1}" FILE_TIMESTAMP=`/usr/bin/stat --format=%Y ${FILE}` LASTCHANGE=`date "+%d/%m/%Y %H:%M" --date=@${FILE_TIMESTAMP}` SETTINGS="" if [ -f ${FILE} ] ; then for PARAM in `cat ${FILE} | egrep -v "^#|^$"`; do eval "CGI_${PARAM%=*}=\"${PARAM#*=}\"" if [ "${PARAM%=*}" != "action" ] ; then SETTINGS="${SETTINGS}\n${PARAM%=*}=${PARAM#*=}" fi done fi } getPostData(){ if [ "$REQUEST_METHOD" = "POST" ]; then if [ "$CONTENT_LENGTH" -gt 0 ]; then read -n $CONTENT_LENGTH POST_DATA <&0 fi fi } checkPostData(){ local STAT=0 local NETWORK_EMPTY_CHECK=0 local PROXY_EMPTY_CHECK=0 for SETTING in `echo -e ${SETTINGS}` do if [ ${STAT} -eq 0 ]; then PARAM_NAME=`echo ${SETTING} | cut -d"=" -f1` PARAM_VALUE=`echo ${SETTING} | cut -d"=" -f2` case "${PARAM_NAME}" in "network_ip") if ! [ -z "${PARAM_VALUE}" ]; then validIP ${PARAM_VALUE} if ! [ `echo $?` -eq 0 ]; then STAT=10; fi else ((NETWORK_EMPTY_CHECK++)) fi ;; "network_mask") if ! [ -z "${PARAM_VALUE}" ]; then validIP ${PARAM_VALUE} if ! [ `echo $?` -eq 0 ]; then STAT=11; fi else ((NETWORK_EMPTY_CHECK++)) fi ;; "network_gw") if ! [ -z "${PARAM_VALUE}" ]; then validIP ${PARAM_VALUE} if ! [ `echo $?` -eq 0 ]; then STAT=12; fi else ((NETWORK_EMPTY_CHECK++)) fi if !([ ${NETWORK_EMPTY_CHECK} -eq 0 ] || [ ${NETWORK_EMPTY_CHECK} -eq 3 ]); then STAT=13; fi ;; "network_dnsforwarding") if ! [ -z "${PARAM_VALUE}" ]; then validIP ${PARAM_VALUE} if ! [ `echo $?` -eq 0 ]; then STAT=20; fi fi ;; "network_proxy_host") if ! [ -z "${PARAM_VALUE}" ]; then # First check that if an IP validIP ${PARAM_VALUE} if ! [ `echo $?` -eq 0 ]; then # Check if is a FQDN # egrep --silent "^[A-Za-z0-9_-]*\.[A-Za-z0-9_-]*\.[A-Za-z]*$" ${PARAM_VALUE} || STAT=30 echo ${PARAM_VALUE} | egrep --silent "^[A-Za-z0-9_-]*\.[A-Za-z0-9_-]*\.[A-Za-z]*$" || STAT=30 fi else ((PROXY_EMPTY_CHECK++)) fi ;; "network_proxy_port") if ! [ -z "${PARAM_VALUE}" ]; then if ! ([ ${PARAM_VALUE} -gt 1024 ] && [ ${PARAM_VALUE} -lt 65536 ]); then STAT=31; fi else ((PROXY_EMPTY_CHECK++)) fi if !([ ${PROXY_EMPTY_CHECK} -eq 0 ] || [ ${PROXY_EMPTY_CHECK} -eq 2 ]); then STAT=32; fi ;; esac fi done return ${STAT} } grabDataToFile(){ # echo -e "
#GENERATED @`date` FROM ${REMOTE_ADDR}${SETTINGS}
" echo -e "#GENERATED @`date` FROM ${REMOTE_ADDR}${SETTINGS}" > ${PENDING_SETTINGS_FILE} } grabDefaultDataToFile(){ getFileData ${DEFAULT_SETTINGS_FILE} grabDataToFile } applyChanges(){ sudo -n ${APPLY_CHANGES_SCRIPT} } # GREATEST COMMON DIVISOR # EUCLID'S ALGORITHM gcd(){ local DIVIDEND=${1} local DIVISOR=${2} local REMAINDER=1 until [ "${REMAINDER}" -eq 0 ] ; do REMAINDER=$((${DIVIDEND}%${DIVISOR})) DIVIDEND=${DIVISOR} DIVISOR=${REMAINDER} done return ${DIVIDEND} } getAspectRatio(){ ASPECT_RATIO="" local RESOLUTION=${1} local VIDEO_WIDTH=`echo ${RESOLUTION} | cut -d "x" -f 1` local VIDEO_HEIGHT=`echo ${RESOLUTION} | cut -d "x" -f 2` # ASPECT RATIO gcd ${VIDEO_WIDTH} ${VIDEO_HEIGHT} GCD=$? if [ ${GCD} -gt 50 ] ; then ASPECT_RATIO="$((${VIDEO_WIDTH}/${GCD})):$((${VIDEO_HEIGHT}/${GCD}))" else if [ "${RESOLUTION}" = "1680x1050" ] ; then ASPECT_RATIO="~16:10"; fi if [ "${RESOLUTION}" = "1440x900" ] ; then ASPECT_RATIO="~16:10"; fi if [ "${RESOLUTION}" = "1280x800" ] ; then ASPECT_RATIO="~16:10"; fi if [ "${RESOLUTION}" = "1920x1080" ] ; then ASPECT_RATIO="~16:9"; fi if [ "${RESOLUTION}" = "1776x1000" ] ; then ASPECT_RATIO="~16:9"; fi if [ "${RESOLUTION}" = "1366x768" ] ; then ASPECT_RATIO="~16:9"; fi if [ "${RESOLUTION}" = "1360x768" ] ; then ASPECT_RATIO="~16:9"; fi if [ "${RESOLUTION}" = "1280x720" ] ; then ASPECT_RATIO="~16:9"; fi if [ "${RESOLUTION}" = "1152x648" ] ; then ASPECT_RATIO="~16:9"; fi if [ "${RESOLUTION}" = "720x400" ] ; then ASPECT_RATIO="~16:9"; fi if [ "${RESOLUTION}" = "1600x1200" ] ; then ASPECT_RATIO="~4:3"; fi if [ "${RESOLUTION}" = "1400x1050" ] ; then ASPECT_RATIO="~4:3"; fi if [ "${RESOLUTION}" = "1280x1024" ] ; then ASPECT_RATIO="~4:3"; fi if [ "${RESOLUTION}" = "1280x960" ] ; then ASPECT_RATIO="~4:3"; fi if [ "${RESOLUTION}" = "1152x864" ] ; then ASPECT_RATIO="~4:3"; fi if [ "${RESOLUTION}" = "1024x768" ] ; then ASPECT_RATIO="~4:3"; fi if [ "${RESOLUTION}" = "832x624" ] ; then ASPECT_RATIO="~4:3"; fi if [ "${RESOLUTION}" = "800x600" ] ; then ASPECT_RATIO="~4:3"; fi if [ "${RESOLUTION}" = "640x480" ] ; then ASPECT_RATIO="~4:3"; fi if [ -z "${ASPECT_RATIO}" ] && [ ${GCD} -gt 0 ] ; then ASPECT_RATIO="$((${VIDEO_WIDTH}/${GCD})):$((${VIDEO_HEIGHT}/${GCD}))" fi fi } printGrabError(){ local ERROR_STAT=$1 case ${ERROR_STAT} in 10) ERROR_MESSAGE="Error Code 10: Network Setup: Incorrect IP" ;; 11) ERROR_MESSAGE="Error Code 11: Network Setup: Incorrect Mask" ;; 12) ERROR_MESSAGE="Error Code 12: Network Setup: Incorrect Gateway" ;; 13) ERROR_MESSAGE="Error Code 13: Network Setup: Empty Fields" ;; 20) ERROR_MESSAGE="Error Code 20: DNS Forwarding: Incorrect IP" ;; 30) ERROR_MESSAGE="Error Code 30: Proxy setup: Incorrect Proxy" ;; 31) ERROR_MESSAGE="Error Code 31: Proxy setup: Incorrect Port" ;; 32) ERROR_MESSAGE="Error Code 32: Proxy setup: Empty Fields" ;; *) ERROR_MESSAGE="Error Code Uknown" ;; esac echo "" echo "" echo "" echo "" } printRebootToApply(){ echo "

${RED_HTML}

[ ERROR ] ${ERROR_MESSAGE}${NOCOLOR_HTML}


" echo "" echo "" echo "" } printOutputHeader(){ echo "" echo "" echo ${HTML_STYLE} echo ":: ${HOSTNAME} setup ::" echo "" echo "" echo "
" echo "

${GREEN_HTML}

[ INFO ] ${REBOOT_MESSAGE} ${NOCOLOR_HTML}


" echo "" echo "" echo "" } printOutputFooter(){ echo "
" echo "
" echo "Copyright © 2008 - 2010 Beabloo. All rights reserved." echo "" } printForm(){ echo "" echo "

[ Beabloo hotspot setup ]

(Settings for ${HOSTNAME})

" echo "" echo "
" echo "" echo "" echo "
" echo "
" echo "Network setup:
" echo "IP      :
" echo "Mask    :
" echo "Gateway :
" echo "
" echo "" echo "
" echo "
" echo "DNS forwarding:
" echo "Server  :
" echo "
" echo "" echo "
" echo "
" echo "Proxy setup:
" echo "Host    :
" echo "Port    :
" echo "


" echo "Display Resolution:
" RESOLUTIONS="" export DISPLAY=:0 RESOLUTIONS=`sudo -n /usr/bin/xrandr -q | grep '^ ' | awk '{print $1}' | sort -rn | uniq` CURRENT_RESOLUTION=`sudo -n /usr/bin/xrandr -q | grep '^ ' | grep "\*" | awk '{print $1}'` if [ -z "${RESOLUTIONS}" ] ; then echo "${RED_HTML}[ ERROR ]${NOCOLOR_HTML} No display detected
" else for ENTRY in `echo ${RESOLUTIONS}` do getAspectRatio ${ENTRY} RESOLUTION_NOTE="" if [ "${ENTRY}" = "${CURRENT_RESOLUTION}" ] ; then echo " ${ENTRY} ${RESOLUTION_NOTE} (Current)
" else if [ "${ENTRY}" = "${CGI_display_resolution}" ] ; then echo " ${ENTRY} ${RESOLUTION_NOTE} (New)
" else echo " ${ENTRY} ${RESOLUTION_NOTE}
" fi fi done fi echo "
" echo "" echo "
" echo "
" sudo -n /usr/bin/xrandr -q | grep " connected " | grep --silent normal && ORIENTATION_POSSIBLE=true || ORIENTATION_POSSIBLE=false if ! ${ORIENTATION_POSSIBLE} ; then DISABLED="disabled=\"disabled\"" HWNOTE="
" else DISABLED="" HWNOTE="" fi echo "Display Orientation:
" if [ "${CGI_display_orientation}" = "normal" ] || [ -z "${CGI_display_orientation}" ] ; then echo " Normal   Inverted
" echo " Left     Right
" elif [ "${CGI_display_orientation}" = "inverted" ] ; then echo " Normal   Inverted
" echo " Left     Right
" elif [ "${CGI_display_orientation}" = "left" ] ; then echo " Normal   Inverted
" echo " Left     Right
" elif [ "${CGI_display_orientation}" = "right" ] ; then echo " Normal   Inverted
" echo " Left     Right
" fi echo "${HWNOTE}" echo "
" sudo -n /usr/bin/xrandr -q | grep " connected " | grep --silent axis && AXIS_POSSIBLE=true || AXIS_POSSIBLE=false if ! ${AXIS_POSSIBLE} ; then DISABLED="disabled=\"disabled\"" HWNOTE="
" else DISABLED="" HWNOTE="" fi echo "Display Reflection:
" if [ "${CGI_display_reflection}" = "normal" ] || [ -z "${CGI_display_reflection}" ] ; then echo " Normal
" echo " Inverted
" elif [ "${CGI_display_reflection}" = "inverted" ] ; then echo " Normal
" echo " Inverted
" fi echo "${HWNOTE}" echo "


" echo "Sound:
" if [ "${CGI_sound_output}" = "inactive" ] || [ -z "${CGI_sound_output}" ] ; then echo " Inactive
" echo " Active
" elif [ "${CGI_sound_output}" = "active" ] ; then echo " Inactive
" echo " Active
" fi echo "

" echo "" echo "" echo "
" echo "
" echo "" echo "
" echo "
" echo "

" } # -------------------------------------------------------------------------------------------- # Main # -------------------------------------------------------------------------------------------- # IF SETTINGS FILE IS PRESENT # INITIALIZE VARIABLES WITH FILE VALUES getFileData ${SETTINGS_FILE} # GET DATA RECEIVED BY HTTP POST getPostData # INIT HTML CONTENT TYPE initContentType # PRINT OUTPUT HEADER printOutputHeader # NEW PARSE PARAMETERS FUNCTION setQueryVars ${POST_DATA} # CHECKS ACTIONS TO RUN CORRECT FUNCTIONS if [ "${CGI_action}" = "Apply changes" ] ; then # CHECKS IF POST DATA ARE CORRECT checkPostData STATUS=`echo $?` if [ ${STATUS} -eq 0 ]; then # GRAB NEW SETTINGS TO FILE grabDataToFile # APPLY CHANGES applyChanges # PRINT REBOOT MESSAGE printRebootToApply else printGrabError ${STATUS} fi elif [ "${CGI_action}" = "Reset defaults" ] ; then # GRAB DEFAULT SETTINGS TO FILE grabDefaultDataToFile # APPLY CHANGES applyChanges fi # PRINT FORM printForm # PRINT HTML FOOTER printOutputFooter