summaryrefslogtreecommitdiffstats
path: root/common
diff options
context:
space:
mode:
authorJean-Christophe PLAGNIOL-VILLARD <plagnioj@jcrosoft.com>2011-10-08 16:41:56 +0200
committerSascha Hauer <s.hauer@pengutronix.de>2011-10-12 08:52:49 +0200
commit05bd7afb3aa581366b41334be91dd01a185d803f (patch)
treeaac8cc37a6f191860a7178c55e3cde9363d5e2c8 /common
parent4ac3a1f9e0d00530204eb81267c9a920e8b27b02 (diff)
downloadbarebox-05bd7afb3aa581366b41334be91dd01a185d803f.tar.gz
barebox-05bd7afb3aa581366b41334be91dd01a185d803f.tar.xz
digest: factorise file digest to common/digest.c
rename it to digest_file_window introduce digest_file to digest a file and digest_file_by_name where we specify the algo by name Signed-off-by: Jean-Christophe PLAGNIOL-VILLARD <plagnioj@jcrosoft.com> Signed-off-by: Sascha Hauer <s.hauer@pengutronix.de>
Diffstat (limited to 'common')
-rw-r--r--common/digest.c101
1 files changed, 101 insertions, 0 deletions
diff --git a/common/digest.c b/common/digest.c
index 10ad06005e..a327395804 100644
--- a/common/digest.c
+++ b/common/digest.c
@@ -23,6 +23,9 @@
#include <common.h>
#include <digest.h>
#include <malloc.h>
+#include <fs.h>
+#include <fcntl.h>
+#include <linux/stat.h>
#include <errno.h>
#include <module.h>
#include <linux/err.h>
@@ -75,3 +78,101 @@ struct digest* digest_get_by_name(char* name)
return NULL;
}
EXPORT_SYMBOL_GPL(digest_get_by_name);
+
+int digest_file_window(struct digest *d, char *filename,
+ unsigned char *hash,
+ ulong start, ulong size)
+{
+ ulong len = 0;
+ int fd, now, ret = 0;
+ unsigned char *buf;
+ int flags;
+
+ d->init(d);
+
+ fd = open(filename, O_RDONLY);
+ if (fd < 0) {
+ perror(filename);
+ return fd;
+ }
+
+ buf = memmap(fd, PROT_READ);
+ if (buf == (void *)-1) {
+ buf = xmalloc(4096);
+ flags = 1;
+ }
+
+ if (start > 0) {
+ if (flags) {
+ ret = lseek(fd, start, SEEK_SET);
+ if (ret == -1) {
+ perror("lseek");
+ goto out;
+ }
+ } else {
+ buf += start;
+ }
+ }
+
+ while (size) {
+ now = min((ulong)4096, size);
+ if (flags) {
+ now = read(fd, buf, now);
+ if (now < 0) {
+ ret = now;
+ perror("read");
+ goto out_free;
+ }
+ if (!now)
+ break;
+ }
+
+ if (ctrlc()) {
+ ret = -EINTR;
+ goto out_free;
+ }
+
+ d->update(d, buf, now);
+ size -= now;
+ len += now;
+ }
+
+ d->final(d, hash);
+
+out_free:
+ if (flags)
+ free(buf);
+out:
+ close(fd);
+
+ return ret;
+}
+EXPORT_SYMBOL_GPL(digest_file_window);
+
+int digest_file(struct digest *d, char *filename,
+ unsigned char *hash)
+{
+ struct stat st;
+ int ret;
+
+ ret = stat(filename, &st);
+
+ if (ret < 0)
+ return ret;
+
+ return digest_file_window(d, filename, hash, 0, st.st_size);
+}
+EXPORT_SYMBOL_GPL(digest_file);
+
+int digest_file_by_name(char *algo, char *filename,
+ unsigned char *hash)
+{
+ struct digest *d;
+
+ d = digest_get_by_name(algo);
+ if (!d)
+ return -EIO;
+
+ return digest_file(d, filename, hash);
+}
+EXPORT_SYMBOL_GPL(digest_file_by_name);