in tools/src/main/kotlin/jetbrains/exodus/crypto/Scytale.kt [36:129]
fun main(args: Array<String>) {
if (args.size < 2) {
printUsage()
}
var sourcePath: String? = null
var targetPath: String? = null
var key: ByteArray? = null
var basicIV: Long? = null
var compress = false
var gzip = false
var overwrite = false
var type = "chacha"
for (arg in args) {
if (arg.startsWith('-') && arg.length < 3) {
when (arg.lowercase().substring(1)) {
"g" -> gzip = true
"z" -> compress = true
"o" -> overwrite = true
else -> {
printUsage()
}
}
} else {
if (sourcePath == null) {
sourcePath = arg
} else if (targetPath == null) {
targetPath = arg
} else if (key == null) {
key = toBinaryKey(arg)
} else if (basicIV == null) {
basicIV = parseIV(arg)
} else {
type = arg.lowercase()
break
}
}
}
if (sourcePath == null || targetPath == null || key == null || basicIV == null) {
printUsage()
}
val cipherId = when (type) {
"salsa" -> SALSA20_CIPHER_ID
"chacha" -> CHACHA_CIPHER_ID
else -> {
abort("Unknown cipher id: $type")
}
}
val source = File(sourcePath)
val target = File(targetPath)
if (!source.exists()) {
abort("File not found: ${source.absolutePath}")
}
if (target.exists()) {
val files = target.list()
files?.let {
if (files.isNotEmpty()) {
if (!overwrite) {
abort("File exists: ${target.absolutePath}")
}
if (!target.deleteRecursively()) {
abort("File cannot be fully deleted: ${target.absolutePath}")
}
}
} ?: target.let {
if (!overwrite) {
println("Invalid file: ${target.absolutePath}")
}
}
}
val enCrypted = if (source.isDirectory) {
BackupUtil.reEncryptBackup(FileTreeArchiveInputStream(source), key, basicIV, null, 0, newCipherProvider(cipherId))
} else {
val stream = ArchiveStreamFactory().createArchiveInputStream(BufferedInputStream(
if (gzip) {
GZIPInputStream(source.inputStream())
} else {
source.inputStream()
}
))
BackupUtil.reEncryptBackup(stream, key, basicIV, null, 0, newCipherProvider(cipherId))
}
if (compress) {
IOUtils.copy(enCrypted, target.outputStream())
} else {
Expander().expand(TarArchiveInputStream(GZIPInputStream(enCrypted)), target.toPath())
}
}