+static int otrx_open_parse(const char *pathname, const char *mode,
+ struct otrx_ctx *otrx)
+{
+ size_t length;
+ size_t bytes;
+ int err;
+
+ otrx->fp = otrx_open(pathname, mode);
+ if (!otrx->fp) {
+ fprintf(stderr, "Couldn't open %s\n", pathname);
+ err = -EACCES;
+ goto err_out;
+ }
+
+ if (trx_offset && otrx_skip(otrx->fp, trx_offset)) {
+ fprintf(stderr, "Couldn't skip first %zd B\n", trx_offset);
+ err = -EIO;
+ goto err_close;
+ }
+
+ bytes = fread(&otrx->hdr, 1, sizeof(otrx->hdr), otrx->fp);
+ if (bytes != sizeof(otrx->hdr)) {
+ fprintf(stderr, "Couldn't read %s header\n", pathname);
+ err = -EIO;
+ goto err_close;
+ }
+
+ if (le32_to_cpu(otrx->hdr.magic) != TRX_MAGIC) {
+ fprintf(stderr, "Invalid TRX magic: 0x%08x\n", le32_to_cpu(otrx->hdr.magic));
+ err = -EINVAL;
+ goto err_close;
+ }
+
+ length = le32_to_cpu(otrx->hdr.length);
+ if (length < sizeof(otrx->hdr)) {
+ fprintf(stderr, "Length read from TRX too low (%zu B)\n", length);
+ err = -EINVAL;
+ goto err_close;
+ }
+
+ return 0;
+
+err_close:
+ otrx_close(otrx->fp);
+err_out:
+ return err;
+}
+