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>
