From owner-freebsd-arch Fri Mar 16 11: 9:25 2001 Delivered-To: freebsd-arch@freebsd.org Received: from ringworld.nanolink.com (ringworld.nanolink.com [195.24.48.13]) by hub.freebsd.org (Postfix) with SMTP id 7F0B937B71A for ; Fri, 16 Mar 2001 11:09:16 -0800 (PST) (envelope-from roam@orbitel.bg) Received: (qmail 8704 invoked by uid 1000); 16 Mar 2001 19:08:33 -0000 Date: Fri, 16 Mar 2001 21:08:33 +0200 From: Peter Pentchev To: arch@FreeBSD.org Subject: add MD5Chunk(filename, .., offset, length) to libmd Message-ID: <20010316210833.C8245@ringworld.oblivion.bg> Mail-Followup-To: arch@FreeBSD.org Mime-Version: 1.0 Content-Type: text/plain; charset=us-ascii Content-Disposition: inline User-Agent: Mutt/1.2.5i Sender: owner-freebsd-arch@FreeBSD.ORG Precedence: bulk X-Loop: FreeBSD.ORG 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 +#include __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 +#include __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 +#include __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 +#include #include #include @@ -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