Merge pull request #91 from FluxionNetwork/airmon-ng-independence
Airmon ng independence
This commit is contained in:
commit
c170ece3cf
|
@ -74,7 +74,7 @@ function captive_portal_set_auth() {
|
||||||
}
|
}
|
||||||
|
|
||||||
function captive_portal_run_certificate_generator() {
|
function captive_portal_run_certificate_generator() {
|
||||||
xterm -title "Generating Self-Signed SSL Certificate" -e openssl req -subj '/CN=captive.router.lan/O=CaptivePortal/OU=Networking/C=US' -new -newkey rsa:2048 -days 365 -nodes -x509 -keyout "$FLUXIONWorkspacePath/server.pem" -out "$FLUXIONWorkspacePath/server.pem" # more details there https://www.openssl.org/docs/manmaster/apps/openssl.html
|
xterm -bg "#000000" -fg "#CCCCCC" -title "Generating Self-Signed SSL Certificate" -e openssl req -subj '/CN=captive.router.lan/O=CaptivePortal/OU=Networking/C=US' -new -newkey rsa:2048 -days 365 -nodes -x509 -keyout "$FLUXIONWorkspacePath/server.pem" -out "$FLUXIONWorkspacePath/server.pem" # more details there https://www.openssl.org/docs/manmaster/apps/openssl.html
|
||||||
chmod 400 "$FLUXIONWorkspacePath/server.pem"
|
chmod 400 "$FLUXIONWorkspacePath/server.pem"
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -357,6 +357,7 @@ if __name__ == '__main__':
|
||||||
|
|
||||||
function signal_stop_attack() {
|
function signal_stop_attack() {
|
||||||
kill -s SIGABRT $$ # Signal STOP ATTACK
|
kill -s SIGABRT $$ # Signal STOP ATTACK
|
||||||
|
handle_abort_authenticator
|
||||||
}
|
}
|
||||||
|
|
||||||
function handle_abort_authenticator() {
|
function handle_abort_authenticator() {
|
||||||
|
@ -835,7 +836,7 @@ function start_attack() {
|
||||||
xterm $FLUXIONHoldXterm $BOTTOMRIGHT -bg "#000000" -fg "#FF0009" -title "FLUXION AP Jammer [mdk3] $APTargetSSID" -e mdk3 $WIMonitor d -b "$FLUXIONWorkspacePath/mdk3_blacklist.lst" -c $APTargetChannel &
|
xterm $FLUXIONHoldXterm $BOTTOMRIGHT -bg "#000000" -fg "#FF0009" -title "FLUXION AP Jammer [mdk3] $APTargetSSID" -e mdk3 $WIMonitor d -b "$FLUXIONWorkspacePath/mdk3_blacklist.lst" -c $APTargetChannel &
|
||||||
|
|
||||||
echo -e "$FLUXIONVLine $CaptivePortalStartingAuthenticatorServiceNotice"
|
echo -e "$FLUXIONVLine $CaptivePortalStartingAuthenticatorServiceNotice"
|
||||||
xterm -hold $TOPRIGHT -title "FLUXION AP Authenticator" -e "$FLUXIONWorkspacePath/captive_portal_authenticator.sh" &
|
xterm -hold $TOPRIGHT -bg "#000000" -fg "#CCCCCC" -title "FLUXION AP Authenticator" -e "$FLUXIONWorkspacePath/captive_portal_authenticator.sh" &
|
||||||
}
|
}
|
||||||
|
|
||||||
# FLUXSCRIPT END
|
# FLUXSCRIPT END
|
||||||
|
|
93
fluxion.sh
93
fluxion.sh
|
@ -40,6 +40,7 @@ FLUXIONPrompt="$CRed[${CBlu}fluxion$CYel@$CClr$HOSTNAME$CRed]-[$CYel~$CRed]$CClr
|
||||||
FLUXIONVLine="$CRed[$CYel*$CRed]$CClr"
|
FLUXIONVLine="$CRed[$CYel*$CRed]$CClr"
|
||||||
|
|
||||||
################################# < Library Includes > #################################
|
################################# < Library Includes > #################################
|
||||||
|
source lib/InterfaceUtils.sh
|
||||||
source lib/SandboxUtils.sh
|
source lib/SandboxUtils.sh
|
||||||
source lib/FormatUtils.sh
|
source lib/FormatUtils.sh
|
||||||
source lib/IOUtils.sh
|
source lib/IOUtils.sh
|
||||||
|
@ -48,6 +49,8 @@ source lib/HashUtils.sh
|
||||||
source language/English.lang
|
source language/English.lang
|
||||||
|
|
||||||
################################ < Library Parameters > ################################
|
################################ < Library Parameters > ################################
|
||||||
|
InterfaceUtilsOutputDevice="$FLUXIONOutputDevice"
|
||||||
|
|
||||||
SandboxWorkspacePath="$FLUXIONWorkspacePath"
|
SandboxWorkspacePath="$FLUXIONWorkspacePath"
|
||||||
SandboxOutputDevice="$FLUXIONOutputDevice"
|
SandboxOutputDevice="$FLUXIONOutputDevice"
|
||||||
|
|
||||||
|
@ -57,6 +60,9 @@ IOUtilsPrompt="$FLUXIONPrompt"
|
||||||
|
|
||||||
HashOutputDevice="$FLUXIONOutputDevice"
|
HashOutputDevice="$FLUXIONOutputDevice"
|
||||||
|
|
||||||
|
################################# < User Preferences > #################################
|
||||||
|
if [ -x "$FLUXIONPath/preferences.sh" ]; then source "$FLUXIONPath/preferences.sh"; fi
|
||||||
|
|
||||||
########################################################################################
|
########################################################################################
|
||||||
if [[ $EUID -ne 0 ]]; then
|
if [[ $EUID -ne 0 ]]; then
|
||||||
echo -e "${CRed}You don't have admin privilegies, execute the script as root.$CClr"
|
echo -e "${CRed}You don't have admin privilegies, execute the script as root.$CClr"
|
||||||
|
@ -98,7 +104,10 @@ function exitmode() {
|
||||||
|
|
||||||
if [ "$WIMonitor" ]; then
|
if [ "$WIMonitor" ]; then
|
||||||
echo -e "$CWht[$CRed-$CWht] $FLUXIONDisablingMonitorNotice$CGrn $WIMonitor$CClr"
|
echo -e "$CWht[$CRed-$CWht] $FLUXIONDisablingMonitorNotice$CGrn $WIMonitor$CClr"
|
||||||
airmon-ng stop $WIMonitor &> $FLUXIONOutputDevice
|
if [ "$FLUXIONAirmonNG" ]
|
||||||
|
then airmon-ng stop "$WIMonitor" &> $FLUXIONOutputDevice
|
||||||
|
else interface_set_mode "$WIMonitor" "managed"
|
||||||
|
fi
|
||||||
fi
|
fi
|
||||||
|
|
||||||
echo -e "$CWht[$CRed-$CWht] $FLUXIONRestoringTputNotice$CClr"
|
echo -e "$CWht[$CRed-$CWht] $FLUXIONRestoringTputNotice$CClr"
|
||||||
|
@ -207,7 +216,6 @@ function handle_exit() {
|
||||||
# to execute cleanup and reset commands.
|
# to execute cleanup and reset commands.
|
||||||
trap handle_exit SIGINT SIGHUP
|
trap handle_exit SIGINT SIGHUP
|
||||||
|
|
||||||
# Design
|
|
||||||
function fluxion_header() {
|
function fluxion_header() {
|
||||||
format_apply_autosize "[%*s]\n"
|
format_apply_autosize "[%*s]\n"
|
||||||
local verticalBorder=$FormatApplyAutosize
|
local verticalBorder=$FormatApplyAutosize
|
||||||
|
@ -443,11 +451,16 @@ function unset_interface() {
|
||||||
# Remove all monitor-mode & all AP interfaces.
|
# Remove all monitor-mode & all AP interfaces.
|
||||||
echo -e "$FLUXIONVLine $FLUXIONRemovingExtraWINotice"
|
echo -e "$FLUXIONVLine $FLUXIONRemovingExtraWINotice"
|
||||||
if [ ${#WIMonitors[@]} -gt 0 ]; then
|
if [ ${#WIMonitors[@]} -gt 0 ]; then
|
||||||
|
local monitor
|
||||||
for monitor in ${WIMonitors[@]}; do
|
for monitor in ${WIMonitors[@]}; do
|
||||||
# Replace interface's mon with ap & remove interface.
|
# Remove any previously created fluxion AP interfaces.
|
||||||
iw dev ${monitor/mon/ap} del 2> $FLUXIONOutputDevice
|
iw dev "${monitor}FLXap" del 2> $FLUXIONOutputDevice
|
||||||
|
|
||||||
# Remove monitoring interface after AP interface.
|
# Remove monitoring interface after AP interface.
|
||||||
airmon-ng stop $monitor > $FLUXIONOutputDevice
|
if [[ "$monitor" = *"mon" ]]
|
||||||
|
then airmon-ng stop "$monitor" > $FLUXIONOutputDevice
|
||||||
|
else interface_set_mode "$monitor" "managed"
|
||||||
|
fi
|
||||||
|
|
||||||
if [ $FLUXIONDebug ]; then
|
if [ $FLUXIONDebug ]; then
|
||||||
echo -e "Stopped $monitor."
|
echo -e "Stopped $monitor."
|
||||||
|
@ -468,35 +481,38 @@ function set_interface() {
|
||||||
# Gather candidate interfaces.
|
# Gather candidate interfaces.
|
||||||
echo -e "$FLUXIONVLine $FLUXIONFindingWINotice"
|
echo -e "$FLUXIONVLine $FLUXIONFindingWINotice"
|
||||||
|
|
||||||
# Create an array with the list of all available wireless network interfaces.
|
# List of all available wireless network interfaces.
|
||||||
local WIAvailableData
|
# These will be stored in our array right below.
|
||||||
readarray -t WIAvailableData < <(airmon-ng | grep -P 'wl(an\d+|\w+)' | sed -r 's/[ ]{2,}|\t+/:_:/g')
|
interface_list_wireless
|
||||||
local WIAvailableDataCount=${#WIAvailableData[@]}
|
|
||||||
local WIAvailable=()
|
local WIAvailable=("${InterfaceListWireless[@]}")
|
||||||
local WIAvailableInfo=()
|
local WIAvailableInfo=()
|
||||||
local WIAvailableColor=()
|
local WIAvailableColor=()
|
||||||
|
|
||||||
for (( i = 0; i < WIAvailableDataCount; i++ )); do
|
local wiCandidate
|
||||||
local data="${WIAvailableData[i]}"
|
for wiCandidate in "${WIAvailable[@]}"; do
|
||||||
WIAvailable[i]=$(echo "$data" | awk -F':_:' '{print $2}')
|
interface_chipset "$wiCandidate"
|
||||||
WIAvailableInfo[i]=$(echo "$data" | awk -F':_:' '{print $4}')
|
WIAvailableInfo+=("$InterfaceChipset")
|
||||||
if [ "`ifconfig ${WIAvailable[i]} | grep "RUNNING"`" ]; then
|
|
||||||
WIAvailableColor[i]="$CPrp"
|
interface_state "$wiCandidate"
|
||||||
WIAvailableState[i]="-"
|
|
||||||
else
|
if [ "$InterfaceState" = "up" ]
|
||||||
WIAvailableColor[i]="$CClr"
|
then WIAvailableColor+=("$CPrp"); WIAvailableState+=("-")
|
||||||
WIAvailableState[i]="+"
|
else WIAvailableColor+=("$CClr"); WIAvailableState+=("+")
|
||||||
fi
|
fi
|
||||||
done
|
done
|
||||||
|
|
||||||
WIAvailable[${#WIAvailable[@]}]="$FLUXIONGeneralRepeatOption"
|
# We'll add an extra option here, the back command.
|
||||||
WIAvailableColor[${#WIAvailableColor[@]}]="$CClr" # (Increases record count)
|
# Color must be incresed since it's the first array,
|
||||||
WIAvailableState[${#WIAvailableState[@]}]="x"
|
# and the io function checks only the first's size.
|
||||||
|
WIAvailableColor+=("$CClr") # (Increases record count)
|
||||||
|
WIAvailable+=("$FLUXIONGeneralRepeatOption")
|
||||||
|
WIAvailableState+=("x")
|
||||||
|
|
||||||
local WISelected
|
local WISelected
|
||||||
local WISelectedState
|
local WISelectedState
|
||||||
if [ $WIAvailableDataCount -ge 1 -a ${WIAvailableState[0]} = "+" -a \
|
if [ ${#WIAvailable[@]} -ge 1 -a ${WIAvailableState[0]} = "+" -a \
|
||||||
$WIAvailableDataCount -eq 1 -o "$FLUXIONAuto" ]; then
|
${#WIAvailable[@]} -eq 1 -o "$FLUXIONAuto" ]; then
|
||||||
WISelected="${WIAvailable[0]}"
|
WISelected="${WIAvailable[0]}"
|
||||||
WISelectedState="+" # It passed the condition, it must be +
|
WISelectedState="+" # It passed the condition, it must be +
|
||||||
else
|
else
|
||||||
|
@ -524,7 +540,8 @@ function set_interface() {
|
||||||
if [ $FLUXIONDropNet ]; then
|
if [ $FLUXIONDropNet ]; then
|
||||||
# Get selected interface's driver details/info-descriptor.
|
# Get selected interface's driver details/info-descriptor.
|
||||||
echo -e "$FLUXIONVLine $FLUXIONGatheringWIInfoNotice"
|
echo -e "$FLUXIONVLine $FLUXIONGatheringWIInfoNotice"
|
||||||
WIDriver=$(airmon-ng | grep $WISelected | awk '{print $3}')
|
interface_driver "$WISelected"
|
||||||
|
WIDriver="$InterfaceDriver"
|
||||||
|
|
||||||
# I'm not really sure about this conditional here.
|
# I'm not really sure about this conditional here.
|
||||||
# FLUXION 2 had the conditional so I kept it there.
|
# FLUXION 2 had the conditional so I kept it there.
|
||||||
|
@ -534,6 +551,7 @@ function set_interface() {
|
||||||
|
|
||||||
# Get list of potentially troublesome programs.
|
# Get list of potentially troublesome programs.
|
||||||
echo -e "$FLUXIONVLine $FLUXIONFindingConflictingProcessesNotice"
|
echo -e "$FLUXIONVLine $FLUXIONFindingConflictingProcessesNotice"
|
||||||
|
# This shit has to go reeeeeal soon (airmon-ng)...
|
||||||
ConflictPrograms=($(airmon-ng check | awk 'NR>6{print $2}'))
|
ConflictPrograms=($(airmon-ng check | awk 'NR>6{print $2}'))
|
||||||
|
|
||||||
# Kill potentially troublesome programs.
|
# Kill potentially troublesome programs.
|
||||||
|
@ -559,16 +577,25 @@ function set_interface() {
|
||||||
function run_interface() {
|
function run_interface() {
|
||||||
# Activate wireless interface monitor mode and save identifier.
|
# Activate wireless interface monitor mode and save identifier.
|
||||||
echo -e "$FLUXIONVLine $FLUXIONStartingWIMonitorNotice"
|
echo -e "$FLUXIONVLine $FLUXIONStartingWIMonitorNotice"
|
||||||
WIMonitor=$(airmon-ng start $WISelected | awk -F'\[phy[0-9]+\]|\)' '$0~/monitor .* enabled/{print $3}' 2> /dev/null)
|
if [ "$FLUXIONAirmonNG" ]; then
|
||||||
|
# TODO: Need to check weather switching to monitor mode below failed.
|
||||||
|
WIMonitor=$(airmon-ng start $WISelected | awk -F'\[phy[0-9]+\]|\)' '$0~/monitor .* enabled/{print $3}' 2> /dev/null)
|
||||||
|
else
|
||||||
|
if interface_set_mode "$WISelected" "monitor"
|
||||||
|
then WIMonitor=$WISelected
|
||||||
|
else WIMonitor=""
|
||||||
|
fi
|
||||||
|
fi
|
||||||
|
|
||||||
# TODO: Verify the monitor interface was successfully created.
|
if [ "$WIMonitor" ]
|
||||||
|
then echo -e "$FLUXIONVLine ${CGrn}Interface monitor mode switch succeeded."; sleep 3
|
||||||
|
else echo -e "$FLUXIONVLine ${CRed}Interface monitor mode switch failed!"; sleep 3; return 1
|
||||||
|
fi
|
||||||
|
|
||||||
# Create an identifier for the access point, AP virtual interface.
|
# Create an identifier for the access point, AP virtual interface.
|
||||||
# The identifier will follow this structure: wlanXap, where X is
|
# The identifier will follow this structure: wl[identifier]FLXap
|
||||||
# the integer assigned to the original interface, wlanXmon.
|
WIAccessPoint="${WISelected}FLXap"
|
||||||
# In alternative systems, the strcture is: wl*ap and wl*mon.
|
|
||||||
WIAccessPoint=${WIMonitor/mon/ap}
|
|
||||||
|
|
||||||
# Create the new virtual interface with the generated identifier.
|
# Create the new virtual interface with the generated identifier.
|
||||||
echo -e "$FLUXIONVLine $FLUXIONStartingWIAccessPointNotice"
|
echo -e "$FLUXIONVLine $FLUXIONStartingWIAccessPointNotice"
|
||||||
if [ `iw dev $WIMonitor interface add $WIAccessPoint type monitor` ]; then
|
if [ `iw dev $WIMonitor interface add $WIAccessPoint type monitor` ]; then
|
||||||
|
|
|
@ -0,0 +1,118 @@
|
||||||
|
#!/bin/bash
|
||||||
|
|
||||||
|
# The methods used in this script are taken from airmon-ng.
|
||||||
|
# This is all thanks for the airmon-ng authors, thanks guys.
|
||||||
|
|
||||||
|
InterfaceUtilsOutputDevice="/dev/stdout"
|
||||||
|
|
||||||
|
if [ -d /sys/bus/usb ] # && hash lsusb
|
||||||
|
then InterfaceUSBBus=1
|
||||||
|
fi
|
||||||
|
|
||||||
|
if [ -d /sys/bus/pci ] || [ -d /sys/bus/pci_express ] || [ -d /proc/bus/pci ] # && hash lspci
|
||||||
|
then InterfacePCIBus=1
|
||||||
|
fi
|
||||||
|
|
||||||
|
function interface_list_all() {
|
||||||
|
InterfaceListAll=($(ls -1 /sys/class/net))
|
||||||
|
}
|
||||||
|
|
||||||
|
function interface_list_wireless() {
|
||||||
|
InterfaceListWireless=()
|
||||||
|
interface_list_all
|
||||||
|
local __interface_list_wireless__candidate
|
||||||
|
for __interface_list_wireless__candidate in "${InterfaceListAll[@]}"; do
|
||||||
|
if grep -qs "DEVTYPE=wlan" /sys/class/net/$__interface_list_wireless__candidate/uevent
|
||||||
|
then InterfaceListWireless+=("$__interface_list_wireless__candidate")
|
||||||
|
fi
|
||||||
|
done
|
||||||
|
}
|
||||||
|
|
||||||
|
function interface_driver() {
|
||||||
|
InterfaceDriver=$(basename $(readlink /sys/class/net/$1/device/driver))
|
||||||
|
}
|
||||||
|
|
||||||
|
function interface_physical() {
|
||||||
|
if [ ! "$1" ]; then return 1; fi
|
||||||
|
|
||||||
|
unset InterfacePhysical
|
||||||
|
|
||||||
|
local -r interface_physical_path="/sys/class/net/$1/phy80211"
|
||||||
|
|
||||||
|
if [ -d "$interface_physical_path" ]; then
|
||||||
|
if [ -r "$interface_physical_path/name" ]
|
||||||
|
then InterfacePhysical="`cat "$interface_physical_path/name"`"
|
||||||
|
else InterfacePhysical="`ls -l "$interface_physical_path" | sed 's/^.*\/\([a-zA-Z0-9_-]*\)$/\1/'`"
|
||||||
|
fi
|
||||||
|
fi
|
||||||
|
|
||||||
|
if [ ! "$InterfacePhysical" ]; then return 2; fi
|
||||||
|
}
|
||||||
|
|
||||||
|
function interface_hardware() {
|
||||||
|
if [ ! "$1" ]; then return 1; fi
|
||||||
|
|
||||||
|
local __interface_hardware__device="/sys/class/net/$1/device"
|
||||||
|
local __interface_hardware__hwinfo="$__interface_hardware__device/modalias"
|
||||||
|
|
||||||
|
InterfaceHardwareBus="`cut -d ":" -f 1 "$__interface_hardware__hwinfo" 2> $InterfaceUtilsOutputDevice`"
|
||||||
|
|
||||||
|
case "$InterfaceHardwareBus" in
|
||||||
|
"usb") # Wanted to replace the line below with awk, but i'll probably just add complexity & issues (mawk vs gawk).
|
||||||
|
InterfaceHardwareID="`cut -d ":" -f 2 $__interface_hardware__hwinfo | cut -b 1-10 | sed 's/^.//;s/p/:/'`";;
|
||||||
|
"pci" | "pcmcia" | "sdio")
|
||||||
|
InterfaceHardwareID="`cat "$__interface_hardware__device/vendor" 2> $InterfaceUtilsOutputDevice`:`cat "$__interface_hardware__device/device" 2> $InterfaceUtilsOutputDevice`";;
|
||||||
|
default) # The following will only work for USB devices.
|
||||||
|
InterfaceHardwareID="`cat "$__interface_hardware__device/idVendor" 2> $InterfaceUtilsOutputDevice`:`cat "$__interface_hardware__device/idProduct" 2> $InterfaceUtilsOutputDevice`"
|
||||||
|
InterfaceHardwareBus="usb";; # This will be reset below if InterfaceHardwareID is invalid.
|
||||||
|
esac
|
||||||
|
|
||||||
|
# Check for invalid InterfaceHardwareID (starts or ends with :) .. not a happy face, still won't quote it.
|
||||||
|
if echo "$InterfaceHardwareID" | egrep -q "^:|:$"; then
|
||||||
|
unset InterfaceHardwareID
|
||||||
|
unset InterfaceHardwareBus
|
||||||
|
return 2
|
||||||
|
fi
|
||||||
|
}
|
||||||
|
|
||||||
|
function interface_chipset() {
|
||||||
|
if [ ! "$1" ]; then return 1; fi
|
||||||
|
|
||||||
|
if ! interface_hardware "$1"; then return 2; fi
|
||||||
|
|
||||||
|
case "$InterfaceHardwareBus" in
|
||||||
|
"usb")
|
||||||
|
if [ ! "$InterfaceUSBBus" ]; then return 3; fi
|
||||||
|
InterfaceChipset="`lsusb -d "$InterfaceHardwareID" | head -n1 - | cut -f3- -d ":" | sed 's/^....//;s/ Network Connection//g;s/ Wireless Adapter//g;s/^ //'`";;
|
||||||
|
"pci" | "pcmcia")
|
||||||
|
if [ ! "$InterfacePCIBus" ]; then return 4; fi
|
||||||
|
InterfaceChipset="$(lspci -d $InterfaceHardwareID | cut -f3- -d ":" | sed 's/Wireless LAN Controller //g;s/ Network Connection//g;s/ Wireless Adapter//;s/^ //')";;
|
||||||
|
"sdio")
|
||||||
|
if [[ "${InterfaceHardwareID,,}" = "0x02d0"* ]]
|
||||||
|
then InterfaceChipset=$(printf "Broadcom %d" ${InterfaceHardwareID:7})
|
||||||
|
else InterfaceChipset="Unknown chipset for SDIO device."
|
||||||
|
fi;;
|
||||||
|
default)
|
||||||
|
InterfaceChipset="Unknown device chipset & device bus."
|
||||||
|
esac
|
||||||
|
}
|
||||||
|
|
||||||
|
function interface_state() {
|
||||||
|
if [ ! "$1" ]; then return 1; fi
|
||||||
|
local __interface_state__stateFile="/sys/class/net/$1/operstate"
|
||||||
|
|
||||||
|
if [ ! -f "$__interface_state__stateFile" ]; then return 2; fi
|
||||||
|
InterfaceState=$(cat "$__interface_state__stateFile")
|
||||||
|
}
|
||||||
|
|
||||||
|
function interface_set_state() {
|
||||||
|
if [ "${#@}" -ne 2 ]; then return 1; fi
|
||||||
|
ip link set "$1" "$2"
|
||||||
|
}
|
||||||
|
|
||||||
|
function interface_set_mode() {
|
||||||
|
if [ "${#@}" -ne 2 ]; then return 1; fi
|
||||||
|
if ! interface_set_state "$1" "down"; then return 2; fi
|
||||||
|
if ! iwconfig "$1" mode "$2" &> $InterfaceUtilsOutputDevice; then return 3; fi
|
||||||
|
if ! interface_set_state "$1" "up"; then return 4; fi
|
||||||
|
}
|
Loading…
Reference in New Issue