summaryrefslogtreecommitdiff
path: root/lib/sqfshelper/write_inode.c
diff options
context:
space:
mode:
Diffstat (limited to 'lib/sqfshelper/write_inode.c')
-rw-r--r--lib/sqfshelper/write_inode.c328
1 files changed, 0 insertions, 328 deletions
diff --git a/lib/sqfshelper/write_inode.c b/lib/sqfshelper/write_inode.c
deleted file mode 100644
index d9dfe53..0000000
--- a/lib/sqfshelper/write_inode.c
+++ /dev/null
@@ -1,328 +0,0 @@
-/* SPDX-License-Identifier: GPL-3.0-or-later */
-/*
- * write_inode.c
- *
- * Copyright (C) 2019 David Oberhollenzer <goliath@infraroot.at>
- */
-#include "config.h"
-
-#include "highlevel.h"
-#include "sqfs/inode.h"
-#include "sqfs/dir.h"
-#include "util.h"
-
-#include <assert.h>
-#include <endian.h>
-#include <stdlib.h>
-#include <string.h>
-
-static size_t hard_link_count(tree_node_t *n)
-{
- size_t count;
-
- if (S_ISDIR(n->mode)) {
- count = 2;
-
- for (n = n->data.dir->children; n != NULL; n = n->next)
- ++count;
-
- return count;
- }
-
- return 1;
-}
-
-static int get_type(tree_node_t *node)
-{
- switch (node->mode & S_IFMT) {
- case S_IFSOCK:
- if (node->xattr != NULL)
- return SQFS_INODE_EXT_SOCKET;
- return SQFS_INODE_SOCKET;
- case S_IFIFO:
- if (node->xattr != NULL)
- return SQFS_INODE_EXT_FIFO;
- return SQFS_INODE_FIFO;
- case S_IFLNK:
- if (node->xattr != NULL)
- return SQFS_INODE_EXT_SLINK;
- return SQFS_INODE_SLINK;
- case S_IFBLK:
- if (node->xattr != NULL)
- return SQFS_INODE_EXT_BDEV;
- return SQFS_INODE_BDEV;
- case S_IFCHR:
- if (node->xattr != NULL)
- return SQFS_INODE_EXT_CDEV;
- return SQFS_INODE_CDEV;
- case S_IFREG: {
- file_info_t *fi = node->data.file;
-
- if (node->xattr != NULL || fi->sparse > 0)
- return SQFS_INODE_EXT_FILE;
-
- if (fi->startblock > 0xFFFFFFFFUL || fi->size > 0xFFFFFFFFUL)
- return SQFS_INODE_EXT_FILE;
-
- if (hard_link_count(node) > 1)
- return SQFS_INODE_EXT_FILE;
-
- return SQFS_INODE_FILE;
- }
- case S_IFDIR: {
- dir_info_t *di = node->data.dir;
-
- if (node->xattr != NULL)
- return SQFS_INODE_EXT_DIR;
-
- if (di->start_block > 0xFFFFFFFFUL || di->size > 0xFFFF)
- return SQFS_INODE_EXT_DIR;
-
- return SQFS_INODE_DIR;
- }
- }
- assert(0);
-}
-
-static int write_file_blocks(fstree_t *fs, file_info_t *fi, meta_writer_t *im)
-{
- uint64_t i, count = fi->size / fs->block_size;
- uint32_t bs;
-
- if ((fi->size % fs->block_size) != 0 &&
- !(fi->flags & FILE_FLAG_HAS_FRAGMENT)) {
- ++count;
- }
-
- for (i = 0; i < count; ++i) {
- bs = htole32(fi->blocks[i].size);
-
- if (meta_writer_append(im, &bs, sizeof(bs)))
- return -1;
- }
- return 0;
-}
-
-static int write_dir_entries(sqfs_dir_writer_t *dirw, tree_node_t *node)
-{
- tree_node_t *it;
- uint64_t ref;
- int ret;
-
- if (sqfs_dir_writer_begin(dirw))
- return -1;
-
- for (it = node->data.dir->children; it != NULL; it = it->next) {
- ret = sqfs_dir_writer_add_entry(dirw, it->name, it->inode_num,
- it->inode_ref, it->mode);
- if (ret)
- return -1;
- }
-
- if (sqfs_dir_writer_end(dirw))
- return -1;
-
- ref = sqfs_dir_writer_get_dir_reference(dirw);
-
- node->data.dir->size = sqfs_dir_writer_get_size(dirw);
- node->data.dir->start_block = ref >> 16;
- node->data.dir->block_offset = ref & 0xFFFF;
- return 0;
-}
-
-int meta_writer_write_inode(fstree_t *fs, id_table_t *idtbl, meta_writer_t *im,
- sqfs_dir_writer_t *dirw, tree_node_t *node)
-{
- uint16_t uid_idx, gid_idx;
- sqfs_inode_t base;
- uint32_t offset;
- uint64_t block;
-
- if (id_table_id_to_index(idtbl, node->uid, &uid_idx))
- return -1;
-
- if (id_table_id_to_index(idtbl, node->gid, &gid_idx))
- return -1;
-
- meta_writer_get_position(im, &block, &offset);
- node->inode_ref = (block << 16) | offset;
-
- if (S_ISDIR(node->mode)) {
- if (write_dir_entries(dirw, node))
- return -1;
- }
-
- base.type = htole16(get_type(node));
- base.mode = htole16(node->mode);
- base.uid_idx = htole16(uid_idx);
- base.gid_idx = htole16(gid_idx);
- base.mod_time = htole32(node->mod_time);
- base.inode_number = htole32(node->inode_num);
-
- if (meta_writer_append(im, &base, sizeof(base)))
- return -1;
-
- switch (le16toh(base.type)) {
- case SQFS_INODE_FIFO:
- case SQFS_INODE_SOCKET: {
- sqfs_inode_ipc_t ipc = {
- .nlink = htole32(hard_link_count(node)),
- };
-
- return meta_writer_append(im, &ipc, sizeof(ipc));
- }
- case SQFS_INODE_EXT_FIFO:
- case SQFS_INODE_EXT_SOCKET: {
- sqfs_inode_ipc_ext_t ipc = {
- .nlink = htole32(hard_link_count(node)),
- .xattr_idx = htole32(0xFFFFFFFF),
- };
-
- if (node->xattr != NULL)
- ipc.xattr_idx = htole32(node->xattr->index);
-
- return meta_writer_append(im, &ipc, sizeof(ipc));
- }
- case SQFS_INODE_SLINK: {
- sqfs_inode_slink_t slink = {
- .nlink = htole32(hard_link_count(node)),
- .target_size = htole32(strlen(node->data.slink_target)),
- };
-
- if (meta_writer_append(im, &slink, sizeof(slink)))
- return -1;
- if (meta_writer_append(im, node->data.slink_target,
- le32toh(slink.target_size))) {
- return -1;
- }
- break;
- }
- case SQFS_INODE_EXT_SLINK: {
- sqfs_inode_slink_t slink = {
- .nlink = htole32(hard_link_count(node)),
- .target_size = htole32(strlen(node->data.slink_target)),
- };
- uint32_t xattr = htole32(0xFFFFFFFF);
-
- if (node->xattr != NULL)
- xattr = htole32(node->xattr->index);
-
- if (meta_writer_append(im, &slink, sizeof(slink)))
- return -1;
- if (meta_writer_append(im, node->data.slink_target,
- le32toh(slink.target_size))) {
- return -1;
- }
- if (meta_writer_append(im, &xattr, sizeof(xattr)))
- return -1;
- break;
- }
- case SQFS_INODE_BDEV:
- case SQFS_INODE_CDEV: {
- sqfs_inode_dev_t dev = {
- .nlink = htole32(hard_link_count(node)),
- .devno = htole32(node->data.devno),
- };
-
- return meta_writer_append(im, &dev, sizeof(dev));
- }
- case SQFS_INODE_EXT_BDEV:
- case SQFS_INODE_EXT_CDEV: {
- sqfs_inode_dev_ext_t dev = {
- .nlink = htole32(hard_link_count(node)),
- .devno = htole32(node->data.devno),
- .xattr_idx = htole32(0xFFFFFFFF),
- };
-
- if (node->xattr != NULL)
- dev.xattr_idx = htole32(node->xattr->index);
-
- return meta_writer_append(im, &dev, sizeof(dev));
- }
- case SQFS_INODE_EXT_FILE: {
- file_info_t *fi = node->data.file;
- sqfs_inode_file_ext_t ext = {
- .blocks_start = htole64(fi->startblock),
- .file_size = htole64(fi->size),
- .sparse = htole64(fi->sparse),
- .nlink = htole32(hard_link_count(node)),
- .fragment_idx = htole32(0xFFFFFFFF),
- .fragment_offset = htole32(0xFFFFFFFF),
- .xattr_idx = htole32(0xFFFFFFFF),
- };
-
- if ((fi->size % fs->block_size) != 0) {
- ext.fragment_idx = htole32(fi->fragment);
- ext.fragment_offset = htole32(fi->fragment_offset);
- }
-
- if (node->xattr != NULL)
- ext.xattr_idx = htole32(node->xattr->index);
-
- if (meta_writer_append(im, &ext, sizeof(ext)))
- return -1;
- return write_file_blocks(fs, fi, im);
- }
- case SQFS_INODE_FILE: {
- file_info_t *fi = node->data.file;
- sqfs_inode_file_t reg = {
- .blocks_start = htole32(fi->startblock),
- .fragment_index = htole32(0xFFFFFFFF),
- .fragment_offset = htole32(0xFFFFFFFF),
- .file_size = htole32(fi->size),
- };
-
- if ((fi->size % fs->block_size) != 0) {
- reg.fragment_index = htole32(fi->fragment);
- reg.fragment_offset = htole32(fi->fragment_offset);
- }
-
- if (meta_writer_append(im, &reg, sizeof(reg)))
- return -1;
- return write_file_blocks(fs, fi, im);
- }
- case SQFS_INODE_DIR: {
- sqfs_inode_dir_t dir = {
- .start_block = htole32(node->data.dir->start_block),
- .nlink = htole32(hard_link_count(node)),
- .size = htole16(node->data.dir->size),
- .offset = htole16(node->data.dir->block_offset),
- .parent_inode = node->parent ?
- htole32(node->parent->inode_num) : htole32(1),
- };
-
- return meta_writer_append(im, &dir, sizeof(dir));
- }
- case SQFS_INODE_EXT_DIR: {
- size_t idx_size;
- sqfs_inode_dir_ext_t ext = {
- .nlink = htole32(hard_link_count(node)),
- .size = htole32(node->data.dir->size),
- .start_block = htole32(node->data.dir->start_block),
- .parent_inode = node->parent ?
- htole32(node->parent->inode_num) : htole32(1),
- .inodex_count = htole32(0),
- .offset = htole16(node->data.dir->block_offset),
- .xattr_idx = htole32(0xFFFFFFFF),
- };
-
- if (node->xattr != NULL)
- ext.xattr_idx = htole32(node->xattr->index);
-
- idx_size = sqfs_dir_writer_get_index_size(dirw);
-
- if (idx_size > 0)
- ext.inodex_count = htole32(idx_size - 1);
-
- if (meta_writer_append(im, &ext, sizeof(ext)))
- return -1;
-
- if (sqfs_dir_writer_write_index(dirw, im))
- return -1;
- break;
- }
- default:
- assert(0);
- }
- return 0;
-}