Skip to content

Commit

Permalink
extract: Add extract.erofs
Browse files Browse the repository at this point in the history
usage: [options]
  -h, --help          Display this help and exit
  -i, --image=[FILE]  Image file
  -p                  Print all entrys
  --print=X           Print the target of path X
  -x                  Extract all items
  --extract=X         Extract the target of path X
  -f, --overwrite     [default: skip] overwrite files that already exist
  -T#                 [1-X] Use # threads, -T0: X/2
  --only-cfg          Only extract fs_config and file_contexts
  -o, --outdir=X      Output dir
  -V, --version       Print the version info

Signed-off-by: sekaiacg <[email protected]>
  • Loading branch information
sekaiacg committed Feb 24, 2023
1 parent e75559a commit d57ff5d
Show file tree
Hide file tree
Showing 15 changed files with 1,911 additions and 2 deletions.
34 changes: 34 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
**extract.erofs**
===========
**使用[erofs-utils](https://github.com/hsiangkao/erofs-utils)实现的提取erofs镜像的工具**
**提取包含:**
- fs_config
- files_context

**A tool for extracting erofs images implemented using [erofs-utils](https://github.com/hsiangkao/erofs-utils)**
**Extract contains:**
- fs_config
- files_context

**fs_config:**`vendor/bin/cnd 1000 1000 0755 capabilities=0x1000001400`

**files_context:** `/vendor/bin/hw/android\.hardware\.bluetooth@1\.0-service-qti u:object_r:hal_bluetooth_default_exec:s0`

```
usage: [options]
-h, --help Display this help and exit
-i, --image=[FILE] Image file
-p Print all entrys
--print=X Print the target of path X
-x Extract all items
--extract=X Extract the target of path X
-f, --overwrite [default: skip] overwrite files that already exist
-T# [1-24] Use # threads, -T0: 12
--only-cfg Only extract fs_config and file_contexts
-o, --outdir=X Output dir
-V, --version Print the version info
```

**Contributors**
- 感谢[lateautumn233](https://github.com/lateautumn233)提供的[erofs-utils](https://github.com/lateautumn233/erofs-utils)编译方法
- Thanks to [lateautumn233](https://github.com/lateautumn233) for the [erofs-utils](https://github.com/lateautumn233/erofs-utils) compilation method.
5 changes: 3 additions & 2 deletions build.sh
Original file line number Diff line number Diff line change
Expand Up @@ -60,17 +60,18 @@ build()
local FSCK_BIN="$BUILD/fsck.erofs"
local FUSE_BIN="$BUILD/fuse.erofs"
local MKFS_BIN="$BUILD/mkfs.erofs"
local EXTRACT_BIN="$BUILD/extract.erofs"
local TARGE_DIR_NAME="erofs-utils-${EROFS_VERSION}-${TARGET}_${ABI}-$(TZ=UTC-8 date +%y%m%d%H%M)"
local TARGET_DIR_PATH="./target/${TARGET}_${ABI}/${TARGE_DIR_NAME}"

if [ -f "$DUMP_BIN" -a -f "$FSCK_BIN" -a -f "$FUSE_BIN" -a -f "$MKFS_BIN" ]; then
if [ -f "$DUMP_BIN" -a -f "$FSCK_BIN" -a -f "$FUSE_BIN" -a -f "$MKFS_BIN" -a -f "$EXTRACT_BIN" ]; then
echo "复制文件中..."
[[ ! -d "$TARGET_DIR_PATH" ]] && mkdir -p ${TARGET_DIR_PATH}
cp -af $BUILD/*.erofs ${TARGET_DIR_PATH}
echo "编译成功: ${TARGE_DIR_NAME}"
else
echo "error"
exit -1
exit 1
fi
}

Expand Down
1 change: 1 addition & 0 deletions build/cmake/erofs-tools/CMakeLists.txt
Original file line number Diff line number Diff line change
@@ -1 +1,2 @@
include(erofs_tools.cmake)
include(extract.cmake)
12 changes: 12 additions & 0 deletions build/cmake/erofs-tools/extract.cmake
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
###############################------extract.erofs------###############################
set(TARGET_extract extract.erofs)
set(TARGET_SRC_DIR "${PROJECT_ROOT_DIR}/extract")
file(GLOB extract_srcs "${TARGET_SRC_DIR}/*.cpp")
add_executable(${TARGET_extract} ${extract_srcs})
target_include_directories(${TARGET_extract} PRIVATE
"${TARGET_SRC_DIR}/include"
${common_headers}
${liblog_headers}
)
target_link_libraries(${TARGET_extract} ${common_static_link_lib})
target_compile_options(${TARGET_extract} PRIVATE ${common_compile_flags})
148 changes: 148 additions & 0 deletions extract/ErofsNode.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,148 @@
#include "ErofsNode.h"
#include "ExtractHelper.h"
#include "ExtractState.h"

#define FS_CONFIG_BUF_SIZE (PATH_MAX + 256)

namespace skkk {

ErofsNode::ErofsNode(const char *path, short typeId, struct erofs_inode *inode) {
this->path = path;
this->typeId = typeId;
this->nid = inode->nid;
this->i_mode = inode->i_mode;
this->i_uid = inode->i_uid;
this->i_gid = inode->i_gid;
this->i_mtime = inode->i_mtime;
this->i_mtime_nsec = inode->i_mtime_nsec;
this->dataLayout = inode->datalayout;
char buf[FS_CONFIG_BUF_SIZE + 1];
snprintf(buf, FS_CONFIG_BUF_SIZE, "%s %u %u %04o",
path,
inode->i_uid,
inode->i_gid,
inode->i_mode & 0777
);
this->fsConfig = buf;
this->inode = new erofs_inode;
this->inode->nid = inode->nid;
erofs_read_inode_from_disk(this->inode);
}

ErofsNode::~ErofsNode() { delete inode; }

const string &ErofsNode::getPath() const { return path; }

short ErofsNode::getTypeId() const { return typeId; }

erofs_inode *ErofsNode::getErofsInode() const { return inode; }

const char *ErofsNode::getTypeIdCStr() const {
switch (typeId) {
case EROFS_FT_DIR:
return "DIR";
case EROFS_FT_REG_FILE:
return "FILE";
case EROFS_FT_SYMLINK:
return "LINK";
case EROFS_FT_CHRDEV:
return "CHR";
case EROFS_FT_BLKDEV:
return "BLK";
case EROFS_FT_FIFO:
return "FIFO";
case EROFS_FT_SOCK:
return "SOCK";
}
return "UNKNOWN";
}

const char *ErofsNode::getDataLayoutStr() const {
switch (dataLayout) {
case EROFS_INODE_FLAT_PLAIN:
return "PLAIN";
case EROFS_INODE_FLAT_INLINE:
return "INLINE";
case EROFS_INODE_CHUNK_BASED:
return "CHUNK";
case EROFS_INODE_FLAT_COMPRESSION_LEGACY:
return "COMPRESSION_LEGACY";
case EROFS_INODE_FLAT_COMPRESSION:
return "COMPRESSION";
}
return "UNKNOWN";
}

const string &ErofsNode::getFsConfig() const { return fsConfig; }

const string &ErofsNode::getSeLabel() const { return seContext; }

void ErofsNode::setSeContext(const string &_seContext) { this->seContext = _seContext; }

#ifdef WITH_ANDROID

uint64_t ErofsNode::getCapability() const { return capabilities; }

void ErofsNode::setCapability(uint64_t _capabilities) { this->capabilities = _capabilities; }

void ErofsNode::setFsConfigCapabilities(const char *capabilitiesStr) { fsConfig.append(capabilitiesStr); }

#endif

bool ErofsNode::initExceptionInfo(int err) {
if (err && err != RET_EXTRACT_FAIL_SKIP) [[unlikely]] {
char buf[256] = {0};
snprintf(buf, 256, "err=%d type=%s dataLayout=%s name=%s",
err,
getTypeIdCStr(),
getDataLayoutStr(),
getPath().c_str()
);
extractExceptionInfo = buf;
return true;
}
return false;
}

void
ErofsNode::writeFsConfigAndSeContext2File(FILE *fsConfigFile, FILE *seContextFile, const char *imgBaseName) const {
if (path == "/") [[unlikely]] {
fprintf(fsConfigFile, "%s\n", fsConfig.c_str());
fprintf(seContextFile, "/%s %s\n", imgBaseName, seContext.c_str());
}
fprintf(fsConfigFile, "%s%s\n", imgBaseName, fsConfig.c_str());
const string seCFilePath = handleSpecialSymbols(path);
fprintf(seContextFile, "/%s%s %s\n", imgBaseName, seCFilePath.c_str(), seContext.c_str());
}

int ErofsNode::writeNodeEntity2File(const string &outDir) {
int err = RET_EXTRACT_DONE;
string _tmp = outDir + path;
const char *filePath = _tmp.c_str();
switch (this->typeId) {
case EROFS_FT_DIR:
err = erofs_extract_dir(filePath);
break;
case EROFS_FT_REG_FILE:
err = erofs_extract_file(inode, filePath);
break;
case EROFS_FT_SYMLINK:
err = erofs_extract_symlink(inode, filePath);
break;
case EROFS_FT_CHRDEV:
case EROFS_FT_BLKDEV:
case EROFS_FT_FIFO:
case EROFS_FT_SOCK:
err = erofs_extract_special(inode, filePath);
break;
}
if (!err) set_attributes(inode, filePath);
return err;
}

void ErofsNode::writeExceptionInfo2FileIfExists(FILE *infoFile) const {
if (!extractExceptionInfo.empty()) [[unlikely]] {
fprintf(infoFile, "%s\n", extractExceptionInfo.c_str());
}
}
}
Loading

0 comments on commit d57ff5d

Please sign in to comment.