Skip site navigation (1)Skip section navigation (2)
Date:      Fri, 16 Mar 2001 21:08:33 +0200
From:      Peter Pentchev <roam@orbitel.bg>
To:        arch@FreeBSD.org
Subject:   add MD5Chunk(filename, .., offset, length) to libmd
Message-ID:  <20010316210833.C8245@ringworld.oblivion.bg>

next in thread | raw e-mail | index | archive | help
Hi,

(I wonder if I'm starting another bikeshed, but oh well ;)

As phk pointed out in the SITE MD5 thread, it is sometimes useful
to compute the MD5 hash over a range of a file.  I agree this is trivial
to implement, but why not have it in our standard toolbox?

Attached is a patch to libmd, which adds an MD5Check() function,
similar in all aspects to MD5File()  (actually quite a lot of it
was shamelessly stolen from MD5File ;), but with additional two
arguments, offset and length to compute the hash over.  If there is
sufficient interest, I could take the time to document it in the
corresponding manpages, too.

At the end is a patch to /sbin/md5, which adds a new -R (range) argument.
There are two proposed implementations with different semantics -
one puts the offset:length as an optarg to -R, thus keeping md5(1)'s
ability to process multiple files, the other - conditionalized on
an ALT_RFLAG compiler define - only accepts one file name, and takes
the offset and length as additional cmdline arguments after the filename.
It's up to y'all to choose between the two, should you like either one
at all :)

G'luck,
Peter

-- 
Hey, out there - is it *you* reading me, or is it someone else?

Index: src/sys/sys/md5.h
===================================================================
RCS file: /home/ncvs/src/sys/sys/md5.h,v
retrieving revision 1.13
diff -u -r1.13 md5.h
--- src/sys/sys/md5.h	1999/12/29 04:24:44	1.13
+++ src/sys/sys/md5.h	2001/03/16 19:00:32
@@ -34,6 +34,7 @@
 } MD5_CTX;
 
 #include <sys/cdefs.h>
+#include <sys/types.h>
 
 __BEGIN_DECLS
 void   MD5Init (MD5_CTX *);
@@ -42,6 +43,7 @@
 void   MD5Final (unsigned char [16], MD5_CTX *);
 char * MD5End(MD5_CTX *, char *);
 char * MD5File(const char *, char *);
+char * MD5Chunk(const char *, char *, off_t, off_t);
 char * MD5Data(const unsigned char *, unsigned int, char *);
 #ifdef _KERNEL
 void MD5Transform __P((u_int32_t [4], const unsigned char [64]));
Index: src/lib/libmd/md2.h
===================================================================
RCS file: /home/ncvs/src/lib/libmd/md2.h,v
retrieving revision 1.8
diff -u -r1.8 md2.h
--- src/lib/libmd/md2.h	1999/08/28 00:05:04	1.8
+++ src/lib/libmd/md2.h	2001/03/16 19:00:32
@@ -31,6 +31,7 @@
 } MD2_CTX;
 
 #include <sys/cdefs.h>
+#include <sys/types.h>
 
 __BEGIN_DECLS
 void   MD2Init(MD2_CTX *);
@@ -39,6 +40,7 @@
 void   MD2Final(unsigned char [16], MD2_CTX *);
 char * MD2End(MD2_CTX *, char *);
 char * MD2File(const char *, char *);
+char * MD2Chunk(const char *, char *, off_t, off_t);
 char * MD2Data(const unsigned char *, unsigned int, char *);
 __END_DECLS
 
Index: src/lib/libmd/md4.h
===================================================================
RCS file: /home/ncvs/src/lib/libmd/md4.h,v
retrieving revision 1.9
diff -u -r1.9 md4.h
--- src/lib/libmd/md4.h	1999/08/28 00:05:05	1.9
+++ src/lib/libmd/md4.h	2001/03/16 19:00:32
@@ -33,6 +33,7 @@
 } MD4_CTX;
 
 #include <sys/cdefs.h>
+#include <sys/types.h>
 
 __BEGIN_DECLS
 void   MD4Init(MD4_CTX *);
@@ -41,6 +42,7 @@
 void   MD4Final(unsigned char [16], MD4_CTX *);
 char * MD4End(MD4_CTX *, char *);
 char * MD4File(const char *, char *);
+char * MD4Chunk(const char *, char *, off_t, off_t);
 char * MD4Data(const unsigned char *, unsigned int, char *);
 __END_DECLS
 
Index: src/lib/libmd/mdXhl.c
===================================================================
RCS file: /home/ncvs/src/lib/libmd/mdXhl.c,v
retrieving revision 1.13
diff -u -r1.13 mdXhl.c
--- src/lib/libmd/mdXhl.c	1999/08/28 00:05:07	1.13
+++ src/lib/libmd/mdXhl.c	2001/03/16 19:00:33
@@ -11,6 +11,7 @@
  */
 
 #include <sys/types.h>
+#include <sys/stat.h>
 #include <fcntl.h>
 #include <unistd.h>
 
@@ -53,6 +54,43 @@
     while ((i = read(f,buffer,sizeof buffer)) > 0) {
 	MDXUpdate(&ctx,buffer,i);
     }
+    j = errno;
+    close(f);
+    errno = j;
+    if (i < 0) return 0;
+    return MDXEnd(&ctx, buf);
+}
+
+char *
+MDXChunk(const char *filename, char *buf, off_t ofs, off_t len)
+{
+    unsigned char buffer[BUFSIZ];
+    MDX_CTX ctx;
+    struct stat stbuf;
+    int f, i, j;
+    off_t n;
+
+    MDXInit(&ctx);
+    f = open(filename, O_RDONLY);
+    if (f < 0) return 0;
+    if (fstat(f, &stbuf) < 0) return 0;
+    if (ofs > stbuf.st_size)
+	ofs = stbuf.st_size;
+    if (len == 0)
+	len = stbuf.st_size - ofs;
+    else if (len > stbuf.st_size - ofs)
+	len = stbuf.st_size - ofs;
+    if (lseek(f, ofs, SEEK_SET) < 0) return 0;
+    n = len;
+    while (n > 0) {
+	if (n > sizeof(buffer))
+	    i = read(f, buffer, sizeof(buffer));
+	else
+	    i = read(f, buffer, n);
+	if (i < 0) break;
+	MDXUpdate(&ctx, buffer, i);
+	n -= i;
+    } 
     j = errno;
     close(f);
     errno = j;
Index: src/sbin/md5/md5.c
===================================================================
RCS file: /home/ncvs/src/sbin/md5/md5.c,v
retrieving revision 1.21
diff -u -r1.21 md5.c
--- src/sbin/md5/md5.c	2000/11/08 20:41:35	1.21
+++ src/sbin/md5/md5.c	2001/03/16 19:01:16
@@ -40,6 +40,7 @@
 
 int qflag;
 int rflag;
+int Rflag;
 
 static void MDString PROTO_LIST((char *));
 static void MDTimeTrial PROTO_LIST((void));
@@ -64,9 +65,15 @@
 	int     ch;
 	char   *p;
 	char	buf[33];
+	off_t	ofs, len;
 
+	ofs = len = 0;
 	if (argc > 1) {
-		while ((ch = getopt(argc, argv, "ps:qrtx")) != -1) {
+#ifndef ALT_RFLAG
+		while ((ch = getopt(argc, argv, "ps:qR:rtx")) != -1) {
+#else
+		while ((ch = getopt(argc, argv, "ps:qRrtx")) != -1) {
+#endif
 			switch (ch) {
 			case 'p':
 				MDFilter(1);
@@ -74,6 +81,20 @@
 			case 'q':
 				qflag = 1;
 				break;
+			case 'R':
+#ifndef ALT_RFLAG
+				ofs = strtoul(optarg, &p, 10);
+				if (p == optarg)
+					usage();
+				if (*p) {
+					if (*p != ':')
+						usage();
+					else
+						len = strtoul(p + 1, NULL, 10);
+				}
+#endif
+				Rflag = 1;
+				break;
 			case 'r':
 				rflag = 1;
 				break;
@@ -90,8 +111,22 @@
 				usage();
 			}
 		}
+#ifdef ALT_RFLAG
+		if (Rflag) {
+			if ((argc == optind) || (argc > optind + 3))
+				usage();
+			if (argc > optind + 1)
+				ofs = strtoul(argv[optind+1], NULL, 10);
+			if (argc > optind + 2)
+				len = strtoul(argv[optind+2], NULL, 10);
+			argc = optind + 1;
+		}
+#endif
 		while (optind < argc) {
-			p = MD5File(argv[optind], buf);
+			if (!Rflag)
+				p = MD5File(argv[optind], buf);
+			else
+				p = MD5Chunk(argv[optind], buf, ofs, len);
 			if (!p)
 				warn("%s", argv[optind]);
 			else
@@ -214,6 +249,11 @@
 usage()
 {
 
+#ifndef ALT_RFLAG
+	fprintf(stderr, "usage: md5 [-pqrtx] [-R ofs:len] [-s string] [files ...]\n");
+#else
 	fprintf(stderr, "usage: md5 [-pqrtx] [-s string] [files ...]\n");
+	fprintf(stderr, "       md5 [-pqrtx] -R file [ofs [len]]\n");
+#endif
 	exit(1);
 }

To Unsubscribe: send mail to majordomo@FreeBSD.org
with "unsubscribe freebsd-arch" in the body of the message




Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?20010316210833.C8245>