From bc8cb4a23738f77ac244dcfa500b560bebe8375d Mon Sep 17 00:00:00 2001 From: fatalerrors Date: Tue, 10 Mar 2026 18:05:44 +0100 Subject: [PATCH] updated readme and final fixes for net.sh --- README.md | 7 +++-- profile.d/net.sh | 74 ++++++++++++++++++++++++++++++------------------ 2 files changed, 51 insertions(+), 30 deletions(-) diff --git a/README.md b/README.md index b62b7ec..effd67e 100644 --- a/README.md +++ b/README.md @@ -20,6 +20,7 @@ prompt. Here is a non-exhaustive list of what we have: - A bar style prompt with hour, execution time and exit code of the last command; - clean: erase after confirmation any backup file, possibly recursively; +- dwl: a curl/wget/fetch download wrapper; - pkgs: search for the given pattern in the installed packages name; - expandlist: usefull in scripts, it expand any expression using wildcards into the corresponding list of file and directories; @@ -31,6 +32,7 @@ the corresponding list of file and directories; - ku: kill all the processes owned by the given user name or ID; - mcd: create a directory and immediately move into it; - meteo: display weather forecast information; +- myextip: get informations about your public IP; - ppg: look for the given patern in the running processes; - rain: console screensaver with rain effect; - rmhost: remove the given host (name or IP) to the list of SSH known host; @@ -51,8 +53,9 @@ directory only if needed; ## 3. Configuration Some functions might have configurable default behaviour. You can create a -.profile.conf file to configure those default behaviour. You should have a look -at the doc/.profile.conf.example to see the list of available options. +profile.conf file to configure those default behaviour. You should have a look +at the doc/profile.conf.example to see the list of available options. The +configuration file is located in the same directory as profile.sh file. ## 4. Contact and more information ### 4.1. New users diff --git a/profile.d/net.sh b/profile.d/net.sh index 6ad28a1..ebb6686 100644 --- a/profile.d/net.sh +++ b/profile.d/net.sh @@ -91,23 +91,32 @@ isipv4() local ip=$1 [[ -z $ip ]] && return 1 - # Start with a regex format test - if [[ $ip =~ ^[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}$ ]]; then + # Start with a regex format test (four octets) + if [[ $ip =~ ^([0-9]{1,3}\.){3}[0-9]{1,3}$ ]]; then local old_ifs=$IFS - IFS="." - ip=($ip) + IFS='.' + read -r -a ip_arr <<< "$ip" IFS=$old_ifs - if [[ ${ip[0]} -le 255 && ${ip[1]} -le 255 && - ${ip[2]} -le 255 && ${ip[3]} -le 255 ]]; then - if [[ -t 1 ]]; then - disp "The given IPv4 is valid." + + # Ensure each octet is between 0 and 255 + local oct + for oct in "${ip_arr[@]}"; do + # Reject leading plus/minus or empty entries + if [[ -z $oct || $oct =~ [^0-9] ]]; then + [[ -t 1 ]] && disp "The given parameter is NOT a valid IPv4." + return 1 fi - return 0 - fi - fi - if [[ -t 1 ]]; then - disp "The given parameter is NOT a valid IPv4." + if (( oct > 255 )); then + [[ -t 1 ]] && disp "The given parameter is NOT a valid IPv4." + return 1 + fi + done + + [[ -t 1 ]] && disp "The given IPv4 is valid." + return 0 fi + + [[ -t 1 ]] && disp "The given parameter is NOT a valid IPv4." return 1 } export -f isipv4 @@ -115,7 +124,7 @@ export -f isipv4 # ------------------------------------------------------------------------------ -# Determine if parameter is a valid IPv4 address +# Determine if parameter is a valid IPv6 address # Usage: isipv6 isipv6() { @@ -146,7 +155,7 @@ urlencode() { for (( i = 0; i < length; i++ )); do local c="${str:i:1}" case "$c" in - [a-zA-Z0-9.~_-]) printf "$c" ;; + [a-zA-Z0-9.~_-]) printf '%s' "$c" ;; ' ') printf '+' ;; *) printf '%%%02X' "'$c" #| cut -d' ' -f2 ;; esac @@ -225,22 +234,31 @@ myextip() { shift done - # Fetch data - local response - response=$(dwl http://ip-api.com/json/) + # Fetch data. Allow overriding endpoint via env var MYEXTIP_URL + local MYEXTIP_URL + MYEXTIP_URL=${MYEXTIP_URL:-http://ip-api.com/json/} - # Parse with jq + local response + if ! response=$(dwl "$MYEXTIP_URL"); then + disp E "Failed to fetch external IP information from $MYEXTIP_URL" + return 2 + fi + + # Parse with jq when available and when raw wasn't requested. The jq filter + # is tolerant to field-name differences between providers (ip-api / ipinfo). if command -v jq >/dev/null 2>&1 && [[ "$show_raw" != true ]]; then echo "$response" | jq -r --argjson all "$all" --argjson ip "$show_ip" \ - --argjson isp "$show_isp" --argjson loc "$show_loc" \ - --argjson coord "$show_coord" --argjson as "$show_as" ' - [ - (if $all or $ip then "IP Address : \(.query)" else empty end), - (if $all or $isp then "ISP : \(.isp)" else empty end), - (if $all or $loc then "Location : \(.city), \(.regionName), \(.country)" else empty end), - (if $all or $coord then "Coordinates: \(.lat), \(.lon)" else empty end), - (if $all or $as then "AS : \(.as)" else empty end) - ] | .[]' + --argjson isp "$show_isp" --argjson loc "$show_loc" \ + --argjson coord "$show_coord" --argjson as "$show_as" ' + [ + (if $all or $ip then "IP Address : \(.query // .ip)" else empty end), + (if $all or $isp then "ISP : \(.isp // .org)" else empty end), + (if $all or $loc then + ("Location : " + ((.city // "") + (if .city then ", " else "" end) + (if .regionName then .regionName else .region end) + (if .country then ", " + .country else "" end))) + else empty end), + (if $all or $coord then (if (.lat and .lon) then "Coordinates: \(.lat), \(.lon)" elif .loc then "Coordinates: \(.loc)" else empty end) else empty end), + (if $all or $as then "AS : \(.as // .org)" else empty end) + ] | .[]' else [[ "$show_raw" != true ]] && disp W "jq is not installed, displaying raw JSON response." echo "$response"