SlackwareThis Forum is for the discussion of Slackware Linux.
Notices
Welcome to LinuxQuestions.org, a friendly and active Linux Community.
You are currently viewing LQ as a guest. By joining our community you will have the ability to post topics, receive our newsletter, use the advanced search, subscribe to threads and access many other special features. Registration is quick, simple and absolutely free. Join our community today!
Note that registered members see fewer ads, and ContentLink is completely disabled once you log in.
If you have any problems with the registration process or your account login, please contact us. If you need to reset your password, click here.
Having a problem logging in? Please visit this page to clear all LQ-related cookies.
Get a virtual cloud desktop with the Linux distro that you want in less than five minutes with Shells! With over 10 pre-installed distros to choose from, the worry-free installation life is here! Whether you are a digital nomad or just looking for flexibility, Shells can put your Linux machine on the device that you want to use.
Exclusive for LQ members, get up to 45% off per month. Click here for more info.
In next Slint installer an at least partial net-installation will be provided, so that user get directly the most recent version of each package found in the repository, and also get the packages added since the release of the ISO, instead of having to download then install or replace a lot of packages after installation.
The Slackware (and Slint) installer can set a wired Internet connection, but not yet a wireless one. However, more and more laptops lack an RJ45 slot.
What would be the minimum set of packages needed to add the ability to setup a wifi connection during installation, using only command line apps? The idea is to present the user with the detected networks and let the user pick one, then type the password if need be.
The software will have to be shipped in the installer itself.
Thanks for any clue.
Last edited by Didier Spaier; 07-23-2020 at 06:57 AM.
I think that wireless-tools package that contains iwconfig, wpa_supplicant package and of course some DHCP client would be enough. You can also add wget/curl if not already present in the stock installer to check if internet connection is really available and if DNS server works similarly to what Android does when connecting to Wi-Fi and you can also add rsync if you're going to use it to check if rsync port is not blocked which might be the case in corporate or public networks. And of course you should include drivers for various Wi-Fi chips such as rtl8188eu, MT7621 etc.
BTW, you can look into raspi-config that has a text UI and does something similar to what you want to achieve in Network Options -> Wi-Fi - it asks for SSID name (it does not list found networks but remember that some users may choose to hide their SSID) and then asks for a password. The job doesn't seem very hard but there might be some corner cases that others have already come across.
Last edited by average_user; 07-23-2020 at 07:56 AM.
What would be the minimum set of packages needed to add the ability to setup a wifi connection during installation, using only command line apps? The idea is to present the user with the detected networks and let the user pick one, then type the password if need be.
NetworkManager has nmtui which is a curses interface to do that. I don't know if NM is too bloated for an installer, but it's very functional from the CLI.
BTW, you can look into raspi-config that has a text UI and does something similar to what you want to achieve in Network Options -> Wi-Fi - it asks for SSID name (it does not list found networks but remember that some users may choose to hide their SSID) and then asks for a password. The job doesn't seem very hard but there might be some corner cases that others have already come across.
Thanks for the clue. I have cloned the repository and will look into raspi-config.
Last edited by Didier Spaier; 07-23-2020 at 10:34 AM.
NetworkManager has nmtui which is a curses interface to do that. I don't know if NM is too bloated for an installer, but it's very functional from the CLI.
And also nmcli. I already tried unsuccessfully to build NM without X, but will try harder, thanks for the reminder.
I was going to wait until I had everything added that I wanted, but since I brought it up in the other thread, I figured I'd post it here as well.
I created a script that will allow connecting to WPA networks. It supports multiple wireless devices (it'll prompt you to select which one you want to use), it will present a list of all available wifi networks (sorted by signal strength) with an option to manually add one that isn't listed (if someone still hides their SSID, this is for them), prompt for the WPA passphrase, connect to it using wpa_supplicant, verify the connection, and then run dhcpcd against the wireless interface. I think I added error catching to get everything (but I wouldn't be surprised if I missed something). And I just thought of maybe trying to use rfkill, but I've never had to tinker with that, so it may take some digging).
I still want to add support for static IPs as everything now relies on dhcp, and not all networks have that. As I was typing the above, I suppose I could try and add support for open/unsecured networks and maybe even networks secured with WEP (but seriously, no one should be using that, so I'm thinking I might leave that alone).
All that seems to be required for the commands I have in there is the n/wireless-tools and n/wpa_supplicant. I did a quick look through some of those binaries and it seems like they'd be fulfilled with what's included in the installer, but I'd have to boot it up to make sure (maybe I'll do that in a VM tonight). I had debated switching from the legacy ifconfig/iwconfig to the newer ip and iw commands, but that'd require adding more programs. I may still tackle it, because I did like the scanning of iw better than iwlist.
In addition to the two packages mentioned above that are directly used in my script, there may be additional packages that need to be added to support all the wireless hardware. At a quick glance, I noticed ipw2100-fw, ipw2200-fw, zd1211-firmware
I did also add support for lshw, which is currently only on SBo, but for those with multiple wifi cards, it'll allow the script to actually display the brand and product names to hopefully make it easier to choose which one you want to use (without lshw, it will just show you the device names as I can't find anywhere in the stock system to match the device names like wlan0 with the brand or product name -- I'm open to any suggestions... I was digging quite a bit yesterday for it). If you don't have lshw installed, the script will just skip the portion that requires it and will just show the non-descriptive names (wlan0, wlan1, wlp2s0, etc).
==========================
I know I can get verbose, so here's what you might need for this (hopefully) functional script to work when booting off the installer.
Code:
REQUIRED PROGRAMS
n/wireless-tools
n/wpa_supplicant
RECOMMENDED FIRMWARE
n/ipw2100-fw
n/ipw2200-fw
n/zd1211-firmware
OPTIONAL, BUT RECOMMENDED PROGRAMsystem/lshw on SBo
# Copyright (c) 2020 Jeremy Hansen <jebrhansen+SBo -at- gmail.com>
# Permission is hereby granted, free of charge, to any person obtaining a copy # of this software and associated documentation files (the "Software"), to deal # in the Software without restriction, including without limitation the rights # to use, copy, modify, merge, publish, distribute, sublicense, and/or sell # copies of the Software, and to permit persons to whom the Software is # furnished to do so, subject to the following conditions:
# The above copyright notice and this permission notice shall be included in all # copies or substantial portions of the Software.
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR # IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, # FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE # AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER # LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, # OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE # SOFTWARE.
# This script has bashisms and won't work with just sh. if [ "$BASH" != "/bin/bash" ] ; then echo "This script requires bash due to bashisms." echo "It does not support running it with 'sh' or other shells." echo "Please chmod +x $0 to execute it directly or run:" echo "bash $0" 1>&2 exit 1 fi
# Check for multiple wifi devices and, if found, prompt user which one to use readarray -t CHECKNUM < <(/sbin/iwconfig 2> /dev/null | /usr/bin/grep ESSID | cut -d' ' -f1)
# If there are more than wireless one devices, prompt the user to select which one if [ ${#CHECKNUM[@]} -gt 1 ]; then
# Check if lshw is available -- if it is, provide brand and model names to user # Otherwise skip this part and keep them ugly if lshw &> /dev/null; then
# Loop through devices and let user know the brand and product # Needs lshw package for ((i=0; i<${#CHECKNUM[@]}; i++)); do DEVICE="${CHECKNUM[i]}" LSHWINFO=$(lshw -class network | /usr/bin/grep -B 4 "logical name" | /usr/bin/grep -B 4 "$DEVICE" | head -2) PRODUCT=$(echo "$LSHWINFO" | head -1 | cut -d: -f2-) VENDOR=$(echo "$LSHWINFO" | tail -1 | cut -d: -f2-) CHECKNUM[i]="$DEVICE -- $VENDOR$PRODUCT" done fi
echo "Multiple wifi devices were found. Please select the one you want: " select WIFIDEV in "${CHECKNUM[@]}"; do [[ -n "$WIFIDEV" ]] || { echo "Invalid choice. Please try again." >&2; continue; } WIFIDEV=$(echo "$WIFIDEV" | cut -d' ' -f1) break done
# If there's only one device, store it elif [ ${#CHECKNUM[@]} -eq 1 ]; then WIFIDEV=${CHECKNUM[0]} # If there's no wireless devices, let the user know else echo "No wireless devices found. Please check hardware/drivers and try again." exit 1 fi
# Go until connected or the user decides to stop while true; do
# Check if we are already connected to a network # Use the broadcast address in case they're on a network without internet # and planning on using a local server BCADDR=$(/sbin/ifconfig "$WIFIDEV" | /usr/bin/grep cast | rev | cut -d' ' -f1 | rev 2> /dev/null) echo "Checking for existing network... " if /bin/ping -W 1 -bc1 "$BCADDR" &>/dev/null; then
# Check for internet if /bin/ping -c1 1.1.1.1 &>/dev/null; then NET="the internet" else NET="a network WITHOUT internet" fi echo -e "\nYou ARE connected to $NET.\n" echo -n "Continuing WILL disconnect you. Do you want to continue? y/N " read -r EXIT
# If anything other than y, exit the script ! /usr/bin/grep -qi "y" <<< "$EXIT" && exit 0 || echo -e "\nDisconnecting from network" else echo -e "Not connected to a network.\n" fi
# Kill wpa_supplicant, dhcpcd, and dhclient if they're already running /usr/bin/killall wpa_supplicant dhcpcd dhclient 2> /dev/null
# Null out access point address, which usually disassociates from router /sbin/iwconfig "$WIFIDEV" ap 00:00:00:00:00:00 2> /dev/null
# Bring the interface down and back up for good measure /sbin/ifconfig "$WIFIDEV" down 2> /dev/null # Needs the sleep to prevent the interface from not coming back up in time sleep 1 /sbin/ifconfig "$WIFIDEV" up 2> /dev/null
echo "Scanning for wireless networks..."
# Store the list and grab SSIDs and Signal rates for each network IWLIST=$(/sbin/iwlist "$WIFIDEV" scan) SSID=$(echo "$IWLIST" | /usr/bin/grep SSID | cut -d\" -f2) SIGNAL=$(echo "$IWLIST" | /usr/bin/grep Signal | cut -d- -f2 | cut -d' ' -f1)
# Store the SSIDs in an array based on signal strength readarray -t NETLIST < <(paste <(echo "$SIGNAL") <(echo "$SSID") | tr '\t' ' ' | sort | cut -d' ' -f2-)
# Add an extra entry to allow manually typing in the SSID NETLIST+=("Not listed - Manually enter SSID")
# Display the SSID selection dialog COLUMNS=single echo -e "\n=================================\n" echo "Please select a wireless network: " select SSID in "${NETLIST[@]}"; do [[ -n $SSID ]] || { echo "Invalid choice. Please try again." >&2; continue; } break done
# If the user selects "Not listed" allow them to type the network if [ "$SSID" == "Not listed - Manually enter SSID" ]; then echo -en "\nPlease enter network SSID: " read -r SSID fi
# Type in the passphrase and hide the characters from the prompt # Make sure the passphrase is between 8 and 63 characters while true; do echo -en "\nPlease type in the passphrase for $SSID: " read -rs PASS if [ ${#PASS} -lt 8 ] || [ ${#PASS} -gt 63 ]; then echo "WPA passphrases are between 8 and 63 characters." echo "Your passphrase was ${#PASS} character(s). Please try again." else break fi done
# Time to try and connect echo -ne "\nAttempting to connect."
# Try and connect with wpa_supplicant /usr/sbin/wpa_supplicant -B -D nl80211 -i "${WIFIDEV}" -c <(echo "ctrl_interface=/var/run/wpa_supplicant"; wpa_passphrase "$SSID" "$PASS") &> /dev/null
# Check if wpa_supplicant has connected once per second for 10 seconds # If connected, break out of the loop early and move onto the DHCP for (( i=0; i<10; i++ )); do WPASTATUS=$(wpa_cli -i wlan0 status | /usr/bin/grep wpa_state | cut -d"=" -f2) if [ "$WPASTATUS" == "COMPLETED" ]; then echo -e "\n\nConnected! Now to request an IP.\n" sleep 1 break else sleep 1 echo -n "." fi done
# Fail after 10 seconds of wpa_supplicant not connecting if [ "$i" -eq 10 ]; then echo -e "FAILED!\n\nCould not connect with SSID: $SSID.\n" echo -n "Would you like to try again? Y/n " read -r TRYAGAIN /usr/bin/grep -qi "n" <<< "$TRYAGAIN" && exit 1
# If we get an address, exit the script. If we don't, offer to try again else if dhcpcd "$WIFIDEV" &> /dev/null; then echo "Successfully connected to $SSID with IP $(ifconfig wlan0 | /usr/bin/grep "inet " | cut -d' ' -f10)" exit else echo "DHCP failed!" echo -n "Would you like to try again? Y/n " read -r TRYAGAIN /usr/bin/grep -qi "n" <<< "$TRYAGAIN" && break fi fi done
For the network configuration I would suggest to use the modern iw & ip tools (it's 2020 already ).
Required packages:
iproute2-*
iw-*
A snippet from a startup script I run on Slackware -current (ARM - Raspberry) for automatically bringing up the WiFi connection if plugged. It's static IP, but can be easily adapted for DHCP:
Code:
FOUND=`/bin/grep "wlan0" /proc/net/dev`
if [ -n "$FOUND" ] ; then
echo WiFi Card Existent
#unblock radio
/usr/sbin/rfkill unblock all
# NetConf
/usr/bin/killall wpa_supplicant 1> /dev/null 2> /dev/null
/sbin/ip link set wlan0 down
/sbin/ip link set wlan0 up
/sbin/ip address flush dev wlan0
sleep 1
/usr/sbin/iw dev wlan0 connect ESSIDNAME
sleep 1
/usr/sbin/wpa_supplicant -D nl80211 -i wlan0 -B -c /etc/wpa_supplicant.conf
/sbin/ip -4 address add 192.168.1.100/24 broadcast 192.168.1.255 dev wlan0
/sbin/ip route add default via 192.168.1.1
fi
Jeremy/bassmadrigal, thanks a lot! your contribution is much appreciated. And in my humble opinion it could indeed be useful for Slackware too.
I will make some tests tomorrow (it's a bit late for that in my time zone), using a clone of your git repository as you plan enhancements.
Just a very small nitpick: I hate bash... no worries, I will try the script as-is and will POSIX-ify it when definitive. At first look no bid deal, that will mostly consist in replacing the array by another construct, which should be doable.
PS. I always try to write POSIX compliant scripts, not only so that they be portable (one could argue that in an installer that includes its own shell that doesn't matter much, except that if doing a chroot we rely on an alien shell, for instance to rescue an already installed system that maybe does not ship the same bash version), but also because of incompatibilities between versions. Let's give two recent examples:
My friend Storm Dragon is a big fan of bash, and as such like to play with the most recently provided features. Like using a new flag, not available in the bash 4.4.38 from Slackware that I also ship in Slint.
Something similar happened for a SlackBuild from SBo (don't remember which one at the moment)
No fuss no muss: I just built for Slint bash version 5.0.17 for Slint...
... Which happened to break an important script we ship...
... So I quickly I reverted this move.
Sorry for this boring rant, thanks again.
Last edited by Didier Spaier; 07-24-2020 at 03:03 PM.
For the network configuration I would suggest to use the modern iw & ip tools (it's 2020 already ).
Required packages:
iproute2-*
iw-*
I had actually started using some of those commands, but found that the packages weren't included with the installer. I was thinking if change is going to be made, it might be minor, so I went with the least amount of added packages. The main networking scripts still use the outdated tools, so I figure they aren't going anywhere anytime soon and there's no guarantee Pat would want to add them to the installer if he were to incorporate something like this to the installer. This is also why I made lshw optional, since it doesn't even exist in -current... yet. I'm hoping it gets added, because it's a great source of a lot of great info, plus it's easily parsable to be able to manipulate it on the CLI.
I might try and make the newer tools optional (there's only 7 total times that ifconfig, iwconfig, or iwlist are used in the script, so it shouldn't be too hard to if/else them) or maybe just make a second script that supports the modern tools.
Quote:
Originally Posted by Didier Spaier
Just a very small nitpick: I hate bash... no worries, I will try the script as-is and will POSIX-ify it when definitive. At first look no bid deal, that will mostly consist in replacing the array by another construct, which should be doable.
PS. I always try to write POSIX compliant scripts, not only so that they be portable (one could argue that in an installer that includes its own shell that doesn't matter much, except that if doing a chroot we rely on an alien shell, for instance to rescue an already installed system that maybe does not ship the same bash version), but also because of incompatibilities between versions. Let's give two recent examples:
I actually prefer using POSIX support when possible as well, but I wasn't sure how to handle the arrays when just using sh to run the script. That is why I added the bash check up top, otherwise it will lead to errors if you run the script with sh. I am not a great coder and when I was searching how to layout some of the sections, the results lead me to using arrays. Then when I ran the script using sh (which is usually how I run my scripts) and I found it threw a nasty error. After searching around, I realized that the arrays I used were bash, so rather than spend a ton of time trying to figure out an alternate method of completing it, I just stuck with bashisms and ran with it.
I'm not opposed to getting this POSIX compliant. I'd be happy to incorporate changes that remove bashisms or if you want to give me a pointer on what I can replace them with, I can try and get it knocked out tonight or tomorrow. I'll also do some searching and see if I can come up with anything on my own.
I'd also be up for any suggestions/additions/etc that anyone else might have.
Last edited by bassmadrigal; 07-24-2020 at 03:33 PM.
I was about to suggest to replace an array by feeding a function with the list of items to choose from so that inside the function you get the item count in $# and list the item number i as $i.
But in second thought that would be an overkill. Instead you could replace the readarray statement by a command that output a lists of items, separated by spaces for instance, then instead of the select statements write something like this:
Code:
list="a1 b2 c3"
vlist=$(echo $list|sed "s/ /\n/g")
echo please select an item in the list below:
echo "$vlist"
read -p "what is your choice? " choice
if ! echo "$list"|grep -q "$choice"; then
echo "not in the list"
else
echo you have selected $choice
fi
Last edited by Didier Spaier; 07-24-2020 at 05:30 PM.
So I've been working on this and I was really hoping to keep the "select" for the menus, because it's dynamic and easily adjusts to however many items are in the list. So I ended up making a fake array in the script so I could still manipulate things as needed. After I figured it all out, I then found that select and a few other things I was using were not POSIX
Code:
$ shellcheck myscript
Line 21:
((COUNT++))
^-- SC2039: In POSIX sh, standalone ((..)) is undefined.
^-- SC2039: In POSIX sh, ++ is undefined.
Line 24:
if lshw &> /dev/null; then
^-- SC2039: In POSIX sh, &> is undefined.
Line 28:
for ((i=0; i<NUMDEV; i++)); do
^-- SC2039: In POSIX sh, arithmetic for loops are undefined.
^-- SC2039: In POSIX sh, ++ is undefined.
Line 38:
LIST=$(for ((i=0; i<NUMDEV; i++)); do eval echo -n \$LINE"$i"%; done)
^-- SC2039: In POSIX sh, arithmetic for loops are undefined.
^-- SC2039: In POSIX sh, ++ is undefined.
Line 42:
select WIFIDEV in $LIST; do
^-- SC2039: In POSIX sh, select loops are undefined.
Line 43:
[[ -n "$WIFIDEV" ]] || { echo "Invalid choice. Please try again." >&2; continue; }
^-- SC2039: In POSIX sh, [[ ]] is undefined.
Luckily, I should still be able to use the fake array and then kludge my way through a menu. Overall, though, I am still proud of faking an array in bash, so I wanted to show it off (I'm temporarily using ifconfig to grab devices since I don't have multiple wifi devices). Now I just need to build a menu, but that will come later:
Code:
#!/bin/sh
LIST=$(ifconfig -a | grep flags | cut -d: -f1)
# LIST=$(/sbin/iwconfig 2> /dev/null | /usr/bin/grep ESSID | cut -d' ' -f1)
# Count how many devices were found
NUMDEV=$(echo "$LIST" | wc -l)
# If only one device, set it automatically
if [ "$NUMDEV" -eq 1 ]; then
WIFIDEV=$LIST
# If no devices, exit the script
elif [ "$NUMDEV" -eq 0 ]; then
echo "No wireless devices found. Please check hardware/drivers and try again."
exit 1
# Otherwise loop through the devices and allow the user to select one
else
COUNT=0
# Create a fake array
for i in $LIST; do
eval LINE$COUNT="$i"
COUNT=$((COUNT+1))
done
# Loop through array
i=0
while [ "$i" -lt "$NUMDEV" ]; do
eval DEVICE="\$LINE$i"
LSHWINFO=$(lshw -class network | /usr/bin/grep -B 4 "logical name" | /usr/bin/grep -B 4 "$DEVICE" | head -2)
PRODUCT=$(echo "$LSHWINFO" | head -1 | cut -d: -f2-)
VENDOR=$(echo "$LSHWINFO" | tail -1 | cut -d: -f2-)
eval LINE"$i"=\""$DEVICE" -- "$VENDOR" "$PRODUCT"\"
i=$((i+1))
done
# Recombine the list and use the % symbol as a delimeter
LIST=$(i=0; while [ "$i" -lt "$NUMDEV" ]; do eval echo -n \$LINE"$i"%; i=$((i+1)); done)
IFS='%'
# Future menu to allow selection of WIFIDEV
fi
echo "$WIFIDEV"
LinuxQuestions.org is looking for people interested in writing
Editorials, Articles, Reviews, and more. If you'd like to contribute
content, let us know.