mirror of
https://github.com/stornic56/debianito-post-install.git
synced 2026-10-31 13:08:06 +00:00
9828ea439c
- Extracted hardware detection logic from firmware.sh into new modules/hw_detect.sh. Declares shared arrays (PCI_NET_DEVS, USB_WIFI_DEVS, etc) and _detect_all_network_devices() function. The main script now sources hw_detect.sh immediately after utils.sh. firmware.sh retains only _DETECTED_FW_PKGS and _FW_PLAN_PKG_LINES plus installation logic — the detection loop is fully removed, eliminating the circular dependency with bluetooth.sh. - Fixed interrupt safety in main script: removed pkill -f "apt.*install" and pkill -f "dpkg.*configure" from _on_interrupt(); updated exit message to "Temp files cleaned." Only the signal handler (trap _on_interrupt INT TERM) remains. - Added strict URL validation to modules/gaming/heroic.sh and modules/gaming/tools.sh using regex ^https://[A-Za-z0-9./_-]+\.deb$ before passing $deb_url to _run_cmd. Blocks command substitution, non-https URLs, and path traversal attempts that could bypass shell quoting. - Implemented real Bullseye Archive rewrite in modules/bullseye/legacy.sh: adds idempotency check (grep -q archive.debian.org && return 0), creates timestamped backup of /etc/apt/sources.list with sudo cp, writes exact archive Debian sources via sudo tee heredoc, and runs sudo apt-get update || true on failure. - Added local scope to modules/bluetooth.sh variable service_enable_only=false before the conditional assignment, preventing state bleed from the previous global-only declaration. - Applied safe array pattern (while IFS= read -r _pkg; do ...) across 32+ files in modules/extras/* and modules/bullseye/legacy.sh, replacing all vulnerable for pkg in $cleaned / for pkg in $install_list loops. Eliminates word-splitting and command-injection risks.
428 lines
17 KiB
Bash
428 lines
17 KiB
Bash
#!/usr/bin/env bash
|
|
|
|
# ── Global arrays ──
|
|
# Device arrays (PCI_NET_DEVS, USB_WIFI_DEVS, PCI_BT_DEVS, USB_BT_DEVS)
|
|
# and _FW_PLAN_HW_LINES are declared in hw_detect.sh.
|
|
_DETECTED_FW_PKGS=()
|
|
_FW_PLAN_PKG_LINES=()
|
|
|
|
# ── Firmware package mapping ──
|
|
_detect_firmware_needs() {
|
|
local -A pkg_info
|
|
_DETECTED_FW_PKGS=()
|
|
_FW_PLAN_PKG_LINES=()
|
|
|
|
local dev_list
|
|
dev_list=("${PCI_NET_DEVS[@]}" "${USB_WIFI_DEVS[@]}")
|
|
|
|
for dev in "${dev_list[@]}"; do
|
|
local raw_desc vendor_lc pkg
|
|
raw_desc=$(echo "$dev" | sed -E 's/^[^ ]+ [^:]+: //; s/ \[[0-9a-fA-F]{4}:[0-9a-fA-F]{4}\]//; s/ \(rev.*\)//')
|
|
vendor_lc=$(echo "$dev" | sed -n 's/^.*]: //p' | awk '{print $1}' | tr '[:upper:]' '[:lower:]')
|
|
|
|
[[ "$vendor_lc" != *intel* && "$vendor_lc" != *realtek* && "$vendor_lc" != *atheros* && "$vendor_lc" != *qualcomm* && "$vendor_lc" != *mediatek* ]] && continue
|
|
|
|
case "$vendor_lc" in
|
|
*intel*)
|
|
if echo "$dev" | grep -qiE 'wireless|wi-fi|wlan|802\.11'; then
|
|
pkg="firmware-iwlwifi"
|
|
else
|
|
pkg="firmware-intel-misc"
|
|
fi
|
|
;;
|
|
*realtek*) pkg="firmware-realtek" ;;
|
|
*atheros* | *qualcomm*) pkg="firmware-atheros" ;;
|
|
*mediatek*) pkg="firmware-mediatek" ;;
|
|
esac
|
|
|
|
local short_dev
|
|
short_dev=$(echo "$raw_desc" | sed 's/ *\[[^]]*\]//g; s/ */ /g')
|
|
if [ -z "${pkg_info[$pkg]-}" ]; then
|
|
pkg_info[$pkg]="$short_dev"
|
|
else
|
|
pkg_info[$pkg]+=", $short_dev"
|
|
fi
|
|
done
|
|
|
|
for pkg in "${!pkg_info[@]}"; do
|
|
_DETECTED_FW_PKGS+=("$pkg")
|
|
_FW_PLAN_PKG_LINES+=(" [+] ${pkg} \xe2\x86\x90 ${pkg_info[$pkg]}")
|
|
done
|
|
|
|
mapfile -t _DETECTED_FW_PKGS < <(printf '%s\n' "${_DETECTED_FW_PKGS[@]}" | sort -u)
|
|
}
|
|
|
|
# ── Build plan string ──
|
|
_build_firmware_plan() {
|
|
local plan=""
|
|
plan+="This section installs the essential non-free firmware stack\n"
|
|
plan+="for Debian (including CPU microcode, GPU, network, and core\n"
|
|
plan+="drivers). The script has scanned your hardware to prepare\n"
|
|
plan+="the setup:\n\n"
|
|
|
|
plan+="Detected controllers:\n"
|
|
if [ ${#_FW_PLAN_HW_LINES[@]} -eq 0 ]; then
|
|
plan+=" (none detected)\n"
|
|
else
|
|
for line in "${_FW_PLAN_HW_LINES[@]}"; do
|
|
plan+="${line}\n"
|
|
done
|
|
fi
|
|
|
|
plan+="\nPlanned firmware packages:\n"
|
|
local fw_line
|
|
if is_installed firmware-linux-nonfree; then
|
|
local cur_ver
|
|
cur_ver=$(_get_installed_version "firmware-linux-nonfree")
|
|
fw_line=" [+] firmware-linux-nonfree ${cur_ver} (already installed)"
|
|
else
|
|
fw_line=" [+] firmware-linux-nonfree (base meta-package)"
|
|
fi
|
|
plan+="${fw_line}\n"
|
|
|
|
for line in "${_FW_PLAN_PKG_LINES[@]}"; do
|
|
plan+="${line}\n"
|
|
done
|
|
|
|
local has_bt=false
|
|
[ ${#PCI_BT_DEVS[@]} -gt 0 ] && has_bt=true
|
|
[ ${#USB_BT_DEVS[@]} -gt 0 ] && has_bt=true
|
|
if ! $has_bt; then
|
|
for dev in "${USB_WIFI_DEVS[@]}"; do
|
|
if echo "$dev" | grep -qi 'bluetooth'; then
|
|
has_bt=true
|
|
break
|
|
fi
|
|
done
|
|
fi
|
|
|
|
plan+="\nBluetooth:\n"
|
|
if $has_bt; then
|
|
if is_installed bluez; then
|
|
plan+=" [+] bluez (already installed)\n"
|
|
else
|
|
plan+=" [+] bluez + bluez-tools + bluez-obexd (base stack)\n"
|
|
fi
|
|
case "${DESKTOP_ENV:-other}" in
|
|
kde)
|
|
plan+=" [+] bluedevil (KDE applet)\n"
|
|
if [ "${AUDIO_SERVER:-}" = "pipewire" ]; then
|
|
plan+=" → pipewire-pulse + wireplumber (if missing)\n"
|
|
fi
|
|
;;
|
|
gnome) plan+=" (already in gnome-control-center)\n" ;;
|
|
*) plan+=" [+] blueman (GTK Bluetooth manager)\n" ;;
|
|
esac
|
|
plan+=" → Bluetooth service will be enabled\n"
|
|
else
|
|
plan+=" (no Bluetooth hardware detected)\n"
|
|
fi
|
|
|
|
plan+="\nInstallation order:\n"
|
|
plan+=" 1. Base firmware (firmware-linux-nonfree)\n"
|
|
plan+=" 2. Network firmware (realtek, iwlwifi, ...)\n"
|
|
plan+=" 3. Broadcom / Bluetooth firmware\n"
|
|
|
|
echo -e "$plan"
|
|
}
|
|
|
|
# ── Install detected firmware packages ──
|
|
_install_detected_firmware() {
|
|
local to_install=()
|
|
for pkg in "${_DETECTED_FW_PKGS[@]}"; do
|
|
if is_installed "$pkg"; then
|
|
echo " --> $pkg already installed."
|
|
continue
|
|
fi
|
|
local ver
|
|
ver=$(_get_pkg_version "$pkg")
|
|
if [ -z "$ver" ] || [ "$ver" = "(none)" ]; then
|
|
echo " --> $pkg not available in repositories, skipping."
|
|
continue
|
|
fi
|
|
to_install+=("$pkg")
|
|
done
|
|
if [ ${#to_install[@]} -gt 0 ]; then
|
|
_run_cmd "Firmware" "sudo DEBIAN_FRONTEND=noninteractive apt install -y ${to_install[*]}" \
|
|
"Installing network firmware packages..." || true
|
|
fi
|
|
}
|
|
|
|
# ── Wireless handler (Broadcom single-path wl) ──
|
|
_handle_wireless() {
|
|
local installed_any=false
|
|
local wl_build_failed=false
|
|
|
|
if [ ${#PCI_NET_DEVS[@]} -eq 0 ] && [ ${#USB_WIFI_DEVS[@]} -eq 0 ]; then
|
|
_detect_all_network_devices
|
|
fi
|
|
|
|
for dev in "${PCI_NET_DEVS[@]}"; do
|
|
local bcm_id dev_id
|
|
bcm_id=$(echo "$dev" | grep -oP '14e4:[0-9a-fA-F]+' || true)
|
|
[ -z "$bcm_id" ] && continue
|
|
dev_id=$(echo "$bcm_id" | cut -d: -f2 | tr '[:upper:]' '[:lower:]')
|
|
|
|
# --- Dependencies verification ---
|
|
if ! is_installed "linux-headers-amd64" || ! is_installed "dkms"; then
|
|
if ! apt-cache show linux-headers-amd64 dkms >/dev/null 2>&1; then
|
|
_msg "Broadcom Error" "linux-headers-amd64 or dkms are not available in your repositories. Cannot compile Broadcom driver.\n\nEnsure repositories are enabled and run:\n sudo apt install linux-headers-amd64 dkms"
|
|
_pause
|
|
continue
|
|
fi
|
|
fi
|
|
|
|
# --- Confirmation ---
|
|
if ! _confirm "Broadcom WiFi" "Detected Broadcom wireless device.\n\nInstall broadcom-sta-dkms, dkms, and wireless-tools?"; then
|
|
continue
|
|
fi
|
|
|
|
# --- Step-by-step installation ---
|
|
_run_cmd "Broadcom Deps" "sudo DEBIAN_FRONTEND=noninteractive apt install -y dkms wireless-tools linux-headers-amd64" || true
|
|
_run_cmd "Broadcom Driver" "sudo DEBIAN_FRONTEND=noninteractive apt install -y broadcom-sta-dkms" || true
|
|
|
|
# --- Persist blacklist of conflicting modules ---
|
|
local blacklist_conf="/etc/modprobe.d/blacklist-broadcom.conf"
|
|
local blacklist_content="blacklist b43\nblacklist b43legacy\nblacklist brcmsmac\nblacklist bcma\nblacklist ssb"
|
|
echo -e "$blacklist_content" | sudo tee "$blacklist_conf" >/dev/null || true
|
|
|
|
# --- Update initramfs and load module ---
|
|
_run_cmd "Initramfs" "sudo update-initramfs -u" || true
|
|
_run_cmd "Modprobe" "sudo modprobe -r b43 b43legacy b44 bcma brcmsmac brcmfmac ssb wl 2>/dev/null || true" "Removing conflicting modules" || true
|
|
_run_cmd "Modprobe" "sudo modprobe wl" || true
|
|
|
|
# --- Combo BT (unchanged) ---
|
|
local has_broadcom_bt=false
|
|
local btdev
|
|
for btdev in "${PCI_BT_DEVS[@]}"; do
|
|
if echo "$btdev" | grep -qi 'broadcom'; then
|
|
has_broadcom_bt=true
|
|
break
|
|
fi
|
|
done
|
|
if $has_broadcom_bt; then
|
|
echo -e "${YELLOW}[+] Broadcom WiFi+BT combo card detected.${NC}"
|
|
sudo mkdir -p /etc/modprobe.d
|
|
printf 'softdep wl post: btusb\n' | sudo tee /etc/modprobe.d/broadcom-combo.conf >/dev/null || true
|
|
echo -e "${YELLOW} A reboot may be required for Bluetooth support.${NC}"
|
|
fi
|
|
|
|
# --- Post-DKMS verification (Fix 5, unchanged) ---
|
|
if ! ls /lib/modules/$(uname -r)/updates/dkms/wl.ko* 2>/dev/null | grep -q .; then
|
|
_msg "Broadcom DKMS Build Failed" "The wl module was not built by DKMS.\n\nPossible causes:\n- Missing build tools (build-essential, dkms)\n- Kernel update without headers\n- Incompatible kernel version\n\nTry: sudo dpkg-reconfigure broadcom-sta-dkms"
|
|
if _confirm "Broadcom" "Rebuild the Broadcom driver now?"; then
|
|
_run_cmd "Broadcom" "sudo dpkg-reconfigure broadcom-sta-dkms" || true
|
|
if ls /lib/modules/$(uname -r)/updates/dkms/wl.ko* 2>/dev/null | grep -q .; then
|
|
:
|
|
else
|
|
local dmesg_out
|
|
dmesg_out=$(sudo dmesg | tail -20 2>/dev/null || echo "(dmesg unavailable)")
|
|
_msg "Broadcom DKMS Still Failed" "dpkg-reconfigure did not produce wl.ko either.\n\nLast kernel messages:\n${dmesg_out}\n\nYou may need to check build logs or report a bug against broadcom-sta-dkms."
|
|
_pause
|
|
wl_build_failed=true
|
|
continue
|
|
fi
|
|
else
|
|
wl_build_failed=true
|
|
continue
|
|
fi
|
|
fi
|
|
|
|
_msg "Network Warning" "The script is about to unload current WiFi kernel modules to load the Broadcom driver.\n\nIf you are connected via SSH over WiFi, YOUR CONNECTION WILL DROP. Please reconnect after a few seconds."
|
|
sudo modprobe -r b43 b43legacy b44 bcma brcmsmac brcmfmac ssb wl 2>/dev/null || true
|
|
sudo modprobe wl 2>/dev/null || true
|
|
|
|
# --- Verificación de carga ---
|
|
if lsmod | grep -q '^wl '; then
|
|
echo -e "${GREEN}[+] Broadcom WiFi activated (wl module loaded).${NC}"
|
|
_pause
|
|
installed_any=true
|
|
else
|
|
echo -e "${YELLOW}[+] Broadcom driver installed but wl module did not load.${NC}"
|
|
echo -e "${YELLOW} A system reboot is required.${NC}"
|
|
_pause
|
|
installed_any=true
|
|
fi
|
|
done
|
|
|
|
# --- USB Broadcom (unchanged) ---
|
|
local usb_dev
|
|
for usb_dev in "${USB_WIFI_DEVS[@]}"; do
|
|
if echo "$usb_dev" | grep -qi '0a5c'; then
|
|
_msg "USB Broadcom" "USB Broadcom device detected (0a5c).\n\nLinux does not have native drivers for most USB Broadcom WiFi chips.\nndiswrapper may be needed as a last resort."
|
|
_pause
|
|
fi
|
|
done
|
|
|
|
# --- Mensaje final (unchanged) ---
|
|
if ! $installed_any && ! $wl_build_failed; then
|
|
echo "No special WiFi firmware needed -- base firmware-linux-nonfree covers this system."
|
|
_pause
|
|
fi
|
|
}
|
|
|
|
# ── Ensure non-free repository is enabled ──
|
|
# Token-exact check for the "non-free" component. "non-free-firmware"
|
|
# contains the substring but is a different component, so word-boundary
|
|
# matching (\b) would produce false positives.
|
|
_has_nonfree_component() {
|
|
local file="$1"
|
|
grep -qE '^[^#]*[[:space:]]non-free([[:space:]]|$)' "$file" 2>/dev/null
|
|
}
|
|
|
|
_ensure_nonfree_repo() {
|
|
local nonfree_found=false
|
|
if [ -f /etc/apt/sources.list ] && _has_nonfree_component /etc/apt/sources.list; then
|
|
nonfree_found=true
|
|
fi
|
|
if ! $nonfree_found && [ -d /etc/apt/sources.list.d ]; then
|
|
for f in /etc/apt/sources.list.d/*.sources /etc/apt/sources.list.d/*.list; do
|
|
[ -f "$f" ] || continue
|
|
if _has_nonfree_component "$f"; then
|
|
nonfree_found=true
|
|
break
|
|
fi
|
|
done
|
|
fi
|
|
if $nonfree_found; then
|
|
return 0
|
|
fi
|
|
|
|
if ! _confirm "non-free Repository" "Component 'non-free' (and 'non-free-firmware') is required for WiFi/Bluetooth/GPU firmware.\n\nAdd them to your APT repositories?"; then
|
|
return 1
|
|
fi
|
|
|
|
# No active sources at all → bootstrap a complete configuration
|
|
if ! has_active_deb_sources; then
|
|
backup_current_repos
|
|
if ! bootstrap_repositories "main contrib non-free non-free-firmware"; then
|
|
return 1
|
|
fi
|
|
else
|
|
if [ -f /etc/apt/sources.list ]; then
|
|
sudo cp /etc/apt/sources.list "/etc/apt/sources.list.backup.$(date +%Y%m%d_%H%M%S)"
|
|
# Add each missing component after the space-delimited "main"
|
|
# component; a bare s/main/ would corrupt mirror URLs that
|
|
# contain "main" (e.g. https://main.example.com).
|
|
sudo sed -i -E '/^deb / { /(^|[[:space:]])non-free([[:space:]]|$)/! s/ main([[:space:]]|$)/ main non-free\1/ }' /etc/apt/sources.list
|
|
# non-free-firmware does not exist on Bullseye
|
|
if [ "$DEBIAN_VERSION" != "11" ]; then
|
|
sudo sed -i -E '/^deb / { /(^|[[:space:]])non-free-firmware([[:space:]]|$)/! s/ main([[:space:]]|$)/ main non-free-firmware\1/ }' /etc/apt/sources.list
|
|
fi
|
|
fi
|
|
if [ -d /etc/apt/sources.list.d ]; then
|
|
for f in /etc/apt/sources.list.d/*.sources; do
|
|
[ -f "$f" ] || continue
|
|
sudo cp "$f" "${f}.backup.$(date +%Y%m%d_%H%M%S)"
|
|
sudo sed -i -E '/^Components:/ { /(^|[[:space:]])non-free([[:space:]]|$)/! s/$/ non-free/ }' "$f"
|
|
if [ "$DEBIAN_VERSION" != "11" ]; then
|
|
sudo sed -i -E '/^Components:/ { /(^|[[:space:]])non-free-firmware([[:space:]]|$)/! s/$/ non-free-firmware/ }' "$f"
|
|
fi
|
|
done
|
|
fi
|
|
fi
|
|
|
|
# Verify the component was actually added before reporting success
|
|
local nonfree_ok=false
|
|
[ -f /etc/apt/sources.list ] && _has_nonfree_component /etc/apt/sources.list && nonfree_ok=true
|
|
if ! $nonfree_ok && [ -d /etc/apt/sources.list.d ]; then
|
|
for f in /etc/apt/sources.list.d/*.sources /etc/apt/sources.list.d/*.list; do
|
|
[ -f "$f" ] || continue
|
|
if _has_nonfree_component "$f"; then
|
|
nonfree_ok=true
|
|
break
|
|
fi
|
|
done
|
|
fi
|
|
if ! $nonfree_ok; then
|
|
echo -e "${RED}Failed to enable non-free repository. Check your APT sources.${NC}"
|
|
return 1
|
|
fi
|
|
|
|
_ensure_apt_updated
|
|
echo -e "${GREEN}non-free repository enabled.${NC}"
|
|
return 0
|
|
}
|
|
|
|
# ── Main entry point ──
|
|
install_firmware() {
|
|
echo -e "${YELLOW}Base firmware check...${NC}"
|
|
|
|
if ! _ensure_nonfree_repo; then
|
|
_msg "Error" "No 'non-free' repositories were enabled and the user declined to add them.\nPlease enable non-free manually or accept the prompt in the Firmware option." 10 65
|
|
return 1
|
|
fi
|
|
|
|
# 1. Detect
|
|
_detect_all_network_devices
|
|
_detect_firmware_needs
|
|
|
|
# 2. Plan
|
|
local plan
|
|
plan=$(_build_firmware_plan)
|
|
_msg "Firmware, Wireless & Bluetooth Setup" "$plan" 22 72
|
|
|
|
# 3. Confirm
|
|
if ! _confirm "Firmware" "Apply the network & firmware plan?"; then
|
|
echo "Firmware installation skipped."
|
|
return
|
|
fi
|
|
|
|
# 4. Install base firmware meta-package (unchanged logic)
|
|
local fw_pkg="firmware-linux-nonfree"
|
|
local fw_bpo
|
|
fw_bpo=$(_get_backports_version "$fw_pkg")
|
|
|
|
local fw_stable
|
|
fw_stable=$(_get_pkg_version "$fw_pkg")
|
|
|
|
if is_installed "$fw_pkg"; then
|
|
if [ -n "$fw_bpo" ]; then
|
|
local current_ver
|
|
current_ver=$(_get_installed_version "$fw_pkg")
|
|
if _confirm "Firmware" "firmware-linux-nonfree ${current_ver} already installed.\n\nUpgrade to backports version ${fw_bpo}?\n\nBackports often includes newer hardware support."; then
|
|
_run_cmd "Firmware" "sudo apt install -y -t ${DEBIAN_CODENAME}-backports $fw_pkg" "Upgrading firmware..." || true
|
|
fi
|
|
else
|
|
echo "$fw_pkg already installed."
|
|
fi
|
|
else
|
|
local msg="firmware-linux-nonfree provides hardware drivers for:\n"
|
|
msg+=" WiFi, Bluetooth, GPU, audio, webcams, and more.\n\n"
|
|
if [ -n "$fw_bpo" ]; then
|
|
msg+=" ● Stable: ${fw_stable}\n"
|
|
msg+=" Ultra tested, but may lack support for\n"
|
|
msg+=" very recent hardware.\n\n"
|
|
msg+=" ● Backports: ${fw_bpo} (Recommended)\n"
|
|
msg+=" Updated firmware for modern hardware from\n"
|
|
msg+=" 2025/2026: recent GPUs, processors, WiFi.\n\n"
|
|
msg+="Choose version:"
|
|
if _confirm_custom "Firmware" "$msg" "Backports" "Stable"; then
|
|
_run_cmd "Firmware" "sudo apt install -y -t ${DEBIAN_CODENAME}-backports $fw_pkg" "Installing firmware from backports..." || true
|
|
else
|
|
_run_cmd "Firmware" "sudo apt install -y $fw_pkg" "Installing firmware from stable..." || true
|
|
fi
|
|
else
|
|
msg+=" Version: ${fw_stable}\n\n"
|
|
msg+="Install it?"
|
|
if _confirm "Firmware" "$msg"; then
|
|
_run_cmd "Firmware" "sudo apt install -y $fw_pkg" "Installing firmware..." || true
|
|
fi
|
|
fi
|
|
echo -e "${GREEN}Base firmware installed.${NC}"
|
|
fi
|
|
|
|
# 5. Install specific network firmware packages
|
|
_install_detected_firmware
|
|
|
|
# 6. Broadcom wireless handler
|
|
_handle_wireless
|
|
|
|
# 7. Bluetooth stack
|
|
_install_bluetooth_stack
|
|
|
|
# 8. Summary
|
|
echo -e "${GREEN}Network & firmware setup complete.${NC}"
|
|
_pause
|
|
}
|