Доделки кода

This commit is contained in:
2026-04-03 13:43:58 +05:00
committed by Thiflict
parent e83a4f15cf
commit e7b9521a8a
3 changed files with 124 additions and 90 deletions

View File

@@ -1,9 +1,13 @@
package ru.thiflict
import kotlinx.coroutines.*
import ru.thiflict.DebugMode.DEBUG
import ru.thiflict.DebugMode.isDebug
import java.io.BufferedReader
import java.io.File
import java.io.InputStreamReader
import kotlin.system.exitProcess
import java.util.*
import java.util.concurrent.*
// Конфигурация GPIO (BCM номера)
object PinConfig {
@@ -14,7 +18,11 @@ object PinConfig {
}
object DebugMode {
const val DEBUG = true
var isDebug = false
fun enableDebugging() {
isDebug = true
}
}
// Состояния системы
@@ -32,12 +40,11 @@ class USBVirusScanner {
private lateinit var greenLed: GPIOController
private lateinit var yellowLed: GPIOController
private lateinit var redLed: GPIOController
private lateinit var buttonReader: ButtonListener
private val scope = CoroutineScope(Dispatchers.IO + SupervisorJob())
fun initialize() {
println(if (DEBUG) "Инициализация..." else "")
println(if (isDebug) "Инициализация..." else "")
try {
// Проверяем доступность gpiod
@@ -54,16 +61,18 @@ class USBVirusScanner {
// Запускаем индикацию состояния
startStateIndication()
currentState = SystemState.IDLE
antivirusDatabaseUpdater()
Thread.sleep(1000)
println("Инициализация завершена.")
println(if (isDebug) "Инициализация завершена." else "")
currentState = SystemState.IDLE
} catch (e: Exception) {
currentState = SystemState.ERROR
println("❌ Ошибка инициализации: ${e.message}")
println(if (isDebug) "❌ Ошибка инициализации: ${e.message}" else "")
e.printStackTrace()
throw e
}
@@ -75,23 +84,23 @@ class USBVirusScanner {
val exitCode = process.waitFor()
if (exitCode != 0) {
throw Exception("gpiodetect не найден")
throw Exception(if (isDebug) "gpiodetect не найден" else "")
}
val output = process.inputStream.bufferedReader().readText()
println("✅ libgpiod найден")
println(if (isDebug) "✅ libgpiod найден" else "")
if (output.isNotBlank()) {
println("Доступные чипы: ${output.trim()}")
println(if (isDebug) "Доступные чипы: ${output.trim()}" else "")
}
} catch (e: Exception) {
throw Exception("libgpiod Не установлен!")
throw Exception(if (isDebug) "libgpiod Не установлен!" else "")
}
}
fun buttonPress(defaultButtonState: Boolean): Boolean {
var finalButtonState = defaultButtonState
println(if (DEBUG) "Начало finalButtonState: $finalButtonState" else "")
println(if (isDebug) "Начало finalButtonState: $finalButtonState" else "")
val buttonListener = ButtonListener()
val initialState = buttonListener.startListening { isPressed ->
@@ -99,7 +108,7 @@ class USBVirusScanner {
finalButtonState = true
}
}
println(if (DEBUG) "finalButtonState: $finalButtonState" else "")
println(if (isDebug) "finalButtonState: $finalButtonState" else "")
return finalButtonState
}
@@ -164,27 +173,27 @@ class USBVirusScanner {
fun startScan() {
if (scanJob?.isActive == true) {
println("Сканирование уже выполняется")
println(if (isDebug) "Сканирование уже выполняется" else "")
return
}
scanJob = scope.launch {
currentState = SystemState.SCANNING
println("=== Начало сканирования ===")
println(if (isDebug) "=== Начало сканирования ===" else "")
try {
// Поиск USB-устройств
val usbDevices = findUSBDevices()
if (usbDevices.isEmpty()) {
println("Устройства не найдены")
println(if (isDebug) "Устройства не найдены" else "")
currentState = SystemState.ERROR
delay(5000)
currentState = SystemState.IDLE
return@launch
}
println("📀 Найдены USB-устройства:")
println(if (isDebug) "📀 Найдены USB-устройства:" else "")
usbDevices.forEach { device ->
println(" - ${device.mountPoint}")
}
@@ -194,23 +203,23 @@ class USBVirusScanner {
val scanResults = mutableListOf<ScanResult>()
for (device in usbDevices) {
println("🔍 Сканирование: ${device.mountPoint}")
println(if (isDebug) "🔍 Сканирование: ${device.mountPoint}" else "")
val result = scanWithClamAV(device.mountPoint)
scanResults.add(result)
if (result.isInfected) {
hasVirus = true
println("⚠️ ВНИМАНИЕ! Найдены угрозы!")
println(if (isDebug) "⚠️ ВНИМАНИЕ! Найдены угрозы!" else "")
result.infectedFiles.take(10).forEach { file ->
println(" 🦠 ${file.take(100)}")
}
if (result.infectedFiles.size > 10) {
println(" ... и ещё ${result.infectedFiles.size - 10} файлов")
println(if (isDebug) " ... и ещё ${result.infectedFiles.size - 10} файлов" else "")
}
} else if (result.error != null) {
println("❌ Ошибка сканирования: ${result.error}")
println(if (isDebug) "❌ Ошибка сканирования: ${result.error}" else "")
} else {
println("✅ Сканирование завершено: угроз не найдено")
println(if (isDebug) "✅ Сканирование завершено: угроз не найдено" else "")
}
println()
}
@@ -225,25 +234,25 @@ class USBVirusScanner {
}
val message = if (hasVirus) {
"🦠 Найдены вирусы! Красный LED горит"
if (isDebug) "🦠 Найдены вирусы! Красный LED горит" else ""
} else {
"✅ Флешка чиста! Зелёный LED горит"
if (isDebug) "✅ Флешка чиста! Зелёный LED горит" else ""
}
println(message)
println(if (isDebug) message else "")
// Держим состояние 5 секунд
delay(5000)
currentState = SystemState.IDLE
} catch (e: Exception) {
println("❌ Критическая ошибка: ${e.message}")
println(if (isDebug) "❌ Критическая ошибка: ${e.message}" else "")
e.printStackTrace()
currentState = SystemState.ERROR
delay(5000)
currentState = SystemState.IDLE
}
println("=== Сканирование завершено ===\n")
println(if (isDebug) "=== Сканирование завершено ===\n" else "")
}
}
@@ -295,7 +304,7 @@ class USBVirusScanner {
}
} catch (e: Exception) {
println("Ошибка при поиске USB-устройств: ${e.message}")
println(if (isDebug) "Ошибка при поиске USB-устройств: ${e.message}" else "")
}
return devices.distinctBy { it.mountPoint }
@@ -316,7 +325,7 @@ class USBVirusScanner {
infectedFiles = emptyList(),
virusNames = emptyMap(),
exitCode = -1,
error = "ClamAV не установлен. Установите: sudo apt install clamav"
error = if (isDebug) "ClamAV не установлен. Установите: sudo apt install clamav" else ""
)
}
@@ -328,11 +337,11 @@ class USBVirusScanner {
infectedFiles = emptyList(),
virusNames = emptyMap(),
exitCode = -1,
error = "Путь не существует или не является директорией: $path"
error = if (isDebug)"Путь не существует или не является директорией: $path" else ""
)
}
println(" Запуск clamscan (это может занять некоторое время)...")
println(if (isDebug) " Запуск clamscan (это может занять некоторое время)..." else "")
// Запускаем ClamAV
val processBuilder = ProcessBuilder(
@@ -340,8 +349,8 @@ class USBVirusScanner {
"-r",
"--stdout",
"--infected",
"--max-filesize=70M",
"--max-scansize=150M",
"--max-filesize=1M",
"--max-scansize=10M",
path
)
@@ -364,30 +373,22 @@ class USBVirusScanner {
}
}
val syncProccessBuilder = ProcessBuilder("sync")
syncProccessBuilder.start()
process.waitFor()
val umountProcessBulder = ProcessBuilder("umount", "/dev/sda", "-f")
umountProcessBulder.start()
process.waitFor()
return ScanResult(
isInfected = infectedFiles.isNotEmpty(),
infectedFiles = infectedFiles,
virusNames = virusNames,
exitCode = exitCode,
error = if (exitCode != 0 && exitCode != 1) "ClamAV вернул код ошибки: $exitCode" else null
error = if (isDebug) (if (exitCode != 0 && exitCode != 1) "ClamAV вернул код ошибки: $exitCode" else "") else ""
)
} catch (e: Exception) {
println(" Ошибка при выполнении clamscan: ${e.message}")
println(if (isDebug) " Ошибка при выполнении clamscan: ${e.message}" else "")
return ScanResult(
isInfected = false,
infectedFiles = emptyList(),
virusNames = emptyMap(),
exitCode = -1,
error = e.message
error = if (isDebug) e.message else ""
)
}
}
@@ -427,14 +428,14 @@ class USBVirusScanner {
}
}
println("📝 Лог сохранён: ${logFile.absolutePath}")
println(if (isDebug) "📝 Лог сохранён: ${logFile.absolutePath}" else "")
} catch (e: Exception) {
println("Ошибка сохранения лога: ${e.message}")
println(if (isDebug) "Ошибка сохранения лога: ${e.message}" else "")
}
}
fun shutdown() {
println("\nЗавершение работы...")
println(if (isDebug) "\nЗавершение работы..." else "")
isRunning = false
indicationJob?.cancel()
@@ -453,7 +454,7 @@ class USBVirusScanner {
// Игнорируем ошибки при закрытии
}
println("✅ Система остановлена")
println(if (isDebug) "✅ Система остановлена" else "")
}
}
@@ -470,14 +471,63 @@ data class ScanResult(
val error: String? = null
)
fun scheduleUpdaterAt3AM() {
val scheduler = Executors.newSingleThreadScheduledExecutor()
val now = Calendar.getInstance()
val targetTime = Calendar.getInstance().apply {
set(Calendar.HOUR_OF_DAY, 3)
set(Calendar.MINUTE, 0)
set(Calendar.SECOND, 0)
set(Calendar.MILLISECOND, 0)
}
fun main() {
var initialDelay = targetTime.timeInMillis - now.timeInMillis
println(if (DebugMode.DEBUG) "Зелёный - ${PinConfig.GREEN_LED}" else "")
println(if (DebugMode.DEBUG) "Жёлтый - ${PinConfig.YELLOW_LED}" else "")
println(if (DebugMode.DEBUG) "Красный - ${PinConfig.RED_LED}" else "")
println(if (DebugMode.DEBUG) "Кнопка - ${PinConfig.BUTTON}" else "")
// Если время уже прошло сегодня, планируем на завтра
if (initialDelay <= 0) {
targetTime.add(Calendar.DAY_OF_MONTH, 1)
initialDelay = targetTime.timeInMillis - now.timeInMillis
}
scheduler.scheduleAtFixedRate(
{ antivirusDatabaseUpdater() },
initialDelay,
TimeUnit.DAYS.toMillis(1),
TimeUnit.MILLISECONDS
)
println("Планировщик запущен. Первый запуск через ${initialDelay / 1000 / 60} минут")
}
fun antivirusDatabaseUpdater() {
println(if (isDebug) "Обновление базы данных антивируса" else "")
val processBuilder = ProcessBuilder("freshclam", "-vvv")
processBuilder.redirectErrorStream(true)
val process = processBuilder.start()
val reader = BufferedReader(InputStreamReader(process.inputStream))
if (isDebug) {
reader.useLines { lines ->
lines.forEach { println("Process output: $it") }
}
}
process.waitFor()
}
fun main(args: Array<String>) {
if (args.contains("--debug")) {
DebugMode.enableDebugging()
}
scheduleUpdaterAt3AM()
println(if (isDebug) "Зелёный - ${PinConfig.GREEN_LED}" else "")
println(if (isDebug) "Жёлтый - ${PinConfig.YELLOW_LED}" else "")
println(if (isDebug) "Красный - ${PinConfig.RED_LED}" else "")
println(if (isDebug) "Кнопка - ${PinConfig.BUTTON}" else "")
val defaultButtonState = false
val scanner = USBVirusScanner()
@@ -495,21 +545,23 @@ fun main() {
}
buttonListener.startListening()
println("═══════════════════════════════════════")
println(" USB Virus Scanner готов к работе")
println("═══════════════════════════════════════")
println("📌 Вставьте флешку и нажмите кнопку")
println("📌 Зелёный LED мигает - режим ожидания")
println("📌 Жёлтый LED мигает - идёт проверка")
println("📌 Зелёный LED горит - флешка чиста")
println("📌 Красный LED горит - найдены вирусы")
println("📌 Для выхода нажмите Ctrl+C\n")
println(if (isDebug) """
═══════════════════════════════════════
USB Virus Scanner готов к работе
═══════════════════════════════════════
📌 Вставьте флешку и нажмите кнопку
📌 Зелёный LED мигает - режим ожидания
📌 Жёлтый LED мигает - идёт проверка
📌 Зелёный LED горит - флешка чиста
📌 Красный LED горит - найдены вирусы
📌 Для выхода нажмите Ctrl+C
""".trimIndent() else "")
while (true) {
Thread.sleep(1000)
}
} catch (e: Exception) {
println("❌ Критическая ошибка: ${e.message}")
println(if (isDebug) "❌ Критическая ошибка: ${e.message}" else "")
e.printStackTrace()
scanner.shutdown()
exitProcess(1)