Files
2026-04-24 04:17:40 +05:00

223 lines
9.3 KiB
Bash
Executable File

#!/bin/sh
export PATH="/bin:/sbin:/usr/bin:/usr/sbin:/usr/local/bin"
REGISTRY_FILE="/calista/registry.db"
BUILTIN_FILE="/calista/builtin_devices"
DRIVER_INSTALLER="/calista/driver_installer"
DETECTED_DEVICES="/tmp/calista_detected_devices.tmp"
# Функция логирования
log_to_registry() {
local type="$1"
local details="$2"
sqlite3 "$REGISTRY_FILE" "INSERT INTO calista_log (type, user, details)
VALUES ('$type', '$USER', '$details');" 2>/dev/null
}
# Проверяем, что реестр существует
if [ ! -f "$REGISTRY_FILE" ]; then
echo "Ошибка: Реестр не найден: $REGISTRY_FILE"
exit 1
fi
# Функция поиска устройства в файле builtin_devices
lookup_builtin_device() {
local vendor="$1"
local device="$2"
if [ -f "$BUILTIN_FILE" ]; then
grep -v "^ver" "$BUILTIN_FILE" 2>/dev/null | grep "^${vendor}:${device}:" | head -1
fi
}
# Очищаем файл обнаруженных устройств
> "$DETECTED_DEVICES"
log_to_registry "info" "Запущено обновление списка устройств"
# -------------------------------------------------------------------
# 1. Сканирование PCI-устройств
# -------------------------------------------------------------------
echo "Сканирование PCI-устройств..."
pciconf -l | while read -r line; do
DEV_NAME=$(echo "$line" | awk '{print $1}' | cut -d'@' -f1)
VENDOR=$(echo "$line" | grep -o 'vendor=0x[0-9a-fA-F]*' | cut -d'=' -f2 | head -1)
DEVICE=$(echo "$line" | grep -o 'device=0x[0-9a-fA-F]*' | cut -d'=' -f2 | head -1)
SUBVENDOR=$(echo "$line" | grep -o 'subvendor=0x[0-9a-fA-F]*' | cut -d'=' -f2 | head -1)
SUBDEVICE=$(echo "$line" | grep -o 'subdevice=0x[0-9a-fA-F]*' | cut -d'=' -f2 | head -1)
CLASS=$(echo "$line" | grep -o 'class=0x[0-9a-fA-F]*' | cut -d'=' -f2 | head -1)
if [ -z "$VENDOR" ] || [ -z "$DEVICE" ]; then
continue
fi
echo "pci|$VENDOR|$DEVICE" >> "$DETECTED_DEVICES"
CURRENT_STATUS=$(sqlite3 "$REGISTRY_FILE" "SELECT status FROM devices
WHERE bus='pci' AND vendor='$VENDOR' AND device='$DEVICE';" 2>/dev/null)
BUILTIN_INFO=$(lookup_builtin_device "$VENDOR" "$DEVICE")
if [ -n "$BUILTIN_INFO" ]; then
DEVICE_NAME=$(echo "$BUILTIN_INFO" | cut -d':' -f3)
DEVICE_TYPE=$(echo "$BUILTIN_INFO" | cut -d':' -f4)
if [ "$DEVICE_TYPE" = "builtin" ]; then
if [ "$DEV_NAME" != "none" ] && [ -n "$DEV_NAME" ]; then
STATUS="installed"
DRIVER="$DEV_NAME"
else
STATUS="builtin_available"
DRIVER=""
fi
else
if [ "$DEV_NAME" != "none" ] && [ -n "$DEV_NAME" ]; then
STATUS="installed"
DRIVER="$DEV_NAME"
else
STATUS="not_installed"
DRIVER=""
fi
fi
else
DEVICE_NAME="Неизвестное устройство (Class: $CLASS)"
DEVICE_TYPE="unknown"
if [ "$DEV_NAME" != "none" ] && [ -n "$DEV_NAME" ]; then
STATUS="installed"
DRIVER="$DEV_NAME"
else
STATUS="not_installed"
DRIVER=""
fi
fi
# Проверяем, существует ли запись
EXISTS=$(sqlite3 "$REGISTRY_FILE" "SELECT 1 FROM devices WHERE bus='pci' AND vendor='$VENDOR' AND device='$DEVICE';" 2>/dev/null)
if [ -z "$EXISTS" ]; then
# Новая запись
sqlite3 "$REGISTRY_FILE" <<EOF
INSERT INTO devices (bus, vendor, device, subvendor, subdevice, name, status, driver, detected_at)
VALUES ('pci', '$VENDOR', '$DEVICE', '$SUBVENDOR', '$SUBDEVICE', '$DEVICE_NAME', '$STATUS', '$DRIVER', CURRENT_TIMESTAMP);
EOF
echo " PCI: $VENDOR:$DEVICE -> $DEVICE_NAME (статус: $STATUS) [НОВОЕ]"
else
# Обновляем только статус и driver, если они изменились и статус не calista
if [ "$CURRENT_STATUS" != "installed_calista" ] && [ "$CURRENT_STATUS" != "installed_calista_error" ]; then
sqlite3 "$REGISTRY_FILE" <<EOF
UPDATE devices SET status='$STATUS', driver='$DRIVER', detected_at=CURRENT_TIMESTAMP
WHERE bus='pci' AND vendor='$VENDOR' AND device='$DEVICE';
EOF
fi
echo " PCI: $VENDOR:$DEVICE -> $DEVICE_NAME (статус: $STATUS) [ОБНОВЛЕНО]"
fi
# Логика установки драйвера
if [ "$CURRENT_STATUS" != "installed_calista" ] && [ "$CURRENT_STATUS" != "installed_calista_error" ] && [ "$DEVICE_TYPE" != "builtin" ]; then
echo " -> Попытка установки через driver-installer..."
if [ -x "$DRIVER_INSTALLER" ]; then
"$DRIVER_INSTALLER" update_list > /dev/null 2>&1
"$DRIVER_INSTALLER" get_name "$VENDOR" "$DEVICE" > /dev/null 2>&1
DEVICE_CHECK=$("$DRIVER_INSTALLER" get_name "$VENDOR" "$DEVICE" 2>/dev/null)
if [ "$DEVICE_CHECK" != "Неизвестное устройство" ] && [ -n "$DEVICE_CHECK" ]; then
echo " -> Найден драйвер: $DEVICE_CHECK"
"$DRIVER_INSTALLER" install "$VENDOR" "$DEVICE"
else
echo " -> Драйвер не найден в driver.list"
fi
fi
elif [ "$CURRENT_STATUS" = "installed_calista" ]; then
echo " -> Уже установлен через Calista, пропускаем"
elif [ "$DEVICE_TYPE" = "builtin" ]; then
echo " -> Встроен в ядро, установка не требуется"
fi
done
# -------------------------------------------------------------------
# 2. Сканирование USB-устройств
# -------------------------------------------------------------------
echo "Сканирование USB-устройств..."
usbconfig list | grep -E "^ugen[0-9]+\.[0-9]+:" | while read -r line; do
DEV_NAME=$(echo "$line" | awk '{print $1}' | cut -d':' -f1)
if echo "$DEV_NAME" | grep -q "\.1$"; then
continue
fi
DEV_INFO=$(usbconfig -d "$DEV_NAME" dump_device_desc 2>/dev/null)
VENDOR=$(echo "$DEV_INFO" | grep "idVendor" | sed -E 's/.*idVendor *= *0x([0-9a-fA-F]+).*/0x\1/' | head -1)
PRODUCT=$(echo "$DEV_INFO" | grep "idProduct" | sed -E 's/.*idProduct *= *0x([0-9a-fA-F]+).*/0x\1/' | head -1)
if [ -z "$VENDOR" ] || [ -z "$PRODUCT" ]; then
continue
fi
echo "usb|$VENDOR|$PRODUCT" >> "$DETECTED_DEVICES"
BUILTIN_INFO=$(lookup_builtin_device "$VENDOR" "$PRODUCT")
if [ -n "$BUILTIN_INFO" ]; then
DEVICE_NAME=$(echo "$BUILTIN_INFO" | cut -d':' -f3)
DEVICE_TYPE=$(echo "$BUILTIN_INFO" | cut -d':' -f4)
STATUS="not_installed"
else
MANUFACTURER=$(echo "$DEV_INFO" | grep "iManufacturer" | head -1 | sed -E 's/.*<([^>]+)>.*/\1/')
PRODUCT_NAME=$(echo "$DEV_INFO" | grep "iProduct" | head -1 | sed -E 's/.*<([^>]+)>.*/\1/')
if [ -n "$MANUFACTURER" ] && [ -n "$PRODUCT_NAME" ]; then
DEVICE_NAME="$MANUFACTURER $PRODUCT_NAME"
else
DEVICE_NAME="USB-устройство"
fi
STATUS="unknown"
fi
# Проверяем, существует ли запись
EXISTS=$(sqlite3 "$REGISTRY_FILE" "SELECT 1 FROM devices WHERE bus='usb' AND vendor='$VENDOR' AND device='$PRODUCT';" 2>/dev/null)
if [ -z "$EXISTS" ]; then
sqlite3 "$REGISTRY_FILE" <<EOF
INSERT INTO devices (bus, vendor, device, name, status, driver, detected_at)
VALUES ('usb', '$VENDOR', '$PRODUCT', '$DEVICE_NAME', '$STATUS', '', CURRENT_TIMESTAMP);
EOF
echo " USB: $VENDOR:$PRODUCT -> $DEVICE_NAME (статус: $STATUS) [НОВОЕ]"
else
sqlite3 "$REGISTRY_FILE" <<EOF
UPDATE devices SET name='$DEVICE_NAME', status='$STATUS', detected_at=CURRENT_TIMESTAMP
WHERE bus='usb' AND vendor='$VENDOR' AND device='$PRODUCT';
EOF
echo " USB: $VENDOR:$PRODUCT -> $DEVICE_NAME (статус: $STATUS) [ОБНОВЛЕНО]"
fi
done
# -------------------------------------------------------------------
# 3. Удаление отсутствующих устройств
# -------------------------------------------------------------------
echo "Проверка отсутствующих устройств..."
sqlite3 "$REGISTRY_FILE" "SELECT bus, vendor, device FROM devices;" 2>/dev/null | while IFS='|' read -r bus vendor device; do
if [ -z "$bus" ] || [ -z "$vendor" ] || [ -z "$device" ]; then
continue
fi
if ! grep -q "^${bus}|${vendor}|${device}$" "$DETECTED_DEVICES" 2>/dev/null; then
DEVICE_NAME=$(sqlite3 "$REGISTRY_FILE" "SELECT name FROM devices
WHERE bus='$bus' AND vendor='$vendor' AND device='$device';" 2>/dev/null)
echo " Удаление: $bus $vendor:$device ($DEVICE_NAME)"
log_to_registry "info" "Устройство удалено: $bus $vendor:$device"
sqlite3 "$REGISTRY_FILE" "DELETE FROM devices
WHERE bus='$bus' AND vendor='$vendor' AND device='$device';" 2>/dev/null
fi
done
rm -f "$DETECTED_DEVICES"
log_to_registry "info" "Проверка устройств завершена"
echo "Проверка устройств завершена."