Код рабочий, осталось фиксить взаимодействие с ClamAV
This commit is contained in:
@@ -1,7 +1,7 @@
|
|||||||
package ru.thiflict
|
package ru.thiflict
|
||||||
|
|
||||||
import kotlinx.coroutines.*
|
import kotlinx.coroutines.*
|
||||||
import ru.thiflict.DebugMode.isDebug
|
import ru.thiflict.DebugMode.DEBUG
|
||||||
import ru.thiflict.PinConfig.BUTTON
|
import ru.thiflict.PinConfig.BUTTON
|
||||||
import java.io.BufferedReader
|
import java.io.BufferedReader
|
||||||
import java.io.InputStreamReader
|
import java.io.InputStreamReader
|
||||||
@@ -26,6 +26,10 @@ class ButtonListener(
|
|||||||
clickListeners.add(listener)
|
clickListeners.add(listener)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fun removeClickListener(listener: ButtonClickListener) {
|
||||||
|
clickListeners.remove(listener)
|
||||||
|
}
|
||||||
|
|
||||||
private fun notifyClick() {
|
private fun notifyClick() {
|
||||||
val event = ButtonClickEvent()
|
val event = ButtonClickEvent()
|
||||||
clickListeners.forEach { it.invoke(event) }
|
clickListeners.forEach { it.invoke(event) }
|
||||||
@@ -51,25 +55,25 @@ class ButtonListener(
|
|||||||
var line: String?
|
var line: String?
|
||||||
|
|
||||||
while (reader.readLine().also { line = it } != null) {
|
while (reader.readLine().also { line = it } != null) {
|
||||||
println(if (isDebug) "$line" else "")
|
println(if (DEBUG) "$line" else "")
|
||||||
when {
|
when {
|
||||||
line?.contains("rising") == true -> {
|
line?.contains("rising") == true -> {
|
||||||
currentButtonState.set(true)
|
currentButtonState.set(true)
|
||||||
onStateChange?.invoke(true)
|
onStateChange?.invoke(true)
|
||||||
println(if (isDebug) "Кнопка нажата" else "")
|
println(if (DEBUG) "Кнопка нажата" else "")
|
||||||
// Генерируем событие клика при нажатии
|
// Генерируем событие клика при нажатии
|
||||||
notifyClick()
|
notifyClick()
|
||||||
}
|
}
|
||||||
line?.contains("falling") == true -> {
|
line?.contains("falling") == true -> {
|
||||||
currentButtonState.set(false)
|
currentButtonState.set(false)
|
||||||
onStateChange?.invoke(false)
|
onStateChange?.invoke(false)
|
||||||
println(if (isDebug) "Кнопка разжата" else "")
|
println(if (DEBUG) "Кнопка разжата" else "")
|
||||||
// Убрана проверка на разжатие для генерации события
|
// Убрана проверка на разжатие для генерации события
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
val exitCode = process!!.waitFor()
|
val exitCode = process!!.waitFor()
|
||||||
println(if (isDebug) "Процесс завершён ($exitCode)" else "")
|
println("Процесс завершён ($exitCode)")
|
||||||
isListening.set(false)
|
isListening.set(false)
|
||||||
}
|
}
|
||||||
} catch (e: Exception) {
|
} catch (e: Exception) {
|
||||||
@@ -78,4 +82,10 @@ class ButtonListener(
|
|||||||
}
|
}
|
||||||
return currentButtonState.get()
|
return currentButtonState.get()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fun stopListening() {
|
||||||
|
listenerJob?.cancel()
|
||||||
|
process?.destroy()
|
||||||
|
isListening.set(false)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
@@ -1,9 +1,16 @@
|
|||||||
package ru.thiflict
|
package ru.thiflict
|
||||||
|
|
||||||
import ru.thiflict.DebugMode.isDebug
|
import kotlinx.coroutines.delay
|
||||||
|
import ru.thiflict.PinConfig
|
||||||
|
import java.io.File
|
||||||
|
import kotlin.system.exitProcess
|
||||||
|
|
||||||
class GPIOController(private val pin: Int) {
|
class GPIOController(private val pin: Int) {
|
||||||
|
|
||||||
|
fun setDirection(direction: String) {
|
||||||
|
// Для libgpiod направление задаётся автоматически
|
||||||
|
}
|
||||||
|
|
||||||
fun setValue(value: Int) {
|
fun setValue(value: Int) {
|
||||||
try {
|
try {
|
||||||
// Пробуем разные варианты синтаксиса gpioset
|
// Пробуем разные варианты синтаксиса gpioset
|
||||||
@@ -20,7 +27,7 @@ class GPIOController(private val pin: Int) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
} catch (e: Exception) {
|
} catch (e: Exception) {
|
||||||
println(if (isDebug) "Ошибка установки GPIO $pin = $value: ${e.message}" else "")
|
println("Ошибка установки GPIO $pin = $value: ${e.message}")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -34,7 +41,7 @@ class GPIOController(private val pin: Int) {
|
|||||||
process.waitFor()
|
process.waitFor()
|
||||||
output.toIntOrNull() ?: 0
|
output.toIntOrNull() ?: 0
|
||||||
} catch (e: Exception) {
|
} catch (e: Exception) {
|
||||||
println(if (isDebug) "Ошибка чтения GPIO $pin: ${e.message}" else "")
|
println("Ошибка чтения GPIO $pin: ${e.message}")
|
||||||
0
|
0
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -44,4 +51,5 @@ class GPIOController(private val pin: Int) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -1,13 +1,9 @@
|
|||||||
package ru.thiflict
|
package ru.thiflict
|
||||||
|
|
||||||
import kotlinx.coroutines.*
|
import kotlinx.coroutines.*
|
||||||
import ru.thiflict.DebugMode.isDebug
|
import ru.thiflict.DebugMode.DEBUG
|
||||||
import java.io.BufferedReader
|
|
||||||
import java.io.File
|
import java.io.File
|
||||||
import java.io.InputStreamReader
|
|
||||||
import kotlin.system.exitProcess
|
import kotlin.system.exitProcess
|
||||||
import java.util.*
|
|
||||||
import java.util.concurrent.*
|
|
||||||
|
|
||||||
// Конфигурация GPIO (BCM номера)
|
// Конфигурация GPIO (BCM номера)
|
||||||
object PinConfig {
|
object PinConfig {
|
||||||
@@ -18,11 +14,7 @@ object PinConfig {
|
|||||||
}
|
}
|
||||||
|
|
||||||
object DebugMode {
|
object DebugMode {
|
||||||
var isDebug = false
|
const val DEBUG = true
|
||||||
|
|
||||||
fun enableDebugging() {
|
|
||||||
isDebug = true
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Состояния системы
|
// Состояния системы
|
||||||
@@ -40,11 +32,12 @@ class USBVirusScanner {
|
|||||||
private lateinit var greenLed: GPIOController
|
private lateinit var greenLed: GPIOController
|
||||||
private lateinit var yellowLed: GPIOController
|
private lateinit var yellowLed: GPIOController
|
||||||
private lateinit var redLed: GPIOController
|
private lateinit var redLed: GPIOController
|
||||||
|
private lateinit var buttonReader: ButtonListener
|
||||||
|
|
||||||
private val scope = CoroutineScope(Dispatchers.IO + SupervisorJob())
|
private val scope = CoroutineScope(Dispatchers.IO + SupervisorJob())
|
||||||
|
|
||||||
fun initialize() {
|
fun initialize() {
|
||||||
println(if (isDebug) "Инициализация..." else "")
|
println("Инициализация...")
|
||||||
|
|
||||||
try {
|
try {
|
||||||
// Проверяем доступность gpiod
|
// Проверяем доступность gpiod
|
||||||
@@ -61,18 +54,16 @@ class USBVirusScanner {
|
|||||||
|
|
||||||
// Запускаем индикацию состояния
|
// Запускаем индикацию состояния
|
||||||
startStateIndication()
|
startStateIndication()
|
||||||
|
currentState = SystemState.IDLE
|
||||||
|
Thread.sleep(500)
|
||||||
|
|
||||||
antivirusDatabaseUpdater()
|
println("Инициализация завершена.")
|
||||||
|
|
||||||
Thread.sleep(1000)
|
|
||||||
|
|
||||||
println(if (isDebug) "Инициализация завершена." else "")
|
|
||||||
|
|
||||||
currentState = SystemState.IDLE
|
currentState = SystemState.IDLE
|
||||||
|
|
||||||
} catch (e: Exception) {
|
} catch (e: Exception) {
|
||||||
currentState = SystemState.ERROR
|
currentState = SystemState.ERROR
|
||||||
println(if (isDebug) "❌ Ошибка инициализации: ${e.message}" else "")
|
println("❌ Ошибка инициализации: ${e.message}")
|
||||||
e.printStackTrace()
|
e.printStackTrace()
|
||||||
throw e
|
throw e
|
||||||
}
|
}
|
||||||
@@ -84,23 +75,23 @@ class USBVirusScanner {
|
|||||||
val exitCode = process.waitFor()
|
val exitCode = process.waitFor()
|
||||||
|
|
||||||
if (exitCode != 0) {
|
if (exitCode != 0) {
|
||||||
throw Exception(if (isDebug) "gpiodetect не найден" else "")
|
throw Exception("gpiodetect не найден")
|
||||||
}
|
}
|
||||||
|
|
||||||
val output = process.inputStream.bufferedReader().readText()
|
val output = process.inputStream.bufferedReader().readText()
|
||||||
println(if (isDebug) "✅ libgpiod найден" else "")
|
println("✅ libgpiod найден")
|
||||||
if (output.isNotBlank()) {
|
if (output.isNotBlank()) {
|
||||||
println(if (isDebug) "Доступные чипы: ${output.trim()}" else "")
|
println("Доступные чипы: ${output.trim()}")
|
||||||
}
|
}
|
||||||
|
|
||||||
} catch (e: Exception) {
|
} catch (e: Exception) {
|
||||||
throw Exception(if (isDebug) "libgpiod Не установлен!" else "")
|
throw Exception("libgpiod Не установлен!")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fun buttonPress(defaultButtonState: Boolean): Boolean {
|
fun buttonPress(defaultButtonState: Boolean): Boolean {
|
||||||
var finalButtonState = defaultButtonState
|
var finalButtonState = defaultButtonState
|
||||||
println(if (isDebug) "Начало finalButtonState: $finalButtonState" else "")
|
println(if (DEBUG) "Начало finalButtonState: $finalButtonState" else "")
|
||||||
|
|
||||||
val buttonListener = ButtonListener()
|
val buttonListener = ButtonListener()
|
||||||
val initialState = buttonListener.startListening { isPressed ->
|
val initialState = buttonListener.startListening { isPressed ->
|
||||||
@@ -108,7 +99,7 @@ class USBVirusScanner {
|
|||||||
finalButtonState = true
|
finalButtonState = true
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
println(if (isDebug) "finalButtonState: $finalButtonState" else "")
|
println(if (DEBUG) "finalButtonState: $finalButtonState" else "")
|
||||||
return finalButtonState
|
return finalButtonState
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -173,27 +164,27 @@ class USBVirusScanner {
|
|||||||
|
|
||||||
fun startScan() {
|
fun startScan() {
|
||||||
if (scanJob?.isActive == true) {
|
if (scanJob?.isActive == true) {
|
||||||
println(if (isDebug) "Сканирование уже выполняется" else "")
|
println("Сканирование уже выполняется")
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
scanJob = scope.launch {
|
scanJob = scope.launch {
|
||||||
currentState = SystemState.SCANNING
|
currentState = SystemState.SCANNING
|
||||||
println(if (isDebug) "=== Начало сканирования ===" else "")
|
println("=== Начало сканирования ===")
|
||||||
|
|
||||||
try {
|
try {
|
||||||
// Поиск USB-устройств
|
// Поиск USB-устройств
|
||||||
val usbDevices = findUSBDevices()
|
val usbDevices = findUSBDevices()
|
||||||
|
|
||||||
if (usbDevices.isEmpty()) {
|
if (usbDevices.isEmpty()) {
|
||||||
println(if (isDebug) "Устройства не найдены" else "")
|
println("Устройства не найдены")
|
||||||
currentState = SystemState.ERROR
|
currentState = SystemState.ERROR
|
||||||
delay(5000)
|
delay(5000)
|
||||||
currentState = SystemState.IDLE
|
currentState = SystemState.IDLE
|
||||||
return@launch
|
return@launch
|
||||||
}
|
}
|
||||||
|
|
||||||
println(if (isDebug) "📀 Найдены USB-устройства:" else "")
|
println("📀 Найдены USB-устройства:")
|
||||||
usbDevices.forEach { device ->
|
usbDevices.forEach { device ->
|
||||||
println(" - ${device.mountPoint}")
|
println(" - ${device.mountPoint}")
|
||||||
}
|
}
|
||||||
@@ -203,23 +194,23 @@ class USBVirusScanner {
|
|||||||
val scanResults = mutableListOf<ScanResult>()
|
val scanResults = mutableListOf<ScanResult>()
|
||||||
|
|
||||||
for (device in usbDevices) {
|
for (device in usbDevices) {
|
||||||
println(if (isDebug) "🔍 Сканирование: ${device.mountPoint}" else "")
|
println("🔍 Сканирование: ${device.mountPoint}")
|
||||||
val result = scanWithClamAV(device.mountPoint)
|
val result = scanWithClamAV(device.mountPoint)
|
||||||
scanResults.add(result)
|
scanResults.add(result)
|
||||||
|
|
||||||
if (result.isInfected) {
|
if (result.isInfected) {
|
||||||
hasVirus = true
|
hasVirus = true
|
||||||
println(if (isDebug) "⚠️ ВНИМАНИЕ! Найдены угрозы!" else "")
|
println("⚠️ ВНИМАНИЕ! Найдены угрозы!")
|
||||||
result.infectedFiles.take(10).forEach { file ->
|
result.infectedFiles.take(10).forEach { file ->
|
||||||
println(" 🦠 ${file.take(100)}")
|
println(" 🦠 ${file.take(100)}")
|
||||||
}
|
}
|
||||||
if (result.infectedFiles.size > 10) {
|
if (result.infectedFiles.size > 10) {
|
||||||
println(if (isDebug) " ... и ещё ${result.infectedFiles.size - 10} файлов" else "")
|
println(" ... и ещё ${result.infectedFiles.size - 10} файлов")
|
||||||
}
|
}
|
||||||
} else if (result.error != null) {
|
} else if (result.error != null) {
|
||||||
println(if (isDebug) "❌ Ошибка сканирования: ${result.error}" else "")
|
println("❌ Ошибка сканирования: ${result.error}")
|
||||||
} else {
|
} else {
|
||||||
println(if (isDebug) "✅ Сканирование завершено: угроз не найдено" else "")
|
println("✅ Сканирование завершено: угроз не найдено")
|
||||||
}
|
}
|
||||||
println()
|
println()
|
||||||
}
|
}
|
||||||
@@ -234,25 +225,25 @@ class USBVirusScanner {
|
|||||||
}
|
}
|
||||||
|
|
||||||
val message = if (hasVirus) {
|
val message = if (hasVirus) {
|
||||||
if (isDebug) "🦠 Найдены вирусы! Красный LED горит" else ""
|
"🦠 Найдены вирусы! Красный LED горит"
|
||||||
} else {
|
} else {
|
||||||
if (isDebug) "✅ Флешка чиста! Зелёный LED горит" else ""
|
"✅ Флешка чиста! Зелёный LED горит"
|
||||||
}
|
}
|
||||||
println(if (isDebug) message else "")
|
println(message)
|
||||||
|
|
||||||
// Держим состояние 5 секунд
|
// Держим состояние 5 секунд
|
||||||
delay(5000)
|
delay(5000)
|
||||||
currentState = SystemState.IDLE
|
currentState = SystemState.IDLE
|
||||||
|
|
||||||
} catch (e: Exception) {
|
} catch (e: Exception) {
|
||||||
println(if (isDebug) "❌ Критическая ошибка: ${e.message}" else "")
|
println("❌ Критическая ошибка: ${e.message}")
|
||||||
e.printStackTrace()
|
e.printStackTrace()
|
||||||
currentState = SystemState.ERROR
|
currentState = SystemState.ERROR
|
||||||
delay(5000)
|
delay(5000)
|
||||||
currentState = SystemState.IDLE
|
currentState = SystemState.IDLE
|
||||||
}
|
}
|
||||||
|
|
||||||
println(if (isDebug) "=== Сканирование завершено ===\n" else "")
|
println("=== Сканирование завершено ===\n")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -293,7 +284,7 @@ class USBVirusScanner {
|
|||||||
if (parts.size >= 2) {
|
if (parts.size >= 2) {
|
||||||
val mountPoint = parts[1]
|
val mountPoint = parts[1]
|
||||||
|
|
||||||
if ((mountPoint.startsWith("/media")) &&
|
if ((mountPoint.startsWith("/media") || mountPoint.startsWith("/mnt")) &&
|
||||||
File(mountPoint).exists() &&
|
File(mountPoint).exists() &&
|
||||||
devices.none { it.mountPoint == mountPoint }) {
|
devices.none { it.mountPoint == mountPoint }) {
|
||||||
|
|
||||||
@@ -304,7 +295,7 @@ class USBVirusScanner {
|
|||||||
}
|
}
|
||||||
|
|
||||||
} catch (e: Exception) {
|
} catch (e: Exception) {
|
||||||
println(if (isDebug) "Ошибка при поиске USB-устройств: ${e.message}" else "")
|
println("Ошибка при поиске USB-устройств: ${e.message}")
|
||||||
}
|
}
|
||||||
|
|
||||||
return devices.distinctBy { it.mountPoint }
|
return devices.distinctBy { it.mountPoint }
|
||||||
@@ -325,7 +316,7 @@ class USBVirusScanner {
|
|||||||
infectedFiles = emptyList(),
|
infectedFiles = emptyList(),
|
||||||
virusNames = emptyMap(),
|
virusNames = emptyMap(),
|
||||||
exitCode = -1,
|
exitCode = -1,
|
||||||
error = if (isDebug) "ClamAV не установлен. Установите: sudo apt install clamav" else ""
|
error = "ClamAV не установлен. Установите: sudo apt install clamav"
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -337,11 +328,11 @@ class USBVirusScanner {
|
|||||||
infectedFiles = emptyList(),
|
infectedFiles = emptyList(),
|
||||||
virusNames = emptyMap(),
|
virusNames = emptyMap(),
|
||||||
exitCode = -1,
|
exitCode = -1,
|
||||||
error = if (isDebug)"Путь не существует или не является директорией: $path" else ""
|
error = "Путь не существует или не является директорией: $path"
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
println(if (isDebug) " Запуск clamscan (это может занять некоторое время)..." else "")
|
println(" Запуск clamscan (это может занять некоторое время)...")
|
||||||
|
|
||||||
// Запускаем ClamAV
|
// Запускаем ClamAV
|
||||||
val processBuilder = ProcessBuilder(
|
val processBuilder = ProcessBuilder(
|
||||||
@@ -349,8 +340,8 @@ class USBVirusScanner {
|
|||||||
"-r",
|
"-r",
|
||||||
"--stdout",
|
"--stdout",
|
||||||
"--infected",
|
"--infected",
|
||||||
"--max-filesize=1M",
|
"--max-filesize=1G",
|
||||||
"--max-scansize=10M",
|
"--max-scansize=1G",
|
||||||
path
|
path
|
||||||
)
|
)
|
||||||
|
|
||||||
@@ -378,17 +369,17 @@ class USBVirusScanner {
|
|||||||
infectedFiles = infectedFiles,
|
infectedFiles = infectedFiles,
|
||||||
virusNames = virusNames,
|
virusNames = virusNames,
|
||||||
exitCode = exitCode,
|
exitCode = exitCode,
|
||||||
error = if (isDebug) (if (exitCode != 0 && exitCode != 1) "ClamAV вернул код ошибки: $exitCode" else "") else ""
|
error = if (exitCode != 0 && exitCode != 1) "ClamAV вернул код ошибки: $exitCode" else null
|
||||||
)
|
)
|
||||||
|
|
||||||
} catch (e: Exception) {
|
} catch (e: Exception) {
|
||||||
println(if (isDebug) " Ошибка при выполнении clamscan: ${e.message}" else "")
|
println(" Ошибка при выполнении clamscan: ${e.message}")
|
||||||
return ScanResult(
|
return ScanResult(
|
||||||
isInfected = false,
|
isInfected = false,
|
||||||
infectedFiles = emptyList(),
|
infectedFiles = emptyList(),
|
||||||
virusNames = emptyMap(),
|
virusNames = emptyMap(),
|
||||||
exitCode = -1,
|
exitCode = -1,
|
||||||
error = if (isDebug) e.message else ""
|
error = e.message
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -428,14 +419,14 @@ class USBVirusScanner {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
println(if (isDebug) "📝 Лог сохранён: ${logFile.absolutePath}" else "")
|
println("📝 Лог сохранён: ${logFile.absolutePath}")
|
||||||
} catch (e: Exception) {
|
} catch (e: Exception) {
|
||||||
println(if (isDebug) "Ошибка сохранения лога: ${e.message}" else "")
|
println("Ошибка сохранения лога: ${e.message}")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fun shutdown() {
|
fun shutdown() {
|
||||||
println(if (isDebug) "\nЗавершение работы..." else "")
|
println("\nЗавершение работы...")
|
||||||
isRunning = false
|
isRunning = false
|
||||||
|
|
||||||
indicationJob?.cancel()
|
indicationJob?.cancel()
|
||||||
@@ -454,7 +445,7 @@ class USBVirusScanner {
|
|||||||
// Игнорируем ошибки при закрытии
|
// Игнорируем ошибки при закрытии
|
||||||
}
|
}
|
||||||
|
|
||||||
println(if (isDebug) "✅ Система остановлена" else "")
|
println("✅ Система остановлена")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -471,63 +462,14 @@ data class ScanResult(
|
|||||||
val error: String? = null
|
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)
|
|
||||||
}
|
|
||||||
|
|
||||||
var initialDelay = targetTime.timeInMillis - now.timeInMillis
|
fun main() {
|
||||||
|
|
||||||
// Если время уже прошло сегодня, планируем на завтра
|
println(if (DebugMode.DEBUG) "Зелёный - ${PinConfig.GREEN_LED}" else "")
|
||||||
if (initialDelay <= 0) {
|
println(if (DebugMode.DEBUG) "Жёлтый - ${PinConfig.YELLOW_LED}" else "")
|
||||||
targetTime.add(Calendar.DAY_OF_MONTH, 1)
|
println(if (DebugMode.DEBUG) "Красный - ${PinConfig.RED_LED}" else "")
|
||||||
initialDelay = targetTime.timeInMillis - now.timeInMillis
|
println(if (DebugMode.DEBUG) "Кнопка - ${PinConfig.BUTTON}" else "")
|
||||||
}
|
|
||||||
|
|
||||||
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 defaultButtonState = false
|
||||||
val scanner = USBVirusScanner()
|
val scanner = USBVirusScanner()
|
||||||
@@ -545,23 +487,21 @@ fun main(args: Array<String>) {
|
|||||||
}
|
}
|
||||||
buttonListener.startListening()
|
buttonListener.startListening()
|
||||||
|
|
||||||
println(if (isDebug) """
|
println("═══════════════════════════════════════")
|
||||||
═══════════════════════════════════════
|
println(" USB Virus Scanner готов к работе")
|
||||||
USB Virus Scanner готов к работе
|
println("═══════════════════════════════════════")
|
||||||
═══════════════════════════════════════
|
println("📌 Вставьте флешку и нажмите кнопку")
|
||||||
📌 Вставьте флешку и нажмите кнопку
|
println("📌 Зелёный LED мигает - режим ожидания")
|
||||||
📌 Зелёный LED мигает - режим ожидания
|
println("📌 Жёлтый LED мигает - идёт проверка")
|
||||||
📌 Жёлтый LED мигает - идёт проверка
|
println("📌 Зелёный LED горит - флешка чиста")
|
||||||
📌 Зелёный LED горит - флешка чиста
|
println("📌 Красный LED горит - найдены вирусы")
|
||||||
📌 Красный LED горит - найдены вирусы
|
println("📌 Для выхода нажмите Ctrl+C\n")
|
||||||
📌 Для выхода нажмите Ctrl+C
|
|
||||||
""".trimIndent() else "")
|
|
||||||
|
|
||||||
while (true) {
|
while (true) {
|
||||||
Thread.sleep(1000)
|
Thread.sleep(1000)
|
||||||
}
|
}
|
||||||
} catch (e: Exception) {
|
} catch (e: Exception) {
|
||||||
println(if (isDebug) "❌ Критическая ошибка: ${e.message}" else "")
|
println("❌ Критическая ошибка: ${e.message}")
|
||||||
e.printStackTrace()
|
e.printStackTrace()
|
||||||
scanner.shutdown()
|
scanner.shutdown()
|
||||||
exitProcess(1)
|
exitProcess(1)
|
||||||
|
|||||||
Reference in New Issue
Block a user