]> www.infradead.org Git - mtd-utils.git/commitdiff
ubi-utils: various clean-ups and preparations
authorArtem Bityutskiy <Artem.Bityutskiy@nokia.com>
Sun, 20 Apr 2008 15:14:37 +0000 (18:14 +0300)
committerArtem Bityutskiy <Artem.Bityutskiy@nokia.com>
Sun, 20 Apr 2008 15:14:37 +0000 (18:14 +0300)
This patch introduces many clean-ups, nicifications and preparations
to the following ubiformat utility. There are also fixes.

Signed-off-by: Artem Bityutskiy <Artem.Bityutskiy@nokia.com>
ubi-utils/new-utils/include/libubi.h
ubi-utils/new-utils/include/libubigen.h
ubi-utils/new-utils/src/common.h
ubi-utils/new-utils/src/libubi.c
ubi-utils/new-utils/src/libubigen.c
ubi-utils/new-utils/src/ubiattach.c
ubi-utils/new-utils/src/ubinize.c

index 3e8c55a2b16759677eea952ee30fe5d9afd072ce..0f5c9c8b2ee261672862ef4102e164a77562d488 100644 (file)
@@ -194,6 +194,17 @@ void libubi_close(libubi_t desc);
  */
 int ubi_get_info(libubi_t desc, struct ubi_info *info);
 
+/**
+ * mtd_num2ubi_dev - find UBI device by attached MTD device.
+ * @@desc: UBI library descriptor
+ * @mtd_num: MTD device number
+ * @dev_num: UBI device number is returned here
+ *
+ * This function finds UBI device to which MTD device @mtd_num is attached.
+ * Returns %0 if the UBI device was found and %-1 if not.
+ */
+int mtd_num2ubi_dev(libubi_t desc, int mtd_num, int *dev_num);
+
 /**
  * ubi_attach_mtd - attach MTD device to UBI.
  * @desc: UBI library descriptor
index 058cf8ab4ff5256de8cab254dfd88f0ac610105f..c2b95b001913ca91dd9df255ca9945231157d484 100644 (file)
@@ -26,8 +26,6 @@
 #define __LIBUBIGEN_H__
 
 #include <stdint.h>
-#include <stdio.h>
-#include <mtd_swab.h>
 
 #ifdef __cplusplus
 extern "C" {
@@ -41,7 +39,6 @@ extern "C" {
  * @vid_hdr_offs: offset of the VID header
  * @data_offs: data offset
  * @ubi_ver: UBI version
- * @ec: initial erase counter
  * @vtbl_size: volume table size
  * @max_volumes: maximum amount of volumes
  */
@@ -53,7 +50,6 @@ struct ubigen_info
        int vid_hdr_offs;
        int data_offs;
        int ubi_ver;
-       long long ec;
        int vtbl_size;
        int max_volumes;
 };
@@ -92,18 +88,20 @@ struct ubigen_vol_info
 };
 
 void ubigen_info_init(struct ubigen_info *ui, int peb_size, int min_io_size,
-                     int subpage_size, int vid_hdr_offs, int ubi_ver,
-                     long long ec);
+                     int subpage_size, int vid_hdr_offs, int ubi_ver);
 struct ubi_vtbl_record *ubigen_create_empty_vtbl(const struct ubigen_info *ui);
+void ubigen_init_ec_hdr(const struct ubigen_info *ui,
+                       struct ubi_ec_hdr *hdr, long long ec);
 int ubigen_get_vtbl_size(const struct ubigen_info *ui);
 int ubigen_add_volume(const struct ubigen_info *ui,
                      const struct ubigen_vol_info *vi,
                      struct ubi_vtbl_record *vtbl);
 int ubigen_write_volume(const struct ubigen_info *ui,
-                       const struct ubigen_vol_info *vi,
-                       long long bytes, FILE *in, FILE *out);
-int ubigen_write_layout_vol(const struct ubigen_info *ui,
-                           struct ubi_vtbl_record *vtbl, FILE *out);
+                       const struct ubigen_vol_info *vi, long long ec,
+                       long long bytes, int in, int out);
+int ubigen_write_layout_vol(const struct ubigen_info *ui, int peb1, int peb2,
+                           long long ec1, long long ec2,
+                           struct ubi_vtbl_record *vtbl, int fd);
 
 #ifdef __cplusplus
 }
index bd99341c8a6a72629c55883ed66de3593d067199..720dec105ffc9997eac3d3e329648f199f610026 100644 (file)
@@ -43,24 +43,29 @@ extern "C" {
 #define normsg_cont(fmt, ...) do {                    \
        printf(PROGRAM_NAME ": " fmt, ##__VA_ARGS__); \
 } while(0)
+#define normsg_cont(fmt, ...) do {                         \
+       printf(PROGRAM_NAME ": " fmt, ##__VA_ARGS__);      \
+} while(0)
 
 /* Error messages */
-#define errmsg(fmt, ...)  ({                                              \
-       fprintf(stderr, PROGRAM_NAME " error: " fmt "\n", ##__VA_ARGS__); \
-       -1;                                                               \
+#define errmsg(fmt, ...)  ({                                                \
+       fprintf(stderr, PROGRAM_NAME ": error!: " fmt "\n", ##__VA_ARGS__); \
+       -1;                                                                 \
 })
 
 /* System error messages */
-#define sys_errmsg(fmt, ...)  ({                                          \
-       int _err = errno;                                                 \
-       fprintf(stderr, PROGRAM_NAME " error: " fmt "\n", ##__VA_ARGS__); \
-       fprintf(stderr, "error %d (%s)\n", _err, strerror(_err));         \
-       -1;                                                               \
+#define sys_errmsg(fmt, ...)  ({                                            \
+       int _err = errno, _i;                                               \
+       fprintf(stderr, PROGRAM_NAME ": error!: " fmt "\n", ##__VA_ARGS__); \
+       for (_i = 0; _i < sizeof(PROGRAM_NAME) + 1; _i++)                   \
+               fprintf(stderr, " ");                                       \
+       fprintf(stderr, "error %d (%s)\n", _err, strerror(_err));           \
+       -1;                                                                 \
 })
 
 /* Warnings */
-#define warnmsg(fmt, ...) do {                                              \
-       fprintf(stderr, PROGRAM_NAME " warning: " fmt "\n", ##__VA_ARGS__); \
+#define warnmsg(fmt, ...) do {                                                \
+       fprintf(stderr, PROGRAM_NAME ": warning!: " fmt "\n", ##__VA_ARGS__); \
 } while(0)
 
 long long ubiutils_get_bytes(const char *str);
index 5e6f9b1b595f55dd2b6c77effa3abeea55b8cbb3..8f951083339ecbf8fd627caa3760496a7e6e78d1 100644 (file)
@@ -477,12 +477,13 @@ static int dev_node2num(struct libubi *lib, const char *node, int *dev_num)
        return -1;
 }
 
-static int mtd_num2ubi_dev(struct libubi *lib, int mtd_num, int *dev_num)
+int mtd_num2ubi_dev(libubi_t desc, int mtd_num, int *dev_num)
 {
        struct ubi_info info;
        int i, ret, mtd_num1;
+       struct libubi *lib = desc;
 
-       if (ubi_get_info((libubi_t *)lib, &info))
+       if (ubi_get_info(desc, &info))
                return -1;
 
        for (i = info.lowest_dev_num; i <= info.highest_dev_num; i++) {
@@ -500,7 +501,7 @@ static int mtd_num2ubi_dev(struct libubi *lib, int mtd_num, int *dev_num)
                }
        }
 
-       errno = ENODEV;
+       errno = 0;
        return -1;
 }
 
@@ -714,8 +715,10 @@ int ubi_detach_mtd(libubi_t desc, const char *node, int mtd_num)
        int ret, ubi_dev;
 
        ret = mtd_num2ubi_dev(desc, mtd_num, &ubi_dev);
-       if (ret == -1)
+       if (ret == -1) {
+               errno = ENODEV;
                return ret;
+       }
 
        return ubi_remove_dev(desc, node, ubi_dev);
 }
index bee6f77e2dced20088977fd171d408741b7c7e9c..70ef0cae0f9f81f2429f8e54d5358489f971793b 100644 (file)
 
 #include <stdlib.h>
 #include <stdint.h>
-#include <stdio.h>
 #include <unistd.h>
 #include <string.h>
 
 #include <mtd/ubi-header.h>
+#include <mtd_swab.h>
 #include <libubigen.h>
 #include "crc32.h"
 #include "common.h"
  *                @min_io_size if does not exist)
  * @vid_hdr_offs: offset of the VID header
  * @ubi_ver: UBI version
- * @ec: initial erase counter
  */
 void ubigen_info_init(struct ubigen_info *ui, int peb_size, int min_io_size,
-                     int subpage_size, int vid_hdr_offs, int ubi_ver,
-                     long long ec)
+                     int subpage_size, int vid_hdr_offs, int ubi_ver)
 {
        if (!vid_hdr_offs) {
                vid_hdr_offs = UBI_EC_HDR_SIZE + subpage_size - 1;
@@ -66,12 +64,11 @@ void ubigen_info_init(struct ubigen_info *ui, int peb_size, int min_io_size,
        ui->data_offs *= min_io_size;
        ui->leb_size = peb_size - ui->data_offs;
        ui->ubi_ver = ubi_ver;
-       ui->ec = ec;
 
-       ui->vtbl_size = ui->leb_size;
-       if (ui->vtbl_size > UBI_MAX_VOLUMES * UBI_VTBL_RECORD_SIZE)
-               ui->vtbl_size = UBI_MAX_VOLUMES * UBI_VTBL_RECORD_SIZE;
-       ui->max_volumes = ui->vtbl_size / UBI_VTBL_RECORD_SIZE;
+       ui->max_volumes = ui->leb_size / UBI_VTBL_RECORD_SIZE;
+       if (ui->max_volumes > UBI_MAX_VOLUMES)
+               ui->max_volumes = UBI_MAX_VOLUMES;
+       ui->vtbl_size = ui->max_volumes * UBI_VTBL_RECORD_SIZE;
 }
 
 /**
@@ -88,11 +85,11 @@ struct ubi_vtbl_record *ubigen_create_empty_vtbl(const struct ubigen_info *ui)
 
        vtbl = calloc(1, ui->vtbl_size);
        if (!vtbl) {
-               errmsg("cannot allocate %d bytes of memory", ui->vtbl_size);
+               sys_errmsg("cannot allocate %d bytes of memory", ui->vtbl_size);
                return NULL;
        }
 
-       for (i = 0; i < UBI_MAX_VOLUMES; i++) {
+       for (i = 0; i < ui->max_volumes; i++) {
                uint32_t crc = crc32(UBI_CRC32_INIT, &vtbl[i],
                                     UBI_VTBL_RECORD_SIZE_CRC);
                vtbl[i].crc = cpu_to_be32(crc);
@@ -144,12 +141,13 @@ int ubigen_add_volume(const struct ubigen_info *ui,
 }
 
 /**
- * init_ec_hdr - initialize EC header.
+ * ubigen_init_ec_hdr - initialize EC header.
  * @ui: libubigen information
  * @hdr: the EC header to initialize
+ * @ec: erase counter value
  */
-static void init_ec_hdr(const struct ubigen_info *ui,
-                       struct ubi_ec_hdr *hdr)
+void ubigen_init_ec_hdr(const struct ubigen_info *ui,
+                       struct ubi_ec_hdr *hdr, long long ec)
 {
        uint32_t crc;
 
@@ -157,7 +155,7 @@ static void init_ec_hdr(const struct ubigen_info *ui,
 
        hdr->magic = cpu_to_be32(UBI_EC_HDR_MAGIC);
        hdr->version = ui->ubi_ver;
-       hdr->ec = cpu_to_be64(ui->ec);
+       hdr->ec = cpu_to_be64(ec);
        hdr->vid_hdr_offset = cpu_to_be32(ui->vid_hdr_offs);
 
        hdr->data_offset = cpu_to_be32(ui->data_offs);
@@ -210,6 +208,7 @@ static void init_vid_hdr(const struct ubigen_info *ui,
  * ubigen_write_volume - write UBI volume.
  * @ui: libubigen information
  * @vi: volume information
+ * @ec: erase coutner value to put to EC headers
  * @bytes: volume size in bytes
  * @in: input file descriptor (has to be properly seeked)
  * @out: output file descriptor
@@ -219,8 +218,8 @@ static void init_vid_hdr(const struct ubigen_info *ui,
  * %-1 on failure.
  */
 int ubigen_write_volume(const struct ubigen_info *ui,
-                       const struct ubigen_vol_info *vi,
-                       long long bytes, FILE *in, FILE *out)
+                       const struct ubigen_vol_info *vi, long long ec,
+                       long long bytes, int in, int out)
 {
        int len = vi->usable_leb_size, rd, lnum = 0;
        char inbuf[ui->leb_size], outbuf[ui->peb_size];
@@ -234,7 +233,7 @@ int ubigen_write_volume(const struct ubigen_info *ui,
                              vi->alignment, ui->leb_size);
 
        memset(outbuf, 0xFF, ui->data_offs);
-       init_ec_hdr(ui, (struct ubi_ec_hdr *)outbuf);
+       ubigen_init_ec_hdr(ui, (struct ubi_ec_hdr *)outbuf, ec);
 
        while (bytes) {
                int l;
@@ -246,13 +245,9 @@ int ubigen_write_volume(const struct ubigen_info *ui,
 
                l = len;
                do {
-                       rd = fread(inbuf + len - l, 1, l, in);
-                       if (rd == 0) {
-                               if (ferror(in))
-                                       return errmsg("cannot read %d bytes from the input file", l);
-                               else
-                                       return errmsg("not enough data in the input file");
-                       }
+                       rd = read(in, inbuf + len - l, l);
+                       if (rd != l)
+                               return sys_errmsg("cannot read %d bytes from the input file", l);
 
                        l -= rd;
                } while (l);
@@ -264,8 +259,8 @@ int ubigen_write_volume(const struct ubigen_info *ui,
                memset(outbuf + ui->data_offs + len, 0xFF,
                       ui->peb_size - ui->data_offs - len);
 
-               if (fwrite(outbuf, 1, ui->peb_size, out) != ui->peb_size)
-                       return errmsg("cannot write %d bytes from the output file", l);
+               if (write(out, outbuf, ui->peb_size) != ui->peb_size)
+                       return sys_errmsg("cannot write %d bytes to the output file", ui->peb_size);
 
                lnum += 1;
        }
@@ -276,27 +271,30 @@ int ubigen_write_volume(const struct ubigen_info *ui,
 /**
  * ubigen_write_layout_vol - write UBI layout volume
  * @ui: libubigen information
+ * @peb1: physical eraseblock number to write the first volume table copy
+ * @peb2: physical eraseblock number to write the second volume table copy
+ * @ec1: erase counter value for @peb1
+ * @ec2: erase counter value for @peb1
  * @vtbl: volume table
- * @out: output file stream
+ * @fd: output file descriptor seeked to the proper position
  *
  * This function creates the UBI layout volume which contains 2 copies of the
  * volume table. Returns zero in case of success and %-1 in case of failure.
  */
-int ubigen_write_layout_vol(const struct ubigen_info *ui,
-                           struct ubi_vtbl_record *vtbl, FILE *out)
+int ubigen_write_layout_vol(const struct ubigen_info *ui, int peb1, int peb2,
+                           long long ec1, long long ec2,
+                           struct ubi_vtbl_record *vtbl, int fd)
 {
-       int size = ui->leb_size;
+       int ret;
        struct ubigen_vol_info vi;
        char outbuf[ui->peb_size];
        struct ubi_vid_hdr *vid_hdr;
-
-       if (size > UBI_MAX_VOLUMES * UBI_VTBL_RECORD_SIZE)
-               size = UBI_MAX_VOLUMES * UBI_VTBL_RECORD_SIZE;
+       off_t seek;
 
        vi.bytes = ui->leb_size * UBI_LAYOUT_VOLUME_EBS;
        vi.id = UBI_LAYOUT_VOLUME_ID;
        vi.alignment = UBI_LAYOUT_VOLUME_ALIGN;
-       vi.data_pad =  ui->leb_size % UBI_LAYOUT_VOLUME_ALIGN;
+       vi.data_pad = ui->leb_size % UBI_LAYOUT_VOLUME_ALIGN;
        vi.usable_leb_size = ui->leb_size - vi.data_pad;
        vi.data_pad = ui->leb_size - vi.usable_leb_size;
        vi.type = UBI_LAYOUT_VOLUME_TYPE;
@@ -306,19 +304,27 @@ int ubigen_write_layout_vol(const struct ubigen_info *ui,
 
        memset(outbuf, 0xFF, ui->data_offs);
        vid_hdr = (struct ubi_vid_hdr *)(&outbuf[ui->vid_hdr_offs]);
-       init_ec_hdr(ui, (struct ubi_ec_hdr *)outbuf);
-       memcpy(outbuf + ui->data_offs, vtbl, size);
-       memset(outbuf + ui->data_offs + size, 0xFF,
-              ui->peb_size - ui->data_offs - size);
-
+       memcpy(outbuf + ui->data_offs, vtbl, ui->vtbl_size);
+       memset(outbuf + ui->data_offs + ui->vtbl_size, 0xFF,
+              ui->peb_size - ui->data_offs - ui->vtbl_size);
+
+       seek = peb1 * ui->peb_size;
+       if (lseek(fd, seek, SEEK_SET) != seek)
+               return sys_errmsg("cannot seek output file");
+       ubigen_init_ec_hdr(ui, (struct ubi_ec_hdr *)outbuf, ec1);
        init_vid_hdr(ui, &vi, vid_hdr, 0, NULL, 0);
-       size = fwrite(outbuf, 1, ui->peb_size, out);
-       if (size == ui->peb_size) {
-               init_vid_hdr(ui, &vi, vid_hdr, 1, NULL, 0);
-               size = fwrite(outbuf, 1, ui->peb_size, out);
-               if (size != ui->peb_size)
-                       return sys_errmsg("cannot write %d bytes", ui->peb_size);
-       }
+       ret = write(fd, outbuf, ui->peb_size);
+       if (ret != ui->peb_size)
+               return sys_errmsg("cannot write %d bytes", ui->peb_size);
+
+       seek = peb2 * ui->peb_size;
+       if (lseek(fd, seek, SEEK_SET) != seek)
+               return sys_errmsg("cannot seek output file");
+       ubigen_init_ec_hdr(ui, (struct ubi_ec_hdr *)outbuf, ec2);
+       init_vid_hdr(ui, &vi, vid_hdr, 1, NULL, 0);
+       ret = write(fd, outbuf, ui->peb_size);
+       if (ret != ui->peb_size)
+               return sys_errmsg("cannot write %d bytes", ui->peb_size);
 
        return 0;
 }
index 04a2f9c447ed2bb865e545d29e2e09ac3470a0f1..3e19ecaf39d516092465596a315cbba93d2551e7 100644 (file)
@@ -84,7 +84,7 @@ static int parse_opt(int argc, char * const argv[])
                int key;
                char *endp;
 
-               key = getopt_long(argc, argv, "m:d:OhV", long_options, NULL);
+               key = getopt_long(argc, argv, "m:d:O:hV", long_options, NULL);
                if (key == -1)
                        break;
 
@@ -103,7 +103,7 @@ static int parse_opt(int argc, char * const argv[])
 
                        break;
 
-               case 'o':
+               case 'O':
                        args.vidoffs = strtoul(optarg, &endp, 0);
                        if (*endp != '\0' || endp == optarg || args.vidoffs <= 0)
                                return errmsg("bad VID header offset: \"%s\"", optarg);
index bd1b07b22511eda8b957b8ea410c47aef977ef80..dab224be1ea96074f42077632ee4f21eac5fd20f 100644 (file)
  *          Oliver Lohmann
  */
 
+#include <sys/stat.h>
+#include <sys/types.h>
+#include <sys/stat.h>
 #include <stdlib.h>
 #include <getopt.h>
-#include <stdio.h>
 #include <string.h>
 #include <unistd.h>
-#include <sys/stat.h>
+#include <fcntl.h>
 
 #include <mtd/ubi-header.h>
 #include <libubigen.h>
@@ -49,7 +51,7 @@ static const char *doc = PROGRAM_NAME " version " PROGRAM_VERSION
 "parameters, do not specify them and let the utility to use default values.";
 
 static const char *optionsstr =
-"-o, --output=<file name>     output file name (default is stdout)\n"
+"-o, --output=<file name>     output file name\n"
 "-p, --peb-size=<bytes>       size of the physical eraseblock of the flash\n"
 "                             this UBI image is created for in bytes,\n"
 "                             kilobytes (KiB), or megabytes (MiB)\n"
@@ -61,14 +63,14 @@ static const char *optionsstr =
 "                             flash (equivalent to the minimum input/output\n"
 "                             unit size by default)\n"
 "-O, --vid-hdr-offset=<num>   offset if the VID header from start of the\n"
-"                             physical eraseblock (default is the second\n"
-"                             minimum I/O unit or sub-page, if it was\n"
-"                             specified)\n"
+"                             physical eraseblock (default is the next\n"
+"                             minimum I/O unit or sub-page after the EC\n"
+"                             header)\n"
 "-e, --erase-counter=<num>    the erase counter value to put to EC headers\n"
 "                             (default is 0)\n"
 "-x, --ubi-ver=<num>          UBI version number to put to EC headers\n"
 "                             (default is 1)\n"
-"-v  --verbose                be verbose\n"
+"-v, --verbose                be verbose\n"
 "-h, --help                   print help message\n"
 "-V, --version                print program version";
 
@@ -128,7 +130,7 @@ struct option long_options[] = {
 struct args {
        const char *f_in;
        const char *f_out;
-       FILE *fp_out;
+       int out_fd;
        int peb_size;
        int min_io_size;
        int subpage_size;
@@ -140,14 +142,10 @@ struct args {
 };
 
 static struct args args = {
-       .f_out        = NULL,
        .peb_size     = -1,
        .min_io_size  = -1,
        .subpage_size = -1,
-       .vid_hdr_offs = 0,
-       .ec           = 0,
        .ubi_ver      = 1,
-       .verbose      = 0,
 };
 
 static int parse_opt(int argc, char * const argv[])
@@ -162,9 +160,10 @@ static int parse_opt(int argc, char * const argv[])
 
                switch (key) {
                case 'o':
-                       args.fp_out = fopen(optarg, "wb");
-                       if (!args.fp_out)
-                               return errmsg("cannot open file \"%s\"", optarg);
+                       args.out_fd = open(optarg, O_CREAT | O_TRUNC | O_WRONLY,
+                                          S_IWUSR | S_IRUSR | S_IRGRP | S_IWGRP | S_IROTH);
+                       if (args.out_fd == -1)
+                               return sys_errmsg("cannot open file \"%s\"", optarg);
                        args.f_out = optarg;
                        break;
 
@@ -242,16 +241,14 @@ static int parse_opt(int argc, char * const argv[])
        if (args.subpage_size < 0)
                args.subpage_size = args.min_io_size;
 
-       if (!args.f_out) {
-               args.f_out = "stdout";
-               args.fp_out = stdout;
-       }
+       if (!args.f_out)
+               return errmsg("output file was not specified (use -h for help)");
 
        return 0;
 }
 
-int read_section(const char *sname, struct ubigen_vol_info *vi,
-                const char **img)
+static int read_section(const char *sname, struct ubigen_vol_info *vi,
+                       const char **img)
 {
        char buf[256];
        const char *p;
@@ -401,6 +398,7 @@ int main(int argc, char * const argv[])
        int err = -1, sects, i, volumes;
        struct ubigen_info ui;
        struct ubi_vtbl_record *vtbl;
+       off_t seek;
 
        err = parse_opt(argc, argv);
        if (err)
@@ -408,7 +406,7 @@ int main(int argc, char * const argv[])
 
        ubigen_info_init(&ui, args.peb_size, args.min_io_size,
                         args.subpage_size, args.vid_hdr_offs,
-                        args.ubi_ver, args.ec);
+                        args.ubi_ver);
 
        verbose(args.verbose, "LEB size:    %d", ui.leb_size);
        verbose(args.verbose, "PEB size:    %d", ui.peb_size);
@@ -444,8 +442,9 @@ int main(int argc, char * const argv[])
         * Skip 2 PEBs at the beginning of the file for the volume table which
         * will be written later.
         */
-       if (fseek(args.fp_out, ui.peb_size * 2, SEEK_SET) == -1) {
-               errmsg("cannot seek file \"%s\"", args.f_out);
+       seek = ui.peb_size * 2;
+       if (lseek(args.out_fd, seek, SEEK_SET) != seek) {
+               sys_errmsg("cannot seek file \"%s\"", args.f_out);
                goto out_dict;
        }
 
@@ -454,7 +453,7 @@ int main(int argc, char * const argv[])
                struct ubigen_vol_info vi;
                const char *img = NULL;
                struct stat st;
-               FILE *f;
+               int fd;
 
                if (!sname) {
                        errmsg("ini-file parsing error (iniparser_getsecname)");
@@ -472,6 +471,10 @@ int main(int argc, char * const argv[])
                        volumes += 1;
                init_vol_info(&ui, &vi);
 
+               if (vi.id >= ui.max_volumes)
+                       return errmsg("too high volume ID %d, max. is %d",
+                                     vi.id, ui.max_volumes);
+
                verbose(args.verbose, "adding volume %d", vi.id);
 
                err = ubigen_add_volume(&ui, &vi, vtbl);
@@ -498,8 +501,8 @@ int main(int argc, char * const argv[])
                        goto out_dict;
                }
 
-               f = fopen(img, "r");
-               if (!f) {
+               fd = open(img, O_RDONLY);
+               if (fd == -1) {
                        sys_errmsg("cannot open \"%s\"", img);
                        goto out_dict;
                }
@@ -507,8 +510,8 @@ int main(int argc, char * const argv[])
                verbose(args.verbose, "writing volume %d", vi.id);
                verbose(args.verbose, "image file: %s", img);
 
-               err = ubigen_write_volume(&ui, &vi, st.st_size, f, args.fp_out);
-               fclose(f);
+               err = ubigen_write_volume(&ui, &vi, args.ec, st.st_size, fd, args.out_fd);
+               close(fd);
                if (err) {
                        errmsg("cannot write volume for section \"%s\"", sname);
                        goto out_dict;
@@ -520,12 +523,7 @@ int main(int argc, char * const argv[])
 
        verbose(args.verbose, "writing layout volume");
 
-       if (fseek(args.fp_out, 0, SEEK_SET) == -1) {
-               errmsg("cannot seek file \"%s\"", args.f_out);
-               goto out_dict;
-       }
-
-       err = ubigen_write_layout_vol(&ui, vtbl, args.fp_out);
+       err = ubigen_write_layout_vol(&ui, 0, 1, args.ec, args.ec, vtbl, args.out_fd);
        if (err) {
                errmsg("cannot write layout volume");
                goto out_dict;
@@ -535,7 +533,7 @@ int main(int argc, char * const argv[])
 
        iniparser_freedict(args.dict);
        free(vtbl);
-       fclose(args.fp_out);
+       close(args.out_fd);
        return 0;
 
 out_dict:
@@ -543,7 +541,7 @@ out_dict:
 out_vtbl:
        free(vtbl);
 out:
-       fclose(args.fp_out);
+       close(args.out_fd);
        remove(args.f_out);
        return err;
 }