From 2734c06fb1e4acce43ca4a345bcf4e6be4265a5f Mon Sep 17 00:00:00 2001 From: thiflict <121az348@gmail.com> Date: Wed, 15 Apr 2026 15:34:20 +0500 Subject: [PATCH] =?UTF-8?q?#1:=20=D0=A7=D1=83=D1=82=D1=8C-=D1=87=D1=83?= =?UTF-8?q?=D1=82=D1=8C=20=D0=BF=D0=BE=D0=B4=D0=B5=D0=BB=D0=B0=D0=BB=20sam?= =?UTF-8?q?ba.=20=D0=9E=D1=81=D1=82=D0=B0=D0=BB=D0=BE=D1=81=D1=8C=20=D1=81?= =?UTF-8?q?=D0=BE=D0=B2=D1=81=D0=B5=D0=BC=20=D0=BD=D0=B5=D0=BC=D0=BD=D0=BE?= =?UTF-8?q?=D0=B3=D0=BE=20=D0=B4=D0=BE=D0=BF=D0=B8=D0=BB=D0=B8=D1=82=D1=8C?= =?UTF-8?q?.?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/main/kotlin/Main.kt | 114 +++++++++++++++++++++++++++++++++------- 1 file changed, 96 insertions(+), 18 deletions(-) diff --git a/src/main/kotlin/Main.kt b/src/main/kotlin/Main.kt index 9efccab..a38f3bd 100644 --- a/src/main/kotlin/Main.kt +++ b/src/main/kotlin/Main.kt @@ -8,6 +8,7 @@ import java.io.InputStreamReader import kotlin.system.exitProcess import java.util.* import java.util.concurrent.* +import kotlin.time.Duration.Companion.milliseconds // Конфигурация GPIO (BCM номера) object PinConfig { @@ -27,10 +28,10 @@ object DebugMode { // Состояния системы enum class SystemState { - IDLE, SCANNING, CLEAN, INFECTED, ERROR, INIT + IDLE, SCANNING, CLEAN, INFECTED, ERROR, INIT, SAMBA } -class USBVirusScanner { +class USBVirusScanner { private var currentState = SystemState.INIT private var scanJob: Job? = null @@ -120,45 +121,56 @@ class USBVirusScanner { greenLed.setValue(1) yellowLed.setValue(1) redLed.setValue(1) - delay(200) + delay(200.milliseconds) greenLed.setValue(0) yellowLed.setValue(0) redLed.setValue(0) - delay(200) + delay(200.milliseconds) } + SystemState.IDLE -> { // Зелёный медленно мигает blinkLed(greenLed, 1000) yellowLed.setValue(0) redLed.setValue(0) } + SystemState.SCANNING -> { // Жёлтый быстро мигает greenLed.setValue(0) blinkLed(yellowLed, 150) redLed.setValue(0) } + SystemState.CLEAN -> { // Зелёный горит greenLed.setValue(1) yellowLed.setValue(0) redLed.setValue(0) - delay(100) + delay(100.milliseconds) } + SystemState.INFECTED -> { // Красный горит greenLed.setValue(0) yellowLed.setValue(0) redLed.setValue(1) - delay(100) + delay(100.milliseconds) } + SystemState.ERROR -> { // Красный мигает greenLed.setValue(0) yellowLed.setValue(0) blinkLed(redLed, 500) } + + SystemState.SAMBA -> { + blinkLed(greenLed, 1000) + blinkLed(yellowLed, 1000) + redLed.setValue(0) + } } } } @@ -166,9 +178,9 @@ class USBVirusScanner { private suspend fun blinkLed(led: GPIOController, intervalMs: Long) { led.setValue(1) - delay(intervalMs / 2) + delay((intervalMs / 2).milliseconds) led.setValue(0) - delay(intervalMs / 2) + delay((intervalMs / 2).milliseconds) } fun startScan() { @@ -188,7 +200,7 @@ class USBVirusScanner { if (usbDevices.isEmpty()) { println(if (isDebug) "Устройства не найдены" else "") currentState = SystemState.ERROR - delay(5000) + delay(5000.milliseconds) currentState = SystemState.IDLE return@launch } @@ -241,14 +253,22 @@ class USBVirusScanner { println(if (isDebug) message else "") // Держим состояние 5 секунд - delay(5000) + delay(10000.milliseconds) + + if (!hasVirus) { + currentState = SystemState.SAMBA + sambaStartSharing() + + while (isUsbSharing()) {} + } + currentState = SystemState.IDLE } catch (e: Exception) { println(if (isDebug) "❌ Критическая ошибка: ${e.message}" else "") e.printStackTrace() currentState = SystemState.ERROR - delay(5000) + delay(10000.milliseconds) currentState = SystemState.IDLE } @@ -295,7 +315,8 @@ class USBVirusScanner { if ((mountPoint.startsWith("/media")) && File(mountPoint).exists() && - devices.none { it.mountPoint == mountPoint }) { + devices.none { it.mountPoint == mountPoint } + ) { devices.add(USBDevice("auto", mountPoint)) } @@ -337,7 +358,7 @@ class USBVirusScanner { infectedFiles = emptyList(), virusNames = emptyMap(), exitCode = -1, - error = if (isDebug)"Путь не существует или не является директорией: $path" else "" + error = if (isDebug) "Путь не существует или не является директорией: $path" else "" ) } @@ -380,7 +401,7 @@ class USBVirusScanner { ) } catch (e: Exception) { - println(if (isDebug) " Ошибка при выполнении clamscan: ${e.message}" else "") + println(if (isDebug) "Ошибка при выполнении clamscan: ${e.message}" else "") return ScanResult( isInfected = false, infectedFiles = emptyList(), @@ -432,6 +453,62 @@ class USBVirusScanner { } } + fun isUsbSharing(isActive: Boolean): Boolean { + var defaultState: Boolean = false + defaultState = isActive + return defaultState + } + + suspend fun sambaStartSharing() { + try { + currentState = SystemState.SAMBA + + var process: Process? = null + val sambaStartServiceCmd = listOf("systemctl", "start", "smbd") + val processBuilder = ProcessBuilder(sambaStartServiceCmd) + .redirectErrorStream(true) + + process = withContext(Dispatchers.IO) { + processBuilder.start() + } + } catch (e: Exception) { + e.printStackTrace() + currentState = SystemState.ERROR + delay(10000.milliseconds) + } + } + + fun sambaShutdown() { + unmount() + try { + var process: Process? = null + val sambaStopServiceCmd = listOf("systemctl", "stop", "smbd") + val processBuilder = ProcessBuilder(sambaStopServiceCmd) + .redirectErrorStream(true) + process = processBuilder.start() + currentState = SystemState.IDLE + } catch (e: Exception) {} + } + + + fun unmount() { + for (i in 0..9) { + val path = if (i == 0) "/media/usb" else "/media/usb$i" + try { + val processBuilder = ProcessBuilder("umount", "-f", path) + .redirectErrorStream(true) + val process = processBuilder.start() + val exitCode = process.waitFor() + if (exitCode == 0) { + println(if (isDebug) "Успешно размонтировано: $path" else "") + } + } catch (e: Exception) { + println(if (isDebug) "Ошибка при размонтировании $path: ${e.message}" else "") + } + } + + } + fun shutdown() { println(if (isDebug) "\nЗавершение работы..." else "") isRunning = false @@ -527,7 +604,6 @@ fun main(args: Array) { println(if (isDebug) "Красный - ${PinConfig.RED_LED}" else "") println(if (isDebug) "Кнопка - ${PinConfig.BUTTON}" else "") - val defaultButtonState = false val scanner = USBVirusScanner() Runtime.getRuntime().addShutdownHook(Thread { @@ -544,12 +620,13 @@ fun main(args: Array) { } buttonListener.addLongPressListener { event -> - println("TODO: Сделать отключение samba и отмонтирование накопителя.") + scanner.sambaShutdown() } buttonListener.startListening() - println(if (isDebug) """ + println( + if (isDebug) """ ═══════════════════════════════════════ USB Virus Scanner готов к работе ═══════════════════════════════════════ @@ -559,7 +636,8 @@ fun main(args: Array) { 📌 Зелёный LED горит - флешка чиста 📌 Красный LED горит - найдены вирусы 📌 Для выхода нажмите Ctrl+C - """.trimIndent() else "") + """.trimIndent() else "" + ) while (true) { Thread.sleep(1000)