Timelapse_Camera_Firmware/Software/3G Modem/Sakis3G/sakis3g.sh

8503 lines
301 KiB
Bash

#!/bin/sh
MYVERSION="0.2.0e"
# Transform debug to DEBUG, in order to declare debug method.
if [ -n "${debug}" ]; then
echo "Warning: debug variable is obsolete. Use DEBUG instead." >> /dev/stderr
export DEBUG="${debug}"
unset debug
fi
# Display formatted debug output if DEBUG variable is set.
# This method should have as less dependencies as possible.
debug() {
if [ "a$1" != "arun_command" -a "a$1" != "ashow_file" -a -z "${DEBUG}" ]; then
return 0
elif [ "a$1" = "arun_command" -a -z "${DEBUG}" ]; then
shift
sh -c "$*" > /dev/null 2> /dev/null
return $?
elif [ "a$1" = "arun_command" -a -n "${DEBUG}" ]; then
shift
printf "/-------------------------------------------------------------------------------\n" >> "/dev/stderr"
printf "[%.5d] [%s] Will now run command: \'%s\'\n" "$$" "`date "+%H:%M:%S"`" "${*}" >> "/dev/stderr"
printf "/-------------------------------------------------------------------------------\n" >> "/dev/stderr"
sh -c "$*" >> "/dev/stderr" 2>&1
rdebug=$?
printf "\-------------------------------------------------------------------------------\n" >> "/dev/stderr"
printf "[%.5d] [%s] Command returned %d.\n" "$$" "`date "+%H:%M:%S"`" "${rdebug}" >> "/dev/stderr"
printf "\-------------------------------------------------------------------------------\n" >> "/dev/stderr"
return ${rdebug}
elif [ -z "${DEBUG}" ]; then
return 0
elif [ "a$1" = "ashow_file" ]; then
if [ -f "$2" ]; then
printf "/-------------------------------------------------------------------------------\n" >> "/dev/stderr"
printf "[%.5d] [%s] Will now display contents of: \'%s\'\n" "$$" "`date "+%H:%M:%S"`" "$2" >> "/dev/stderr"
printf "/-------------------------------------------------------------------------------\n" >> "/dev/stderr"
cat "$2" >> "/dev/stderr"
printf "\-------------------------------------------------------------------------------\n" >> "/dev/stderr"
ls -ld "$2" >> "/dev/stderr"
printf "\-------------------------------------------------------------------------------\n" >> "/dev/stderr"
else
printf "/-------------------------------------------------------------------------------\n" >> "/dev/stderr"
printf "[%.5d] [%s] File does not exist: \'%s\'\n" "$$" "`date "+%H:%M:%S"`" "$2" >> "/dev/stderr"
printf "\-------------------------------------------------------------------------------\n" >> "/dev/stderr"
fi
return 0
else
rfmt="$1"
shift
if [ "a${YESFUNCNAME}" = "a" ]; then
if [ "$#" -ge "1" ]; then
printf "[%.5d] [%s] ${rfmt}" "$$" "`date "+%H:%M:%S"`" "${@}" >> "/dev/stderr"
else
printf "[%.5d] [%s] ${rfmt}" "$$" "`date "+%H:%M:%S"`" >> "/dev/stderr"
fi
else
if [ "$#" -ge "1" ]; then
printf "[%.5d] [%s] [%-20s] ${rfmt}" "$$" "`date "+%H:%M:%S"`" "${FUNCNAME[1]}" "${@}" >> "/dev/stderr"
else
printf "[%.5d] [%s] [%-20s] ${rfmt}" "$$" "`date "+%H:%M:%S"`" "${FUNCNAME[1]}" >> "/dev/stderr"
fi
fi
unset rfmt
fi
return 0
}
# Print debug header
debug_header() {
if [ -n "${DEBUG}" ]; then
echo >> "/dev/stderr"
echo "-------------------------------------------" >> "/dev/stderr"
echo "Sakis3G ${MYVERSION} running on DEBUG mode." >> "/dev/stderr"
echo "-------------------------------------------" >> "/dev/stderr"
date >> "/dev/stderr"
echo "-------------------------------------------" >> "/dev/stderr"
if [ "a${allargs}" = "a" ]; then
echo "Command line was: $0 $@" >> "/dev/stderr"
else
echo "Command line was: $0 ${allargs}" >> "/dev/stderr"
fi
echo "Running with PID: $$" >> "/dev/stderr"
echo "-------------------------------------------" >> "/dev/stderr"
echo "Environment is:" >> "/dev/stderr"
set >> "/dev/stderr"
echo "-------------------------------------------" >> "/dev/stderr"
echo "Will now proceed with Sakis3G execution." >> "/dev/stderr"
echo "-------------------------------------------" >> "/dev/stderr"
fi
}
need_arg() {
[ "a`eval echo \\\$$1 2> /dev/null`" != "a" ] && return 0
case "$1" in
foldwrapping)
export foldwrapping=60
;;
pppint)
export pppint="ppp0"
;;
CHAT_ABORT_STRINGS)
# Abort strings that chat program may encounter
export CHAT_ABORT_STRINGS="ABORT BUSY ABORT ERROR ABORT BLOCKED ABORT NOCARRIER"
;;
BAUD)
export BAUD="460800"
;;
PPPD_OPTIONS)
# Options passed to pppd when called directly
export PPPD_OPTIONS="modem crtscts -detach defaultroute dump noipdefault usepeerdns usehostname ktune logfd 2 noauth name sakis3g lock maxfail 3"
;;
PPPD_PEERS)
# Directory where pppd keeps its peers
export PPPD_PEERS=/etc/ppp/peers
;;
SERIALDRIVERS)
export SERIALDRIVERS="ftdi_sio ipaq safe_serial usbserial visor"
;;
LOGPOSITION)
export LOGPOSITION="/var/log/sakis3g.log"
;;
XOSDFONT)
export XOSDFONT='-*-freesans-bold-r-*-*-36-*-*-*-*-*-*-*'
;;
AOSDFONT)
export AOSDFONT='DejaVuSans 36'
;;
MENUFONT)
export MENUFONT="-monotype-arial-medium-r-normal-*-18-*-*-*-*-*-*-*"
;;
*)
debug "No default value for %s was found.\n" "$1"
;;
esac
debug "Loaded default value for %s: %s\n" "$1" "`eval echo \\\$$1 2> /dev/null`"
}
sanitize() {
echo "$@" 2> /dev/null | ${trbin} "\\" " " 2> /dev/null | ${trbin} "\"" " " | ${trbin} "'" " " | ${trbin} "\`" " "
}
release_X_cookie() {
debug "Disposing stolen X session cookie for %s.\n" "${XCOOKIE}"
if [ -n "${XCOOKIE}" ] && find_binary "xauth"; then
# If having an authority file that does not belong to us, unset it.
if [ "a${XAUTHORITY}" = "a${runhome}/.Xauthority" -a "a$HOME" != "a${runhome}" ]; then
unset XAUTHORITY
fi
found=`${xauthbin} nlist ${XCOOKIE} | ${wcbin} -l`
found=`echo ${found}`
if [ "a${found}" = "a0" ]; then
debug "Cookie already disposed.\n"
else
${xauthbin} remove ${XCOOKIE}
found=`xauth nlist ${XCOOKIE} | ${wcbin} -l`
found=`echo ${found}`
if [ "a${found}" = "a0" ]; then
debug "Cookie disposed as it should.\n"
unset XCOOKIE
else
debug "Failed to dispose cookie.\n"
fi
fi
unset found
fi
}
# Callback function called on EXIT to execute traps.
exittrap() {
if [ -n "${TRAPS}" ]; then
debug "Now executing traps.\n"
for tr in ${TRAPS}
do
debug "Executing trap \"%s\".\n" "${tr}"
${tr}
done
else
debug "No exit traps defined.\n"
fi
if ppp_fast_status; then
debug "\n>>>>>>>>> If program is paused, you may freely press Ctrl+C. <<<<<<<<<\n>>> This happens due to DEBUG being set. Connection will NOT drop. <<<\n"
fi
}
# Adds trap to be executed on EXIT
addexittrap() {
[ "a$1" = "a" ] && return 0;
if [ "a${TRAPS}" = "a" ]; then
trap exittrap EXIT
debug "Established trap handler.\n"
fi
if ! strinstr "$1" "${TRAPS}" " "; then
TRAPS="$1 ${TRAPS}"
debug "Traps are now: %s\n" "${TRAPS}"
else
debug "Trap %s already registered.\n" "${1}"
fi
}
translate_load() {
unset translatebase
! find_binary "printf" && return 1
! find_binary "grep" && return 1
! find_binary "head" && return 1
! find_binary "tail" && return 1
! find_binary "sed" && return 1
! find_binary "cat" && return 1
! find_binary "cut" && return 1
! find_binary "tr" && return 1
if [ "a${notranslate}" != "a" ]; then
export notranslate=yes; unset foldwrapping; need_arg "foldwrapping"
return 1
fi
if [ "a${TRANSLATION}" != "a" ] && [ -f "${TRANSLATION}" ]; then
debug "Requested to use file %s for translations.\n" "${TRANSLATION}"
translatebase=`${catbin} "${TRANSLATION}" 2> /dev/null`
elif [ "a${PROVIDER}" != "a" ] && [ -x "${PROVIDER}" ]; then
translatelocale="${LC_MESSAGES}"
[ "a${translatelocale}" = "a" ] && translatelocale="${LC_ALL}"
[ "a${translatelocale}" = "a" ] && translatelocale="${LOCALE}"
[ "a${translatelocale}" = "a" ] && translatelocale="${LANG}"
if [ "a${translatelocale}" = "a" ]; then
debug "No locale reported by system. Will not be using translations.\n"
export notranslate=yes; unset foldwrapping; need_arg "foldwrapping"
return 1
fi
debug "Locale %s found in environment.\n" "${translatelocale}"
translatelocale=`echo ${translatelocale} | ${grepbin} -i "UTF\(.*\)8"`
if [ "a${translatelocale}" = "a" ]; then
debug "Reported locale is not UTF-8. Will not be using translations.\n"
export notranslate=yes; unset foldwrapping; need_arg "foldwrapping"
return 1
fi
translatelocale=`echo ${translatelocale} | ${cutbin} -d. -f1 | ${sedbin} -e "s/$/.UTF-8/g"`
debug "Will attempt to get translation file from package: %s.\n" "messages/${translatelocale}"
translatebase=`${PROVIDER} getfile "messages/${translatelocale}" 2> /dev/null`
else
debug "Unable to retrieve any translation file. Will not be using translations.\n"
export notranslate=yes; unset foldwrapping; need_arg "foldwrapping"
return 1
fi
helperfactor=`echo "${translatebase}" 2> /dev/null | ${headbin} -1 | ${grepbin} "^##\([0-9]\)$" | ${sedbin} -e "s/^##//g"`
[ "a${helperfactor}" = "a" ] && helperfactor=1
unset foldwrapping; need_arg "foldwrapping";
foldwrapping=`expr ${foldwrapping} \* ${helperfactor} 2> /dev/null`; foldwrapping=`echo ${foldwrapping}`
[ "a${foldwrapping}" = "a" ] && unset foldwrapping
need_arg "foldwrapping"; unset helperfactor
translatebase=`${printfbin} "%s" "${translatebase}" | ${grepbin} -v "^#"`
if [ "a${translatebase}" = "a" ]; then
debug "No translations retrieved from file. Will not be using translations.\n"
export notranslate=yes; unset foldwrapping; need_arg "foldwrapping"
return 1
fi
export foldwrapping
debug "Translations loaded. Wrapping at %d bytes.\n" "${foldwrapping}"
return 0
}
# Translates argument to locale
translate_text() {
if [ "a${notranslate}" != "a" ]; then
${printfbin} "%s" "$1"
return 0
fi
[ "a${translatebase}" = "a" ] && translate_load
if [ "a${notranslate}" != "a" -o "a${translatebase}" = "a" ]; then
${printfbin} "%s" "$1"
return 0
fi
# Safer, still slower way to translate
#texttomatch=`${printfbin} "%s" "$1" | ${trbin} "\\n" ".." | ${trbin} "\n" "." | ${trbin} "\t" "." | ${trbin} "\\\\\\\" "." | ${sedbin} -e "s/\\\\\\/\./g" | ${sedbin} -e "s/\"/\./g"`
texttomatch=`${printfbin} "%s" "$1" | ${trbin} "\\\\\\\" "." | ${trbin} "\\\\\"" "." | ${trbin} "\n" "."`
# Comment below is to help gedit in colouring text
# `"`
if [ -n "${showtext}" ]; then
debug "Text to check: %s\n" "${1}"
debug "Text to match: %s\n" "${texttomatch}"
fi
texttranslated=`${printfbin} "%s" "${translatebase}" | ${grepbin} -A 1 -G "^.${texttomatch}.$" | ${headbin} -2 | ${tailbin} -1 | ${sedbin} -e "s/^\"\(.*\)\"$/\1/g"`
unset texttomatch
if [ "a${texttranslated}" != "a" -a "a${texttranslated}" != "a\"" ]; then
[ -n "${showtext}" ] && debug "Text returned: %s\n" "${texttranslated}"
${printfbin} "%s" "${texttranslated}"
else
[ -n "${showtext}" ] && debug "No translation found, returning original text: %s\n" "$1"
${printfbin} "%s" "$1"
fi
unset texttranslated
return 0
}
# Safety helper
safe_invoke() {
if [ "a${NOFUNCNAME}" != "a" ]; then
debug "FIXME: Called %s without FUNCNAME variables available.\n" "$0"
return 99
fi
if [ "a${FUNCNAME[1]}" = "a" ]; then
debug "FIXME: %s called without FUNCNAME[1] being available.\n"
return 99
fi
debug "Function %s requested to call it in a safe manner.\n" "${FUNCNAME[1]}"
callertimeout="$1"; callertimeout=`expr ${callertimeout} + 1 - 1 2> /dev/null`
if [ "a${callertimeout}" = "a$1" ]; then
debug "Timeout set by %s to %d seconds.\n" "${FUNCNAME[1]}" "${callertimeout}"
shift
else
callertimeout=5
debug "Caller did not provide timeout. Using default (%d seconds).\n" "${callertimeout}"
fi
if [ "a${safetimeout}" != "a" ]; then
unset callertimeout
debug "FIXME: However, we are already within a safe session.\n"
${FUNCNAME[1]} "safe" "$@"
ret=$?
debug "FIXME: Function %s returned from within a nested safe session.\n" "${FUNCNAME[1]}"
return ${ret}
elif [ "a${nosafety}" != "a" ]; then
unset callertimeout
debug "However, config instructs not to use safety-checks.\n"
${FUNCNAME[1]} "safe" "$@"
ret=$?
unset TIMEOUTOCCURED
debug "Unsafe function %s returned.\n" "${FUNCNAME[1]}"
return ${ret}
fi
safetimeout="${callertimeout}"
callermethod="${FUNCNAME[1]}"
unset TIMEOUTOCCURED; unset callertimeout
if find_binary "mktemp"; then
debug "Using %s to store standard output and error of %s.\n" "${mktempbin}" "${callermethod}"
outputholder=`${mktempbin} -p /tmp -q sakis3g.safe.output.$$.XXXXXXXX`
errorholder=`${mktempbin} -p /tmp -q sakis3g.safe.error.$$.XXXXXXXX`
fi
if [ "a${outputholder}" = "a" ]; then
debug "Using backup method for creating temporary output holder.\n"
outputholder="/tmp/sakis3g.unsafe.output.$$"
fi
if [ "a${errorholder}" = "a" ]; then
debug "Using backup method for creating temporary output holder.\n"
errorholder="/tmp/sakis3g.unsafe.error.$$"
fi
debug "Will store output at: %s\n" "${outputholder}"
debug "Will store error at: %s\n" "${errorholder}"
debug "Initiating safe session for %s (%d seconds timeout).\n" "${callermethod}" "${safetimeout}"
"${callermethod}" "safe" "$@" > "${outputholder}" 2> "${errorholder}" &
safecallerpid=$!; eval "disown -a" > /dev/null 2> /dev/null
debug "Method spawned with PID %d.\n" "${safecallerpid}"
while ! notrunning "${safecallerpid}"
do
debug "%s still runs. %d seconds before killing.\n" "${callermethod}" "${safetimeout}"
if [ "a${safetimeout}" = "a0" ]; then
debug "Time expired with no results.\n"
if find_binary "kill"; then
debug "Will attempt to kill process with PID %d.\n" "${safecallerpid}"
! notrunning "${safecallerpid}" && debug run_command "${killbin} -1 ${safecallerpid}"
! notrunning "${safecallerpid}" && debug run_command "${killbin} -9 ${safecallerpid}"
! notrunning "${safecallerpid}" && debug "Failed to kill it.\n"
fi
if find_binary "rm"; then
debug "Will attempt to unlink temporary holders.\n"
debug run_command "${rmbin} -f \"${outputholder}\" \"${errorholder}\""
fi
export TIMEOUTOCCURED="${callermethod}"
unset callermethod; unset safecallerpid; unset outputholder; unset errorholder
debug "Method %s failed to respond within timeout.\n"
unset safetimeout
return 99
fi
safetimeout=`expr ${safetimeout} - 1`; safetimeout=`echo ${safetimeout}`
sleep 1
done
debug "Method returned while %d seconds were remaining.\n" "${safetimeout}"
debug show_file "${outputholder}"
debug show_file "${errorholder}"
if find_binary "cat"; then
debug "Will now route output and error to mine.\n"
[ -f "${outputholder}" ] && ${catbin} "${outputholder}" 2> /dev/null
[ -f "${errorholder}" ] && ${catbin} "${errorholder}" >> /dev/stderr 2> /dev/null
fi
if find_binary "rm"; then
debug "Will attempt to unlink temporary holders.\n"
debug run_command "${rmbin} -f \"${outputholder}\" \"${errorholder}\""
fi
debug "Method %s responded within timeout specified.\n" "${FUNCNAME[1]}"
unset callermethod; unset safecallerpid; unset outputholder; unset errorholder
unset safetimeout
debug "Left safe mode.\n"
return 0
}
safe_lsusb() {
if [ "a$1" != "asafe" -a "a${NOFUNCNAME}" = "a" ]; then
safe_invoke "5" "$@"
return $?
elif [ "a${NOFUNCNAME}" = "a" ]; then
shift
fi
[ "a${lsusbbin}" != "a" ] && ${lsusbbin} "$@"
}
safe_chat() {
if [ "a$1" != "asafe" -a "a${NOFUNCNAME}" = "a" ]; then
safe_invoke "10" "$@"
return $?
elif [ "a${NOFUNCNAME}" = "a" ]; then
shift
fi
[ "a${chatbin}" != "a" ] && ${chatbin} "$@"
}
safe_cat() {
if [ "a$1" != "asafe" -a "a${NOFUNCNAME}" = "a" ]; then
safe_invoke "5" "$@"
return $?
elif [ "a${NOFUNCNAME}" = "a" ]; then
shift
fi
[ "a${catbin}" != "a" ] && ${catbin} "$@"
}
# Formats text
format_text() {
if find_binary "printf"; then
rfmt="$1"
[ "$#" -gt "0" ] && shift
rfmt=`translate_text "${rfmt}"`
if [ "$#" -ge "1" ]; then
${printfbin} "${rfmt}" "${@}"
else
${printfbin} "${rfmt}"
fi
unset rfmt
else
echo "${@}"
fi
}
# Clears terminal line if required
term_clearline() {
[ "a${COLUMNS}" != "a" ] && find_binary "printf" && [ -n "${interactive}" ] && ${printfbin} "\r%.-${COLUMNS}s\r" "" && return 0
[ "a${COLUMNS}" = "a" ] && find_binary "printf" && [ -n "${interactive}" ] && ${printfbin} "\r%s\r" " " && return 0
}
# Prints argument to terminal
term_print() {
term_clearline
echo "${@}"
}
# Sends error to terminal, colored if possible.
term_error() {
if find_binary "grep" && [ -n "${interactive}" ]; then
term_print "$@" | ${grepbin} --color "."
else
term_print "$@"
fi
}
term_verbose() {
if [ -n "${interactive}" ]; then
if find_binary "grep" && find_binary "tr"; then
currentlyverbosing=yes
term_print "$@" | GREP_COLOR=2 ${grepbin} --color=always "." | ${trbin} "\n" " "
unset currentlyverbosing; lastlineverbose=yes
else
term_print "$@"
fi
fi
}
term_notify() {
if find_binary "grep" && [ -n "${interactive}" ]; then
term_print "$@" | GREP_COLOR=1 ${grepbin} --color "."
else
term_print "$@"
fi
}
select_example() {
examplevariable=`selection_argument variable "$@"`
exampleoptions=`selection_argument options "$@"`
[ "a${exampleoptions}" != "a" ] && format_text "\nAvailable options are:\n" && format_text "%s\n" "${exampleoptions}"
[ "a${exampleoptions}" = "a" ] && exampleoptions="foo"
format_text "\nExample:\n"
format_text "\t$ %s [...] %s=\"%s\"\n\r\n" "${ME}" "${examplevariable}" "`echo ${exampleoptions} | ${cutbin} -d\ -f1`"
unset exampletitle; unset examplevariable; unset exampleoptions
}
term_select_example() {
examplevariable=`selection_argument variable "$@"`
exampleoptions=`selection_argument options "$@"`
[ "a${exampleoptions}" != "a" ] && notify "\nAvailable options are:\n" && notify "%s\n" "${exampleoptions}"
[ "a${exampleoptions}" = "a" ] && exampleoptions="foo"
notify "\nExample:\n"
notify "\t$ %s %s=\"%s\"\n\r\n" "${ME}" "${examplevariable}" "`echo ${exampleoptions} | ${cutbin} -d\ -f1`"
unset exampletitle; unset examplevariable; unset exampleoptions
}
term_select() {
options=`selection_argument options "$@" | ${wcbin} -l`; options=`echo ${options}`
variable=`selection_argument variable "$@"`
if [ "a${options}" != "a1" ]; then
exampletitle=`selection_argument title "$@"`
notify "%s by using %s variable, or by enabling interactive mode.\n" "${exampletitle}" "${variable}"
notify "\t$ %s --interactive %s\n" "${ME}" "${allargs}"
unset exampletitle
term_select_example "$@"
else
eval export ${variable}="`selection_argument option 1 "$@"`"
debug "Returning sole available option \"%s\" on behalf of user.\n" "`eval echo \\\${${variable}}`"
unset variable
return 1
fi
unset variable; unset options
stop_with 98
return 98
}
term_confirm() {
options=`selection_argument options "$@" | ${wcbin} -l`; options=`echo ${options}`
variable=`selection_argument variable "$@"`
exampletitle=`selection_argument title "$@"`
notify "%s by using --%syes or --%sno switches, or by enabling interactive mode.\n" "${exampletitle}" "${variable}" "${variable}"
notify "\t$ %s --interactive %s\n" "${ME}" "${allargs}"
unset exampletitle
stop_with 98
return 98
}
term_prompt() {
variable=`selection_argument variable "$@"`
exampletitle=`selection_argument title "$@"`
notify "%s by using %s variable, or by enabling interactive mode.\n" "${exampletitle}" "${variable}"
notify "\t$ %s --interactive %s\n" "${ME}" "${allargs}"
unset exampletitle
term_select_example "$@"
return 98
}
interactive_term_select() {
variable=`selection_argument variable "$@"`
title=`selection_argument title "$@"`
text=`selection_argument text "$@"`
options=`selection_argument options "$@" | ${wcbin} -l` ; options=`echo ${options}`
debug "Prompting user to select variable %s.\n" "${variable}"
[ "a${title}" != "a" ] && notify "%s\n\r\n" "${title}"
[ "a${text}" != "a" ] && ${printfbin} "%s\n\r\n" "${text}"
notify "Available options are:\n"
selection_argument options "$@" | ${grepbin} -n "." | ${sedbin} -e "s/^\([0-9]*\):\(.*\) \(.*\)/\1. \3/g" | GREP_COLOR=1 ${grepbin} --color=AUTO "\([0-9]*\)\."
selection_argument button2 "$@" | ${grepbin} -n "." | ${sedbin} -e "s/^\([0-9]*\):\(.*\)/0. \2/g" | GREP_COLOR=1 ${grepbin} --color=AUTO "\([0-9]*\)\."
format_text "You can automate this selection by setting %s variable.\nEnter \"*\" to discover how.\n" "${variable}" | GREP_COLOR=2 ${grepbin} --color=ALWAYS "."
notify "\r\n"
echo -n "`format_text "Please use numbers %d-%d to perform your selection: " "0" "${options}"`"
read termselection
debug "User typed: \"%s\"\n" "${termselection}"
if [ "a${termselection}" = "a*" ]; then
debug "Showing select example through variable %s.\n" "${variable}"
term_select_example "$@"
interactive_term_select "$@"
selection=$?
else
selection=`${printfbin} "%d\n" "${termselection}" 2> /dev/null`
[ "${selection}" -gt "${options}" ] && selection=0
[ "${selection}" -eq "0" ] && selection=98
[ "${selection}" -gt "0" -a "${selection}" -le "${options}" ] && eval export ${variable}="`selection_argument option ${selection} "$@"`"
fi
debug "Considering selection: %d\n" "${selection}"
unset variable; unset title; unset text; unset options; unset termselection
[ "a${DEBUG}" = "a" ] && find_binary "clear" && ${clearbin}
return "${selection}"
}
interactive_term_confirm() {
variable=`selection_argument variable "$@"`
title=`selection_argument title "$@"`
text=`selection_argument text "$@"`
debug "Prompting user to select variable %s.\n" "${variable}"
[ "a${title}" != "a" ] && notify "%s\n\r\n" "${title}"
[ "a${text}" != "a" ] && ${printfbin} "%s\n\r\n" "${text}"
notify "Available options are:\n"
selection_argument button1 "$@" | ${sedbin} -e "s/^\(.*\)$/1. \1/g" | GREP_COLOR=1 ${grepbin} --color=AUTO "^\([0-9]*\)\."
selection_argument button2 "$@" | ${sedbin} -e "s/^\(.*\)$/2. \1/g" | GREP_COLOR=1 ${grepbin} --color=AUTO "^\([0-9]*\)\."
[ "a$6" != "areset" ] && format_text "You can automate this selection by setting --%syes or --%sno switches.\n" "${variable}" "${variable}" | GREP_COLOR=2 ${grepbin} --color=ALWAYS "."
notify "\r\n"
echo -n "`format_text "Please use numbers %d-%d to perform your selection: " "1" "2"`"
read termselection
debug "User typed: \"%s\"\n" "${termselection}"
if [ "a${termselection}" = "a1" ]; then
debug "User selected \"yes\".\n"
selection=0
elif [ "a${termselection}" = "a2" ]; then
debug "User selected \"no\".\n"
selection=1
else
interactive_term_confirm "$@"
selection=$?
return ${selection}
fi
unset variable; unset title; unset text; unset options; unset termselection
[ "a${DEBUG}" = "a" ] && find_binary "clear" && ${clearbin}
return "${selection}"
}
interactive_term_prompt() {
variable=`selection_argument variable "$@"`
title=`selection_argument title "$@"`
text=`selection_argument text "$@"`
debug "Prompting user to type variable %s.\n" "${variable}"
[ "a${title}" != "a" ] && notify "%s\n" "${title}"
format_text "You can automate this selection by setting %s variable.\nEnter \"*\" to discover how.\n" "${variable}" | GREP_COLOR=2 ${grepbin} --color=ALWAYS "."
notify "\r\n"
[ "a${text}" != "a" ] && ${printfbin} "%s: " "${text}"
read termselection
termselection=`sanitize "${termselection}"`
termselection=`echo "${termselection}" | ${sedbin} -e "s/^ *//g" | ${sedbin} -e "s/ *$//g"`
debug "User typed: \"%s\"\n" "${termselection}"
if [ "a${termselection}" = "a*" ]; then
debug "Showing select example through variable %s.\n" "${variable}"
term_select_example "$@"
interactive_term_prompt "$@"
selection=$?
elif [ "a${termselection}" = "a" ]; then
debug "User pressed enter which indicates to abort.\n"
selection=98
else
eval "export ${variable}=\"${termselection}\""
selection=0
fi
debug "Considering selection: %d\n" "${selection}"
unset variable; unset title; unset text; unset termselection
[ "a${DEBUG}" = "a" ] && find_binary "clear" && ${clearbin}
return "${selection}"
}
nine_verbose() {
term_verbose "$@"
}
nine_fixcolors() {
status_connected
[ "a${NINEISP}" != "a${ISPID}" -o "a${ISPID}" = "a" ] && unset NINEBGCOLOR && unset NINEFGCOLOR
[ "a${NINEFGCOLOR}" = "a" ] && NINEFGCOLOR=`echo ${ISP_FGCOLOR} | ${sedbin} -e "s/^\(..\)\(..\)\(..\)$/rgb:\1\/\2\/\3/g"`
[ "a${NINEBGCOLOR}" = "a" ] && NINEBGCOLOR=`echo ${ISP_BGCOLOR} | ${sedbin} -e "s/^\(..\)\(..\)\(..\)$/rgb:\1\/\2\/\3/g"`
[ "a${ISPID}" = "a" ] && unset NINEBGCOLOR && unset NINEFGCOLOR
[ "a${NINEFGCOLOR}" = "a" ] && NINEFGCOLOR="rgb:00/00/00"
[ "a${NINEBGCOLOR}" = "a" ] && NINEBGCOLOR="rgb:ec/ec/ec"
[ "a${NINEISP}" = "a" ] && NINEISP="${ISPID}"
export NINEISP; export NINEFGCOLOR; export NINEBGCOLOR
}
nine_notify() {
unset nineerrormode
! find_binary "9menu" && return 1
if [ "a${1}" = "aerror" ]; then
nineerrormode=1
shift
debug "Going into error mode.\n"
else
debug "Normal notification.\n"
fi
ninetext=`echo "$@" | ${sedbin} -e "s/:/;/g"`
need_arg "MENUFONT"
need_arg "foldwrapping"
if find_binary "fold"; then
ninetext=`echo "${ninetext}" | ${foldbin} -s -w ${foldwrapping}`
else
ninetext=`echo "${ninetext}" | ${sedbin} -e "s/^\(............................................................\)\(.*\)$/\1\\n\2/g"`
fi
ninetext=`echo "${ninetext}" | ${sedbin} -e "s/^\(.*\)$/\"\1:\"/g" | ${trbin} " " " " | ${trbin} "\n" " "`
debug "Displaying text to user through 9menu:%s\n" " $@ "
debug "Displaying text to user through 9menu:%s\n" " ${ninetext} "
if [ "a${nineerrormode}" = "a1" ]; then
result=`eval "${ninemenubin} -font \"${MENUFONT}\" -bg \"rgb:ff/80/80\" -fg white -display \"${DISPLAY}\" -label \"\`translate_text "Error"\`\" ${ninetext} \":\" \"OK:exec echo OK-\"" 2> /dev/null | ${grepbin} "^OK-" | ${cutbin} -d- -f1`
else
nine_fixcolors
result=`eval "${ninemenubin} -font \"${MENUFONT}\" -bg ${NINEBGCOLOR} -fg ${NINEFGCOLOR} -display \"${DISPLAY}\" -label \"\`translate_text "Notification"\`\" ${ninetext} \":\" \"OK:exec echo OK-\"" 2> /dev/null | ${grepbin} "^OK-" | ${cutbin} -d- -f1`
fi
if [ "a${result}" = "aOK" ]; then
debug "User saw message.\n"
else
debug "9menu died or user closed it.\n"
fi
unset ninetext; unset result; unset nineerrormode
}
nine_error() {
nine_notify "error" "$@"
}
nine_select() {
! find_binary "9menu" && return 1
nine_fixcolors
need_arg "MENUFONT"
need_arg "foldwrapping"
debug "Prompting user to select variable %s with 9menu.\n" "${variable}"
variable=`selection_argument variable "$@"`
title=`selection_argument title "$@"`
text=`selection_argument text "$@"`
options=`selection_argument options "$@" | ${wcbin} -l` ; options=`echo ${options}`
helptext=`format_text "You can automate this selection by setting %s variable on command line, click here to discover how.\n" "${variable}" | ${sedbin} -e "s/:/;/g"`
localbutton2=`selection_argument button2 "$@"`; [ "a${localbutton2}" = "a" ] && localbutton2="Cancel"
ninetext=`echo "${text}" | ${sedbin} -e "s/:/;/g"`
if find_binary "fold"; then
ninetext=`echo "${ninetext}" | ${foldbin} -s -w ${foldwrapping}`
helptext=`echo "${helptext}" | ${foldbin} -s -w ${foldwrapping}`
else
ninetext=`echo "${ninetext}" | ${sedbin} -e "s/^\(............................................................\)\(.*\)$/\1\\n\2/g"`
helptext=`echo "${helptext}" | ${sedbin} -e "s/^\(............................................................\)\(.*\)$/\1\\n\2/g"`
fi
ninetext=`echo "${ninetext}" | ${sedbin} -e "s/^\(.*\)$/\"\1:\"/g" | ${trbin} " " " " | ${trbin} "\n" " "`
helptext=`echo "${helptext}" | ${sedbin} -e "s/^\(.*\)$/\"\1:exec echo OPTION-AUTOMATE\"/g" | ${trbin} " " " " | ${trbin} "\n" " "`
localarguments=`selection_argument options "$@" | ${sedbin} -e "s/:/;/g" | ${grepbin} -n "." | ${sedbin} -e "s/^\([0-9]*\):\(.*\) \(.*\)$/\"\1. \3:exec echo OPTION-\1\"/g" | ${trbin} "\n" " "`
termselection=`eval "${ninemenubin} -font \"${MENUFONT}\" -bg ${NINEBGCOLOR} -fg ${NINEFGCOLOR} -display \"${DISPLAY}\" -label \"${title}\" ${ninetext} \":\" ${localarguments} \":\" ${helptext} \":\" \"${localbutton2}:exec echo OPTION-9menuexit\"" 2> /dev/null | ${grepbin} "^OPTION-" | ${cutbin} -d- -f2-`
debug "User selected: \"%s\"\n" "${termselection}"
if [ "a${termselection}" = "aAUTOMATE" ]; then
localtext=`format_text "You can automate this selection by setting %s variable on command line.\n" "${variable}"`
notify "${localtext}\n`select_example "$@"`"
nine_select "$@"
selection=$?
return ${selection}
elif [ "a${termselection}" = "a9menuexit" -o "a${termselection}" = "a" ]; then
debug "User selected button: %s\n" "${localbutton2}"
selection=98
else
termselection=`echo "${termselection}" | ${trbin} -t "." ""`
selection=`${printfbin} "%d\n" "${termselection}" 2> /dev/null`
[ "${selection}" -gt "${options}" ] && selection=0
[ "${selection}" -eq "0" ] && selection=98
[ "${selection}" -gt "0" -a "${selection}" -le "${options}" ] && eval export ${variable}="`selection_argument option ${selection} "$@"`"
fi
debug "Considering selection: %d\n" "${selection}"
unset variable; unset title; unset text; unset ninetext; unset helptext; unset options; unset termselection; unset buttonselection; unset localtext; unset localarguments; unset localbutton2
return "${selection}"
}
nine_confirm() {
! find_binary "9menu" && return 1
nine_fixcolors
need_arg "MENUFONT"
need_arg "foldwrapping"
variable=`selection_argument variable "$@"`
title=`selection_argument title "$@"`
ninetext=`selection_argument text "$@" | ${sedbin} -e "s/:/;/g"`
localbutton1=`selection_argument button1 "$@"`; [ "a${localbutton1}" = "a" ] && localbutton1="OK"
localbutton2=`selection_argument button2 "$@"`; [ "a${localbutton2}" = "a" ] && localbutton2="Cancel"
debug "Prompting user to confirm variable %s with 9menu.\n" "${variable}"
helptext=""
[ "a$6" != "areset" ] && helptext=`format_text "You can automate this selection by setting --%syes or --%sno switches.\n" "${variable}" "${variable}" | ${sedbin} -e "s/:/;/g"`
if find_binary "fold"; then
ninetext=`echo "${ninetext}" | ${foldbin} -s -w ${foldwrapping}`
helptext=`echo "${helptext}" | ${foldbin} -s -w ${foldwrapping}`
else
ninetext=`echo "${ninetext}" | ${sedbin} -e "s/^\(............................................................\)\(.*\)$/\1\\n\2/g"`
helptext=`echo "${helptext}" | ${sedbin} -e "s/^\(............................................................\)\(.*\)$/\1\\n\2/g"`
fi
ninetext=`echo "${ninetext}" | ${sedbin} -e "s/^\(.*\)$/\"\1:\"/g" | ${trbin} " " " " | ${trbin} "\n" " "`
helptext=`echo "${helptext}" | ${sedbin} -e "s/^\(.*\)$/\"\1:\"/g" | ${trbin} " " " " | ${trbin} "\n" " "`
localarguments="\"${localbutton1}:exec echo Answer-Yes\" \"${localbutton2}:exec echo Answer-No\""
termselection=`eval "${ninemenubin} -font \"${MENUFONT}\" -bg ${NINEBGCOLOR} -fg ${NINEFGCOLOR} -display \"${DISPLAY}\" -label \"${title}\" ${ninetext} \":\" ${localarguments} \":\" ${helptext} \":\"" 2> /dev/null | ${grepbin} "^Answer-" | ${cutbin} -d- -f2-`
debug "User selected: \"%s\"\n" "${termselection}"
if [ "a${termselection}" = "aYes" ]; then
selection=0
else
selection=1
fi
debug "Considering selection: %d\n" "${selection}"
unset variable; unset title; unset text; unset ninetext; unset helptext; unset options; unset termselection; unset buttonselection; unset localtext; unset localarguments; unset localbutton2; unset localbutton1
return "${selection}"
}
nine_prompt() {
! find_binary "xterm" && return 1
variable=`selection_argument variable "$@"`
title=`selection_argument title "$@"`
text=`selection_argument text "$@"`
debug "Prompting user to type variable %s through xterm.\n" "${variable}"
localtext=`format_text "You can automate this selection by setting %s variable.\n" "${variable}"`
[ "a${text}" != "a" ] && localtext=`${printfbin} "%s\n\n%s: " "${localtext}" "${text}"`
locallines=`echo "${localtext}" | ${wcbin} -l`; locallines=`echo ${locallines}`; locallines=`expr ${locallines} + 10`; locallines=`echo ${locallines}`;
${printfbin} "%s\n" "${localtext}" > "/tmp/sakis3g.xterm.pipe.$$"
${xtermbin} -T "${title}" +cm +dc -e sh -c "${catbin} /tmp/sakis3g.xterm.pipe.$$; read XTERMANSWER; set >> /tmp/sakis3g.xterm.pipe.$$;" 2> /dev/null
debug show_file "/tmp/sakis3g.xterm.pipe.$$"
termselection=`${grepbin} "^XTERMANSWER=" "/tmp/sakis3g.xterm.pipe.$$" 2> /dev/null | ${cutbin} -d= -f2- | ${sedbin} -e "s/^\"\(.*\)\"$/\1/g" | ${sedbin} -e "s/^\'\(.*\)\'$/\1/g"`; ${rmbin} -f "/tmp/sakis3g.xterm.pipe.$$"
termselection=`sanitize "${termselection}"`
debug "User typed: \"%s\"\n" "${termselection}"
# TODO: Implement example
if [ "a${termselection}" != "a" ]; then
debug "User typed: %s\n" "${termselection}"
eval "export ${variable}=\"${termselection}\""
selection=0
elif [ "a${termselection}" = "a" ]; then
debug "User requested to cancel.\n"
selection=98
else
debug "Unknown error.\n"
selection=99
fi
debug "Considering selection: %d\n" "${selection}"
unset variable; unset title; unset text; unset termselection; unset buttonselection; unset localtext
return "${selection}"
}
dialog_error() {
dialog_cleanscreen
if [ "a${SGUI}" = "adialog" ]; then
! find_binary "dialog" && return 1
${dialogbin} --backtitle "Sakis3G ${MYVERSION}" --colors --title "\Z1\Zb`translate_text "Error occured"`" --ok-label `translate_text "OK"` --clear --colors --aspect 30 --msgbox "\Z1\ZB$@" 0 0
elif [ "a${SGUI}" = "aXdialog" ]; then
! find_binary "Xdialog" && return 1
${Xdialogbin} --backtitle `translate_text "Error occured"` --title "Sakis3G ${MYVERSION}" --ok-label `translate_text "OK"` --msgbox "$@ " 0 0
elif [ "a${SGUI}" = "azenity" ]; then
! find_binary "zenity" && return 1
${zenitybin} --title "`translate_text "Error occured"`" --error --text "$@ "
elif [ "a${SGUI}" = "akdialog" ]; then
! find_binary "kdialog" && return 1
${kdialogbin} --title "`translate_text "Error occured"`" --error "$@ " > /dev/null 2> /dev/null
elif [ "a${SGUI}" = "awhiptail" ]; then
! find_binary "whiptail" && return 1
${whiptailbin} --backtitle "Sakis3G ${MYVERSION}" --title "`translate_text "Error occured"`" --clear --msgbox "$@ " 0 0
fi
}
dialog_notify() {
dialog_cleanscreen
if [ "a${SGUI}" = "adialog" ]; then
! find_binary "dialog" && return 1
${dialogbin} --backtitle "Sakis3G ${MYVERSION}" --title `translate_text "Notification"` --ok-label `translate_text "OK"` --clear --aspect 30 --msgbox "$@" 0 0
elif [ "a${SGUI}" = "aXdialog" ]; then
! find_binary "Xdialog" && return 1
${Xdialogbin} --title "Sakis3G ${MYVERSION}" --ok-label `translate_text "OK"` --msgbox "$@" 0 0
elif [ "a${SGUI}" = "azenity" ]; then
! find_binary "zenity" && return 1
${zenitybin} --title "Sakis3G ${MYVERSION}" --info --text "$@ "
elif [ "a${SGUI}" = "akdialog" ]; then
! find_binary "kdialog" && return 1
${kdialogbin} --title "Sakis3G ${MYVERSION}" --msgbox "$@ " > /dev/null 2> /dev/null
elif [ "a${SGUI}" = "awhiptail" ]; then
! find_binary "whiptail" && return 1
${whiptailbin} --backtitle "Sakis3G ${MYVERSION}" --title `translate_text "Notification"` --clear --msgbox "$@" 0 0
fi
}
dialog_cleanscreen() {
if [ "a${SGUI}" = "aXdialog" ]; then
if [ "a${XdialogVerbose}" != "a" -a "a${XdialogVerbose}" != "a0" ]; then
! notrunning "${XdialogVerbose}" && find_binary "kill" && ${killbin} -1 "${XdialogVerbose}" 2> /dev/null
unset XdialogVerbose
fi
unset currentlyverbosing
elif [ "a${SGUI}" = "azenity" ]; then
[ -f "/tmp/sakis3g.zenity.pipe" ] && ${printfbin} "\n100\n" >> "/tmp/sakis3g.zenity.pipe"
[ -f "/tmp/sakis3g.zenity.pipe" ] && debug run_command "${rmbin} -f /tmp/sakis3g.zenity.pipe"
[ "a${zenityverbosepid}" != "a" ] && ! notrunning "${zenityverbosepid}" && ${killbin} -1 "${zenityverbosepid}" 2> /dev/null
[ "a${zenityverbosepid}" != "a" ] && ! notrunning "${zenityverbosepid}" && ${killbin} -9 "${zenityverbosepid}" 2> /dev/null
unset zenityverbosepid
elif [ "a${SGUI}" = "akdialog" ]; then
! find_binary "kdialog" && return 1
if [ "a${kdialogaddress}" != "a" ]; then
dcopbased=`echo ${kdialogaddress} | ${grepbin} -i "dcop"`
if [ "a${dcopbased}" != "a" ]; then
if find_binary "dcop"; then
debug run_command "${dcopbin} \"${kdialogaddress}\" close"
fi
else
! find_binary "dbus-send" && find_binary "qdbus"
if [ "a${dbus_sendbin}" != "a" ]; then
debug run_command "${dbus_sendbin} --print-reply --dest=${kdialogaddress} \"org.kde.kdialog.ProgressDialog.close\""
elif [ "a${qdbusbin}" != "a" ]; then
debug run_command "${qdbusbin} ${kdialogaddress} \"org.kde.kdialog.ProgressDialog.close\""
fi
fi
else
term_clearline
fi
unset kdialogaddress
fi
}
dialog_verbose() {
if [ "a${SGUI}" = "adialog" ]; then
! find_binary "dialog" && return 1
verbwidth=`echo "${COLUMNS}"`; verbwidth=`expr ${verbwidth} + 1 - 1`; verbwidth=`echo ${verbwidth}`
verbheight=0; [ "${verbwidth}" -gt "40" ] && verbheight=3
currentlyverbosing=yes
${dialogbin} --backtitle "Sakis3G ${MYVERSION}" --title "Working" --aspect 40 --infobox "$@..." ${verbheight} ${verbwidth}
unset currentlyverbosing; lastlineverbose=yes; unset verbwidth; unset verbheight
elif [ "a${SGUI}" = "aXdialog" ]; then
# ! find_binary "Xdialog" && return 1
# ${Xdialogbin} --title "Sakis3G is working" --infobox "$@..." 0 0 30000 &
# XdialogVerbose=$!; currentlyverbosing=yes
term_verbose "$@"
elif [ "a${SGUI}" = "akdialog" ]; then
! find_binary "kdialog" && return 1
if ! find_binary "dbus-send" && ! find_binary "qdbus"; then
term_verbose "$@"; return 0
fi
if [ "a${kdialogaddress}" = "a" ]; then
temptext=`translate_text Working...`
kdialogaddress=`${kdialogbin} --title "Sakis3G ${MYVERSION}" --progressbar "${temptext}" 100`
# kdialogaddress=`${kdialogbin} --title "Sakis3G ${MYVERSION}" --progressbar "${temptext}" 100 2> /dev/null`
debug "Returned 1\n"
unset temptext
[ "a${kdialogaddress}" != "a" ] && export kdialogaddress
fi
debug "Returned 2\n"
if [ "a${kdialogaddress}" != "a" ]; then
dcopbased=`echo ${kdialogaddress} | ${grepbin} -i "dcop"`
if [ "a${dcopbased}" != "a" ]; then
if find_binary "dcop"; then
debug run_command "${dcopbin} --user \"${runner}\" --all-sessions \"${kdialogaddress}\" setProgress ${verbosecurrentcount}"
debug run_command "${dcopbin} --user \"${runner}\" --all-sessions \"${kdialogaddress}\" setLabel \"$@\""
fi
else
if [ "a${kdialogaddress}" != "a" ] && [ "a${dbus_sendbin}" != "a" ]; then
debug run_command "${dbus_sendbin} --print-reply --dest=${kdialogaddress} \"org.freedesktop.DBus.Properties.Set\" string:'org.kde.kdialog.ProgressDialog' string:'value' variant:int32:${verbosecurrentcount}"
debug run_command "${dbus_sendbin} --print-reply --dest=${kdialogaddress} \"org.kde.kdialog.ProgressDialog.setLabelText\" \"string:$@\""
elif [ "a${kdialogaddress}" != "a" ] && [ "a${qdbusbin}" != "a" ]; then
debug run_command "qdbus ${kdialogaddress} \"org.kde.kdialog.ProgressDialog.setLabelText\" \"$@\""
debug run_command "qdbus ${kdialogaddress} \"org.freedesktop.DBus.Properties.Set\" \"\" \"value\" \"${verbosecurrentcount}\""
fi
fi
else
term_verbose "$@"
fi
elif [ "a${SGUI}" = "azenity" ]; then
! find_binary "zenity" && return 1
[ "a${zenityverbosepid}" != "a" ] && notrunning "${zenityverbosepid}" && unset zenityverbosepid
[ ! -f "/tmp/sakis3g.zenity.pipe" ] && unset zenityverbosepid
if [ "a${zenityverbosepid}" = "a" ] && find_binary "rm" && find_binary "tail" && find_binary "kill" && find_binary "printf" && find_binary "touch" && find_binary "chmod" && find_binary "setsid"; then
debug "Establishing zenity verbose helper.\n"
[ -f "/tmp/sakis3g.zenity.pipe" ] && ${printfbin} "\n100\n" >> "/tmp/sakis3g.zenity.pipe"
[ -f "/tmp/sakis3g.zenity.pipe" ] && debug run_command "${rmbin} -f /tmp/sakis3g.zenity.pipe"
debug run_command "${touchbin} /tmp/sakis3g.zenity.pipe"
debug run_command "${chmodbin} 666 /tmp/sakis3g.zenity.pipe"
if [ -f "/tmp/sakis3g.zenity.pipe" ]; then
eval ${tailbin} -f "/tmp/sakis3g.zenity.pipe" "2> /dev/null" | ${zenitybin} --title="Sakis3G ${MYVERSION}" --text="`translate_text Working...`" --progress --percentage=0 --auto-close "> /dev/null 2> /dev/null" &
zenityverbosepid=$!
eval "disown -a" > /dev/null 2> /dev/null
export zenityverbosepid
fi
fi
[ "a${zenityverbosepid}" != "a" ] && notrunning "${zenityverbosepid}" && unset zenityverbosepid
[ "a${zenityverbosepid}" = "a" ] && term_verbose "$@" && return 1
${printfbin} "\n%d\n# $@...\n\n" "${verbosecurrentcount}" >> "/tmp/sakis3g.zenity.pipe"
elif [ "a${SGUI}" = "awhiptail" ]; then
term_verbose "$@"
fi
}
dialog_confirm() {
dialog_cleanscreen
if [ "a${SGUI}" = "adialog" ]; then
! find_binary "dialog" && return 1
elif [ "a${SGUI}" = "aXdialog" ]; then
! find_binary "Xdialog" && return 1
elif [ "a${SGUI}" = "azenity" ]; then
! find_binary "zenity" && return 1
elif [ "a${SGUI}" = "akdialog" ]; then
! find_binary "kdialog" && return 1
elif [ "a${SGUI}" = "awhiptail" ]; then
! find_binary "whiptail" && return 1
fi
variable=`selection_argument variable "$@"`
title=`selection_argument title "$@"`
text=`selection_argument text "$@"`
debug "Prompting user to select yes%s or no%s.\n" "${variable}" "${variable}"
localtext=""
[ "a$6" != "areset" ] && localtext=`format_text "You can automate this selection by setting --%syes or --%sno switches.\n" "${variable}" "${variable}"`
if [ "a${SGUI}" = "adialog" ]; then
[ "a${text}" != "a" ] && localtext=`${printfbin} "%s\\\\\\n\\\\\\n%s\n" "${text}" "${localtext}"`
${dialogbin} --backtitle "Sakis3G ${MYVERSION}" --title " ${title} " --clear --cr-wrap --yesno "${localtext}" 0 0 2> /dev/null
buttonselection=$?
elif [ "a${SGUI}" = "aXdialog" ]; then
[ "a${text}" != "a" ] && localtext=`${printfbin} "%s\\\\\\n\\\\\\n%s\n" "${text}" "${localtext}"`
${Xdialogbin} --backtitle " ${title} " --title "Sakis3G ${MYVERSION}" --wrap --fill --yesno "${localtext}" 0 0 2> /dev/null
buttonselection=$?
elif [ "a${SGUI}" = "akdialog" ]; then
[ "a${text}" != "a" ] && localtext=`${printfbin} "%s\\\\\\n\\\\\\n%s\n" "${text}" "${localtext}"`
${kdialogbin} --title " ${title} " --yesno "${text}" 2> /dev/null
buttonselection=$?
elif [ "a${SGUI}" = "azenity" ]; then
need_arg "foldwrapping"
text=`echo "${text}" | ${sedbin} -e "s/_/__/g"`
localtext=`echo "${localtext}" | ${sedbin} -e "s/_/__/g"`
# if find_binary "fold"; then
# localtext=`echo "${localtext}" | ${foldbin} -s -w ${foldwrapping}`
# text=`echo "${text}" | ${foldbin} -s -w ${foldwrapping}`
# fi
[ "a${text}" != "a" ] && localtext=`${printfbin} "%s\\\\\\n\\\\\\n%s\n" "${text}" "${localtext}"`
${zenitybin} --title " ${title} " --question --text "${localtext}" 2> /dev/null
buttonselection=$?
elif [ "a${SGUI}" = "awhiptail" ]; then
[ "a${text}" != "a" ] && localtext=`${printfbin} "%s\\\\\\n\\\\\\n%s\n" "${text}" "${localtext}"`
${whiptailbin} --backtitle "Sakis3G ${MYVERSION}" --title " ${title} " --clear --yesno "${localtext}" 0 0 2> /dev/null
buttonselection=$?;
fi
if [ "a${buttonselection}" = "a0" ]; then
debug "User selected \"yes\" (%d).\n" "${buttonselection}"
return 0
else
debug "User selected \"no\" (%d).\n" "${buttonselection}"
return 1
fi
}
dialog_select() {
dialog_cleanscreen
if [ "a${SGUI}" = "adialog" ]; then
! find_binary "dialog" && return 1
elif [ "a${SGUI}" = "aXdialog" ]; then
! find_binary "Xdialog" && return 1
elif [ "a${SGUI}" = "azenity" ]; then
! find_binary "zenity" && return 1
elif [ "a${SGUI}" = "akdialog" ]; then
! find_binary "kdialog" && return 1
elif [ "a${SGUI}" = "awhiptail" ]; then
! find_binary "whiptail" && return 1
fi
variable=`selection_argument variable "$@"`
title=`selection_argument title "$@"`
text=`selection_argument text "$@"`
options=`selection_argument options "$@" | ${wcbin} -l` ; options=`echo ${options}`
debug "Prompting user to select variable %s.\n" "${variable}"
localtext=`format_text "You can automate this selection by setting %s variable on command line.\n" "${variable}"`
[ "a${text}" != "a" ] && localtext=`${printfbin} "%s\\\\\\n\\\\\\n%s\n" "${localtext}" "${text}"`
localbutton2=`selection_argument button2 "$@"`; [ "a${localbutton2}" = "a" ] && localbutton2="Cancel"
if [ "a${SGUI}" = "adialog" ]; then
localarguments=`selection_argument options "$@" | ${grepbin} -n "." | ${sedbin} -e "s/^\([0-9]*\):\(.*\) \(.*\)$/\"\1.\" \"\3\" \"${variable}=\\\\\"\2\\\\\"\"/g"`
eval ${dialogbin} --backtitle \"Sakis3G ${MYVERSION}\" --title \" ${title} \" --ok-label \"`translate_text "OK"`\" --cancel-label \"${localbutton2}\" --item-help --clear --cr-wrap --menu \"${localtext}\" 0 0 0 ${localarguments} 2> "/tmp/sakis3g.dialog.$$"
buttonselection=$?
elif [ "a${SGUI}" = "aXdialog" ]; then
localarguments=`selection_argument options "$@" | ${grepbin} -n "." | ${sedbin} -e "s/^\([0-9]*\):\(.*\) \(.*\)$/\"\1.\" \"\3\" \"${variable}=\\\\\"\2\\\\\"\"/g"`
eval ${Xdialogbin} --backtitle \" ${title} \" --title \"Sakis3G ${MYVERSION}\" --ok-label \"`translate_text "OK"`\" --cancel-label \"${localbutton2}\" --item-help --wrap --fill --menubox \""${localtext}"\" 0 0 0 ${localarguments} 2> "/tmp/sakis3g.dialog.$$"
buttonselection=$?
elif [ "a${SGUI}" = "akdialog" ]; then
localarguments=`selection_argument options "$@" | ${grepbin} -n "." | ${sedbin} -e "s/^\([0-9]*\):\(.*\) \(.*\)$/\"\1.\" \"\3\"/g"`
eval ${kdialogbin} --title \" ${title} \" --menu \""${text}"\" ${localarguments} \"AUTOMATE\" \"`translate_text "Help with this question"`\" > "/tmp/sakis3g.dialog.$$" 2> /dev/null
buttonselection=$?
elif [ "a${SGUI}" = "azenity" ]; then
need_arg "foldwrapping"
localarguments=`selection_argument options "$@" | ${grepbin} -n "." | ${sedbin} -e "s/^\([0-9]*\):\(.*\) \(.*\)$/\"\1.\" \"\3\"/g"`
localtext=`echo "${text}" | ${sedbin} -e "s/_/__/g"`
find_binary "fold" && localtext=`echo "${localtext}" | ${foldbin} -s -w ${foldwrapping}`
eval ${zenitybin} --title \" ${title} \" --list --text \""${localtext}"\" --hide-column 1 --column Index --column `translate_text "Option"` ${localarguments} \"AUTOMATE\" \"`translate_text "Help with this question"`\" > "/tmp/sakis3g.dialog.$$"
buttonselection=$?
elif [ "a${SGUI}" = "awhiptail" ]; then
localarguments=`selection_argument options "$@" | ${grepbin} -n "." | ${sedbin} -e "s/^\([0-9]*\):\(.*\) \(.*\)$/\"\1. \3\" \"\2\"/g"`
eval ${whiptailbin} --backtitle \"Sakis3G ${MYVERSION}\" --title \" ${title} \" --noitem --clear --menu \"${localtext}\" 0 0 0 ${localarguments} 2> "/tmp/sakis3g.dialog.$$"
buttonselection=$?;
fi
termselection=`${catbin} "/tmp/sakis3g.dialog.$$" 2> /dev/null`; ${rmbin} -f "/tmp/sakis3g.dialog.$$"
debug "User selected: \"%s\"\n" "${termselection}"
if [ "a${termselection}" = "aAUTOMATE" ]; then
variable=`selection_argument variable "$@"`
localtext=`format_text "You can automate this selection by setting %s variable on command line.\n" "${variable}"`
notify "${localtext}\n`select_example "$@" | ${sedbin} -e "s/ /\\\n /g"`"
dialog_select "$@"
selection=$?
return ${selection}
elif [ "a${buttonselection}" != "a0" ]; then
debug "User selected button: %d\n" "${buttonselection}"
selection=98
else
termselection=`echo "${termselection}" | ${trbin} -t "." ""`
selection=`${printfbin} "%d\n" "${termselection}" 2> /dev/null`
[ "${selection}" -gt "${options}" ] && selection=0
[ "${selection}" -eq "0" ] && selection=98
[ "${selection}" -gt "0" -a "${selection}" -le "${options}" ] && eval export ${variable}="`selection_argument option ${selection} "$@"`"
fi
debug "Considering selection: %d\n" "${selection}"
unset variable; unset title; unset text; unset options; unset termselection; unset buttonselection; unset localtext; unset localarguments; unset localbutton2
return "${selection}"
}
dialog_prompt() {
dialog_cleanscreen
if [ "a${SGUI}" = "adialog" ]; then
! find_binary "dialog" && return 1
elif [ "a${SGUI}" = "aXdialog" ]; then
! find_binary "Xdialog" && return 1
elif [ "a${SGUI}" = "azenity" ]; then
! find_binary "zenity" && return 1
elif [ "a${SGUI}" = "akdialog" ]; then
! find_binary "kdialog" && return 1
elif [ "a${SGUI}" = "awhiptail" ]; then
! find_binary "whiptail" && return 1
fi
variable=`selection_argument variable "$@"`
title=`selection_argument title "$@"`
text=`selection_argument text "$@"`
debug "Prompting user to type variable %s.\n" "${variable}"
localtext=`format_text "You can automate this selection by setting %s variable.\n" "${variable}"`
[ "a${text}" != "a" ] && localtext=`${printfbin} "%s\n\n%s: " "${localtext}" "${text}"`
locallines=`echo "${localtext}" | ${wcbin} -l`; locallines=`echo ${locallines}`; locallines=`expr ${locallines} + 10`; locallines=`echo ${locallines}`;
if [ "a${SGUI}" = "adialog" ]; then
${dialogbin} --backtitle "Sakis3G ${MYVERSION}" --title " ${title} " --ok-label `translate_text "OK"` --cancel-label `translate_text "Cancel"` --clear --inputbox "${localtext}" ${locallines} 0 2> "/tmp/sakis3g.dialog.$$"
buttonselection=$?
elif [ "a${SGUI}" = "aXdialog" ]; then
${Xdialogbin} --backtitle " ${title} " --title "Sakis3G ${MYVERSION}" --ok-label `translate_text "OK"` --cancel-label `translate_text "Cancel"` --wrap --fill --clear --inputbox "${localtext}" ${locallines} 0 2> "/tmp/sakis3g.dialog.$$"
buttonselection=$?
elif [ "a${SGUI}" = "akdialog" ]; then
${kdialogbin} --title " ${title} " --inputbox "${localtext}" "" > "/tmp/sakis3g.dialog.$$" 2> /dev/null
buttonselection=$?
elif [ "a${SGUI}" = "azenity" ]; then
need_arg "foldwrapping"
localtext=`echo "${localtext}" | ${sedbin} -e "s/_/__/g"`
find_binary "fold" && localtext=`echo "${localtext}" | ${foldbin} -s -w ${foldwrapping}`
${zenitybin} --title " ${title} " --entry --text "${localtext}" > "/tmp/sakis3g.dialog.$$"
buttonselection=$?
elif [ "a${SGUI}" = "awhiptail" ]; then
${whiptailbin} --backtitle "Sakis3G ${MYVERSION}" --title " ${title} " --clear --inputbox "${localtext}" 0 0 2> "/tmp/sakis3g.dialog.$$"
buttonselection=$?
fi
termselection=`${catbin} "/tmp/sakis3g.dialog.$$" 2> /dev/null`; ${rmbin} -f "/tmp/sakis3g.dialog.$$"
termselection=`sanitize "${termselection}"`
debug "User pressed button %d while typed: \"%s\"\n" "${buttonselection}" "${termselection}"
# TODO: Implement example
if [ "a${buttonselection}" = "a0" ]; then
debug "User pressed OK.\n"
if [ "a${termselection}" != "a" ]; then
debug "User typed: %s\n" "${termselection}"
eval "export ${variable}=\"${termselection}\""
selection=0
else
debug "User entered no text.\n" "${variable}"
selection=98
fi
elif [ "a${termselection}" = "a" -o "a${buttonselection}" != "a0" ]; then
debug "User requested to cancel.\n"
selection=98
else
debug "Unknown error.\n"
selection=99
fi
debug "Considering selection: %d\n" "${selection}"
unset variable; unset title; unset text; unset termselection; unset buttonselection; unset localtext
return "${selection}"
}
dialog_clearscreen() {
[ "a${DEBUG}" = "a" ] && find_binary "clear" && ${clearbin}
return 0
}
selection_argument() {
selectarg="$1"
[ "$#" -gt "0" ] && shift
case "${selectarg}" in
variable)
echo "$1"
;;
title)
echo "$2"
;;
text)
echo "$3"
;;
button1)
echo "$4"
;;
button2)
echo "$5"
;;
options)
for selectind in `${seqbin} 6 2 $#`
do
eval selcode=\${${selectind}}
selectinc=`expr ${selectind} + 1`; selectinc=`echo ${selectinc}`
eval seloption=\${${selectinc}}
echo "${selcode} ${seloption}"
unset selcode; unset seloption; unset selectinc
done
unset selectind
;;
option)
selectind=$1
[ "$#" -gt "0" ] && shift
selectind=`expr ${selectind} \* 2`; selectind=`echo ${selectind}`
selectind=`expr ${selectind} + 4`; selectind=`echo ${selectind}`
eval selcode=\${${selectind}}
echo "${selcode}"
unset selcode; unset selectind
;;
invalid)
for selectind in `${seqbin} 7 2 $#`
do
eval selcode=\${${selectind}}
if [ "a${selcode}" = "a$1" ]; then
debug "%s==%s.\n" "$1" "${selcode}"
unset selcode; unset selectarg
selectind=`expr ${selectind} - 5`; selectind=`echo ${selectind}`
selectind=`expr ${selectind} / 2`; selectind=`echo ${selectind}`
return ${selectind}
fi
debug "%s!=%s\n" "${selcode}" "${1}"
unset selcode
done
debug "Not a valid option \"%s\".\n" "$1"
unset selectind
return 0
;;
*)
debug "Unknown selection id %s.\n" "${selectarg}"
;;
esac
unset selectarg
}
# Returns true if $1 is found within $2.
strinstr() {
[ "a$1" = "a" -o "a$2" = "a" ] && return 1
if [ "a$3" = "a" ]; then
strinstrsep=":"
else
strinstrsep="$3"
fi
strinstrfound=`echo "${strinstrsep}${2}${strinstrsep}" | grep "${strinstrsep}${1}${strinstrsep}"`
strinstrfound=`echo "${strinstrfound}"`
unset strinstrsep
if [ "a${strinstrfound}" != "a" ]; then
unset strinstrfound
return 0
fi
unset strinstrfound
return 1
}
# Checks if running with root priviledges
we_are_root_already() {
if [ "a${UID}" = "a0" -o "a${USER}" = "aroot" -o "a${EUID}" = "a0" ]; then
return 0
fi
debug "Not currently running with root privileges.\n"
return 1
}
# Makes sure we are root
we_are_root() {
if we_are_root_already; then
debug "We are root already. Proceeding.\n"
return 0
fi
state_variables
verbose "Acquiring root privileges"
[ -z "${SUMETHOD}" ] && check_su_software
[ -z "${ME}" ] && have_me
cleanscreen
debug "This instance will call %s and abort.\n" "${SUMETHOD}"
case "${SUMETHOD}" in
"sudo")
[ "a${DEBUG}" = "a" ] && find_binary "clear" && ${clearbin}
eval ${sudobin} ${ME} ${allargs} ${statevariables}
ret=$?
if [ "$ret" -eq "1" ]; then
echo
echo If it didn\'t worked, you need to add yourself
echo to sudo file: as root, type visudo and add the
echo following line at the end of file:
echo ${runner} ALL=\(root\) NOPASSWD: ${ME}
stop_fmt_error 1 "Failed to become root."
fi
;;
"gksu")
# Nusty workaround because gksu does not properly handle arguments containing whitespaces
${touchbin} "/tmp/sakis3g.gksu.wrapper.$$"
${chmodbin} +x "/tmp/sakis3g.gksu.wrapper.$$"
${printfbin} "#!/bin/sh\nexport PROVIDER=\"%s\"\n%s %s %s\nexit \$?\n\n" "${PROVIDER}" "${ME}" "${allargs}" "${statevariables}" > "/tmp/sakis3g.gksu.wrapper.$$"
[ ! -f "/tmp/sakis3g.gksu.wrapper.$$" ] && stop_fmt_error 3 "No method for acquiring root privileges found."
debug show_file "/tmp/sakis3g.gksu.wrapper.$$"
${gksubin} /tmp/sakis3g.gksu.wrapper.$$
ret=$?
${rmbin} -f "/tmp/sakis3g.gksu.wrapper.$$"
;;
"kdesu")
${kdesubin} "${ME} ${allargs} ${statevariables}"
ret=$?
;;
"su")
if [ -n "${stick_to_console}" -a -z "${interactive}" ]; then
notify "\nUtility \"%s\" found but cannot be used since we are not interactive.\n" "su"
notify "Either enable interactive mode:\n"
notify "\t%s --interactive %s\n" "${ME}" "${allargs}"
notify "or, force using %s instead:\n" "sudo"
notify "\t%s --sudo %s\n\r\n" "${ME}" "${allargs}"
stop_fmt_error 3 "No method for acquiring root privileges found."
fi
[ "a${DEBUG}" = "a" ] && find_binary "clear" && ${clearbin}
term_print "Please supply root password, or press enter to abort."
${subin} -c "${ME} ${allargs} ${statevariables}"
ret=$?
;;
esac
stop_with ${ret}
}
# Shows error
show_fmt_error() {
errortext=`format_text "$@"`
debug "Error: %s\n" "${errortext}"
if [ "a${noerror}" != "a" ]; then
debug "Skipping error notification due to configuration.\n"
unset errortext
return 0
fi
guruplug_error
case "${SGUI}" in
whiptail|dialog|Xdialog|zenity|kdialog)
dialog_error "${errortext}"
;;
"9menu")
nine_error "${errortext}"
;;
"interactive terminal")
term_error "${errortext}"
;;
"terminal")
term_error "${errortext}"
;;
*)
term_error "${errortext}"
;;
esac
unset errortext
}
cleanscreen() {
osd_cleanscreen
case "${SGUI}" in
whiptail|dialog|Xdialog|zenity|kdialog)
dialog_cleanscreen
term_clearline
;;
"9menu")
term_clearline
;;
"interactive terminal")
term_clearline
;;
"terminal")
term_clearline
;;
*)
term_clearline
;;
esac
}
osd_cleanscreen() {
if [ "a${OSDPID}" != "a" ]; then
if find_binary "kill"; then
! notrunning "${OSDPID}" && ${killbin} -1 "${OSDPID}" 2> /dev/null
! notrunning "${OSDPID}" && ${killbin} -9 "${OSDPID}" 2> /dev/null
fi
unset OSDPID
fi
return 0
}
osd_verbose() {
[ "a${OSDOUTPUT}" = "a" ] && return 1
osd_cleanscreen
case "${OSDOUTPUT}" in
osd_cat)
need_arg "XOSDFONT"
if [ "a${OSDISP}" != "a${ISPID}" ]; then
unset OSDFGCOLOR; unset OSDBGCOLOR;
fi
[ "a${OSDFGCOLOR}" = "a" ] && OSDFGCOLOR=`echo ${ISP_FG_COLOR} | ${sedbin} -e "s/^\(..\)\(..\)\(..\)$/rgb:\1\/\2\/\3/g"`
[ "a${OSDBGCOLOR}" = "a" ] && OSDBGCOLOR=`echo ${ISP_BG_COLOR} | ${sedbin} -e "s/^\(..\)\(..\)\(..\)$/rgb:\1\/\2\/\3/g"`
[ "a${OSDFGCOLOR}" = "a" ] && OSDFGCOLOR="rgb:80/ff/80"
[ "a${OSDBGCOLOR}" = "a" ] && OSDBGCOLOR="rgb:00/40/00"
OSDISP="${ISPID}"
export OSDISP; export OSDFGCOLOR; export OSDBGCOLOR;
${OSDOUTPUT} -T "Sakis3G: $1" -P ${verbosecurrentcount} -b percentage -O 2 -c ${OSDFGCOLOR} -u ${OSDBGCOLOR} -f "${XOSDFONT}" -p bottom -a 0 -d 10 -A center &
OSDPID=$!
eval "disown -a" > /dev/null 2> /dev/null
export OSDPID
[ "a${verbosecurrentcount}" = "a100" ] && sleep 3
;;
aosd_cat)
need_arg "AOSDFONT"
${OSDOUTPUT} -n "${AOSDFONT}" -f 100 -t 2 --input=- -u 10000 -o 3000 <<endl &
$1
endl
OSDPID=$!
eval "disown -a" > /dev/null 2> /dev/null
export OSDPID
[ "a${verbosecurrentcount}" = "a100" ] && sleep 3
;;
esac
}
verbose() {
need_binary "printf"
if [ "a$1" = "a100" ]; then
verbosecurrentcount=93
shift
fi
verbosetext=`format_text "$@"`
[ "${verbosecurrentcount}" = "a" ] && verbosecurrentcount=0
if [ "a${verbosetext}" = "a${lastverbosetext}" ]; then
verbosecurrentcount=`expr ${verbosecurrentcount} + 1`;
guruplug_verbose_same
else
verbosecurrentcount=`expr ${verbosecurrentcount} + 7`;
guruplug_verbose
fi
lastverbosetext="${verbosetext}"
verbosecurrentcount=`echo ${verbosecurrentcount}`
export lastverbosetext
export verbosecurrentcount
debug "Verbosing: %d%% %s\n" "${verbosecurrentcount}" "${verbosetext}"
if [ "a${noverbose}" != "a" ]; then
debug "Skipping verbose due to configuration.\n"
unset verbosetext
return 0
fi
if [ "a${OSDOUTPUT}" != "a" ]; then
osdtext=`${printfbin} "$@"`
osd_verbose "${osdtext}"
unset osdtext
else
case "${SGUI}" in
whiptail|dialog|Xdialog|zenity|kdialog)
dialog_verbose "${verbosetext}"
;;
"9menu")
nine_verbose "${verbosetext}"
;;
"interactive terminal")
term_verbose "${verbosetext}"
;;
"terminal")
term_verbose "${verbosetext}"
;;
*)
term_verbose "${verbosetext}"
;;
esac
fi
unset verbosetext
}
notify() {
notificationtext=`format_text "$@"`
debug "Notify: %s\n" "${notificationtext}"
if [ "a${nonotify}" != "a" ]; then
debug "Skipping notification due to configuration.\n"
unset notificationtext
return 0
fi
case "${SGUI}" in
whiptail|dialog|Xdialog|zenity|kdialog)
dialog_notify "${notificationtext}"
;;
"9menu")
nine_notify "${notificationtext}"
;;
"interactive terminal")
term_notify "${notificationtext}"
;;
"terminal")
term_notify "${notificationtext}"
;;
*)
term_notify "${notificationtext}"
;;
esac
unset notificationtext
}
balloon_notify() {
notificationtext=`format_text "$@"`
if [ "a${nonotify}" != "a" ]; then
debug "Skipping balloon notification due to configuration: %s\n" "${notificationtext}"
unset notificationtext
return 0
fi
# File is deleted during release_X_cookie
[ "a${PROVIDER}" != "a" ] && [ -x "${PROVIDER}" ] && ${PROVIDER} getfile "files/sakis3g.png" 2> /dev/null > "/tmp/sakis3g.notification.icon.$$.png"
debug "Will display final message using libnotify.\n"
if [ ! -f "/tmp/sakis3g.notification.icon.$$.png" ]; then
debug "Notifying user without icon.\n"
debug run_command "${notify_sendbin} \"Sakis3G\" \"${notificationtext}\""
else
debug "Notifying user with icon.\n"
debug run_command "${notify_sendbin} --icon=\"/tmp/sakis3g.notification.icon.$$.png\" \"Sakis3G\" \"${notificationtext}\""
debug run_command "${rmbin} -f \"/tmp/sakis3g.notification.icon.$$.png\""
fi
unset notificationtext
}
finalnotify() {
guruplug_notify
if [ "a${prefer_osd}" != "a" -a "a${OSDOUTPUT}" != "a" ]; then
verbose "100" "$@"
elif [ "a${prefer_osd}" = "a" -a "a${balloons}" != "a" -a "a${stick_to_console}" = "a" ] && find_binary "notify-send" && [ "a${DBUS_SESSION_BUS_ADDRESS}" != "a" -a "a${SESSION_MANAGER}" != "a" ]; then
balloon_notify "$@"
else
notify "$@"
fi
}
translate_selection() {
unset translatedarguments
localcounter=0
for localargument in "$@"
do
localcounter=`expr ${localcounter} + 1`; localcounter=`echo ${localcounter}`
if [ "${localcounter}" -eq "1" ]; then
translatedarguments="\"${localargument}\""
elif [ "${localcounter}" -le "5" ]; then
translatedtext=`translate_text "${localargument}"`
translatedarguments=`${printfbin} "%s \"%s\"" "${translatedarguments}" "${translatedtext}"`
unset translatedtext
elif [ "${localcounter}" -gt "5" ]; then
verification=`expr \( ${localcounter} / 2 \) \* 2`; verification=`echo ${verification}`
if [ "a${verification}" = "a${localcounter}" ]; then
translatedarguments=`${printfbin} "%s \"%s\"" "${translatedarguments}" "${localargument}"`
else
translatedtext=`translate_text "${localargument}"`
translatedarguments=`${printfbin} "%s \"%s\"" "${translatedarguments}" "${translatedtext}"`
unset translatedtext
fi
unset verification
fi
done
unset localcounter; unset
eval "user_select \"translated\" ${translatedarguments}"
translatedselection=$?
unset translatedarguments
return ${translatedselection}
}
translate_confirm() {
unset translatedarguments
localcounter=0
for localargument in "$@"
do
localcounter=`expr ${localcounter} + 1`; localcounter=`echo ${localcounter}`
if [ "${localcounter}" -eq "1" ]; then
translatedarguments="\"${localargument}\""
elif [ "${localcounter}" -le "5" ]; then
translatedtext=`translate_text "${localargument}"`
translatedarguments=`${printfbin} "%s \"%s\"" "${translatedarguments}" "${translatedtext}"`
unset translatedtext
elif [ "${localcounter}" -gt "5" ]; then
translatedarguments=`${printfbin} "%s \"%s\"" "${translatedarguments}" "${localargument}"`
fi
done
unset localcounter; unset
eval "user_confirm \"translated\" ${translatedarguments}"
translatedselection=$?
unset translatedarguments
return ${translatedselection}
}
translate_prompt() {
unset translatedarguments
localcounter=0
for localargument in "$@"
do
localcounter=`expr ${localcounter} + 1`; localcounter=`echo ${localcounter}`
if [ "${localcounter}" -eq "1" ]; then
translatedarguments="\"${localargument}\""
elif [ "${localcounter}" -le "5" ]; then
translatedtext=`translate_text "${localargument}"`
translatedarguments=`${printfbin} "%s \"%s\"" "${translatedarguments}" "${translatedtext}"`
unset translatedtext
elif [ "${localcounter}" -gt "5" ]; then
verification=`expr \( ${localcounter} / 2 \) \* 2`; verification=`echo ${verification}`
if [ "a${verification}" = "a${localcounter}" ]; then
translatedarguments=`${printfbin} "%s \"%s\"" "${translatedarguments}" "${localargument}"`
else
translatedtext=`translate_text "${localargument}"`
translatedarguments=`${printfbin} "%s \"%s\"" "${translatedarguments}" "${translatedtext}"`
unset translatedtext
fi
unset verification
fi
done
unset localcounter; unset
eval "user_prompt \"translated\" ${translatedarguments}"
translatedselection=$?
unset translatedarguments
return ${translatedselection}
}
user_confirm() {
unset selection
if [ "a$1" != "atranslated" ]; then
debug "Asking user to confirm: %s\n" "`echo "$@"`"
translate_confirm "$@"
return $?
else
shift
debug "Asking user to confirm: %s\n" "`echo "$@"`"
fi
if [ "$#" -lt 3 ]; then
debug "FIXME: Wrong number of arguments (%d). Returning 99.\n" "$#"
return 99
fi
variable=`selection_argument variable "$@"`
if [ "a$6" = "areset" -a "a${interactive}" != "a" ]; then
eval unset ${variable}yes
eval unset ${variable}no
else
eval alreadyset=\${${variable}yes}
if [ "a${alreadyset}" != "a" ]; then
debug "Switch %syes is already set.\n" "${variable}"
return 0
fi
eval alreadyset=\${${variable}no}
if [ "a${alreadyset}" != "a" ]; then
debug "Switch %sno is already set.\n" "${variable}"
return 1
fi
fi
if voodoo_mode; then
debug "Voodoo-mode is enabled. Will consider it a yes.\n"
eval unset ${variable}no
eval ${variable}yes=1
eval export ${variable}yes
selection=0
return 0
fi
case "${SGUI}" in
whiptail|dialog|Xdialog|zenity|kdialog)
dialog_confirm "$@"
selection=$?
;;
"9menu")
nine_confirm "$@"
selection=$?
;;
"interactive terminal")
interactive_term_confirm "$@"
selection=$?
;;
"terminal")
term_confirm "$@"
selection=$?
;;
*)
term_confirm "$@"
selection=$?
;;
esac
variable=`selection_argument variable "$@"`
if [ "a${selection}" = "a0" ]; then
debug "User answered \"yes\".\n"
eval unset ${variable}no
eval ${variable}yes=1
eval export ${variable}yes
selection=0
else
debug "User answered \"no\".\n"
eval unset ${variable}yes
eval ${variable}no=1
eval export ${variable}no
selection=1
fi
unset variable
return ${selection}
}
user_select() {
unset selection
if [ "a$1" != "atranslated" ]; then
debug "Asking user to select: %s\n" "`echo "$@"`"
translate_selection "$@"
return $?
else
shift
debug "Asking user to select: %s\n" "`echo "$@"`"
fi
if [ "$#" -lt 3 ]; then
debug "FIXME: Wrong number of arguments (%d). Returning 99.\n" "$#"
return 99
fi
variable=`selection_argument variable "$@"`
eval alreadyset=\${${variable}}
if [ "a${alreadyset}" != "a" ]; then
debug "%s=%s\n" "${variable}" "${alreadyset}"
# Check tokens first
for selectioniterator in ${alreadyset}
do
selection_argument invalid "${selectioniterator}" "$@"
selection=$?
if [ "a${selection}" != "a0" -a "a${selection}" != "a" ]; then
debug "User has already selected %s=\"%s\". Returning %d.\n" "${variable}" "${selectioniterator}" "${selection}"
eval export ${variable}="${selectioniterator}"
unset variable; unset alreadyset; unset selectioniterator
return ${selection}
fi
unset selection;
done
unset selectioniterator
# Check whole value then
selection_argument invalid "${alreadyset}" "$@"
selection=$?
if [ "a${selection}" != "a0" -a "a${selection}" != "a" ]; then
debug "User has already selected %s=\"%s\". Returning %d.\n" "${variable}" "${alreadyset}" "${selection}"
eval export ${variable}="${alreadyset}"
unset variable; unset alreadyset
return ${selection}
fi
# Else warn
show_fmt_error "Already selected value %s=\"%s\". Is not valid.\n" "${variable}" "${alreadyset}"
eval unset ${variable}
unset variable; unset alreadyset;
else
debug "Variable %s is not set already.\n" "${variable}"
unset alreadyset; unset variable
fi
if voodoo_mode; then
variable=`selection_argument variable "$@"`
selectioncount=`selection_argument options "$@" | ${wcbin} -l`; selectioncount=`echo ${selectioncount}`
if [ "a${selectioncount}" = "a1" ]; then
selection=1
eval export ${variable}="`selection_argument option 1 "$@"`"
debug "Employed voodoo-mode in selecting %s from unique option: %s\n" "${variable}" "`eval echo \\${${variable}}`"
unset selectioncount; unset variable
return ${selection}
elif [ "a${selectioncount}" = "a2" ]; then
for selection in 1 2
do
voodoovalue=`selection_argument option ${selection} "$@" | ${grepbin} -i "custom" | ${wcbin} -l`; voodoovalue=`echo ${voodoovalue}`
[ "a${voodoovalue}" = "a0" ] && voodoovalue=`selection_argument option ${selection} "$@" | ${grepbin} -i "other" | ${wcbin} -l`; voodoovalue=`echo ${voodoovalue}`
if [ "a${voodoovalue}" = "a1" ]; then
debug "Voodoo determined that selection %d leads to custom/other.\n" "${selection}"
if [ "${selection}" -eq "1" ]; then
selection=2
else
selection=1
fi
eval export ${variable}="`selection_argument option 1 "$@"`"
debug "Employed voodoo-mode in selecting %s from option %d: %s\n" "${variable}" "${selection}" "`eval echo \\${${variable}}`"
unset selectioncount; unset voodoovalue; unset variable
return ${selection}
fi
unset voodoovalue
done
unset selection
fi
unset selectioncount; unset variable
fi
case "${SGUI}" in
whiptail|dialog|Xdialog|zenity|kdialog)
dialog_select "$@"
selection=$?
;;
"9menu")
nine_select "$@"
selection=$?
;;
"interactive terminal")
interactive_term_select "$@"
selection=$?
;;
"terminal")
term_select "$@"
selection=$?
;;
*)
term_select "$@"
selection=$?
;;
esac
debug "User selection was %d.\n" "${selection}"
return ${selection}
}
# Prompts user to enter text
user_prompt() {
if [ "a$1" != "atranslated" ]; then
debug "Asking user to enter: %s\n" "`echo "$@"`"
translate_prompt "$@"
return $?
else
shift
debug "Asking user to enter: %s\n" "`echo "$@"`"
fi
if [ "$#" -lt 3 ]; then
debug "FIXME: Wrong number of arguments (%d). Returning 99.\n" "$#"
return 99
fi
promptvariable=`selection_argument variable "$@"`
eval alreadyset=\${${promptvariable}}
if [ "a${alreadyset}" != "a" ]; then
selection=0
debug "%s=%s\n" "${promptvariable}" "${alreadyset}"
debug "User has already entered %s=\"%s\". Returning %d.\n" "${promptvariable}" "${alreadyset}" "${selection}"
unset alreadyset; unset promptvariable
return ${selection}
else
debug "Variable %s is not set already.\n" "${promptvariable}"
unset alreadyset; unset promptvariable
fi
case "${SGUI}" in
whiptail|dialog|Xdialog|zenity|kdialog)
dialog_prompt "$@"
selection=$?
;;
"9menu")
nine_prompt "$@"
selection=$?
;;
"interactive terminal")
interactive_term_prompt "$@"
selection=$?
;;
"terminal")
term_prompt "$@"
selection=$?
;;
*)
term_prompt "$@"
selection=$?
;;
esac
promptvariable=`selection_argument variable "$@"`
eval "alreadyset=\"\${${promptvariable}}\""
debug "New value is %s=\"%s\". Returning %d.\n" "${promptvariable}" "${alreadyset}" "${selection}"
unset alreadyset; unset promptvariable
return ${selection}
}
# Stops execution with return status $1
stop_with() {
verbose "Cleaning"
if [ "a$1" = "a" ]; then
debug "Stopping operation with return status: %d\n" "99"
exit 99
else
debug "Stopping operation with return status: %d\n" "$1"
exit $1
fi
}
# Shows error and aborts execution
stop_fmt_error() {
errorcode="$1"
[ "$#" -gt "0" ] && shift
show_fmt_error "$@"
stop_with ${errorcode}
}
# Make sure usual binary containing directories exist in PATH, even
# if not running as root. Some distributions do not include those
# folders in PATH (although they contain some useful user oriented
# utilities) if not running as root, or if not running from an
# interactive shell.
fix_path() {
[ -n "${PATHFIXXED}" ] && return 0
for fixpathi in "/bin" "/usr/bin" "/sbin" "/usr/sbin"
do
if strinstr "${fixpathi}" "${PATH}"; then
debug "Dir \"%s\" exists in PATH.\n" "${fixpathi}"
else
export PATH="${fixpathi}:${PATH}"
debug "Added \"%s\" to PATH.\n" "${fixpathi}"
fi
done
unset fixpathi
PATHFIXXED=YES
debug "Done setting up PATH.\n"
}
# Locates full path of binary specified in argument
find_binary() {
[ "a$1" = "a" ] && return 1
binaryvariable=`echo "$1" | sed -e "s/-/_/g"`
binaryvariable=`echo "${binaryvariable}" | sed -e "s/9/nine/g"`
[ "a${binaryvariable}" = "a" ] && binaryvariable="$1"
findbinaryfound=`eval echo \\\${${binaryvariable}bin}`
if [ "a${findbinaryfound}" = "a" ]; then
if [ "a${whichbin}" = "a" ]; then
findbinaryfound=`which which 2> /dev/null`
elif [ ! -x "${whichbin}" ]; then
findbinaryfound=`which which 2> /dev/null`
else
findbinaryfound="${whichbin}"
fi
if [ "a${findbinaryfound}" = "a" ]; then
debug "Unable to locate \"%s\" within PATH, because \"%s\" utility is not available.\n" "$1" "which"
unset findbinaryfound
return 1
else
if [ -z "${whichbin}" ]; then
export whichbin="${findbinaryfound}"
debug "Can search through PATH, \"%s\" binary found.\n" "which"
fi
findbinaryfound=`${findbinaryfound} "${1}" 2> /dev/null`
if [ "a${findbinaryfound}" = "a" ]; then
debug "Unable to locate \"%s\" within PATH.\n" "$1"
unset findbinaryfound
return 1
elif [ -x "${findbinaryfound}" ]; then
debug "Located \"%s\" within PATH (%s).\n" "$1" "${findbinaryfound}"
eval export ${binaryvariable}bin="${findbinaryfound}"
fi
fi
fi
if [ -x "${findbinaryfound}" ]; then
unset findbinaryfound
return 0
else
debug "Unable to execute \"%s\" from \"%s\".\n" "$1" "${findbinaryfound}"
unset findbinaryfound
eval unset ${binaryvariable}bin
return 1
fi
}
# Aborts execution if "$1" binary is not found.
need_binary() {
[ "a$1" = "a" ] && term_error "FIXME: Executed need_binary with no argument."
! find_binary "$1" && stop_fmt_error 4 "Unable to locate dependency \"%s\". Script will now abort." "$1"
}
# Check dependencies. Only really required staff should be placed here.
# We cannot yet search in PATH.
check_level_one_deps() {
for checkdependency in which echo grep
do
need_binary "${checkdependency}"
done
unset checkdependency
debug "Level 1 dependencies met.\n"
}
# Checks if communication software is available and aborts if not
check_com_software() {
! find_binary "wvdial" && direct_pppd=yes
if [ -n "${direct_pppd}" ]; then
need_binary "pppd"
need_arg "PPPD_PEERS"
if [ ! -d "${PPPD_PEERS}" ]; then
debug "Unable to locate pppd peers directory (%s)." "${pppdpeerdir}"
fi
fi
for checkdependency in chat
do
need_binary "${checkdependency}"
done
unset checkdependency
return 0
}
# Checks if method for becoming root, exists.
check_su_software() {
unset SUMETHOD
if [ -z "${alwayssudo}" ]; then
if [ -z "${stick_to_console}" ]; then
if find_binary "gksu"; then
debug "Running on a GNOME system.\n"
SUMETHOD="gksu"
elif find_binary "kdesu"; then
debug "Running on a KDE system.\n"
SUMETHOD="kdesu"
elif [ -x "/usr/lib/kde4/libexec/kdesu" ]; then
export kdesubin="/usr/lib/kde4/libexec/kdesu"
debug "Running on a KDE4 system.\n"
SUMETHOD="kdesu"
fi
fi
if [ -z "${SUMETHOD}" ]; then
if find_binary "su"; then
debug "Using plain text mode su.\n"
SUMETHOD="su"
else
debug "No su method found. Will check if sudo available.\n"
export alwayssudo=yes
fi
fi
fi
if [ -n "${alwayssudo}" ]; then
! find_binary "sudo" && stop_fmt_error 3 "No method for acquiring root privileges found."
debug "Running with sudo configuration.\n"
SUMETHOD="sudo"
fi
return 0
}
# Forces use of text mode utilities for getting root privileges
console_su_software() {
if [ "${SUMETHOD}" = "kdesu" -o "${SUMETHOD}" = "gksu" ]; then
if find_binary "su"; then
debug "Reverting to plain text mode su.\n"
SUMETHOD="su"
else
debug "No text mode su found. Will check if sudo available.\n"
export alwayssudo=yes
check_su_software
fi
fi
}
# Check dependencies. Only really required staff should be placed here.
# We can now search within path.
check_level_two_deps() {
for checkdependency in printf wc cut cat tail head sort uniq ls sed setsid getent ps chmod chown touch expr tr seq cp rm who mv expr basename dirname
do
need_binary "${checkdependency}"
done
unset checkdependency
debug "Level 2 dependencies met.\n"
if [ "a${PROVIDER}" != "a" ] && [ ! -x "${PROVIDER}" ]; then
debug run_command "${chmodbin} +x \"${PROVIDER}\""
if [ ! -x "${PROVIDER}" ]; then
stop_fmt_error 5 "Unable to determine my path.\n"
fi
debug "Successfully turned myself an executable.\n"
fi
}
# If running as root, checks dependencies that should be met
# once running as root. If not running as root, checks if
# software for becoming root, is available.
check_root_deps() {
if ! we_are_root_already; then
check_su_software
else
for checkdependency in ifconfig
do
need_binary "${checkdependency}"
done
unset checkdependency
fi
debug "Root level dependencies met.\n"
}
# Locate required utilities within PATH
resolv_binaries() {
check_level_one_deps
fix_path
get_me ${1}
check_level_two_deps
debug "Basic binaries are resolved.\n"
}
# Provides a writable log position
need_log() {
need_arg "LOGPOSITION"
for logcandidate in "${LOGPOSITION}" "/var/log/sakis3g.log" "sakis3g.log.$$" "/tmp/sakis3g.log.$$"
do
if [ "a${logcandidate}" != "a" ]; then
${touchbin} "${logcandidate}" 2> /dev/null
if [ -w "${logcandidate}" ]; then
export LOGPOSITION="${logcandidate}"
debug "Log file is set to \"%s\".\n" "${LOGPOSITION}"
return 0
else
unset logposition
fi
fi
done
debug "Failed to find a place to store log.\n"
export LOGPOSITION="/dev/null"
debug "Log file is set to \"%s\".\n" "${logposition}"
return 1
}
# Returns true(0) if process with PID given as
# argument, is not running any more.
notrunning() {
if [ -n "$1" ]; then
pidrunning=`${psbin} -p $1 -o pid= 2> /dev/null | wc -l`
pidrunning=`echo ${pidrunning}`
else
pidrunning=1
fi
if [ "${pidrunning}" -ne "0" ]; then
debug "PID %s is still running.\n" "$1"
else
debug "PID %s is not running any more.\n" "$1"
fi
return ${pidrunning}
}
# Sets PPROCESS variable
get_parent_process() {
pidtocheck=$1
[ "a${pidtocheck}" = "a" ] && pidtocheck="${PPID}"
PPROCESS=`${psbin} -p ${pidtocheck} -o comm= 2> /dev/null`
export PPROCESS
if [ "a${PPROCESS}" = "a" ]; then
debug "Unable to get parent process name.\n"
unset PPROCESS; unset pidtocheck
return 1
fi
unset pidtocheck
return 0
}
# Check if called by udevd. If yes, spawn in background
# and exit this instance.
check_udevd() {
if [ "a${PROVIDER}" = "a" ]; then
get_parent_process
else
pppid=`${psbin} -p ${PPID} -o ppid= 2> /dev/null`
pppid=`echo ${pppid}`
get_parent_process "${pppid}"
unset pppid
fi
debug "Parent process is: %s\n" "${PPROCESS}"
if [ "a${PPROCESS}" = "audevd" ]; then
debug "Running by a udevd event.\n"
need_log
if have_me; then
debug "Unconditionally setting DISPLAY to :0.\n"
export DISPLAY=:0
debug "Will now spawn child process in background.\n"
${ME} "$@" > "${LOGPOSITION}" 2>&1 &
stop_with 0
fi
else
debug "Running by user request.\n"
fi
}
# Get my location if possible
get_me() {
unset metarget
[ -x "${PROVIDER}" ] && metarget="${PROVIDER}"
[ -z "${metarget}" ] && metarget="$1"
find_binary "readlink" && ME=`${readlinkbin} -e ${metarget} 2> /dev/null`
[ -z "${ME}" ] && find_binary "which" && ME="`${whichbin} ${metarget} 2> /dev/null`"
unset metarget
[ -n "${ME}" ] && [ ! -x "${ME}" ] && unset ME
if [ -z "${ME}" ]; then
unset ME
debug "Unable to determine my own location.\n"
else
debug "My location is \"%s\".\n" "${ME}"
fi
}
# Makes sure we know our own executable
have_me() {
[ -n "${ME}" ] && [ -x "${ME}" ] && return 0;
stop_fmt_error 5 "Unable to determine my path.\n"
}
# If we are root, attempts to determine real user
# behind it, by looking back the process tree. Goes
# back 15 processes before giving up.
resolv_root() {
[ -z "$1" ] && pid=$$
[ -z "${pid}" ] && pid=$1
puser=`${psbin} -p ${pid} -o user= 2> /dev/null`
if [ -z "${puser}" ]; then
unset pid; unset puser
return
elif [ "${puser}" != "root" ]; then
runner="${puser}"
unset pid; unset puser
return
fi
unset puser
ppid=`${psbin} -p ${pid} -o ppid= 2> /dev/null`; unset pid
if [ -z "${ppid}" ]; then
unset ppid
return
elif [ "a${ppid}" = "a1" ]; then
unset ppid
return
fi
[ -z "$2" ] && count=0
count=`expr $2 + 1`
count=`echo ${count}`
[ "$count" -lt 15 ] && resolv_root ${ppid} ${count}
unset ppid; unset count
}
# Locates really running user. If root, attempts to resolv
# it to real user.
find_user() {
unset runner; unset runhome
[ -n "${USER}" ] && runner="${USER}"
[ -n "${LOGNAME}" ] && runner="${LOGNAME}"
[ -n "${USERNAME}" ] && runner="${USERNAME}"
[ -z "${runner}" ] && find_binary "who" && runner=`${whobin} -m | ${cutbin} -d\ -f1`
[ -z "${runner}" ] && we_are_root_already && runner="root"
[ -n "${runner}" ] && [ "${runner}" = "root" ] && resolv_root $$ 0
if [ -n "${runner}" ]; then
runhome=`${getentbin} passwd ${runner} 2> /dev/null | ${cutbin} -d: -f6`
[ -n "${runhome}" ] && [ ! -d "${runhome}" ] && unset runhome
[ -z "${runhome}" ] && unset runner
[ -n "${runner}" ] && debug "Person behind screen is %s.\n" "${runner}"
fi
[ -z "${runner}" ] && debug "Unable to find our username.\n"
}
# Determines if display $1 is unique local display.
unique_local_display() {
debug "Will check if display %s belongs to unique user logged in.\n" "$1"
[ "a$1" = "a" ] && return 1
! find_binary "who" && return 1
loggedusers=`${whobin} | ${grepbin} -v root | ${cutbin} -d\ -f1 | ${sortbin} | ${uniqbin} | ${wcbin} -l`
loggedusers=`echo ${loggedusers}`
if [ "a${loggedusers}" != "a1" ]; then
debug "Found %d logged users. Cannot make sure who will really see message.\n" "${loggedusers}"
unset loggedusers
return 1
fi
unset loggedusers
loggeduser=`${whobin} | ${grepbin} -v root | ${cutbin} -d\ -f1 | ${sortbin} | ${uniqbin}`
confirm=`${whobin} | ${grepbin} ${1} | ${cutbin} -d\ -f1 | ${sortbin} | ${uniqbin} | ${grepbin} "^${loggeduser}$"`
if [ "a${loggeduser}" = "a${confirm}" ]; then
debug "Unique display %s belongs to user %s.\n" "$1" "${loggeduser}"
unset confirm; unset loggeduser;
return 0
fi
debug "Display %s does not belongs to user %s.\n" "$1" "${loggeduser}"
unset confirm; unset loggeduser;
return 1
}
# Attemtps to get access to display $1
access_display() {
debug "Will attempt to get access to display %s.\n" "$1"
[ "a$1" = "a" ] && return 1
! find_binary "xauth" && return 1
[ "a${XAUTHORITY}" = "a" ] && unset XAUTHORITY
gotaccess=`${xauthbin} nlist $1 2> /dev/null | ${wcbin} -l`
gotaccess=`echo ${gotaccess}`
if [ "a${gotaccess}" = "a0" ]; then
xuser=`${whobin} -u | ${grepbin} -v "^root" | ${grepbin} ${1} | ${cutbin} -d\ -f1 | ${sortbin} | ${uniqbin}`
xhome=$(${getentbin} passwd ${xuser} | ${cutbin} -d: -f6)
debug "Not currently trusted to display %s belonging to %s.\n" "${1}" "${xuser}"
if [ "a${LOCALAUTHORITY}" != "a" ] && [ -r "${LOCALAUTHORITY}" ]; then
xholder="${LOCALAUTHORITY}"
elif [ -d "${xhome}" ] && [ -r "${xhome}/.Xauthority" ]; then
xholder="${xhome}/.Xauthority"
else
unset xholder
fi
if [ "a${xholder}" = "a" ]; then
debug "Unable to locate Xauthority file of %s.\n" "${xuser}"
else
debug "Will attempt to steal cookie from %s.\n" "${xholder}"
if [ "a${HOME}" = "a" ]; then
rruser="${runner}"
we_are_root_already && rruser="root"
rrhome=$(${getentbin} passwd ${rruser} | ${cutbin} -d: -f6)
if [ -d "${rrhome}" -a "a${xhome}" != "a${rrhome}" ]; then
debug "HOME variable not set already. Setting HOME for %s: %s\n" "${rruser}" "${rrhome}"
export HOME="${rrhome}"
fi
unset rruser; unset rrhome;
else
debug "HOME directory set already (%s).\n" "${HOME}"
fi
${xauthbin} -f "${xholder}" nextract - $1 2> /dev/null | ${xauthbin} nmerge - 2> /dev/null
gotaccess=`${xauthbin} nlist ${1} 2> /dev/null | ${wcbin} -l`
gotaccess=`echo ${gotaccess}`
if [ "a${gotaccess}" = "a0" ]; then
debug "Failed to steal cookie.\n"
else
debug "Cookie stolen from %s(%s) to %s.\n" "${xuser}" "${1}" "${HOME}/.Xauthority"
export XCOOKIE="$1"
addexittrap "release_X_cookie" EXIT
unset xuser; unset xhome; unset gotaccess; unset xholder
return 0
fi
fi
unset xuser; unset xhome; unset gotaccess; unset xholder
else
debug "Already granted access to display %s.\n" "${1}"
[ "a${XAUTHORITY}" != "a" ] && export LOCALAUTHORITY="${XAUTHORITY}"
unset gotaccess
return 0
fi
return 1
}
# Find DISPLAY
find_display() {
if [ -n "${stick_to_console}" ]; then
unset DISPLAY; unset display;
debug "Not using an X display due to stick-to-console variable.\n"
else
display="${DISPLAY}"
# If display is not set, or is remote, attempt to find a local display of runner user.
[ -z "${DISPLAY}" -o "`echo ${DISPLAY} | ${cutbin} -b1`" != ":" ] \
&& display="" \
&& [ -n "${runner}" -a "a${runner}" != "aroot" ] \
&& find_binary "who" \
&& display=`${whobin} -m | ${grepbin} "^${runner}" | ${grepbin} "(\:.*)" | ${cutbin} -d\( -f2 | ${cutbin} -d\) -f1 | ${sortbin} | ${headbin} -1`
# If DISPLAY is set to a local display, but we are run
# from root himself, and that X display is the unique
# local X display available, use it no matter what.
[ -n "${display}" -a -n "${DISPLAY}" -a "a${runner}" = "aroot" ] \
&& ! unique_local_display "${DISPLAY}" && unset display
# Get number of display (if any)
displaynum=`echo ${display} | ${cutbin} -b2- | ${cutbin} -d. -f1`
display=":${displaynum}"
# Validate that determined xsession exists.
[ ! -S "/tmp/.X11-unix/X${displaynum}" ] && unset display
unset displaynum
[ -n "${display}" ] && ! access_display "${display}" && unset display
if [ -z "${display}" ]; then
debug "Unable to find a local X display, will stick to terminal.\n"
unset DISPLAY; unset display;
export stick_to_console=yes
find_gui
else
export display
export DISPLAY="${display}"
fi
fi
if [ -z "${display}" ]; then
unset DISPLAY; unset display;
export stick_to_console=yes
console_su_software
else
debug "Will be using display %s.\n" "${display}"
fi
}
# Selects GUI to be used if not already set by SGUI variable.
find_gui() {
debug "Selecting GUI.\n"
if [ -n "${stick_to_console}" -a -n "$SGUI" ]; then
debug "Validating pre-selected GUI: %s\n" "${SGUI}"
[ "a$SGUI" = "azenity" ] && unset SGUI
[ "a$SGUI" = "agdialog" ] && unset SGUI
[ "a$SGUI" = "akdialog" ] && unset SGUI
[ "a$SGUI" = "aXdialog" ] && unset SGUI
[ "a$SGUI" = "a9menu" ] && unset SGUI
[ "a$SGUI" = "agnome-terminal" ] && unset SGUI
[ "a$SGUI" = "akonsole" ] && unset SGUI
[ "a$SGUI" = "axterm" ] && unset SGUI
[ -z "${SGUI}" ] && debug "Could not be used from console. Will seek an alternative.\n"
fi
if [ "a${SGUI}" != "a" -a "a${SGUI}" != "ainteractive terminal" -a "a${SGUI}" != "aterminal" ] && ! find_binary "${SGUI}"; then
debug "%s not found. Will search for another GUI provider.\n" "${SGUI}"
unset SGUI
fi
if [ "a${stick_to_console}" = "a" ]; then
[ "a${SGUI}" = "a9menu" ] && ! find_binary "9menu" && unset SGUI
[ "a${SGUI}" = "a9menu" ] && ! find_binary "xterm" && unset SGUI
[ -z "${SGUI}" ] && find_binary "kdialog" && SGUI="kdialog"
[ -z "${SGUI}" ] && find_binary "zenity" && SGUI="zenity"
[ -z "${SGUI}" ] && find_binary "Xdialog" && SGUI="Xdialog"
[ -z "${SGUI}" ] && find_binary "gnome-terminal" && SGUI="gnome-terminal"
[ -z "${SGUI}" ] && find_binary "konsole" && SGUI="konsole"
[ -z "${SGUI}" ] && find_binary "xterm" && SGUI="xterm"
if [ -z "${SGUI}" ]; then
debug "No graphical GUI found. Forced to stick to terminal.\n"
export stick_to_console=yes
fi
fi
if [ "a${interactive}" != "a" ]; then
[ -z "${SGUI}" ] && find_binary "dialog" && SGUI="dialog"
[ -z "${SGUI}" ] && find_binary "whiptail" && SGUI="whiptail"
[ -z "${SGUI}" ] && SGUI="interactive terminal"
fi
[ -z "${SGUI}" ] && SGUI="terminal"
# Custom setup per GUI
[ "a${SGUI}" = "adialog" ] && addexittrap "dialog_clearscreen"
[ "a${SGUI}" = "aXdialog" -o "a${SGUI}" = "a9menu" ] && export notranslate=yes && unset foldwrapping && need_arg "foldwrapping"
[ "a${SGUI}" = "adialog" -o "a${SGUI}" = "awhiptail" -o "a${SGUI}" = "aterminal" -o "a${SGUI}" = "ainteractive terminal" ] && export stick_to_console=yes
[ "a${SGUI}" = "adialog" -o "a${SGUI}" = "awhiptail" -o "a${SGUI}" = "ainteractive terminal" -o "a${SGUI}" = "aXdialog" -o "a${SGUI}" = "azenity" -o "a${SGUI}" = "akdialog" -o "a${SGUI}" = "a9menu" ] && export interactive=yes
debug "%s selected as GUI.\n" "${SGUI}"
# Forward to terminal if have to do so
case "${SGUI}" in
xterm)
debug "Will spawn xterm window.\n"
unset SGUI; export stick_to_console=yes; export interactive=yes;
state_variables
eval ${xtermbin} -T "Sakis3G" +cm +dc -e ${ME} ${allargs} ${statevariables}
stop_with $?
;;
gnome-terminal)
debug "Will spawn gnome-terminal window.\n"
unset SGUI; export stick_to_console=yes; export interactive=yes;
state_variables
eval ${gnome_terminalbin} -t "Sakis3G" -x ${ME} ${allargs} ${statevariables}
stop_with $?
;;
konsole)
debug "Will spawn konsole window.\n"
unset SGUI; export stick_to_console=yes; export interactive=yes;
state_variables
eval ${konsolebin} --title "Sakis3G" -e "${ME} ${allargs} ${statevariables}"
stop_with $?
;;
esac
# Check for OSD
unset OSDOUTPUT
if [ "a${stick_to_console}" = "a" -a "a${prefer_osd}" != "a" ]; then
if find_binary "osd_cat"; then
export OSDOUTPUT="osd_cat"
elif find_binary "aosd_cat"; then
export OSDOUTPUT="aosd_cat"
fi
[ "a${OSDOUTPUT}" != "a" ] && debug "Will be using \"%s\" for displaying OSD messages.\n" "${OSDOUTPUT}"
fi
[ "a${prefer_osd}" != "a" -a "a${OSDOUTPUT}" = "a" ] && unset prefer_osd && debug "OSD will not appear.\n"
return 0
}
# Checks if module $1 is loaded
module_loaded() {
[ "a$1" = "a" ] && return 99
unset moduleloaded
debug "Checking if module \"%s\" is currently loaded.\n" "$1"
if [ -r "/proc/modules" ]; then
moduleloaded=`${grepbin} "^$1 " "/proc/modules" 2> /dev/null | ${sedbin} -e "s/^$1 \([0-9][0-9]*\) \([0-9][0-9]*\) \(.*\)$/\1 \3/g"`
if [ "a${moduleloaded}" = "a" ]; then
debug "Module \"%s\" is not currently loaded.\n" "$1"
unset moduleloaded
return 1
elif [ "a${moduleloaded}" = "a$1 0" ]; then
debug "Module \"%s\" is currently loaded having no users.\n" "$1"
unset moduleloaded
return 0
else
debug "Module \"%s\" is currently loaded and occupied.\n" "$1"
unset moduleloaded
return 0
fi
elif find_binary "lsmod"; then
moduleloaded=`${lsmodbin} | ${grepbin} "^$1 " | ${wcbin} -l`; moduleloaded=`echo ${moduleloaded}`
if [ "a${moduleloaded}" = "a" -o "a${moduleloaded}" = "a0" ]; then
debug "Module \"%s\" is not currently loaded.\n" "$1"
unset moduleloaded
return 1
else
debug "Module \"%s\" is currently loaded.\n" "$1"
unset moduleloaded
return 0
fi
else
show_fmt_error "Unable to check if module is currently loaded or if it has users.\n"
return 1
fi
}
# Unloads module from system if possible
module_unload() {
[ "a$1" = "a" ] && return 99
! module_loaded "$1" && return 0
! find_binary "modprobe" && return 1
debug "Attempting to unload module \"%s\".\n" "$1"
debug run_command "${modprobebin} -r -v $1"
debug "Waiting for module to vanish.\n"
if module_loaded "$1"; then
show_fmt_error "Failed to unload module \"%s\".\n" "$1"
return 1
else
debug "Module \"%s\" succesfully unloaded.\n" "$1"
return 0
fi
}
# Loads module $1 if possible, providing arguments for device $2 if applicable
module_load() {
[ "a$1" = "a" ] && return 99
module_loaded "$1" && return 0
! find_binary "modprobe" && return 1
debug "Attempting to load module \"%s\".\n" "$1"
need_arg "SERIALDRIVERS"
needsarg=`echo " ${SERIALDRIVERS} " | ${grepbin} " $1 " | ${wcbin} -l`; needsarg=`echo ${needsarg}`
if [ "a${needsarg}" = "a1" -a "a$2" != "a" ]; then
if usb_device_connected "$2"; then
modulevend=`echo "$2" | ${cutbin} -d: -f1`
moduleprod=`echo "$2" | ${cutbin} -d: -f2`
modargs="vendor=0x${modulevend} product=0x${moduleprod}"
unset modulevend; unset moduleprod
debug "Will provide arguments to \"%s\": %s\n" "$1" "${modargs}"
else
debug "Warning: Module \"%s\" needs arguments, but \"%s\" does not refer to a connected device.\n" "$1" "$2"
unset modargs
fi
elif [ "a${needsarg}" = "a1" ]; then
debug "Warning: Module \"%s\" needs arguments but device was not specified.\n" "$1"
unset modargs
fi
debug run_command "${modprobebin} $1 ${modargs}"
debug "Waiting for module to get loaded.\n"
unset modargs; unset needsarg
counter=0
while [ "${counter}" -lt "6" ]
do
if ! module_loaded "$1"; then
debug "Module \"%s\" still not live. Waiting a second.\n" "$1"
sleep 1
fi
if module_loaded "$1"; then
debug "Module \"%s\" succesfully loaded.\n" "$1"
unset counter
return 0
fi
counter=`expr ${counter} + 1`; counter=`echo ${counter}`
done
unset counter
show_fmt_error "Failed to load module \"%s\".\n" "$1"
return 1
}
# Attempts to detach driver $1 from device $2 interface $3
# If failed to detach, attempts to completely unload $1 before failing.
module_unbind() {
[ "a$1" = "a" ] && return 99
verbose "Unloading driver %s" "$1"
if [ "a$2" = "a" -a "a$3" = "a" ]; then
debug "Requested to unbind module \"%s\" without device specified. Will try to unload it.\n" "$1"
module_unload "$1"
return $?
fi
moduleattached=`usb_loaded_driver "$2" "$3" | ${tailbin} -1 | ${grepbin} "$1" | ${wcbin} -l`
if [ "a${TIMEOUTOCCURED}" != "a" ]; then
show_fmt_error "Seems like an electrical/USB bus error occured. You may need to replug your modem for it to properly work.\n"
unset TIMEOUTOCCURED
fi
moduleattached=`echo ${moduleattached}`
if [ "a${moduleattached}" = "a" -o "a${moduleattached}" = "a0" ]; then
debug "Module \"%s\" does not appear to be attached to device \"%s\".\n" "$1" "$2"
unset moduleattached
return 0
fi
debug "Module \"%s\" is currently attached to \"%s\".\n" "$1" "$2"
[ "a$3" != "a" ] && usb_sysfsdir_int "$2" "$3" && unbindvalue=`${basenamebin} ${sysfsintloc}`
[ "a$3" = "a" ] && usb_sysfsdir && unbindvalue=`cd "${sysfsloc}"; ${lsbin} -1d \`${basenamebin} ${sysfsloc}\`*`
[ "a${unbindvalue}" = "a" ] && unbindvalue=`echo "$2" | ${sedbin} -e "s/:/ /g"`
sent=0
[ "a$1" = "ausb_storage" ] && localdrivername="usb-storage"
for endpoint in /sys/bus/usb/drivers/${localdrivername}/unbind /sys/bus/usb/drivers/$1/unbind
do
for destination in ${unbindvalue}
do
if [ -w "${endpoint}" ]; then
echo -n "${destination}" > "${endpoint}" 2> /dev/null
debug "Sent \"%s\" to \"%s\".\n" "${destination}" "${endpoint}"
sent=1
fi
done
unset destination
done
unset unbindvalue; unset endpoint; unset localdrivername
if [ "${sent}" -eq "1" ]; then
debug "Expecting module to detach from device.\n"
while [ "${sent}" -lt "6" ]
do
unset moduleattached
moduleattached=`usb_loaded_driver "$2" "$3" | ${tailbin} -1 | ${grepbin} "$1" | ${wcbin} -l`
if [ "a${TIMEOUTOCCURED}" != "a" ]; then
show_fmt_error "Seems like an electrical/USB bus error occured. You may need to replug your modem for it to properly work.\n"
unset TIMEOUTOCCURED
break
fi
moduleattached=`echo ${moduleattached}`
if [ "a${moduleattached}" = "a" -o "a${moduleattached}" = "a0" ]; then
debug "Module \"%s\" has detached from device \"%s\".\n" "$1" "$2"
unset moduleattached; unset sent
if find_binary "modprobe"; then
if [ "a$1" != "ausb_storage" -a "a$1" != "ausb-storage" ]; then
debug "Will attempt to also remove it.\n"
debug run_command "${modprobebin} -r -v $1"
module_loaded "$1"
fi
fi
return 0
fi
debug "Module still attached. Waiting for %d second(s).\n" "${sent}"
sent=`expr ${sent} + 1`; sent=`echo ${sent}`
sleep 1
done
debug "Module \"%s\" did not detach from device \"%s\". Will try to unload it.\n" "$1" "$2"
fi
module_unload "$1"
return $?
}
# Attempts to bind module $1 to device $2, interface $3 (optional)
module_bind() {
[ "a$1" = "a" -o "a$2" = "a" ] && return 99
verbose "Loading driver %s" "$1"
module_load "$1" "$2"
ret=$?; [ "${ret}" -ne "0" ] && return ${ret}
unset moduleattached
modulename="$1"
[ "a${modulename}" = "ausb-storage" ] && modulename="usb_storage"
[ "a${modulename}" = "acdc-acm" ] && modulename="cdc_acm"
moduleattached=`usb_loaded_driver "$2" "$3" | ${tailbin} -1 | ${grepbin} "${modulename}" | ${wcbin} -l`
if [ "a${TIMEOUTOCCURED}" != "a" ]; then
show_fmt_error "Seems like an electrical/USB bus error occured. You may need to replug your modem for it to properly work.\n"
unset TIMEOUTOCCURED
fi
moduleattached=`echo ${moduleattached}`
if [ "a${moduleattached}" != "a" -a "a${moduleattached}" != "a0" ]; then
debug "Module \"%s\" attached to device \"%s\".\n" "$1" "$2"
unset moduleattached; unset sent; unset modulename
return 0
fi
unset moduleattached
debug "Module \"%s\" not yet attached to \"%s\".\n" "$1" "$2"
bindvalue=`echo "$2" | ${sedbin} -e "s/:/ /g"`
sent=0
for endpoint in /sys/module/${modulename}/drivers/usb-serial:*/new_id
do
if [ -w "${endpoint}" ]; then
echo -n "${bindvalue}" > "${endpoint}" 2> /dev/null
if [ "$?" -eq "0" ]; then
debug "Sent \"%s\" to \"%s\".\n" "${bindvalue}" "${endpoint}"
sent=1
fi
fi
done
if [ "a${sent}" != "a1" ]; then
for endpoint in /sys/module/${modulename}/drivers/usb:*/new_id
do
echo -n "${bindvalue}" > "${endpoint}" 2> /dev/null
if [ "$?" -eq "0" ]; then
debug "Sent \"%s\" to \"%s\".\n" "${bindvalue}" "${endpoint}"
sent=1
fi
done
fi
unset bindvalue; unset endpoint
if [ "a${sent}" = "a1" ]; then
counter=0
while [ "${counter}" -lt "10" ]
do
moduleattached=`usb_loaded_driver "$2" "$3" | ${tailbin} -1 | ${grepbin} "${modulename}" | ${wcbin} -l`
if [ "a${TIMEOUTOCCURED}" != "a" ]; then
show_fmt_error "Seems like an electrical/USB bus error occured. You may need to replug your modem for it to properly work.\n"
unset TIMEOUTOCCURED
break;
fi
moduleattached=`echo ${moduleattached}`
if [ "a${moduleattached}" != "a1" ]; then
debug "Waiting one second.\n"
sleep 1
fi
moduleattached=`usb_loaded_driver "$2" "$3" | ${tailbin} -1 | ${grepbin} "${modulename}" | ${wcbin} -l`
if [ "a${TIMEOUTOCCURED}" != "a" ]; then
show_fmt_error "Seems like an electrical/USB bus error occured. You may need to replug your modem for it to properly work.\n"
unset TIMEOUTOCCURED
break;
fi
moduleattached=`echo ${moduleattached}`
if [ "a${moduleattached}" != "a" -a "a${moduleattached}" != "a0" ]; then
debug "Module \"%s\" attached to device \"%s\".\n" "$1" "$2"
unset moduleattached; unset sent; unset counter; unset modulename
return 0
fi
unset moduleattached
counter=`expr ${counter} + 1`; counter=`echo ${counter}`
done
unset counter
fi
debug "Module \"%s\" did not bind to device \"%s\".\n" "$1" "$2"
if [ "a$4" != "anoreload" ]; then
debug "Will attempt to do a reload cycle.\n"
if module_unload "$1" "$2" "$3"; then
if module_bind "$1" "$2" "$3" "noreload"; then
unset counter; unset sent; unset moduleattached; unset modulename
debug "Reload cycle did the trick.\n"
debug "Module \"%s\" attached to device \"%s\".\n" "$1" "$2"
return 0
else
return $?
fi
fi
fi
unset moduleattached; unset modulename
if [ "${sent}" -eq "0" ]; then
show_fmt_error "Module \"%s\" loaded but did not bind to device \"%s\".\n" "$1" "$2"
else
show_fmt_error "Module \"%s\" loaded but refused to bind to device \"%s\".\n" "$1" "$2"
fi
unset sent; unset counter
return 1
return 99
}
# Unlocks a previously acquired lock to hal
hal_unlock() {
[ "a${nohal}" != "a" ] && return 0
[ "a${HAL_LOCK}" = "a" ] && return 0
debug "Releasing HAL lock %d.\n" "${HAL_LOCK}"
if notrunning "${HAL_LOCK}"; then
debug "Already unlocked.\n"
else
if [ -f "/tmp/sakis3g.hal.lock.$$" ]; then
${rmbin} -f "/tmp/sakis3g.hal.lock.$$"
sleep 2
fi
if ! notrunning "${HAL_LOCK}"; then
debug "Failed to unlock by unlinking mutex file. Will try to kill.\n"
term_clearline
${killbin} -1 ${HAL_LOCK} 2> /dev/null
if ! notrunning "${HAL_LOCK}"; then
debug "Failed to kill PID %d.\n" "${HAL_LOCK}"
return 1
fi
fi
debug "Unlocked.\n"
fi
unset HAL_LOCK
return 0
}
# Attempts to establish lock of interface $1 (i.e. org.freedesktop.Hal.Device.Storage)
hal_acquire_lock() {
[ "a${nohal}" != "a" ] && return 0
[ "a${HAL_LOCK}" != "a" ] && ! hal_unlock && return 1
! find_binary "hal-lock" && return 1
! find_binary "kill" && return 1
! find_binary "touch" && return 1
! we_are_root && return 1
debug "Acquiring lock in HAL for \"%s\".\n" "$1"
${touchbin} "/tmp/sakis3g.hal.lock.$$"
hal-lock --interface "$1" --exclusive --run "${ME} holdlock /tmp/sakis3g.hal.lock.$$" &
halpid=$!; unset informed
while ! notrunning ${halpid}
do
hallocksuccess=`${catbin} "/tmp/sakis3g.hal.lock.$$" 2> /dev/null`; hallocksuccess=`echo ${hallocksuccess} | ${sedbin} -e "s/ //g"`
if [ "a${hallocksuccess}" = "a" ]; then
unset hallocksuccess
[ "a${informed}" = "a" ] && verbose "Acquiring exclusive lock to HAL"
informed=`expr ${informed} + 1`; informed=`echo ${informed}`
if [ "${informed}" -le "20" ]; then
debug "Waiting for spawned process to acquire lock (%d secs will have passed).\n" "${informed}"
sleep 1
else
debug "Giving up waiting for lock to occur. Will try to terminate current lock attempt.\n"
export HAL_LOCK=${halpid}
hal_unlock; unset HAL_LOCK
break
fi
else
debug "Exclusive lock granted to PID %d.\n" "${hallocksuccess}"
break;
fi
done
if [ "a${hallocksuccess}" != "a" ]; then
export HAL_LOCK=${halpid}
addexittrap hal_unlock
debug "Succesfully locked HAL interface \"%s\" (hal-lock itself running with PID %d).\n" "$1" "${HAL_LOCK}"
unset halpid; unset informed; unset hallocksuccess
return 0
fi
unset halpid; unset informed; unset hallocksuccess
debug "Failed to acquire exclusive lock to %s.\n" "$1"
return 1
}
# Makes sure that only one instance of $3 is contained within
# list $2 of hal udi $1.
hal_add_to_list() {
! find_binary "hal-get-property" && return 1
! find_binary "hal-set-property" && return 1
[ "$#" -ne "3" ] && return 1
halfound=0
while [ "${halfound}" -ne "1" ];
do
contents=`hal-get-property --udi "$1" --key "$2" 2> /dev/null`
halfound=0
for op in ${contents}
do
if [ "a${op}" = "a$3" ]; then
halfound=`expr ${halfound} + 1`
halfound=`echo ${halfound}`
fi
done
if [ "${halfound}" -eq "0" ]; then
debug "Will attempt to add \"%s\" inside \"%s\".\n" "$3" "$2"
hal-set-property --udi "$1" --key "$2" --strlist-post "$3" 2> /dev/null
elif [ "${halfound}" -gt "1" ]; then
debug "Will attempt to remove multiple instance of \"%s\" inside \"%s\".\n" "$3" "$2"
hal-set-property --udi "$1" --key "$2" --strlist-rem "$3" 2> /dev/null
fi
hala=$?
if [ "a${hala}" != "a0" ]; then
debug "Unable to properly modify HAL.\n"
break
fi
done
[ "${halfound}" -eq "1" ] && debug "HAL is updated.\n"
unset contents; unset op; unset hala
if [ "a${halfound}" = "a1" ]; then
unset halfound
return 0
fi
unset halfound
return 1
}
# Makes sure modem $1 capabilities are loaded on hal
hal_tty_update() {
[ "a${nohal}" != "a" ] && return 0
[ "a${nohalinform}" != "a" ] && return 0
! find_binary "hal-get-property" && return 1
! find_binary "hal-set-property" && return 1
! find_binary "hal-find-by-property" && return 1
unset halcapabilities
case "a${TTY_CAPABILITIES}" in
aGSM)
halcapabilities="GSM-07.07 GSM-07.05"
;;
a)
debug "No capabilities found. Don't know what to tell to HAL.\n"
;;
*)
debug "FIX ME: Unknown capabilities %s. Don't know what to tell to HAL.\n" "${TTY_CAPABILITIES}"
;;
esac
[ "a${halcapabilities}" = "a" ] && unset halcapabilities && return 1
debug "Capabilities of %s are: %s\n" "$1" "${halcapabilities}"
haludi=`hal-find-by-property --key "linux.device_file" --string "$1" 2> /dev/null | ${tailbin} -1`
if [ "a${haludi}" = "a" ]; then
unset haludi; unset halcapabilities
debug "No HAL device referring to %s was found.\n" "$1"
return 1
fi
debug "Found device in HAL: %s\n" "${haludi}"
verbose "Updating HAL"
hal_add_to_list "${haludi}" info.capabilities "modem"
for cap in ${halcapabilities}
do
hal_add_to_list "${haludi}" modem.command_sets "${cap}"
done
debug "HAL was updated that %s is a modem.\n" "$1"
find_binary "hal-device" && debug run_command "hal-device \"${haludi}\""
unset cap; unset halcapabilities; unset haludi
return 0
}
# If $1 node does not exist, creates it with major $2 and minor $3
dev_create_node() {
[ "a$1" = "a" -o "a$2" = "a" -o "a$3" = "a" ] && return 99
if [ ! -c "$1" ]; then
debug "Device node \"%s\" does not exist.\n" "$1"
if ! find_binary "mknod"; then
show_fmt_error "Unable to create device node \"%s\"." "$1"
return 1
fi
debug run_command "${mknodbin} \"$1\" c $2 $3"
if [ ! -c "$1" ]; then
show_fmt_error "Failed to create device node \"%s\"." "$1"
return 1
fi
debug "Made node \"%s (%d,%d)\" ourselves.\n" "$1" "$2" "$3"
return 0
else
debug "Device node \"%s\" already exists.\n" "$1"
return 0
fi
}
pin_valid() {
[ "a$1" = "a" ] && return 1
need_binary "expr"
givenpin=`echo $1`
mathpin=`${exprbin} 1${givenpin} + 1 - 1 2> /dev/null`; mathpin=`echo ${mathpin}`
if [ "a${mathpin}" = "a1${givenpin}" ]; then
if [ "1${givenpin}" -ge "10000" -a "1${givenpin}" -le "19999" ]; then
debug "Valid PIN %s.\n" "$1"
return 0
fi
fi
debug "Invalid PIN %s.\n" "$1"
return 1
}
pin_prompt() {
user_prompt "SIM_PIN" "Modem needs PIN" "Please enter PIN number, or leave empty to abort" "OK" "Cancel"
case "a${SIM_PIN}" in
a)
debug "User did not provide PIN.\n"
unset SIM_PIN
return 98
;;
*)
if ! pin_valid "${SIM_PIN}"; then
debug "PIN supplied by user was not a valid PIN number (%s).\n" "${SIM_PIN}"
unset SIM_PIN
pin_prompt
ret=$?
fi
export SIM_PIN
return 0
;;
esac
}
# Makes sure tty $1 is not busy
tty_not_busy() {
[ "a$1" = "a" ] && return 1
[ ! -c "$1" ] && return 1
if we_are_root; then
ttyusers=`${lsbin} -l /proc/*/fd/* 2> /dev/null | ${grepbin} "${1}$" | ${sedbin} -e "s/\(.*\)\/proc\/\([0-9][0-9]*\)\/fd\/\(.*\)/\2/g" | ${sortbin} | ${uniqbin} | ${wcbin} -l` ; ttyusers=`echo ${ttyusers}`
if [ "a${ttyusers}" = "a0" ]; then
unset ttyusers
debug "Device %s is not busy.\n" "$1"
[ "a$2" != "a" ] && verbose "Resuming"
return 0
fi
debug "Device %s is currently occupied by %d process(es).\n" "$1" "${users}"
ttyusers=`${lsbin} -l /proc/*/fd/* 2> /dev/null | ${grepbin} "${1}$" | ${sedbin} -e "s/\(.*\)\/proc\/\([0-9][0-9]*\)\/fd\/\(.*\)/\2/g" | ${sortbin} | ${uniqbin}` ; ttyusers=`echo ${ttyusers}`
debug "PID(s) are: %s\n" "${ttyusers}"
for ttyp in ${ttyusers}
do
debug run_command "${psbin} -p ${ttyp} -o pid,comm= | ${tailbin} -1"
ttyusers="${ttyusers} `${psbin} -p ${ttyp} -o comm= 2> /dev/null`"
done
unset ttyp
if [ "a$2" = "a" ]; then
debug "Will wait for 10 seconds in case port is freed.\n"
verbose "Waiting %s to be released by PID %s." "$1" "${ttyusers}"
ttycount=11
else
ttycount=$2
fi
ttycount=`expr ${ttycount} - 1`
if [ "a${ttycount}" = "a0" ]; then
show_fmt_error "Port %s is currently occupied by %s." "$1" "${ttyusers}"
unset ttyusers; unset ttycount;
return 1
else
debug "Wait for another %d seconds in case port %s is freed.\n" "${ttycount}" "$1"
sleep 1
if tty_not_busy $1 $ttycount; then
unset ttyusers; unset ttycount;
return 0
else
unset ttyusers; unset ttycount;
return 1
fi
fi
unset ttyusers; unset ttycount;
else
show_fmt_error "Unable to check if %s is occupied. Not root." "$1"
fi
return 1
}
at_default_commands() {
unset ttycommands
[ "a$1" = "a" ] && return 1
case "a$1" in
aPROBEGSM)
ttycommands="ATI OK 'AT+GCAP' OK 'AT+CGSN' OK"
;;
aIDENTIFY)
ttycommands="AT+CGMM OK"
;;
aSTAGE0)
if [ "a${INIT_STAGE0}" != "a" ]; then
ttycommands="${INIT_STAGE0}"
fi
;;
aSTAGE1)
if [ "a${INIT_STAGE1}" != "a" ]; then
ttycommands="${INIT_STAGE1}"
fi
;;
aPINCHECK)
if [ "a${INIT_STAGE2}" != "a" ]; then
ttycommands="${INIT_STAGE2}"
debug "Using instructed PINCHECK.\n"
else
ttycommands="'AT+CPIN?' OK"
debug "Using default PINCHECK.\n"
fi
;;
aPINSUPPLY)
if pin_valid "${2}"; then
if [ "a${INIT_STAGE3}" != "a" ]; then
ttycommands=`${printfbin} "${INIT_STAGE3}\n" "${2}"`
debug "Using instructed PINSUPPLY.\n"
else
ttycommands=`${printfbin} "'AT+CPIN=\"%s\"' OK\n" "${2}"`
debug "Using default PINSUPPLY.\n"
fi
fi
;;
aSTAGE4)
if [ "a${INIT_STAGE4}" != "a" ]; then
ttycommands="${INIT_STAGE4}"
fi
;;
aOPERATOR)
ttycommands="AT+COPS=3,2 OK 'AT+COPS?' OK"
;;
aOPERATORS)
ttycommands="AT+COPS=3,2 OK 'AT+COPS=?' TIMEOUT 120 OK"
;;
aOPERATORNAME)
ttycommands="AT+COPS=3,0 OK 'AT+COPS?' OK"
;;
aSIMOPERATORNAME)
ttycommands="'AT+CRSM=176,28486,0,0,17' OK"
;;
aSETOPERATOR)
ttycommands=`${printfbin} "'AT+COPS=1,2,\"%s\"' OK\n" "${2}"`
;;
aSTAGE5)
if [ "a${INIT_STAGE5}" != "a" ]; then
ttycommands="${INIT_STAGE5}"
fi
;;
aDETECTAPN)
ttycommands="AT+CGDCONT? OK"
;;
aINITIALIZE)
if [ "a${APN}" != "a" ]; then
apnpart=`echo "${APN}" | ${cutbin} -d: -f1`
[ "a${apnpart}" = "aCUSTOM_APN" ] && apnpart="${CUSTOM_APN}"
if [ "a${INIT_STAGE6}" != "a" ]; then
ttycommands=`${printfbin} "${INIT_STAGE6}\n" "${apnpart}"`
debug "Using instructed INITIALIZE.\n"
else
ttycommands=`${printfbin} "ATZ OK 'AT&F' OK 'ATQ0 V1 E1' OK 'AT&D2 &C1' OK AT+FCLASS=0 OK ATS0=0 OK 'AT+CGDCONT=1,\"IP\",\"%s\"' OK\n" "${apnpart}"`
debug "Using default INITIALIZE.\n"
fi
unset apnpart
fi
;;
aSTAGE7)
if [ "a${INIT_STAGE7}" != "a" ]; then
ttycommands="${INIT_STAGE7}"
fi
;;
aSTAGE8)
if [ "a${INIT_STAGE8}" != "a" ]; then
ttycommands="${INIT_STAGE8}"
fi
;;
aDIAL)
dialphone="${ISP_DIAL}"
[ "a${dialphone}" = "a" ] && dialphone="*99#"
ttycommands=`${printfbin} "ATD%s\n" "${dialphone}"`
unset dialphone
;;
esac
[ "a${ttycommands}" != "a" ] && debug "Command \"%s\" refers to AT commands: %s\n" "$1" "${ttycommands}" && return 0
debug "Unknown command \"%s\".\n" "$1"
return 1
}
# Send command $2 to tty $1
tty_send_command() {
unset LASTTTYLOG
[ "a$1" = "a" -o "a$2" = "a" ] && return 99
if [ ! -c "$1" ]; then
debug "Device node %s did not exist while trying \"%s\" command.\n" "$1" "$2"
if [ "a${informedspurious}" != "a1" ] && [ "a${usbdevice}" != "a" ] && usb_device_connected "${usbdevice}" && usb_has_storage "$1" && [ "a${killstorage}" = "a" ]; then
show_fmt_error "Spurious changes in tty %s. Consider using \"killstorage\" switch in case it improves stability." "$1"
export informedspurious=1
fi
if [ "a${informedspurious}" != "a1" ]; then
show_fmt_error "Spurious changes in tty %s. Problem may be solved by upgrading your kernel or by choosing another driver." "$1"
export informedspurious=1
fi
[ ! -c "$1" ] && debug "Waiting one second in case it appears.\n" && sleep 1
[ ! -c "$1" ] && debug "Device still missing. Aborting.\n" && return 1
debug "Device %s appeared. Will proceed sending %s commands.\n" "$1" "$2"
fi
! find_binary "chat" && return 4
need_arg "CHAT_ABORT_STRINGS"
! at_default_commands "$2" "$3" && return 1
ttycommands="\"\" '\pAT' OK ${ttycommands} '\pAT' OK"
debug "Will send %s commands to tty %s: %s\n" "$2" "$1" "${ttycommands}"
! tty_not_busy "$1" && return 1
timestamp_before=`${lsbin} --full-time -G1 $1 2> /dev/null`; timestamp_before=`echo ${timestamp_before}`
sh -c "${chatbin} -t 2 -e ${CHAT_ABORT_STRINGS} ${ttycommands} >> ${1} < ${1} 2> /tmp/sakis3g.chat.$$.log"
timestamp_after=`${lsbin} --full-time -G1 $1 2> /dev/null`; timestamp_before=`echo ${timestamp_after}`
if [ "a${timestamp_before}" != "a${timestamp_after}" ]; then
debug "Spurious changes in tty %s.\n" "$1"
if [ "a${usbdevice}" != "a" ] && usb_device_connected "${usbdevice}" && usb_has_storage "$1" && [ "a${killstorage}" = "a" ] && [ "a${informedspurious}" != "a1" ]; then
show_fmt_error "Spurious changes in tty %s. Consider using \"killstorage\" switch in case it improves stability." "$1"
export informedspurious=1
fi
if [ "a${informedspurious}" != "a1" ]; then
show_fmt_error "Spurious changes in tty %s. Problem may be solved by upgrading your kernel or by choosing another driver." "$1"
export informedspurious=1
fi
fi
unset ttycommands
if [ -f "/tmp/sakis3g.chat.$$.log" ]; then
LASTTTYLOG=`${catbin} "/tmp/sakis3g.chat.$$.log"`
debug "Got response from tty:\n%s\n" "${LASTTTYLOG}"
rm -f "/tmp/sakis3g.chat.$$.log"
return 0
else
debug "No response from tty %s.\n" "$1"
return 1
fi
}
# Finds capabilities of tty $1 and sets TTY_CAPABILITIES variable
tty_get_caps() {
unset TTY_CAPABILITIES
[ "a$1" = "a" ] && return 1
! tty_send_command "$1" "PROBEGSM" && return 1
gsmfound=`echo "${LASTTTYLOG}" | ${grepbin} "+CGSM" | wc -l`; gsmfound=`echo ${gsmfound}`
if [ "a${gsmfound}" = "a0" ]; then
debug "No GSM capabilities were advertised.\n"
gsmfound=`echo "${LASTTTYLOG}" | ${grepbin} "^\([0-9][0-9][0-9][0-9][0-9][0-9][0-9][0-9][0-9][0-9][0-9][0-9][0-9][0-9][0-9]\)$" | wc -l` ; gsmfound=`echo ${gsmfound}`
if [ "a${gsmfound}" = "a1" ]; then
debug "However, IMEI information was provided. Will consider it GSM capable.\n"
fi
fi
[ "a${gsmfound}" = "a0" -o "a${gsmfound}" = "a" ] && [ "a${NOPROBEGSM}" != "a" ] && debug "Forced by user to consider tty %s GSM capable.\n" "$1" && gsmfound=1
if [ "a${gsmfound}" != "a0" ]; then
export TTY_CAPABILITIES="GSM"
debug "Found GSM capabilities on tty %s.\n" "$1"
return 0
fi
# TODO: Implement support for non GSM devices.
debug "Device did not report GSM capabilities.\n"
if [ "a$2" != "anoretry" ]; then
debug "Will check one more time.\n"
tty_get_caps "$1" "noretry"
return $?
fi
show_fmt_error "Device did not report GSM capabilities. You can skip this by adding --noprobe command line switch.\n"
return 1
}
# Sets MODEM_VARIANT, if possible, for tty $1
tty_identify() {
unset MODEM_VARIANT
[ "a$1" = "a" ] && return 1
! tty_send_command "$1" "IDENTIFY" && return 1
MODEM_VARIANT=`echo "${LASTTTYLOG}" | ${grepbin} -v "^AT" | ${sedbin} -e "s/AT//g" | ${sedbin} -e "s/OK//g" | ${sedbin} -e "s/ERROR//g" | ${trbin} "\n" " " | ${trbin} "\t" " " | ${sedbin} -e "s/ */ /g" | ${sedbin} -e "s/^ *//g" | ${sedbin} -e "s/ *$//g"`
MODEM_VARIANT=`echo ${MODEM_VARIANT}`
if [ "a${MODEM_VARIANT}" = "a" ]; then
debug "Modem did not report a name.\n"
unset MODEM_VARIANT
else
debug "Modem on tty identified itself as: %s\n" "${MODEM_VARIANT}"
base_modem "${usbdevice}" "${MODEM_VARIANT}"
fi
return 0
}
# Checks if tty $1 needs PIN.
tty_needspin() {
unset pinrequirement
[ "a$1" = "a" ] && return 1
! tty_send_command "$1" "PINCHECK" && return 1
pinrequirement=`echo "${LASTTTYLOG}" | ${grepbin} "ERROR"`
[ "a${pinrequirement}" != "a" ] && pinrequirement="ERROR"
[ "a${pinrequirement}" = "a" ] && pinrequirement=`echo "${LASTTTYLOG}" | ${grepbin} "^.CPIN: " | ${cutbin} -d\ -f2-`
[ "a${pinrequirement}" = "a" ] && pinrequirement="ERROR"
[ "a${pinrequirement}" = "aREADY" ] && debug "Modem on %s does not need PIN.\n" "$1" && return 1
[ "a${pinrequirement}" = "aSIM PIN" ] && debug "Modem on %s needs PIN.\n" "$1" && return 0
debug "Got \"%s\" while checking modem on %s for PIN requirement.\n" "${pinrequirement}" "$1"
return 0
}
# Unlocks tty $1 from PIN.
tty_pin_unlock() {
[ "a$1" = "a" ] && return 1
! tty_needspin "$1" && unset pinrequirement && return 0
if [ "a${pinrequirement}" = "a" ]; then
show_fmt_error "Failed to get valid response from modem while checking for PIN."
unset pinrequirement
return 1
elif [ "a${pinrequirement}" != "aSIM PIN" ]; then
show_fmt_error "Modem responded \"%s\" while checking for PIN." "${pinrequirement}"
unset pinrequirement
return 1
fi
unset pinrequirement
if ! pin_valid "${SIM_PIN}"; then
unset SIM_PIN
! pin_prompt && return 98
! pin_valid "${SIM_PIN}" && return 1
fi
verbose "Sending PIN"
! tty_send_command "$1" "PINSUPPLY" "${SIM_PIN}" && return 1
debug "PIN sent to %s. Waiting 3 seconds before checking success.\n" "$1"
sleep 3
if ! tty_needspin "$1"; then
unset pinrequirement
debug "SIM is now READY.\n"
return 0
fi
unset SIM_PIN
stop_fmt_error 12 "WRONG PIN. Aborting to prevent you from locking your SIM card."
return 1
}
tty_detect_apn() {
unset MODEM_APN
[ "a${MODEM_TTY}" = "a" ] && return 1
! tty_send_command "${MODEM_TTY}" "DETECTAPN" && return 1
MODEM_APN=`echo "${LASTTTYLOG}" | ${grepbin} "^+CGDCONT" | ${sedbin} -e "s/^\(.*\)IP\",\"\(.*\)\",\"\(.*\)$/\2/g" | ${grepbin} -v "^+CGDCONT"`
export MODEM_APN
debug "APN stored in modem was: %s\n" "${MODEM_APN}"
[ "a${MODEM_APN}" = "a" ] && unset MODEM_APN && return 1
return 0
}
tty_sim_provider_name() {
unset ISPSIMNAME
[ "a$1" = "a" ] && return 1
if tty_send_command "$1" "SIMOPERATORNAME"; then
ISPSIMNAME=`echo "${LASTTTYLOG}" | ${grepbin} "^+CRSM:\( *\)144," | ${sedbin} -e "s/^.CRSM:\( *\)144,\(.*\),\"\(.*\)\"\(.*\)$/ISPSIMNAME=\3/g" | ${grepbin} "^ISPSIMNAME=" | ${cutbin} -d= -f2-`
[ "a${ISPSIMNAME}" = "a" ] && unset ISPSIMNAME && return 1
ISPSIMNAME=`${printfbin} "\`echo "${ISPSIMNAME}" | ${sedbin} -e "s/\([0-9A-Fa-f][0-9A-Fa-f]\)/\\\\\\\\\\x\1/g" | ${sedbin} -e "s/\\\\\\\\\\xFF//g" | ${sedbin} -e "s/\\\\\\\\\\x01//g" | ${sedbin} -e "s/\\\\\\\\\\x02//g"\`\n"`
ISPSIMNAME=`echo ${ISPSIMNAME}`
[ "a${ISPSIMNAME}" = "a" ] && unset ISPSIMNAME && return 1
debug "SIM contains \"service provider\" name: %s\n" "${ISPSIMNAME}"
export ISPSIMNAME
return 0
fi
return 1
}
tty_select_network() {
unset FORCE_ISP
verbose "Scanning networks"
! tty_send_command "$1" "OPERATORS" && return 1
networks=`echo "${LASTTTYLOG}" | ${grepbin} "^+COPS:" | ${cutbin} -d: -f2- -s | ${sedbin} -e "s/(/\\\n(/g" | ${sedbin} -e "s/)/)\\\n/g" | ${grepbin} "^([1-3],\"\(.*\)\",\"\(.*\)\",\"\([0-9][0-9]*\)\",0)$" | ${sedbin} -e "s/^(1,/(Allowed,/g" | ${sedbin} -e "s/^(2,/(Current,/g" | ${sedbin} -e "s/^(3,/(Forbidden,/g" | ${sedbin} -e "s/^(\(.*\),\"\(.*\)\",\"\(.*\)\",\"\([0-9][0-9]*\)\",0)$/\"\4\" \"\2 (\1\)\" /g"`
eval user_select \"FORCE_ISP\" \"Please select a network\" \"Select network for modem to register.\" \"Select\" \"Cancel\" ${networks}
# in
case "$?" in
0)
unset FORCE_ISP; unset networks
return 98
;;
98)
unset FORCE_ISP; unset networks
return 98
;;
99)
unset FORCE_ISP; unset networks
return 99
;;
*)
case "a${FORCE_ISP}" in
a)
unset FORCE_ISP; unset networks
return 98
;;
*)
debug "User selected %s.\n" "${FORCE_ISP}"
return 0
;;
esac
;;
esac
return 1
}
tty_registered_network() {
unset ISPID; unset ISPNAME; unset ISPTEXT
[ "a$1" = "a" ] && return 1
! tty_send_command "$1" "OPERATOR" && return 1
ISPID=`echo "${LASTTTYLOG}" | ${grepbin} "^+COPS:" | ${cutbin} -d\" -f2`; ISPID=`echo ${ISPID}`
if [ "a${ISPID}" = "a+COPS: 0" -o "a${ISPID}" = "a" ]; then
debug "Modem not registered to a network yet.\n"
unset ISPID
return 1
fi
debug "Modem registered to network ID \"%s\".\n" "${ISPID}"
if [ -n "${FORCE_ISP}" ]; then
if [ "a${ISPID}" != "a${FORCE_ISP}" ]; then
debug "FORCE_ISP variable instructs to use \"%s\" instead.\n" "${FORCE_ISP}"
fi
debug "Will attempt to manually set %s and prevent roaming.\n" "${FORCE_ISP}"
! tty_send_command "$1" "SETOPERATOR" "${FORCE_ISP}"
if [ "a$2" != "aFORCE_ISP" ]; then
tty_registered_network "$1" "FORCE_ISP"
else
if [ "a${ISPID}" != "a" ]; then
show_fmt_error "Modem refused to register operator \"%s\" (currently registered to \"%s\").\n" "${FORCE_ISP}" "${ISPID}"
else
show_fmt_error "Modem refused to register operator \"%s\".\n" "${FORCE_ISP}"
fi
unset ISPID
return 1
fi
unset ISPID
return $?
fi
export ISPID
if tty_send_command "$1" "OPERATORNAME"; then
ISPNAME=`echo "${LASTTTYLOG}" | ${grepbin} "^+COPS:" | ${sedbin} -e "s/^.COPS: 0,0,\"\(.*\)\"\(.*\)$/ISPNAME=\1/g" | ${grepbin} "^ISPNAME=" | ${cutbin} -d= -f2-`
if tty_sim_provider_name "$1" && [ "a${ISPSIMNAME}" != "a" -a "a${ISPSIMNAME}" != "a${ISPNAME}" ]; then
debug "SIM card instructs to use \"%s\" as service provider name, instead of \"%s\".\n" "${ISPSIMNAME}" "${ISPNAME}"
ISPNAME="${ISPSIMNAME}"
fi
# Some modems return numeric ID, even if instructed to display name.
[ "a${ISPNAME}" = "a${ISPID}" ] && unset ISPNAME
# Some SIMs incorrectly confuse modem to display FFs as service provider name.
[ "a`echo ${ISPNAME} | ${cutbin} -b1-8`" = "aFFFFFFFF" ] && unset ISPNAME
# Huawei E160 does not correctly report operator name.
# This is not true. Was a SIM issue. This is not true.
#[ "a${MODEM_VARIANT}" = "aE160" ] && unset ISPNAME
export ISPNAME
[ "a${ISPNAME}" = "a" ] && net_info "${ISPID}"
[ "a${ISPNAME}" = "a" ] && unset ISPNAME
fi
export ISPTEXT="${ISPID}"
[ "a${ISPNAME}" != "a" ] && export ISPTEXT="${ISPNAME}"
return 0
}
tty_register_network() {
[ "a$1" = "a" ] && return 1
wat=0
if [ -n "${FORCE_ISP}" ]; then
debug "FORCE_ISP variable instructs to enter network \"%s\".\n" "${FORCE_ISP}"
debug "Will attempt to manually set %s and prevent roaming.\n" "${FORCE_ISP}"
! tty_send_command "$1" "SETOPERATOR" "${FORCE_ISP}"
fi
while ! tty_registered_network $1;
do
if [ "${wat}" -gt "20" ]; then
debug "Giving up after %d seconds have passed.\n" "${wat}"
break
else
wat=`expr ${wat} + 4`
wat=`echo ${wat}`
fi
debug "Waiting modem to register network (%d seconds).\n" "${wat}"
verbose "Registering network"
sleep 4
done
unset wat
if [ "a${ISPID}" = "a" ]; then
show_fmt_error "Modem unable to register a network."
unset ISPID
if user_confirm "scan" "Scan for network" "Modem was unable to register a network. Would you like to manually select a network?" "Yes" "No" "reset"; then
if tty_select_network "$@"; then
tty_register_network "$@"
return $?
fi
fi
return 13
else
debug "Modem on %s has registered %s.\n" "$1" "${ISPID}"
return 0
fi
}
# Makes sure tty $1 is ready for connection to be established.
tty_prepare() {
check_com_software
ret=$?; [ "${ret}" -ne "0" ] && return ${ret}
[ "a$1" = "a" ] && return 1
verbose "Preparing modem"
tty_send_command "$1" "STAGE0"
! tty_get_caps "$@" && return 1
! tty_identify "$@" && return 1
tty_send_command "$1" "STAGE1"
! tty_pin_unlock "$@" && return 1
tty_send_command "$1" "STAGE4"
tty_register_network "$@"; ret=$?; [ "${ret}" -ne "0" ] && return ${ret}
tty_send_command "$1" "STAGE5"
hal_tty_update "$@"
debug "Modem on device node %s is now ready for connection.\n" "$1"
return 0
}
# Attempts to get connected USB devices, exiting if it fails.
usb_connected_devices() {
unset usb_devices
need_binary "sort"; need_binary "uniq"; need_binary "sed"
if [ -r "/proc/bus/usb/devices" ]; then
debug "Fetching connected USB devices by using \"%s\".\n" "/proc/bus/usb/devices"
usb_devices=`safe_cat "/proc/bus/usb/devices" | ${grepbin} -A 4 "^P:" | ${sedbin} -e "s/^\(.*\)Ven\(.*\)=\(....\) Pro\(.*\)=\(....\) \(.*\)$/\3:\5:/g" | ${sedbin} -e "s/^S:\(.*\)Pro\(.*\)=\(.*\)$/\3/g" | ${sedbin} -e "s/^.:\(.*\)$//g" | ${grepbin} -v "^$"`
usb_devices=`echo ${usb_devices} | ${sedbin} -e "s/: */:/g" | ${sedbin} -e "s/ -- /\\\n/g" | ${sortbin} | ${uniqbin} | ${grepbin} -v "HCI Host Controller"`
elif [ -d "/sys/bus/usb/devices" ]; then
debug "Fetching connected USB devices by using \"%s\".\n" "/sys/bus/usb/devices"
usb_devices=`cd /sys/bus/usb/devices/; ${grepbin} . */idProduct */idVendor */product */uevent | ${sortbin} | ${sedbin} -e "s/idProduct:\(.*\)$/idProduct:\1:/g" | ${sedbin} -e "s/idVendor:\(.*\)$/idVendor:\1:/g" | ${grepbin} -A 2 "idProduct" | ${sedbin} -e "s/^\(.*\):\(..*\):*$/\2/g"`
usb_devices=`echo ${usb_devices} | ${sedbin} -e "s/: */:/g" | ${sedbin} -e "s/ -- /\\\n/g" | ${sortbin} | ${uniqbin} | ${sedbin} -e "s/^\(....\):\(....\):/\2:\1:/g" | ${sortbin} | ${uniqbin} | ${grepbin} -v "HCI Host Controller"`
elif find_binary "lsusb"; then
debug "Fetching connected USB devices by using \"%s\".\n" "${lsusbbin}"
usb_devices=`safe_lsusb | ${sedbin} -e "s/\(.*\)ID \(....\):\(....\) \(.*\)$/\2:\3:\4/g" | ${sortbin} | ${uniqbin} | ${grepbin} -v "root hub"`
else
stop_fmt_error 7 "Unable to discover connected USB devices. Script will now abort."
fi
if [ "a${TIMEOUTOCCURED}" != "a" ]; then
show_fmt_error "Seems like an electrical/USB bus error occured. You may need to replug your modem for it to properly work.\n"
unset TIMEOUTOCCURED
fi
debug "Connected USB devices are:\n%s\n" "${usb_devices}"
return 0
}
# Helper method. Prints equivalent of usb_devices only for those devices in $1
usb_device_list() {
for condevice in $@
do
echo "${usb_devices}" | ${grepbin} "^${condevice}:"
done
}
# Does scoring things to determine if which usb device looks like a sure candidate for being a modem.
# On success, returns 0 and sets usb_modems.
# On failure, returns 1
voodoo_connected_modems() {
unset usb_modems
need_binary "uname"
debug "Voodoo mode employed to discover a possible modem.\n"
debug "Attempting to enumerate interfaces.\n"
uevents=`cd /sys/bus/usb/devices; ${grepbin} . [0-9]*/uevent 2> /dev/null`
interfaces=`echo "${uevents}" | ${cutbin} -d/ -f1 -s | ${grepbin} ":" | ${sortbin} | ${uniqbin}` ; interfaces=`echo ${interfaces}`
debug "uevent contents are:\n%s\n" "${uevents}"
debug "Interfaces are:\n%s\n" "${interfaces}"
unset orphaninterfaces; unset storageinterfaces; unset communicationdevices; unset suspectdevices; unset serialinterfaces; unset interruptinterfaces
for intstr in ${interfaces}
do
intclass=`echo "${uevents}" | ${grepbin} "^${intstr}\/" | ${grepbin} "uevent:INTERFACE=" | ${cutbin} -d= -f2 -s | ${cutbin} -d/ -f1`
[ "a${intclass}" = "a9" ] && continue
intdriver=`echo "${uevents}" | ${grepbin} "^${intstr}\/" | ${grepbin} "uevent:DRIVER=" | ${cutbin} -d= -f2 -s | ${sedbin} -e "s/-/_/g"`
intserial=0; [ "a${intdriver}" != "a" ] && intserial=`usb_serial_drivers ${intdriver} 2> /dev/null | ${wcbin} -w`; intserial=`echo ${intserial}`
intpoint=`cd /sys/bus/usb/devices; ${grepbin} . ${intstr}/ep_*/type 2> /dev/null | ${grepbin} -i "interrupt$" | ${wcbin} -l`; intpoint=`echo ${intpoint}`
intdevice=`echo "${intstr}" | ${cutbin} -d: -f1 -s`
intvendor=`${catbin} /sys/bus/usb/devices/${intdevice}/idVendor 2> /dev/null`
intmodemmaker=`${grepbin} -i "usb:v${intvendor}" /lib/modules/\`${unamebin} -r\`/modules.alias 2> /dev/null | ${cutbin} -d\ -f3 -s | ${sortbin} | ${uniqbin}`
intmodemmaker=`usb_serial_drivers ${intmodemmaker} 2> /dev/null`
intbrothers=`echo "${interfaces}" | ${trbin} " " "\n" | ${sedbin} -e "s/^\( *\)//g" | ${grepbin} "^${intdevice}:" | ${wcbin} -l`; intbrothers=`echo ${intbrothers}`
if [ "a${intdriver}" = "a" ]; then
orphaninterfaces="${orphaninterfaces} ${intstr} ${intstr} ${intstr}"
debug "Added interface %s to orphan interfaces.\n" "${intstr}"
fi
if [ "a${intpoint}" = "a1" ]; then
interruptinterfaces="${interruptinterfaces} ${intstr} ${intstr} ${intstr}"
debug "Added interface %s to interrupt interfaces.\n" "${intstr}"
fi
if [ "a${intdriver}" = "ausb-storage" -o "a${intdriver}" = "ausb_storage" -o "a${intclass}" = "a8" ]; then
storageinterfaces="${storageinterfaces} ${intstr} ${intstr} ${intstr} ${intstr}"
debug "Added interface %s to storage interfaces.\n" "${intstr}"
if [ "a${intbrothers}" = "a1" ]; then
storageinterfaces="${storageinterfaces} ${intstr} ${intstr}"
debug "+2 for being unique interface of device %s.\n" "${intdevice}"
fi
if [ "a${intbrothers}" = "a1" ] && [ "a${intmodemmaker}" != "a" ]; then
storageinterfaces="${storageinterfaces} ${intstr} ${intstr} ${intstr}"
debug "+3 for vendor %s being a modem maker.\n" "${intvendor}"
fi
fi
if [ "a${intclass}" = "a2" ]; then
communicationdevices="${communicationdevices} ${intstr} ${intstr}"
debug "Added interface %s to communication interfaces.\n" "${intstr}"
fi
if [ "a${intclass}" = "a255" -o "a${intclass}" = "a224" ]; then
suspectdevices="${suspectdevices} ${intstr}"
debug "Added interface %s to suspect interfaces.\n" "${intstr}"
fi
if [ "a${intserial}" = "a1" ]; then
serialinterfaces="${serialinterfaces} ${intstr} ${intstr} ${intstr} ${intstr} ${intstr}"
debug "Added interface %s to serial interfaces.\n" "${intstr}"
fi
done
unset interfaces; unset uevents
unset intstr; unset intclass; unset intdriver; unset intserial; unset intpoint; unset intdevice; unset intvendor; unset intmodemmaker; unset intbrothers
devicescore=`echo ${serialinterfaces} ${suspectdevices} ${communicationdevices} ${storageinterfaces} ${orphaninterfaces} ${interruptinterfaces} | ${trbin} " " "\n" | ${sedbin} -e "s/ //g" | ${grepbin} -v "^$" | ${cutbin} -d: -f1 -s | ${sortbin} | ${uniqbin} -c | ${sedbin} -e "s/^\( *\)//g" | ${sedbin} -e "s/\( *\)/ /g" | ${sedbin} -e "s/^\([0-9]\) /0\1 /g" | ${sedbin} -e "s/^\([0-9][0-9]\) /0\1 /g" | ${sedbin} -e "s/^\([0-9][0-9][0-9]\) /0\1 /g" | ${sortbin} -r`
interfacescore=`echo ${serialinterfaces} ${suspectdevices} ${communicationdevices} ${storageinterfaces} ${orphaninterfaces} ${interruptinterfaces} | ${trbin} " " "\n" | ${sedbin} -e "s/ //g" | ${grepbin} -v "^$" | ${sortbin} | ${uniqbin} -c | ${sedbin} -e "s/^\( *\)//g" | ${sedbin} -e "s/\( *\)/ /g" | ${sedbin} -e "s/^\([0-9]\) /0\1 /g" | ${sedbin} -e "s/^\([0-9][0-9]\) /0\1 /g" | ${sedbin} -e "s/^\([0-9][0-9][0-9]\) /0\1 /g" | ${sortbin} -r`
unset serialinterfaces; unset suspectdevices; unset communicationdevices; unset storageinterfaces; unset orphaninterfaces; unset interruptinterfaces;
debug "Device score is:\n%s\n" "${devicescore}"
debug "Interface score is:\n%s\n" "${interfacescore}"
besttwo=`echo "${interfacescore}" | ${headbin} -2 | ${cutbin} -d\ -f2 -s | ${cutbin} -d: -f1 -s | ${uniqbin}`
besttwocount=`echo "${besttwo}" | ${wcbin} -w`; besttwocount=`echo ${besttwocount}`
if [ "a${besttwocount}" != "a" ] && [ "${besttwocount}" -eq "1" ]; then
intvendor=`${catbin} /sys/bus/usb/devices/${besttwo}/idVendor 2> /dev/null`
intproduct=`${catbin} /sys/bus/usb/devices/${besttwo}/idProduct 2> /dev/null`
if usb_device_connected "${intvendor}:${intproduct}"; then
export usb_modems="${intvendor}:${intproduct}"
unset intvendor; unset intproduct
debug "Voodoo operations determined device %s (%s) is a modem.\n" "${usb_modems}" "${besttwo}"
unset besttwocount; unset besttwo; unset interfacescore; unset devicescore
return 0
fi
unset intvendor; unset intproduct
fi
debug "No device is the absolute winner. Will check for dominating score.\n"
firstscore=`echo "${interfacescore}" | ${headbin} -1 | ${cutbin} -d\ -f1 -s | ${sedbin} -e "s/^\(0*\)//g" | ${sedbin} -e "s/^$/0/g"`
firstscore=`${printfbin} "%d\n" "${firstscore}" 2> /dev/null`; [ "a${firstscore}" = "a" ] && firstscore=0
secondscore=`echo "${interfacescore}" | ${headbin} -2 | ${tailbin} -1 | ${cutbin} -d\ -f1 -s | ${sedbin} -e "s/^\(0*\)//g" | ${sedbin} -e "s/^$/0/g"`
secondscore=`${printfbin} "%d\n" "${secondscore}" 2> /dev/null`; [ "a${secondscore}" = "a" ] && secondscore=0
if [ "a${firstscore}" != "a" -a "a${secondscore}" != "a" ] && [ "a${firstscore}" != "a${secondscore}" ] && [ "${firstscore}" -gt "0" -a "${firstscore}" -gt "${secondscore}" ]; then
secondscore=`expr ${secondscore} + ${secondscore}`; secondscore=`echo ${secondscore}`
if [ "${firstscore}" -gt "${secondscore}" ]; then
besttwo=`echo "${interfacescore}" | ${headbin} -1 | ${cutbin} -d\ -f2 -s | ${cutbin} -d: -f1 -s | ${uniqbin}`
intvendor=`${catbin} /sys/bus/usb/devices/${besttwo}/idVendor 2> /dev/null`
intproduct=`${catbin} /sys/bus/usb/devices/${besttwo}/idProduct 2> /dev/null`
if usb_device_connected "${intvendor}:${intproduct}"; then
export usb_modems="${intvendor}:${intproduct}"
unset intvendor; unset intproduct
debug "Device %s (%s) out-numbered second candidate and will be considered a modem.\n" "${usb_modems}" "${besttwo}"
unset firstscore; unset secondscore
unset besttwocount; unset besttwo; unset interfacescore; unset devicescore
return 0
fi
fi
fi
unset firstscore; unset secondscore
debug "No device dominates the other in score. Cannot decide.\n"
unset besttwo; unset besttwocount; unset interfacescore; unset devicescore
return 1
}
# Attempts to get connected modems, and sets usb_modems and usb_modem_devices variables
usb_connected_modems() {
unset usb_modems; unset usb_modem_devices
[ "a${KNOWN_devices}" = "a" ] && ! modeswitch_load && return 1
! usb_connected_devices && return 1
connectedevices=`echo "${usb_devices}" | ${cutbin} -d: -f1,2`
for condevice in ${connectedevices}
do
devfound=`${printfbin} "%s\n%s\n%s\n" "${KNOWN_devices}" "${MODEM}" "${USBMODEM}" | ${grepbin} "${condevice}"`
[ "a${devfound}" != "a" ] && usb_modems="${usb_modems} ${condevice}"
unset devfound
done
unset condevice; unset connectedevices
usb_modems=`echo ${usb_modems}`
export usb_modems
if [ "a${usb_modems}" = "a" ] && unset usb_modems; then
debug "No plugged modems found.\n"
! voodoo_mode && return 1
! voodoo_connected_modems && return 1
fi
usb_modem_devices=`usb_device_list ${usb_modems}`
export usb_modem_devices
debug "Connected USB modems are:\n%s\n" "${usb_modem_devices}"
return 0
}
# Returns true if device $1 is currently connected
usb_device_connected() {
[ "a$1" = "a" ] && return 99
usb_connected_devices
usbconnected=`echo "${usb_devices}" | ${cutbin} -d: -f1,2 | ${grepbin} "^$1"`
[ "a${usbconnected}" = "a$1" ] && unset usbconnected && return 0
unset usbconnected
debug "Device \"%s\" is not connected.\n" "$1"
return 1
}
# Parses /proc/bus/usb/devices and only returns block referring to $1.
usb_device_block() {
unset usbdeviceblock
[ "a$1" = "a" ] && return 1
if [ -r "/proc/bus/usb/devices" ]; then
usbvend=`echo "$1" | ${cutbin} -d: -f1`
usbprod=`echo "$1" | ${cutbin} -d: -f2`
usbdevcat=`safe_cat /proc/bus/usb/devices`
usblines=`${printfbin} "%s\n\n" "${usbdevcat}" | ${grepbin} -A 60 "=${usbvend} \(.*\)=${usbprod}" | ${grepbin} -n "^$" | ${headbin} -1 | ${sedbin} -e "s/:$//g"`; usblines=`echo ${usblines}`
[ "a${usblines}" = "a" ] && usblines=0
[ "${usblines}" -gt "0" ] && usbdeviceblock=`echo "${usbdevcat}" | ${grepbin} -A 60 "Vendor=${usbvend} ProdID=${usbprod}" | ${headbin} -${usblines}`
unset usblines; unset usbvend; unset usbprod; unset usbdevcat
echo "${usbdeviceblock}" | ${grepbin} -v "^$"
return 0
fi
return 1
}
# Filters arguments and returns back only those that usb serial drivers
usb_serial_drivers() {
[ "a${kernel}" = "a" ] && find_binary "uname" && kernel=`${unamebin} -r`
[ "a${kernel}" = "a" ] && return 1
export kernel
for driver in $@
do
[ -f "/lib/modules/${kernel}/kernel/drivers/usb/serial/${driver}.ko" ] && echo "${driver}" && continue
[ "a${driver}" = "acdc_acm" ] && [ -f "/lib/modules/${kernel}/kernel/drivers/usb/class/cdc-acm.ko" ] && echo "${driver}"
done
}
# Attempts to find appropriate driver for USB device $1, and sets USBDRIVER
usb_serial_detect_driver() {
unset USBDRIVER
[ "a$1" = "a" ] && return 99
serialvend=`echo "$1" | ${cutbin} -d: -f1`
serialprod=`echo "$1" | ${cutbin} -d: -f2`
if ! find_binary "uname"; then
debug "Failed to locate running kernel's modules. Uname missing.\n"
else
kernel=`${unamebin} -r`
if [ -f "/lib/modules/${kernel}/modules.alias" ]; then
drivercandidates=`${grepbin} -i "usb:v${serialvend}p${serialprod}" "/lib/modules/${kernel}/modules.alias" | ${cutbin} -d\ -f3 | ${sortbin} | ${uniqbin}`;
drivercandidates=`usb_serial_drivers ${drivercandidates}`
if [ "a${drivercandidates}" = "a" ]; then
debug "No perfect match found for device \"%s\".\n" "$1"
debug "Will seek if exists a driver for other devices from vendor \"%s\".\n" "${serialvend}"
drivercandidates=`${grepbin} -i "usb:v${serialvend}p" "/lib/modules/${kernel}/modules.alias" | ${cutbin} -d\ -f3 | ${sortbin} | ${uniqbin}`;
drivercandidates=`usb_serial_drivers ${drivercandidates}`
if [ "a${drivercandidates}" = "a" ]; then
debug "No candidates were found.\n"
else
debug "Found driver(s) for other devices of same vendor: %s\n" "${drivercandidates}"
fi
drivercandidates=`echo "${drivercandidates}" | ${trbin} " " "\n" | ${sedbin} -e "s/ //g" | ${sortbin} | ${uniqbin}`
else
debug "Found driver(s) available for \"%s\": %s\n" "$1" "${drivercandidates}"
fi
fi
unset kernel
fi
if base_drivers "${serialvend}" "${serialprod}"; then
drivercandidates=`echo ${drivercandidates} ${basedrivercandidates}`
unset basedrivercandidates
fi
drivercandidates=`echo ${drivercandidates} | ${trbin} " " "\n" | ${sedbin} -e "s/ //g" | ${sortbin} | ${uniqbin}`
candidatenum=`echo ${drivercandidates} | ${wcbin} -w`; candidatenum=`echo ${candidatenum}`
if [ "a${candidatenum}" = "a1" ]; then
USBDRIVER=`echo ${drivercandidates}`
export USBDRIVER
debug "Only one candidate, will use it unconditionally: %s\n" "${USBDRIVER}"
unset candidatenum; unset drivercandidates; unset serialvend; unset serialprod
return 0
elif [ "a${candidatenum}" = "a0" ]; then
drivercandidates="option"
debug "No driver found, will propose \"%s\" driver.\n" "${drivercandidates}"
if usb_usable_interfaces "$1" && [ "a${usableinterfacecount}" != "a" ] && [ "${usableinterfacecount}" -gt "1" ]; then
debug "Device has %d usable interfaces. Will propose cdc_acm also.\n"
drivercandidates="cdc_acm option"
fi
fi
debug "Driver candidates are: %s\n" "${drivercandidates}"
if voodoo_mode; then
for safetoprobe in cdc_acm
do
debug "Will try safe to probe driver %s.\n" "${safetoprobe}"
if module_bind "${safetoprobe}" "$1"; then
debug "Appropriate driver %s determined.\n" "${safetoprobe}"
export USBDRIVER="${safetoprobe}"
unset candidatenum; unset drivercandidates; unset serialvend; unset serialprod
return 0
else
debug "Determined %s is not a valid candidate. Will make sure is not within list of candidates either.\n" "${safetoprobe}"
drivercandidates=`echo ${drivercandidates} | ${sedbin} -e "s/\( *\)${safetoprobe}\( *\)/ /g" | ${sedbin} -e "s/ / /g"`
drivercandidates=`echo ${drivercandidates}`
debug "Driver candidates are: %s\n" "${drivercandidates}"
fi
done
fi
drivers=`echo ${drivercandidates} | ${trbin} " " "\n" | ${sedbin} -e "s/^\( *\)\(.*\)\( *\)$/\2/g" | ${sortbin} | ${uniqbin} | ${sedbin} -e "s/^\(.*\)$/\"\1\" \"\1 kernel module\"/g"`
eval user_select \"USBDRIVER\" \"Please select appropriate driver\" \"Select kernel module that should be used.\" \"Select\" \"Cancel\" ${drivers} \"OTHER\" \"Other driver...\"
case "$?" in
0)
unset drivers
unset candidatenum; unset drivercandidates; unset serialvend; unset serialprod
return 98
;;
98)
unset drivers
unset candidatenum; unset drivercandidates; unset serialvend; unset serialprod
return 98
;;
99)
unset drivers
unset candidatenum; unset drivercandidates; unset serialvend; unset serialprod
return 99
;;
*)
case "a${USBDRIVER}" in
aOTHER)
unset USBDRIVER
user_prompt "USBDRIVER" "Please enter name of driver" "Enter name of appropriate kernel module that should be used, or leave empty to abort" "OK" "Cancel"
if [ "a${USBDRIVER}" != "a" ]; then
unset drivers
unset candidatenum; unset drivercandidates; unset serialvend; unset serialprod
return 0
fi
usb_serial_detect_driver "$@"
return $?
;;
*)
unset drivers
unset candidatenum; unset drivercandidates; unset serialvend; unset serialprod
return 0
;;
esac
;;
esac
return 99
}
# Returns driver attached to interface $2 of device $1
usb_loaded_driver() {
[ "a$1" = "a" ] && return 99
if [ -r "/proc/bus/usb/devices" ]; then
usbblock=`usb_device_block "$1"`; [ "a${usbblock}" = "a" ] && return 7
if [ "a$2" != "a" ]; then
usbdriver=`echo "${usbblock}" | ${grepbin} "^I:\(.*\)If.=\( *\)$2 " | ${sedbin} -e "s/^I:\(.*\)If.=\( *\)$2 \(.*\) Driver=\(.*\)/\4/g"`
else
usbdriver=`echo "${usbblock}" | ${grepbin} "^I:\(.*\)If.=" | ${sedbin} -e "s/^I:\(.*\)If.=\( *\) \(.*\) Driver=\(.*\)/\4/g"`
fi
case "a${usbdriver}" in
a)
usbdriver="FAIL"
echo ${usbdriver}
unset usbdriver
return 1
;;
"a(none)")
usbdriver="NONE"
echo ${usbdriver}
unset usbdriver
return 0
;;
*)
usbdriver=`echo ${usbdriver} | ${trbin} "-" "_"`
usbdriver=`echo ${usbdriver} | ${sedbin} -e "s/usbserial_generic/usbserial/g"`
echo ${usbdriver}
unset usbdriver
return 1
esac
elif usb_sysfsdir "$1"; then
if [ "a$2" != "a" ]; then
usbdriver=`${grepbin} . ${sysfsloc}/*-*\:*.$2/uevent | ${grepbin} -i DRIVER= | ${cutbin} -d= -f2 -s`
else
usbdriver=`${grepbin} . ${sysfsloc}/*-*\:*.*/uevent | ${grepbin} -i DRIVER= | ${cutbin} -d= -f2 -s`; usbdriver=`echo ${usbdriver}`
fi
usbdriver=`echo ${usbdriver} | ${trbin} "-" "_"`
usbdriver=`echo ${usbdriver} | ${sedbin} -e "s/usbserial_generic/usbserial/g"`
[ "a${usbdriver}" = "a" ] && usbdriver="NONE"
echo ${usbdriver}
unset usbdriver
return 0
else
debug "Unable to determine driver attached to interface %s of device %s.\n" "$2" "$1"
usbdriver="FAIL"
echo ${usbdriver}
unset usbdriver
return 1
fi
}
usb_usable_interfaces() {
unset usableinterfaces; usableinterfacecount=0
[ "a$1" = "a" ] && return 99
if [ -r "/proc/bus/usb/devices" ]; then
debug "Using information of %s to determine usable interfaces.\n" "/proc/bus/usb/devices"
usbblock=`usb_device_block "$1"`
usbinter=`echo "${usbblock}" | ${grepbin} "^I:" | ${wcbin} -l`; usbinter=`echo ${usbinter}`
debug "USB Device %s provides %d interface(s).\n" "$1" "${usbinter}"
usbinter=`echo "${usbblock}" | ${grepbin} "(I)\(.*\)Atr=...Int\.. " | ${wcbin} -l`; usbinter=`echo ${usbinter}`
debug "USB Device %s provides %d interruptable endpoint(s).\n" "$1" "${usbinter}"
if [ "a${usbinter}" = "a0" -o "a${usbinter}" = "a" ]; then
debug "USB device block output was:\n%s\n" "${usbblock}"
debug "No modem lines on USB device \"%s\". Device may need switching.\n" "$1"
else
usbinter=`echo "${usbblock}" | ${grepbin} "(I)\(.*\)Atr=...Int\.. " | ${sedbin} -e "s/^E:\(.*\)Ad=\(.*\)(I)\(.*\)Atr=...Int\..\(.*\)$/\2/g"`; usbinter=`echo ${usbinter}`
debug "Interruptable endpoint(s) are: %s\n" "${usbinter}"
unset USB_INTERFACE
for endpoint in ${usbinter}
do
localinter=`echo "${usbblock}" | ${grepbin} -B 10 "^E\(.*\)Ad=${endpoint}(I)" | ${grepbin} "^I" | ${tailbin} -1 | ${sedbin} -e "s/^\(.*\)If.=\( *\)\([0-9][0-9]*\) \(.*\)$/\3/g"`
if [ "a${localinter}" != "a" ]; then
localinter=`${printfbin} "%d\n" ${localinter} 2> /dev/null`
if [ "a${localinter}" != "a" ]; then
debug "Added interface %s, containing endpoint %s.\n" "${localinter}" "${endpoint}"
usableinterfaces="${usableinterfaces} ${localinter}"
fi
fi
unset localinter
done
unset localinter; unset endpoint
fi
unset usbinter; unset usbblock
usableinterfaces=`echo ${usableinterfaces}`
export usableinterfaces
debug "Interfaces collected from %s are: %s\n" "/proc/bus/usb/devices" "${usableinterfaces}"
fi
if find_binary "lsusb"; then
debug "Using information of %s to determine usable interfaces.\n" "lsusb"
usbvend=`echo "$1" | ${cutbin} -d: -f1`; usbprod=`echo "$1" | ${cutbin} -d: -f2`
usbblock=`safe_lsusb -v -d ${usbvend}:${usbprod}`
usbinter=`echo "${usbblock}" | ${sedbin} -e "s/ */ /g" | ${grepbin} -i "transfer type interrupt" | ${wcbin} -l`; usbinter=`echo ${usbinter}`
debug "USB Device %s provides %d interruptable endpoint(s).\n" "$1" "${usbinter}"
if [ "a${usbinter}" = "a0" -o "a${usbinter}" = "a" ]; then
debug "lsusb output was:\n%s\n" "${usbblock}"
debug "No modem lines on USB device \"%s\". Device may need switching.\n" "$1"
unset usbinter
else
# Enter character after "interrupt" word on following line IS NOT a mistake
usbinter=`echo "${usbblock}" | ${sedbin} -e "s/ */ /g" | ${grepbin} -F -i "transfer type interrupt
binterfacenumber" | ${grepbin} -B 1 -i interrupt | ${grepbin} -i "binterfacenumber" | ${cutbin} -d\ -f3 -s`; usbinter=`echo ${usbinter}`
fi
debug "Interfaces collected from %s are: %s\n" "lsusb" "${usbinter}"
[ "a${usbinter}" != "a" ] && usableinterfaces=`echo "${usableinterfaces} ${usbinter}"`
export usableinterfaces
unset usbvend; unset usbprod; unset usbblock; unset usbinter;
elif [ ! -r "/proc/bus/usb/devices" ]; then
debug "Failed to read USB information.\n"
show_fmt_error "Both \"%s\" and \"%s\" are missing." "lsusb" "/proc/bus/usb/devices"
return 7
fi
if [ "a${TIMEOUTOCCURED}" != "a" ]; then
show_fmt_error "Seems like an electrical/USB bus error occured. You may need to replug your modem for it to properly work.\n"
unset TIMEOUTOCCURED
fi
usableinterfaces=`echo ${usableinterfaces} | ${trbin} " " "\n" | ${sedbin} -e "s/ //g" | ${sortbin} | ${uniqbin}`
usableinterfaces=`echo ${usableinterfaces}`
usableinterfacecount=`echo ${usableinterfaces} | ${wcbin} -w`; usableinterfacecount=`echo ${usableinterfacecount}`
return 0
}
usb_get_interface() {
unset USB_INTERFACE
[ "a$1" = "a" ] && return 99
usb_usable_interfaces "$1"
ret=$?; [ "a${ret}" != "a0" ] && return ${ret}
USB_INTERFACE=`echo ${usableinterfaces}`
export USB_INTERFACE
if [ "a${USB_INTERFACE}" = "a" -o "a${usableinterfacecount}" = "a0" ]; then
debug "Failed to locate any usable interface for device %s.\n" "$1"
unset USB_INTERFACE
return 8
fi
debug "Collected %d interface(s): %s\n" "${usableinterfacecount}" "${USB_INTERFACE}"
if [ "a${usableinterfacecount}" = "a1" ]; then
debug "Only one interface available. Will use that one unconditionally.\n"
return 0
fi
usbvend=`echo "$1" | ${cutbin} -d: -f1 -s`
usbprod=`echo "$1" | ${cutbin} -d: -f2 -s`
if base_drivers "${usbvend}" "${usbprod}"; then
if [ "a${baseintercandidates}" != "a" ]; then
ifvalid=`echo ${USB_INTERFACE} | ${trbin} " " "\n" | ${grepbin} "^${baseintercandidates}$"`
if [ "a${ifvalid}" = "a${baseintercandidates}" ]; then
if [ "a${USBINTERFACE}" = "a" ]; then
export USB_INTERFACE="${baseintercandidates}"
debug "Will use interface #%d derived by config.\n" "${USB_INTERFACE}"
unset ifvalid; unset usbvend; unset usbprod; unset baseintercandidates
return 0
else
debug "However, will not use it in favor of already selected USBINTERFACE: %s\n" "${USBINTERFACE}"
fi
else
debug "However, this interface is not available from device.\n"
fi
unset ifvalid
else
debug "Config does not specify interface for device %s.\n" "$1"
fi
unset baseintercandidates
else
debug "No configuration for device %s.\n" "$1"
fi
unset usbvend; unset usbprod
if flow_select_interface "$1" "${USB_INTERFACE}"; then
[ "a${USBINTERFACE}" = "a" ] && return 98
export USB_INTERFACE="${USBINTERFACE}"
debug "Will use interface #%d of USB device \"%s\".\n" "${USB_INTERFACE}" "$1"
return 0
else
unset USB_INTERFACE
debug "User did not provide an interface.\n"
return 98
fi
return 99
}
usb_sysfsdir() {
unset sysfsloc
[ "a$1" = "a" ] && return 1
! find_binary "dirname" && return 1
usbven=`echo "$1" | ${cutbin} -d: -f1`; usbpro=`echo "$1" | ${cutbin} -d: -f2`
venentry=`${grepbin} -H . /sys/bus/usb/devices/*/*/idVendor 2> /dev/null | ${grepbin} ":${usbven}$"`
if [ "a${venentry}" != "a" ]; then
for ff in ${venentry}
do
unset dirloc
dirloc=`${dirnamebin} \`echo ${ff} | ${sedbin} -e "s/:${usbven}$//g"\` 2> /dev/null`
if [ "a${dirloc}" != "a" ]; then
if [ -d "${dirloc}" ]; then
dirpro=`${catbin} ${dirloc}/idProduct`
if [ "a${dirpro}" = "a${usbpro}" ]; then
export sysfsloc="${dirloc}"
debug "Device %s sysfs dir found: %s\n" "$1" "${sysfsloc}"
unset dirpro; unset dirloc; unset venentry; unset usbven; unset usbpro
return 0
fi
unset dirpro
fi
fi
unset dirloc
done
fi
debug "No device %s located in sysfs.\n" "$1"
unset venentry; unset usbven; unset usbpro
return 1
}
usb_sysfsdir_int() {
unset sysfsintloc
[ "a$1" = "a" -o "a$2" = "a" ] && return 99
! usb_sysfsdir "$1" && return 1
intnum="$2"; [ "${intnum}" -lt "10" ] && intnum="0$2"
intdir=`${grepbin} "." ${sysfsloc}/*/bInterfaceNumber | ${grepbin} "bInterfaceNumber:${intnum}$" | ${sedbin} -e "s/bInterfaceNumber:${intnum}$/bInterfaceNumber/g"`; intdir=`${dirnamebin} "${intdir}" 2> /dev/null`; unset intnum
if [ "a${intdir}" = "a" ]; then
unset intdir; debug "Failed to retrieve sysfs directory of interface #%d.\n" "$2"
return 1
elif [ ! -d "${intdir}" ]; then
unset intdir; debug "Unable to retrieve sysfs directory of interface #%d.\n" "$2"
return 1
fi
debug "Interface #%d sysfs dir is: %s\n" "$2" "${intdir}"
export sysfsintloc="${intdir}"
unset intdir
return 0
}
# Finds tty which resides on interface $2 of usb device $1 and sets USBTTY
usb_sysfs_locate_tty() {
unset USBTTY
[ "a$1" = "a" -o "a$2" = "a" ] && return 99
! usb_sysfsdir_int "$1" "$2" && return 1
intstr=`cd ${sysfsintloc} ; ${grepbin} -H "." tty*/dev tty*/tty*/dev tty*/tty*/tty*/dev 2> /dev/null | ${sortbin} | ${uniqbin}`; unset intdir
if [ "a${intstr}" = "a" ]; then
unset intstr; debug "Failed to retrieve sysfs tty for interface #%d.\n" "$2"
return 1
fi
debug "Interface #%d tty string is: %s\n" "$2" "${intstr}"
unset ttynode
[ "a${ttynode}" = "a" ] && ttynode=`echo "${intstr}" | ${sedbin} -e "s/^\(.*\)ttyUSB\([0-9][0-9]*\)\(.*\)$/ttyUSB\2/g" | ${grepbin} "^ttyUSB"`
[ "a${ttynode}" = "a" ] && ttynode=`echo "${intstr}" | ${sedbin} -e "s/^\(.*\)ttyACM\([0-9][0-9]*\)\(.*\)$/ttyACM\2/g" | ${grepbin} "^ttyACM"`
[ "a${ttynode}" = "a" ] && ttynode=`echo "${intstr}" | ${sedbin} -e "s/^\(.*\)ttyHS\([0-9][0-9]*\)\(.*\)$/ttyHS\2/g" | ${grepbin} "^ttyHS"`
devicenode=`echo "${intstr}" | ${sedbin} -e "s/^\(.*\)dev:\([0-9][0-9]*\):\([0-9][0-9]*\)$/\2:\3/g"`
ttymajor=`echo "${devicenode}" | ${cutbin} -d: -f1`
ttyminor=`echo "${devicenode}" | ${cutbin} -d: -f2`
unset intstr; unset devicenode
debug "Will check if \"%s\" exists, or will create it with major %d and minor %d.\n" "/dev/${ttynode}" "${ttymajor}" "${ttyminor}"
if dev_create_node "/dev/${ttynode}" "${ttymajor}" "${ttyminor}"; then
export USBTTY="/dev/${ttynode}"
unset ttynode; unset ttymajor; unset ttyminor
debug "Found tty device node of interface #%d from device \"%s\": %s\n" "$2" "$1" "${USBTTY}"
return 0
else
debug "Failed to create tty device of interface #%d from device \"%s\".\n" "$2" "$1"
unset ttynode; unset ttymajor; unset ttyminor
return 8
fi
unset ttynode; unset ttymajor; unset ttyminor
return 99
}
usb_sysfsattr() {
unset SYSFS_USB_Manufacturer
unset SYSFS_USB_Product
unset SYSFS_USB_Serial
[ "a$1" = "a" ] && return 1
! usb_sysfsdir "$1" && return 1
[ "a${sysfsloc}" = "a" ] && return 1
[ ! -d "${sysfsloc}" ] && return 1
SYSFS_USB_Manufacturer=`${sedbin} -e "s/ /_/g" "${sysfsloc}/manufacturer" 2> /dev/null`
SYSFS_USB_Product=`${sedbin} -e "s/ /_/g" "${sysfsloc}/product" 2> /dev/null`
SYSFS_USB_Serial=`${sedbin} -e "s/ /_/g" "${sysfsloc}/serial" 2> /dev/null`
debug "Information from sysfs:\nUSB Manufacturer: %s\nUSB Product: %s\nUSB Serial: %s\n" "${SYSFS_USB_Manufacturer}" "${SYSFS_USB_Product}" "${SYSFS_USB_Serial}"
return 0
}
usb_scsisysfsattr() {
unset scsidir
unset SYSFS_SCSI_Vendor
unset SYSFS_SCSI_Model
unset SYSFS_SCSI_Revision
[ "a$1" = "a" ] && return 1
! usb_sysfsattr "$1" && return 1
! find_binary "dirname" && return 1
# How many seconds to wait for SCSI device to settle
counter=30
while [ "a${scsidir}" = "a" ];
do
if [ "a$2" = "a" ]; then
debug "Checking interface #%d of device %s.\n" "0" "$1"
target=`${lsbin} -1d ${sysfsloc}/*.0/host*/target*/*/vendor 2> /dev/null`
else
debug "Checking interface #%d of device %s.\n" "$2" "$1"
target=`${lsbin} -1d ${sysfsloc}/*.$2/host*/target*/*/vendor 2> /dev/null | ${tailbin} -1`
fi
[ "a${target}" != "a" ] && scsidir=`${dirnamebin} "${target}" 2> /dev/null`
[ "a${scsidir}" = "a" ] && unset scsidir
[ "a${scsidir}" != "a" ] && [ ! -d "${scsidir}" ] && unset scsidir
unset target
if [ "a${scsidir}" = "a" ]; then
if [ "${counter}" -gt "0" ]; then
debug "Device not yet settled. Will be waiting for another %d second(s).\n" "${counter}"
[ "${counter}" -eq "30" ] && verbose "Waiting device to settle"
sleep 1
else
debug "Giving up. SCSI device did not settle, or is switched already.\n"
break
fi
counter=`expr ${counter} - 1`; counter=`echo ${counter}`
fi
done
unset counter
[ "a${scsidir}" = "a" ] && unset scsidir && return 1
SYSFS_SCSI_Vendor=`${sedbin} -e "s/ /_/g" "${scsidir}/vendor" 2> /dev/null`
SYSFS_SCSI_Model=`${sedbin} -e "s/ /_/g" "${scsidir}/model" 2> /dev/null`
SYSFS_SCSI_Revision=`${sedbin} -e "s/ /_/g" "${scsidir}/rev" 2> /dev/null`
debug "SCSI device is settled:\nSCSI Vendor: %s\nSCSI Model: %s\nSCSI Revision: %s\n" "${SYSFS_SCSI_Vendor}" "${SYSFS_SCSI_Model}" "${SYSFS_SCSI_Revision}"
return 0
}
# Returns true if device $1 has a storage interface
usb_has_storage() {
unset STORAGEIF
[ "a$1" = "a" ] && return 99
if [ -r "/proc/bus/usb/devices" ]; then
usbblock=`usb_device_block "$1"`
if [ "a${usbblock}" = "a" ]; then
if [ "a${TIMEOUTOCCURED}" != "a" ]; then
show_fmt_error "Seems like an electrical/USB bus error occured. You may need to replug your modem for it to properly work.\n"
unset TIMEOUTOCCURED
fi
debug "No information for device was available. Is device really connected?\n"
debug "Will consider storage part does not exist.\n"
debug "However, this may lead into problems later.\n"
unset usbblock
return 1
fi
storageclass=`echo "${usbblock}" | ${grepbin} "Cls=08.stor."`
[ "a${storageclass}" = "a" ] && storageclass=`echo "${usbblock}" | ${grepbin} "river=usb_storage"`
[ "a${storageclass}" = "a" ] && storageclass=`echo "${usbblock}" | ${grepbin} "river=usb-storage"`
if [ "a${storageclass}" = "a" ]; then
debug "Device \"%s\" has no storage part.\n" "$1"
unset usbblock; unset storageclass
return 1
fi
storageclass=`echo "${storageclass}" | ${sedbin} -e "s/^I:\(.*\)If.=\( *\)\([0-9][0-9]*\) \(.*\)$/\3/g"`
debug "Device has storage part on interface #%s.\n" "${storageclass}"
STORAGEIF=`echo "${storageclass}" | ${headbin} -1 | ${cutbin} "-d " -f1`
export STORAGEIF
unset usbblock; unset storageclass
return 0
elif find_binary "lsusb"; then
storageclass=`safe_lsusb -d "$1" -v | ${grepbin} -B 10 -A 10 -i storage | ${grepbin} -i "bInterfaceNumber" | ${tailbin} -1 | ${sedbin} -e "s/ */ /g" | ${sedbin} -e "s/^ //g" | ${cutbin} -d\ -f2`
if [ "a${storageclass}" = "a" ]; then
if [ "a${TIMEOUTOCCURED}" != "a" ]; then
show_fmt_error "Seems like an electrical/USB bus error occured. You may need to replug your modem for it to properly work.\n"
unset TIMEOUTOCCURED
fi
debug "Device \"%s\" has no storage part.\n" "$1"
unset storageclass
return 1
fi
debug "Device has storage part on interface #%s.\n" "${storageclass}"
# TODO: What happens when more storage interfaces exist?
STORAGEIF=`echo "${storageclass}" | ${headbin} -1 | ${cutbin} -d\ -f1`
export STORAGEIF
unset storageclass
return 0
else
debug "Both %s and %s are not available.\n" "/proc/bus/usb/devices" "lsusb"
debug "Failed to determine if device %s has a storage interface.\n" "$1"
debug "Will consider storage part does not exist.\n"
debug "However, this may lead into problems later.\n"
return 1
fi
}
# Newer kernels provide this feature
usb_stabilize() {
[ "a$1" = "a" ] && return 1
! usb_sysfsdir "$1" && return 1
[ "a${sysfsloc}" = "a" ] && return 1
[ ! -d "${sysfsloc}" ] && return 1
[ ! -w "${sysfsloc}/avoid_reset_quirk" ] && return 1
debug "Kernel provides AVOID_RESET_QUIRK for device %s.\n" "$1"
echo "1" > "${sysfsloc}/avoid_reset_quirk" 2> /dev/null
ret=$?
[ "a${ret}" = "a0" ] && debug "Succesfully enabled AVOID_RESET_QUIRK for device %s.\n" "$1"
[ "a${ret}" = "a0" ] && debug "Failed to enable AVOID_RESET_QUIRK for device %s.\n" "$1"
return ${ret}
}
# Makes sure that if device $1 has a storage part, this part
# is settled.
usb_storage_settled() {
if ! usb_has_storage "$1"; then
hal_unlock
return 0
fi
debug "Device %s, provides storage interface #%s.\n" "$1" "${STORAGEIF}"
storageloaded=`usb_loaded_driver "$1" "${STORAGEIF}" | ${tailbin} -1`
if [ "a${TIMEOUTOCCURED}" != "a" ]; then
show_fmt_error "Seems like an electrical/USB bus error occured. You may need to replug your modem for it to properly work.\n"
unset TIMEOUTOCCURED
fi
if [ "a${storageloaded}" != "ausb-storage" -a "a${storageloaded}" != "ausb_storage" ]; then
debug "Interface %s of device %s is bound to driver: %s\n" "${STORAGEIF}" "$1" "${storageloaded}"
debug "No need to wait for storage interface to settle.\n"
unset storageloaded
hal_unlock
return 0
fi
debug "Storage interface #%s is binded by %s driver.\n" "${STORAGEIF}" "${storageloaded}"
if [ "a${killstorage}" != "a" ]; then
debug "User has set \"%s\" switch. Will try to unbind %s driver from interface #%d.\n" "killstorage" "${storageloaded}" "${STORAGEIF}"
if module_unbind "${storageloaded}" "$1" "${STORAGEIF}"; then
debug "Storage interface has been freed as instructed.\n"
debug "No need to wait for storage interface to settle.\n"
unset storageloaded
hal_unlock
return 0
else
debug "Failed to unbind it. Too bad.\n"
show_fmt_error "Failed to unbind driver %s. I am sorry." "${storageloaded}"
fi
fi
unset storageloaded
if ! usb_scsisysfsattr "$1" "${STORAGEIF}"; then
debug "Will consider storage part is settled.\n"
debug "However, this may lead into problems later.\n"
fi
storagedevices=`${grepbin} . ${sysfsloc}/*.${STORAGEIF}/host*/target*/*/block*/size 2> /dev/null | ${grepbin} -v ":0$" | ${sedbin} -e "s/^\(.*\)\/block:\(.*\)\/size:\(.*\)$/\2/g" | ${trbin} "\n" " "`; storagedevices=`echo ${storagedevices}`
if [ "a${storagedevices}" = "a" ]; then
debug "No storage device(s) with inserted media exist. Safe to unlock HAL.\n"
hal_unlock
unset storagedevices; unset STORAGEIF
return 0
fi
debug "Media found on following device(s) provided by interface #%s of device %s: %s\n" "${STORAGEIF}" "$1" "${storagedevices}"
if [ "a${HAL_LOCK}" != "a" ]; then
hal_unlock
debug "HAL is unlocked. Checking if HAL will kick in.\n"
pausecounter=21
while [ "${pausecounter}" -gt "0" ]
do
blocking=""
for blockdevice in ${storagedevices}
do
poller=`${psbin} -Af | ${grepbin} "hald" | ${grepbin} "storage" | ${grepbin} "polling \(.*\)${blockdevice}" | ${grepbin} -v "${grepbin}"`
if [ "a${poller}" = "a" ]; then
debug "No polling process exists for %s.\n" "${blockdevice}"
continue
fi
debug "Polling process exists for %s: %s\n" "${blockdevice}" "${poller}"
poller=`${grepbin} "\/${blockdevice} " "/proc/mounts" 2> /dev/null`
if [ "a${poller}" != "a" ]; then
debug "Device %s mounted: %s\n" "${blockdevice}" "${poller}"
else
debug "Device %s still not mounted.\n" "${blockdevice}"
blocking="${blocking} ${blockdevice}"
fi
done
unset blockdevice; unset poller; blocking=`echo ${blocking}`
if [ "a${blocking}" = "a" ]; then
debug "HAL has finished mounting media on device(s): %s\n" "${storagedevices}"
break
fi
pausecounter=`expr ${pausecounter} - 1`; pausecounter=`echo ${pausecounter}`
if [ "${pausecounter}" -eq "0" ]; then
debug "Giving up waiting for HAL to mount devices.\n"
debug "This may lead into problems later on.\n"
else
[ "${pausecounter}" -eq "20" ] && verbose "Waiting HAL to mount device(s)"
debug "Waiting for HAL to mount all devices. %d second(s) to abort.\n" "${pausecounter}"
sleep 1
fi
done
unset poller; unset blockdevice
unset pausecounter; unset blocking
else
debug "HAL was not locked. Will skip waiting for device mount.\n"
fi
unset storagedevices; unset STORAGEIF
return 0
}
# Scans for bluetooth devices
bluetooth_scan_devices() {
! find_binary "hcitool" && return 1
verbose "Scanning bluetooth devices"
bluetooth_devices=`${hcitoolbin} scan 2> /dev/null | ${grepbin} "^ " | ${sedbin} -e "s/^ \(.*\) \(.*\)/\1 \2/g"`
debug "Found bluetooth devices:\n%s\n" "${bluetooth_devices}"
return 0
}
# Returns rfcomm channel for service $2 for device $1
bluetooth_rfcomm_channel() {
! find_binary "sdptool" && return 0
rfchannel=`${sdptoolbin} search --raw --bdaddr "$1" "$2" 2> /dev/null | ${grepbin} -A 1 --binary-files=text "RFCOMM" | ${grepbin} "UINT8" | ${sedbin} -e "s/^\(.*\)UINT8 \(.*\)/\2/g"`
rfchannel=`echo ${rfchannel}`
debug "Found RFCOMM channel \"%s\" of service \"%s\" on device \"%s\".\n" "${rfchannel}" "$2" "$1"
[ "a${rfchannel}" != "a" ] && rfchannel=`${printfbin} "%d\n" ${rfchannel} 2> /dev/null`
[ "a${rfchannel}" = "a" ] && rfchannel="0"
debug "Returning RFCOMM channels \"%s\".\n" "`echo ${rfchannel}`"
return `echo ${rfchannel} | ${cutbin} -d\ -f1`
}
# Returns true if device $1, channel $2 is on tty $3
# NOTE: Does not depend on bluetooth_rfcomm_dev because
# bluetooth_rfcomm_dev only returns 1st valid
# channel
bluetooth_rfcomm_match() {
! find_binary "rfcomm" && return 1
[ "a${3}" != "a" ] && [ ! -c "${3}" ] && return 1
bluematch=`${rfcommbin} -a --raw | ${grepbin} --binary-files=text " $1 " | ${grepbin} --binary-files=text " channel $2 " | ${grepbin} "^\`${basenamebin} $3\`:" | ${wcbin} -l`; bluematch=`echo ${bluematch}`
if [ "a${bluematch}" = "a1" ]; then
debug "%s refers to RFCOMM channel %d of device %s.\n" "$3" "$2" "$1"
unset bluematch
return 0
fi
debug "%s does not refer to RFCOMM channel %d of device %s.\n" "$3" "$2" "$1"
unset bluematch
return 1
}
# Returns tty where device $1, channel $2 resides (if any)
bluetooth_rfcomm_dev() {
! find_binary "rfcomm" > /dev/null && return 1
bluematch=`${rfcommbin} -a --raw 2> /dev/null | ${grepbin} --binary-files=text " $1 " | ${grepbin} --binary-files=text " channel $2 " | ${headbin} -1 | ${cutbin} -d: -f1`
if [ "a${bluematch}" = "a" ]; then
unset bluematch
return 1
fi
echo "${bluematch}"
unset bluematch
return 0
}
# Creates rfcomm device for device $1, channel $2 and sets RFCOMM_TTY
bluetooth_create_dev() {
! we_are_root_already && debug "Need root privileges to create rfcomm nodes.\n"
! we_are_root && return 1
need_binary "rfcomm"
for devindex in 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15
do
unset occupied
occupied=`${rfcommbin} show ${devindex} 2> /dev/null`
[ "a${occupied}" = "a" ] && break
done
if [ "a${occupied}" != "a" ]; then
unset occupied
unset devindex
show_fmt_error "Unable to find available rfcomm device index. Minors occupied."
return 1
fi
unset occupied
debug "Found available rfcomm device node %d.\n" "${devindex}"
debug run_command "${rfcommbin} bind ${devindex} \"$1\" \"$2\""
if ! bluetooth_rfcomm_match "$1" "$2" "/dev/rfcomm${devindex}"; then
show_fmt_error "Unable to create rfcomm node %s." "rfcomm${devindex}"
unset devindex
return 1
fi
if [ ! -c "/dev/rfcomm${devindex}" ]; then
debug "Device node \"%s\" was not automatically created.\n" "/dev/rfcomm${devindex}"
if ! dev_create_node "/dev/rfcomm${devindex}" "216" "${devindex}"; then
show_fmt_error "Unable to create rfcomm device node \"%s\"." "/dev/rfcomm${devindex}"
unset devindex
return 1
fi
debug "Made node \"%s\" ourselves.\n" "/dev/rfcomm${devindex}"
fi
export RFCOMM_TTY="/dev/rfcomm${devindex}"
unset devindex
}
# Setups rfcomm device for device $1, channel $2 and sets RFCOMM_TTY
bluetooth_setup_rfcomm() {
if [ "a${RFCOMM_TTY}" != "a" ]; then
if bluetooth_rfcomm_match "$1" "$2" "${RFCOMM_TTY}"; then
debug "Will use already set RFCOMM_TTY (%s).\n" "${RFCOMM_TTY}"
return 0
else
debug "Already set RFCOMM_TTY does not refer to a tty of \"%s\": \"%s\"\n" "$1" "${RFCOMM_TTY}"
unset RFCOMM_TTY
fi
fi
RFCOMM_TTY=`bluetooth_rfcomm_dev "$1" "$2"`
if [ "a${RFCOMM_TTY}" != "a" ]; then
export RFCOMM_TTY="/dev/${RFCOMM_TTY}"
if [ -c "${RFCOMM_TTY}" ]; then
debug "Found already binded rfcomm tty %s.\n" "${RFCOMM_TTY}"
return 0
fi
unset RFCOMM_TTY
fi
unset RFCOMM_TTY
if bluetooth_create_dev "$1" "$2"; then
debug "Succesfully binded to rfcomm tty %s.\n" "${RFCOMM_TTY}"
return 0
fi
debug "Failed to setup rfcomm tty for device \"%s\".\n" "$1"
return 1
}
# Method invoked when "status" action was requested.
ppp_fast_status() {
need_binary "grep"
need_arg "pppint"
unset status
[ -f "/proc/net/dev" ] && [ -r "/proc/net/dev" ] && status=`${grepbin} "${pppint}:" /proc/net/dev`
[ -z "${status}" ] && find_binary "ifconfig" && status=`${ifconfigbin} ${pppint} 2> /dev/null | ${grepbin} " UP "`
if [ "a${status}" = "a" ]; then
unset status
return 1
else
unset status
return 0
fi
}
# Called by ispconnect to determine if connection is established
ppp_slow_status() {
need_arg "pppint"
need_binary "netstat"
[ "a${pppint}" = "a" ] && pppint="ppp0"
pppcon=`${catbin} /proc/net/dev | ${grepbin} "^\( *\)${pppint}:" | ${wcbin} -l`; pppcon=`echo ${pppcon}`
[ "a${pppcon}" = "a0" ] && unset pppcon && return 1
debug "Interface %s is up.\n" "${pppint}"
pppcon=`${netstatbin} -rn | ${grepbin} " ${pppint}$" | ${grepbin} -v "^0.0.0.0" | ${wcbin} -l`; pppcon=`echo ${pppcon}`
[ "a${pppcon}" = "a0" ] && unset pppcon && return 1
debug "Default route through %s is established.\n" "${pppint}"
debug "Really connected.\n"
return 0
}
# Shows version
show_version() {
if find_binary "printf"; then
format_text "Sakis 3G All-in-one script - Version %s\n" "${MYVERSION}"
format_text "(c) Sakis Dimopoulos 2009, 2010 under GNU GPL v2\n\n"
else
need_binary "echo"
echo "Sakis 3G All-in-one script - Version ${MYVERSION}"
echo "(c) Sakis Dimopoulos 2009, 2010 under GNU GPL v2"
echo
fi
}
# Shows usage help
show_help() {
helptext=`raw_help`
notify "%s\n" "${helptext}"
return 0
}
raw_help() {
[ "a${PROVIDER}" = "a" ] && return 1
[ ! -x "${PROVIDER}" ] && return 1
show_version
echo
"${PROVIDER}" getfile "files/help.txt" 2> /dev/null
}
modeswitch_load_realtime() {
debug "Loading system supplied device database.\n"
for dep in sed rm grep tr sort uniq cut printf basename
do
! find_binary "${dep}" && return 1
done
unset dep; unset realtime_switchable; unset realtime_switched;
unset CheckSuccess; unset Configuration;
unset GCTMode; unset HuaweiMode; unset SierraMode; unset SonyMode;
unset Interface; unset MessageContent; unset ResponseNeeded
unset DefaultProduct; unset DefaultVendor;
unset TargetClass; unset TargetProduct; unset TargetProductList; unset TargetVendor
for filename in /etc/usb_modeswitch.d/* /etc/usb_modeswitch.d/*
do
current_device=`${basenamebin} ${filename} | ${cutbin} -d: -f1,2 -s`
[ "a${current_device}" = "a" ] && unset current_device && continue
realtime_switchable="${realtime_switchable} ${current_device}"
${sedbin} -e "s/ //g" "${filename}" > "/tmp/$$.tmp" 2> /dev/null
. "/tmp/$$.tmp" > /dev/null 2> /dev/null
${rmbin} -f "/tmp/$$.tmp" > /dev/null 2> /dev/null
for ven in ${TargetVendor}
do
if [ -n "${TargetProductList}" ]; then
list=`echo ${TargetProductList} | ${sedbin} -e "s/,/ /g"`
for pro in $list
do
realtime_switched="${realtime_switched} ${ven}:${pro}"
done
unset list
elif [ -n "${TargetProduct}" ]; then
realtime_switched="${realtime_switched} ${ven}:${TargetProduct}"
fi
done
unset current_device
unset CheckSuccess; unset Configuration;
unset GCTMode; unset HuaweiMode; unset SierraMode; unset SonyMode;
unset Interface; unset MessageContent; unset ResponseNeeded
unset DefaultProduct; unset DefaultVendor;
unset TargetClass; unset TargetProduct; unset TargetProductList; unset TargetVendor
done
realtime_switched=`echo ${realtime_switched} | ${sedbin} -e "s/0x//g" | ${trbin} " " "\n" | ${sortbin} | ${uniqbin}`
realtime_switched=`echo ${realtime_switched}`
realtime_switchable=`echo ${realtime_switchable} | ${sedbin} -e "s/0x//g" | ${trbin} " " "\n" | ${sortbin} | ${uniqbin}`
realtime_switchable=`echo ${realtime_switchable}`
debug "Switchable devices within system device database:\n%s\n" "${realtime_switchable}"
debug "Switched devices within system device database:\n%s\n" "${realtime_switched}"
${printfbin} "%s\n%s\n" "${realtime_switchable}" "${realtime_switched}"
unset realtime_switched; unset realtime_switchable
return 0
}
# Loads Usb-ModeSwitch device database, both embedded and system supplied
modeswitch_load() {
unset SWITCHABLE_devices; unset SWITCHED_devices; unset KNOWN_devices
debug "Loading Usb-ModeSwitch device database.\n"
# Check if possible to include embedded database
if [ "a${PROVIDER}" = "a" ]; then
debug "Unable to locate package provider.\n"
elif [ ! -x "${PROVIDER}" ]; then
debug "Unable to execute package provider.\n"
else
"${PROVIDER}" getfile "build/switchconfig" > "/tmp/sakis3g.$$.sw"
if [ ! -f "/tmp/sakis3g.$$.sw" ]; then
debug "Unable to find device database.\n"
elif [ ! -s "/tmp/sakis3g.$$.sw" ]; then
rm -f "/tmp/sakis3g.$$.sw"
debug "Embedded device database contains 0 entries.\n"
else
. "/tmp/sakis3g.$$.sw"
rm -f "/tmp/sakis3g.$$.sw"
getswitchabledevices 2> /dev/null
# TODO: Comment following line to render embedded device database unusable.
#unset usbswitchabledevices && unset usbswitcheddevices && debug "DELETED DATABASE TO EMULATE VOODOO MODE.\n"
ret=$?;
if [ "${ret}" -ne "0" ]; then
debug "Failed to load embedded Usb-ModeSwitch device database.\n"
else
debug "Embedded device database loaded.\n"
export SWITCHABLE_devices="${usbswitchabledevices}"
export SWITCHED_devices="${usbswitcheddevices}"
debug "Switchable devices within embedded device database:\n%s\n" "${SWITCHABLE_devices}"
debug "Switched devices within embedded device database:\n%s\n" "${SWITCHED_devices}"
KNOWN_devices=`echo "${SWITCHABLE_devices} ${SWITCHED_devices}" | ${trbin} " " "\n" | ${sortbin} | ${uniqbin}`
KNOWN_devices=`echo "${KNOWN_devices}"`
export KNOWN_devices
devicecount=`echo "${KNOWN_devices}" | ${wcbin} -w`; devicecount=`echo ${devicecount}`; [ "a${devicecount}" = "a" ] && devicecount=0
debug "Embedded Usb-ModeSwitch device database contains %d entries.\n" "${devicecount}"
unset devicecount
fi
fi
fi
# Check if system supplied Usb-ModeSwitch database exists
if [ -d "/etc/usb_modeswitch.d" ]; then
debug "Folder \"%s\" exists. Will check if it contains configuration files.\n" "/etc/usb_modeswitch.d"
realtime_devices=`modeswitch_load_realtime`
if [ "a${realtime_devices}" != "a" ]; then
usbswitchabledevices=`echo "${realtime_devices}" | ${tailbin} -2 | ${headbin} -1`
usbswitcheddevices=`echo "${realtime_devices}" | ${tailbin} -1`
SWITCHABLE_devices="${SWITCHABLE_devices} ${usbswitchabledevices}"
SWITCHED_devices="${SWITCHED_devices} ${usbswitcheddevices}"
SWITCHABLE_devices=`echo "${SWITCHABLE_devices}" | ${trbin} " " "\n" | ${sortbin} | ${uniqbin}`
SWITCHED_devices=`echo "${SWITCHED_devices}" | ${trbin} " " "\n" | ${sortbin} | ${uniqbin}`
SWITCHABLE_devices=`echo ${SWITCHABLE_devices}`
SWITCHED_devices=`echo ${SWITCHED_devices}`
KNOWN_devices=`echo "${SWITCHABLE_devices} ${SWITCHED_devices}" | ${trbin} " " "\n" | ${sortbin} | ${uniqbin}`
KNOWN_devices=`echo "${KNOWN_devices}"`
export SWITCHABLE_devices
export SWITCHED_devices
export KNOWN_devices
devicecount=`echo "${KNOWN_devices}" | ${wcbin} -w`; devicecount=`echo ${devicecount}`; [ "a${devicecount}" = "a" ] && devicecount=0
debug "Device database now contains %d entries.\n" "${devicecount}"
unset devicecount
fi
unset realtime_devices
fi
unset usbswitchabledevices; unset usbswitcheddevices
return 0
}
# Returns 0 if device $1 is switchable
modeswitch_is_switchable() {
[ "a${KNOWN_devices}" = "a" ] && ! modeswitch_load && return 1
isswitchable=`echo "${SWITCHABLE_devices}" | ${grepbin} "$1" | ${wcbin} -l`; isswitchable=`echo ${isswitchable}`
[ "a${isswitchable}" = "a" ] && isswitchable="0"
if [ "a${isswitchable}" = "a0" ]; then
if [ -f "/etc/usb_modeswitch.d/$1" ]; then
debug "Since file \"%s\" exists, will consider device \"%s\" switchable.\n" "/etc/usb_modeswitch.d/$1" "$1"
unset isswitchable
return 0
fi
debug "Device \"%s\" is not switchable.\n" "$1"
unset isswitchable
return 1
else
unset isswitchable
return 0
fi
}
modeswitch_switchable_devices() {
! usb_connected_modems && return 1
for condevice in ${usb_modems}
do
if modeswitch_is_switchable "${condevice}"; then
debug "There is at least one (%s) switchable device plugged.\n" "${condevice}"
unset condevice
return 0
fi
done
unset condevice
debug "No switchable device plugged.\n" "${condevice}"
return 1
}
modeswitch_conf_realtime() {
unset modeswitch_config
debug "Seeking a system supplied configuration file for switching device %s.\n" "$1"
[ ! -d "/etc/usb_modeswitch.d" -a ! -d "/etc/usb-modeswitch.d" ] && return 1
# Check if exists a candidate which needs SCSI information
needscsi=`${lsbin} -1r /etc/usb_modeswitch.d/$1:s* /etc/usb-modeswitch.d/$1:s* 2> /dev/null | ${wcbin} -l`
needscsi=`echo ${needscsi}`
if [ "a${needscsi}" != "a0" -a "a${needscsi}" != "a" ]; then
debug "Will need SCSI information for finding appropriate file.\n"
usb_scsisysfsattr "$1"
fi
unset needscsi
# Iterate through files
files=`${lsbin} -1r /etc/usb_modeswitch.d/$1* /etc/usb-modeswitch.d/$1* 2> /dev/null`
for filename in ${files}
do
debug "Checking if file \"%s\" matches.\n" "${filename}"
bn=`${basenamebin} "${filename}"`
crit=`echo "${bn}" | ${cutbin} -d: -f3-`; crit=`echo ${crit}`
if [ "a${crit}" != "a" ]; then
field=`echo "${crit}" | ${cutbin} -d= -f1 -s`
value=`echo "${crit}" | ${cutbin} -d= -f2 -s`
if [ "a${field}" = "a" ]; then
debug "File %s does not specify criteria to match. Skipping it." "${bn}"
unset bn; unset crit; unset field; unset value
continue
fi
if [ "a${value}" = "a" ]; then
debug "File %s does not specify value for attribute %s. Skipping it." "${bn}" "${field}"
unset bn; unset crit; unset field; unset value
continue
fi
len=`echo "${value}" | ${wcbin} -c`; len=`echo ${len}`; len=`expr ${len} - 1 2> /dev/null`; len=`echo ${len}`
if [ "a${len}" = "a" ] || [ "${len}" -eq "0" ]; then
debug "Value \"%s\" to be checked is not valid. Skipping file %s." "${value}" "${bn}"
unset bn; unset crit; unset field; unset value
continue
fi
unset attribute
case "${field}" in
sVe)
attribute=`echo ${SYSFS_SCSI_Vendor}`
;;
sMo)
attribute=`echo ${SYSFS_SCSI_Model}`
;;
sRe)
attribute=`echo ${SYSFS_SCSI_Revision}`
;;
uMa)
attribute=`echo ${SYSFS_USB_Manufacturer}`
;;
uPr)
attribute=`echo ${SYSFS_USB_Product}`
;;
uSe)
attribute=`echo ${SYSFS_USB_Serial}`
;;
*)
debug "FIXME: Unknown field \"%s\". Try downloading a newer Sakis3G version.\n" "${field}"
;;
esac
if [ "a${attribute}" = "a" ]; then
debug "No value for field %s exists for device %s.\n" "${field}" "$1"
unset attribute; unset len; unset field; unset value; unset bn; unset crit
continue
fi
debug "Found %s.%s=\"%s\".\n" "$1" "${field}" "${attribute}"
attribute=`echo ${attribute} | ${cutbin} -b1-${len} 2> /dev/null`
if [ "a${attribute}" != "a" -a "a${attribute}" = "a${value}" ]; then
debug "File %s matches information derived from device.\n" "${bn}"
modeswitch_config="${filename}"
unset attribute; unset len; unset field; unset value; unset bn; unset crit
break;
fi
debug "File %s does not match.\n" "${bn}"
unset attribute; unset len; unset field; unset value;
else
debug "Found an exact match file: %s\n" "${filename}"
modeswitch_config="${filename}"
fi
unset crit; unset bn
done
filename="${modeswitch_config}"
unset modeswitch_config
if [ "a${filename}" != "a" ] && [ -f "${filename}" ]; then
${catbin} "${filename}" > "/tmp/sakis3g.sw.dev.$$" 2> /dev/null
if [ -s "/tmp/sakis3g.sw.dev.$$" ]; then
export modeswitch_config="/tmp/sakis3g.sw.dev.$$"
unset filename
return 0
else
${rmbin} -f "/tmp/sakis3g.sw.dev.$$"
fi
fi
unset filename
debug "No system supplied configuration file found for switching device \"%s\".\n" "$1"
return 1
}
# Returns location of extracted configuration file that should be used to switch device $1 within modeswitch_config variable
modeswitch_conf_embedded() {
unset modeswitch_config
debug "Seeking embedded configuration file for switching device %s.\n" "$1"
switchfunc="usbswitchconf_`echo "$1" | ${sedbin} -e "s/:/_/g"`"
unset modeswitchconf
eval ${switchfunc} 2> /dev/null
ret=$?; unset switchfunc
if [ "${ret}" -ne "0" ]; then
debug "Failed to retrieve configuration for switching device \"%s\".\n" "$1"
return 1
fi
[ "a${modeswitchconf}" = "a" ] && debug "No configuration file found for switching device \"%s\".\n" "$1" && return 1
[ "a${PROVIDER}" = "a" ] && debug "Unable to locate package provider.\n" && unset modeswitchconf && return 1
[ ! -x "${PROVIDER}" ] && debug "Unable to execute package provider.\n" && unset modeswitchconf && return 1
eval "${PROVIDER}" getfile "${modeswitchconf}" > "/tmp/sakis3g.sw.dev.$$"
[ ! -f "/tmp/sakis3g.sw.dev.$$" ] && debug "Configuration file \"%s\" for switching device \"%s\" not found within package.\n" "${modeswitchconf}" "$1" && unset modeswitchconf && return 1
if [ ! -s "/tmp/sakis3g.sw.dev.$$" ]; then
${rmbin} -f "/tmp/sakis3g.sw.dev.$$"
debug "Configuration file \"%s\" for switching device \"%s\" not found within package.\n" "${modeswitchconf}" "$1"
unset modeswitchconf
return 1
fi
unset modeswitchconf
export modeswitch_config="/tmp/sakis3g.sw.dev.$$"
return 0
}
modeswitch_conf() {
unset modeswitch_config
debug "Seeking configuration file for switching device %s.\n" "$1"
[ "a${KNOWN_devices}" = "a" ] && ! modeswitch_load && return 1
! modeswitch_conf_embedded "$1" && modeswitch_conf_realtime "$1"
if [ "a${modeswitch_config}" = "a" ] || [ ! -f "${modeswitch_config}" ] || [ ! -s "${modeswitch_config}" ]; then
unset modeswitch_config
show_fmt_error "Unable to locate a configuration file for switching device %s.\n" "$1"
return 1
fi
debug run_command "${catbin} \"${modeswitch_config}\""
debug "Configuration file for switching device \"%s\" at: %s\n" "$1" "${modeswitch_config}"
return 0
}
# Executed when binary Usb-ModeSwitch is binary incompatible on running platform.
modeswitch_emergency() {
! usb_has_storage "$1" && return 1
debug "Will attempt to switch device by detaching usb-storage driver.\n"
storageloaded=`usb_loaded_driver "$1" "${STORAGEIF}" | ${tailbin} -1`
if [ "a${TIMEOUTOCCURED}" != "a" ]; then
show_fmt_error "Seems like an electrical/USB bus error occured. You may need to replug your modem for it to properly work.\n"
unset TIMEOUTOCCURED
fi
[ "a${storageloaded}" = "aNONE" ] && ! module_bind "usb_storage" "$1" "${STORAGEIF}"
! module_unbind "usb_storage" "$1" "${STORAGEIF}"
unset STORAGEIF
return 0
}
# Switches device $1. Caller should check NEWIDS variable, because device most likely will change its ID.
modeswitch_switch() {
[ "a$1" = "a" ] && return 1
! modeswitch_is_switchable "$1" && return 1
! modeswitch_conf "$1" && return 1
[ ! -f "${modeswitch_config}" ] && debug "Configuration file \"%s\" disappeared.\n" "${modeswitch_config}"
# Block hal from messing with us
hal_acquire_lock "org.freedesktop.Hal.Device.Storage"
verbose "Switching modem"
debug "Connected devices before switching.\n"
usb_connected_devices
previously=`echo "${usb_devices}" | ${grepbin} -v "^$1:" | ${cutbin} -d: -f1,2`
if [ "a${binaryfree}" = "a" ]; then
debug run_command "${PROVIDER} usb_modeswitch -W -I -c \"${modeswitch_config}\""
ret=$?
else
ret=95
fi
if [ "${ret}" -eq "95" ]; then
[ "a${binaryfree}" = "a" ] && debug "Binary incompatibility of package provided usb-modeswitch.\n"
if find_binary "usb_modeswitch"; then
debug "Will try system provided binary, hoping it is a recent one: %s\n" "${usb_modeswitchbin}"
verbose "Switching modem (using %s)" "${usb_modeswitchbin}"
debug run_command "${usb_modeswitchbin} --version"
debug run_command "${usb_modeswitchbin} -W -I -c \"${modeswitch_config}\""
ret=$?
elif [ "a${binaryfree}" = "a" ]; then
show_fmt_error "Embedded Usb-ModeSwitch binary is not valid for your architect. You need to recompile for devices to switch properly. Start by issueing: %s recompile" "${PROVIDER}"
debug "Will try emergency mode.\n"
verbose "Trying emergency switch"
modeswitch_emergency "$1"
ret=$?
else
show_fmt_error "%s is not installed on your system.\n" "Usb-ModeSwitch"
return 4
fi
fi
rm -f "${modeswitch_config}"; unset modeswitch_config
counter=0
while [ "${counter}" -lt "20" ]
do
usb_connected_devices
after=`echo "${usb_devices}" | ${grepbin} "^$1:"`
if [ "a${after}" != "a" -a "${counter}" -eq "0" ]; then
debug "Device \"%s\" still there. Lets hope it has switched.\n" "$1"
unset after; unset previously
export NEWIDS="$1"
return 0
fi
after="`echo "${usb_devices}" | ${cutbin} -d: -f1,2`"
for device in ${after}
do
newdevice=`echo "${previously}" | ${grepbin} "^${device}"`
if [ "a${newdevice}" = "a" ]; then
export NEWIDS="${device}"
debug "New device \"%s\" appeared.\n" "${NEWIDS}"
unset device; unset after; unset previously
return 0
fi
done
unset device
counter=`expr ${counter} + 1`; counter=`echo ${counter}`
[ "${counter}" -lt "20" ] && debug "Waiting a second for device to appear.\n" && sleep 1
done
debug "Giving up waiting for new device to appear after %d seconds.\n" "${counter}"
unset after; unset previously; unset counter
return 1
}
# Detects usable interface of device $1 and sets USB_INTERFACE variable. Device will get switched if required.
# Callers should check NEWIDS variable
modem_usb_detect_int() {
[ "a$1" = "a" ] && return 99
usb_get_interface "$1"; ret=$?
case "${ret}" in
7)
debug "Failed to get USB interface.\n"
return 7
;;
98)
debug "Failed to get USB interface, by user request.\n"
return 98
;;
8)
debug "Failed to get an interface for device.\n"
if modeswitch_is_switchable "$1"; then
if [ "a$2" != "aNOSWITCH" ]; then
debug "This is normal, device \"%s\" is switchable.\n" "$1"
modeswitch_switch "$1"
ret=$?
if [ "${ret}" -eq "0" -a "a${NEWIDS}" != "a" -a "a$2" != "aNOSWITCH" ]; then
debug "Device \"%s\" is now switched to \"%s\". Will attempt to setup this one instead.\n" "$1" "${NEWIDS}"
modem_usb_detect_int "${NEWIDS}" "NOSWITCH"
ret=$?
return ${ret}
else
debug "Failed to switch device \"%s\".\n" "$1"
return ${ret}
fi
else
debug "However, device \"%s\" is already switched.\n" "$1"
return 8
fi
fi
debug "Failed setting up USB modem \"%s\".\n" "$1"
return 8
;;
0)
debug "Got valid USB interface %d of USB modem \"%s\".\n" "${USB_INTERFACE}" "$1"
return 0
;;
*)
debug "Unknown error %d while retrieving interface number of USB Device.\n" "${ret}"
return ${ret}
;;
esac
}
# Sets USBTTY one way or another
modem_usb_locate_tty() {
verbose "Locating tty"
lcounter=0
while ! usb_sysfs_locate_tty "$1" "$2" "$3"
do
lcounter=`expr ${lcounter} + 1`; lcounter=`echo ${lcounter}`
if [ "${lcounter}" -le "20" ]; then
if [ "a$3" != "a" ]; then
debug "Waiting for driver %s to create tty of device %s (interface #%d). [%d second(s) will have pass]\n" "$3" "$1" "$2" "${lcounter}"
else
debug "Waiting for tty of device %s (interface #%d). [%d second(s) will have pass]\n" "$1" "$2" "${lcounter}"
fi
sleep 1
else
if [ "a$3" != "a" ]; then
debug "Driver %s failed to create a tty node for interface #%d of device %s.\n" "$3" "$2" "$1"
else
debug "No tty node created for interface #%d of device %s.\n" "$2" "$1"
fi
debug "Failed to locate tty device of interface #%d from device \"%s\".\n" "$2" "$1"
unset lcounter
return 8
fi
done
return 0
}
modem_usb_fix_driver() {
[ "a$1" = "a" -o "a$2" = "a" ] && return 99
usb_stabilize "$1"
# Make sure storage part (if exists), is settled before
# we start playing with drivers. This should eliminate
# cases that appeared on 2.6.31+ kernels.
usb_storage_settled "$1"
# Retrieve loaded driver
usbdriver=`usb_loaded_driver "$1" "$2" | ${tailbin} -1`
if [ "a${TIMEOUTOCCURED}" != "a" ]; then
show_fmt_error "Seems like an electrical/USB bus error occured. You may need to replug your modem for it to properly work.\n"
unset TIMEOUTOCCURED
fi
# Check value
if [ "a${usbdriver}" = "a" -o "a${usbdriver}" = "aFAIL" ]; then
show_fmt_error "Failed to detect driver of interface %d.\n" "$2"
unset usbdriver
return 7
elif [ "a${usbdriver}" = "aNONE" ]; then
debug "No driver attached to interface #%d of \"%s\".\n" "$2" "$1"
else
debug "Found already loaded driver \"%s\".\n" "${usbdriver}"
fi
# If driver mismatch, unload wrong driver
if [ "a${USBDRIVER}" != "a" -a "a${usbdriver}" != "a" -a "a${usbdriver}" != "a${USBDRIVER}" -a "a${usbdriver}" != "aNONE" ]; then
debug "USBDRIVER variable instructs to use \"%s\" instead.\n" "${USBDRIVER}"
if ! module_unbind "${usbdriver}" "$1" "$2"; then
show_fmt_error "Failed to detach wrong driver \"%s\". Please do it yourself and retry.\n" "${usbdriver}"
unset usbdriver
return 9
fi
usbdriver="NONE"
fi
# If no driver, attempt to detect one
[ "a${USBDRIVER}" = "a" -a "a${usbdriver}" != "aNONE" ] && USBDRIVER="${usbdriver}"
if [ "a${USBDRIVER}" = "a" -a "a${usbdriver}" = "aNONE" ]; then
if [ "a${USB_INTERFACE}" != "a" ]; then
usb_serial_detect_driver "$1" "$2"
if [ "a${USB_INTERFACE}" = "a" ]; then
# "usb_serial_detect_driver" call above, called "usb_usable_interfaces" which reset USB_INTERFACE
USB_INTERFACE="$2" ; export USB_INTERFACE
debug "Interface of device \"%s\" is still #%d.\n" "$1" "${USB_INTERFACE}"
fi
else
usb_serial_detect_driver "$1" "$2"
fi
fi
# We should know a driver now
if [ "a${USBDRIVER}" = "a" ]; then
unset usbdriver
show_fmt_error "Unable to locate driver to use for device \"%s\"" "$1"
return 10
fi
# Load driver (if required)
if [ "${USBDRIVER}" = "${usbdriver}" ]; then
debug "Driver \"%s\" already attached to interface #%d of device \"%s\".\n" "${USBDRIVER}" "$2" "$1"
unset usbdriver
return 0
elif module_bind "${USBDRIVER}" "$1" "$2"; then
debug "Driver \"%s\" loaded for interface #%d of device \"%s\".\n" "${USBDRIVER}" "$2" "$1"
unset usbdriver
return 0
else
show_fmt_error "Unable to load driver \"%s\" for device \"%s\"" "${USBDRIVER}" "$1"
unset usbdriver
return 11
fi
}
modem_usb() {
unset MODEM_TTY
[ "a$1" = "a" ] && return 99
! usb_device_connected "$1" && debug "Device \"%s\" not found.\n" "$1" && return 7
export usbdevice="$1"
# Find appropriate interface, switching if required
modem_usb_detect_int "${usbdevice}"
ret=$?; [ "${ret}" -ne "0" ] && unset usbdevice && return ${ret}
# Check if device is switched
[ "a${NEWIDS}" != "a" ] && export usbdevice="${NEWIDS}"
# Load driver
modem_usb_fix_driver "${usbdevice}" "${USB_INTERFACE}"
ret=$?; [ "${ret}" -ne "0" ] && unset usbdevice && return ${ret}
# Locate tty
modem_usb_locate_tty "${usbdevice}" "${USB_INTERFACE}" "${USBDRIVER}"
ret=$?; [ "${ret}" -ne "0" ] && unset usbdevice && return ${ret}
if [ "a${USBTTY}" != "a" ]; then
if [ -c "${USBTTY}" ]; then
debug "Nothing more to do for setting it up device \"%s\".\n" "$1"
export MODEM_TTY="${USBTTY}"
return 0
fi
fi
unset USB_INTERFACE
unset USBTTY
unset MODEM_TTY
unset usbdevice
return 99
}
modem_bluetooth() {
unset MODEM_TTY
[ "a$1" = "a" -o "a$2" = "a" ] && return 99
debug "Attempting to setup bluetooth modem \"%s\" on channel \"%s\".\n" "$1" "$2"
bluetooth_setup_rfcomm "$1" "$2"
ret=$?
if [ "a${ret}" = "a0" ]; then
if [ "a${RFCOMM_TTY}" = "a" ]; then
debug "No RFCOMM tty returned.\n"
elif [ ! -c "${RFCOMM_TTY}" ]; then
debug "RFCOMM tty returned (%s), does exist.\n" "${RFCOMM_TTY}"
else
debug "Nothing more to do for setting it up %s(channel #%d).\n" "$1" "$2"
export MODEM_TTY="${RFCOMM_TTY}"
return 0
fi
fi
return 8
}
modem_custom() {
[ "a$1" = "a" ] && return 99
debug "Attempting to setup custom tty modem on \"%s\".\n" "$1"
if [ -c "$1" ]; then
debug "Custom tty \"%s\" exists. Nothing more to do for setting it up.\n" "$1"
export MODEM_TTY="$1"
return 0
else
debug "Custom tty \"%s\" does not exist. Unable to proceed.\n" "$1"
show_fmt_error "Device node \"%s\" does not exist. Setup failed." "$1"
unset MODEM_TTY
return 8
fi
}
modem_setup() {
unset MODEM_TTY
debug "Setting up modem.\n"
! we_are_root && return 3
[ "a${MODEM}" = "a" ] && ! flow_select_modem "$@" && return 98
if [ "a${MODEM}" = "aOTHER" ]; then
[ "a${OTHER}" = "a" ] && ! flow_other_modem "$@" && return 98
if [ "a${OTHER}" = "aUSBMODEM" ]; then
[ "a${USBMODEM}" = "a" ] && ! flow_usb_modem "$@" && return 98
if [ "a${USBMODEM}" != "a" ]; then
debug "Setting up USB modem %s.\n" "${USBMODEM}"
modem_usb "${USBMODEM}" "$@"
ret=$?
[ "a${usbdevice}" != "a" -a "a${usbdevice}" = "a${NEWIDS}" ] && export USBMODEM="${USBMODEM} ${usbdevice}"
return ${ret}
fi
elif [ "a${OTHER}" = "aBLUETOOTH" ]; then
[ "a${BLUETOOTH}" = "a" ] && ! flow_blue_modem "$@" && return 98
if [ "a${BLUETOOTH}" = "aUNDISCOVERABLE" ]; then
[ "a${UNDISCOVERABLE}" = "a" ] && ! flow_undiscoverable "$@" && return 98
if [ "a${UNDISCOVERABLE}" != "a" ]; then
[ "a${RFSERVICE}" = "a" ] && ! flow_rfchannel "$@" && return 98
if [ "a${RFSERVICE}" = "aRFCHANNEL" ]; then
[ "a${RFCHANNEL}" = "a" ] && ! flow_manual_rfcomm "$@" && return 98
if [ "a${RFCHANNEL}" != "a" ]; then
debug "Setting up Bluetooth modem %s on channel %s.\n" "${UNDISCOVERABLE}" "${RFCHANNEL}"
modem_bluetooth "${UNDISCOVERABLE}" "${RFCHANNEL}" "$@"
return $?
fi
elif [ "a${RFSERVICE}" != "a" ]; then
debug "Setting up Bluetooth modem %s on channel %s.\n" "${UNDISCOVERABLE}" "${RFSERVICE}"
modem_bluetooth "${UNDISCOVERABLE}" "${RFSERVICE}" "$@"
return $?
fi
fi
elif [ "a${BLUETOOTH}" != "a" ]; then
[ "a${RFSERVICE}" = "a" ] && ! flow_rfchannel "$@" && return 98
if [ "a${RFSERVICE}" = "aRFCHANNEL" ]; then
[ "a${RFCHANNEL}" = "a" ] && ! flow_manual_rfcomm "$@" && return 98
if [ "a${RFCHANNEL}" != "a" ]; then
debug "Setting up Bluetooth modem %s on channel %s.\n" "${BLUETOOTH}" "${RFCHANNEL}"
modem_bluetooth "${BLUETOOTH}" "${RFCHANNEL}" "$@"
return $?
fi
elif [ "a${RFSERVICE}" != "a" ]; then
debug "Setting up Bluetooth modem %s on channel %s.\n" "${BLUETOOTH}" "${RFSERVICE}"
modem_bluetooth "${BLUETOOTH}" "${RFSERVICE}" "$@"
return $?
fi
fi
elif [ "a${OTHER}" = "aCUSTOM_TTY" ]; then
[ "a${CUSTOM_TTY}" = "a" ] && ! flow_custom_tty "$@" && return 98
if [ "a${CUSTOM_TTY}" != "a" ]; then
debug "Setting up custom modem on %s.\n" "${CUSTOM_TTY}"
modem_custom "${CUSTOM_TTY}" "$@"
return $?
fi
fi
elif [ "a${MODEM}" != "a" ]; then
debug "Setting up USB modem %s.\n" "${MODEM}"
modem_usb "${MODEM}" "$@"
ret=$?
[ "a${usbdevice}" != "a" -a "a${usbdevice}" = "a${NEWIDS}" ] && export MODEM="${MODEM} ${usbdevice}"
return ${ret}
fi
debug "Failed to setup any modem.\n"
return 99
}
# Gets entries from file $1 that start with $2:$3
base_fetch() {
unset BASERESULT
[ "a$1" = "a" ] && return 1
[ "a${PROVIDER}" = "a" ] && debug "Unable to locate package provider.\n" && return 1
[ ! -x "${PROVIDER}" ] && debug "Unable to execute package provider.\n" && return 1
baseentries=`"${PROVIDER}" getfile "$1" | ${grepbin} -v "^#" | ${grepbin} -i "^$2:"`
if [ "a${baseentries}" = "a" ]; then
unset baseentries
debug "No information found for %s within %s database.\n" "$2" "$1"
return 1
fi
[ "a$3" != "a" ] && BASERESULT=`echo "${baseentries}" | ${grepbin} -i "^$2:$3:"`
[ "a${BASERESULT}" = "a" ] && BASERESULT=`echo "${baseentries}" | ${grepbin} -i "^$2::"`
export BASERESULT
unset baseentries
if [ "a${BASERESULT}" = "a" ]; then
unset BASERESULT
[ "a$3" != "a" ] && debug "No information found for \"%s:%s:\" within %s.\n" "$2" "$3" "$1"
[ "a$3" = "a" ] && debug "No default entry \"%s::\" found within %s.\n" "$2" "$1"
return 1
fi
debug "Loaded entries from %s:\n%s\n" "$1" "${BASERESULT}"
return 0
}
base_drivers() {
unset basedrivercandidates; unset baseintercandidates
[ "a$1" = "a" ] && return 1
! base_fetch "files/usb_devices.db" "$1" "$2" && return 1
[ "a${BASERESULT}" = "a" ] && return 1
BASERESULT=`echo "${BASERESULT}" | ${headbin} -1`
basedrivercandidates=`echo "${BASERESULT}" | ${cutbin} -f2 -s`
baseintercandidates=`echo "${BASERESULT}" | ${cutbin} -f3 -s`
[ "a${basedrivercandidates}" != "a" ] && debug "Device database indicates to use \"%s\" driver(s) for device %s.\n" "${basedrivercandidates}" "$1"
[ "a${baseintercandidates}" != "a" ] && debug "Device database indicates to use interface #%d for device %s.\n" "${baseintercandidates}" "$1"
unset BASERESULT
return 0
}
# Sets INIT_STAGES of modem $1 with optional name $2.
# Parses files/modem_init.db.
base_modem() {
unset INIT_STAGE0; unset INIT_STAGE1; unset INIT_STAGE2; unset INIT_STAGE3; unset INIT_STAGE4; unset INIT_STAGE5; unset INIT_STAGE6; unset INIT_STAGE7; unset INIT_STAGE8;
[ "a$1" = "a" -a "a$2" = "a" ] && return 1
! base_fetch "files/modem_init.db" "$1" "$2" && return 1
[ "a${BASERESULT}" = "a" ] && return 1
BASERESULT=`echo "${BASERESULT}" | ${headbin} -1`
for item in 0 1 2 3 4 5 6 7 8
do
plusone=`expr ${item} + 1`; plusone=`echo ${plusone}`
if [ "${item}" -le "7" -a "${item}" -ge "1" ]; then
contents=`${printfbin} "%s\n" "${BASERESULT}" | ${cutbin} -f${plusone}`
elif [ "${item}" -eq "8" ]; then
contents=`${printfbin} "%s\n" "${MODEM_INIT}"`
elif [ "${item}" -eq "0" ]; then
contents=`${printfbin} "%s\n" "${MODEM_PREPARE}"`
fi
if [ "a${contents}" != "a" ]; then
replacement=`${printfbin} "%s\n" "${contents}" | ${sedbin} -e "s/AT/\\nAT/g" | ${sedbin} -e "s/ *$//g" | ${grepbin} -v "^$" | ${grepbin} "^AT" | ${sedbin} -e "s/^\(.*\)$/\\\'\1\\\' OK/g" | ${trbin} "\n" " "`
eval "INIT_STAGE${item}=\${replacement}"
eval export INIT_STAGE${item}
unset replacement
if [ "a$1" != "a" ]; then
if [ "a$2" != "a" ]; then
debug "Loaded INIT Stage #%d for %s(%s): %s\n" "${item}" "$1" "$2" "`eval echo \\"\\${INIT_STAGE${item}}\\"`"
else
debug "Loaded INIT Stage #%d for %s: %s\n" "${item}" "$1" "`eval echo \\"\\${INIT_STAGE${item}}\\"`"
fi
else
debug "Loaded INIT Stage #%d for %s: %s\n" "${item}" "$2" "`eval echo \\"\\${INIT_STAGE${item}}\\"`"
fi
else
eval unset INIT_STAGE${item}
fi
unset contents; unset plusone
done
debug run_command "set | ${grepbin} \"^INIT_STAGE\""
unset item
return 0
}
# Sets NETINFO of ISP $1 with optional name $2. If $1==$ISPID sets ISP_ fields also
# Parses files/operators.db.
base_net() {
unset NETINFO
[ "a$1" = "a" ] && return 1
! base_fetch "files/operators.db" "$1" "$2" && return 1
[ "a${BASERESULT}" = "a" ] && return 1
BASERESULT=`echo "${BASERESULT}" | ${headbin} -1`
ISP_NAME=`echo "${BASERESULT}" | ${cutbin} -f2`
ISP_PRODUCT=`echo "${BASERESULT}" | ${cutbin} -f3`
ISP_FGCOLOR=`echo "${BASERESULT}" | ${cutbin} -f4`
ISP_BGCOLOR=`echo "${BASERESULT}" | ${cutbin} -f5`
ISP_DIAL=`echo "${BASERESULT}" | ${cutbin} -f6`
ISP_APNS=`echo "${BASERESULT}" | ${cutbin} -f7 | ${trbin} " " "\n"`
ISP_ICON=`echo "${BASERESULT}" | ${cutbin} -f8`
export ISP_NAME
export ISP_PRODUCT
export ISP_FGCOLOR
export ISP_BGCOLOR
export ISP_DIAL
export ISP_APNS
export ISP_ICON
return 0
}
# Gathers information about ISP $1 with optional name $2
net_info() {
[ "a$1" != "a" ] && base_net "$@"
[ "a$1" != "a${ISPID}" -a "a$1" != "a" ] && return 0
[ "a${ISP_NAME}" = "a" ] && export ISP_NAME="${ISPNAME}"
[ "a${ISP_NAME}" = "a" ] && export ISP_NAME="Unknown operator ${ISPID}"
[ "a${ISPNAME}" = "a${ISPID}" -o "a${ISPNAME}" = "a" ] && export ISPNAME="${ISP_NAME}"
[ "a${ISPNAME}" = "a${ISPID}" -o "a${ISPNAME}" = "a" ] && export ISPNAME="${ISP_NAME}"
export ISPTEXT="${ISPNAME}"
[ "a${ISP_PRODUCT}" = "a" ] && export ISP_PRODUCT="${ISP_NAME} Internet"
[ "a${ISP_FGCOLOR}" = "a" ] && export ISP_FGCOLOR="ffffff"
[ "a${ISP_BGCOLOR}" = "a" ] && export ISP_BGCOLOR="000000"
[ "a${ISP_DIAL}" = "a" ] && export ISP_DIAL="*99#"
[ "a${ISP_ICON}" = "a" ] && export ISP_ICON="files/sakis3g.png"
if [ "a${CUSTOM_DIAL}" != "a" -a "a${CUSTOM_DIAL}" != "a${ISP_DIAL}" ]; then
debug "Will dial \"%s\" specified by user instead of \"%s\" found in database.\n" "${CUSTOM_DIAL}" "${ISP_DIAL}"
export ISP_DIAL="${CUSTOM_DIAL}"
fi
debug "ISPID: %s / ISPNAME: %s / ISPTEXT: %s\n" "${ISPID}" "${ISPNAME}" "${ISPTEXT}"
return 0
}
# Select a device interface
flow_select_interface() {
usbinterfaces=`echo "$2" | ${trbin} " " "\n" | ${sedbin} -e "s/^\(.*\)$/\"\1\" \"Interface #\1\"/g" | ${trbin} "\n" " "`
eval user_select \"USBINTERFACE\" \"Please appropriate interface\" \"Select modem interface of USB device that provides modem capabilities.\" \"Select\" \"Cancel\" ${usbinterfaces}
case "$?" in
0)
unset usbinterfaces
return 98
;;
98)
unset usbinterfaces
return 98
;;
99)
unset usbinterfaces
return 99
;;
*)
unset usbinterfaces
return 0
;;
esac
return 99
}
# Makes sure one USB modem exists
flow_usb_modem() {
usb_connected_devices
usbmodems=`echo "${usb_devices}" | ${sedbin} -e "s/^\(....\):\(....\):\(.*\)$/\"\1:\2\" \"\3\"/g"`
eval user_select \"USBMODEM\" \"Please select USB modem\" \"Select USB device that provides modem capabilities.\" \"Select\" \"Cancel\" ${usbmodems}
case "$?" in
0)
unset usbmodems
return 98
;;
98)
unset usbmodems
return 98
;;
99)
unset usbmodems
return 99
;;
*)
unset usbmodems
usb_connected_devices
usbmodems=`echo "${usb_devices}" | ${sedbin} -e "s/^\(....\):\(....\):\(.*\)$/ \1:\2 /g" | ${grepbin} " ${USBMODEM} "`; usbmodems=`echo ${usbmodems}`
if [ "a${usbmodems}" = "a${USBMODEM}" ]; then
debug "User selected USB modem \"%s\".\n" "${USBMODEM}"
unset usbmodems
return 0
else
debug "USB modem \"%s\" is not currently plugged.\n" "${USBMODEM}"
unset usbmodems; unset USBMODEM
flow_usb_modem "$@"
return "$?"
fi
;;
esac
return 99
}
flow_manual_rfcomm() {
user_prompt "RFCHANNEL" "Please enter RFCOMM channel" "Enter RFCOMM channel that should be used, or leave empty to abort [1-255]" "OK" "Cancel"
case "a${RFCHANNEL}" in
a)
return 98
;;
*)
RFCHANNEL=`${printfbin} "%d\n" "${RFCHANNEL}" 2> /dev/null`
[ "a$RFCHANNEL" = "a" ] && RFCHANNEL=0
[ "$RFCHANNEL" -gt "255" ] && RFCHANNEL=0
export RFCHANNEL
if [ "$RFCHANNEL" -eq "0" ]; then
unset RFCHANNEL
return 98
fi
return 0
;;
esac
}
flow_custom_tty() {
user_prompt "CUSTOM_TTY" "Please enter tty" "Enter tty node where your 3G modem resides, or leave empty to abort" "OK" "Cancel"
case "a${CUSTOM_TTY}" in
a)
unset CUSTOM_TTY
return 98
;;
*)
[ ! -c "${CUSTOM_TTY}" ] && [ -c "/dev/${CUSTOM_TTY}" ] && CUSTOM_TTY="/dev/${CUSTOM_TTY}"
[ ! -c "${CUSTOM_TTY}" ] && [ -c "/dev${CUSTOM_TTY}" ] && CUSTOM_TTY="/dev${CUSTOM_TTY}"
if [ ! -c "${CUSTOM_TTY}" ]; then
show_fmt_error "Device node \"%s\" does not exist.\n" "${CUSTOM_TTY}"
unset CUSTOM_TTY
flow_custom_tty "$@"
return $?
else
debug "Using device node \"%s\".\n" "${CUSTOM_TTY}"
export CUSTOM_TTY
return 0
fi
;;
esac
}
flow_rfchannel() {
[ "a${BLUETOOTH}" = "a" ] && ! flow_blue_modem "$@" && return $?
if [ "a${RFSERVICE}" = "aRFCHANNEL" ]; then
if ! flow_manual_rfcomm; then
unset RFSERVICE
flow_rfchannel "$@"
return "$?"
fi
return 0
fi
verbose "Seeking %s" "${BLUETOOTH}"
if bluetooth_rfcomm_channel "${BLUETOOTH}" "DUN"; then
debug "No DUN rfcomm channels returned from \"%s\".\n" "${BLUETOOTH}"
bluetooth_rfcomm_channel "${BLUETOOTH}" "SP"
rfchannels=`echo "${rfchannel}" | ${sedbin} -e "s/^\([0-9][0-9]*\)$/\"\1\" \"Serial Port from RFCOMM channel #\1\"/g"`
else
rfchannels=`echo "${rfchannel}" | ${sedbin} -e "s/^\([0-9][0-9]*\)$/\"\1\" \"Dialup Networking from RFCOMM channel #\1\"/g"`
bluetooth_rfcomm_channel "${BLUETOOTH}" "SP"
rfchannels="${rfchannels} `echo \"${rfchannel}\" | ${sedbin} -e \"s/^\\\([0-9][0-9]*\\\)$/\\\"\\\1\\\" \\\"Serial Port from RFCOMM channel #\\\1\\\"/g\"`"
fi
eval user_select \"RFSERVICE\" \"Please select RFCOMM service\" \"Select RFCOMM service of Bluetooth device that provides 3G modem capabilities.\" \"Select\" \"Cancel\" \"RESCAN\" \"Scan device again\" ${rfchannels} \"RFCHANNEL\" \"Manually enter non-discovered channel...\"
case "$?" in
0)
unset rfchannels
return 98
;;
98)
unset rfchannels
return 98
;;
99)
unset rfchannels
return 99
;;
*)
unset rfchannels
case "a${RFSERVICE}" in
aRESCAN)
unset RFSERVICE
flow_rfchannel "$@"
return "$?"
;;
aRFCHANNEL)
if ! flow_manual_rfcomm; then
unset RFSERVICE
flow_rfchannel "$@"
return "$?"
fi
return 0
;;
*)
export RFCHANNEL="${RFSERVICE}"
return 0
;;
esac
;;
esac
return 99
}
# Makes sure one UNDISCOVERABLE BLUETOOTH modem exists
flow_undiscoverable() {
user_prompt "UNDISCOVERABLE" "Enter Bluetooth address" "Enter Bluetooth address of undiscoverable device, or leave empty to abort" "OK" "Cancel"
case "a${UNDISCOVERABLE}" in
a)
return 98
;;
*)
export BLUETOOTH="${UNDISCOVERABLE}"
if ! flow_rfchannel; then
unset UNDISCOVERABLE; unset BLUETOOTH
return 98
fi
export BLUETOOTH="UNDISCOVERABLE"
return 0
;;
esac
}
# Makes sure one BLUETOOTH modem exists
flow_blue_modem() {
if [ "a${BLUETOOTH}" = "aUNDISCOVERABLE" ]; then
if ! flow_undiscoverable; then
unset BLUETOOTH
flow_blue_modem "$@"
return "$?"
fi
return 0
fi
bluetooth_scan_devices
bluemodems=`echo "${bluetooth_devices}" | ${sedbin} -e "s/^\(.*\) \(.*\)$/\"\1\" \"\2 (\1)\"/g"`
eval user_select \"BLUETOOTH\" \"Please select Bluetooth device\" \"Select Bluetooth device that provides 3G modem capabilities.\" \"Select\" \"Cancel\" \"RESCAN\" \"Scan devices again\" ${bluemodems} \"UNDISCOVERABLE\" \"Manually enter undiscoverable device...\"
case "$?" in
0)
unset bluemodems
return 98
;;
98)
unset bluemodems
return 98
;;
99)
unset bluemodems
return 99
;;
*)
unset bluemodems
case "a${BLUETOOTH}" in
aRESCAN)
unset BLUETOOTH
flow_blue_modem "$@"
return "$?"
;;
aUNDISCOVERABLE)
if ! flow_undiscoverable; then
unset BLUETOOTH
flow_blue_modem "$@"
return "$?"
fi
return 0
;;
*)
if ! flow_rfchannel; then
unset BLUETOOTH
flow_blue_modem "$@"
return "$?"
fi
return 0
;;
esac
;;
esac
return 99
}
# Makes sure one other modem is selected
flow_other_modem() {
user_select "OTHER" "Please select modem type" "Select modem category that best fits your 3G modem." "Select" "Cancel" "USBMODEM" "USB device" "BLUETOOTH" "Bluetooth modem" "CUSTOM_TTY" "Custom tty..."
case "$?" in
0)
return 98
;;
98)
return 98
;;
99)
return 99
;;
*)
case "a${OTHER}" in
aUSBMODEM)
if ! flow_usb_modem; then
unset OTHER
flow_other_modem "$@"
return "$?"
fi
return 0
;;
aBLUETOOTH)
if ! flow_blue_modem; then
unset OTHER
flow_other_modem "$@"
return "$?"
fi
return 0
;;
aCUSTOM_TTY)
if ! flow_custom_tty; then
unset OTHER
flow_other_modem "$@"
return "$?"
fi
return 0
;;
*)
return 99
;;
esac
;;
esac
return 99
}
# Makes sure one selected modem exists
flow_select_modem() {
verbose "Locating device"
usb_connected_modems
modems=`echo "${usb_modem_devices}" | ${sedbin} -e "s/^\(....\):\(....\):\(.*\)$/\"\1:\2\" \"\3\"/g"`
if [ "a${modems}" != "a" ]; then
modemscount=`echo "${usb_modem_devices}" | ${wcbin} -l`; modemscount=`echo ${modemscount}`
if [ "a${modemscount}" = "a1" -a "a${MODEM}" = "a" ]; then
MODEM=`echo "${usb_modem_devices}" | ${headbin} -1 | ${sedbin} -e "s/^\(....\):\(....\):\(.*\)$/\1:\2/g"`
export MODEM
debug "Autoselecting unique USB modem plugged: %s\n" "${MODEM}"
ret=1
else
eval user_select \"MODEM\" \"Please select modem\" \"Select modem that will be used for establishing 3G connection.\" \"Select\" \"Cancel\" ${modems} \"OTHER\" \"Other...\"
# in
ret=$?
fi
unset modemscount
else
export MODEM="OTHER"
ret=97
fi
case "${ret}" in
0)
return 98
;;
98)
return 98
;;
99)
return 99
;;
*)
case "a${MODEM}" in
aOTHER)
if [ "${ret}" -eq "97" ]; then
flow_other_modem "$@"
ret=$?
[ "${ret}" -ne "0" ] && unset MODEM
return ${ret}
else
if ! flow_other_modem "$@"; then
unset MODEM
flow_select_modem "$@"
return "$?"
fi
fi
return 0
;;
a)
return 98
;;
*)
return 0
;;
esac
return 99
;;
esac
return 0
}
flow_custom_apn() {
user_prompt "CUSTOM_APN" "Please enter APN" "Enter correct APN, or leave empty to abort. Contact your operator if unsure" "OK" "Cancel"
case "a${CUSTOM_APN}" in
a)
unset CUSTOM_APN
return 98
;;
*)
export CUSTOM_APN
return 0
;;
esac
}
# Makes selected APN exists
flow_select_apn() {
net_info "${ISPID}" "${ISPNAME}"
[ "a${FORCE_APN}" != "a" ] && export ISP_APNS="${FORCE_APN}"
[ "a${ISP_APNS}" = "a" ] && tty_detect_apn && export ISP_APNS="${MODEM_APN}"
if [ "a${ISP_APNS}" != "a" -a "a${FORCE_APN}" = "a" ]; then
apnoptions=""
for apnoption in ${ISP_APNS}
do
apnname=`echo "${apnoption}" | ${cutbin} -d: -f1 -s`
if [ "a${apnname}" = "a" ]; then
apnname="${apnoption}"
apndesc="${apnoption}"
apnuser="" ; apnpass=""
else
apndesc=`echo "${apnoption}" | ${cutbin} -d: -f2 | ${sedbin} -e "s/_/ /g"`
apndesc="${apndesc} (${apnname})"
apnuser=`echo "${apnoption}" | ${cutbin} -d: -f3`
apnpass=`echo "${apnoption}" | ${cutbin} -d: -f4`
fi
if [ "a${apnname}" = "a${MODEM_APN}" -a "a${MODEM_APN}" != "a" ]; then
apndesc=`format_text "Reported by your modem (%s)" "${apnname}"`
fi
apnoptions="${apnoptions} \"${apnname}\" \"${apndesc}\""
unset apnname; unset apndesc; unset apnuser; unset apnpass
done
unset apnoption
eval user_select \"APN\" \"Please select APN\" \"Select APN that best describes your connection. Contact your operator if unsure. This information, along with APN username and password, is usually easily retrieved through a fast call to customer support\" \"Select\" \"Cancel\" ${apnoptions} \"CUSTOM_APN\" \"Custom APN...\"
ret=$?
unset apnoptions
elif [ "a${FORCE_APN}" != "a" ]; then
debug "Selected APN by FORCE_APN: %s\n" "${FORCE_APN}"
APN=`echo "${FORCE_APN}" | ${cutbin} -d: -f1`
export APN
ret=1
else
export APN="CUSTOM_APN"
ret=97
fi
case "${ret}" in
0)
return 98
;;
98)
return 98
;;
99)
return 99
;;
*)
case "a${APN}" in
aCUSTOM_APN)
if [ "${ret}" -eq "97" ]; then
if ! flow_custom_apn "$@"; then
unset APN
return 98
fi
else
if ! flow_custom_apn "$@"; then
unset APN
flow_select_apn "$@"
return "$?"
fi
fi
return 0
;;
a)
return 98
;;
*)
APN=`echo "${ISP_APNS}" | ${grepbin} "^${APN}\(:*\)" | ${cutbin} -d: -f1`
export APN
if [ "a${APN}" = "a" ]; then
unset APN
flow_select_apn "$@"
return "$?"
else
apnuser=`echo "${ISP_APNS}" | ${grepbin} "^${APN}\(:*\)" | ${cutbin} -d: -f3 -s`
[ "a${apnuser}" != "a" -a "a${APN_USER}" = "a" ] && export APN_USER="${apnuser}"
apnpass=`echo "${ISP_APNS}" | ${grepbin} "^${APN}\(:*\)" | ${cutbin} -d: -f4 -s`
[ "a${apnuser}" != "a" -a "a${APN_PASS}" = "a" ] && export APN_PASS="${apnpass}"
unset apnuser; unset apnpass
fi
return 0
;;
esac
return 99
;;
esac
return 0
}
flow_apn_user() {
[ "a${APN}" = "a" ] && return 98
if [ "a${APN_USER}" = "a" ]; then
if [ "a${APN}" != "a" ]; then
if [ "a${APN}" = "aCUSTOM_APN" -a "a${CUSTOM_APN}" != "a" ]; then
APN_USER=`echo "${CUSTOM_APN}" | ${cutbin} -d: -s -f3`
else
APN_USER=`echo "${APN}" | ${cutbin} -d: -s -f3`
fi
fi
fi
[ "a${APN_USER}" = "a" ] && unset APN_USER
if [ "a${APN}" = "aCUSTOM_APN" -a "a${CUSTOM_APN}" != "a" ]; then
apntitle=`echo "${CUSTOM_APN}" | ${cutbin} -d: -f1`
elif [ "a${APN}" != "a" ]; then
apntitle=`echo "${APN}" | ${cutbin} -d: -f1`
fi
user_prompt "APN_USER" "APN: ${apntitle}" "Enter username required by APN, or leave empty to abort. Contact your operator if unsure. This information, along with APN password, is usually easily retrieved through a fast call to customer support" "OK" "Cancel"
case "a${APN_USER}" in
a)
unset APN_USER
return 98
;;
*)
export APN_USER
return 0
;;
esac
}
flow_apn_pass() {
[ "a${APN}" = "a" ] && return 98
if [ "a${APN_PASS}" = "a" ]; then
if [ "a${APN}" != "a" ]; then
if [ "a${APN}" = "aCUSTOM_APN" -a "a${CUSTOM_APN}" != "a" ]; then
APN_PASS=`echo "${CUSTOM_APN}" | ${cutbin} -d: -s -f4`
else
APN_PASS=`echo "${APN}" | ${cutbin} -d: -s -f4`
fi
fi
fi
[ "a${APN_PASS}" = "a" ] && unset APN_PASS
if [ "a${APN}" = "aCUSTOM_APN" -a "a${CUSTOM_APN}" != "a" ]; then
apntitle=`echo "${CUSTOM_APN}" | ${cutbin} -d: -f1`
elif [ "a${APN}" != "a" ]; then
apntitle=`echo "${APN}" | ${cutbin} -d: -f1`
fi
user_prompt "APN_PASS" "APN: ${apntitle}" "Enter password required by APN, or leave empty to abort. Contact your operator if unsure. This information is usually easily retrieved through a fast call to customer support" "OK" "Cancel"
case "a${APN_PASS}" in
a)
unset APN_PASS
return 98
;;
*)
export APN_PASS
return 0
;;
esac
}
flow_switch() {
flow_select_modem "$@"
ret=$?; [ "${ret}" -ne "0" ] && return ${ret}
unset NEWIDS
if modeswitch_is_switchable "${MODEM}" && usb_device_connected "${MODEM}"; then
modeswitch_switch "${MODEM}"
ret=$?
if [ "a${NEWIDS}" != "a" -a "a${NEWIDS}" != "a${MODEM}" ]; then
debug "Device changed ID. From \"%s\" to \"%s\".\n" "${MODEM}" "${NEWIDS}"
export MODEM="${NEWIDS}"
fi
localdev="${MODEM}"
elif modeswitch_is_switchable "${USBMODEM}" && usb_device_connected "${USBMODEM}"; then
modeswitch_switch "${USBMODEM}"
ret=$?
if [ "a${NEWIDS}" != "a" -a "a${NEWIDS}" != "a${USBMODEM}" ]; then
debug "Device changed ID. From \"%s\" to \"%s\".\n" "${USBMODEM}" "${NEWIDS}"
export USBMODEM="${NEWIDS}"
fi
localdev="${USBMODEM}"
else
debug "Currently selected modem cannot be switched. No need to switch anything.\n"
return 0
fi
# Should normally unlock HAL here. But we don't.
# If we will stay within program, it will get unlocked during driver setup.
# If stand-alone action, exit trap will unlock it.
# So, line below should be commented out.
#hal_unlock
return ${ret}
}
flow_setup() {
flow_select_modem "$@"
ret=$?; [ "${ret}" -ne "0" ] && return ${ret}
if modem_setup "$@"; then
debug "Modem is now setup and resides on %s.\n" "${MODEM_TTY}"
return 0
else
return $?
fi
}
flow_prepare() {
flow_setup "$@"
ret=$?; [ "${ret}" -ne "0" ] && return ${ret}
if tty_prepare "${MODEM_TTY}" "$@"; then
debug "Device %s is now prepared and registered to %s.\n" "${MODEM_TTY}" "${ISPTEXT}"
else
return $?
fi
}
pppd_config() {
need_binary "pppd"
need_arg "PPPD_OPTIONS"; need_arg "BAUD"
unset CONNECTION_CONF; unset CONNECTION_COMMAND
${touchbin} "/tmp/pppd.tmp.$$"
if [ ! -w "/tmp/pppd.tmp.$$" ]; then
show_fmt_error "Unable to create temporary pppd config file within %s directory.\n" "/tmp"
return 99
fi
CONNECTION_CONF="/tmp/pppd.tmp.$$"
find_binary "chmod" && ${chmodbin} 600 "${CONNECTION_CONF}"
${catbin} > "${CONNECTION_CONF}" <<endl
ABORT "NO CARRIER"
ABORT "NO DIALTONE"
ABORT "BUSY"
ABORT "ERROR"
ABORT "NO ANSWER"
"" ATZ
endl
#initstrings=`echo "${INIT_COMMANDS}" "ATDT${ISP_DIAL}" | ${sedbin} -e "s/AT/\\nAT/g" | ${grepbin} "^AT" | ${sedbin} -e "s/ *$//g" | ${grepbin} -v "^$" | ${sedbin} -e "s/^\(.*\)$/OK '\1'/g"`
initstrings=`echo "${DIAL_COMMANDS}" | ${sedbin} -e "s/AT/\\nAT/g" | ${grepbin} "^AT" | ${sedbin} -e "s/ *$//g" | ${grepbin} -v "^$" | ${sedbin} -e "s/^\(.*\)$/OK '\1'/g"`
debug "Init strings are:\n%s\n" "${initstrings}"
echo "${initstrings}" >> "${CONNECTION_CONF}"
unset initstrings
if [ ! -s "${CONNECTION_CONF}" ]; then
${rmbin} -f "${CONNECTION_CONF}"
show_fmt_error "Failure to write on %s.\n" "${CONNECTION_CONF}"
unset CONNECTION_CONF
return 99
fi
debug "Config file that will be used is: \"%s\".\n" "${CONNECTION_CONF}"
debug show_file "${CONNECTION_CONF}"
pppdoptions="${PPPD_OPTIONS}"
[ "a${pppdoptions}" = "a" ] && pppdoptions="modem crtscts -detach defaultroute dump noipdefault usepeerdns usehostname ktune logfd 2 noauth name sakis3g lock maxfail 3"
if [ "a${PPPD_PEERS}" != "a" ]; then
if [ -d "${PPPD_PEERS}" ]; then
if [ -f "${PPPD_PEERS}/sakis3g" ]; then
debug "Found peers file %s.\n" "${PPPD_PEERS}/sakis3g"
pppdoptions="-detach dump logfd 2 name sakis3gpeer maxfail 3 call sakis3g"
fi
fi
fi
export CONNECTION_COMMAND="${setsidbin} ${pppdbin} ${MODEM_TTY} ${BAUD} ${pppdoptions} connect \"${chatbin} -v -f ${CONNECTION_CONF}\" user \"${APN_USER}\" password \"${APN_PASS}\""
unset pppdoptions
debug "Connection command that will be used is: %s\n" "${CONNECTION_COMMAND}"
return 0
}
wvdial_config() {
need_binary "wvdial"
need_arg "BAUD"
unset CONNECTION_CONF; unset CONNECTION_COMMAND
${touchbin} "/tmp/wvdial.tmp.$$"
if [ ! -w "/tmp/wvdial.tmp.$$" ]; then
show_fmt_error "Unable to create temporary wvdial config file within %s directory.\n" "/tmp"
return 99
fi
CONNECTION_CONF="/tmp/wvdial.tmp.$$"
find_binary "chmod" && ${chmodbin} 600 "${CONNECTION_CONF}"
${catbin} > "${CONNECTION_CONF}" <<endl
[Dialer Defaults]
Modem = ${MODEM_TTY}
Modem Type = Analog Modem
ISDN = 0
Baud = ${BAUD}
Dial Attempts = 3
Username = ${APN_USER}
Password = ${APN_PASS}
Phone = ${ISP_DIAL}
Auto Reconnect = off
Stupid Mode = 1
endl
echo "Init1 = ATZ" >> "${CONNECTION_CONF}"
if [ ! -s "${CONNECTION_CONF}" ]; then
${rmbin} -f "${CONNECTION_CONF}"
show_fmt_error "Failure to write on %s.\n" "${CONNECTION_CONF}"
unset CONNECTION_CONF
return 99
fi
debug "Config file that will be used is: \"%s\".\n" "${CONNECTION_CONF}"
debug show_file "${CONNECTION_CONF}"
export CONNECTION_COMMAND="${setsidbin} ${wvdialbin} --config \"${CONNECTION_CONF}\""
debug "Connection command that will be used is: %s\n" "${CONNECTION_COMMAND}"
return 0
}
ispconnect() {
[ "a${CONNECTION_COMMAND}" = "a" ] && return 95
if ppp_fast_status; then
debug "Already connected.\n"
return 0
fi
! we_are_root && return 1
debug run_command "${rmbin} -f \"/tmp/sakis3g.3gnet\""
! tty_not_busy "${MODEM_TTY}" && return 1
if [ "a$1" = "anoretry" ]; then
verbose "Connecting (second attempt)"
else
verbose "Connecting"
fi
logpid=0
if [ -n "${DEBUG}" ]; then
eval "${CONNECTION_COMMAND} &"
logpid=$!
else
eval "${CONNECTION_COMMAND} <&- >&- 2>&- &"
logpid=$!
fi
passed=0
while ! notrunning "${logpid}"
do
ppp_slow_status && break
debug "Waiting for interface to go up (%d seconds passed).\n" "${passed}"
passed=`expr ${passed} + 1`; passed=`echo ${passed}`
if [ "a${passed}" = "a21" ]; then
debug "Giving up waiting for connection to occur.\n"
if find_binary "kill"; then
${killbin} -1 ${logpid} 2> /dev/null
! notrunning "${logpid}" && sleep 1
! notrunning "${logpid}" && sleep 1
fi
break
fi
sleep 1
done
if notrunning "${logpid}" && [ "a$1" != "anoretry" ]; then
unset logpid
ispconnect "noretry"
return $?
fi
unset passed
if ! ppp_slow_status; then
debug "Failed to connect.\n"
unset logpid
return 95
fi
debug "Connection is established.\n"
${printfbin} "%s\n%s\n%s\n%s\n%s\n%s\n%s\n%s\n%s\n%s\n%s\n%s\n" "${ISPID}" "${ISPTEXT}" "${MODEM_VARIANT}" "${USBDRIVER}" "${MODEM_TTY}" "${MODEM}" "${OTHER}" "${APN}" "${CUSTOM_APN}" "${APN_USER}" "${APN_PASS}" "${logpid}" > "/tmp/sakis3g.3gnet"
[ -f "/tmp/sakis3g.3gnet" ] && ${chmodbin} 644 "/tmp/sakis3g.3gnet"
unset logpid
return 0
}
# Deletes all currently existing default gateways.
routing_delete_gateways() {
! we_are_root && return 1
! find_binary "netstat" && return 1
! find_binary "route" && return 1
while [ "1" = "1" ];
do
gatehost=`${netstatbin} -rn | ${grepbin} "^0.0.0.0 " | ${tailbin} -1 | ${sedbin} -e "s/ */ /g" | ${cutbin} -d\ -f2`
if [ "a${gatehost}" != "a" ]; then
debug "Deleting default gateway %s.\n" "${gatehost}"
debug run_command "${routebin} del default gw ${gatehost}"
else
debug "Deleted all default gateways.\n"
break
fi
done
unset gatehost
return 0
}
# Makes sure only our pppint(ppp0) peer is used as default gateway.
routing_fix() {
! find_binary "netstat" && return 1
! find_binary "route" && return 1
need_arg "pppint"
hostpeer=`${netstatbin} -rn | ${grepbin} " ${pppint}$" | ${grepbin} -v "^0.0.0.0 " | ${cutbin} -d\ -f1`
if [ "a${hostpeer}" != "a" ]; then
routing_delete_gateways
debug run_command "${routebin} add default gw ${hostpeer}"
debug "Added correct default gateway: %s.\n" "${hostpeer}"
debug run_command "${netstatbin} -rn"
fi
unset hostpeer
return 0
}
dns_fix() {
debug "Checking if required to fix DNS settings.\n"
unset needdnsfix
if [ ! -f "/etc/resolv.conf" ]; then
needdnsfix=1
debug "No %s exists. Will make it ourselves.\n" "/etc/resolv.conf"
else
debug show_file "/etc/resolv.conf"
baddns=`${grepbin} "10.11.12.13" "/etc/resolv.conf" | ${wcbin} -l`; baddns=`echo ${baddns}`
[ "a${baddns}" = "a0" ] && baddns=`${grepbin} "10.11.12.14" "/etc/resolv.conf" | ${wcbin} -l`
baddns=`echo ${baddns}`
if [ "a${baddns}" != "a0" ]; then
needdnsfix=1
debug "File %s contains bad DNS servers. Will fix it.\n" "/etc/resolv.conf"
fi
unset baddns
fi
if [ "a${DNS}" != "a" ]; then
needdnsfix=1
debug "Will fix DNS due to DNS servers being set: %s\n" "${DNS}"
fi
if [ "a${needdnsfix}" != "a1" ]; then
debug "No need to fix DNS servers. Skipping it.\n"
unset needdnsfix
return 0
fi
if [ "a${DNS}" = "a" ]; then
debug "No DNS servers where set. Will use Google DNS.\n"
export DNS="8.8.8.8 8.8.4.4"
fi
${rmbin} -f "/etc/resolv.conf"
${touchbin} "/etc/resolv.conf"
${chmodbin} 644 "/etc/resolv.conf"
for dnsserver in ${DNS}
do
${printfbin} "nameserver %s\n" "${dnsserver}" >> "/etc/resolv.conf"
debug "Added name server %s to %s.\n" "${dnsserver}" "/etc/resolv.conf"
done
unset dnsserver
${printfbin} "\n# This file was autogenerated by %s.\n\n" "Sakis3G script" >> "/etc/resolv.conf"
debug "Done setting up custom DNS server(s).\n"
return 0
}
flow_post_connection() {
if [ "a${NOSMART}" != "a" ]; then
debug "Requested not to smart-fix connection.\n"
return 0
fi
verbose "Fixing connection"
debug "Running post-connection setup.\n"
routing_fix
dns_fix
}
flow_connect() {
ppp_fast_status && return 0
flow_prepare "$@"
ret=$?; [ "${ret}" -ne "0" ] && return ${ret}
verbose "Resolving connection details"
flow_select_apn "$@"
ret=$?; [ "${ret}" -ne "0" ] && return ${ret}
flow_apn_user "$@"
ret=$?; [ "${ret}" -ne "0" ] && return ${ret}
flow_apn_pass "$@"
ret=$?; [ "${ret}" -ne "0" ] && return ${ret}
[ "a${MODEM_TTY}" = "a" ] && return 99
[ ! -c "${MODEM_TTY}" ] && return 99
[ "a${APN}" = "a" -o "a${APN_USER}" = "a" -o "a${APN_PASS}" = "a" -o "a${ISP_DIAL}" = "a" ] && return 99
! at_default_commands "DIAL" && return 99
[ "a${ttycommands}" = "a" ] && return 99
export DIAL_COMMANDS="${ttycommands}"
if [ "a${direct_pppd}" != "a" ]; then
pppd_config "$@"
ret=$?
else
wvdial_config "$@"
ret=$?
fi
unset DIAL_COMMANDS
[ "${ret}" -ne "0" ] && return ${ret}
verbose "Initializing modem"
tty_send_command "${MODEM_TTY}" "INITIALIZE"
ret=$?; [ "${ret}" -ne "0" ] && return ${ret}
tty_send_command "${MODEM_TTY}" "STAGE7"
tty_send_command "${MODEM_TTY}" "STAGE8"
ispconnect "$@"
ret=$?
[ "a${CONNECTION_CONF}" != "a" ] && [ -f "${CONNECTION_CONF}" ] && ${rmbin} -f "${CONNECTION_CONF}"
unset CONNECTION_CONF; unset CONNECTION_COMMAND
[ "${ret}" -ne "0" ] && return ${ret}
flow_post_connection "$@"
if [ "a${CONNECTION_HOOK}" != "a" ]; then
debug "Will now execute CONNECTION_HOOK: %s.\n" "${CONNECTION_HOOK}"
term_clearline
debug run_command "${CONNECTION_HOOK}"
debug "Connection hook returned.\n"
fi
! ppp_slow_status && return 99
return ${ret}
}
flow_disconnect() {
! ppp_fast_status && return 0
! we_are_root && return 1
verbose "Disconnecting"
if find_binary "killall"; then
${killallbin} -q -1 pppd
sleep 1
ppp_fast_status && ${killallbin} -q -9 pppd
elif find_binary "ps" && find_binary "kill"; then
ppppid=`${psbin} -C "pppd" -o pid= 2> /dev/null | ${grepbin} -i "PID"`; ppppid=`echo ${ppppid}`
for propid in ${ppppid}
do
debug run_command "kill -1 ${propid}"
done
ppppid=`${psbin} -C "pppd" -o pid= 2> /dev/null | ${grepbin} -i "PID"`; ppppid=`echo ${ppppid}`
for propid in ${ppppid}
do
debug run_command "kill -9 ${propid}"
done
unset ppppid; unset propid
else
show_fmt_error "Unable to stop running pppd session. Both %s and % were not found.\n" "kill" "killall"
return 1
fi
sleep 1
if ppp_fast_status; then
debug "Failed to disconnect.\n"
return 1
fi
debug "Disconnected.\n"
return 0
}
compile_check_local_requirements() {
if [ "a${PROVIDER}" = "a" ]; then
show_fmt_error "Not running from within package.\n"
return 1
fi
if [ ! -x "${PROVIDER}" ]; then
show_fmt_error "Reported package location is not executable: %s\n" "${PROVIDER}"
return 1
fi
if [ ! -w "${PROVIDER}" ] && we_are_root; then
show_fmt_error "Unable to overwrite existing package %s. Check if on read-only filesystem.\n" "${PROVIDER}"
return 1
fi
return 0
}
compile_check_dependencies() {
unset missing
for localdependency in bzip2 bunzip2 pwd basename dirname gcc tar dd stat cp chmod rm mkdir mv find rmdir printf grep expr ls sort uniq cut sed tr cat touch
do
! find_binary "${localdependency}" && missing="${missing} ${localdependency}"
done
missing=`echo ${missing}`
if [ "a${missing}" != "a" ]; then
show_fmt_error "Following dependencies not found within path: %s\n" "${missing}"
unset missing
return 1
fi
unset missing
return 0
}
compile_compilation_dependencies() {
[ "a${PROVIDER}" = "a" ] && return 1
[ ! -x "${PROVIDER}" ] && return 1
${rmbin} -f "/tmp/sakis3g.source.$$.combined.c" > /dev/null 2> /dev/null
${touchbin} "/tmp/sakis3g.source.$$.combined.c" > /dev/null 2> /dev/null
if [ ! -f "/tmp/sakis3g.source.$$.combined.c" ]; then
show_fmt_error "Unable to create file %s.\n" "/tmp/sakis3g.source.$$.combined.c"
return 1
fi
${PROVIDER} getfile usb_modeswitch.c 2> /dev/null > "/tmp/sakis3g.source.$$.c"
${PROVIDER} getfile usb_modeswitch.h 2> /dev/null > "/tmp/sakis3g.source.$$.h"
${catbin} "/tmp/sakis3g.source.$$.c" "/tmp/sakis3g.source.$$.h" > "/tmp/sakis3g.source.$$.combined.c"
if [ ! -s "/tmp/sakis3g.source.$$.combined.c" ]; then
${rmbin} -f "/tmp/sakis3g.source.$$.combined.c" "/tmp/sakis3g.source.$$.c" "/tmp/sakis3g.source.$$.h" > /dev/null 2> /dev/null
show_fmt_error "Unable to extract %s source from package.\n" "Usb-ModeSwitch"
return 1
fi
headerfiles=`${grepbin} "^#include <" "/tmp/sakis3g.source.$$.combined.c" | ${sedbin} -e "s/\( *\)/ /g" | ${cutbin} -d\ -f2 -s | ${sedbin} -e "s/^<\(.*\)>$/INCLUDE:\1/g" | ${grepbin} "^INCLUDE:" | ${cutbin} -d: -f2- -s`
if [ "a${headerfiles}" = "a" ]; then
unset headerfiles
${rmbin} -f "/tmp/sakis3g.source.$$.combined.c" "/tmp/sakis3g.source.$$.c" "/tmp/sakis3g.source.$$.h" > /dev/null 2> /dev/null
show_fmt_error "Problem while parsing %s sources.\n" "Usb-ModeSwitch"
return 1
fi
debug "Header files are:\n%s\n" "${headerfiles}"
accumulative=""
for header in ${headerfiles}
do
debug "Probing: %s\n" "${header}"
accumulative=`${printfbin} "%s\n%s\n" "${accumulative}" "${header}" | ${grepbin} -v "^$"`
echo "${accumulative}" | ${sedbin} -e "s/^\(.*\)$/#include <\1\>/g" > "/tmp/sakis3g.source.$$.combined.c"
${printfbin} "int main(int argc, char **argv) {\nreturn 22;\n}\n\n" >> "/tmp/sakis3g.source.$$.combined.c"
${rmbin} -f "/tmp/sakis3g.object.$$" > /dev/null 2> /dev/null
if [ -f "/tmp/sakis3g.object.$$" ]; then
unset headerfiles; unset header; unset accumulative;
${rmbin} -f "/tmp/sakis3g.source.$$.combined.c" "/tmp/sakis3g.source.$$.c" "/tmp/sakis3g.source.$$.h" > /dev/null 2> /dev/null
show_fmt_error "Unable to delete \"%s\".\n" "/tmp/sakis3g.object.$$"
return 1
fi
debug run_command "${gccbin} -Wall -o \"/tmp/sakis3g.object.$$\" \"/tmp/sakis3g.source.$$.combined.c\""
if [ ! -x "/tmp/sakis3g.object.$$" ]; then
if [ "a${header}" != "ausb.h" ]; then
show_fmt_error "Header file %s missing from your system.\n" "${header}"
else
show_fmt_error "Header file %s missing from your system. This usually indicates libusb (or libusb-compat) development kit missing.\n" "${header}"
fi
unset headerfiles; unset header; unset accumulative;
${rmbin} -f "/tmp/sakis3g.source.$$.combined.c" "/tmp/sakis3g.source.$$.c" "/tmp/sakis3g.source.$$.h" > /dev/null 2> /dev/null
${rmbin} -f "/tmp/sakis3g.object.$$" > /dev/null 2> /dev/null
return 1
fi
debug run_command "/tmp/sakis3g.object.$$"
ret=$?
if [ "${ret}" -ne "22" ]; then
show_fmt_error "Unusable binary after including \"%s\".\n" "${header}"
unset headerfiles; unset header; unset accumulative;
${rmbin} -f "/tmp/sakis3g.source.$$.combined.c" "/tmp/sakis3g.source.$$.c" "/tmp/sakis3g.source.$$.h" > /dev/null 2> /dev/null
${rmbin} -f "/tmp/sakis3g.object.$$" > /dev/null 2> /dev/null
return 1
fi
debug "No problem encountered when including \"%s\".\n" "${header}"
${rmbin} -f "/tmp/sakis3g.object.$$" > /dev/null 2> /dev/null
done
${rmbin} -f "/tmp/sakis3g.source.$$.combined.c" > /dev/null 2> /dev/null
unset header; unset headerfiles;
debug "Will now attempt linking.\n"
echo "${accumulative}" | ${sedbin} -e "s/^\(.*\)$/#include <\1\>/g" > "/tmp/sakis3g.source.$$.combined.c"
${catbin} "/tmp/sakis3g.source.$$.h" "/tmp/sakis3g.source.$$.c" | ${grepbin} -v "^#include" >> "/tmp/sakis3g.source.$$.combined.c"
debug show_file "/tmp/sakis3g.source.$$.combined.c"
debug run_command "${gccbin} -Wall -lusb -o \"/tmp/sakis3g.object.$$\" \"/tmp/sakis3g.source.$$.combined.c\""
unset accumulative;
${rmbin} -f "/tmp/sakis3g.source.$$.combined.c" "/tmp/sakis3g.source.$$.c" "/tmp/sakis3g.source.$$.h" > /dev/null 2> /dev/null
if [ ! -x "/tmp/sakis3g.object.$$" ]; then
${rmbin} -f "/tmp/sakis3g.object.$$" > /dev/null 2> /dev/null
show_fmt_error "Failed to link %s. This usually indicates libusb (or libusb-compat) development kit missing.\n" "Usb-ModeSwitch"
return 1
fi
${rmbin} -f "/tmp/sakis3g.object.$$" > /dev/null 2> /dev/null
debug "Linking test was successful.\n"
return 0
}
compile_perform() {
[ "a${PROVIDER}" = "a" ] && return 1
[ ! -x "${PROVIDER}" ] && return 1
tempdestination="/tmp/sakis3g.recompile.$$"
debug run_command "${rmbin} -rf \"${tempdestination}\""
debug run_command "${mkdirbin} \"${tempdestination}\""
if [ ! -d "${tempdestination}" ]; then
show_fmt_error "Unable to create temporary folder \"%s\".\n" "${tempdestination}"
unset tempdestination
return 1
fi
debug run_command "${touchbin} \"${tempdestination}/test.$$\""
if [ ! -w "${tempdestination}/test.$$" ]; then
debug run_command "${rmbin} -rf \"${tempdestination}\""
show_fmt_error "No write access to temporary folder \"%s\".\n" "${tempdestination}"
unset tempdestination
return 1
fi
debug run_command "${rmbin} -rf \"${tempdestination}/\"*"
if [ ! -d "${tempdestination}" ]; then
show_fmt_error "Oops. Weird \"%s\" version. Deleted temporary folder \"%s\".\n" "${rmbin}" "${tempdestination}"
unset tempdestination
return 1
fi
debug run_command "${PROVIDER} disassemble \"${tempdestination}/.\""
if [ ! -x "${tempdestination}/sakis3g-${MYVERSION}/compile" ]; then
debug run_command "${rmbin} -rf \"${tempdestination}\""
show_fmt_error "Failed to disassemble Sakis3G package.\n" "${tempdestination}"
unset tempdestination
return 1
fi
debug run_command "${rmbin} -f \"${tempdestination}/sakis3g-${MYVERSION}/build/sakis3gz\""
compilation_error=`cd "${tempdestination}/sakis3g-${MYVERSION}"; ./compile 2>&1`
debug "Compilation output:\n%s\n" "${compilation_error}"
if [ ! -x "${tempdestination}/sakis3g-${MYVERSION}/build/sakis3gz" -o ! -s "${tempdestination}/sakis3g-${MYVERSION}/build/sakis3gz" ]; then
debug run_command "${rmbin} -rf \"${tempdestination}\""
show_fmt_error "Failed to compile. Compilation output:\n%s\n" "${compilation_error}"
unset compilation_error; unset tempdestination
return 1
fi
unset compilation_error
verification=`"${tempdestination}/sakis3g-${MYVERSION}/build/sakis3gz" usb_modeswitch --version 2> /dev/null | ${grepbin} -i "josua" | ${wcbin} -l`; verification=`echo ${verification}`
if [ "a${verification}" = "a" -o "a${verification}" = "a0" ]; then
unset verification
debug run_command "${rmbin} -rf \"${tempdestination}\""
show_fmt_error "Failed to verify result of compilation.\n"
unset tempdestination
return 1
fi
unset verification
debug run_command "${rmbin} -f \"${PROVIDER}.backup\""
if [ -f "${PROVIDER}.backup" ]; then
debug run_command "${rmbin} -rf \"${tempdestination}\""
show_fmt_error "Unable to delete previously existing \"%s\".\n" "${PROVIDER}.backup"
unset tempdestination
return 1
fi
debug run_command "${cpbin} \"${PROVIDER}\" \"${PROVIDER}.backup\""
if [ ! -f "${PROVIDER}.backup" ]; then
debug run_command "${rmbin} -rf \"${tempdestination}\""
show_fmt_error "Unable to create a safe backup to \"%s\".\n" "${PROVIDER}.backup"
unset tempdestination
return 1
fi
debug run_command "${lsbin} -l \"${PROVIDER}\""
# No rm, or we loose owner and rights information
#debug run_command "${rmbin} -f \"${PROVIDER}\""
#debug run_command "${lsbin} -l \"${PROVIDER}\""
debug run_command "${cpbin} \"${tempdestination}/sakis3g-${MYVERSION}/build/sakis3gz\" \"${PROVIDER}\""
debug run_command "${lsbin} -l \"${PROVIDER}\""
debug run_command "${rmbin} -rf \"${tempdestination}\""
unset tempdestination
verification=`"${PROVIDER}" usb_modeswitch --version 2> /dev/null | ${grepbin} -i "josua" | ${wcbin} -l`; verification=`echo ${verification}`
if [ "a${verification}" = "a" -o "a${verification}" = "a0" ]; then
debug "Verification failed. Restoring previous version.\n"
debug run_command "${cpbin} \"${PROVIDER}.backup\" \"${PROVIDER}\""
unset verification
if [ -x "${PROVIDER}" ]; then
show_fmt_error "Failed to succesfully place new version. You are still using old version.\n"
elif [ -x "${PROVIDER}.backup" ]; then
show_fmt_error "Failed to succesfully create new version. Old version is still available at \"%s\".\n" "${PROVIDER}.backup"
else
show_fmt_error "Something really bad happened. I am really sorry. You may need to re-download Sakis3G.\n"
fi
return 1
fi
unset verification
debug run_command "${rmbin} -f \"${PROVIDER}.backup\""
debug run_command "${lsbin} -l \"${PROVIDER}.backup\""
debug "Succesfully recompiled.\n"
return 0
}
flow_compile() {
if [ "a${binaryfree}" != "a" ]; then
show_fmt_error "You are running a binary free version of Sakis3G. Unable to recompile %s.\n" "Usb-ModeSwitch"
return 99
fi
verbose "Checking tools availability"
compile_check_local_requirements
ret=$?; [ "${ret}" -ne "0" ] && return ${ret}
verbose "Checking dependencies"
compile_check_dependencies
ret=$?; [ "${ret}" -ne "0" ] && return ${ret}
verbose "Testing compiler"
compile_compilation_dependencies
ret=$?; [ "${ret}" -ne "0" ] && return ${ret}
verbose "Compiling"
compile_perform
ret=$?; [ "${ret}" -ne "0" ] && return ${ret}
return 0
}
flow_report() {
if ! status_connected; then
show_fmt_error "You need to be connected for generating report.\n"
return 6
fi
unset report_text
old_translation=${notranslate}
export notranslate=1
report_text="Sakis3G version: ${MYVERSION}"
if [ "a${PROVIDER}" = "a" ]; then
report_text=`${printfbin} "%s\nNot running from within package.\n" "${report_text}"`
elif [ ! -x "${PROVIDER}" ]; then
report_text=`${printfbin} "%s\nPackage is not executable.\n" "${report_text}"`
else
if [ "a${binaryfree}" != "a" ]; then
if [ "a${stripped}" != "a" ]; then
report_text=`${printfbin} "%s\nRunning a binary free version.\n" "${report_text}"`
else
report_text=`${printfbin} "%s\nRunning a stripped version.\n" "${report_text}"`
fi
switchversion="95"
else
switchversion=`${PROVIDER} usb_modeswitch --version 2> /dev/null || echo $?`
fi
if [ "a${switchversion}" = "a95" ]; then
if find_binary "usb_modeswitch"; then
switchversion=`${usb_modeswitchbin} --version 2> /dev/null`
report_text=`${printfbin} "%s\nSystem provided Usb-ModeSwitch:\n%s\n" "${report_text}" "${switchversion}"`
else
report_text=`${printfbin} "%s\nUsb-ModeSwitch is not available.\n" "${report_text}"`
fi
else
switchversion=`${printfbin} "%s\n" "${switchversion}" | ${grepbin} -i version`
report_text=`${printfbin} "%s\nUsing embedded Usb-ModeSwitch version:\n%s\n" "${report_text}" "${switchversion}"`
fi
fi
if find_binary "uname"; then
report_text=`${printfbin} "%s\nKernel version: %s\nArchitect: %s\n" "${report_text}" "\`${unamebin} -r\`" "\`${unamebin} -m\`"`
else
report_text=`${printfbin} "%s\nUtility uname is not available.\n" "${report_text}"`
fi
report_text=`${printfbin} "%s\nSelected UI is: %s\n" "${report_text}" "${SGUI}"`
info_text=`action_info report | ${grepbin} -v "^$" | ${grepbin} -v "^ $"`
report_text=`${printfbin} "%s\n%s\n" "${report_text}" "${info_text}"`
state_variables "APN_USER APN_PASS SIM_PIN SGUI UNDISCOVERABLE BLUETOOTH MENU MOREMENU BALOONIZER"
report_text=`${printfbin} "%s\nVariables: %s\n" "${report_text}" "${statevariables}"`
unset info_text
export notranslate="${old_translation}"
[ "a${notranslate}" = "a" ] && unset notranslate
unset old_translation
trtext=`format_text "Please report following text:\n"`
notify "%s\n\n%s\n" "${trtext}" "${report_text}"
unset trtext; unset switchversion; unset report_text
return 0
}
# Returns 0 if connected, 1 if not connected.
# Sets as much of the following information:
# - statusnet containing numeric ID of ISP
# - statusname containing text of ISP or nothing
# - statusicon if statusnet exists within operator database and contains icon.
# Sets ISPID only if not set already.
# It is possible that it returns 0 and not set variables. This happens
# if ppp interface was initiated by another application.
status_connected() {
unset statusnet; unset statusname; unset statusicon; unset localpid
! ppp_fast_status && return 1
if [ -r "/tmp/sakis3g.3gnet" ]; then
statusnet=`${headbin} -1 "/tmp/sakis3g.3gnet"`
statusname=`${headbin} -2 "/tmp/sakis3g.3gnet" | ${tailbin} -1`
debug "Retrieved from %s: \"%s\" - \"%s\"\n" "/tmp/sakis3g.3gnet" "${statusnet}" "${statusname}"
statusnet=`echo "${statusnet}" | ${grepbin} "^[0-9][0-9][0-9][0-9][0-9]"`
if [ "a${statusnet}" != "a" ]; then
[ "a${statusname}" = "a${statusnet}" ] && unset statusname
debug "Retrieved ISP ID from %s: %s\n" "/tmp/sakis3g.3gnet" "${statusnet}"
[ "a${statusname}" != "a" ] && debug "Also retrieved ISP name: %s\n" "${statusname}"
else
unset statusname; unset statusnet
debug "Invalid or not existing %s within %s.\n" "ISPID" "/tmp/sakis3g.3gnet"
fi
if [ "a${statusnet}" != "a" ] && [ "a${ISPID}" = "a" -o "a${ISPID}" = "a${statusnet}" ]; then
if [ "a${MODEM_VARIANT}" = "a" ]; then
MODEM_VARIANT=`${headbin} -3 "/tmp/sakis3g.3gnet" | ${tailbin} -1`
[ "a${MODEM_VARIANT}" != "a" ] && export MODEM_VARIANT && debug "Also read: %s\n" "${MODEM_VARIANT}"
fi
if [ "a${USBDRIVER}" = "a" ]; then
USBDRIVER=`${headbin} -4 "/tmp/sakis3g.3gnet" | ${tailbin} -1`
[ "a${USBDRIVER}" != "a" ] && export USBDRIVER && debug "Also read: %s\n" "${USBDRIVER}"
fi
if [ "a${MODEM_TTY}" = "a" ]; then
MODEM_TTY=`${headbin} -5 "/tmp/sakis3g.3gnet" | ${tailbin} -1`
[ "a${MODEM_TTY}" != "a" ] && export MODEM_TTY && debug "Also read: %s\n" "${MODEM_TTY}"
fi
if [ "a${MODEM}" = "a" ]; then
MODEM=`${headbin} -6 "/tmp/sakis3g.3gnet" | ${tailbin} -1`
[ "a${MODEM}" != "a" ] && export MODEM && debug "Also read: %s\n" "${MODEM}"
fi
if [ "a${OTHER}" = "a" ]; then
OTHER=`${headbin} -7 "/tmp/sakis3g.3gnet" | ${tailbin} -1`
[ "a${OTHER}" != "a" ] && export OTHER && debug "Also read: %s\n" "${OTHER}"
fi
if [ "a${APN}" = "a" ]; then
APN=`${headbin} -8 "/tmp/sakis3g.3gnet" | ${tailbin} -1`
[ "a${APN}" != "a" ] && export APN && debug "Also read: %s\n" "${APN}"
fi
if [ "a${CUSTOM_APN}" = "a" -a "a${APN}" = "aCUSTOM_APN" ]; then
CUSTOM_APN=`${headbin} -9 "/tmp/sakis3g.3gnet" | ${tailbin} -1`
[ "a${CUSTOM_APN}" != "a" ] && export CUSTOM_APN && debug "Also read: %s\n" "${CUSTOM_APN}"
fi
if [ "a${APN_USER}" = "a" ]; then
APN_USER=`${headbin} -10 "/tmp/sakis3g.3gnet" | ${tailbin} -1`
[ "a${APN_USER}" != "a" ] && export APN_USER && debug "Also read: %s\n" "${APN_USER}"
fi
if [ "a${APN_PASS}" = "a" ]; then
APN_PASS=`${headbin} -11 "/tmp/sakis3g.3gnet" | ${tailbin} -1`
[ "a${APN_PASS}" != "a" ] && export APN_PASS && debug "Also read: %s\n" "${APN_PASS}"
fi
localpid=`${headbin} -12 "/tmp/sakis3g.3gnet" | ${tailbin} -1`
if [ "a${localpid}" != "a" ]; then
localprocess=`${psbin} -p ${localpid} -o comm= 2> /dev/null`
if [ "a${localprocess}" != "a" ]; then
debug "Process ID %s is: %s\n" "${localpid}" "${localprocess}"
[ "${localprocess}" != "pppd" -a "${localprocess}" != "wvdial" ] && unset localprocess
elif notrunning "${localpid}"; then
debug "Process ID %s is not running.\n" "${localpid}"
elif [ "a${localprocess}" = "a" ]; then
debug "Process ID %s is not valid.\n" "${localpid}"
fi
if [ "a${localprocess}" = "a" -a "a${ISPID}" = "a" ]; then
debug "Status file %s is stalled. Will discard information read from it.\n" "/tmp/sakis3g.3gnet"
unset statusnet; unset statusname
fi
fi
unset localpid; unset localprocess
fi
else
debug "Invalid or not existing %s.\n" "/tmp/sakis3g.3gnet"
fi
if [ "a${ISPID}" != "a" ]; then
debug "%s is set to: %s\n" "ISPID" "${ISPID}"
if [ "a${statusnet}" = "a" ]; then
statusnet="${ISPID}"
debug "Was adapted since file not available.\n" "statusnet"
if [ "a${ISPTEXT}" != "a" -a "a${ISPTEXT}" != "a${ISPID}" ]; then
statusname="${ISPTEXT}"
debug "Also adapted %s: %s\n" "ISPTEXT" "${ISPTEXT}"
fi
elif [ "a${statusnet}" = "a${ISPID}" ]; then
debug "It matches value retrieved from file.\n"
if [ "a${ISPTEXT}" != "a" -a "a${ISPTEXT}" != "a${ISPID}" -a "a${statusname}" = "a" ]; then
statusname="${ISPTEXT}"
debug "Also adapted %s since networks match: %s\n" "ISPTEXT" "${ISPTEXT}"
fi
else
debug "Does not match value retrieved from file.\n"
debug "Will trust file.\n"
fi
else
debug "%s is not set.\n" "ISPID"
if [ "a${statusnet}" = "a" ]; then
debug "Unable to determine on which network we are connected.\n"
else
export ISPID="${statusnet}"
debug "All information derived from file.\n"
debug "Also set %s from file contents.\n" "ISPID"
fi
fi
if net_info "${statusnet}" "${statusname}" && [ "a${BASERESULT}" != "a" ]; then
statusproduct=`echo "${BASERESULT}" | ${cutbin} -f3 -s`
[ "a${statusproduct}" != "a" ] && export statusproduct
statusicon=`echo "${BASERESULT}" | ${cutbin} -f8 -s`
[ "a${statusicon}" != "a" ] && export statusicon
if [ "a${statusname}" = "a" ]; then
statusname=`echo "${BASERESULT}" | ${cutbin} -d: -f2 -s`
[ "a${statusname}" != "a" ] && debug "Retrieved %s name from database: %s\n" "${statusnet}" "${statusname}"
fi
fi
if [ "a${statusnet}" = "a" ]; then
unset statusnet; unset statusname
else
export statusnet
if [ "a${statusname}" = "a" ]; then
unset statusname
else
export statusname
fi
fi
return 0
}
# Method invoked when "status" action was requested.
action_status() {
unset verbosecurrentcount
if ! ppp_fast_status; then
show_fmt_error "Not connected.\n"
return 6
fi
status_connected
if [ "a${statusnet}" != "a" ]; then
if [ "a${statusnet}" != "a${statusname}" -a "a${statusname}" != "a" ]; then
if [ "a${MODEM_VARIANT}" != "a" ]; then
finalnotify "%s connected to %s (%s)." "${MODEM_VARIANT}" "${statusname}" "${statusnet}"
else
finalnotify "Connected to %s (%s)." "${statusname}" "${statusnet}"
fi
else
if [ "a${MODEM_VARIANT}" != "a" ]; then
finalnotify "%s connected to %s." "${MODEM_VARIANT}" "${statusnet}"
else
finalnotify "Connected to %s." "${statusnet}"
fi
fi
else
finalnotify "Connected."
fi
return 0
}
action_info() {
unset verbosecurrentcount
if ! ppp_fast_status; then
notify "Not connected.\n"
return 0
fi
status_connected
if [ "a${statusnet}" = "a" ]; then
notify "Unable to gather connection information.\n"
return 0
fi
if [ "a$1" != "areport" ]; then
infotext=`translate_text "Connection Information"`
infotext=`${printfbin} "%s\n \n" "${infotext}"`
fi
[ "a${pppint}" != "a" ] && localtext=`format_text "Interface:\t\t\tP-t-P (%s)\n" "${pppint}"`
[ "a${localtext}" != "a" ] && infotext=`${printfbin} "%s\n%s\n" "${infotext}" "${localtext}"`; unset localtext
infotext=`${printfbin} "%s\n \n" "${infotext}"`
if [ "a$1" != "areport" ]; then
if find_binary "stat"; then
upsince=`${statbin} --printf="%z" "/tmp/sakis3g.3gnet" | ${cutbin} -d: -f1,2 -s`
if [ "a${upsince}" != "a" ]; then
localtext=`format_text "Connected since:\t%s\n" "${upsince}"`
infotext=`${printfbin} "%s\n%s\n" "${infotext}" "${localtext}"`; unset localtext
fi
unset upsince
fi
if [ -r "/proc/net/dev" -a "a${pppint}" != "a" ]; then
traffic=`${sedbin} -e "s/ */ /g" "/proc/net/dev" | ${grepbin} "^\( *\)${pppint}:" | ${headbin} -1 | ${cutbin} -d: -f2- | ${sedbin} -e "s/^ *//g" | ${cutbin} -d\ -f1,9`
debug "Traffic details are: %s\n" "${traffic}"
bytesreceived=`echo ${traffic} | ${cutbin} -d\ -f1 -s`
[ "a${bytesreceived}" != "a" ] && bytesreceived=`expr \( ${bytesreceived} + 512 \) / 1024 2> /dev/null`
[ "a${bytesreceived}" != "a" ] && localtext=`format_text "Kilobytes received:\t%d\n" ${bytesreceived}`
[ "a${localtext}" != "a" ] && infotext=`${printfbin} "%s\n%s\n" "${infotext}" "${localtext}"`; unset localtext
bytessent=`echo ${traffic} | ${cutbin} -d\ -f2 -s`
[ "a${bytessent}" != "a" ] && bytessent=`expr \( ${bytessent} + 512 \) / 1024 2> /dev/null`
[ "a${bytessent}" != "a" ] && localtext=`format_text "Kilobytes sent:\t%d\n" ${bytessent}`
[ "a${localtext}" != "a" ] && infotext=`${printfbin} "%s\n%s\n" "${infotext}" "${localtext}"`; unset localtext
unset traffic; unset bytesreceived; unset bytessent
fi
fi
localtext=`format_text "Network ID:\t\t%s" "${statusnet}"`
[ "a${localtext}" != "a" ] && infotext=`${printfbin} "%s\n\n%s\n" "${infotext}" "${localtext}"`; unset localtext
[ "a${statusname}" != "a" ] && localtext=`format_text "Operator name:\t%s" "${statusname}"`
[ "a${localtext}" != "a" ] && infotext=`${printfbin} "%s\n%s\n" "${infotext}" "${localtext}"`; unset localtext
if [ "a${APN}" != "a" ]; then
if [ "a${APN}" = "aCUSTOM_APN" -a "a${CUSTOM_APN}" != "a" ]; then
localtext=`format_text "APN:\t\t\t%s" "${CUSTOM_APN}"`
elif [ "a${APN}" != "aCUSTOM_APN" ]; then
localtext=`format_text "APN:\t\t\t%s" "${APN}"`
fi
fi
[ "a${localtext}" != "a" ] && infotext=`${printfbin} "%s\n%s\n" "${infotext}" "${localtext}"`; unset localtext
infotext=`${printfbin} "%s\n \n" "${infotext}"`
[ "a${MODEM_VARIANT}" != "a" ] && localtext=`format_text "Modem:\t\t\t%s\n" "${MODEM_VARIANT}"`
[ "a${localtext}" != "a" ] && infotext=`${printfbin} "%s\n%s\n" "${infotext}" "${localtext}"`; unset localtext
if [ "a${MODEM}" != "a" ]; then
if [ "a${MODEM}" != "a" -a "a${MODEM}" != "aOTHER" ]; then
localtext=`format_text "Modem type:\t\tUSB\n"`
elif [ "a${MODEM}" = "aOTHER" ]; then
if [ "a${OTHER}" = "aUSBMODEM" ]; then
localtext=`format_text "Modem type:\t\tUSB\n"`
elif [ "a${OTHER}" = "aBLUETOOTH" ]; then
localtext=`format_text "Modem type:\t\tBluetooth\n"`
else
localtext=`format_text "Modem type:\t\tCustom\n"`
fi
else
localtext=`format_text "Modem type:\t\tUnknown\n"`
fi
else
localtext=`format_text "Modem type:\t\tUnspecified\n"`
fi
[ "a${localtext}" != "a" ] && infotext=`${printfbin} "%s\n%s\n" "${infotext}" "${localtext}"`; unset localtext
[ "a${USBDRIVER}" != "a" ] && localtext=`format_text "Kernel driver:\t\t%s\n" "${USBDRIVER}"`
[ "a${localtext}" != "a" ] && infotext=`${printfbin} "%s\n%s\n" "${infotext}" "${localtext}"`; unset localtext
[ "a${MODEM_TTY}" != "a" ] && localtext=`format_text "Device:\t\t\t%s\n" "${MODEM_TTY}"`
[ "a${localtext}" != "a" ] && infotext=`${printfbin} "%s\n%s\n" "${infotext}" "${localtext}"`; unset localtext
infotext=`${printfbin} "%s\n \n" "${infotext}"`
if [ "a$1" != "areport" ]; then
if find_binary "ifconfig" && [ "a${pppint}" != "a" ]; then
ipaddress=`${ifconfigbin} ${pppint} | ${sedbin} -e "s/^.*:\([0-9][0-9]*\)\.\([0-9][0-9]*\)\.\([0-9][0-9]*\)\.\([0-9][0-9]*\) .*:\([0-9][0-9]*\)\.\([0-9][0-9]*\)\.\([0-9][0-9]*\)\.\([0-9][0-9]*\) \(.*\):\([0-9][0-9]*\)\.\([0-9][0-9]*\)\.\([0-9][0-9]*\)\.\([0-9][0-9]*\)$/IPADDRESSES: \1.\2.\3.\4 \5.\6.\7.\8/g" | ${grepbin} "^IPADDRESSES:" | ${cutbin} -d: -f2- -s`
if [ "a${ipaddress}" != "a" ]; then
localip=`echo ${ipaddress} | ${cutbin} -d\ -f1 -s`
localpeer=`echo ${ipaddress} | ${cutbin} -d\ -f2 -s`
localmask="255.255.255.255"
[ "a${localip}" != "a" ] && localtext=`format_text "IP Address:\t\t%s\n" "${localip}"`
[ "a${localtext}" != "a" ] && infotext=`${printfbin} "%s\n%s\n" "${infotext}" "${localtext}"`; unset localtext
[ "a${localip}" != "a" ] && localtext=`format_text "Subnet Mask:\t\t%s\n" "${localmask}"`
[ "a${localtext}" != "a" ] && infotext=`${printfbin} "%s\n%s\n" "${infotext}" "${localtext}"`; unset localtext
[ "a${localpeer}" != "a" ] && localtext=`format_text "Peer IP Address:\t%s\n" "${localpeer}"`
[ "a${localtext}" != "a" ] && infotext=`${printfbin} "%s\n%s\n" "${infotext}" "${localtext}"`; unset localtext
unset localip; unset localpeer; unset localmask
fi
unset ipaddress
fi
if find_binary "netstat" && [ "a${pppint}" != "a" ]; then
localpeer=`${netstatbin} -rn | ${grepbin} "^0.0.0.0 " | ${sedbin} -e "s/ */ /g" | ${cutbin} -d\ -f2 -s`; localpeer=`echo ${localpeer}`
[ "a${localpeer}" != "a" ] && localtext=`format_text "Default route(s):\t%s\n" "${localpeer}"`
[ "a${localtext}" != "a" ] && infotext=`${printfbin} "%s\n%s\n" "${infotext}" "${localtext}"`; unset localtext
unset localpeer
fi
[ "a${SGUI}" != "azenity" ] && infotext=`echo "${infotext}" | ${sedbin} -e "s/\( *\)/ /g"`
notify "%s\n" "${infotext}"
else
infotext=`echo "${infotext}" | ${sedbin} -e "s/\( *\)/ /g"`
${printfbin} "%s\n" "${infotext}"
fi
unset localtext; unset infotext
return 0
}
action_desktop() {
# Retrieve icon information if possible
[ "a${runner}" = "a" ] && return 1
[ "a${runhome}" = "a" ] && return 1
[ ! -d "${runhome}" ] && return 1
need_binary "touch"; need_binary "mkdir"; need_binary "chown"; need_binary "chmod"; need_binary "cat"
unset desktopdestination
if [ "a${DESKTOP}" = "a" ] && find_binary "xdg-user-dir"; then
DESKTOP=`${xdg_user_dirbin} DESKTOP`
[ "a${DESKTOP}" = "a" ] && DESKTOP=`${xdg_user_dirbin} desktop`
if [ "a${DESKTOP}" != "a" ]; then
DESKTOP=`echo "${DESKTOP}" | ${sedbin} -e "s/\/$//g"`
DESKTOP=`${basenamebin} "${DESKTOP}"`
fi
fi
if [ "a${DESKTOP}" != "a" ] && [ -d "${DESKTOP}" ]; then
desktopdestination="${DESKTOP}"
elif [ -d "${runhome}/Desktop" ]; then
desktopdestination="${runhome}/Desktop"
elif [ -d "${runhome}/desktop" ]; then
desktopdestination="${runhome}/desktop"
elif [ "a${HOME}" != "a" -a "a${DESKTOP}" != "a" ] && [ -d "${HOME}/${DESKTOP}" ]; then
desktopdestination="${HOME}/${DESKTOP}"
elif find_binary "pwd"; then
desktopdestination="`${pwdbin} 2> /dev/null`"
else
desktopdestination="."
fi
[ "a${desktopdestination}" = "a" ] && desktopdestination="."
debug "Destination of shortcut is: %s\n" "${desktopdestination}"
if status_connected && [ "a${statusicon}" != "a" -a "a${statusname}" != "a" ] && find_binary "wget" && find_binary "basename"; then
user_select "DESKTOPICON" "Desktop icon" "Select icon to use for shortcut" "OK" "Cancel" "SAKIS3G" "Sakis3G tux icon" "OPERATOR" "${statusname} icon"
selection=$?
case "${selection}" in
1)
DESKTOPICON="SAKIS3G"
;;
2)
DESKTOPICON="OPERATOR"
;;
98)
return 98
;;
*)
return 99
;;
esac
else
debug "${statusicon} ${statusname}\n"
debug "Automatically selecting %s icon.\n" "Sakis3G"
DESKTOPICON="SAKIS3G"
fi
if [ "a${DESKTOPICON}" = "aOPERATOR" ]; then
extension=`${basenamebin} "${statusicon}" | ${cutbin} -d. -f2-`
verbose "Retrieving operator icon"
debug run_command "${rmbin} -f \"/tmp/sakis3g.$$.${ISPID}_logo.${extension}\""
debug run_command "${wgetbin} -O \"/tmp/sakis3g.$$.${ISPID}_logo.${extension}\" \"${statusicon}\""
if [ ! -s "/tmp/sakis3g.$$.${ISPID}_logo.${extension}" ]; then
debug run_command "${rmbin} -f \"/tmp/sakis3g.$$.${ISPID}_logo.${extension}\""
show_fmt_error "Unable to get %s icon, unknown reason." "${statusname}"
DESKTOPICON="SAKIS3G"
else
debug "Successfully retrieved %s icon.\n" "operator"
fi
fi
if [ "a${DESKTOPICON}" = "aSAKIS3G" ] && [ "a${PROVIDER}" != "a" ] && [ -x "${PROVIDER}" ]; then
extension="png"
"${PROVIDER}" getfile "files/sakis3g.png" > "/tmp/sakis3g.$$.${ISPID}_logo.${extension}" 2> /dev/null
if [ ! -s "/tmp/sakis3g.$$.${ISPID}_logo.${extension}" ]; then
debug run_command "${rmbin} -f \"/tmp/sakis3g.$$.${ISPID}_logo.${extension}\""
show_fmt_error "Unable to get %s icon, unknown reason." "Sakis3G"
DESKTOPICON=""
else
debug "Successfully retrieved %s icon.\n" "Sakis3G"
fi
fi
if [ -s "/tmp/sakis3g.$$.${ISPID}_logo.${extension}" ]; then
debug run_command "${mkdirbin} -p \"${runhome}/.local\""
debug run_command "${chownbin} ${runner} \"${runhome}/.local\""
debug run_command "${mkdirbin} -p \"${runhome}/.local/share\""
debug run_command "${chownbin} ${runner} \"${runhome}/.local/share\""
debug run_command "${mkdirbin} -p \"${runhome}/.local/share/icons\""
debug run_command "${chownbin} ${runner} \"${runhome}/.local/share/icons\""
if [ "a${extension}" = "agif" -o "a${extension}" = "aGIF" -o "a${extension}" = "aGif" ]; then
debug run_command "${mvbin} \"/tmp/sakis3g.$$.${ISPID}_logo.${extension}\" \"${runhome}/.local/share/icons/sakis3g.png\""
debug run_command "${rmbin} -f \"/tmp/sakis3g.$$.${ISPID}_logo.${extension}\""
extension="png"
else
debug run_command "${mvbin} \"/tmp/sakis3g.$$.${ISPID}_logo.${extension}\" \"${runhome}/.local/share/icons/sakis3g.${extension}\""
debug run_command "${rmbin} -f \"/tmp/sakis3g.$$.${ISPID}_logo.${extension}\""
fi
if [ -s "${runhome}/.local/share/icons/sakis3g.${extension}" ]; then
debug run_command "${chownbin} ${runner} \"${runhome}/.local/share/icons/sakis3g.${extension}\""
debug run_command "${chmodbin} 644 \"${runhome}/.local/share/icons/sakis3g.${extension}\""
icon="${runhome}/.local/share/icons/sakis3g.${extension}"
debug "Successfully installed icon to \"%s\".\n" "${runhome}/.local/share/icons/sakis3g.${extension}"
fi
else
debug "File %s does not exist or is empty.\n" "/tmp/sakis3g.$$.${ISPID}_logo.${extension}"
[ -f "/tmp/sakis3g.$$.${ISPID}_logo.${extension}" ] && debug run_command "${rmbin} -f \"/tmp/sakis3g.$$.${ISPID}_logo.${extension}\""
if [ -f "/usr/share/icons/gnome/scalable/status/nm-device-wireless.svg" ]; then
debug "Selecting default GNOME icon.\n"
icon="/usr/share/icons/gnome/scalable/status/nm-device-wireless.svg"
else
debug "Unable to locate any icon.\n"
icon=""
fi
fi
debug "Icon selected is: %s\n" "${icon}"
shortcuttitle="Sakis3G"
[ "a${DESKTOPICON}" = "aOPERATOR" ] && shortcuttitle="${statusproduct}" && [ "a${shortcuttitle}" = "a" ] && shortcuttitle="${statusname} Internet"
[ "a${shortcuttitle}" = "a" ] && shortcuttitle="Sakis3G"
commenttext=`format_text "Manages 3G internet connection and 3G USB modems"`
${catbin} > "${desktopdestination}/sakis3g.desktop" <<endl
[Desktop Entry]
Version=1.0
Encoding=UTF-8
Type=Application
Terminal=false
Name=${shortcuttitle}
Name[en_US]=${shortcuttitle}
Exec=${ME} clicked
Comment=${commenttext}
Comment[en_US]=${commenttext}
Icon=${icon}
Icon[en_US]=${icon}
GenericName=
GenericName[en_US]=
endl
debug run_command "${catbin} \"${desktopdestination}/sakis3g.desktop\""
unset commenttext; unset shortcuttitle
if [ -s "${desktopdestination}/sakis3g.desktop" ]; then
debug run_command "${chownbin} ${runner} \"${desktopdestination}/sakis3g.desktop\""
debug run_command "${chmodbin} 750 \"${desktopdestination}/sakis3g.desktop\""
debug run_command "${lsbin} \"${desktopdestination}/sakis3g.desktop\""
finalnotify "Desktop shortcut created at %s." "${desktopdestination}/sakis3g.desktop"
unset desktopdestination
return 0
else
debug run_command "${rmbin} -f \"${desktopdestination}/sakis3g.desktop\""
unset desktopdestination
return 1
fi
}
action_modem() {
unset verbosecurrentcount
flow_select_modem "$@"
ret=$?
if [ "a${ret}" = "a0" ]; then
finalnotify "Modem selected.\n"
return 0
else
show_fmt_error "No modem selected.\n"
return ${ret}
fi
}
action_switch() {
unset verbosecurrentcount
flow_switch "$@"
ret=$?
if [ "a${ret}" = "a0" ]; then
if [ "a${NEWIDS}" = "a" ]; then
finalnotify "Modem switched.\n"
else
finalnotify "Modem switched to %s.\n" "${NEWIDS}"
fi
return 0
else
show_fmt_error "Failed to switch.\n"
return ${ret}
fi
}
action_setup() {
unset verbosecurrentcount
flow_setup "$@"
ret=$?
if [ "a${ret}" = "a0" ]; then
finalnotify "Modem setup residing on %s.\n" "${MODEM_TTY}"
return 0
else
show_fmt_error "Failed to setup modem.\n"
return ${ret}
fi
}
action_prepare() {
unset verbosecurrentcount
flow_prepare "$@"
ret=$?
if [ "a${ret}" = "a0" ]; then
finalnotify "Modem on %s is registered to %s.\n" "${MODEM_TTY}" "${ISPTEXT}"
return 0
else
show_fmt_error "Failed to prepare modem.\n"
return ${ret}
fi
}
action_connect() {
unset verbosecurrentcount
flow_connect "$@"
ret=$?
if [ "a${ret}" = "a0" ]; then
action_status "$@"
return 0
else
show_fmt_error "Failed to connect.\n"
return ${ret}
fi
}
action_compile() {
unset verbosecurrentcount
flow_compile "$@"
ret=$?
if [ "a${ret}" = "a0" ]; then
finalnotify "Succesfully recompiled.\n"
return 0
else
return ${ret}
fi
}
action_disconnect() {
unset verbosecurrentcount
if ! ppp_fast_status; then
finalnotify "Not connected.\n"
return 0
fi
flow_disconnect "$@"
ret=$?
if [ "a${ret}" = "a0" ]; then
finalnotify "Disconnected.\n"
return 0
else
show_fmt_error "Failed to disconnect.\n"
return ${ret}
fi
}
action_reconnect() {
unset verbosecurrentcount
unset disconnectedbefore
if ppp_fast_status; then
status_connected
flow_disconnect "$@"
ret=$?
if [ "${ret}" -ne "0" ]; then
show_fmt_error "Failed to disconnect.\n"
return ${ret}
fi
disconnectedbefore=1
fi
flow_connect "$@"
ret=$?
if [ "a${ret}" = "a0" -a "a${disconnectedbefore}" = "a1" ]; then
unset disconnectedbefore
finalnotify "Reconnected to %s.\n" "${ISPTEXT}"
return 0
elif [ "a${ret}" = "a0" ]; then
action_status "$@"
return 0
else
unset disconnectedbefore
show_fmt_error "Failed to connect.\n"
return ${ret}
fi
}
action_toggle() {
unset verbosecurrentcount
unset disconnectedbefore
if ppp_fast_status; then
action_disconnect "$@"
ret=$?
else
action_connect "$@"
ret=$?
fi
return ${ret}
}
action_clicked() {
unset verbosecurrentcount
unset ret; unset tester
tester="${SGUI}"; [ "a${tester}" = "a" ] && tester="terminal"
case "${SGUI}" in
zenity|dialog|Xdialog|whiptail|kdialog)
action_menu "$@"
ret=$?
;;
"9menu")
action_menu "$@"
ret=$?
;;
terminal|"interactive terminal")
if [ "a${interactive}" = "a" ]; then
action_toggle "$@"
ret=$?
else
unset interactive
action_toggle "$@"
ret=$?
export interactive=yes
fi
;;
esac
return ${ret}
}
# Method invoked when "more" action was requested.
action_more() {
unset verbosecurrentcount
unset usboptions; [ "a${binaryfree}" = "a" ] && usboptions="\"COMPILE\" \"Compile embedded Usb-ModeSwitch\""
alwaysoptions="\"DESKTOP\" \"Create desktop shortcut\" \"ABOUT\" \"About Sakis3G\" \"HELP\" \"Show help\" \"EXIT\" \"Exit\""
if ppp_fast_status; then
stateoptions="\"DISCONNECT\" \"Disconnect\" \"RECONNECT\" \"Disconnect and then connect again\" \"INFO\" \"Connection information\" \"REPORT\" \"Generate success report\""
else
stateoptions="\"CONNECT\" \"Connect with 3G\" \"PREPARE\" \"Only prepare modem (Setup + PIN unlock + Register Network + Update HAL)\" \"SETUP\" \"Only setup modem (Switch + Load module + Setup tty)\" \"SWITCH\" \"Only switch modem (if applicable)\""
fi
eval user_select \"MOREMENU\" \"Please select an action\" \"Choose action for Sakis3G script to follow.\" \"OK\" \"Cancel\" ${stateoptions} ${usboptions} ${alwaysoptions}
# in
ret=$?
unset usboptions; unset alwaysoptions; unset stateoptions
case "${ret}" in
99)
return 99
;;
98)
debug "No action selected.\n"
# Instead of returning 98, returns 0 to allow chaining of actors
# EXIT menu item is used from breaking chain
unset MOREMENU
return 0
;;
*)
case "a${MOREMENU}" in
aCONNECT)
action_connect "$@"
;;
aDISCONNECT)
action_disconnect "$@"
;;
aRECONNECT)
action_reconnect "$@"
;;
aPREPARE)
action_prepare "$@"
;;
aSETUP)
action_setup "$@"
;;
aSWITCH)
action_switch "$@"
;;
aCOMPILE)
action_compile "$@"
;;
aDESKTOP)
action_desktop "$@"
;;
aINFO)
action_info "$@"
;;
aREPORT)
action_report "$@"
;;
aHELP)
show_help
;;
aABOUT)
action_about "$@"
;;
aEXIT)
unset MOREMENU
return 98
;;
a)
unset MOREMENU
return 98
;;
*)
show_fmt_error "Option %s not implemented.\n" "${MOREMENU}"
;;
esac
;;
esac
unset MOREMENU
action_more "$@"
return $?
}
# Method invoked when "menu" action was requested.
action_menu() {
unset verbosecurrentcount
if ppp_fast_status; then
menuoptions="\"DISCONNECT\" \"Disconnect\" \"INFO\" \"Connection information\" \"DESKTOP\" \"Create shortcut\""
else
menuoptions="\"CONNECT\" \"Connect with 3G\""
fi
menuoptions="${menuoptions} \"MOREMENU\" \"More options...\" \"ABOUT\" \"About Sakis3G\""
menuoptions="${menuoptions} \"EXIT\" \"Exit\""
eval user_select \"MENU\" \"Please select an action\" \"Choose action for Sakis3G script to follow.\" \"OK\" \"Cancel\" ${menuoptions}
# in
ret=$?; unset menuoptions
case "${ret}" in
99)
return 99
;;
98)
debug "No action selected.\n"
# Instead of returning 98, returns 0 to allow chaining of actors
# EXIT menu item is used from breaking chain
return 0
;;
*)
case "a${MENU}" in
aCONNECT)
action_connect "$@"
;;
aDISCONNECT)
action_disconnect "$@"
;;
aMOREMENU)
action_more "$@"
ret=$?; [ "a${ret}" = "a98" ] && unset MENU && return 98
;;
aINFO)
action_info "$@"
;;
aDESKTOP)
action_desktop "$@"
;;
aHELP)
show_help
;;
aABOUT)
action_about "$@"
;;
aEXIT)
debug "Breaking chain.\n"
unset MENU
return 98
;;
a)
unset MENU
return 98
;;
*)
show_fmt_error "Option %s not implemented.\n" "${MENU}"
;;
esac
;;
esac
unset MENU
action_menu "$@"
return $?
}
helper_cleaner() {
[ -f "/tmp/sakis3g.helper.icon.green.$$.png" ] && ${rmbin} -f "/tmp/sakis3g.helper.icon.green.$$.png"
[ -f "/tmp/sakis3g.helper.icon.red.$$.png" ] && ${rmbin} -f "/tmp/sakis3g.helper.icon.red.$$.png"
[ -f "/tmp/sakis3g.helper.icon.yellow.$$.png" ] && ${rmbin} -f "/tmp/sakis3g.helper.icon.yellow.$$.png"
[ "a${helperpid}" != "a" ] && ! notrunning "${helperpid}" && ${killbin} -1 ${helperpid} 2> /dev/null > /dev/null
[ "a${helperpid}" != "a" ] && ! notrunning "${helperpid}" && ${killbin} -9 ${helperpid} 2> /dev/null > /dev/null
if [ "a${balloons}" != "a" ] && [ "a${BALOONIZERPID}" != "a" -o "a${BALOONIZER}" != "a" ]; then
[ "a${BALOONIZER}" != "a" ] && [ -f "${BALOONIZER}" ] && debug run_command "${rmbin} -f \"${BALOONIZER}\""
[ "a${BALOONIZERPID}" != "a" ] && ! notrunning "${BALOONIZERPID}" && debug run_command "${killbin} -1 ${BALOONIZERPID}"
[ "a${BALOONIZERPID}" != "a" ] && ! notrunning "${BALOONIZERPID}" && debug run_command "${killbin} -9 ${BALOONIZERPID}"
find_binary "ps" && tailpid=`${psbin} -A -o pid,command | ${grepbin} "${tailbin} -f ${BALOONIZER}" | ${grepbin} -v "${grepbin}" | ${cutbin} -d\ -f1`
[ "a${tailpid}" != "a" ] && ! notrunning "${tailpid}" && debug run_command "${killbin} -1 ${tailpid}"
[ "a${tailpid}" != "a" ] && ! notrunning "${tailpid}" && debug run_command "${killbin} -9 ${tailpid}"
unset BALOONIZERPID; unset BALOONIZER
fi
}
action_helper() {
if ! find_binary "zenity"; then
show_fmt_error "Unable to install tray icon to system notification area. You need to install %s.\n" "zenity"
return 0
fi
need_binary "kill"
[ "a${PROVIDER}" = "a" ] && return 1
[ ! -x "${PROVIDER}" ] && return 1
if we_are_root_already && [ "a${MENU}" != "a" ]; then
debug "Calling menu since state variable MENU is set.\n"
action_menu "$@"
unset MENU
debug "MENU actor returned. Will now run as helper.\n"
fi
debug run_command "${rmbin} -f /tmp/sakis3g.helper.icon.red.$$.png /tmp/sakis3g.helper.icon.green.$$.png /tmp/sakis3g.helper.icon.yellow.$$.png"
addexittrap helper_cleaner
${PROVIDER} getfile files/sakis3g.red.png > "/tmp/sakis3g.helper.icon.red.$$.png" 2> /dev/null
${PROVIDER} getfile files/sakis3g.green.png > "/tmp/sakis3g.helper.icon.green.$$.png" 2> /dev/null
${PROVIDER} getfile files/sakis3g.yellow.png > "/tmp/sakis3g.helper.icon.yellow.$$.png" 2> /dev/null
if [ ! -s "/tmp/sakis3g.helper.icon.green.$$.png" ]; then
debug "Failed to retrieve green/connected state icon.\n"
return 1
elif [ ! -s "/tmp/sakis3g.helper.icon.red.$$.png" ]; then
debug "Failed to retrieve red/no hardware state icon.\n"
return 1
elif [ ! -s "/tmp/sakis3g.helper.icon.yellow.$$.png" ]; then
debug "Failed to retrieve yellow/not connected state icon.\n"
return 1
fi
debug run_command "${chmodbin} 644 \"/tmp/sakis3g.helper.icon.red.$$.png\""
debug run_command "${chmodbin} 644 \"/tmp/sakis3g.helper.icon.green.$$.png\""
debug run_command "${chmodbin} 644 \"/tmp/sakis3g.helper.icon.yellow.$$.png\""
if [ "a${balloons}" != "a" ]; then
# Establish balloon helper now that will be accessible from root session later
if [ "a${BALOONIZER}" = "a" ]; then
BALOONIZER="/tmp/sakis3g.baloon.pipe.$$"
debug run_command "${rmbin} -f \"${BALOONIZER}\""
debug run_command "${touchbin} -f \"${BALOONIZER}\""
if [ -w "${BALOONIZER}" ]; then
${printfbin} "\n\n\n\n\nvisible:false\n" >> "${BALOONIZER}"
export BALOONIZER
eval ${tailbin} -f "${BALOONIZER}" "2> /dev/null" | ${zenitybin} --notification --listen > /dev/null 2> /dev/null &
BALOONIZERPID=$!; eval "disown -a" > /dev/null 2> /dev/null
export BALOONIZERPID
${printfbin} "visible:false\n" >> "${BALOONIZER}"
${printfbin} "visible:false\nvisible:false\n" >> "${BALOONIZER}"
debug "Balloon pipe created. Location is \"%s\" and runs with PID %d.\n" "${BALOONIZER}" "${BALOONIZERPID}"
else
debug "Error while creating pipe for balloons.\n"
debug run_command "${rmbin} -f \"${BALOONIZER}\""
unset BALOONIZER
fi
elif [ -w "${BALOONIZER}" ]; then
debug "Will be using already existing balloon pipe: %s\n" "${BALOONIZER}"
elif [ ! -w "${BALOONIZER}" ]; then
debug "Balloons pipe \"%s\" exists but no write access granted.\n" "${BALOONIZER}"
fi
[ "a${BALOONIZER}" = "a" ] && debug "No balloons will be appearing.\n"
fi
debug "All set. Going into helper mode.\n"
while [ "1" = "1" ]
do
if ppp_slow_status && status_connected; then
helpertext="`translate_text "Connected"`"
[ "a${statusname}" != "a" ] && helpertext="${statusname}"
helperconnected=2
else
usb_connected_modems
if [ "a${usb_modem_devices}" != "a" ]; then
helpertext="`translate_text "Not connected"`"
helperconnected=1
helpermodems=`echo "${usb_modem_devices}" | ${cutbin} -d: -f3- | ${trbin} "\n" " "`
else
helpertext="`translate_text "No USB modem"`"
helperconnected=0
fi
fi
# Check if something was changed not by us. Then balloon user.
if [ "a${balloons}" != "a" ]; then
if [ "a${BALOONIZER}" != "a" ] && [ "a${previousstatus}" != "a" -a "a${previousstatus}" != "a${helperconnected}" ]; then
debug "Status changed. Not by us.\n"
notificationtext=`translate_text "Notification"`
if [ "a${helperconnected}" = "a2" ]; then
iconpath="/tmp/sakis3g.helper.icon.green.$$.png"
elif [ "a${helperconnected}" = "a1" ]; then
iconpath="/tmp/sakis3g.helper.icon.yellow.$$.png"
elif [ "a${helperconnected}" = "a0" ]; then
iconpath="/tmp/sakis3g.helper.icon.red.$$.png"
else
iconpath="/tmp/sakis3g.helper.icon.yellow.$$.png"
fi
unset largetext; unset smalltext
if [ "a${previousstatus}" = "a0" -a "a${helperconnected}" = "a1" ]; then
largetext=`translate_text "USB Modem plugged"`
smalltext=`format_text "USB Modem %s is now plugged on computer." "${helpermodems}"`
elif [ "a${helperconnected}" = "a2" ]; then
largetext=`translate_text "Connected"`
if [ "a${MODEM_VARIANT}" != "a" -a "a${statusname}" != "a" ]; then
smalltext=`format_text "Modem %s is now connected to %s." "${MODEM_VARIANT}" "${statusname}"`
elif [ "a${MODEM_VARIANT}" != "a" ]; then
smalltext=`format_text "Modem %s is now connected." "${MODEM_VARIANT}"`
elif [ "a${statusname}" != "a" ]; then
smalltext=`format_text "You are now connected to %s." "${statusname}"`
else
smalltext=`translate_text "Computer is now connected.\n"`
fi
elif [ "a${previousstatus}" = "a1" -a "a${helperconnected}" = "a0" ]; then
largetext=`translate_text "USB Modem Unplugged"`
smalltext=`translate_text "No USB modem is anymore plugged on computer."`
elif [ "a${previousstatus}" = "a2" ]; then
largetext=`translate_text "Disconnected"`
if [ "a${helperconnected}" = "a0" ]; then
smalltext=`translate_text "You were disconnected due to modem being unplugged."`
elif [ "a${helperconnected}" = "a1" ]; then
smalltext=`translate_text "You are now disconnected from operator."`
fi
fi
debug "Will display baloon:\nIcon: %s\nTitle: %s\nMessage: %s\n" "${iconpath}" "${largetext}" "${smalltext}"
if [ "a${smalltext}" != "a" -a "a${largetext}" != "a" ]; then
${printfbin} "icon:%s\n" "${iconpath}" >> "${BALOONIZER}" 2> /dev/null
${printfbin} "tooltip:%s\n" "${notificationtext}" >> "${BALOONIZER}" 2> /dev/null
${printfbin} "visible:true\n" >> "${BALOONIZER}" 2> /dev/null
${printfbin} "message:%s\\\n<small>%s</small>\n" "${largetext}" "${smalltext}" >> "${BALOONIZER}" 2> /dev/null
${printfbin} "visible:false\n" >> "${BALOONIZER}" 2> /dev/null
fi
unset iconpath; unset smalltext; unset largetext; unset notificationtext
fi
previousstatus="${helperconnected}"
fi
if [ "a${helpertext}" != "a${announcedtext}" -a "a${helperpid}" != "a" ] && ! notrunning "${helperpid}"; then
[ "a${helperpid}" != "a" ] && ! notrunning "${helperpid}" && ${killbin} -1 ${helperpid} 2> /dev/null > /dev/null
[ "a${helperpid}" != "a" ] && ! notrunning "${helperpid}" && ${killbin} -9 ${helperpid} 2> /dev/null > /dev/null
notrunning "${helperpid}" && unset helperpid
fi
if [ "a${helperpid}" = "a" ]; then
if [ "a${helperconnected}" = "a2" ]; then
${zenitybin} --notification --window-icon=/tmp/sakis3g.helper.icon.green.$$.png --text="${helpertext}" > /dev/null 2> /dev/null &
elif [ "a${helperconnected}" = "a1" ]; then
${zenitybin} --notification --window-icon=/tmp/sakis3g.helper.icon.yellow.$$.png --text="${helpertext}" > /dev/null 2> /dev/null &
elif [ "a${helperconnected}" = "a0" ]; then
${zenitybin} --notification --window-icon=/tmp/sakis3g.helper.icon.red.$$.png --text="${helpertext}" > /dev/null 2> /dev/null &
else
${zenitybin} --notification --text="${helpertext}" > /dev/null 2> /dev/null &
fi
helperpid=$!;
eval "disown -a" > /dev/null 2> /dev/null
announcedtext="${helpertext}"
export helperpid
elif notrunning "${helperpid}"; then
unset helperpid; unset previousstatus
debug "User clicked on icon.\n"
action_menu "$@"; ret=$?
if [ "${ret}" -eq "98" ]; then
if [ "a${forever}" != "a" ]; then
debug "User selected exit on MENU. However, \"forever\" is set.\n"
unset MENU; unset MOREMENU;
else
debug "User selected exit on MENU. Will ask for confirmation to exit.\n"
#${zenitybin} --question --title="`translate_text "Confirm exit"`" --text="`translate_text "Exiting will also remove tray icon. Are you sure you want to exit Sakis3G?"`"
#ret=$?
#if [ "a${ret}" = "a0" ]; then
if user_confirm "helperexit" "Confirm exit" "Exiting will also remove tray icon. Are you sure you want to exit Sakis3G?" "Yes" "No" "reset"; then
debug "User confirmed he wants to exit. Helper will die.\n"
break
else
debug "User did not confirm.\n"
unset MENU; unset MOREMENU
fi
fi
fi
debug "Resuming helper operation.\n"
else
debug "Helper is sleeping for a second.\n"
sleep 1
fi
done
helper_cleaner
return 98
}
# Method called when called as a helper to hold HAL lock
action_holdlock() {
unset verbosecurrentcount
[ "a$2" != "a" ] && [ -f "$2" ] && checkfile="$2" && echo "$$" > "${checkfile}"
unset TRAPS
while [ "1" = "1" ]
do
if [ "a${PROVIDER}" = "a" ]; then
ppppp=`ps -p $$ -o ppid=`
else
ppppp=`ps -p $$ -o ppid=`
ppppp=`ps -p ${ppppp} -o ppid=`
fi
ppppp=`echo $ppppp`
[ "a${ppppp}" = "a1" ] && exit 0
[ "a${ppppp}" = "a${PPID}" ] && exit 0
[ "a${checkfile}" != "a" ] && [ ! -f "${checkfile}" ] && exit 0
#echo $ppppp
sleep 1
done
}
action_state() {
unset verbosecurrentcount
state_variables "SGUI interactive stick_to_console DEBUG LOCALAUTHORITY BALOONIZER"
notify "To automatically repeat result of last action, use following command line:\n%s\n" "${ME} ${actors} ${statevariables}"
return 0
}
action_udevrule() {
unset verbosecurrentcount
state_variables "SGUI MODEM interactive stick_to_console USBMODEM OTHER DEBUG LOCALAUTHORITY BALOONIZER"
# statevariables=`echo "${statevariables}" | ${sedbin} -e "s/\"/\\\\\\\\\"/g"`
statevariables=`echo "${statevariables}" | ${sedbin} -e "s/\"//g"`
unset content
candidates="${MODEM}"
[ "a${candidates}" = "aOTHER" ] && unset candidates
[ "a${candidates}" = "aOTHER" -a "a${OTHER}" = "aUSBMODEM" -a "a${USBMODEM}" != "a" ] && candidates="${USBMODEM}"
localactors=`echo ${actors}`
for candidate in ${candidates}
do
modemvendor=`echo ${candidate} | ${cutbin} -d: -f1 -s`
modemproduct=`echo ${candidate} | ${cutbin} -d: -f2 -s`
if [ "a${modemvendor}" != "a" -a "a${modemproduct}" != "a" ]; then
content=`${printfbin} "%s\nACTION==\"add\", SUBSYSTEM==\"usb\", ATTRS{idVendor}==\"%s\", ATTRS{idProduct}==\"%s\", ATTRS{bInterfaceNumber}==\"00\", RUN+=\"%s %s %s MODEM=OTHER OTHER=USBMODEM USBMODEM=%s:%s\"\n\n" "${content}" "${modemvendor}" "${modemproduct}" "${ME}" "${localactors}" "${statevariables}" "${modemvendor}" "${modemproduct}"`
break;
fi
done
unset localactors; unset modemvendor; unset modemproduct; unset candidate; unset candidates; unset statevariables
term_clearline
if [ "a${content}" != "a" ]; then
format_text "To automatically repeat result of last action, immediately upon device connection, include following line within a %s file within \"%s\" directory:\n%s\n" ".rules" "/etc/udev/rules.d/" "${content}"
else
format_text "No USB modem was selected. No need for a udev example.\n"
fi
unset content
return 0
}
action_about() {
unset verbosecurrentcount
notify "%s\n" "`show_version`"
return 0
}
show_man() {
destination="$1"
case "a${destination}" in
ausb_modeswitch|ausb-modeswitch)
destination="dependencies/usb-modeswitch/usb_modeswitch.1"
;;
asakis3g.conf)
destination="man/sakis3g.conf.5"
;;
*)
destination="man/sakis3g.1"
;;
esac
debug "Destination man page is: %s\n" "${destination}"
[ "a${PROVIDER}" = "a" ] && return 1
[ ! -x "${PROVIDER}" ] && return 1
need_binary "man"
need_binary "rm"
"${PROVIDER}" getfile "${destination}" > "/tmp/sakis3g.man.$$"
debug "Will now display man page %s.\n" "${destination}"
[ -s "/tmp/sakis3g.man.$$" ] && ${manbin} -l "/tmp/sakis3g.man.$$"
${rmbin} -f "/tmp/sakis3g.man.$$"
return 0
}
action_report() {
unset verbosecurrentcount
flow_report "$@"
ret=$?
if [ "a${ret}" = "a0" ]; then
return 0
else
return ${ret}
fi
}
# Executes actor $1 with the arguments
run_action() {
actioncandidate=$1
[ "$#" -gt "0" ] && shift
unset verbosecurrentcount
newactors="${actors} ${actioncandidate}"
case "${actioncandidate}" in
about)
action_about "$@"
actionresult=$?
;;
desktop)
action_desktop "$@"
actionresult=$?
;;
helper)
action_helper "$@"
actionresult=$?
;;
status)
action_status "$@"
actionresult=$?
;;
connected)
ppp_fast_status
actionresult=$?
;;
disconnected)
if ppp_fast_status; then
actionresult=99
else
actionresult=0
fi
;;
plugged)
if usb_connected_modems; then
actionresult=0
else
actionresult=99
fi
;;
unplugged)
if usb_connected_modems; then
actionresult=99
else
actionresult=0
fi
;;
switched)
if usb_connected_modems; then
if modeswitch_switchable_devices; then
actionresult=99
else
actionresult=0
fi
else
actionresult=0
fi
;;
switchable)
if modeswitch_switchable_devices; then
actionresult=0
else
actionresult=99
fi
;;
wait|sleep)
debug "Sleeping for 1 second.\n"
sleep 1
actionresult=0
;;
info)
action_info "$@"
actionresult=$?
;;
clicked)
action_clicked "$@"
actionresult=$?
;;
modem|select)
action_modem "$@"
actionresult=$?
;;
switchonly)
action_switch "$@"
actionresult=$?
;;
setup)
action_setup "$@"
actionresult=$?
;;
prepare|init)
action_prepare "$@"
actionresult=$?
;;
connect|start)
action_connect "$@"
actionresult=$?
;;
toggle)
action_toggle "$@"
actionresult=$?
;;
reconnect|restart)
action_reconnect "$@"
actionresult=$?
;;
disconnect|stop)
action_disconnect "$@"
actionresult=$?
;;
more|moremenu|menumore)
action_more "$@"
actionresult=$?
;;
menu)
action_menu "$@"
actionresult=$?
;;
state)
action_state "$@"
actionresult=$?
;;
udevrule)
action_udevrule "$@"
actionresult=$?
;;
compile|recompile)
action_compile "$@"
actionresult=$?
;;
report)
action_report "$@"
actionresult=$?
;;
*)
newactors="${actors}"
unset actioncandidate
actionresult=0
;;
esac
actors="${newactors}"
unset actioncandidate; unset newactors
[ "a${actionresult}" = "a" ] && actionresult=99
return ${actionresult}
}
# Executes actors in the order defined
action_command() {
unset actors
while [ "$#" -gt "0" ]
do
if [ "a${1}" = "anot" -o "a${1}" = "aNot" -o "a${1}" = "a!" ]; then
[ "$#" -gt "0" ] && shift
actors="${actors} not"
run_action "$@"
actionresult=$?
if [ "${actionresult}" -eq "0" ]; then
actionresult=99
debug "Actor \"%s\" returned %d, \"not\" operator instructs to abort.\n" "${1}" "${actionresult}"
break
else
debug "Actor \"%s\" returned %d, but was inverted by \"not\" operator.\n" "${1}" "${actionresult}"
actionresult=0
fi
elif [ "a${1}" = "aignore" -o "a${1}" = "aIgnore" -o "a${1}" = "aignoring" -o "a${1}" = "aIgnoring" -o "a${1}" = "a|" ]; then
[ "$#" -gt "0" ] && shift
actors="${actors} ignore"
run_action "$@"
actionresult=$?
if [ "${actionresult}" -ne "0" ]; then
debug "Actor \"%s\" returned %d, \"ignore\" operator instructs to continue.\n" "${1}" "${actionresult}"
actionresult=0
fi
elif [ "a${1}" != "a" ] && ! run_action "$@"; then
debug "Aborting execution chain due to actor \"%s\" returning %d.\n" "${1}" "${actionresult}"
break
fi
[ "$#" -gt "0" ] && shift
done
unset arg
actors=`echo ${actors}`
if [ "a${actors}" = "a" ]; then
debug "No actors defined.\n"
unset actors
return 1
else
debug "Following actors executed: %s\n" "${actors}"
unset actors
return 0
fi
}
# Checks if arguments defined a dummy action and aborts if it does
no_action_command() {
for arg in $@
do
case "$arg" in
--help|help)
unset arg
if find_binary "fold"; then
if [ "a${COLUMNS}" != "a" ]; then
raw_help | ${foldbin} -s -w "${COLUMNS}"
else
raw_help | ${foldbin} -s -w "80"
fi
else
raw_help
fi
return 0
;;
--version|version)
unset arg
show_version
return 0
;;
--holdlock|holdlock)
unset arg
action_holdlock "$@"
return 0
;;
usb_modeswitch)
if [ "a${binaryfree}" != "a" ]; then
show_fmt_error "You are running a binary free version of Sakis3G. This action is not available.\n"
fi
return 0
;;
man)
if [ "a${stripped}" != "a" ]; then
show_fmt_error "You are running a stripped version of Sakis3G. This action is not available.\n"
else
shift
show_man "$@"
fi
unset arg
return 0
;;
esac
done
unset arg
return 1
}
# When no actor defined, executes default actor of GUI selected.
default_actor() {
debug "Executing default actor for \"%s\".\n" "${SGUI}"
if voodoo_mode; then
debug "Voodoo actions will happen.\n"
if action_connect "$@"; then
actors="connect"
action_state "$@"
return $?
else
return $?
fi
fi
case "${SGUI}" in
whiptail|dialog|Xdialog|zenity|kdialog)
action_menu "$@"
return $?
;;
"9menu")
action_menu "$@"
return $?
;;
"interactive terminal")
action_menu "$@"
return $?
;;
"terminal")
show_help
return $?
;;
*)
debug "No default actor for this GUI. Showing help.\n"
show_help
return $?
;;
esac
}
voodoo_mode() {
[ "a${voodoo}" != "a" ] && return 0
return 1
}
guruplug_led() {
if [ "a$1" = "anoexecute" ]; then
noexecute=1
shift
elif [ "a$1" = "aall" ]; then
shift
guruplug_leds "$@"
return 0
else
noexecute=0
fi
ledcolor=""; ledname=""; othercolor=""; otherled=""; ledblink=""; ledon=""; ledoff=""
for ledarg in "$@"
do
case "a${ledarg}" in
ared|aRED|aRed|aR|ar|"a${redcolor}")
ledcolor="${redcolor}"
othercolor="${othercolor} ${greencolor}"
;;
agreen|aGREEN|aGreen|aG|ag|"a${greencolor}")
ledcolor="${greencolor}"
othercolor="${othercolor} ${redcolor}"
;;
ablack|aBLACK|aBlack|aB|ab|anone|aNONE|aNone|aN|an|aNO|aNo|ano|aReset|aRESET|areset)
ledcolor=""
othercolor="${othercolor} ${redcolor} ${greencolor}"
;;
aorange|aOrange|aORANGE|aO|ao|ayellow|aYellow|aYellow|aY|ay|aBOTH|aBoth|aboth)
ledcolor="${ledcolors}"
othercolor=""
;;
aleft|aLEFT|aLeft|aL|al|"a${leftled}")
ledname="${leftled}"
otherled="${otherled}"
;;
aright|aRIGHT|aRight|"a${rightled}")
ledname="${rightled}"
otherled="${otherled}"
;;
ablink|aBlink|aBLINK)
ledblink=1;
;;
anand|aNAND|assd|aSSD|adisk|aDISK|aDisk|aNand|aSsd|anand-disk|ananddisk|assddisk|assd-disk)
ledblink=2;
;;
ammc|ammc0|aMMC|aMmc|aMMC0|acard|aCard|aCARD)
ledblink=3;
;;
*)
ledcheck=`expr ${ledarg} + 1 - 1 2> /dev/null`
if [ "a${ledcheck}" = "a${ledarg}" ]; then
if [ "a${ledon}" = "a" ]; then
ledon="${ledarg}"
elif [ "a${ledoff}" = "a" ]; then
ledoff="${ledarg}"
fi
fi
;;
esac
done
if [ "a${ledcolor}${othercolor}" = "a" -o "a${ledname}" = "a" ]; then
unset noexecute; unset ledarg; unset ledcolor; unset ledname; unset othercolor; unset otherled;
unset color; unset oled; unset ledcommand; unset ledblink; unset ledmode; unset ledon; unset ledoff;
return 1
fi
ledcommand=""
for oled in ${otherled}
do
for color in ${ledcolors}
do
ledcommand="${ledcommand} echo \"none\" > \"${ledpath}/${color}:${oled}/trigger\";"
ledcommand="${ledcommand} echo \"0\" > \"${ledpath}/${color}:${oled}/brightness\";"
done
done
if [ "a${ledblink}" = "a1" ]; then
unset othercolor
ledmode="timer"
[ "a${ledon}" = "a" ] && ledon=500
[ "a${ledoff}" = "a" ] && ledoff=500
if [ "a${ledcolor}" = "a" ]; then
ttt="${ledon}"; ledon="${ledoff}"; ledoff="${ttt}"; unset ttt
ledcheck=`guruplug_led_getstate "${ledname}" | ${grepbin} "_brightness=1" | ${sedbin} -e "s/^${ledname}_\(.*\)_brightness=1$/\1/g" | tr "\n" " "`
ledcheck=`echo ${ledcheck}`
for color in ${ledcolors}
do
colorname=`echo "${color}" | ${sedbin} -e "s/:/_/g"`
if strinstr "${colorname}" "${ledcheck}" " "; then
ledcolor="${ledcolor} ${color}"
else
othercolor="${othercolor} ${color}"
fi
done
unset color; unset colorname; unset ledcheck
fi
[ "a${ledcolor}" = "a" ] && unset othercolor
elif [ "a${ledblink}" = "a2" ]; then
ledmode="nand-disk"
elif [ "a${ledblink}" = "a3" ]; then
ledmode="mmc0"
else
ledmode="none"
fi
for color in ${othercolor}
do
ledcommand="${ledcommand} echo \"none\" > \"${ledpath}/${color}:${ledname}/trigger\";"
ledcommand="${ledcommand} echo \"0\" > \"${ledpath}/${color}:${ledname}/brightness\";"
done
if [ "a${ledcolor}" != "a" ]; then
for color in ${ledcolor}
do
ledcommand="${ledcommand} echo \"${ledmode}\" > \"${ledpath}/${color}:${ledname}/trigger\";"
[ "a${ledmode}" = "anone" ] && ledcommand="${ledcommand} echo \"1\" > \"${ledpath}/${color}:${ledname}/brightness\";"
if [ "a${ledblink}" = "a1" ]; then
ledcommand="${ledcommand} echo \"${ledon}\" > \"${ledpath}/${color}:${ledname}/delay_on\";"
ledcommand="${ledcommand} echo \"${ledoff}\" > \"${ledpath}/${color}:${ledname}/delay_off\";"
fi
done
unset color
fi
if [ "a${noexecute}" = "a1" ]; then
echo "${ledcommand}"
else
unset LEDSCLEAN
eval ${ledcommand}
fi
unset noexecute; unset ledarg; unset ledcolor; unset ledname; unset othercolor; unset otherled;
unset color; unset oled; unset ledcommand; unset ledblink; unset ledmode; unset ledon; unset ledoff;
return 0
}
guruplug_leds() {
ledscommands=""
for ledi in ${allleds}
do
ledscommands="${ledscommands} `guruplug_led noexecute "${ledi}" "$@"`"
done
unset LEDSCLEAN
eval ${ledscommands}
unset ledscommands; unset ledi
return 0
}
guruplug_verbose() {
[ "a${guruplug}" = "a" ] && return 0
if [ "a${gurucycle}" = "a" -o "a${gurucycle}" = "a0" ]; then
gurucycle="1"
led1="left"
led2="right"
elif [ "a${gurucycle}" = "a1" ]; then
gurucycle="0"
led1="right"
led2="left"
fi
export gurucycle
ledscommands=""
ledscommands="${ledscommands} `guruplug_led noexecute ${led1} reset`"
ledscommands="${ledscommands} `guruplug_led noexecute ${led2} reset`"
ledscommands="${ledscommands} `guruplug_led noexecute ${led1} green`"
ledscommands="${ledscommands} `guruplug_led noexecute ${led2} blink green`"
eval ${ledscommands}
unset led1; unset led2; unset ledscommands
return 0
}
guruplug_verbose_same() {
[ "a${guruplug}" = "a" ] && return 0
if [ "a${gurucycle}" = "a" -o "a${gurucycle}" = "a0" ]; then
led1="left"
led2="right"
elif [ "a${gurucycle}" = "a1" ]; then
led1="right"
led2="left"
fi
export gurucycle
ledscommands=""
ledscommands="${ledscommands} `guruplug_led noexecute ${led1} reset`"
ledscommands="${ledscommands} `guruplug_led noexecute ${led2} reset`"
ledscommands="${ledscommands} `guruplug_led noexecute ${led1} green`"
ledscommands="${ledscommands} `guruplug_led noexecute ${led2} green`"
ledscommands="${ledscommands} `guruplug_led noexecute ${led2} blink red`"
eval ${ledscommands}
unset led1; unset led2; unset ledscommands
return 0
}
guruplug_notify() {
[ "a${guruplug}" = "a" ] && return 0
guruplug_leds black
guruplug_leds blink green
[ "a${interactive}" = "a" ] && sleep 5
}
guruplug_error() {
[ "a${guruplug}" = "a" ] && return 0
guruplug_leds black
guruplug_leds blink red
[ "a${interactive}" = "a" ] && sleep 5
}
guruplug_led_exists() {
[ "a${guruplug}" = "a" ] && return 1
[ "a$1" = "a" ] && return 1
for color in ${ledcolors}
do
[ ! -d "${ledpath}/${color}:$1" ] && return 1
done
unset color
return 0
}
guruplug_led_getstate() {
[ "a${guruplug}" = "a" ] && return 0
! guruplug_led_exists "$@" && return 1
for color in ${ledcolors}
do
colorname=`echo ${color} | ${sedbin} -e "s/:/_/g"`
for file in ${ledvariables}
do
if [ -r "${ledpath}/${color}:${1}/${file}" ]; then
value=`${catbin} "${ledpath}/${color}:$1/${file}"`
eval "$1_${colorname}_${file}=\"${value}\""
eval "export $1_${colorname}_${file}"
else
eval "unset $1_${colorname}_${file}"
fi
done
value=`${catbin} "${ledpath}/${color}:$1/trigger" | ${sedbin} -e "s/^\(.*\)\[\(.*\)\]\(.*\)$/\2/g"`
eval "$1_${colorname}_trigger=\"${value}\""
eval "export $1_${colorname}_trigger"
[ "a${value}" != "anone" ] && eval "unset $1_${colorname}_brightness"
done
unset colorname; unset color; unset value; unset file;
debug "Led $1 saved.\n"
set | ${grepbin} "^$1_"
return 0
}
guruplug_state() {
[ "a${guruplug}" = "a" ] && return 0
for ledi in ${allleds}
do
! guruplug_led_getstate ${ledi} && return 1
done
unset ledi
debug "All leds are saved.\n"
return 0
}
guruplug_restore() {
[ "a${guruplug}" = "a" ] && return 0
command=""
for ledi in ${allleds}
do
for color in ${ledcolors}
do
colorname=`echo ${color} | ${sedbin} -e "s/:/_/g"`
for file in trigger ${ledvariables}
do
value=`echo "$1" | ${grepbin} "^${ledi}_${colorname}_${file}=" | ${cutbin} -d= -f2- -s`
if [ "a${value}" != "a" ]; then
debug "echo \"${value}\" > \"${ledpath}/${color}:${ledi}/${file}\"\n"
command="${command} echo \"${value}\" > \"${ledpath}/${color}:${ledi}/${file}\";"
fi
done
done
done
unset LEDSCLEAN
eval ${command}
unset command
unset value; unset file; unset colorname; unset color; unset ledi;
return 0
}
guruplug_restore_state() {
[ "a${guruplug}" = "a" ] && return 0
[ "a${guruplug_original_state}" != "a" ] && guruplug_restore "${guruplug_original_state}" && debug "Original state of GuruPlug leds is now restored.\n" && return 0
debug "Failed to restore GuruPlug leds into original state.\n"
return 1
}
guruplug_save_state() {
[ "a${guruplug}" = "a" ] && return 0
! guruplug_state > /dev/null && return 1
guruplug_original_state=`guruplug_state`
export guruplug_original_state
addexittrap guruplug_restore_state
debug "Original state of GuruPlug leds is saved.\n"
return 0
}
guruplug_probe() {
[ "a${guruplug}" = "a" ] && return 1
[ ! -w "/sys/class/leds/guruplug:green:health/trigger" ] && unset guruplug
[ ! -w "/sys/class/leds/guruplug:green:health/brightness" ] && unset guruplug
[ ! -w "/sys/class/leds/guruplug:red:health/trigger" ] && unset guruplug
[ ! -w "/sys/class/leds/guruplug:red:health/brightness" ] && unset guruplug
[ ! -w "/sys/class/leds/guruplug:green:wmode/trigger" ] && unset guruplug
[ ! -w "/sys/class/leds/guruplug:green:wmode/brightness" ] && unset guruplug
[ ! -w "/sys/class/leds/guruplug:red:wmode/trigger" ] && unset guruplug
[ ! -w "/sys/class/leds/guruplug:red:wmode/brightness" ] && unset guruplug
if [ "a${guruplug}" = "a" ]; then
debug "GuruPlug leds not found, or not accessible.\n"
return 1
else
##############################################
export ledpath="/sys/class/leds"
##############################################
export redcolor="guruplug:red"
export greencolor="guruplug:green"
export ledcolors="${redcolor} ${greencolor}"
##############################################
export leftled="health"
export rightled="wmode"
export allleds="${leftled} ${rightled}"
##############################################
export ledvariables="brightness delay_off delay_on"
##############################################
debug "GuruPlug leds found.\n"
fi
if ! guruplug_save_state; then
unset guruplug
debug "Failed to retrieve state of leds.\n"
return 1
fi
}
config_args_read() {
for arg in "$@"
do
debug "Parsing configuration value: %s.\n" "${arg}"
parse_eval "readconfig" "${arg}" && continue
parse_switches "${arg}"
done
unset arg
}
config_load() {
# If no PIN supplied from command line and $HOME/.3gnet exists, use PIN from there.
[ "a${SIM_PIN}" = "a" -a "a${runhome}" != "a" ] && [ -d "${runhome}" ] && [ -r "${runhome}/.3gpin" ] && SIM_PIN=`${headbin} -1 "${runhome}/.3gpin" 2> /dev/null | ${cutbin} -b1-4` && [ "a${SIM_PIN}" != "a" ] && export SIM_PIN && debug "Loaded PIN value from %s.\n" "${runhome}/.3gpin" && ! pin_valid "${SIM_PIN}" && unset SIM_PIN && debug "PIN supplied was not valid.\n"
# Load PIN from system-wide PIN suppliers
for pinsupplier in "/etc/default/3gpin" "/etc/sysconfig/3gpin" "/etc/3gpin" "/etc/default/sakis3g.3gpin" "/etc/sysconfig/sakis3g.3gpin" "/etc/sakis3g.3gpin"
do
[ -r "${pinsupplier}" ] && unset SIM_PIN && SIM_PIN=`${headbin} -1 "${pinsupplier}" 2> /dev/null | ${cutbin} -b1-4` && [ "a${SIM_PIN}" != "a" ] && export SIM_PIN && debug "Loaded PIN value from %s.\n" "${pinsupplier}" &&! pin_valid "${SIM_PIN}" && unset SIM_PIN && debug "PIN supplied was not valid.\n"
done
unset pinsupplier
# If system-wide configuration exists, load it overriding anything (user configuration/arguments/everything)
for configfile in "/etc/default/sakis3g" "/etc/sysconfig/sakis3g" "/etc/sakis3g.conf"
do
if [ -r "${configfile}" ]; then
debug "Loading system-wide configuration file %s.\n" "${configfile}"
debug show_file "${configfile}"
configargs=`${grepbin} -v "^#" "${configfile}" | ${grepbin} -v "^$" | ${sedbin} -e "s/^\(.*\)$/\"\1\"/g" | ${sedbin} -e "s/^\"\([A-Za-z_]*\)=\"\(.*\)\"\"$/\"\1=\2\"/g" | ${trbin} "\n" " "`
debug "Configuration arguments are: %s\n" "${configargs}"
eval config_args_read ${configargs}
unset configargs
debug "Finished loading file %s.\n" "${configfile}"
else
debug "Configuration file %s does not exist or is not readable.\n" "${configfile}"
fi
done
unset configfile
debug "Configuration file(s) loaded.\n"
}
# Parses command line switch arguments
parse_switch() {
if [ "a$1" = "a$2" -o "a$1" = "a--$2" -o "a$1" = "a-$2" ]; then
debug "Command line switch defined: %s\n" "$1"
return 0
fi
return 1
}
# Parses command line variable settings
parse_eval() {
! find_binary "cut" && return 1
! find_binary "grep" && return 1
if [ "a$1" = "areadconfig" ]; then
readconfig=1
shift
[ "a$1" = "a" ] && unset readconfig && return 1
else
readconfig=0
fi
[ "a`echo "$1" | ${grepbin} "="`" = "a" ] && unset readconfig && return 1
variable=`echo "${1}" | ${cutbin} -d= -f1`
[ "a${variable}" = "a" ] && unset variable && unset readconfig && return 1
value=`echo "${1}" | ${cutbin} -d= -f2-`
[ "a${value}" = "a" ] && unset variable && unset value && unset readconfig && return 1
case "${variable}" in
pppint|PPPINT)
export pppint="${value}"
;;
CHAT_ABORT_STRINGS)
# Abort strings that chat program may encounter
export CHAT_ABORT_STRINGS="${value}"
;;
BAUD)
# Baud rate
if [ "a${value}" = "aMAX" -o "a${value}" = "amax" ]; then
export BAUD="4000000"
elif [ "a${value}" = "aMIN" -o "a${value}" = "amin" ]; then
export BAUD="115200"
elif [ "a${value}" = "aDEFAULT" -o "a${value}" = "adefault" -o "a${value}" = "aNORMAL" -o "a${value}" = "anormal" ]; then
export BAUD="460800"
else
export BAUD="${value}"
fi
;;
PPPD_OPTIONS)
# Options passed to pppd when called directly
export PPPD_OPTIONS="${value}"
;;
PPPD_PEERS)
# Directory where pppd keeps its peers
export PPPD_PEERS="${value}"
;;
XOSDFONT)
# Font that will be used when displaying messages through XOSD (osd_cat)
export XOSDFONT="${value}"
;;
AOSDFONT)
# Font that will be used when displaying messages through XOSD (osd_cat)
export AOSDFONT="${value}"
;;
MENUFONT|menufont)
# Font that will be used when using 9menu
export MENUFONT="${value}"
;;
OSDFONT)
# Font that will be used when displaying messages through XOSD (osd_cat)
export AOSDFONT="${value}"
export XOSDFONT="${value}"
;;
LOGPOSITION|logposition)
# Directory where pppd keeps its peers
export LOGPOSITION="${value}"
;;
DESKTOPICON)
# Directory where pppd keeps its peers
export DESKTOPICON="${value}"
;;
DCOPSERVER)
# Directory where pppd keeps its peers
export DCOPSERVER="${value}"
;;
connection_hook|CONNECTION_HOOK|HOOK)
# Enabling this is a security issue.
# Users can pass argument to do whatever they want.
if [ "a${readconfig}" = "a1" ]; then
export CONNECTION_HOOK="${value}"
else
echo "Ignoring ${variable} variable for security reasons." > /dev/stderr
echo "This variable is only usable through global configuration." > /dev/stderr
echo "Consult documentation." > /dev/stderr
fi
;;
DNS)
export DNS="${value}"
;;
MODEM_PREPARE|PREPARE)
export MODEM_PREPARE="${value}"
INIT_STAGE0=`${printfbin} "%s\n" "${value}" | ${sedbin} -e "s/AT/\\nAT/g" | ${sedbin} -e "s/ *$//g" | ${grepbin} -v "^$" | ${grepbin} "^AT" | ${sedbin} -e "s/^\(.*\)$/\\\'\1\\\' OK/g" | ${trbin} "\n" " "`
export INIT_STAGE0
;;
MODEM_INIT|INIT)
export MODEM_INIT="${value}"
;;
DIAL|CUSTOM_DIAL)
export CUSTOM_DIAL="${value}"
;;
FORCE_APN)
export FORCE_APN="${value}"
;;
CUSTOM_APN)
export CUSTOM_APN="${value}"
;;
APN)
export APN="${value}"
;;
APN_USER)
export APN_USER="${value}"
;;
APN_PASS)
export APN_PASS="${value}"
;;
FORCE_ISP)
export FORCE_ISP="${value}"
;;
SIM_PIN)
export SIM_PIN="${value}"
;;
RFCOMM_TTY)
export RFCOMM_TTY="${value}"
;;
CUSTOM_TTY)
export CUSTOM_TTY="${value}"
;;
RFSERVICE)
export RFSERVICE="${value}"
;;
RFCHANNEL)
export RFCHANNEL="${value}"
;;
UNDISCOVERABLE)
export UNDISCOVERABLE="${value}"
;;
BLUETOOTH)
export BLUETOOTH="${value}"
;;
USBINTERFACE)
export USBINTERFACE="${value}"
;;
USBDRIVER)
export USBDRIVER="${value}"
;;
USBMODEM)
export USBMODEM="${value}"
;;
OTHER)
export OTHER="${value}"
;;
MODEM)
export MODEM="${value}"
;;
MOREMENU)
export MOREMENU="${value}"
;;
MENU)
export MENU="${value}"
;;
DISPLAY)
export DISPLAY="${value}"
;;
XAUTHORITY|LOCALAUTHORITY)
export LOCALAUTHORITY="${value}"
;;
BALOONIZER|BALLOONIZER)
export BALOONIZER="${value}"
;;
DESKTOP)
export DESKTOP="${value}"
;;
SGUI)
export SGUI="${value}"
;;
TRANSLATION)
export TRANSLATION="${value}"
;;
*)
debug "Unknown variable %s specified in command line.\n" "${variable}"
unset variable
;;
esac
unset readconfig
if [ "a${variable}" != "a" ]; then
debug "Command line set variable %s to \"%s\".\n" "${variable}" "`eval echo \\\${${variable}}`"
unset variable; unset value;
return 0
fi
unset variable; unset value
return 1
}
parse_switches() {
parse_switch "${1}" "balloons" && export balloons=yes
parse_switch "${1}" "balloon" && export balloons=yes
parse_switch "${1}" "baloons" && export balloons=yes
parse_switch "${1}" "baloon" && export balloons=yes
parse_switch "${1}" "ballons" && export balloons=yes
parse_switch "${1}" "ballon" && export balloons=yes
parse_switch "${1}" "balons" && export balloons=yes
parse_switch "${1}" "balon" && export balloons=yes
parse_switch "${1}" "b" && export balloons=yes
parse_switch "${1}" "console" && export stick_to_console=yes
parse_switch "${1}" "stick_to_console" && export stick_to_console=yes
parse_switch "${1}" "c" && export stick_to_console=yes
parse_switch "${1}" "debug" && export DEBUG=on
parse_switch "${1}" "DEBUG" && export DEBUG=on
parse_switch "${1}" "d" && export DEBUG=on
parse_switch "${1}" "NOSMART" && export NOSMART=yes
parse_switch "${1}" "NOFIX" && export NOSMART=yes
parse_switch "${1}" "nosmart" && export NOSMART=yes
parse_switch "${1}" "nofix" && export NOSMART=yes
parse_switch "${1}" "smart" && export NOSMART=yes
parse_switch "${1}" "fix" && export NOSMART=yes
parse_switch "${1}" "f" && export NOSMART=yes
parse_switch "${1}" "GOOGLEDNS" && export DNS="8.8.8.8 8.8.4.4"
parse_switch "${1}" "GOOGLE" && export DNS="8.8.8.8 8.8.4.4"
parse_switch "${1}" "googledns" && export DNS="8.8.8.8 8.8.4.4"
parse_switch "${1}" "google" && export DNS="8.8.8.8 8.8.4.4"
parse_switch "${1}" "g" && export DNS="8.8.8.8 8.8.4.4"
parse_switch "${1}" "GURUPLUG" && export guruplug=yes
parse_switch "${1}" "guruplug" && export guruplug=yes
parse_switch "${1}" "GURU" && export guruplug=yes
parse_switch "${1}" "guru" && export guruplug=yes
parse_switch "${1}" "G" && export guruplug=yes
parse_switch "${1}" "nohal" && export nohal=yes
parse_switch "${1}" "hal" && export nohal=yes
parse_switch "${1}" "h" && export nohal=yes
parse_switch "${1}" "interactive" && export interactive=yes
parse_switch "${1}" "i" && export interactive=yes
parse_switch "${1}" "killstorage" && export killstorage=yes
parse_switch "${1}" "nostorage" && export killstorage=yes
parse_switch "${1}" "storage" && export killstorage=yes
parse_switch "${1}" "k" && export killstorage=yes
parse_switch "${1}" "nohalinform" && export nohalinform=yes
parse_switch "${1}" "noinform" && export nohalinform=yes
parse_switch "${1}" "l" && export nohalinform=yes
parse_switch "${1}" "NOPROBE" && export NOPROBEGSM=yes
parse_switch "${1}" "NOPROBEGSM" && export NOPROBEGSM=yes
parse_switch "${1}" "noprobe" && export NOPROBEGSM=yes
parse_switch "${1}" "noprobegsm" && export NOPROBEGSM=yes
parse_switch "${1}" "GSM" && export NOPROBEGSM=yes
parse_switch "${1}" "gsm" && export NOPROBEGSM=yes
parse_switch "${1}" "n" && export NOPROBEGSM=yes
parse_switch "${1}" "prefer_osd" && export prefer_osd=yes
parse_switch "${1}" "preferosd" && export prefer_osd=yes
parse_switch "${1}" "osd" && export prefer_osd=yes
parse_switch "${1}" "OSD" && export prefer_osd=yes
parse_switch "${1}" "o" && export prefer_osd=yes
parse_switch "${1}" "forever" && export forever=yes
parse_switch "${1}" "persist" && export forever=yes
parse_switch "${1}" "P" && export forever=yes
parse_switch "${1}" "directpppd" && export direct_pppd=yes
parse_switch "${1}" "direct_pppd" && export direct_pppd=yes
parse_switch "${1}" "ppp" && export direct_pppd=yes
parse_switch "${1}" "pppd" && export direct_pppd=yes
parse_switch "${1}" "p" && export direct_pppd=yes
parse_switch "${1}" "noverbose" && export noverbose=yes
parse_switch "${1}" "noinformation" && export nonotify=yes
parse_switch "${1}" "nonotifications" && export nonotify=yes
parse_switch "${1}" "nonotify" && export nonotify=yes
parse_switch "${1}" "noerrors" && export noerror=yes
parse_switch "${1}" "noerror" && export noerror=yes
if parse_switch "${1}" "silent" || parse_switch "${1}" "quiet" || parse_switch "${1}" "q"; then
export noerror=yes
export nonotify=yes
export noverbose=yes
fi
parse_switch "${1}" "sudo" && export alwayssudo=yes
parse_switch "${1}" "alwayssudo" && export alwayssudo=yes
parse_switch "${1}" "always_sudo" && export alwayssudo=yes
parse_switch "${1}" "s" && export alwayssudo=yes
parse_switch "${1}" "showtext" && export showtext=yes
parse_switch "${1}" "T" && export showtext=yes
parse_switch "${1}" "notranslate" && export notranslate=yes
parse_switch "${1}" "t" && export notranslate=yes
parse_switch "${1}" "nosafety" && export nosafety=yes
parse_switch "${1}" "unsafe" && export nosafety=yes
parse_switch "${1}" "u" && export nosafety=yes
parse_switch "${1}" "voodoo" && export voodoo=yes
parse_switch "${1}" "please" && export voodoo=yes
parse_switch "${1}" "magic" && export voodoo=yes
parse_switch "${1}" "Voodoo" && export voodoo=yes
parse_switch "${1}" "Please" && export voodoo=yes
parse_switch "${1}" "Magic" && export voodoo=yes
parse_switch "${1}" "v" && export voodoo=yes
parse_switch "${1}" "whiptail" && export SGUI="whiptail"
parse_switch "${1}" "dialog" && export SGUI="dialog"
parse_switch "${1}" "Xdialog" && export SGUI="Xdialog"
parse_switch "${1}" "xdialog" && export SGUI="Xdialog"
parse_switch "${1}" "zenity" && export SGUI="zenity"
parse_switch "${1}" "kdialog" && export SGUI="kdialog"
parse_switch "${1}" "9menu" && export SGUI="9menu"
parse_switch "${1}" "xterm" && export SGUI="xterm"
parse_switch "${1}" "gnome-terminal" && export SGUI="gnome-terminal"
parse_switch "${1}" "konsole" && export SGUI="konsole"
parse_switch "${1}" "interactiveterminal" && export SGUI="interactive terminal"
parse_switch "${1}" "iterm" && export SGUI="interactive terminal"
parse_switch "${1}" "terminal" && export SGUI="terminal"
parse_switch "${1}" "term" && export SGUI="terminal"
if parse_switch "${1}" "legacy"; then
export SGUI="9menu"
export prefer_osd="yes"
fi
parse_switch "${1}" "scanyes" && export scanyes="1"
parse_switch "${1}" "scanno" && export scanno="1"
}
state_variables() {
unset statevariables
for flagvariable in stick_to_console:console interactive:interactive DEBUG:debug NOSMART:nofix killstorage:nostorage NOPROBEGSM:noprobegsm prefer_osd:osd direct_pppd:pppd alwayssudo:sudo forever:forever balloons:balloons
do
variablename=`echo "${flagvariable}" | cut -d: -f1`
strinstr "${variablename}" "${1}" " " && debug "Variable %s excluded from state variables.\n" "${variablename}" && continue
variablearg=`echo "${flagvariable}" | cut -d: -f2`
variablevalue=`eval echo \\\${${variablename}}`
[ "a${variablevalue}" != "a" ] && statevariables="${statevariables} --${variablearg}"
done
unset flagvariable; unset variablename; unset variablearg; unset variablevalue
[ "a${DNS}" = "a8.8.8.8 8.8.4.4" ] && statevariables="${statevariables} --googledns"
[ "a${DNS}" != "a8.8.8.8 8.8.4.4" -a "a${DNS}" != "a" ] && statevariables="${statevariables} DNS=\"${DNS}\""
for valuevariable in MODEM_INIT FORCE_APN APN APN_USER APN_PASS FORCE_ISP SIM_PIN SGUI RFCOMM_TTY CUSTOM_TTY RFSERVICE RFCHANNEL UNDISCOVERABLE BLUETOOTH USBINTERFACE USBDRIVER USBMODEM OTHER MODEM MENU MOREMENU DISPLAY DESKTOP DCOPSERVER LOCALAUTHORITY BALOONIZER
do
strinstr "${valuevariable}" "${1}" " " && debug "Variable %s excluded from state variables.\n" "${valuevariable}" && continue
variablevalue=`eval echo \\\${${valuevariable}}`
[ "a${variablevalue}" != "a" ] && statevariables="${statevariables} ${valuevariable}=\"${variablevalue}\""
done
unset valuevariable; unset variablevalue
statevariables=`echo ${statevariables}`
export statevariables
debug "State variables are: %s\n" "${statevariables}"
return 0
}
# Parses command line arguments
parse_arguments() {
need_binary "tr"
unset allargs
for arg in "$@"
do
varg=`sanitize "${arg}"`
allargs="${allargs} \"${varg}\""
parse_eval "${varg}" && continue
parse_switches "${varg}"
unset varg
done
unset arg
allargs=`echo ${allargs}`
export allargs
}
# Unsets binary variables if running as root. This eliminates the chance
# that a malicious user has succeed into setting a "trojan" binary helper
# that will be executed with root privileges.
secure_path() {
PATH="/bin:/sbin:/usr/bin:/usr/sbin"
export PATH
unset whichbin
unset grepbin
unset cutbin
need_binary "grep"
need_binary "cut"
for variable in `set | ${grepbin} "bin=" | ${cutbin} -d= -f1`
do
value=`eval echo \\${${variable}} 2> /dev/null`
if [ "a${value}" != "a" ] && [ -x "${value}" ]; then
eval "unset ${variable}"
debug "Unset variable %s for security reasons.\n" "${variable}"
fi
done
unset variable; unset value
return 0
}
# Removes \, ", ', ` from variables' contents
secure_variables() {
need_binary "sed"
need_binary "tr"
for variable in DISPLAY XAUTHORITY USERNAME HOME USER DESKTOP
do
debug "Sanitizing %s: %s\n" "${variable}" "`eval echo \"\\${${variable}}\"`"
value=`eval "echo \"\\${${variable}}\"" 2> /dev/null | ${trbin} "\\\\" " " 2> /dev/null | ${trbin} "\"" " " | ${trbin} "'" " " | ${trbin} "\\\`" " "`
debug "Sanitized value: %s\n" "${value}"
eval "${variable}=\"""${value}""\""
eval "${variable}=\"`eval echo \"\\${${variable}}\"`\""
eval "export ${variable}"
debug "Sanitized %s: %s\n" "${variable}" "`eval echo \"\\${${variable}}\"`"
done
unset value; unset variable
return 0
}
secure_capabilities() {
debug "Will check shell capabilities.\n"
set +o monitor > /dev/null 2> /dev/null
set +m > /dev/null 2> /dev/null
funcname=`set | grep "^FUNCNAME="`
if [ "a${funcname}" = "a" ]; then
debug "Shell does not provide FUNCNAME environment variable.\n"
debug "USB Safety will be disabled.\n"
export NOFUNCNAME="1"
unset YESFUNCNAME=""
else
debug "Shell provides FUNCNAME environment variable.\n"
unset NOFUNCNAME
export YESFUNCNAME="1"
fi
unset funcname
return 0
}
# Makes sure no danger exists when run as root
secure_environment() {
secure_capabilities
! we_are_root_already && return 0
secure_path
secure_variables
return 0
}
# Preparation or death
startup() {
# try to set shell as helpful as possible with background jobs
secure_environment
addexittrap cleanscreen
me=$1; [ "$#" -gt "0" ] && shift
# Draftly set allargs. Will better do it during parse_arguments
allargs="$@"; export allargs
no_action_command "$@" && stop_with 0
verbose "Starting up"
parse_arguments "$@"
debug_header "$@"
resolv_binaries "${me}"; unset me
check_udevd "$@"
find_user
config_load
find_display
find_gui
translate_load
check_root_deps
modeswitch_load
guruplug_probe
debug "Finished starting up.\n"
}
# Main program
sakis3g_main() {
# Initialization
startup "$@"
# Get action
action_command "$@" && stop_with ${actionresult}
default_actor
ret=$?
stop_with ${ret}
}
# Execute main method
sakis3g_main $0 "$@"
# In case all actors performed well
debug "Reached end of program.\n"
stop_with 0