#!/bin/bash
#
# see if we can implement a gui network device selector
# using zenity
#
# after the initial device selection,
# wrap most of the script in a "progress" window to allow
# updating as we go w/out the user having to deal w/"OK"
# button
#
set -o nounset
WIFIDRIVER="ipw2100"
MODEMDRIVER="slamr"
MODEMDAEMON="slmodemd"
DISPDELAY=1
FULLPATH="/etc/sysconfig/network-scripts/"
DEVPREFIX="ifcfg-"
DEVLIST=""
UPDEVLIST=""
DEVCHOICE=""
DEVMENU="stopall none none"
LASTSTATUS=""
INDEX=""
# arrays device names, types, and dhcp/ip add
declare -a DEVARRAY
declare -a TYPEARRAY
declare -a ADDARRAY
# get list of all the ifcfg- devices
dev_list()
{
FULLDEVLIST=$( ls $FULLPATH$DEVPREFIX* )
# clip the path and ifcfg-, and discard lo
for FULLDEV in $FULLDEVLIST
do
DEV=${FULLDEV/"$FULLPATH$DEVPREFIX"}
[ $DEV != "lo" ] && DEVLIST="$DEVLIST $DEV"
done
}
#make arrays of devices, types, and bootproto/ipadds
make_dev_arrays()
{
DEVARRAY=($DEVLIST)
ARRAYSIZE="${#DEVARRAY[*]}"
# get each device's type and ip add/dhcp setting
# convert all to lower case
# save triads of info in menu list for zenity --list display
let INDEX=0
while [ $INDEX -lt $ARRAYSIZE ]
do
. $FULLPATH$DEVPREFIX${DEVARRAY[$INDEX]}
TYPEARRAY[$INDEX]=$(echo "$TYPE" | tr '[:upper:]' '[:lower:]')
ADDARRAY[$INDEX]=$(echo "$BOOTPROTO" | tr '[:upper:]' '[:lower:]')
[ ${ADDARRAY[$INDEX]} = "none" ] && ADDARRAY[$INDEX]=$IPADDR
DEVMENU="$DEVMENU ${DEVARRAY[$INDEX]} ${TYPEARRAY[$INDEX]} ${ADDARRAY[$INDEX]}"
let INDEX=INDEX+1
done
}
#given an device choice, set index into array
get_index()
{
let INDEX=0
while [ ${DEVARRAY[$INDEX]} != $DEVCHOICE ]
do
let INDEX=INDEX+1
done
}
# display choices w/add'l info and make selection
# may select more than one - but probably not a
# good idea - may hose routing
display_and_choose()
{
DEVCHOICE=$( zenity --list --title="$0: select from available interfaces " \
--separator=" " --column="device" --column="type" --column="ip add" \
$DEVMENU 2>&1)
LASTSTATUS=$?
if [ $(echo "$DEVCHOICE" | wc -w) -gt 1 ]
then
zenity --warning --text="bringing up more than one interface\nmay confuse routing"
[ $? -ne 0 ] && exit 1
fi
}
# "down" all interfaces that are up, except lo
everybody_down()
{
UPDEVLIST=$(/sbin/ifconfig | awk '/^[^\ ]/ {print $1}')
for DEV in $UPDEVLIST
do
[ $DEV = "lo" ] && continue
echo "# ifdown $DEV"
/sbin/ifdown $DEV
done
}
# unload modem driver and daemon if running
unload_modem_driver_and_daemon()
{
echo "# pkill $MODEMDAEMON"
pkill $MODEMDAEMON
sleep $DISPDELAY
echo "# rmmod $MODEMDRIVER"
if awk '{print $1}' /proc/modules | grep -q $MODEMDRIVER
then
/sbin/rmmod $MODEMDRIVER
fi
}
# unload wifi driver if running
unload_wifi_driver()
{
echo "# rmmod $WIFIDRIVER"
if awk '{print $1}' /proc/modules | grep -q $WIFIDRIVER
then
/sbin/rmmod $WIFIDRIVER
fi
}
# load modem driver and start daemon
load_modem_driver_daemon()
{
echo "# modprobe $MODEMDRIVER"
/sbin/modprobe $MODEMDRIVER
LASTSTATUS=$?
[ $LASTSTATUS -ne 0 ] && return
echo "# starting modem daemon"
/usr/sbin/$MODEMDAEMON &
# allow time for daemon to start
sleep 3
LASTSTATUS=0
}
# load the wifi driver
load_wifi_driver()
{
echo "# modprobe $WIFIDRIVER"
/sbin/modprobe $WIFIDRIVER
LASTSTATUS=$?
# there is a strange interaction that causes the following
# ifup to hang a _very_ long time before it returns failure
# status (if it is doomed to fail) if ifup is called immediately
# after this modprobe
# if it is going to succeed, no delay seems necessary
# this is probably an ipw bug -- for now wait 8 seconds
echo "# pausing 8 seconds"
sleep 8
}
# -main- starts here
# better be root at this point
if [ $UID -ne 0 ]
then
zenity --error --text="$0 requires root privileges"
exit 1
fi
# get list of devices
dev_list
if [ "$DEVLIST" = "" ]
then
zenity --error --text="no valid devices found in $FULLPATH!"
exit 1
fi
# get device names, types, ip adds
make_dev_arrays
# if an arg - use it for device name
if [ $# != "0" ]
then
for DEVTRY in $DEVLIST
do
[ "$DEVTRY" = "$1" ] && DEVCHOICE=$DEVTRY
done
if [ "$DEVCHOICE" = "" ]
then
zenity --error --text="invalid device choice "$1"!"
exit 1
fi
else
# display choices, and return choice
# may be more than one
display_and_choose
[ "$LASTSTATUS" -ne 0 ] && exit 1
fi
# wrap the down and up code in zenity progress window so we
# can update messages and (maybe) exit on error w/out having
# to pop up another window (use 100% as exit)
(
# "down" anything that is up except lo
# and turn off any stray device drivers
everybody_down
# dhcp interfaces leave multiple copies of dhclient running
# i don't know if that is bad or good but kill them for now
pkill dhclient
echo "20"
# unload wifi driver and modem driver and daemon
unload_wifi_driver
unload_modem_driver_and_daemon
echo "40"
# if choice was stopall, we are done
if [ "$DEVCHOICE" = "stopall" ]
then
echo "100"
echo "# $DEVCHOICE SUCCESS\nclick OK to exit"
exit 0
fi
# get index into devarray for this interface
get_index
# if TYPE is modem, start modem driver & daemon
if [ "${TYPEARRAY[$INDEX]}" = "modem" ]
then
load_modem_driver_daemon
if [ $LASTSTATUS -ne 0 ]
then
echo "# load modem driver/daemon FAILURE\nclick OK to exit"
exit 1
fi
fi
# if TYPE is wifi, load wireless driver
if [ "${TYPEARRAY[$INDEX]}" = "wireless" ]
then
load_wifi_driver
if [ $LASTSTATUS -ne 0 ]
then
echo "# load wifi driver FAILURE\nclick OK to exit"
exit 1
fi
fi
echo "60"
# start up the chosen interface
# NOTE for modems, using wvdial $DEVCHOICE directly
# instead of ifup in an xterm gets you a "log" for debugging
echo "# ifup $DEVCHOICE"
/sbin/ifup $DEVCHOICE
if [ "$?" -ne 0 ]
then
# try to shut down gracefully
unload_wifi_driver
unload_modem_driver_and_daemon
# when modem fails, it leaves pppd and wvdial running...
pkill -KILL pppd
# dhcp interfaces leave multiple copies of dhclient running
# i don't know if that is bad or good but kill them for now
pkill dhclient
echo "100"
echo "# ifup $DEVCHOICE FAILURE\n- all devices shut down -\nclick OK to exit"
exit 1
fi
echo "100"
echo "# ifup $DEVCHOICE SUCCESS\nclick OK to exit\nmodem will be shut down\nwifi or ethernet stay up"
exit 0
) | zenity --progress --title="$0: working..." --text="" --percentage=0
# unload modem driver and daemon if running
unload_modem_driver_and_daemon >/dev/null
exit 0