mirror of
https://github.com/pygos/pkg-utils.git
synced 2024-09-07 23:28:29 +02:00
cleanup: move generic squashfs code to library
Signed-off-by: David Oberhollenzer <goliath@infraroot.at>
This commit is contained in:
parent
5f0ee09c83
commit
7a70868fcd
10 changed files with 175 additions and 146 deletions
|
@ -2,6 +2,9 @@
|
|||
#ifndef SQUASHFS_H
|
||||
#define SQUASHFS_H
|
||||
|
||||
#include "comp/compressor.h"
|
||||
#include "pkg/pkgformat.h"
|
||||
|
||||
#include <stdint.h>
|
||||
|
||||
#define SQFS_MAGIC 0x73717368
|
||||
|
@ -160,4 +163,36 @@ typedef enum {
|
|||
SQFS_INODE_EXT_SOCKET = 14,
|
||||
} E_SQFS_INODE_TYPE;
|
||||
|
||||
typedef struct {
|
||||
uint8_t data[SQFS_META_BLOCK_SIZE + 2];
|
||||
uint8_t scratch[SQFS_META_BLOCK_SIZE];
|
||||
size_t offset;
|
||||
size_t written;
|
||||
int outfd;
|
||||
compressor_stream_t *strm;
|
||||
} meta_writer_t;
|
||||
|
||||
int sqfs_super_init(sqfs_super_t *s, int64_t timestamp,
|
||||
uint32_t blocksize, E_SQFS_COMPRESSOR comp);
|
||||
|
||||
int sqfs_super_write(const sqfs_super_t *super, int outfd);
|
||||
|
||||
compressor_stream_t *sqfs_get_compressor(sqfs_super_t *s);
|
||||
|
||||
meta_writer_t *meta_writer_create(int fd, compressor_stream_t *strm);
|
||||
|
||||
void meta_writer_destroy(meta_writer_t *m);
|
||||
|
||||
int meta_writer_flush(meta_writer_t *m);
|
||||
|
||||
int meta_writer_append(meta_writer_t *m, const void *data, size_t size);
|
||||
|
||||
int sqfs_write_ids(int outfd, sqfs_super_t *super,
|
||||
uint32_t *id_tbl, size_t count,
|
||||
compressor_stream_t *strm);
|
||||
|
||||
int sqfs_write_fragment_table(int outfd, sqfs_super_t *super,
|
||||
sqfs_fragment_t *fragments, size_t count,
|
||||
compressor_stream_t *strm);
|
||||
|
||||
#endif /* SQUASHFS_H */
|
|
@ -33,4 +33,7 @@ libpkg_a_SOURCES += include/pkg/pkgio.h include/pkg/pkgwriter.h
|
|||
libpkg_a_SOURCES += lib/pkg/pkgreader.c lib/pkg/pkgwriter.c
|
||||
libpkg_a_SOURCES += lib/pkg/pkg_unpack.c lib/pkg/pkgio_rd_image_entry.c
|
||||
|
||||
noinst_LIBRARIES += libutil.a libfilelist.a libcomp.a libpkg.a
|
||||
libsqfs_a_SOURCES = include/sqfs/squashfs.h lib/sqfs/super.c
|
||||
libsqfs_a_SOURCES += lib/sqfs/meta_writer.c lib/sqfs/table.c
|
||||
|
||||
noinst_LIBRARIES += libutil.a libfilelist.a libcomp.a libpkg.a libsqfs.a
|
||||
|
|
|
@ -1,5 +1,10 @@
|
|||
/* SPDX-License-Identifier: ISC */
|
||||
#include "pkg2sqfs.h"
|
||||
#include "sqfs/squashfs.h"
|
||||
#include "util/util.h"
|
||||
|
||||
#include <string.h>
|
||||
#include <stdlib.h>
|
||||
#include <stdio.h>
|
||||
|
||||
meta_writer_t *meta_writer_create(int fd, compressor_stream_t *strm)
|
||||
{
|
|
@ -1,10 +1,11 @@
|
|||
/* SPDX-License-Identifier: ISC */
|
||||
#include <endian.h>
|
||||
#include <string.h>
|
||||
#include <unistd.h>
|
||||
#include <stdio.h>
|
||||
|
||||
#include "sqfs/squashfs.h"
|
||||
#include "util/util.h"
|
||||
#include "pkg2sqfs.h"
|
||||
|
||||
int sqfs_super_init(sqfs_super_t *s, int64_t timestamp,
|
||||
uint32_t blocksize, E_SQFS_COMPRESSOR comp)
|
||||
|
@ -50,47 +51,47 @@ int sqfs_super_init(sqfs_super_t *s, int64_t timestamp,
|
|||
return 0;
|
||||
}
|
||||
|
||||
int sqfs_super_write(sqfs_info_t *info)
|
||||
int sqfs_super_write(const sqfs_super_t *super, int outfd)
|
||||
{
|
||||
sqfs_super_t copy;
|
||||
ssize_t ret;
|
||||
off_t off;
|
||||
|
||||
copy.magic = htole32(info->super.magic);
|
||||
copy.inode_count = htole32(info->super.inode_count);
|
||||
copy.modification_time = htole32(info->super.modification_time);
|
||||
copy.block_size = htole32(info->super.block_size);
|
||||
copy.fragment_entry_count = htole32(info->super.fragment_entry_count);
|
||||
copy.compression_id = htole16(info->super.compression_id);
|
||||
copy.block_log = htole16(info->super.block_log);
|
||||
copy.flags = htole16(info->super.flags);
|
||||
copy.id_count = htole16(info->super.id_count);
|
||||
copy.version_major = htole16(info->super.version_major);
|
||||
copy.version_minor = htole16(info->super.version_minor);
|
||||
copy.root_inode_ref = htole64(info->super.root_inode_ref);
|
||||
copy.bytes_used = htole64(info->super.bytes_used);
|
||||
copy.id_table_start = htole64(info->super.id_table_start);
|
||||
copy.xattr_id_table_start = htole64(info->super.xattr_id_table_start);
|
||||
copy.inode_table_start = htole64(info->super.inode_table_start);
|
||||
copy.directory_table_start = htole64(info->super.directory_table_start);
|
||||
copy.fragment_table_start = htole64(info->super.fragment_table_start);
|
||||
copy.export_table_start = htole64(info->super.export_table_start);
|
||||
copy.magic = htole32(super->magic);
|
||||
copy.inode_count = htole32(super->inode_count);
|
||||
copy.modification_time = htole32(super->modification_time);
|
||||
copy.block_size = htole32(super->block_size);
|
||||
copy.fragment_entry_count = htole32(super->fragment_entry_count);
|
||||
copy.compression_id = htole16(super->compression_id);
|
||||
copy.block_log = htole16(super->block_log);
|
||||
copy.flags = htole16(super->flags);
|
||||
copy.id_count = htole16(super->id_count);
|
||||
copy.version_major = htole16(super->version_major);
|
||||
copy.version_minor = htole16(super->version_minor);
|
||||
copy.root_inode_ref = htole64(super->root_inode_ref);
|
||||
copy.bytes_used = htole64(super->bytes_used);
|
||||
copy.id_table_start = htole64(super->id_table_start);
|
||||
copy.xattr_id_table_start = htole64(super->xattr_id_table_start);
|
||||
copy.inode_table_start = htole64(super->inode_table_start);
|
||||
copy.directory_table_start = htole64(super->directory_table_start);
|
||||
copy.fragment_table_start = htole64(super->fragment_table_start);
|
||||
copy.export_table_start = htole64(super->export_table_start);
|
||||
|
||||
off = lseek(info->outfd, 0, SEEK_SET);
|
||||
off = lseek(outfd, 0, SEEK_SET);
|
||||
if (off == (off_t)-1) {
|
||||
perror("seek on output file");
|
||||
perror("squashfs writing super block: seek on output file");
|
||||
return -1;
|
||||
}
|
||||
|
||||
ret = write_retry(info->outfd, ©, sizeof(copy));
|
||||
ret = write_retry(outfd, ©, sizeof(copy));
|
||||
|
||||
if (ret < 0) {
|
||||
perror("Error writing squashfs super block");
|
||||
perror("squashfs writing super block");
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (ret == 0) {
|
||||
fputs("Truncated write trying to write squashfs super block\n",
|
||||
fputs("squashfs writing super block: truncated write\n",
|
||||
stderr);
|
||||
return -1;
|
||||
}
|
92
lib/sqfs/table.c
Normal file
92
lib/sqfs/table.c
Normal file
|
@ -0,0 +1,92 @@
|
|||
/* SPDX-License-Identifier: ISC */
|
||||
#include "sqfs/squashfs.h"
|
||||
#include "util/util.h"
|
||||
|
||||
#include <endian.h>
|
||||
#include <stdio.h>
|
||||
|
||||
static int sqfs_write_table(int outfd, sqfs_super_t *super, const void *data,
|
||||
size_t entsize, size_t count, uint64_t *startblock,
|
||||
compressor_stream_t *strm)
|
||||
{
|
||||
size_t ent_per_blocks = SQFS_META_BLOCK_SIZE / entsize;
|
||||
uint64_t blocks[count / ent_per_blocks + 1];
|
||||
size_t i, blkidx = 0, tblsize;
|
||||
meta_writer_t *m;
|
||||
ssize_t ret;
|
||||
|
||||
/* Write actual data. Whenever we cross a block boundary, remember
|
||||
the block start offset */
|
||||
m = meta_writer_create(outfd, strm);
|
||||
if (m == NULL)
|
||||
return -1;
|
||||
|
||||
for (i = 0; i < count; ++i) {
|
||||
if (blkidx == 0 || m->written > blocks[blkidx - 1])
|
||||
blocks[blkidx++] = m->written;
|
||||
|
||||
if (meta_writer_append(m, data, entsize))
|
||||
goto fail;
|
||||
|
||||
data = (const char *)data + entsize;
|
||||
}
|
||||
|
||||
if (meta_writer_flush(m))
|
||||
goto fail;
|
||||
|
||||
for (i = 0; i < blkidx; ++i)
|
||||
blocks[i] = htole64(blocks[i] + super->bytes_used);
|
||||
|
||||
super->bytes_used += m->written;
|
||||
meta_writer_destroy(m);
|
||||
|
||||
/* write new index table */
|
||||
*startblock = super->bytes_used;
|
||||
tblsize = sizeof(blocks[0]) * blkidx;
|
||||
|
||||
ret = write_retry(outfd, blocks, tblsize);
|
||||
if (ret < 0) {
|
||||
perror("writing index table");
|
||||
return -1;
|
||||
}
|
||||
|
||||
if ((size_t)ret < tblsize) {
|
||||
fputs("index table truncated\n", stderr);
|
||||
return -1;
|
||||
}
|
||||
|
||||
super->bytes_used += tblsize;
|
||||
return 0;
|
||||
fail:
|
||||
meta_writer_destroy(m);
|
||||
return -1;
|
||||
}
|
||||
|
||||
int sqfs_write_fragment_table(int outfd, sqfs_super_t *super,
|
||||
sqfs_fragment_t *fragments, size_t count,
|
||||
compressor_stream_t *strm)
|
||||
{
|
||||
super->fragment_entry_count = count;
|
||||
|
||||
return sqfs_write_table(outfd, super, fragments, sizeof(fragments[0]),
|
||||
count, &super->fragment_table_start, strm);
|
||||
}
|
||||
|
||||
int sqfs_write_ids(int outfd, sqfs_super_t *super,
|
||||
uint32_t *id_tbl, size_t count,
|
||||
compressor_stream_t *strm)
|
||||
{
|
||||
size_t i;
|
||||
int ret;
|
||||
|
||||
for (i = 0; i < count; ++i)
|
||||
id_tbl[i] = htole32(id_tbl[i]);
|
||||
|
||||
ret = sqfs_write_table(outfd, super, id_tbl, sizeof(id_tbl[0]),
|
||||
count, &super->id_table_start, strm);
|
||||
|
||||
for (i = 0; i < count; ++i)
|
||||
id_tbl[i] = htole32(id_tbl[i]);
|
||||
|
||||
return ret;
|
||||
}
|
|
@ -1,9 +1,9 @@
|
|||
pkg2sqfs_SOURCES = sqfs/squashfs.h sqfs/super.c sqfs/pkg2sqfs.c
|
||||
pkg2sqfs_SOURCES = sqfs/pkg2sqfs.c
|
||||
pkg2sqfs_SOURCES += sqfs/vfs.c sqfs/pkg2sqfs.h sqfs/block.c
|
||||
pkg2sqfs_SOURCES += sqfs/meta.c sqfs/meta_writer.c sqfs/table.c
|
||||
pkg2sqfs_SOURCES += sqfs/meta.c
|
||||
pkg2sqfs_CPPFLAGS = $(AM_CPPFLAGS) -I$(top_srcdir)/sqfs
|
||||
pkg2sqfs_CFLAGS = $(AM_CFLAGS)
|
||||
pkg2sqfs_LDADD = libpkg.a libutil.a libfilelist.a libcomp.a
|
||||
pkg2sqfs_LDADD = libsqfs.a libpkg.a libutil.a libfilelist.a libcomp.a
|
||||
|
||||
if WITH_LZMA
|
||||
pkg2sqfs_LDADD += $(XZ_LIBS)
|
||||
|
|
|
@ -269,7 +269,7 @@ int main(int argc, char **argv)
|
|||
if (create_vfs_tree(&info))
|
||||
goto out_buffer;
|
||||
|
||||
if (sqfs_super_write(&info))
|
||||
if (sqfs_super_write(&info.super, info.outfd))
|
||||
goto out_tree;
|
||||
|
||||
if (pkg_data_to_sqfs(&info, cmp))
|
||||
|
@ -281,13 +281,16 @@ int main(int argc, char **argv)
|
|||
if (sqfs_write_inodes(&info, cmp))
|
||||
goto out_fragments;
|
||||
|
||||
if (sqfs_write_fragment_table(&info, cmp))
|
||||
if (sqfs_write_fragment_table(info.outfd, &info.super,
|
||||
info.fragments, info.num_fragments,
|
||||
cmp))
|
||||
goto out_fragments;
|
||||
|
||||
if (sqfs_write_ids(&info, cmp))
|
||||
if (sqfs_write_ids(info.outfd, &info.super,
|
||||
info.fs.id_tbl, info.fs.num_ids, cmp))
|
||||
goto out_fragments;
|
||||
|
||||
if (sqfs_super_write(&info))
|
||||
if (sqfs_super_write(&info.super, info.outfd))
|
||||
goto out_fragments;
|
||||
|
||||
if (sqfs_padd_file(&info))
|
||||
|
|
|
@ -23,20 +23,11 @@
|
|||
#include "filelist/image_entry.h"
|
||||
#include "comp/compressor.h"
|
||||
#include "pkg/pkgreader.h"
|
||||
#include "sqfs/squashfs.h"
|
||||
#include "pkg/pkgio.h"
|
||||
#include "squashfs.h"
|
||||
|
||||
#include "config.h"
|
||||
|
||||
typedef struct {
|
||||
uint8_t data[SQFS_META_BLOCK_SIZE + 2];
|
||||
uint8_t scratch[SQFS_META_BLOCK_SIZE];
|
||||
size_t offset;
|
||||
size_t written;
|
||||
int outfd;
|
||||
compressor_stream_t *strm;
|
||||
} meta_writer_t;
|
||||
|
||||
typedef struct file_info_t {
|
||||
struct file_info_t *frag_next;
|
||||
uint64_t size;
|
||||
|
@ -112,11 +103,6 @@ typedef struct {
|
|||
|
||||
int pkg_data_to_sqfs(sqfs_info_t *info, compressor_stream_t *strm);
|
||||
|
||||
int sqfs_super_init(sqfs_super_t *s, int64_t timestamp,
|
||||
uint32_t blocksize, E_SQFS_COMPRESSOR comp);
|
||||
|
||||
int sqfs_super_write(sqfs_info_t *info);
|
||||
|
||||
int create_vfs_tree(sqfs_info_t *info);
|
||||
|
||||
void destroy_vfs_tree(vfs_t *fs);
|
||||
|
@ -125,18 +111,4 @@ node_t *vfs_node_from_file_id(vfs_t *fs, uint32_t id);
|
|||
|
||||
int sqfs_write_inodes(sqfs_info_t *info, compressor_stream_t *strm);
|
||||
|
||||
int sqfs_write_ids(sqfs_info_t *info, compressor_stream_t *strm);
|
||||
|
||||
int sqfs_write_fragment_table(sqfs_info_t *info, compressor_stream_t *strm);
|
||||
|
||||
meta_writer_t *meta_writer_create(int fd, compressor_stream_t *strm);
|
||||
|
||||
void meta_writer_destroy(meta_writer_t *m);
|
||||
|
||||
int meta_writer_flush(meta_writer_t *m);
|
||||
|
||||
int meta_writer_append(meta_writer_t *m, const void *data, size_t size);
|
||||
|
||||
compressor_stream_t *sqfs_get_compressor(sqfs_super_t *s);
|
||||
|
||||
#endif /* PKG2SQFS_H */
|
||||
|
|
77
sqfs/table.c
77
sqfs/table.c
|
@ -1,77 +0,0 @@
|
|||
/* SPDX-License-Identifier: ISC */
|
||||
#include "pkg2sqfs.h"
|
||||
|
||||
static int sqfs_write_table(sqfs_info_t *info, const void *data,
|
||||
size_t entsize, size_t count, uint64_t *startblock,
|
||||
compressor_stream_t *strm)
|
||||
{
|
||||
size_t ent_per_blocks = SQFS_META_BLOCK_SIZE / entsize;
|
||||
uint64_t blocks[count / ent_per_blocks + 1];
|
||||
size_t i, blkidx = 0, tblsize;
|
||||
meta_writer_t *m;
|
||||
ssize_t ret;
|
||||
|
||||
/* Write actual data. Whenever we cross a block boundary, remember
|
||||
the block start offset */
|
||||
m = meta_writer_create(info->outfd, strm);
|
||||
if (m == NULL)
|
||||
return -1;
|
||||
|
||||
for (i = 0; i < count; ++i) {
|
||||
if (blkidx == 0 || m->written > blocks[blkidx - 1])
|
||||
blocks[blkidx++] = m->written;
|
||||
|
||||
if (meta_writer_append(m, data, entsize))
|
||||
goto fail;
|
||||
|
||||
data = (const char *)data + entsize;
|
||||
}
|
||||
|
||||
if (meta_writer_flush(m))
|
||||
goto fail;
|
||||
|
||||
for (i = 0; i < blkidx; ++i)
|
||||
blocks[i] = htole64(blocks[i] + info->super.bytes_used);
|
||||
|
||||
info->super.bytes_used += m->written;
|
||||
meta_writer_destroy(m);
|
||||
|
||||
/* write new index table */
|
||||
*startblock = info->super.bytes_used;
|
||||
tblsize = sizeof(blocks[0]) * blkidx;
|
||||
|
||||
ret = write_retry(info->outfd, blocks, tblsize);
|
||||
if (ret < 0) {
|
||||
perror("writing index table");
|
||||
return -1;
|
||||
}
|
||||
|
||||
if ((size_t)ret < tblsize) {
|
||||
fputs("index table truncated\n", stderr);
|
||||
return -1;
|
||||
}
|
||||
|
||||
info->super.bytes_used += tblsize;
|
||||
return 0;
|
||||
fail:
|
||||
meta_writer_destroy(m);
|
||||
return -1;
|
||||
}
|
||||
|
||||
int sqfs_write_fragment_table(sqfs_info_t *info, compressor_stream_t *strm)
|
||||
{
|
||||
info->super.fragment_entry_count = info->num_fragments;
|
||||
|
||||
return sqfs_write_table(info, info->fragments,
|
||||
sizeof(info->fragments[0]),
|
||||
info->num_fragments,
|
||||
&info->super.fragment_table_start, strm);
|
||||
}
|
||||
|
||||
int sqfs_write_ids(sqfs_info_t *info, compressor_stream_t *strm)
|
||||
{
|
||||
return sqfs_write_table(info, info->fs.id_tbl,
|
||||
sizeof(info->fs.id_tbl[0]),
|
||||
info->fs.num_ids,
|
||||
&info->super.id_table_start, strm);
|
||||
}
|
|
@ -316,7 +316,6 @@ int create_vfs_tree(sqfs_info_t *info)
|
|||
uint32_t counter = 2;
|
||||
vfs_t *fs = &info->fs;
|
||||
node_t *n;
|
||||
size_t i;
|
||||
|
||||
if (image_entry_list_from_package(info->rd, &list))
|
||||
return -1;
|
||||
|
@ -351,10 +350,6 @@ int create_vfs_tree(sqfs_info_t *info)
|
|||
info->super.id_count = fs->num_ids;
|
||||
|
||||
image_entry_free_list(list);
|
||||
|
||||
for (i = 0; i < fs->num_ids; ++i)
|
||||
fs->id_tbl[i] = htole32(fs->id_tbl[i]);
|
||||
|
||||
return 0;
|
||||
fail_oom:
|
||||
fputs("out of memory\n", stderr);
|
||||
|
|
Loading…
Reference in a new issue