🔒 Repository is read-only – file editing is disabled.

PaganLinux/fix-rootfs.sh main

444 linii Raw ← Powrót
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444
#!/bin/bash
# fix-rootfs.sh — nakłada poprawki na istniejący rootfs (bez przebudowy pakietów),
# przed ponownym budowaniem ISO. Uzupełnienie dla build-pagan.sh (którego poprawki
# wchodzą w życie dopiero przy świeżym buildzie; resume pomija już zbudowane pakiety).
#
# Uruchom: sudo ./fix-rootfs.sh [PAGAN_ROOT]
set -euo pipefail

PAGAN_ROOT="${1:-/mnt/pagan}"

if [[ ! -d "$PAGAN_ROOT/usr" || ! -d "$PAGAN_ROOT/etc" || ! -f "$PAGAN_ROOT/etc/passwd" ]]; then
    echo "BŁĄD: $PAGAN_ROOT nie wygląda na rootfs Pagan" >&2
    exit 1
fi

# dbus: jeśli binarka wspiera aktywację socketową (przebudowa z ENABLE_SYSTEMD=ON
# w build-pagan.sh), piszemy POPRAWNE jednostki dbus.socket/dbus.service
# (cmake z dbus 1.16.2 generuje je z pustymi @EXPANDED_BINDIR@/@DBUS_SYSTEM_SOCKET@ –
# bug, patrz bus/dbus.service.in) i włączamy socket. Hack tylko dla starego dbus
# (bez wsparcia systemd). Uwaga: dbus-daemon --help NIE pokazuje tej opcji,
# dlatego sprawdzamy strings.
if strings "$PAGAN_ROOT/usr/bin/dbus-daemon" 2>/dev/null | grep -q -- "--systemd-activation"; then
    echo "=== 1/8 dbus: wsparcie systemd (aktywacja socketowa) – poprawne jednostki ==="
    cat > "$PAGAN_ROOT/usr/lib/systemd/system/dbus.socket" <<'EOF'
[Unit]
Description=D-Bus System Message Bus Socket

[Socket]
ListenStream=/run/dbus/system_bus_socket
SocketMode=0666

[Install]
WantedBy=sockets.target
EOF
    cat > "$PAGAN_ROOT/usr/lib/systemd/system/dbus.service" <<'EOF'
[Unit]
Description=D-Bus System Message Bus
Documentation=man:dbus-daemon(1)
Requires=dbus.socket

[Service]
Type=notify
NotifyAccess=main
ExecStart=/usr/bin/dbus-daemon --system --address=systemd: --nofork --nopidfile --systemd-activation --syslog-only
ExecReload=/usr/bin/dbus-send --print-reply --system --type=method_call --dest=org.freedesktop.DBus / org.freedesktop.DBus.ReloadConfig
ExecStartPre=/usr/bin/dbus-uuidgen --ensure
RuntimeDirectory=dbus
RuntimeDirectoryMode=0755
Restart=on-failure
RestartSec=1s
OOMScoreAdjust=-900
EOF
    # Stary symlink z hacka (multi-user.target.wants) i drop-in logind są zbędne
    rm -f "$PAGAN_ROOT/etc/systemd/system/multi-user.target.wants/dbus.service" \
          "$PAGAN_ROOT/etc/systemd/system/systemd-logind.service.d/override.conf"
    chroot "$PAGAN_ROOT" systemctl enable dbus.socket 2>/dev/null || true
    # Wczesny start dbus.service (sockets.target) – klienci (PID1/networkd) łączą
    # się zanim daemon wystartuje; dbus zrywa połączenia z okna startowego
    ln -sf /usr/lib/systemd/system/dbus.service \
           "$PAGAN_ROOT/etc/systemd/system/sockets.target.wants/dbus.service"
else
    echo "=== 1/8 dbus: usuwam dbus.socket (aktywacja socketowa psuje dbus-daemon) ==="
    rm -f "$PAGAN_ROOT/usr/lib/systemd/system/dbus.socket" \
          "$PAGAN_ROOT/etc/systemd/system/sockets.target.wants/dbus.socket"

    echo "=== 2/8 dbus.service: klasyczne wywołanie + czekanie na socket + restart ==="
    cat > "$PAGAN_ROOT/usr/lib/systemd/system/dbus.service" <<'EOF'
[Unit]
Description=D-Bus System Message Bus

[Service]
ExecStart=/usr/bin/dbus-daemon --system --nofork --nopidfile
ExecStartPost=/bin/sh -c 'i=0; while [ ! -S /run/dbus/system_bus_socket ] && [ $i -lt 100 ]; do i=$((i+1)); sleep 0.1; done; [ -S /run/dbus/system_bus_socket ]'
ExecReload=/usr/bin/dbus-send --print-reply --system --type=method_call --dest=org.freedesktop.DBus / org.freedesktop.DBus.ReloadConfig
ExecStartPre=/usr/bin/dbus-uuidgen --ensure
RuntimeDirectory=dbus
RuntimeDirectoryMode=0755
Restart=on-failure
RestartSec=1
Type=simple
EOF
    # dbus-daemon loguje na stderr → journal → konsola (diagnostyka)
    grep -q '^ExecStart=/usr/bin/dbus-daemon --system --nofork --nopidfile$' "$PAGAN_ROOT/usr/lib/systemd/system/dbus.service" || {
        echo "BŁĄD: dbus.service nie ma poprawnego ExecStart" >&2
        exit 1
    }
fi

echo "=== 3/7 usrmerge: /usr/sbin → /usr/bin, /sbin → usr/bin (systemd split-usr=false) ==="
if [[ ! -L "$PAGAN_ROOT/usr/sbin" && -d "$PAGAN_ROOT/usr/sbin" ]]; then
    # SysVinit-owe halt/shutdown/poweroff/reboot przegrywają z systemd (/usr/bin)
    rm -f "$PAGAN_ROOT/usr/sbin/halt" "$PAGAN_ROOT/usr/sbin/shutdown" \
          "$PAGAN_ROOT/usr/sbin/poweroff" "$PAGAN_ROOT/usr/sbin/reboot" \
          "$PAGAN_ROOT/usr/sbin/init"
    mv "$PAGAN_ROOT/usr/sbin"/* "$PAGAN_ROOT/usr/bin/"
    rmdir "$PAGAN_ROOT/usr/sbin"
fi
ln -sfn bin "$PAGAN_ROOT/usr/sbin"
ln -sfn usr/bin "$PAGAN_ROOT/sbin"

echo "=== 4/7 /usr/lib64 → /usr/lib (ld.so nie szuka /usr/lib64; libtiff → libjpeg.so.62) ==="
if [[ ! -L "$PAGAN_ROOT/usr/lib64" && -d "$PAGAN_ROOT/usr/lib64" ]]; then
    # zachowaj dev-symlink libjpeg.so z /usr/lib (→ .8); stary .pc też pomijamy
    rm -f "$PAGAN_ROOT/usr/lib64/libjpeg.so" "$PAGAN_ROOT/usr/lib64/pkgconfig/libjpeg.pc"
    cp -a "$PAGAN_ROOT/usr/lib64/." "$PAGAN_ROOT/usr/lib/" 2>/dev/null || true
    rm -rf "$PAGAN_ROOT/usr/lib64"
fi
ln -sfn lib "$PAGAN_ROOT/usr/lib64"

echo "=== 5/7 /var/run, /var/lock → symlinki do tmpfs /run (taint var-run-bad) ==="
rm -rf "$PAGAN_ROOT/var/run"
ln -sfn ../run "$PAGAN_ROOT/var/run"
rm -rf "$PAGAN_ROOT/var/lock"
ln -sfn ../run/lock "$PAGAN_ROOT/var/lock"

echo "=== 6/7 użytkownicy/grupy + systemd-owe binarki kontrolne ==="
grep -q '^man:' "$PAGAN_ROOT/etc/passwd" || \
    echo 'man:x:12:12:Manuals Reader:/var/cache/man:/usr/sbin/nologin' >> "$PAGAN_ROOT/etc/passwd"
grep -q '^messagebus:' "$PAGAN_ROOT/etc/passwd" || \
    echo 'messagebus:x:81:81:system message bus:/:/usr/sbin/nologin' >> "$PAGAN_ROOT/etc/passwd"
for g in "man:x:12:" "clock:x:35:" "sgx:x:974:" "messagebus:x:81:"; do
    name="${g%%:*}"
    grep -q "^${name}:" "$PAGAN_ROOT/etc/group" || echo "$g" >> "$PAGAN_ROOT/etc/group"
done
for b in halt poweroff reboot shutdown; do
    ln -sf systemctl "$PAGAN_ROOT/usr/bin/$b"
done
ln -sf ../lib/systemd/systemd "$PAGAN_ROOT/usr/bin/init"

# logind: zależał od dbus.socket (nie istnieje) – drop-in na dbus.service.
# (tylko dla starego dbus bez aktywacji socketowej; przy standardowym dbus.socket
# drop-in jest zbędny – socket aktywuje daemona przed dokończeniem connect)
echo "=== 7/8 logind drop-in (After=dbus.service) + locale UTF-8 ==="
if strings "$PAGAN_ROOT/usr/bin/dbus-daemon" 2>/dev/null | grep -q -- "--systemd-activation"; then
    rm -rf "$PAGAN_ROOT/etc/systemd/system/systemd-logind.service.d"
else
    mkdir -p "$PAGAN_ROOT/etc/systemd/system/systemd-logind.service.d"
    cat > "$PAGAN_ROOT/etc/systemd/system/systemd-logind.service.d/override.conf" <<'EOF'
[Unit]
Wants=dbus.service
After=dbus.service
EOF
fi

for _loc in en_US.UTF-8 pl_PL.UTF-8; do
    mkdir -p "$PAGAN_ROOT/usr/lib/locale"
    chroot "$PAGAN_ROOT" /usr/bin/localedef -i "${_loc%.*}" -f UTF-8 "$_loc" || true
done
ls "$PAGAN_ROOT/usr/lib/locale/" 2>/dev/null || true

# PAM + sddm + autologin – parzystość z finalize_build() w build-pagan.sh.
# Stary /etc/pam.d/login (np. z shadow) odwołuje się do pam_selinux.so i
# pam_console.so, których w tym systemie NIE MA → login: Permission denied,
# getty@tty1 w crash-loopie i w końcu start-limit-hit. Bez tych plików NIE
# da się zalogować na tty1/ttyS0.
echo "=== 8/8 PAM (login/system-*) + autologin tty1 + sddm off ==="
mkdir -p "$PAGAN_ROOT/etc/pam.d"

cat > "$PAGAN_ROOT/etc/pam.d/other" <<'EOF'
#%PAM-1.0
auth        required    pam_deny.so
auth        required    pam_warn.so
account     required    pam_deny.so
account     required    pam_warn.so
password    required    pam_deny.so
password    required    pam_warn.so
session     required    pam_deny.so
session     required    pam_warn.so
EOF

cat > "$PAGAN_ROOT/etc/pam.d/system-auth" <<'EOF'
#%PAM-1.0
auth      required    pam_env.so
auth      sufficient  pam_unix.so nullok try_first_pass
auth      required    pam_deny.so
EOF

cat > "$PAGAN_ROOT/etc/pam.d/system-account" <<'EOF'
#%PAM-1.0
account   required    pam_unix.so
EOF

cat > "$PAGAN_ROOT/etc/pam.d/system-password" <<'EOF'
#%PAM-1.0
password  required    pam_unix.so sha512 shadow nullok try_first_pass
EOF

cat > "$PAGAN_ROOT/etc/pam.d/system-session" <<'EOF'
#%PAM-1.0
session   required    pam_limits.so
session   required    pam_unix.so
session   optional    pam_systemd.so
EOF

cat > "$PAGAN_ROOT/etc/pam.d/system-login" <<'EOF'
#%PAM-1.0
auth      include     system-auth
account   include     system-account
password  include     system-password
session   include     system-session
EOF

cat > "$PAGAN_ROOT/etc/pam.d/system-local-login" <<'EOF'
#%PAM-1.0
auth      include     system-login
account   include     system-login
password  include     system-login
session   include     system-login
EOF

cat > "$PAGAN_ROOT/etc/pam.d/sddm-autologin" <<'EOF'
#%PAM-1.0
auth      required    pam_env.so
auth      required    pam_permit.so
account   include     system-local-login
password  include     system-local-login
session   include     system-local-login
session   optional    pam_systemd.so
EOF

cat > "$PAGAN_ROOT/etc/pam.d/sddm" <<'EOF'
#%PAM-1.0
auth      include     system-login
account   include     system-login
password  include     system-login
session   include     system-login
session   optional    pam_systemd.so
EOF

cat > "$PAGAN_ROOT/etc/pam.d/sddm-greeter" <<'EOF'
#%PAM-1.0
auth      required    pam_env.so
auth      required    pam_permit.so
account   required    pam_permit.so
password  required    pam_deny.so
session   required    pam_unix.so
session   optional    pam_systemd.so
EOF

# Nadpisanie domyślnego niespójnego /etc/pam.d/login (np. z shadow), które odwołuje się do SELinux/console
cat > "$PAGAN_ROOT/etc/pam.d/login" <<'EOF'
#%PAM-1.0
auth       required     pam_securetty.so
auth       requisite    pam_nologin.so
auth       include      system-local-login
account    include      system-local-login
password   include      system-local-login
session    include      system-local-login
session    optional     pam_loginuid.so
EOF

# Naprawa /etc/pam.d/sudo – starsze obrazy miały "account include system-auth",
# co daje PUSTY stos account (system-auth ma tylko auth) i sudo pada:
# "account validation failure, is your account locked?".
cat > "$PAGAN_ROOT/etc/pam.d/sudo" <<'EOF'
#%PAM-1.0
auth      include     system-auth
account   include     system-account
session   required    pam_env.so
session   include     system-session
EOF
chmod 644 "$PAGAN_ROOT/etc/pam.d/sudo"

# Upewnij sie, ze uzytkownik pagan nie ma wygaszonego hasla (wazne dla autologin)
chroot "$PAGAN_ROOT" chage -E -1 -m 0 -M 99999 pagan 2>/dev/null || true
echo "pagan:changeme" | chroot "$PAGAN_ROOT" chpasswd 2>/dev/null || true

# Autologin na tty1 (root) dla automatycznego startu instalatora
mkdir -p "$PAGAN_ROOT/etc/systemd/system/getty@tty1.service.d"
cat > "$PAGAN_ROOT/etc/systemd/system/getty@tty1.service.d/autologin.conf" <<'EOF'
[Service]
ExecStart=
ExecStart=-/sbin/agetty --autologin root --noclear %I $TERM
EOF

# Autostart sesji live po zalogowaniu na tty1 (bash): startx → .xinitrc.
# Instalator to Calamares (ikona „Zainstaluj Pagan Linux” na pulpicie).
mkdir -p "$PAGAN_ROOT/etc/profile.d"
rm -f "$PAGAN_ROOT/etc/profile.d/pagan-installer.sh" 2>/dev/null || true
cat > "$PAGAN_ROOT/etc/profile.d/pagan-live.sh" <<'EOF'
if [ "$(tty 2>/dev/null)" = "/dev/tty1" ] && command -v startx >/dev/null 2>&1; then
    if [ -n "${DISPLAY:-}${WAYLAND_DISPLAY:-}" ]; then
        return 0 2>/dev/null || true
    fi
    clear
    echo "PaganLinux – uruchamiam sesję live (startx)..."
    startx
fi
EOF
chmod +x "$PAGAN_ROOT/etc/profile.d/pagan-live.sh"

# /etc/profile – bash login shell ładuje TYLKO /etc/profile; bez niego profile.d
# (m.in. pagan-live.sh) nigdy się nie wykona i live wita gołym bashem.
if [[ ! -s "$PAGAN_ROOT/etc/profile" ]]; then
    cat > "$PAGAN_ROOT/etc/profile" <<'EOF'
# /etc/profile – systemowe zmienne środowiskowe i programy startowe
export PATH=/usr/local/bin:/usr/bin:/bin:/usr/local/sbin:/usr/sbin:/sbin
export HISTCONTROL=ignoredups
export HISTSIZE=1000
export HISTFILESIZE=2000
if [ "$PS1" ]; then
    umask 022
fi
# Ładuj skrypty z /etc/profile.d (kolejność alfabetyczna)
for script in /etc/profile.d/*.sh ; do
    if [ -r "$script" ]; then
        . "$script"
    fi
done
unset script
EOF
    echo "[fix] /etc/profile utworzony (ładuje /etc/profile.d/*.sh)"
fi
if [[ ! -s "$PAGAN_ROOT/etc/bashrc" ]]; then
    cat > "$PAGAN_ROOT/etc/bashrc" <<'EOF'
# /etc/bashrc – interaktywne shelle nie-loginowe (aliasy/funkcje)
if [ "$PS1" ]; then
    umask 022
fi
EOF
echo "[fix] /etc/bashrc utworzony"
fi

# DNS dla live: bez resolv.conf netinstall nie ruszy (curl nie rozwiąże nazw)
if [[ ! -s "$PAGAN_ROOT/etc/resolv.conf" ]]; then
    cat > "$PAGAN_ROOT/etc/resolv.conf" <<'EOF'
nameserver 1.1.1.1
nameserver 8.8.8.8
EOF
    echo "[fix] /etc/resolv.conf utworzony (fallback DNS)"
fi

# mkfs.vfat: dosfstools 4.2 bez --enable-compat-symlinks nie tworzy symlinku
if [[ -x "$PAGAN_ROOT/usr/sbin/mkfs.fat" && ! -e "$PAGAN_ROOT/usr/sbin/mkfs.vfat" ]]; then
    ln -sf mkfs.fat "$PAGAN_ROOT/usr/sbin/mkfs.vfat"
    ln -sf mkfs.fat "$PAGAN_ROOT/usr/sbin/mkfs.msdos"
    echo "[fix] symlinki mkfs.vfat/mkfs.msdos utworzone"
fi

# Domyślny start do trybu TUI (multi-user.target) zamiast odpalania menedżera logowania
chroot "$PAGAN_ROOT" systemctl set-default multi-user.target 2>/dev/null || true
chroot "$PAGAN_ROOT" systemctl disable sddm 2>/dev/null || true

# Uprawnienia sudo dla grupy wheel
mkdir -p "$PAGAN_ROOT/etc/sudoers.d"
echo "%wheel ALL=(ALL:ALL) ALL" > "$PAGAN_ROOT/etc/sudoers.d/wheel"
chmod 440 "$PAGAN_ROOT/etc/sudoers.d/wheel" 2>/dev/null || true

# TYMCZASOWA usługa diagnostyczna – zrzuca stan boota + RĘCZNIE odpala Xorga,
# żeby zobaczyć stderr/log Xorga (sddm go połyka). Domyślnie WYŁĄCZONA –
# włącza się tylko przez PAGAN_DIAG=1 ./fix-rootfs.sh. NIGDY nie powinna
# trafić do ISO (opóźnia boot o 10 s i samowolnie startuje/zabija Xorga).
if [[ "${PAGAN_DIAG:-0}" == "1" ]]; then
    cat > "$PAGAN_ROOT/etc/pagan-diag.sh" <<'EOF'
#!/bin/sh
sleep 10
echo "===== PAGAN DIAG V2 ====="
echo "-- /run/dbus:"; ls -la /run/dbus 2>&1
echo "-- dri:"; ls -la /dev/dri 2>&1
echo "-- locale:"; locale -a 2>&1
echo "-- mount:"; mount 2>&1 | grep -E "overlay|squashfs|/ " | head
echo "-- procs:"; pgrep -a dbus 2>&1; pgrep -a sddm 2>&1; pgrep -a X 2>&1
echo "-- Xorg perms:"; ls -la /usr/bin/Xorg 2>&1
echo "-- journal sddm:"; journalctl -b -u sddm --no-pager 2>&1 | tail -20
echo "-- dmesg tail:"; dmesg 2>&1 | tail -12
echo "=== RĘCZNY START Xorg ==="
/usr/bin/X -nolisten tcp -background none -seat seat0 vt2 -noreset \
    -logfile /tmp/xorg-diag.log -logverbose 3 >/tmp/xorg-stderr.log 2>&1 &
XPID=$!
sleep 8
kill $XPID 2>/dev/null
wait $XPID 2>/dev/null
echo "-- Xorg stderr:"; cat /tmp/xorg-stderr.log 2>&1 | head -40
echo "-- Xorg logfile:"; cat /tmp/xorg-diag.log 2>&1 | head -60
echo "===== END DIAG ====="
EOF
    chmod +x "$PAGAN_ROOT/etc/pagan-diag.sh"
    cat > "$PAGAN_ROOT/etc/systemd/system/pagan-diag.service" <<'EOF'
[Unit]
Description=Pagan boot diagnostics (TYMCZASOWA)
After=multi-user.target

[Service]
Type=oneshot
ExecStart=/bin/sh /etc/pagan-diag.sh
EOF
    mkdir -p "$PAGAN_ROOT/etc/systemd/system/multi-user.target.wants"
    ln -sf /usr/lib/systemd/system/pagan-diag.service \
           "$PAGAN_ROOT/etc/systemd/system/multi-user.target.wants/pagan-diag.service"
    echo "[diag] PAGAN_DIAG=1 – usługa diagnostyczna WŁĄCZONA (pamiętaj o wyłączeniu przed ISO!)"
else
    # Domyślnie: upewnij się, że po poprzednich diagnozach nic nie zostało
    rm -f "$PAGAN_ROOT/etc/systemd/system/multi-user.target.wants/pagan-diag.service" \
          "$PAGAN_ROOT/etc/systemd/system/pagan-diag.service" "$PAGAN_ROOT/etc/pagan-diag.sh"
fi

echo "=== Odświeżam ld.so.cache ==="
ldconfig -r "$PAGAN_ROOT" 2>/dev/null || echo "(ldconfig -r niekrytyczne)"

echo "=== Weryfikacja w chroot ==="
mount --rbind /dev "$PAGAN_ROOT/dev" 2>/dev/null || true
mount --make-rslave "$PAGAN_ROOT/dev" 2>/dev/null || true
mount -t proc proc "$PAGAN_ROOT/proc" 2>/dev/null || true
mount -t sysfs sysfs "$PAGAN_ROOT/sys" 2>/dev/null || true
mount -t tmpfs tmpfs "$PAGAN_ROOT/run" 2>/dev/null || true

rc=0
for b in /usr/bin/dbus-daemon /usr/bin/Xorg /usr/bin/sddm /usr/bin/kwin_wayland \
         /usr/bin/NetworkManager /usr/bin/agetty /usr/bin/modprobe; do
    if [[ ! -x "$PAGAN_ROOT$b" && ! -L "$PAGAN_ROOT$b" ]]; then
        echo "BRAK binarki: $b"
        rc=1
        continue
    fi
    missing=$(chroot "$PAGAN_ROOT" /usr/bin/ldd "$b" 2>&1 | grep "not found" || true)
    if [[ -z "$missing" ]]; then
        echo "OK   $b"
    else
        echo "BRAKUJĄCE LIBKI dla $b:"
        echo "$missing"
        rc=1
    fi
done

if chroot "$PAGAN_ROOT" /usr/bin/ldd /usr/lib/libtiff.so.6 2>&1 | grep -q "libjpeg.so.62"; then
    echo "OK   libtiff.so.6 → libjpeg.so.62"
else
    echo "UWAGA: libtiff.so.6 nie widzi libjpeg.so.62"
    rc=1
fi

umount -R "$PAGAN_ROOT/dev" 2>/dev/null || true
umount "$PAGAN_ROOT/proc" 2>/dev/null || true
umount "$PAGAN_ROOT/sys" 2>/dev/null || true
umount -R "$PAGAN_ROOT/run" 2>/dev/null || true

echo ""
if [[ $rc -eq 0 ]]; then
    echo "✅ Rootfs naprawiony. Można budować ISO:"
    echo "   cd /home/patryks/pagbuild && sudo ./build-pagan.sh --de kde --iso"
else
    echo "⚠️  Weryfikacja wykazała problemy (patrz wyżej)."
fi
exit $rc