Skip to content

Instantly share code, notes, and snippets.

@jneen
Created May 30, 2014 00:14
Show Gist options
  • Save jneen/d697fbb42399806f46cf to your computer and use it in GitHub Desktop.
Save jneen/d697fbb42399806f46cf to your computer and use it in GitHub Desktop.
/usr/local/bin/wifi
#!/bin/bash
. /usr/lib/network/globals
. "$SUBR_DIR"/wpa
BIN_DIR="$(dirname "$0")"
PREFIX="${WIFI_PREFIX:-$BIN_DIR/..}"
LIB_DIR="$PREFIX/lib/wifi"
NOW="$(date +%s)"
CACHE_FILE="$LIB_DIR/cache.$(($NOW / 20 / 60))"
INTERFACE=wifi
LOG=1
EDITOR="${EDITOR:-/bin/vi}"
edit() { "$EDITOR" "$@" ;}
exists?() { type "$1" >/dev/null 2>/dev/null ;}
info() { [[ $LOG=1 ]] && echo "$@" >&2 ;}
p() { echo "$@" >&2 ;}
error() { echo "$@" >&2; exit 1 ;}
input() {
local input_var="$1"; shift
local confirm
p "$@"
read "$input_var"
echo "${!input_var}"
printf "...is this correct? (y/n) "
read confirm
case "$confirm" in
y|Y|yes) ;;
*) input "$input_var" "$@"
esac
}
wifi::usage() {
cat <<EOF >&2
usage:
wifi <command> [opts...]
wifi profile <profile> print the configuration for the given profile
wifi profile-attr <profile> <attr> print the given <attr> of configured <profile>
wifi edit <profile> edit the given profile with \$EDITOR (currently $EDITOR)
wifi rm <profile> remove the configured <profile>
wifi connect <profile> [command...] try to connect to <profile> and run <command> if successful
wifi menu [args...] open a wifi connection dialog
wifi new <profile> <ssid> create a new profile with the given name and ssid
wifi ls list networks in range
wifi scan scan for networks in range
wifi configured list configured networks
wifi auto connect to the first configured network in range
EOF
}
wifi::profile() {
local profile_name="$1"; shift
local profile_path=/etc/netctl/"$profile_name"
[[ -s "$profile_path" ]] || error "no such profile '$profile_name'"
cat "$profile_path"
}
wifi::profile-attr() {
local profile="$1"; shift
local attr="$1"; shift
[[ -s /etc/netctl/"$profile" ]] || error "no such profile: '$profile'"
(
. /etc/netctl/"$profile"
echo ${!attr}
) | cat # force a subshell
}
wifi::edit() {
local profile_name="$1"; shift
edit /etc/netctl/"$profile_name"
wifi profile "$profile_name"
}
wifi::rm() {
local profile_name="$1"; shift
rm /etc/netctl/"$profile_name"
}
wifi::connect() {
local profile_name="$1"; shift
info "connecting to '$profile_name'"
netctl switch-to "$profile_name"
if [[ -n "$@" ]]; then
"$@"
else
ping 8.8.8.8
fi
}
wifi::menu() {
wifi-menu "$@"
}
escape() { printf "'${1//\'/\'\\\'\'}'" ;}
wifi::new() {
local profile="$1"; shift
local ssid="$1"; shift
input password "Enter the password for $ssid:"
echo "creating profile '$profile'..."
{
echo "Description='auto'"
echo "Interface=$(escape "$INTERFACE")"
echo "Connection=wireless"
echo "IP=dhcp"
echo "ESSID=$(escape "$ssid")"
echo "Security=wpa"
echo "Key=$(escape "$password")"
} > /etc/netctl/"$profile"
chown root:network /etc/netclt/"$profile"
wifi edit "$profile"
}
wifi::profiles() {
netctl list | sed -E 's/^[*]?\s*//' | while read profile; do
[[ "$(wifi profile-attr "$profile" Interface)" = "$INTERFACE" ]] && echo "$profile"
done
return 0
}
wifi::ls() {
local signal flags ssid
cached-scan | while IFS=$'\t' read signal flags ssid; do
echo "$signal"$'\t'"$ssid"$'\t'"$flags"
done
}
cached-scan() {
[[ -s "$CACHE_FILE" ]] || scan
cat "$CACHE_FILE"
}
wifi::configured() {
local ssids="$(cached-scan | cut -d$'\t' -f3)"
local profile
local ssid
wifi profiles | while read profile; do
ssid="$(wifi profile-attr "$profile" ESSID)"
[[ -n "$ssid" ]] && fgrep -q "$ssid" <<<"$ssids" && {
echo "$profile"
}
done
return 0
}
wifi::auto() {
local configured="$(wifi configured | head -1)"
if [[ -n "$configured" ]]; then
wifi connect "$configured"
else
error "no configured networks."
fi
}
scan() {
info 'scanning...'
wifi clean
local file="$(wpa_supplicant_scan "$INTERFACE" 3,4,5 || error "scan failed!")"
mv "$file" "$CACHE_FILE"
}
wifi::scan() {
scan && wifi ls
}
wifi::clean() { find "$LIB_DIR" -name 'cache.*' -delete ;}
wifi() {
while [[ $# -gt 0 ]]; do
local switch="$1"; shift
case "$switch" in
-i|--interface) INTERFACE="$1"; shift ;;
help|-h|--help|-?) wifi usage ;;
*)
if exists? wifi::"$switch"; then
wifi::"$switch" "$@"
return $?
else
error "no such command \`$1'"
fi
;;
esac
done
}
wifi "$@"
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment