Some handlers can need to write theiselves
the image instead of implicitely call the write()
function from copyfile / copyimage. Add a callback
to copyimage(), and adjust all handlers to the new
interface.
core/cpio_utils.c | 18 +++++++++++-------
corelib/stream_interface.c | 6 +++---
handlers/archive_handler.c | 2 +-
handlers/flash_handler.c | 2 +-
handlers/raw_handler.c | 4 ++--
handlers/ubivol_handler.c | 2 +-
handlers/uboot_handler.c | 2 +-
include/util.h | 9 +++++++--
8 files changed, 27 insertions(+), 18 deletions(-)
diff --git a/core/cpio_utils.c b/core/cpio_utils.c
index 20b7e04..b987656 100644
--- a/core/cpio_utils.c
+++ b/core/cpio_utils.c
@@ -118,7 +118,7 @@ static int copy_write(int fd, const void *buf, int len)
int copyfile(int fdin, int fdout, int nbytes, unsigned long *offs,
int skip_file, int __attribute__ ((__unused__)) compressed,
- uint32_t *checksum, unsigned char *hash, int encrypted)
+ uint32_t *checksum, unsigned char *hash, int encrypted, writeimage callback)
{
unsigned long size;
unsigned char *in;
@@ -132,6 +132,9 @@ int copyfile(int fdin, int fdout, int nbytes, unsigned long *offs,
*/
unsigned int md_len = 0;
+ if (!callback)
+ callback = copy_write;
+
if (IsValidHash(hash)) {
dgst = swupdate_HASH_init();
if (!dgst)
@@ -182,7 +185,7 @@ int copyfile(int fdin, int fdout, int nbytes, unsigned long *offs,
* results corrupted. This lets the cleanup routine
* to remove it
*/
- if (copy_write(fdout, in, size) < 0) {
+ if (callback(fdout, in, size) < 0) {
close(fdout);
free(in);
return -ENOSPC;
@@ -227,7 +230,7 @@ int copyfile(int fdin, int fdout, int nbytes, unsigned long *offs,
return 0;
}
-int copyimage(int fdout, struct img_type *img)
+int copyimage(int fdout, struct img_type *img, writeimage callback)
{
return copyfile(img->fdin,
fdout,
@@ -237,7 +240,8 @@ int copyimage(int fdout, struct img_type *img)
img->compressed,
&img->checksum,
img->sha256,
- img->is_encrypted);
+ img->is_encrypted,
+ callback);
}
int extract_cpio_header(int fd, struct filehdr *fhdr, unsigned long *offset)
@@ -299,7 +303,7 @@ off_t extract_sw_description(int fd, const char *descfile, off_t start)
ERROR("CPIO file corrupted : %s\n", strerror(errno));
return -1;
}
- if (copyfile(fd, fdout, fdh.size, &offset, 0, 0, &checksum, NULL, 0) < 0) {
+ if (copyfile(fd, fdout, fdh.size, &offset, 0, 0, &checksum, NULL, 0, NULL) < 0) {
ERROR("%s corrupted or not valid\n", descfile);
return -1;
}
@@ -360,7 +364,7 @@ off_t extract_next_file(int fd, int fdout, off_t start, int compressed,
if (lseek(fd, offset, SEEK_SET) < 0)
ERROR("CPIO file corrupted : %s\n", strerror(errno));
- if (copyfile(fd, fdout, fdh.size, &offset, 0, compressed, &checksum, hash, 0) < 0) {
+ if (copyfile(fd, fdout, fdh.size, &offset, 0, compressed, &checksum, hash, 0, NULL) < 0) {
ERROR("Error copying extracted file\n");
}
@@ -409,7 +413,7 @@ int cpio_scan(int fd, struct swupdate_cfg *cfg, off_t start)
* use copyfile for checksum verification, as we skip file
* we do not have to provide fdout
*/
- if (copyfile(fd, 0, fdh.size, &offset, 1, 0, &checksum, NULL, 0) != 0) {
+ if (copyfile(fd, 0, fdh.size, &offset, 1, 0, &checksum, NULL, 0, NULL) != 0) {
ERROR("invalid archive\n");
return -1;
}
diff --git a/corelib/stream_interface.c b/corelib/stream_interface.c
index 7f7bd25..bed76d0 100644
--- a/corelib/stream_interface.c
+++ b/corelib/stream_interface.c
@@ -104,7 +104,7 @@ static int extract_file_to_tmp(int fd, const char *fname, unsigned long *poffs)
if (fdout < 0)
return -1;
- if (copyfile(fd, fdout, fdh.size, poffs, 0, 0, &checksum, NULL, 0) < 0) {
+ if (copyfile(fd, fdout, fdh.size, poffs, 0, 0, &checksum, NULL, 0, NULL) < 0) {
return -1;
}
if (checksum != (uint32_t)fdh.chksum) {
@@ -206,7 +206,7 @@ static int extract_files(int fd, struct swupdate_cfg *software)
fdout = openfileoutput(img->extract_file);
if (fdout < 0)
return -1;
- if (copyfile(fd, fdout, fdh.size, &offset, 0, 0, &checksum, img->sha256, 0) < 0) {
+ if (copyfile(fd, fdout, fdh.size, &offset, 0, 0, &checksum, img->sha256, 0, NULL) < 0) {
return -1;
}
if (checksum != (unsigned long)fdh.chksum) {
@@ -218,7 +218,7 @@ static int extract_files(int fd, struct swupdate_cfg *software)
break;
case SKIP_FILE:
- if (copyfile(fd, fdout, fdh.size, &offset, skip, 0, &checksum, NULL, 0) < 0) {
+ if (copyfile(fd, fdout, fdh.size, &offset, skip, 0, &checksum, NULL, 0, NULL) < 0) {
return -1;
}
if (checksum != (unsigned long)fdh.chksum) {
diff --git a/handlers/archive_handler.c b/handlers/archive_handler.c
index 4a57ed1..bf1a9e4 100644
--- a/handlers/archive_handler.c
+++ b/handlers/archive_handler.c
@@ -208,7 +208,7 @@ static int install_archive_image(struct img_type *img,
fdout = open(FIFO, O_WRONLY);
- ret = copyimage(fdout, img);
+ ret = copyimage(fdout, img, NULL);
if (ret< 0) {
ERROR("Error copying extracted file\n");
return -EFAULT;
diff --git a/handlers/flash_handler.c b/handlers/flash_handler.c
index 3365dcc..1fdab01 100644
--- a/handlers/flash_handler.c
+++ b/handlers/flash_handler.c
@@ -649,7 +649,7 @@ static int flash_write_nor(int mtdnum, struct img_type *img)
return -1;
}
- ret = copyimage(fdout, img);
+ ret = copyimage(fdout, img, NULL);
/* tell 'nbytes == 0' (EOF) from 'nbytes < 0' (read error) */
if (ret < 0) {
diff --git a/handlers/raw_handler.c b/handlers/raw_handler.c
index 0c885b0..0346a27 100644
--- a/handlers/raw_handler.c
+++ b/handlers/raw_handler.c
@@ -49,7 +49,7 @@ static int install_raw_image(struct img_type *img,
return -1;
}
- ret = copyimage(fdout, img);
+ ret = copyimage(fdout, img, NULL);
close(fdout);
return ret;
@@ -85,7 +85,7 @@ static int install_raw_file(struct img_type *img,
TRACE("Installing file %s on %s\n",
img->fname, path);
fdout = openfileoutput(path);
- ret = copyimage(fdout, img);
+ ret = copyimage(fdout, img, NULL);
if (ret< 0) {
ERROR("Error copying extracted file\n");
}
diff --git a/handlers/ubivol_handler.c b/handlers/ubivol_handler.c
index 0d7788c..c741b99 100644
--- a/handlers/ubivol_handler.c
+++ b/handlers/ubivol_handler.c
@@ -104,7 +104,7 @@ static int update_volume(libubi_t libubi, struct img_type *img,
TRACE("Updating UBI : %s %lld\n",
img->fname, img->size);
- if (copyimage(fdout, img) < 0) {
+ if (copyimage(fdout, img, NULL) < 0) {
ERROR("Error copying extracted file");
err = -1;
}
diff --git a/handlers/uboot_handler.c b/handlers/uboot_handler.c
index 2d51113..b6e3d21 100644
--- a/handlers/uboot_handler.c
+++ b/handlers/uboot_handler.c
@@ -50,7 +50,7 @@ static int install_uboot_environment(struct img_type *img,
* U-Boot environment is set inside sw-description
* there is no hash but sw-description was already verified
*/
- ret = copyimage(fdout, img);
+ ret = copyimage(fdout, img, NULL);
close(fdout);
}
diff --git a/include/util.h b/include/util.h
index ad38329..e82d4c1 100644
--- a/include/util.h
+++ b/include/util.h
@@ -120,6 +120,11 @@ int gpio_direction_output(int gpio_number, int value);
int gpio_set_value(int gpio_number, int value);
int gpio_get_value(int gpio_number);
+/*
+ * Function to extract / copy images
+ */
+typedef int (*writeimage) (int fd, const void *buf, int len);
+
int fill_buffer(int fd, unsigned char *buf, int nbytes, unsigned long *offs,
uint32_t *checksum, void *dgst);
int decompress_image(int infile, unsigned long *offs, int nbytes,
@@ -128,8 +133,8 @@ int fw_set_one_env(const char *name, const char *value);
int openfile(const char *filename);
int copyfile(int fdin, int fdout, int nbytes, unsigned long *offs,
int skip_file, int compressed, uint32_t *checksum,
- unsigned char *hash, int encrypted);
-int copyimage(int fdout, struct img_type *img);
+ unsigned char *hash, int encrypted, writeimage callback);
+int copyimage(int fdout, struct img_type *img, writeimage callback);
off_t extract_sw_description(int fd, const char *descfile, off_t start);
off_t extract_next_file(int fd, int fdout, off_t start, int compressed,