package xyz.maxwellj.mapm import fuel.Fuel import fuel.get import java.io.File import java.math.BigInteger import java.security.MessageDigest import kotlin.system.exitProcess import org.tukaani.xz.XZInputStream import java.io.* import org.apache.commons.compress.archivers.tar.TarArchiveInputStream import java.io.BufferedInputStream import java.io.FileInputStream import java.nio.file.Files import java.nio.file.Paths import kotlin.collections.listOf as listOf fun uncompressXZFile(inputFile: String, outputFile: String) { XZInputStream(FileInputStream(inputFile)).use { input -> FileOutputStream(outputFile).use { output -> input.copyTo(output) } } } fun unarchiveTarFile(tarFilePath: String, outputDirectoryPath: String) { val tarFile = File(tarFilePath) val outputDir = File(outputDirectoryPath) if (!outputDir.exists()) { outputDir.mkdirs() } TarArchiveInputStream(BufferedInputStream(FileInputStream(tarFile))).use { tarIn -> var entry = tarIn.nextTarEntry while (entry != null) { val outputFile = File(outputDir, entry.name) if (entry.isDirectory) { outputFile.mkdirs() } else { outputFile.parentFile.mkdirs() Files.copy(tarIn, Paths.get(outputFile.absolutePath)) } entry = tarIn.nextTarEntry } } } // hurrah for https://stackoverflow.com/questions/64171624/how-to-generate-an-md5-hash-in-kotlin! fun md5(input:String): String { val md = MessageDigest.getInstance("MD5") return BigInteger(1, md.digest(input.toByteArray())).toString(16).padStart(32, '0') } suspend fun main(args: Array) { var userInput: String = args[0] println(userInput) if (userInput == "g") { val userInput: String = args[1] val linkToUse = "https://git.maxwellj.xyz/mapm/stable/raw/branch/main/$userInput" val dingus = Fuel.get(linkToUse).body.string() println("Package $userInput found at $dingus") // val packageList = listOf($userInput) println("Downloading package $userInput") println("Is this okay?") val userInputInteractive: String = readln() if (userInputInteractive != "y") { println("Confirmation not given. Exiting...") exitProcess(0) } val file = File("/usr/mapm/tmp/$userInput.tar.xz") val fileBytes = Fuel.get(dingus).body.bytes() file.writeBytes(fileBytes) val fileChecksum = Fuel.get("https://git.maxwellj.xyz/mapm/stable/raw/branch/main/$userInput.hash").body.string() if (fileChecksum == md5(file.readText())) { println("Checksum matches!") uncompressXZFile(inputFile = "/usr/mapm/tmp/${userInput}.tar.xz", outputFile = "/usr/mapm/tmp/${userInput}.tar") unarchiveTarFile(tarFilePath = "/usr/mapm/tmp/${userInput}.tar", outputDirectoryPath = "/usr/mapm/") Runtime.getRuntime().exec("chmod +x /usr/mapm/${userInput}") println("Finished!") exitProcess(0) } else { println("Checksum doesn't match! Aborting...") println("Please tell Max or your app's developer to use mapm to generate a new checksum. If the checksum is right, check your internet connection security.") exitProcess(1) } } else if (userInput == "r") { val executable = File("/usr/mapm/${args[1]}") println("Deleting package ${args[1]}") println("Is this okay? (y/n)") var userInput = readln() if (userInput != "y") { executable.delete() } } else if (userInput == "c") { val userInput = args[1] val file = File(userInput) println("Checksum of that file is ${md5(file.readText())}") } else { println("mapm - Max's Package Manager") println("Version 0.0.2") println("(C) Maxwell Jeffress 2024, licensed under the GNU GPL V3") println("") println("---Help---") println("Arguments that can be run") println("g Grab a package from the internet") println("r Remove a package") println("c Generate a checksum for a package") println("") println("More info at the following links:") println("https://maxwellj.xyz/mapm") println("https://git.maxwellj.xyz/max/mapm") } }