[PATCH 2/5] digest: factorise file digest to common/digest.c
Jean-Christophe PLAGNIOL-VILLARD
plagnioj at jcrosoft.com
Sat Oct 8 10:41:56 EDT 2011
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 at jcrosoft.com>
---
commands/digest.c | 78 ++++++++--------------------------------
common/digest.c | 101 +++++++++++++++++++++++++++++++++++++++++++++++++++++
include/digest.h | 8 ++++
3 files changed, 125 insertions(+), 62 deletions(-)
diff --git a/commands/digest.c b/commands/digest.c
index 2a699e6..1fbffb6 100644
--- a/commands/digest.c
+++ b/commands/digest.c
@@ -29,71 +29,12 @@
#include <malloc.h>
#include <digest.h>
-static int file_digest(struct digest *d, char *filename,
- ulong start, ulong size)
-{
- ulong len = 0;
- int fd, now, i, ret = 0;
- unsigned char *buf;
-
- d->init(d);
-
- fd = open(filename, O_RDONLY);
- if (fd < 0) {
- perror(filename);
- return fd;
- }
-
- if (start > 0) {
- ret = lseek(fd, start, SEEK_SET);
- if (ret == -1) {
- perror("lseek");
- goto out;
- }
- }
-
- buf = xmalloc(4096);
-
- while (size) {
- now = min((ulong)4096, size);
- 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, buf);
-
- for (i = 0; i < d->length; i++)
- printf("%02x", buf[i]);
-
- printf(" %s\t0x%08lx ... 0x%08lx\n", filename, start, start + len);
-
-out_free:
- free(buf);
-out:
- close(fd);
-
- return ret;
-}
-
static int do_digest(char *algorithm, int argc, char *argv[])
{
struct digest *d;
int ret = 0;
+ int i;
+ unsigned char *hash;
d = digest_get_by_name(algorithm);
BUG_ON(!d);
@@ -101,6 +42,12 @@ static int do_digest(char *algorithm, int argc, char *argv[])
if (argc < 2)
return COMMAND_ERROR_USAGE;
+ hash = calloc(d->length, sizeof(unsigned char));
+ if (!hash) {
+ perror("calloc");
+ return COMMAND_ERROR_USAGE;
+ }
+
argv++;
while (*argv) {
char *filename = "/dev/mem";
@@ -113,12 +60,19 @@ static int do_digest(char *algorithm, int argc, char *argv[])
argv++;
}
- if (file_digest(d, filename, start, size) < 0)
+ if (digest_file_window(d, filename, hash, start, size) < 0)
ret = 1;
+ for (i = 0; i < d->length; i++)
+ printf("%02x", hash[i]);
+
+ printf(" %s\t0x%08lx ... 0x%08lx\n", filename, start, start + size);
+
argv++;
}
+ free(hash);
+
return ret;
}
diff --git a/common/digest.c b/common/digest.c
index 10ad060..a327395 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);
diff --git a/include/digest.h b/include/digest.h
index 1dcfd9d..36a8e37 100644
--- a/include/digest.h
+++ b/include/digest.h
@@ -46,4 +46,12 @@ void digest_unregister(struct digest *d);
struct digest* digest_get_by_name(char* name);
+int digest_file_window(struct digest *d, char *filename,
+ unsigned char *hash,
+ ulong start, ulong size);
+int digest_file(struct digest *d, char *filename,
+ unsigned char *hash);
+int digest_file_by_name(char *algo, char *filename,
+ unsigned char *hash);
+
#endif /* __SH_ST_DEVICES_H__ */
--
1.7.6.3
More information about the barebox
mailing list