iwd-dmenu (5127B)
1 #!/bin/sh 2 # 3 # iwd-dmenu 4 5 NEWLINE=' 6 ' 7 8 iwd_dmenu() { 9 main_menu() { 10 while :; do 11 # get first 802.11 capable device from /sys/class/net 12 interface="$(for dev in /sys/class/net/*; do 13 [ -d "${dev}/wireless/" ] && printf '%s\n' "${dev##*/}" 14 done | head -n 1)" 15 16 # user can connect, disconnect, or forget network 17 # don't care bout access points or other stuff 18 if ! show_menu 'iwd dmenu' 'Connect' 'Disconnect' 'Forget'; then break; fi 19 done 20 } 21 22 connect() { 23 get_network_info "iwctl station ${interface} get-networks" 24 25 # user can choose network to connect to 26 network="$(show_menu 'Connect' "${network_names}")" 27 28 # if network starts with '> ' it means user is already on that network 29 case "${network}" in '> '*) herbe 'Already connected to this network' & return ;; esac 30 31 get_network_info 'iwctl known-networks list' 32 33 # if network is known connect with no passphrase 34 if printf '%s\n' "${network_info}" | awk -F '|' '{print $1}' | grep -iq "\<${network}\>"; then 35 iwctl station "${interface}" connect "${network}" 36 return 37 fi 38 39 get_network_info "iwctl station ${interface} get-networks" 40 41 # if network is wep, psk, or 8021x get passphrase 42 case "$(printf '%s\n' "${network_info}" | grep -i "\<${network}\>" | awk -F '|' '{print $2}')" in 43 'wep'|'psk'|'8021x') get_passphrase ;; 44 # if open just connect without passphrase 45 'open') iwctl station "${interface}" connect "${network}" ;; 46 esac 47 48 # connect with passphrase 49 [ -n "${passphrase}" ] && iwctl --passphrase "${passphrase}" station "${interface}" connect "${network}" 50 } 51 52 disconnect() { 53 connected_network="$(iwctl station "${interface}" show | grep -i '\<Connected network\>' | awk '{ $1=""; $2=""; sub(" ", " "); { $1=$1; print } }')" 54 if [ -n "${connected_network}" ]; then 55 answer="$(show_menu "Disconnect from ${connected_network}?" 'Yes' 'No')" 56 case "$(printf '%s\n' "${answer}" | tr '[:upper:]' '[:lower:]')" in 57 'yes') iwctl station "${interface}" disconnect ;; 58 'no') return ;; 59 esac 60 fi 61 } 62 63 forget() { 64 get_network_info 'iwctl known-networks list' 65 66 # if there are known networks 67 if [ -n "${network_names}" ]; then 68 # get network 69 network="$(show_menu 'Forget' "${network_names}")" 70 71 # get confirmation 72 [ -n "${network}" ] && answer="$(show_menu "Forget ${network}?" 'Yes' 'No')" 73 74 # forget if answer is yes 75 [ "${answer}" = 'Yes' ] && iwctl known-networks "${network}" forget 76 fi 77 } 78 79 # get network column separately 80 get_network_column() { 81 printf '%s\n' "${info}" | awk -v var="${1}" 'BEGIN { FS = "open|wep|psk|8021x" } { print $var }' | sed 's/^[ \t]*//;s/[ \t]*$//' 82 } 83 84 get_network_info() { 85 # scan interface 86 iwctl station "${interface}" scan 87 88 printf '%s\n' "${1}" 89 90 info="$(eval "${1}" | grep '\s' | tail +3 | awk '{ $1 = $1 }; 1' | sed -e 's/\x1b\[[0-9;]*m//g')" 91 92 network_names="$(get_network_column '1')" 93 network_types="$(printf '%s\n' "${info}" | awk '{ for (i=1;i<=NF;i++){ if ($i ~ /open|wep|psk|8021x/) { print $i } } }')" 94 network_metas="$(get_network_column '2')" 95 96 i=1 97 network_info="$(printf '%s\n' "${network_names}" | ( while read -r name; do 98 type_field="$(printf '%s\n' "${network_types}" | sed -n ${i}p)" 99 meta_field="$(printf '%s\n' "${network_metas}" | sed -n ${i}p)" 100 101 if [ ${i} -eq 1 ]; then network_info="${name}|${type_field}|${meta_field}" 102 else network_info="${network_info}${NEWLINE}${name}|${type_field}|${meta_field}" 103 fi 104 105 i=$((i+1)) 106 done 107 printf '%s\n' "${network_info}" ))" 108 } 109 110 # hide input with dmenu -P flag 111 get_passphrase() { passphrase="$(dmenu -c -p 'Passphrase:' -P)" ; } 112 113 show_menu() { 114 # first arg is prompt 115 prompt="${1}" 116 shift 117 118 # remaining opts are options 119 options="$(for option in "${@}"; do 120 printf '%s\n' "${option}" 121 done)" 122 123 # print using dmenu 124 if ! answer="$(printf '%s\n' "${options}" | dmenu -c -l 10 -p "${prompt}")"; then return 1; fi 125 126 # get user's answer 127 printf '%s\n' "${options}" | while read -r line; do 128 if [ "${line}" = "${answer}" ]; then 129 # if answer is a function run it else just print it 130 cmd="$(printf '%s\n' "${answer}" | tr '[:upper:]' '[:lower:]')" 131 if command -v "${cmd}" >/dev/null 2>&1 && [ "${cmd}" != 'yes' ]; then "${cmd}" 132 else printf '%s\n' "${answer}" 133 fi 134 break 135 fi 136 done 137 } 138 139 main_menu 140 } 141 142 main() { iwd_dmenu ; } 143 144 main "${@}"