diff options
Diffstat (limited to 'libfstools/common.c')
-rw-r--r-- | libfstools/common.c | 124 |
1 files changed, 124 insertions, 0 deletions
diff --git a/libfstools/common.c b/libfstools/common.c new file mode 100644 index 0000000..f2d415d --- /dev/null +++ b/libfstools/common.c @@ -0,0 +1,124 @@ +// SPDX-License-Identifier: GPL-2.0-or-later + +#include "common.h" +#define BUFLEN 128 + +int +read_uint_from_file(char *dirname, char *filename, unsigned int *i) +{ + FILE *f; + char fname[BUFLEN]; + int ret = -1; + + snprintf(fname, sizeof(fname), "%s/%s", dirname, filename); + + f = fopen(fname, "r"); + if (!f) + return ret; + + if (fscanf(f, "%u", i) == 1) + ret = 0; + + fclose(f); + return ret; +} + +char +*read_string_from_file(const char *dirname, const char *filename, char *buf, size_t bufsz) +{ + FILE *f; + char fname[BUFLEN]; + int i; + + snprintf(fname, sizeof(fname), "%s/%s", dirname, filename); + + f = fopen(fname, "r"); + if (!f) + return NULL; + + if (fgets(buf, bufsz, f) == NULL) + return NULL; + + fclose(f); + + /* make sure the string is \0 terminated */ + buf[bufsz - 1] = '\0'; + + /* remove trailing whitespace */ + i = strlen(buf) - 1; + while (i > 0 && buf[i] <= ' ') + buf[i--] = '\0'; + + return buf; +} + +int block_file_identify(FILE *f, uint64_t offset) +{ + uint32_t magic = 0; + size_t n; + + fseeko(f, offset, SEEK_SET); + n = fread(&magic, sizeof(magic), 1, f); + if (magic == cpu_to_le32(0x88b1f)) { + return FS_TARGZ; + } + + fseeko(f, offset + 0x400, SEEK_SET); + n = fread(&magic, sizeof(magic), 1, f); + if (n != 1) + return -1; + + if (magic == cpu_to_le32(0xF2F52010)) + return FS_F2FS; + + magic = 0; + fseeko(f, offset + 0x438, SEEK_SET); + n = fread(&magic, sizeof(magic), 1, f); + if (n != 1) + return -1; + + if ((le32_to_cpu(magic) & 0xffff) == 0xef53) + return FS_EXT4; + + return FS_NONE; +} + +static bool use_f2fs(struct volume *v, uint64_t offset, const char *bdev) +{ + uint64_t size = 0; + bool ret = false; + int fd; + + fd = open(bdev, O_RDONLY); + if (ioctl(fd, BLKGETSIZE64, &size) == 0) + ret = size - offset > F2FS_MINSIZE; + close(fd); + + return ret; +} + +int block_volume_format(struct volume *v, uint64_t offset, const char *bdev) +{ + int ret = 0; + char str[128]; + + switch (volume_identify(v)) { + case FS_TARGZ: + snprintf(str, sizeof(str), "gzip -cd %s > /tmp/sysupgrade.tar", v->blk); + system(str); + /* fall-through */ + case FS_NONE: + ULOG_INFO("overlay filesystem in %s has not been formatted yet\n", v->blk); + if (use_f2fs(v, offset, bdev)) + snprintf(str, sizeof(str), "mkfs.f2fs -q -l rootfs_data %s", v->blk); + else + snprintf(str, sizeof(str), "mkfs.ext4 -q -L rootfs_data %s", v->blk); + + ret = system(str); + break; + default: + break; + } + + return ret; +} |