summaryrefslogtreecommitdiff
path: root/mkfs/mkfs.c
diff options
context:
space:
mode:
Diffstat (limited to 'mkfs/mkfs.c')
-rw-r--r--mkfs/mkfs.c118
1 files changed, 118 insertions, 0 deletions
diff --git a/mkfs/mkfs.c b/mkfs/mkfs.c
new file mode 100644
index 0000000..d708d37
--- /dev/null
+++ b/mkfs/mkfs.c
@@ -0,0 +1,118 @@
+/* SPDX-License-Identifier: GPL-3.0-or-later */
+#include "mkfs.h"
+#include "util.h"
+
+static int padd_file(sqfs_info_t *info)
+{
+ size_t padd_sz = info->super.bytes_used % info->opt.devblksz;
+ uint8_t *buffer;
+ ssize_t ret;
+
+ if (padd_sz == 0)
+ return 0;
+
+ padd_sz = info->opt.devblksz - padd_sz;
+
+ buffer = calloc(1, padd_sz);
+ if (buffer == NULL) {
+ perror("padding output file to block size");
+ return -1;
+ }
+
+ ret = write_retry(info->outfd, buffer, padd_sz);
+
+ if (ret < 0) {
+ perror("Error padding squashfs image to page size");
+ free(buffer);
+ return -1;
+ }
+
+ if ((size_t)ret < padd_sz) {
+ fputs("Truncated write trying to padd squashfs image\n",
+ stderr);
+ return -1;
+ }
+
+ free(buffer);
+ return 0;
+}
+
+int main(int argc, char **argv)
+{
+ int status = EXIT_FAILURE;
+ sqfs_info_t info;
+
+ memset(&info, 0, sizeof(info));
+
+ process_command_line(&info.opt, argc, argv);
+
+ if (sqfs_super_init(&info.super, info.opt.blksz, info.opt.def_mtime,
+ info.opt.compressor)) {
+ return EXIT_FAILURE;
+ }
+
+ if (id_table_init(&info.idtbl))
+ return EXIT_FAILURE;
+
+ info.outfd = open(info.opt.outfile, info.opt.outmode, 0644);
+ if (info.outfd < 0) {
+ perror(info.opt.outfile);
+ goto out_idtbl;
+ }
+
+ if (sqfs_super_write(&info.super, info.outfd))
+ goto out_outfd;
+
+ if (fstree_init(&info.fs, info.opt.blksz, info.opt.def_mtime,
+ info.opt.def_mode, info.opt.def_uid,
+ info.opt.def_gid)) {
+ goto out_outfd;
+ }
+
+ if (fstree_from_file(&info.fs, info.opt.infile))
+ goto out_fstree;
+
+ fstree_sort(&info.fs);
+
+ info.cmp = compressor_create(info.super.compression_id, true,
+ info.super.block_size);
+ if (info.cmp == NULL) {
+ fputs("Error creating compressor\n", stderr);
+ goto out_outfd;
+ }
+
+ if (write_data_to_image(&info))
+ goto out_cmp;
+
+ if (sqfs_write_inodes(&info))
+ goto out_cmp;
+
+ info.super.fragment_entry_count = info.num_fragments;
+
+ if (sqfs_write_table(info.outfd, &info.super, info.fragments,
+ sizeof(info.fragments[0]), info.num_fragments,
+ &info.super.fragment_table_start, info.cmp)) {
+ goto out_cmp;
+ }
+
+ if (id_table_write(&info.idtbl, info.outfd, &info.super, info.cmp))
+ goto out_cmp;
+
+ if (sqfs_super_write(&info.super, info.outfd))
+ goto out_cmp;
+
+ if (padd_file(&info))
+ goto out_cmp;
+
+ status = EXIT_SUCCESS;
+out_cmp:
+ free(info.fragments);
+ info.cmp->destroy(info.cmp);
+out_fstree:
+ fstree_cleanup(&info.fs);
+out_outfd:
+ close(info.outfd);
+out_idtbl:
+ id_table_cleanup(&info.idtbl);
+ return status;
+}