From 9c37b558705b776e51f7d522f376de019a6ea203 Mon Sep 17 00:00:00 2001
From: Adrian Hunter <ext-adrian.hunter@nokia.com>
Date: Wed, 21 Mar 2007 11:53:25 +0200
Subject: UBI-Utils: Convert to new ubi library

Signed-off-by: Adrian Hunter <ext-adrian.hunter@nokia.com>
---
 ubi-utils/src/libpfiflash.c     |   2 +-
 ubi-utils/src/libubi.c          | 917 ++++++++++++++++++++++++++++++++++++++++
 ubi-utils/src/libubi_int.h      | 129 ++++++
 ubi-utils/src/libubimirror.c    |  10 +-
 ubi-utils/src/libubiold.c       |   6 +-
 ubi-utils/src/libubiold_sysfs.c |   2 +-
 ubi-utils/src/pddcustomize.c    |   2 +-
 ubi-utils/src/reader.c          |  13 +-
 ubi-utils/src/ubimkvol.c        |  33 +-
 ubi-utils/src/ubirmvol.c        |  24 +-
 ubi-utils/src/ubiupdatevol.c    |  46 +-
 11 files changed, 1129 insertions(+), 55 deletions(-)
 create mode 100644 ubi-utils/src/libubi.c
 create mode 100644 ubi-utils/src/libubi_int.h

(limited to 'ubi-utils/src')

diff --git a/ubi-utils/src/libpfiflash.c b/ubi-utils/src/libpfiflash.c
index 4dfafea..4f1f5cd 100644
--- a/ubi-utils/src/libpfiflash.c
+++ b/ubi-utils/src/libpfiflash.c
@@ -36,7 +36,7 @@
 #include <stdlib.h>
 #include <sys/ioctl.h>
 
-#include <libubi.h>
+#include <libubiold.h>
 #include <pfiflash.h>
 
 #include <mtd/ubi-user.h>	/* FIXME Is this ok here? */
diff --git a/ubi-utils/src/libubi.c b/ubi-utils/src/libubi.c
new file mode 100644
index 0000000..17ab4ee
--- /dev/null
+++ b/ubi-utils/src/libubi.c
@@ -0,0 +1,917 @@
+/*
+ * Copyright (c) International Business Machines Corp., 2006
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See
+ * the GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ *
+ * Author: Artem B. Bityutskiy
+ *
+ * UBI (Unsorted Block Images) library.
+ */
+
+#include <stdlib.h>
+#include <stdio.h>
+#include <string.h>
+#include <fcntl.h>
+#include <sys/stat.h>
+#include <sys/types.h>
+#include <dirent.h>
+#include <errno.h>
+#include <unistd.h>
+#include <sys/ioctl.h>
+#include <limits.h>
+#include "libubi.h"
+#include "libubi_int.h"
+
+libubi_t libubi_open(void)
+{
+	int fd, version;
+	struct libubi *lib;
+
+	lib = calloc(1, sizeof(struct libubi));
+	if (!lib)
+		return NULL;
+
+	/* TODO: this must be discovered instead */
+	lib->sysfs = strdup("/sys");
+	if (!lib->sysfs)
+		goto error;
+
+	lib->sysfs_ubi = mkpath(lib->sysfs, SYSFS_UBI);
+	if (!lib->sysfs_ubi)
+		goto error;
+
+	/* Make sure UBI is present */
+	fd = open(lib->sysfs_ubi, O_RDONLY);
+	if (fd == -1)
+		goto error;
+	close(fd);
+
+	lib->ubi_dev = mkpath(lib->sysfs_ubi, UBI_DEV_NAME_PATT);
+	if (!lib->ubi_dev)
+		goto error;
+
+	lib->ubi_version = mkpath(lib->sysfs_ubi, UBI_VER);
+	if (!lib->ubi_version)
+		goto error;
+
+	lib->dev_dev = mkpath(lib->ubi_dev, DEV_DEV);
+	if (!lib->dev_dev)
+		goto error;
+
+	lib->dev_avail_ebs = mkpath(lib->ubi_dev, DEV_AVAIL_EBS);
+	if (!lib->dev_avail_ebs)
+		goto error;
+
+	lib->dev_total_ebs = mkpath(lib->ubi_dev, DEV_TOTAL_EBS);
+	if (!lib->dev_total_ebs)
+		goto error;
+
+	lib->dev_bad_count = mkpath(lib->ubi_dev, DEV_BAD_COUNT);
+	if (!lib->dev_bad_count)
+		goto error;
+
+	lib->dev_eb_size = mkpath(lib->ubi_dev, DEV_EB_SIZE);
+	if (!lib->dev_eb_size)
+		goto error;
+
+	lib->dev_max_ec = mkpath(lib->ubi_dev, DEV_MAX_EC);
+	if (!lib->dev_max_ec)
+		goto error;
+
+	lib->dev_bad_rsvd = mkpath(lib->ubi_dev, DEV_MAX_RSVD);
+	if (!lib->dev_bad_rsvd)
+		goto error;
+
+	lib->dev_max_vols = mkpath(lib->ubi_dev, DEV_MAX_VOLS);
+	if (!lib->dev_max_vols)
+		goto error;
+
+	lib->dev_min_io_size = mkpath(lib->ubi_dev, DEV_MIN_IO_SIZE);
+	if (!lib->dev_min_io_size)
+		goto error;
+
+	lib->ubi_vol = mkpath(lib->sysfs_ubi, UBI_VOL_NAME_PATT);
+	if (!lib->ubi_vol)
+		goto error;
+
+	lib->vol_type = mkpath(lib->ubi_vol, VOL_TYPE);
+	if (!lib->vol_type)
+		goto error;
+
+	lib->vol_dev = mkpath(lib->ubi_vol, VOL_DEV);
+	if (!lib->vol_dev)
+		goto error;
+
+	lib->vol_alignment = mkpath(lib->ubi_vol, VOL_ALIGNMENT);
+	if (!lib->vol_alignment)
+		goto error;
+
+	lib->vol_data_bytes = mkpath(lib->ubi_vol, VOL_DATA_BYTES);
+	if (!lib->vol_data_bytes)
+		goto error;
+
+	lib->vol_rsvd_ebs = mkpath(lib->ubi_vol, VOL_RSVD_EBS);
+	if (!lib->vol_rsvd_ebs)
+		goto error;
+
+	lib->vol_eb_size = mkpath(lib->ubi_vol, VOL_EB_SIZE);
+	if (!lib->vol_eb_size)
+		goto error;
+
+	lib->vol_corrupted = mkpath(lib->ubi_vol, VOL_CORRUPTED);
+	if (!lib->vol_corrupted)
+		goto error;
+
+	lib->vol_name = mkpath(lib->ubi_vol, VOL_NAME);
+	if (!lib->vol_name)
+		goto error;
+
+	if (read_int(lib->ubi_version, &version))
+		goto error;
+	if (version != LIBUBI_UBI_VERSION) {
+		fprintf(stderr, "LIBUBI: this library was made for UBI version "
+				"%d, but UBI version %d is detected\n",
+			LIBUBI_UBI_VERSION, version);
+		goto error;
+	}
+
+	return lib;
+
+error:
+	free(lib->vol_corrupted);
+	free(lib->vol_eb_size);
+	free(lib->vol_rsvd_ebs);
+	free(lib->vol_data_bytes);
+	free(lib->vol_alignment);
+	free(lib->vol_dev);
+	free(lib->vol_type);
+	free(lib->ubi_vol);
+	free(lib->dev_min_io_size);
+	free(lib->dev_max_vols);
+	free(lib->dev_bad_rsvd);
+	free(lib->dev_max_ec);
+	free(lib->dev_eb_size);
+	free(lib->dev_bad_count);
+	free(lib->dev_total_ebs);
+	free(lib->dev_avail_ebs);
+	free(lib->dev_dev);
+	free(lib->ubi_version);
+	free(lib->ubi_dev);
+	free(lib->sysfs_ubi);
+	free(lib->sysfs);
+	free(lib);
+	return NULL;
+}
+
+void libubi_close(libubi_t desc)
+{
+	struct libubi *lib = (struct libubi *)desc;
+
+	free(lib->vol_name);
+	free(lib->vol_corrupted);
+	free(lib->vol_eb_size);
+	free(lib->vol_rsvd_ebs);
+	free(lib->vol_data_bytes);
+	free(lib->vol_alignment);
+	free(lib->vol_dev);
+	free(lib->vol_type);
+	free(lib->ubi_vol);
+	free(lib->dev_min_io_size);
+	free(lib->dev_max_vols);
+	free(lib->dev_bad_rsvd);
+	free(lib->dev_max_ec);
+	free(lib->dev_eb_size);
+	free(lib->dev_bad_count);
+	free(lib->dev_total_ebs);
+	free(lib->dev_avail_ebs);
+	free(lib->dev_dev);
+	free(lib->ubi_version);
+	free(lib->ubi_dev);
+	free(lib->sysfs_ubi);
+	free(lib->sysfs);
+	free(lib);
+}
+
+int ubi_get_info(libubi_t desc, struct ubi_info *info)
+{
+	DIR *sysfs_ubi;
+	struct dirent *dirent;
+	struct libubi *lib = (struct libubi *)desc;
+
+	memset(info, '\0', sizeof(struct ubi_info));
+
+	/*
+	 * We have to scan the UBI sysfs directory to identify how many UBI
+	 * devices are present.
+	 */
+	sysfs_ubi = opendir(lib->sysfs_ubi);
+	if (!sysfs_ubi)
+		return -1;
+
+	info->lowest_dev_num = INT_MAX;
+	while ((dirent = readdir(sysfs_ubi))) {
+		char *name = &dirent->d_name[0];
+		int dev_num, ret;
+
+		ret = sscanf(name, UBI_DEV_NAME_PATT, &dev_num);
+		if (ret == 1) {
+			info->dev_count += 1;
+			if (dev_num > info->highest_dev_num)
+				info->highest_dev_num = dev_num;
+			if (dev_num < info->lowest_dev_num)
+				info->lowest_dev_num = dev_num;
+		}
+	}
+
+	if (info->lowest_dev_num == INT_MAX)
+		info->lowest_dev_num = 0;
+
+	if (read_int(lib->ubi_version, &info->version))
+		goto close;
+
+	return closedir(sysfs_ubi);
+
+close:
+	closedir(sysfs_ubi);
+	return -1;
+}
+
+int ubi_mkvol(libubi_t desc, const char *node, struct ubi_mkvol_request *req)
+{
+	int fd, ret;
+	struct ubi_mkvol_req r;
+	size_t n;
+
+	desc = desc;
+	r.vol_id = req->vol_id;
+	r.alignment = req->alignment;
+	r.bytes = req->bytes;
+	r.vol_type = req->vol_type;
+
+	n = strlen(req->name);
+	if (n > UBI_MAX_VOLUME_NAME)
+		return -1;
+
+	strncpy(r.name, req->name, UBI_MAX_VOLUME_NAME + 1);
+	r.name_len = n;
+
+	fd = open(node, O_RDONLY);
+	if (fd == -1)
+		return -1;
+
+	ret = ioctl(fd, UBI_IOCMKVOL, &r);
+
+	if (!ret)
+		req->vol_id = r.vol_id;
+
+	close(fd);
+	return ret;
+}
+
+int ubi_rmvol(libubi_t desc, const char *node, int vol_id)
+{
+	int fd, ret;
+
+	desc = desc;
+	fd = open(node, O_RDONLY);
+	if (fd == -1)
+		return -1;
+
+	ret = ioctl(fd, UBI_IOCRMVOL, &vol_id);
+	close(fd);
+	return ret;
+}
+
+int ubi_rsvol(libubi_t desc, const char *node, int vol_id, long long bytes)
+{
+	int fd, ret;
+	struct ubi_rsvol_req req;
+
+	desc = desc;
+	fd = open(node, O_RDONLY);
+	if (fd == -1)
+		return -1;
+
+	req.bytes = bytes;
+	req.vol_id = vol_id;
+
+	ret = ioctl(fd, UBI_IOCRSVOL, &req);
+	close(fd);
+	return ret;
+}
+
+int ubi_update_start(libubi_t desc, int fd, long long bytes)
+{
+	desc = desc;
+	if (ioctl(fd, UBI_IOCVOLUP, &bytes))
+		return -1;
+	return 0;
+}
+
+int ubi_get_dev_info(libubi_t desc, const char *node, struct ubi_dev_info *info)
+{
+	int dev_num;
+	struct libubi *lib = (struct libubi *)desc;
+
+	dev_num = find_dev_num(lib, node);
+	if (dev_num == -1)
+		return -1;
+
+	return ubi_get_dev_info1(desc, dev_num, info);
+}
+
+int ubi_get_dev_info1(libubi_t desc, int dev_num, struct ubi_dev_info *info)
+{
+	DIR *sysfs_ubi;
+	struct dirent *dirent;
+	struct libubi *lib = (struct libubi *)desc;
+
+	memset(info, '\0', sizeof(struct ubi_dev_info));
+	info->dev_num = dev_num;
+
+	sysfs_ubi = opendir(lib->sysfs_ubi);
+	if (!sysfs_ubi)
+		return -1;
+
+	info->lowest_vol_num = INT_MAX;
+	while ((dirent = readdir(sysfs_ubi))) {
+		char *name = &dirent->d_name[0];
+		int vol_id, ret, devno;
+
+		ret = sscanf(name, UBI_VOL_NAME_PATT, &devno, &vol_id);
+		if (ret == 2 && devno == dev_num) {
+			info->vol_count += 1;
+			if (vol_id > info->highest_vol_num)
+				info->highest_vol_num = vol_id;
+			if (vol_id < info->lowest_vol_num)
+				info->lowest_vol_num = vol_id;
+		}
+	}
+
+	closedir(sysfs_ubi);
+
+	if (info->lowest_vol_num == INT_MAX)
+		info->lowest_vol_num = 0;
+
+	if (dev_read_int(lib->dev_avail_ebs, dev_num, &info->avail_ebs))
+		return -1;
+	if (dev_read_int(lib->dev_total_ebs, dev_num, &info->total_ebs))
+		return -1;
+	if (dev_read_int(lib->dev_bad_count, dev_num, &info->bad_count))
+		return -1;
+	if (dev_read_int(lib->dev_eb_size, dev_num, &info->eb_size))
+		return -1;
+	if (dev_read_int(lib->dev_bad_rsvd, dev_num, &info->bad_rsvd))
+		return -1;
+	if (dev_read_ll(lib->dev_max_ec, dev_num, &info->max_ec))
+		return -1;
+	if (dev_read_int(lib->dev_max_vols, dev_num, &info->max_vol_count))
+		return -1;
+	if (dev_read_int(lib->dev_min_io_size, dev_num, &info->min_io_size))
+		return -1;
+
+	info->avail_bytes = info->avail_ebs * info->eb_size;
+	info->total_bytes = info->total_ebs * info->eb_size;
+
+	return 0;
+}
+
+int ubi_get_vol_info(libubi_t desc, const char *node, struct ubi_vol_info *info)
+{
+	int vol_id, dev_num;
+	struct libubi *lib = (struct libubi *)desc;
+
+	dev_num = find_dev_num_vol(lib, node);
+	if (dev_num == -1)
+		return -1;
+
+	vol_id = find_vol_num(lib, dev_num, node);
+	if (vol_id == -1)
+		return -1;
+
+	return ubi_get_vol_info1(desc, dev_num, vol_id, info);
+}
+
+int ubi_get_vol_info1(libubi_t desc, int dev_num, int vol_id,
+		      struct ubi_vol_info *info)
+{
+	int ret;
+	struct libubi *lib = (struct libubi *)desc;
+	char buf[50];
+
+	memset(info, '\0', sizeof(struct ubi_vol_info));
+	info->dev_num = dev_num;
+	info->vol_id = vol_id;
+
+	ret = vol_read_data(lib->vol_type, dev_num, vol_id, &buf[0], 50);
+	if (ret < 0)
+		return -1;
+
+	if (strncmp(&buf[0], "static\n", ret) == 0)
+		info->type = UBI_STATIC_VOLUME;
+	else if (strncmp(&buf[0], "dynamic\n", ret) == 0)
+		info->type = UBI_DYNAMIC_VOLUME;
+	else {
+		fprintf(stderr, "LIBUBI: bad value at sysfs file\n");
+		errno = EINVAL;
+		return -1;
+	}
+
+	ret = vol_read_int(lib->vol_alignment, dev_num, vol_id,
+			   &info->alignment);
+	if (ret)
+		return -1;
+	ret = vol_read_ll(lib->vol_data_bytes, dev_num, vol_id,
+			  &info->data_bytes);
+	if (ret)
+		return -1;
+	ret = vol_read_int(lib->vol_rsvd_ebs, dev_num, vol_id, &info->rsvd_ebs);
+	if (ret)
+		return -1;
+	ret = vol_read_int(lib->vol_eb_size, dev_num, vol_id, &info->eb_size);
+	if (ret)
+		return -1;
+	ret = vol_read_int(lib->vol_corrupted, dev_num, vol_id,
+			   &info->corrupted);
+	if (ret)
+		return -1;
+	info->rsvd_bytes = info->eb_size * info->rsvd_ebs;
+
+	ret = vol_read_data(lib->vol_name, dev_num, vol_id, &info->name,
+			    UBI_VOL_NAME_MAX + 2);
+	if (ret < 0)
+		return -1;
+
+	info->name[ret - 1] = '\0';
+
+	return 0;
+}
+
+/**
+ * read_int - read an 'int' value from a file.
+ *
+ * @file   the file to read from
+ * @value  the result is stored here
+ *
+ * This function returns %0 in case of success and %-1 in case of failure.
+ */
+static int read_int(const char *file, int *value)
+{
+	int fd, rd;
+	char buf[50];
+
+	fd = open(file, O_RDONLY);
+	if (fd == -1)
+		return -1;
+
+	rd = read(fd, &buf[0], 50);
+	if (rd == -1)
+		goto error;
+
+	if (sscanf(&buf[0], "%d\n", value) != 1) {
+		/* This must be a UBI bug */
+		fprintf(stderr, "LIBUBI: bad value at sysfs file\n");
+		errno = EINVAL;
+		goto error;
+	}
+
+	close(fd);
+	return 0;
+
+error:
+	close(fd);
+	return -1;
+}
+
+/**
+ * dev_read_int - read an 'int' value from an UBI device's sysfs file.
+ *
+ * @patt     the file pattern to read from
+ * @dev_num  UBI device number
+ * @value    the result is stored here
+ *
+ * This function returns %0 in case of success and %-1 in case of failure.
+ */
+static int dev_read_int(const char *patt, int dev_num, int *value)
+{
+	int fd, rd;
+	char buf[50];
+	char file[strlen(patt) + 50];
+
+	sprintf(&file[0], patt, dev_num);
+	fd = open(&file[0], O_RDONLY);
+	if (fd == -1)
+		return -1;
+
+	rd = read(fd, &buf[0], 50);
+	if (rd == -1)
+		goto error;
+
+	if (sscanf(&buf[0], "%d\n", value) != 1) {
+		/* This must be a UBI bug */
+		fprintf(stderr, "LIBUBI: bad value at sysfs file\n");
+		errno = EINVAL;
+		goto error;
+	}
+
+	close(fd);
+	return 0;
+
+error:
+	close(fd);
+	return -1;
+}
+
+/**
+ * dev_read_ll - read a 'long long' value from an UBI device's sysfs file.
+ *
+ * @patt     the file pattern to read from
+ * @dev_num  UBI device number
+ * @value    the result is stored here
+ *
+ * This function returns %0 in case of success and %-1 in case of failure.
+ */
+static int dev_read_ll(const char *patt, int dev_num, long long *value)
+{
+	int fd, rd;
+	char buf[50];
+	char file[strlen(patt) + 50];
+
+	sprintf(&file[0], patt, dev_num);
+	fd = open(&file[0], O_RDONLY);
+	if (fd == -1)
+		return -1;
+
+	rd = read(fd, &buf[0], 50);
+	if (rd == -1)
+		goto error;
+
+	if (sscanf(&buf[0], "%lld\n", value) != 1) {
+		/* This must be a UBI bug */
+		fprintf(stderr, "LIBUBI: bad value at sysfs file\n");
+		errno = EINVAL;
+		goto error;
+	}
+
+	close(fd);
+	return 0;
+
+error:
+	close(fd);
+	return -1;
+}
+
+/**
+ * dev_read_data - read data from an UBI device's sysfs file.
+ *
+ * @patt     the file pattern to read from
+ * @dev_num  UBI device number
+ * @buf      buffer to read data to
+ * @buf_len  buffer length
+ *
+ * This function returns number of read bytes in case of success and %-1 in
+ * case of failure.
+ */
+static int dev_read_data(const char *patt, int dev_num, void *buf, int buf_len)
+{
+	int fd, rd;
+	char file[strlen(patt) + 50];
+
+	sprintf(&file[0], patt, dev_num);
+	fd = open(&file[0], O_RDONLY);
+	if (fd == -1)
+		return -1;
+
+	rd = read(fd, buf, buf_len);
+	if (rd == -1) {
+		close(fd);
+		return -1;
+	}
+
+	close(fd);
+	return rd;
+}
+
+/**
+ * vol_read_int - read an 'int' value from an UBI volume's sysfs file.
+ *
+ * @patt     the file pattern to read from
+ * @dev_num  UBI device number
+ * @vol_id   volume identifier
+ * @value    the result is stored here
+ *
+ * This function returns %0 in case of success and %-1 in case of failure.
+ */
+static int vol_read_int(const char *patt, int dev_num, int vol_id, int *value)
+{
+	int fd, rd;
+	char buf[50];
+	char file[strlen(patt) + 100];
+
+	sprintf(&file[0], patt, dev_num, vol_id);
+	fd = open(&file[0], O_RDONLY);
+	if (fd == -1)
+		return -1;
+
+	rd = read(fd, &buf[0], 50);
+	if (rd == -1)
+		goto error;
+
+	if (sscanf(&buf[0], "%d\n", value) != 1) {
+		/* This must be a UBI bug */
+		fprintf(stderr, "LIBUBI: bad value at sysfs file\n");
+		errno = EINVAL;
+		goto error;
+	}
+
+	close(fd);
+	return 0;
+
+error:
+	close(fd);
+	return -1;
+}
+
+/**
+ * vol_read_ll - read a 'long long' value from an UBI volume's sysfs file.
+ *
+ * @patt     the file pattern to read from
+ * @dev_num  UBI device number
+ * @vol_id   volume identifier
+ * @value    the result is stored here
+ *
+ * This function returns %0 in case of success and %-1 in case of failure.
+ */
+static int vol_read_ll(const char *patt, int dev_num, int vol_id,
+		       long long *value)
+{
+	int fd, rd;
+	char buf[50];
+	char file[strlen(patt) + 100];
+
+	sprintf(&file[0], patt, dev_num, vol_id);
+	fd = open(&file[0], O_RDONLY);
+	if (fd == -1)
+		return -1;
+
+	rd = read(fd, &buf[0], 50);
+	if (rd == -1)
+		goto error;
+
+	if (sscanf(&buf[0], "%lld\n", value) != 1) {
+		/* This must be a UBI bug */
+		fprintf(stderr, "LIBUBI: bad value at sysfs file\n");
+		errno = EINVAL;
+		goto error;
+	}
+
+	close(fd);
+	return 0;
+
+error:
+	close(fd);
+	return -1;
+}
+
+/**
+ * vol_read_data - read data from an UBI volume's sysfs file.
+ *
+ * @patt     the file pattern to read from
+ * @dev_num  UBI device number
+ * @vol_id   volume identifier
+ * @buf      buffer to read to
+ * @buf_len  buffer length
+ *
+ * This function returns number of read bytes in case of success and %-1 in
+ * case of failure.
+ */
+static int vol_read_data(const char *patt, int dev_num, int vol_id, void *buf,
+			 int buf_len)
+{
+	int fd, rd;
+	char file[strlen(patt) + 100];
+
+	sprintf(&file[0], patt, dev_num, vol_id);
+	fd = open(&file[0], O_RDONLY);
+	if (fd == -1)
+		return -1;
+
+	rd = read(fd, buf, buf_len);
+	if (rd == -1) {
+		close(fd);
+		return -1;
+	}
+
+	close(fd);
+	return rd;
+}
+
+/**
+ * mkpath - compose full path from 2 given components.
+ *
+ * @path  first component
+ * @name  second component
+ *
+ * This function returns the resulting path in case of success and %NULL in
+ * case of failure.
+ */
+static char *mkpath(const char *path, const char *name)
+{
+	char *n;
+	int len1 = strlen(path);
+	int len2 = strlen(name);
+
+	n = malloc(len1 + len2 + 2);
+	if (!n)
+		return NULL;
+
+	memcpy(n, path, len1);
+	if (n[len1 - 1] != '/')
+		n[len1++] = '/';
+
+	memcpy(n + len1, name, len2 + 1);
+	return n;
+}
+
+/**
+ * find_dev_num - find UBI device number by its character device node.
+ *
+ * @lib   UBI library descriptor
+ * @node  UBI character device node name
+ *
+ * This function returns positive UBI device number in case of success and %-1
+ * in case of failure.
+ */
+static int find_dev_num(struct libubi *lib, const char *node)
+{
+	struct stat stat;
+	struct ubi_info info;
+	int i, major, minor;
+
+	if (lstat(node, &stat))
+		return -1;
+
+	if (!S_ISCHR(stat.st_mode)) {
+		errno = EINVAL;
+		return -1;
+	}
+
+	major = major(stat.st_rdev);
+	minor = minor(stat.st_rdev);
+
+	if (minor != 0) {
+		errno = -EINVAL;
+		return -1;
+	}
+
+	if (ubi_get_info((libubi_t *)lib, &info))
+		return -1;
+
+	for (i = info.lowest_dev_num; i <= info.highest_dev_num; i++) {
+		int major1, minor1, ret;
+		char buf[50];
+
+		ret = dev_read_data(lib->dev_dev, i, &buf[0], 50);
+		if (ret < 0)
+			return -1;
+
+		ret = sscanf(&buf[0], "%d:%d\n", &major1, &minor1);
+		if (ret != 2) {
+			fprintf(stderr, "LIBUBI: bad value at sysfs file\n");
+			errno = EINVAL;
+			return -1;
+		}
+
+		if (minor1 == minor && major1 == major)
+			return i;
+	}
+
+	errno = ENOENT;
+	return -1;
+}
+
+/**
+ * find_dev_num_vol - find UBI device number by volume character device node.
+ *
+ * @lib   UBI library descriptor
+ * @node  UBI character device node name
+ *
+ * This function returns positive UBI device number in case of success and %-1
+ * in case of failure.
+ */
+static int find_dev_num_vol(struct libubi *lib, const char *node)
+{
+	struct stat stat;
+	struct ubi_info info;
+	int i, major;
+
+	if (lstat(node, &stat))
+		return -1;
+
+	if (!S_ISCHR(stat.st_mode)) {
+		errno = EINVAL;
+		return -1;
+	}
+
+	major = major(stat.st_rdev);
+
+	if (minor(stat.st_rdev) == 0) {
+		errno = -EINVAL;
+		return -1;
+	}
+
+	if (ubi_get_info((libubi_t *)lib, &info))
+		return -1;
+
+	for (i = info.lowest_dev_num; i <= info.highest_dev_num; i++) {
+		int major1, minor1, ret;
+		char buf[50];
+
+		ret = dev_read_data(lib->dev_dev, i, &buf[0], 50);
+		if (ret < 0)
+			return -1;
+
+		ret = sscanf(&buf[0], "%d:%d\n", &major1, &minor1);
+		if (ret != 2) {
+			fprintf(stderr, "LIBUBI: bad value at sysfs file\n");
+			errno = EINVAL;
+			return -1;
+		}
+
+		if (major1 == major)
+			return i;
+	}
+
+	errno = ENOENT;
+	return -1;
+}
+
+/**
+ * find_vol_num - find UBI volume number by its character device node.
+ *
+ * @lib      UBI library descriptor
+ * @dev_num  UBI device number
+ * @node     UBI volume character device node name
+ *
+ * This function returns positive UBI volume number in case of success and %-1
+ * in case of failure.
+ */
+static int find_vol_num(struct libubi *lib, int dev_num, const char *node)
+{
+	struct stat stat;
+	struct ubi_dev_info info;
+	int i, major, minor;
+
+	if (lstat(node, &stat))
+		return -1;
+
+	if (!S_ISCHR(stat.st_mode)) {
+		errno = EINVAL;
+		return -1;
+	}
+
+	major = major(stat.st_rdev);
+	minor = minor(stat.st_rdev);
+
+	if (minor == 0) {
+		errno = -EINVAL;
+		return -1;
+	}
+
+	if (ubi_get_dev_info1((libubi_t *)lib, dev_num, &info))
+		return -1;
+
+	for (i = info.lowest_vol_num; i <= info.highest_vol_num; i++) {
+		int major1, minor1, ret;
+		char buf[50];
+
+		ret = vol_read_data(lib->vol_dev,  dev_num, i, &buf[0], 50);
+		if (ret < 0)
+			return -1;
+
+		ret = sscanf(&buf[0], "%d:%d\n", &major1, &minor1);
+		if (ret != 2) {
+			fprintf(stderr, "LIBUBI: bad value at sysfs file\n");
+			errno = EINVAL;
+			return -1;
+		}
+
+		if (minor1 == minor && major1 == major)
+			return i;
+	}
+
+	errno = ENOENT;
+	return -1;
+}
diff --git a/ubi-utils/src/libubi_int.h b/ubi-utils/src/libubi_int.h
new file mode 100644
index 0000000..e68b791
--- /dev/null
+++ b/ubi-utils/src/libubi_int.h
@@ -0,0 +1,129 @@
+/*
+ * Copyright (c) International Business Machines Corp., 2006
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See
+ * the GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ *
+ * Author: Artem B. Bityutskiy
+ *
+ * UBI (Unsorted Block Images) library.
+ */
+
+#ifndef __LIBUBI_INT_H__
+#define __LIBUBI_INT_H__
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/*
+ * UBI heavily makes use of the sysfs file system to interact with users-pace.
+ * The below are pre-define UBI file and directory names.
+ */
+
+#define SYSFS_UBI         "class/ubi"
+#define UBI_DEV_NAME_PATT "ubi%d"
+#define UBI_VER           "version"
+#define DEV_DEV           "dev"
+#define UBI_VOL_NAME_PATT "ubi%d_%d"
+#define DEV_AVAIL_EBS     "avail_eraseblocks"
+#define DEV_TOTAL_EBS     "total_eraseblocks"
+#define DEV_BAD_COUNT     "bad_peb_count"
+#define DEV_EB_SIZE       "eraseblock_size"
+#define DEV_MAX_EC        "max_ec"
+#define DEV_MAX_RSVD      "reserved_for_bad"
+#define DEV_MAX_VOLS      "max_vol_count"
+#define DEV_MIN_IO_SIZE   "min_io_size"
+#define VOL_TYPE          "type"
+#define VOL_DEV           "dev"
+#define VOL_ALIGNMENT     "alignment"
+#define VOL_DATA_BYTES    "data_bytes"
+#define VOL_RSVD_EBS      "reserved_ebs"
+#define VOL_EB_SIZE       "usable_eb_size"
+#define VOL_CORRUPTED     "corrupted"
+#define VOL_NAME          "name"
+
+/**
+ * libubi - UBI library description data structure.
+ *
+ * @sysfs            sysfs file system path
+ * @sysfs_ubi        UBI directory in sysfs
+ * @ubi_dev          UBI device sysfs directory pattern
+ * @ubi_version      UBI version file sysfs path
+ * @dev_dev          UBI device's major/minor numbers file pattern
+ * @dev_avail_ebs    count of available eraseblocks sysfs path pattern
+ * @dev_total_ebs    total eraseblocks count sysfs path pattern
+ * @dev_bad_count    count of bad eraseblocks sysfs path pattern
+ * @dev_eb_size      size of UBI device's eraseblocks sysfs path pattern
+ * @dev_max_ec       maximum erase counter sysfs path pattern
+ * @dev_bad_rsvd     count of physical eraseblock reserved for bad eraseblocks
+ *                   handling
+ * @dev_max_vols     maximum volumes number count sysfs path pattern
+ * @dev_min_io_size  minimum I/O unit size sysfs path pattern
+ * @ubi_vol          UBI volume sysfs directory pattern
+ * @vol_type         volume type sysfs path pattern
+ * @vol_dev          volume's major/minor numbers file pattern
+ * @vol_alignment    volume alignment sysfs path pattern
+ * @vol_data_bytes   volume data size sysfs path pattern
+ * @vol_rsvd_ebs     volume reserved size sysfs path pattern
+ * @vol_eb_size      volume eraseblock size sysfs path pattern
+ * @vol_corrupted    volume corruption flag sysfs path pattern
+ * @vol_name         volume name sysfs path pattern
+ */
+struct libubi
+{
+	char *sysfs;
+	char *sysfs_ubi;
+	char *ubi_dev;
+	char *ubi_version;
+	char *dev_dev;
+	char *dev_avail_ebs;
+	char *dev_total_ebs;
+	char *dev_bad_count;
+	char *dev_eb_size;
+	char *dev_max_ec;
+	char *dev_bad_rsvd;
+	char *dev_max_vols;
+	char *dev_min_io_size;
+	char *ubi_vol;
+	char *vol_type;
+	char *vol_dev;
+	char *vol_alignment;
+	char *vol_data_bytes;
+	char *vol_rsvd_ebs;
+	char *vol_eb_size;
+	char *vol_corrupted;
+	char *vol_name;
+	char *vol_max_count;
+};
+
+static int read_int(const char *file, int *value);
+static int dev_read_int(const char *patt, int dev_num, int *value);
+static int dev_read_ll(const char *patt, int dev_num, long long *value);
+static int dev_read_data(const char *patt, int dev_num, void *buf, int buf_len);
+static int vol_read_int(const char *patt, int dev_num, int vol_id, int *value);
+static int vol_read_ll(const char *patt, int dev_num, int vol_id,
+		       long long *value);
+static int vol_read_data(const char *patt, int dev_num, int vol_id, void *buf,
+			 int buf_len);
+static char *mkpath(const char *path, const char *name);
+static int find_dev_num(struct libubi *lib, const char *node);
+static int find_dev_num_vol(struct libubi *lib, const char *node);
+static int find_vol_num(struct libubi *lib, int dev_num, const char *node);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* !__LIBUBI_INT_H__ */
diff --git a/ubi-utils/src/libubimirror.c b/ubi-utils/src/libubimirror.c
index e5715fc..d8ea548 100644
--- a/ubi-utils/src/libubimirror.c
+++ b/ubi-utils/src/libubimirror.c
@@ -22,7 +22,7 @@
 #include <memory.h>
 #include <fcntl.h>
 
-#include <libubi.h>
+#include <libubiold.h>
 #include "ubimirror.h"
 
 #define COMPARE_BUF_SIZE    (128 * 1024)
@@ -207,11 +207,11 @@ ubimirror(uint32_t devno, int seqnum, uint32_t *ids, ssize_t ids_size,
 			fd_out = -1;
 	}
 err:
-	if (ulib != NULL)
-		ubi_close(&ulib);
-	if (fd_in != -1)
-		ubi_vol_close(fd_in);
 	if (fd_out != -1)
 		ubi_vol_close(fd_out);
+	if (fd_in != -1)
+		ubi_vol_close(fd_in);
+	if (ulib != NULL)
+		ubi_close(&ulib);
 	return rc;
 }
diff --git a/ubi-utils/src/libubiold.c b/ubi-utils/src/libubiold.c
index da4919b..0ff8bae 100644
--- a/ubi-utils/src/libubiold.c
+++ b/ubi-utils/src/libubiold.c
@@ -36,9 +36,9 @@
 #include <mtd/ubi-user.h>
 #include <mtd/ubi-header.h>
 
-#include "libubi.h"
-#include "libubi_int.h"
-#include "libubi_sysfs.h"
+#include "libubiold.h"
+#include "libubiold_int.h"
+#include "libubiold_sysfs.h"
 
 /**
  * struct ubi_lib - UBI library descriptor.
diff --git a/ubi-utils/src/libubiold_sysfs.c b/ubi-utils/src/libubiold_sysfs.c
index 95fd3de..c4860f6 100644
--- a/ubi-utils/src/libubiold_sysfs.c
+++ b/ubi-utils/src/libubiold_sysfs.c
@@ -33,7 +33,7 @@
 #include <stdarg.h>
 
 #include "config.h"
-#include "libubi_int.h"
+#include "libubiold_int.h"
 
 int
 sysfs_read_data(const char *file, void *buf, int len)
diff --git a/ubi-utils/src/pddcustomize.c b/ubi-utils/src/pddcustomize.c
index 764f2e7..a86e942 100644
--- a/ubi-utils/src/pddcustomize.c
+++ b/ubi-utils/src/pddcustomize.c
@@ -41,7 +41,7 @@
 #include "bootenv.h"
 #include "error.h"
 #include "example_ubi.h"
-#include "libubi.h"
+#include "libubiold.h"
 #include "ubimirror.h"
 
 #define PROGRAM_VERSION "1.4"
diff --git a/ubi-utils/src/reader.c b/ubi-utils/src/reader.c
index 7935a15..0ea8c6d 100644
--- a/ubi-utils/src/reader.c
+++ b/ubi-utils/src/reader.c
@@ -142,6 +142,7 @@ read_pfi_raw(pfi_header pfi_hd, FILE* fp_pfi __unused, pfi_raw_t* pfi_raw,
 	char tmp_str[PFI_KEYWORD_LEN];
 	bootenv_list_t raw_start_list = NULL;
 	pfi_raw_t res;
+	size_t size;
 
 	res = (pfi_raw_t) malloc(sizeof(struct pfi_raw));
 	if (!res)
@@ -178,8 +179,9 @@ read_pfi_raw(pfi_header pfi_hd, FILE* fp_pfi __unused, pfi_raw_t* pfi_raw,
 	}
 
 	rc = bootenv_list_to_num_vector(raw_start_list,
-					(void *) &(res->starts_size),
-					&(res->starts));
+					&size, &(res->starts));
+	res->starts_size = size;
+
 	if (rc != 0) {
 		EBUF_PFI("Cannot create numeric value array: %s", tmp_str);
 		goto err;
@@ -209,6 +211,7 @@ read_pfi_ubi(pfi_header pfi_hd, FILE* fp_pfi __unused, pfi_ubi_t* pfi_ubi,
 	bootenv_list_t ubi_name_list = NULL;
 	pfi_ubi_t res;
 	uint32_t i;
+	size_t size;
 
 	res = (pfi_ubi_t) calloc(1, sizeof(struct pfi_ubi));
 	if (!res)
@@ -247,8 +250,9 @@ read_pfi_ubi(pfi_header pfi_hd, FILE* fp_pfi __unused, pfi_ubi_t* pfi_ubi,
 		goto err;
 	}
 
-	rc = bootenv_list_to_num_vector(ubi_id_list, (void *) &(res->ids_size),
+	rc = bootenv_list_to_num_vector(ubi_id_list, &size,
 					&(res->ids));
+	res->ids_size = size;
 	if (rc != 0) {
 		EBUF_PFI("Cannot create numeric value array: %s", tmp_str);
 		goto err;
@@ -299,8 +303,9 @@ read_pfi_ubi(pfi_header pfi_hd, FILE* fp_pfi __unused, pfi_ubi_t* pfi_ubi,
 		EBUF_PFI("Cannot translate PFI value: %s", tmp_str);
 		goto err;
 	}
-	rc = bootenv_list_to_vector(ubi_name_list, (void *) &(res->names_size),
+	rc = bootenv_list_to_vector(ubi_name_list, &size,
 				    &(tmp_names));
+	res->names_size = size;
 	if (rc != 0) {
 		EBUF_PFI("Cannot create string array: %s", tmp_str);
 		goto err;
diff --git a/ubi-utils/src/ubimkvol.c b/ubi-utils/src/ubimkvol.c
index 879dcb6..1368671 100644
--- a/ubi-utils/src/ubimkvol.c
+++ b/ubi-utils/src/ubimkvol.c
@@ -28,6 +28,7 @@
  * 1.2 Reworked the user-interface to use argp.
  * 1.3 Removed argp because we want to use uClibc.
  * 1.4 Minor cleanups
+ * 1.5 Use a different libubi
  */
 
 #include <stdio.h>
@@ -40,7 +41,7 @@
 #include <config.h>
 #include <libubi.h>
 
-#define PROGRAM_VERSION "1.4"
+#define PROGRAM_VERSION "1.5"
 
 /*
  * The variables below	are set by command line arguments.
@@ -53,6 +54,7 @@ struct args {
 	int alignment;
 	char *name;
 	int nlen;
+	char node[256];
 
 	/* special stuff needed to get additional arguments */
 	char *arg1;
@@ -69,7 +71,7 @@ static struct args myargs = {
 	.nlen = 0,
 };
 
-static int param_sanity_check(struct args *args, ubi_lib_t lib);
+static int param_sanity_check(struct args *args, libubi_t libubi);
 
 static char doc[] = "\nVersion: " PROGRAM_VERSION "\n\t"
 	BUILD_OS" "BUILD_CPU" at "__DATE__" "__TIME__"\n"
@@ -177,6 +179,7 @@ parse_opt(int argc, char **argv, struct args *args)
 						"\"%s\"\n", optarg);
 					goto out;
 				}
+				sprintf(args->node, "/dev/ubi%d", args->devn);
 				break;
 			case 'n': /* --volid=<volume id> */
 				args->vol_id = strtoul(optarg, &endp, 0);
@@ -224,7 +227,7 @@ parse_opt(int argc, char **argv, struct args *args)
 	return -1;
 }
 
-static int param_sanity_check(struct args *args, ubi_lib_t lib)
+static int param_sanity_check(struct args *args, libubi_t libubi)
 {
 	int err, len;
 	struct ubi_info ubi;
@@ -239,7 +242,7 @@ static int param_sanity_check(struct args *args, ubi_lib_t lib)
 		goto out;
 	}
 
-	err = ubi_get_info(lib, &ubi);
+	err = ubi_get_info(libubi, &ubi);
 	if (err)
 		return -1;
 
@@ -264,7 +267,8 @@ out:
 int main(int argc, char * const argv[])
 {
 	int err;
-	ubi_lib_t lib;
+	libubi_t libubi;
+	struct ubi_mkvol_request req;
 
 	err = parse_opt(argc, (char **)argv, &myargs);
 	if (err) {
@@ -278,21 +282,26 @@ int main(int argc, char * const argv[])
 		return -1;
 	}
 
-	err = ubi_open(&lib);
-	if (err) {
+	libubi = libubi_open();
+	if (libubi == NULL) {
 		perror("Cannot open libubi");
 		return -1;
 	}
 
-	err = param_sanity_check(&myargs, lib);
+	err = param_sanity_check(&myargs, libubi);
 	if (err) {
 		perror("Input parameters check");
 		fprintf(stderr, "Use -h option for help\n");
 		goto out_libubi;
 	}
 
-	err = ubi_mkvol(lib, myargs.devn, myargs.vol_id, myargs.vol_type,
-			myargs.bytes, myargs.alignment, myargs.name);
+	req.vol_id = myargs.vol_id;
+	req.alignment = myargs.alignment;
+	req.bytes = myargs.bytes;
+	req.vol_type = myargs.vol_type;
+	req.name = myargs.name;
+
+	err = ubi_mkvol(libubi, myargs.node, &req);
 	if (err < 0) {
 		perror("Cannot create volume");
 		fprintf(stderr, "  err=%d\n", err);
@@ -304,10 +313,10 @@ int main(int argc, char * const argv[])
 	   "dynamic" : "static", name); */
 
 	myargs.vol_id = err;
-	ubi_close(&lib);
+	libubi_close(libubi);
 	return 0;
 
 out_libubi:
-	ubi_close(&lib);
+	libubi_close(libubi);
 	return -1;
 }
diff --git a/ubi-utils/src/ubirmvol.c b/ubi-utils/src/ubirmvol.c
index f458e8a..f32cbe0 100644
--- a/ubi-utils/src/ubirmvol.c
+++ b/ubi-utils/src/ubirmvol.c
@@ -25,6 +25,7 @@
  * 1.1 Reworked the userinterface to use argp.
  * 1.2 Removed argp because we want to use uClibc.
  * 1.3 Minor cleanups
+ * 1.4 Use a different libubi
  */
 
 #include <stdio.h>
@@ -37,7 +38,7 @@
 #include <config.h>
 #include <libubi.h>
 
-#define PROGRAM_VERSION "1.3"
+#define PROGRAM_VERSION "1.4"
 
 /*
  * The below variables are set by command line options.
@@ -45,6 +46,7 @@
 struct args {
 	int devn;
 	int vol_id;
+	char node[256];
 
 	/* special stuff needed to get additional arguments */
 	char *arg1;
@@ -59,7 +61,7 @@ static struct args myargs = {
 	.options = NULL,
 };
 
-static int param_sanity_check(struct args *args, ubi_lib_t lib);
+static int param_sanity_check(struct args *args, libubi_t libubi);
 
 static char doc[] = "\nVersion: " PROGRAM_VERSION "\n\t"
 	BUILD_OS" "BUILD_CPU" at "__DATE__" "__TIME__"\n"
@@ -118,6 +120,7 @@ parse_opt(int argc, char **argv, struct args *args)
 						"\"%s\"\n", optarg);
 					goto out;
 				}
+				sprintf(args->node, "/dev/ubi%d", args->devn);
 				break;
 			case 'n': /* --volid=<volume id> */
 				args->vol_id = strtoul(optarg, &endp, 0);
@@ -156,7 +159,7 @@ parse_opt(int argc, char **argv, struct args *args)
 	return -1;
 }
 
-static int param_sanity_check(struct args *args, ubi_lib_t lib)
+static int param_sanity_check(struct args *args, libubi_t libubi)
 {
 	int err;
 	struct ubi_info ubi;
@@ -166,7 +169,7 @@ static int param_sanity_check(struct args *args, ubi_lib_t lib)
 		goto out;
 	}
 
-	err = ubi_get_info(lib, &ubi);
+	err = ubi_get_info(libubi, &ubi);
 	if (err)
 		return -1;
 
@@ -185,7 +188,7 @@ out:
 int main(int argc, char * const argv[])
 {
 	int err, old_errno;
-	ubi_lib_t lib;
+	libubi_t libubi;
 
 	err = parse_opt(argc, (char **)argv, &myargs);
 	if (err)
@@ -197,20 +200,20 @@ int main(int argc, char * const argv[])
 		return -1;
 	}
 
-	err = ubi_open(&lib);
-	if (err) {
+	libubi = libubi_open();
+	if (libubi == NULL) {
 		perror("Cannot open libubi");
 		return -1;
 	}
 
-	err = param_sanity_check(&myargs, lib);
+	err = param_sanity_check(&myargs, libubi);
 	if (err) {
 		perror("Input parameters check");
 		fprintf(stderr, "Use -h option for help\n");
 		goto out_libubi;
 	}
 
-	err = ubi_rmvol(lib, myargs.devn, myargs.vol_id);
+	err = ubi_rmvol(libubi, myargs.node, myargs.vol_id);
 	old_errno = errno;
 	if (err < 0) {
 		perror("Cannot remove volume");
@@ -218,9 +221,10 @@ int main(int argc, char * const argv[])
 		goto out_libubi;
 	}
 
+	libubi_close(libubi);
 	return 0;
 
 out_libubi:
-	ubi_close(&lib);
+	libubi_close(libubi);
 	return -1;
 }
diff --git a/ubi-utils/src/ubiupdatevol.c b/ubi-utils/src/ubiupdatevol.c
index c0b4178..5401eb1 100644
--- a/ubi-utils/src/ubiupdatevol.c
+++ b/ubi-utils/src/ubiupdatevol.c
@@ -25,6 +25,7 @@
  * 1.0 Reworked the userinterface to use argp.
  * 1.1 Removed argp parsing because we want to use uClib.
  * 1.2 Minor cleanups
+ * 1.3 Use a different libubi
  */
 
 #include <errno.h>
@@ -36,14 +37,12 @@
 #include <stdlib.h>
 #include <string.h>
 #include <unistd.h>
-#include <sys/ioctl.h>
 #include <sys/stat.h>
-#include <sys/types.h>
 
 #include <config.h>
 #include <libubi.h>
 
-#define PROGRAM_VERSION "1.2"
+#define PROGRAM_VERSION "1.3"
 
 #define MAXPATH		1024
 #define BUFSIZE		128 * 1024
@@ -174,7 +173,7 @@ parse_opt(int argc, char **argv, struct args *args)
  * some reason nothing is written. The volume is unusable after this.
  */
 static int
-ubi_truncate_volume(struct args *args, int64_t bytes)
+ubi_truncate_volume(struct args *args, int64_t bytes,libubi_t libubi)
 {
 	int rc, ofd;
 	char path[MAXPATH];
@@ -188,7 +187,7 @@ ubi_truncate_volume(struct args *args, int64_t bytes)
 		fprintf(stderr, "Cannot open volume %s\n", path);
 		exit(EXIT_FAILURE);
 	}
-	rc = ioctl(ofd, UBI_IOCVOLUP, &bytes);
+	rc = ubi_update_start(libubi, ofd, bytes);
 	old_errno = errno;
 	if (rc < 0) {
 		perror("UBI volume update ioctl");
@@ -220,7 +219,7 @@ static ssize_t ubi_write(int fd, const void *buf, size_t count)
 }
 
 static int
-ubi_update_volume(struct args *args)
+ubi_update_volume(struct args *args, libubi_t libubi)
 {
 	int rc, ofd;
 	FILE *ifp = NULL;
@@ -263,7 +262,7 @@ ubi_update_volume(struct args *args)
 		exit(EXIT_FAILURE);
 	}
 
-	rc = ioctl(ofd, UBI_IOCVOLUP, &bytes);
+	rc = ubi_update_start(libubi, ofd, bytes);
 	old_errno = errno;
 	if (rc < 0) {
 		perror("UBI volume update ioctl");
@@ -304,24 +303,35 @@ int
 main(int argc, char *argv[])
 {
 	int rc;
+	libubi_t libubi;
 
 	parse_opt(argc, argv, &myargs);
 
+	libubi = libubi_open();
+	if (libubi == NULL) {
+		perror("Cannot open libubi");
+		return -1;
+	}
+
 	if (myargs.truncate) {
-		rc = ubi_truncate_volume(&myargs, 0LL);
+		rc = ubi_truncate_volume(&myargs, 0LL, libubi);
 		if (rc < 0)
-			exit(EXIT_FAILURE);
-		exit(EXIT_SUCCESS);
+			goto out_libubi;
 	}
-	if (myargs.broken_update) {
-		rc = ubi_truncate_volume(&myargs, 1LL);
+	else if (myargs.broken_update) {
+		rc = ubi_truncate_volume(&myargs, 1LL, libubi);
 		if (rc < 0)
-			exit(EXIT_FAILURE);
-		exit(EXIT_SUCCESS);
+			goto out_libubi;
+	} else {
+		rc = ubi_update_volume(&myargs, libubi);
+		if (rc < 0)
+			goto out_libubi;
 	}
-	rc = ubi_update_volume(&myargs);
-	if (rc < 0)
-		exit(EXIT_FAILURE);
 
-	exit(EXIT_SUCCESS);
+	libubi_close(libubi);
+	return 0;
+	
+out_libubi:
+	libubi_close(libubi);
+	return -1;
 }
-- 
cgit v1.2.3