#!/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" < $DEVICE_NAME (статус: $STATUS) [НОВОЕ]" else # Обновляем только статус и driver, если они изменились и статус не calista if [ "$CURRENT_STATUS" != "installed_calista" ] && [ "$CURRENT_STATUS" != "installed_calista_error" ]; then sqlite3 "$REGISTRY_FILE" < $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" < $DEVICE_NAME (статус: $STATUS) [НОВОЕ]" else sqlite3 "$REGISTRY_FILE" < $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 "Проверка устройств завершена."