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>