dev
cfig 3 weeks ago
parent 43078016d4
commit 1ba97938ff

@ -525,23 +525,46 @@ class Common {
}
}
fun createWorkspaceIni(fileName: String) {
//create workspace file
val workspaceFile = File(Helper.prop("workDir"), "workspace.ini").canonicalPath
fun createWorkspaceIni(fileName: String, iniFileName: String = "workspace.ini", prefix: String? = null) {
log.trace("create workspace file")
val workDir = Helper.prop("workDir")
val workspaceFile = File(workDir, iniFileName)
try {
FileOutputStream(workspaceFile).use { output ->
Properties().also {
it.setProperty("file", fileName)
it.setProperty("workDir", Helper.prop("workDir"))
it.setProperty("role", File(fileName).name)
it.store(output, "unpackInternal configuration")
if (prefix.isNullOrBlank()) {
// override existing file entirely when prefix is null or empty
val props = Properties().apply {
setProperty("file", fileName)
setProperty("workDir", workDir)
setProperty("role", File(fileName).name)
}
FileOutputStream(workspaceFile).use { out ->
props.store(out, "unpackInternal configuration (overridden)")
}
log.info("workspace file created: $workspaceFile")
log.info("workspace file overridden: ${workspaceFile.canonicalPath}")
} else {
// merge into existing (or create new) with prefixed keys
val props = Properties().apply {
if (workspaceFile.exists()) {
FileInputStream(workspaceFile).use { load(it) }
}
}
fun key(name: String) = "${prefix.trim()}.$name"
props.setProperty(key("file"), fileName)
props.setProperty(key("workDir"), workDir)
props.setProperty(key("role"), File(fileName).name)
FileOutputStream(workspaceFile).use { out ->
props.store(out, "unpackInternal configuration (with prefix='$prefix')")
}
log.info("workspace file created/updated with prefix '$prefix': ${workspaceFile.canonicalPath}")
}
} catch (e: IOException) {
log.error("error writing workspace file: ${e.message}")
}
//create workspace file done
log.trace("create workspace file done")
}
}
}

@ -300,8 +300,8 @@ data class BootV2(
"verify fail"
}
Avb.getJsonFileName(info.output).let { jsonFile ->
it.addRow("AVB info [$verifyStatus]", jsonFile)
prints.add(Pair("AVB info [$verifyStatus]", jsonFile))
it.addRow("AVB info [$verifyStatus]", shortenPath(jsonFile))
prints.add(Pair("AVB info [$verifyStatus]", shortenPath(jsonFile)))
if (File(jsonFile).exists()) {
mapper.readValue(File(jsonFile), AVBInfo::class.java).let { ai ->
val inspectRet = Avb.inspectKey(ai)
@ -362,11 +362,11 @@ data class BootV2(
if (theDtb.size > 0) {
val dtbCount = this.dtb!!.dtbList.size
it.addRule()
it.addRow("dtb", theDtb.file)
prints.add(Pair("dtb", theDtb.file.toString()))
it.addRow("dtb", theDtb.file?.let { fullPath -> shortenPath(fullPath) })
prints.add(Pair("dtb", shortenPath(theDtb.file.toString())))
if (File(theDtb.file + ".0.${dtsSuffix}").exists()) {
it.addRow("\\-- decompiled dts [$dtbCount]", theDtb.file + ".*.${dtsSuffix}")
prints.add(Pair("\\-- decompiled dts [$dtbCount]", theDtb.file + ".*.${dtsSuffix}"))
it.addRow("\\-- decompiled dts [$dtbCount]", shortenPath(theDtb.file + ".*.${dtsSuffix}"))
prints.add(Pair("\\-- decompiled dts [$dtbCount]", shortenPath(theDtb.file + ".*.${dtsSuffix}")))
}
}
}
@ -377,8 +377,8 @@ data class BootV2(
val tabVBMeta = AsciiTable().let {
if (File("vbmeta.img").exists()) {
it.addRule()
it.addRow("vbmeta.img", Avb.getJsonFileName("vbmeta.img"))
prints.add(Pair("vbmeta.img", Avb.getJsonFileName("vbmeta.img")))
it.addRow("vbmeta.img", shortenPath(Avb.getJsonFileName("vbmeta.img")))
prints.add(Pair("vbmeta.img", shortenPath(Avb.getJsonFileName("vbmeta.img"))))
it.addRule()
"\n" + it.render()
} else {

@ -341,7 +341,9 @@ data class VendorBoot(
}
fun postCopy(outFile: String): VendorBoot {
val signedFile = Helper.joinPath(Helper.prop("intermediateDir")!!, this.info.role + ".signed")
val dir = Helper.prop("intermediateDir")!!
val signedFile = Helper.joinPath(dir, "${info.role}.signed").takeIf { File(it).exists() }
?: Helper.joinPath(dir, "${info.role}.clear")
log.info("COPY $signedFile -> $outFile")
File(signedFile).copyTo(File(outFile), overwrite = true)
return this

@ -1,6 +1,7 @@
package packable
import cfig.bootimg.Common
import cfig.bootimg.v3.VendorBoot
import cfig.helper.Helper
import cfig.helper.Helper.Companion.check_call
import cfig.helper.Helper.Companion.check_output
@ -15,13 +16,24 @@ class DeviceTreeParser : IPackable {
override fun capabilities(): List<String> {
return listOf("^.*\\.dtb$")
}
override val loopNo: Int
get() = 1
override fun unpack(fileName: String) {
super.clear()
log.info("unpacking $fileName")
val outFile = workDir + fileName.removeSuffix(".dtb") + "." + Helper.prop("config.dts_suffix")
unpackInternal(fileName, Helper.prop("workDir")!!)
}
fun unpackInternal(fileName: String, unpackDir: String) {
//set workdir
log.info("unpackInternal(fileName: $fileName, unpackDir: $unpackDir)")
Helper.setProp("workDir", unpackDir)
clear()
//create workspace file
Common.createWorkspaceIni(fileName)
//create workspace file done
val outFile = File(workDir, File(fileName).nameWithoutExtension + "." + Helper.prop("config.dts_suffix")).path
DTC().decompile(fileName, outFile)
//print summary
@ -32,15 +44,26 @@ class DeviceTreeParser : IPackable {
}
override fun pack(fileName: String) {
log.info("packing $fileName")
val outFile = workDir + fileName.removeSuffix(".dtb") + "." + Helper.prop("config.dts_suffix")
check(DTC().compile(outFile, "$fileName.new")) { "fail to compile dts" }
packInternal(Helper.prop("workDir")!!, fileName)
}
fun packInternal(workspace: String, outFileName: String) {
log.info("packInternal($workspace, $outFileName)")
Helper.setProp("workDir", workspace)
//workspace+cfg
val iniRole = Common.loadProperties(File(workspace, "workspace.ini").canonicalPath).getProperty("role")
val dtsSrc = File(workDir, File(iniRole).nameWithoutExtension + "." + Helper.prop("config.dts_suffix")).path
val origFile = File(workDir, File(outFileName).name + ".orig").path
log.info("COPY $outFileName -> $origFile")
File(outFileName).copyTo(File(origFile), overwrite = true)
check(DTC().compile(dtsSrc, outFileName)) { "fail to compile dts" }
//print summary
val prints: MutableList<Pair<String, String>> = mutableListOf()
prints.add(Pair("DTS", outFile))
prints.add(Pair("updated DTB", "$fileName.new"))
log.info("\n\t\t\tPack Summary of {}\n{}\n", fileName, Common.table2String(prints))
prints.add(Pair("DTS", dtsSrc))
prints.add(Pair("updated DTB", outFileName))
log.info("\n\t\t\tPack Summary of {}\n{}\n", outFileName, Common.table2String(prints))
}
fun pull(fileName: String) {

@ -53,8 +53,9 @@ class VBMetaParser : IPackable {
it.mkdirs()
}
}
//workspace.ini
log.info("workspace set to $unpackDir")
Common.createWorkspaceIni(fileName)
Common.createWorkspaceIni(fileName, prefix = "vbmeta")
val ai = AVBInfo.parseFrom(Dumpling(fileName)).dumpDefault(fileName)
log.info("Signing Key: " + Avb.inspectKey(ai))
@ -66,9 +67,9 @@ class VBMetaParser : IPackable {
// called via reflection
fun packInternal(workspace: String, outFileName: String) {
log.info("packInternal(workspace: $workspace)")
log.info("packInternal(workspace: $workspace, $outFileName)")
Helper.setProp("workDir", workspace)
val iniRole = Common.loadProperties(File(workspace, "workspace.ini").canonicalPath).getProperty("role")
val iniRole = Common.loadProperties(File(workspace, "workspace.ini").canonicalPath).getProperty("vbmeta.role")
val blob = ObjectMapper().readValue(File(Avb.getJsonFileName(iniRole)), AVBInfo::class.java).encodePadded()
log.info("Writing padded vbmeta to file: $outFileName.signed")
Files.write(Paths.get("$outFileName.signed"), blob, StandardOpenOption.CREATE)

@ -36,6 +36,7 @@ class VendorBootParser : IPackable {
}
fun unpackInternal(fileName: String, unpackDir: String) {
//set workdir
log.info("unpackInternal(fileName: $fileName, unpackDir: $unpackDir)")
Helper.setProp("workDir", unpackDir)
clear()

@ -147,29 +147,32 @@ data class SparseImage(var info: SparseInfo = SparseInfo()) {
val ret = SparseImage()
ret.info.json = File(fileName).name.removeSuffix(".img") + ".json"
ret.info.output = fileName
ret.info.pulp = workDir + fileName
ret.info.pulp = File(Helper.prop("workDir")!!, File(fileName).nameWithoutExtension).path
log.info(ObjectMapper().writerWithDefaultPrettyPrinter().writeValueAsString(ret.info))
if (isSparse(fileName)) {
val tempFile = UUID.randomUUID().toString()
ret.info.outerFsType = "sparse"
val rawFile = "${workDir}${File(fileName).nameWithoutExtension}"
simg2img(fileName, tempFile)
ret.info.pulp = if (isExt4(tempFile)) {
ret.info.innerFsType = "ext4"
"$rawFile.ext4"
ret.info.pulp + ".ext4"
} else if (isErofs(tempFile)) {
ret.info.innerFsType = "erofs"
"$rawFile.erofs"
ret.info.pulp + ".erofs"
} else {
"$rawFile.raw"
ret.info.pulp + ".raw"
}
Files.move(Path(tempFile), Path(ret.info.pulp))
} else if (isExt4(fileName)) {
ret.info.outerFsType = "ext4"
ret.info.innerFsType = "ext4"
ret.info.pulp = ret.info.pulp + ".ext4"
log.info("COPY $fileName -> ${ret.info.pulp}")
File(fileName).copyTo(File(ret.info.pulp))
} else if (isErofs(fileName)) {
ret.info.outerFsType = "erofs"
ret.info.innerFsType = "erofs"
ret.info.pulp = ret.info.pulp + ".erofs"
File(fileName).copyTo(File(ret.info.pulp))
}
when (ret.info.innerFsType) {

@ -15,6 +15,7 @@
package rom.sparse
import avb.blob.Footer
import cfig.bootimg.Common
import cfig.helper.Helper
import cfig.packable.IPackable
import cfig.packable.VBMetaParser
@ -38,12 +39,24 @@ class SparseImgParser : IPackable {
}
override fun unpack(fileName: String) {
log.info("unpack(fileName: $fileName)")
unpackInternal(fileName, Helper.prop("workDir")!!)
}
fun unpackInternal(fileName: String, unpackDir: String) {
//set workdir
log.info("unpackInternal(fileName: $fileName, unpackDir: $unpackDir)")
Helper.setProp("workDir", unpackDir)
clear()
//create workspace file
Common.createWorkspaceIni(fileName)
//create workspace file done
SparseImage
.parse(fileName)
.printSummary(fileName)
}
override fun pack(fileName: String) {
//TODO("not implemented: refer to https://github.com/cfig/Android_boot_image_editor/issues/133")
val cfgFile = outDir + fileName.removeSuffix(".img") + ".json"
@ -54,6 +67,24 @@ class SparseImgParser : IPackable {
.unwrap()
}
fun packInternal(workspace: String, outFileName: String) {
log.info("packInternal($workspace, $outFileName)")
Helper.setProp("workDir", workspace)
//intermediate
Helper.joinPath(workspace, "intermediate").also { intermediateDir ->
File(intermediateDir).let {
if (!it.exists()) {
it.mkdir()
}
}
Helper.setProp("intermediateDir", intermediateDir)
}
//workspace+cfg
val iniRole = Common.loadProperties(File(workspace, "workspace.ini").canonicalPath).getProperty("role")
val cfgFile = File(workspace, iniRole.removeSuffix(".img") + ".json").canonicalPath
log.info("Loading config from $cfgFile")
}
// invoked solely by reflection
fun `@footer`(fileName: String) {
FileInputStream(fileName).use { fis ->

Loading…
Cancel
Save