From 3ca36638947f69755e956e432fa4f926f42a3faf Mon Sep 17 00:00:00 2001 From: Karthik K Date: Wed, 6 May 2015 22:38:40 +0530 Subject: [PATCH 1/7] Print descriptive messages for several switches * Print messages for terminating switches like --list, --stop, --fix-unmanaged and --daemon * Minor change in help string --- bash_completion | 3 ++- create_ap | 7 ++++++- 2 files changed, 8 insertions(+), 2 deletions(-) diff --git a/bash_completion b/bash_completion index 19f996b..23acf2d 100644 --- a/bash_completion +++ b/bash_completion @@ -111,7 +111,8 @@ _create_ap() { # No Options ;; --stop) - opts=$("$1" --list) + local stop_awk_cmd='$1 ~ /^[0-9]+$/' + opts=$("$1" --list | awk "$stop_awk_cmd") ;; --list) # No Options diff --git a/create_ap b/create_ap index e1b93e4..4edf172 100755 --- a/create_ap +++ b/create_ap @@ -47,7 +47,7 @@ usage() { echo " --freq-band Set frequency band. Valid inputs: 2.4, 5 (default: 2.4)" echo " --driver Choose your WiFi adapter driver (default: nl80211)" echo " --no-virt Do not create virtual interface" - echo " --no-haveged Do not run \`haveged' automatically when needed" + echo " --no-haveged Do not run 'haveged' automatically when needed" echo " --fix-unmanaged If NetworkManager shows your interface as unmanaged after you" echo " close create_ap, then use this option to switch your interface" echo " back to managed" @@ -915,6 +915,7 @@ while :; do esac done +# Check if required number of positional args are present if [[ $# -lt 1 && $FIX_UNMANAGED -eq 0 && -z "$STOP_ID" && $LIST_RUNNING -eq 0 ]]; then usage >&2 exit 1 @@ -934,6 +935,7 @@ trap "clean_exit" SIGINT SIGUSR1 trap "die" SIGUSR2 if [[ $LIST_RUNNING -eq 1 ]]; then + echo -e "List of running $PROGNAME instances:\n" list_running exit 0 fi @@ -944,11 +946,13 @@ if [[ $(id -u) -ne 0 ]]; then fi if [[ -n "$STOP_ID" ]]; then + echo "Trying to kill $PROGNAME instance associated with $STOP_ID..." send_stop "$STOP_ID" exit 0 fi if [[ $FIX_UNMANAGED -eq 1 ]]; then + echo "Trying to fix unmanaged status in NetworkManager..." networkmanager_fix_unmanaged exit 0 fi @@ -959,6 +963,7 @@ if [[ $DAEMONIZE -eq 1 ]]; then for x in "${ARGS[@]}"; do [[ "$x" != "--daemon" ]] && NEW_ARGS+=( "$x" ) done + echo "Running as Daemon..." # run a detached create_ap setsid "$0" "${NEW_ARGS[@]}" & From 13569a5a42dface5c962572db27f8c1c60fd5e11 Mon Sep 17 00:00:00 2001 From: Karthik K Date: Wed, 6 May 2015 22:38:40 +0530 Subject: [PATCH 2/7] Support --mkconfig option When invoked with --mkconfig , the options are stored in conf_file and create_ap exits. --- bash_completion | 11 ++++++ create_ap | 102 +++++++++++++++++++++++++++++++++--------------- 2 files changed, 81 insertions(+), 32 deletions(-) diff --git a/bash_completion b/bash_completion index 23acf2d..3e2dfd1 100644 --- a/bash_completion +++ b/bash_completion @@ -2,6 +2,14 @@ # Bash Completion routine for create_ap # +_use_filedir() { + if [[ $(type -t _filedir) == "function" ]]; then + _filedir + return 0 + fi + return 1 +} + _create_ap() { local awk_cmd=' ($1 ~ /^-/) { @@ -117,6 +125,9 @@ _create_ap() { --list) # No Options ;; + --mkconfig) + _use_filedir && return 0 + ;; -g) # Not going to implement ;; diff --git a/create_ap b/create_ap index 4edf172..467a127 100755 --- a/create_ap +++ b/create_ap @@ -30,37 +30,38 @@ usage() { echo "Usage: "$PROGNAME" [options] [] [ []]" echo echo "Options:" - echo " -h, --help Show this help" - echo " --version Print version number" - echo " -c Channel number (default: 1)" - echo " -w Use 1 for WPA, use 2 for WPA2, use 1+2 for both (default: 1+2)" - echo " -n Disable Internet sharing (if you use this, don't pass" - echo " the argument)" - echo " -m Method for Internet sharing." - echo " Use: 'nat' for NAT (default)" - echo " 'bridge' for bridging" - echo " 'none' for no Internet sharing (equivalent to -n)" - echo " --hidden Make the Access Point hidden (do not broadcast the SSID)" - echo " --ieee80211n Enable IEEE 802.11n (HT)" - echo " --ht_capab HT capabilities (default: [HT40+])" - echo " --country Set two-letter country code for regularity (example: US)" - echo " --freq-band Set frequency band. Valid inputs: 2.4, 5 (default: 2.4)" - echo " --driver Choose your WiFi adapter driver (default: nl80211)" - echo " --no-virt Do not create virtual interface" - echo " --no-haveged Do not run 'haveged' automatically when needed" - echo " --fix-unmanaged If NetworkManager shows your interface as unmanaged after you" - echo " close create_ap, then use this option to switch your interface" - echo " back to managed" - echo " --mac Set MAC address" - echo " --daemon Run create_ap in the background" - echo " --stop Send stop command to an already running create_ap. For an " - echo " you can put the PID of create_ap or the WiFi interface. You can" - echo " get them with --list" - echo " --list Show the create_ap processes that are already running" + echo " -h, --help Show this help" + echo " --version Print version number" + echo " -c Channel number (default: 1)" + echo " -w Use 1 for WPA, use 2 for WPA2, use 1+2 for both (default: 1+2)" + echo " -n Disable Internet sharing (if you use this, don't pass" + echo " the argument)" + echo " -m Method for Internet sharing." + echo " Use: 'nat' for NAT (default)" + echo " 'bridge' for bridging" + echo " 'none' for no Internet sharing (equivalent to -n)" + echo " --hidden Make the Access Point hidden (do not broadcast the SSID)" + echo " --ieee80211n Enable IEEE 802.11n (HT)" + echo " --ht_capab HT capabilities (default: [HT40+])" + echo " --country Set two-letter country code for regularity (example: US)" + echo " --freq-band Set frequency band. Valid inputs: 2.4, 5 (default: 2.4)" + echo " --driver Choose your WiFi adapter driver (default: nl80211)" + echo " --no-virt Do not create virtual interface" + echo " --no-haveged Do not run 'haveged' automatically when needed" + echo " --fix-unmanaged If NetworkManager shows your interface as unmanaged after you" + echo " close create_ap, then use this option to switch your interface" + echo " back to managed" + echo " --mac Set MAC address" + echo " --daemon Run create_ap in the background" + echo " --stop Send stop command to an already running create_ap. For an " + echo " you can put the PID of create_ap or the WiFi interface. You can" + echo " get them with --list" + echo " --list Show the create_ap processes that are already running" + echo " --mkconfig Store configs in conf_file" echo echo "Non-Bridging Options:" - echo " -g IPv4 Gateway for the Access Point (default: 192.168.12.1)" - echo " -d DNS server will take into account /etc/hosts" + echo " -g IPv4 Gateway for the Access Point (default: 192.168.12.1)" + echo " -d DNS server will take into account /etc/hosts" echo echo "Useful informations:" echo " * If you're not using the --no-virt option, then you can create an AP with the same" @@ -574,14 +575,21 @@ IEEE80211N=0 HT_CAPAB='[HT40+]' DRIVER=nl80211 NO_VIRT=0 -FIX_UNMANAGED=0 COUNTRY= FREQ_BAND=2.4 NEW_MACADDR= DAEMONIZE=0 +NO_HAVEGED=0 + +CONFIG_OPTS=(CHANNEL GATEWAY WPA_VERSION ETC_HOST HIDDEN SHARE_METHOD + IEEE80211N HT_CAPAB DRIVER NO_VIRT COUNTRY FREQ_BAND + NEW_MACADDR DAEMONIZE NO_HAVEGED) + +FIX_UNMANAGED=0 LIST_RUNNING=0 STOP_ID= -NO_HAVEGED=0 + +STORE_CONFIG= CONFDIR= WIFI_IFACE= @@ -806,8 +814,31 @@ send_stop() { mutex_unlock } +# Storing configs +write_config() { + local i=1 + + if ! eval 'echo -n > "$STORE_CONFIG"' > /dev/null 2>&1; then + echo "ERROR: Unable to create config file $STORE_CONFIG" >&2 + exit 1 + fi + + for config_opt in "${CONFIG_OPTS[@]}"; do + eval echo $config_opt=\$$config_opt + done >> "$STORE_CONFIG" + + while [[ $# -ne 0 ]]; do + echo "ARG$i=$1" + shift + ((i++)) + done >> "$STORE_CONFIG" + + echo -e "\nConfigs written to $STORE_CONFIG" + exit 0 +} + ARGS=( "$@" ) -GETOPT_ARGS=$(getopt -o hc:w:g:dnm: -l "help","hidden","ieee80211n","ht_capab:","driver:","no-virt","fix-unmanaged","country:","freq-band:","mac:","daemon","stop:","list","version","no-haveged" -n "$PROGNAME" -- "$@") +GETOPT_ARGS=$(getopt -o hc:w:g:dnm: -l "help","hidden","ieee80211n","ht_capab:","driver:","no-virt","fix-unmanaged","country:","freq-band:","mac:","daemon","stop:","list","version","no-haveged","mkconfig:" -n "$PROGNAME" -- "$@") [[ $? -ne 0 ]] && exit 1 eval set -- "$GETOPT_ARGS" @@ -908,6 +939,11 @@ while :; do shift NO_HAVEGED=1 ;; + --mkconfig) + shift + STORE_CONFIG="$1" + shift + ;; --) shift break @@ -934,6 +970,8 @@ trap "clean_exit" SIGINT SIGUSR1 # if we get USR2 signal then run die(). trap "die" SIGUSR2 +[[ -n "$STORE_CONFIG" ]] && write_config "$@" + if [[ $LIST_RUNNING -eq 1 ]]; then echo -e "List of running $PROGNAME instances:\n" list_running From 583ef73fa156635c57e817870fa863bb020465d3 Mon Sep 17 00:00:00 2001 From: Karthik K Date: Thu, 7 May 2015 11:40:30 +0530 Subject: [PATCH 3/7] Support --config option --config loads configs from conf_file --- bash_completion | 3 +++ create_ap | 72 ++++++++++++++++++++++++++++++++++++++++++++++++- 2 files changed, 74 insertions(+), 1 deletion(-) diff --git a/bash_completion b/bash_completion index 3e2dfd1..dbc1af2 100644 --- a/bash_completion +++ b/bash_completion @@ -128,6 +128,9 @@ _create_ap() { --mkconfig) _use_filedir && return 0 ;; + --config) + _use_filedir && return 0 + ;; -g) # Not going to implement ;; diff --git a/create_ap b/create_ap index 467a127..604d52c 100755 --- a/create_ap +++ b/create_ap @@ -58,6 +58,7 @@ usage() { echo " get them with --list" echo " --list Show the create_ap processes that are already running" echo " --mkconfig Store configs in conf_file" + echo " --config Load configs from conf_file" echo echo "Non-Bridging Options:" echo " -g IPv4 Gateway for the Access Point (default: 192.168.12.1)" @@ -590,6 +591,9 @@ LIST_RUNNING=0 STOP_ID= STORE_CONFIG= +LOAD_CONFIG= + +declare -A LOADED_ARGS CONFDIR= WIFI_IFACE= @@ -837,8 +841,61 @@ write_config() { exit 0 } +is_config_opt() { + local elem opt="$1" + + for elem in "${CONFIG_OPTS[@]}"; do + if [[ "$elem" == "$opt" ]]; then + return 0 + fi + done + return 1 +} + +# Load options from config file +read_config() { + local opt_name opt_val + local pos_max=0 pos_num=0 pos_idx + + while read line; do + # Read switches and their values + opt_name="${line%=*}" + opt_val="${line#*=}" + if is_config_opt "$opt_name" ; then + eval $opt_name="\$opt_val" + elif [[ "$opt_name" =~ ^ARG([1-9][0-9]*)$ ]]; then + pos_idx="${BASH_REMATCH[1]}" + ((pos_num++)) + [[ $pos_idx > $pos_max ]] && pos_max=$pos_idx + LOADED_ARGS[$pos_idx]="$opt_val" + else + echo "WARN: Unrecognized configuration entry $opt_name" >&2 + fi + done < "$LOAD_CONFIG" + + if [[ $pos_num -ne $pos_max ]]; then + echo "ERROR: Positional arguments cannot be skipped" >&2 + exit 1 + fi +} + + ARGS=( "$@" ) -GETOPT_ARGS=$(getopt -o hc:w:g:dnm: -l "help","hidden","ieee80211n","ht_capab:","driver:","no-virt","fix-unmanaged","country:","freq-band:","mac:","daemon","stop:","list","version","no-haveged","mkconfig:" -n "$PROGNAME" -- "$@") +# Preprocessing for --config before option-parsing starts +for ((i=0; i<$#; i++)); do + if [[ "${ARGS[i]}" = "--config" ]]; then + if [[ -f "${ARGS[i+1]}" ]]; then + LOAD_CONFIG="${ARGS[i+1]}" + read_config + else + echo "ERROR: No config file found at given location" >&2 + exit 1 + fi + break + fi +done + +GETOPT_ARGS=$(getopt -o hc:w:g:dnm: -l "help","hidden","ieee80211n","ht_capab:","driver:","no-virt","fix-unmanaged","country:","freq-band:","mac:","daemon","stop:","list","version","no-haveged","mkconfig:","config:" -n "$PROGNAME" -- "$@") [[ $? -ne 0 ]] && exit 1 eval set -- "$GETOPT_ARGS" @@ -944,6 +1001,10 @@ while :; do STORE_CONFIG="$1" shift ;; + --config) + shift + shift + ;; --) shift break @@ -951,6 +1012,15 @@ while :; do esac done +# Load positional args from config file, if needed +if [[ -n "$LOAD_CONFIG" ]]; then + for ((i=$# + 1; i<=${#LOADED_ARGS[@]}; i++)); do + ((j=i-1)) + ((k=i+1)) + set -- "${@:1:$j}" "${LOADED_ARGS[$i]}" "${@:$k}" + done +fi + # Check if required number of positional args are present if [[ $# -lt 1 && $FIX_UNMANAGED -eq 0 && -z "$STOP_ID" && $LIST_RUNNING -eq 0 ]]; then usage >&2 From ee69810dc5efcf2305a07d3623c1f61044638fa8 Mon Sep 17 00:00:00 2001 From: oblique Date: Sun, 17 May 2015 18:42:25 +0300 Subject: [PATCH 4/7] Fix typo in CONFIG_OPTS array --- create_ap | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/create_ap b/create_ap index 604d52c..b399338 100755 --- a/create_ap +++ b/create_ap @@ -582,7 +582,7 @@ NEW_MACADDR= DAEMONIZE=0 NO_HAVEGED=0 -CONFIG_OPTS=(CHANNEL GATEWAY WPA_VERSION ETC_HOST HIDDEN SHARE_METHOD +CONFIG_OPTS=(CHANNEL GATEWAY WPA_VERSION ETC_HOSTS HIDDEN SHARE_METHOD IEEE80211N HT_CAPAB DRIVER NO_VIRT COUNTRY FREQ_BAND NEW_MACADDR DAEMONIZE NO_HAVEGED) From 92d35c0da301adc4aba05392959b66b729bc8c46 Mon Sep 17 00:00:00 2001 From: oblique Date: Sun, 17 May 2015 18:44:04 +0300 Subject: [PATCH 5/7] Fix daemonize infinite loop If `DAEMONIZE=1' is set in the config file then create_ap tries to create daemon process all the time. This is done because we were removing `--daemon' option from the parameters of the daemon process. We fix this by using an environment variable instead. --- create_ap | 10 ++-------- 1 file changed, 2 insertions(+), 8 deletions(-) diff --git a/create_ap b/create_ap index b399338..9a50548 100755 --- a/create_ap +++ b/create_ap @@ -1065,16 +1065,10 @@ if [[ $FIX_UNMANAGED -eq 1 ]]; then exit 0 fi -if [[ $DAEMONIZE -eq 1 ]]; then - # remove --daemon - NEW_ARGS=( ) - for x in "${ARGS[@]}"; do - [[ "$x" != "--daemon" ]] && NEW_ARGS+=( "$x" ) - done +if [[ $DAEMONIZE -eq 1 && $RUNNING_AS_DAEMON -eq 0 ]]; then echo "Running as Daemon..." - # run a detached create_ap - setsid "$0" "${NEW_ARGS[@]}" & + RUNNING_AS_DAEMON=1 setsid "$0" "${ARGS[@]}" & exit 0 fi From ce8d4c9ee56dcdcf9d9a853542090c34118ee088 Mon Sep 17 00:00:00 2001 From: oblique Date: Sun, 17 May 2015 19:08:18 +0300 Subject: [PATCH 6/7] All positional arguments are overridden if user pass at least one of them --- create_ap | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/create_ap b/create_ap index 9a50548..b78693e 100755 --- a/create_ap +++ b/create_ap @@ -1013,7 +1013,7 @@ while :; do done # Load positional args from config file, if needed -if [[ -n "$LOAD_CONFIG" ]]; then +if [[ -n "$LOAD_CONFIG" && $# -eq 0 ]]; then for ((i=$# + 1; i<=${#LOADED_ARGS[@]}; i++)); do ((j=i-1)) ((k=i+1)) From df727ff5fd03c097f19ad39b7fda9be5926e2d92 Mon Sep 17 00:00:00 2001 From: oblique Date: Sun, 17 May 2015 19:10:55 +0300 Subject: [PATCH 7/7] Use option names for positional arguments instead of ARG[1-4] --- create_ap | 51 ++++++++++++++++++++++++--------------------------- 1 file changed, 24 insertions(+), 27 deletions(-) diff --git a/create_ap b/create_ap index b78693e..0bf0967 100755 --- a/create_ap +++ b/create_ap @@ -584,7 +584,8 @@ NO_HAVEGED=0 CONFIG_OPTS=(CHANNEL GATEWAY WPA_VERSION ETC_HOSTS HIDDEN SHARE_METHOD IEEE80211N HT_CAPAB DRIVER NO_VIRT COUNTRY FREQ_BAND - NEW_MACADDR DAEMONIZE NO_HAVEGED) + NEW_MACADDR DAEMONIZE NO_HAVEGED WIFI_IFACE INTERNET_IFACE + SSID PASSPHRASE) FIX_UNMANAGED=0 LIST_RUNNING=0 @@ -593,8 +594,6 @@ STOP_ID= STORE_CONFIG= LOAD_CONFIG= -declare -A LOADED_ARGS - CONFDIR= WIFI_IFACE= VWIFI_IFACE= @@ -827,17 +826,21 @@ write_config() { exit 1 fi + WIFI_IFACE=$1 + if [[ "$SHARE_METHOD" == "none" ]]; then + SSID=$2 + PASSPHRASE=$3 + else + INTERNET_IFACE=$2 + SSID=$3 + PASSPHRASE=$4 + fi + for config_opt in "${CONFIG_OPTS[@]}"; do eval echo $config_opt=\$$config_opt done >> "$STORE_CONFIG" - while [[ $# -ne 0 ]]; do - echo "ARG$i=$1" - shift - ((i++)) - done >> "$STORE_CONFIG" - - echo -e "\nConfigs written to $STORE_CONFIG" + echo -e "Config options written to '$STORE_CONFIG'" exit 0 } @@ -854,29 +857,18 @@ is_config_opt() { # Load options from config file read_config() { - local opt_name opt_val - local pos_max=0 pos_num=0 pos_idx + local opt_name opt_val line while read line; do # Read switches and their values - opt_name="${line%=*}" + opt_name="${line%%=*}" opt_val="${line#*=}" if is_config_opt "$opt_name" ; then eval $opt_name="\$opt_val" - elif [[ "$opt_name" =~ ^ARG([1-9][0-9]*)$ ]]; then - pos_idx="${BASH_REMATCH[1]}" - ((pos_num++)) - [[ $pos_idx > $pos_max ]] && pos_max=$pos_idx - LOADED_ARGS[$pos_idx]="$opt_val" else echo "WARN: Unrecognized configuration entry $opt_name" >&2 fi done < "$LOAD_CONFIG" - - if [[ $pos_num -ne $pos_max ]]; then - echo "ERROR: Positional arguments cannot be skipped" >&2 - exit 1 - fi } @@ -1014,10 +1006,15 @@ done # Load positional args from config file, if needed if [[ -n "$LOAD_CONFIG" && $# -eq 0 ]]; then - for ((i=$# + 1; i<=${#LOADED_ARGS[@]}; i++)); do - ((j=i-1)) - ((k=i+1)) - set -- "${@:1:$j}" "${LOADED_ARGS[$i]}" "${@:$k}" + i=0 + # set arguments in order + for x in WIFI_IFACE INTERNET_IFACE SSID PASSPHRASE; do + if eval "[[ -n \"\$${x}\" ]]"; then + eval "set -- \"\${@:1:$i}\" \"\$${x}\"" + ((i++)) + fi + # we unset the variable to avoid any problems later + eval "unset $x" done fi