#!/bin/bash
if [ "$#" -ne 3 ]; then
    echo "Usage: $0 <network_prefix> <username> <password>"
    echo "Example: $0 192.168.1 user pass"
    exit 1
fi

NETWORK_PREFIX=$1
USERNAME=$2
export SSHPASS=$3
OUTPUT_FILE="scan_$(date +%Y%m%d_%H%M%S).txt"
TOTAL=254
TMPDIR_SCAN=$(mktemp -d)
COUNTER_FILE="$TMPDIR_SCAN/counter"
LOCK_FILE="$TMPDIR_SCAN/counter.lock"
echo 0 > "$COUNTER_FILE"
trap 'rm -rf "$TMPDIR_SCAN"' EXIT

# Check dependencies
for cmd in sshpass ping ssh flock; do
    command -v "$cmd" &>/dev/null || { echo "Missing dependency: $cmd"; exit 1; }
done

progress_bar() {
    local done=$1
    local width=40
    local filled=$(( done * width / TOTAL ))
    local empty=$(( width - filled ))
    local pct=$(( done * 100 / TOTAL ))
    local bar="" i
    for (( i=0; i<filled; i++ )); do bar+="#"; done
    for (( i=0; i<empty;  i++ )); do bar+=" "; done
    echo -n "[${bar}] ${pct}% (${done}/${TOTAL})"
}

check_host() {
    local IP="$1"
    local USERNAME="$2"
    local COUNTER_FILE="$3"
    local LOCK_FILE="$4"
    local OUTPUT_FILE="$5"

    if ping -c 1 -W 1 "$IP" > /dev/null 2>&1; then
        local USERS
        USERS=$(sshpass -e ssh -o StrictHostKeyChecking=no -o ConnectTimeout=3 \
            -o LogLevel=ERROR "$USERNAME@$IP" 'who' 2>/dev/null)

        if [ $? -eq 0 ]; then
            local result
            result="[+] IP Address: $IP"$'\n'
            if [ -n "$USERS" ]; then
                result+="Logged-in Users:"$'\n'"$USERS"$'\n'
            else
                result+="No users logged in."$'\n'
            fi
            result+="-----------------------------"

            echo "$result" >> "$OUTPUT_FILE"
            printf "\r\033[K%s\n" "$result"
        fi
    fi

    (
        flock 9
        val=$(cat "$COUNTER_FILE")
        echo $(( val + 1 )) > "$COUNTER_FILE"
    ) 9>"$LOCK_FILE"
}

export -f check_host

echo "Scanning $NETWORK_PREFIX.1 – $NETWORK_PREFIX.254 (254 hosts) as '$USERNAME'..."
echo "Output: $OUTPUT_FILE"

printf "%s" "$(progress_bar 0)"

for i in $(seq 1 $TOTAL); do
    check_host "$NETWORK_PREFIX.$i" "$USERNAME" "$COUNTER_FILE" "$LOCK_FILE" "$OUTPUT_FILE" &

    if (( i % 20 == 0 )); then
        wait
    fi

    done_count=$(cat "$COUNTER_FILE")
    printf "\r%s" "$(progress_bar "$done_count")"
done

wait

printf "\r%s\n" "$(progress_bar $TOTAL)"
FOUND=$(grep -c '^\[+\]' "$OUTPUT_FILE" 2>/dev/null || echo 0)
echo "Scan complete — $FOUND host(s) found. Results saved to $OUTPUT_FILE"