[PATCH firmware-utils 1/2] oseama: allow reading from stdin
Rafał Miłecki
zajec5 at gmail.com
Fri Nov 26 08:17:07 PST 2021
From: Rafał Miłecki <rafal at milecki.pl>
This adds support for reading Seama seal from stdin when using "info" or
"extract" command. It allows e.g.
cat firmware.bin | oseama info -
Signed-off-by: Rafał Miłecki <rafal at milecki.pl>
---
src/oseama.c | 77 +++++++++++++++++++++++++++++++++++++++++++---------
1 file changed, 64 insertions(+), 13 deletions(-)
diff --git a/src/oseama.c b/src/oseama.c
index 75580e6..d3eb9b9 100644
--- a/src/oseama.c
+++ b/src/oseama.c
@@ -59,6 +59,44 @@ static inline size_t oseama_min(size_t x, size_t y) {
return x < y ? x : y;
}
+/**************************************************
+ * Helpers
+ **************************************************/
+
+static FILE *oseama_open(const char *pathname, const char *mode) {
+ if (strcmp(pathname, "-"))
+ return fopen(pathname, mode);
+
+ if (isatty(fileno(stdin))) {
+ fprintf(stderr, "Reading from TTY stdin is unsupported\n");
+ return NULL;
+ }
+
+ return stdin;
+}
+
+static int oseama_skip(FILE *fp, size_t length)
+{
+ if (fseek(fp, length, SEEK_CUR)) {
+ uint8_t buf[1024];
+ size_t bytes;
+
+ do {
+ bytes = fread(buf, 1, oseama_min(sizeof(buf), length), fp);
+ if (bytes <= 0)
+ return -EIO;
+ length -= bytes;
+ } while (length);
+ }
+
+ return 0;
+}
+
+static void oseama_close(FILE *fp) {
+ if (fp != stdin)
+ fclose(fp);
+}
+
/**************************************************
* Info
**************************************************/
@@ -75,7 +113,7 @@ static void oseama_info_parse_options(int argc, char **argv) {
}
}
-static int oseama_info_entities(FILE *seama) {
+static int oseama_info_entities(FILE *seama, size_t *pos) {
struct seama_entity_header hdr;
size_t bytes, metasize, imagesize;
uint8_t buf[1024];
@@ -84,6 +122,8 @@ static int oseama_info_entities(FILE *seama) {
int err = 0;
while ((bytes = fread(&hdr, 1, sizeof(hdr), seama)) == sizeof(hdr)) {
+ *pos += bytes;
+
if (be32_to_cpu(hdr.magic) != SEAMA_MAGIC) {
fprintf(stderr, "Invalid Seama magic: 0x%08x\n", be32_to_cpu(hdr.magic));
err = -EINVAL;
@@ -93,7 +133,8 @@ static int oseama_info_entities(FILE *seama) {
imagesize = be32_to_cpu(hdr.imagesize);
if (entity_idx >= 0 && i != entity_idx) {
- fseek(seama, metasize + imagesize, SEEK_CUR);
+ oseama_skip(seama, metasize + imagesize);
+ *pos += metasize + imagesize;
i++;
continue;
}
@@ -106,7 +147,7 @@ static int oseama_info_entities(FILE *seama) {
if (entity_idx < 0)
printf("\n");
- printf("Entity offset:\t%ld\n", ftell(seama) - sizeof(hdr));
+ printf("Entity offset:\t%ld\n", *pos - sizeof(hdr));
printf("Entity size:\t%zd\n", sizeof(hdr) + metasize + imagesize);
printf("Meta size:\t%zd\n", metasize);
printf("Image size:\t%zd\n", imagesize);
@@ -117,6 +158,7 @@ static int oseama_info_entities(FILE *seama) {
err = -EIO;
goto err_out;
}
+ *pos += bytes;
end = (char *)&buf[metasize - 1];
*end = '\0';
@@ -124,7 +166,8 @@ static int oseama_info_entities(FILE *seama) {
printf("Meta entry:\t%s\n", tmp);
}
- fseek(seama, imagesize, SEEK_CUR);
+ oseama_skip(seama, imagesize);
+ *pos += imagesize;
i++;
}
@@ -139,6 +182,7 @@ static int oseama_info(int argc, char **argv) {
uint16_t metasize;
uint32_t imagesize;
uint8_t buf[1024];
+ size_t pos = 0;
int err = 0;
if (argc < 3) {
@@ -151,7 +195,7 @@ static int oseama_info(int argc, char **argv) {
optind = 3;
oseama_info_parse_options(argc, argv);
- seama = fopen(seama_path, "r");
+ seama = oseama_open(seama_path, "r");
if (!seama) {
fprintf(stderr, "Couldn't open %s\n", seama_path);
err = -EACCES;
@@ -164,6 +208,8 @@ static int oseama_info(int argc, char **argv) {
err = -EIO;
goto err_close;
}
+ pos += bytes;
+
metasize = be16_to_cpu(hdr.metasize);
imagesize = be32_to_cpu(hdr.imagesize);
@@ -191,6 +237,7 @@ static int oseama_info(int argc, char **argv) {
err = -EIO;
goto err_close;
}
+ pos += bytes;
if (entity_idx < 0) {
char *end, *tmp;
@@ -205,10 +252,10 @@ static int oseama_info(int argc, char **argv) {
}
}
- oseama_info_entities(seama);
+ oseama_info_entities(seama, &pos);
err_close:
- fclose(seama);
+ oseama_close(seama);
out:
return err;
}
@@ -424,14 +471,18 @@ static int oseama_extract_entity(FILE *seama, FILE *out) {
imagesize = be32_to_cpu(hdr.imagesize);
if (i != entity_idx) {
- fseek(seama, metasize + imagesize, SEEK_CUR);
+ oseama_skip(seama, metasize + imagesize);
i++;
continue;
}
- fseek(seama, -sizeof(hdr), SEEK_CUR);
+ if (fwrite(&hdr, 1, sizeof(hdr), out) != sizeof(hdr)) {
+ fprintf(stderr, "Couldn't write %zu B to %s\n", sizeof(hdr), out_path);
+ err = -EIO;
+ break;
+ }
- length = sizeof(hdr) + metasize + imagesize;
+ length = metasize + imagesize;
while ((bytes = fread(buf, 1, oseama_min(sizeof(buf), length), seama)) > 0) {
if (fwrite(buf, 1, bytes, out) != bytes) {
fprintf(stderr, "Couldn't write %zu B to %s\n", bytes, out_path);
@@ -480,7 +531,7 @@ static int oseama_extract(int argc, char **argv) {
goto out;
}
- seama = fopen(seama_path, "r");
+ seama = oseama_open(seama_path, "r");
if (!seama) {
fprintf(stderr, "Couldn't open %s\n", seama_path);
err = -EACCES;
@@ -502,14 +553,14 @@ static int oseama_extract(int argc, char **argv) {
}
metasize = be16_to_cpu(hdr.metasize);
- fseek(seama, metasize, SEEK_CUR);
+ oseama_skip(seama, metasize);
oseama_extract_entity(seama, out);
err_close_out:
fclose(out);
err_close_seama:
- fclose(seama);
+ oseama_close(seama);
out:
return err;
}
--
2.31.1
More information about the openwrt-devel
mailing list