Hello.
I''ve modified patch for md5.c, so now md5/sha256/etc handles input files
containing checksums in two formats:
ALGORITHM(path_to_file) = checksum
and
checksum path_to_file.

It seems, this patch (which at least applies to md5.c in 8.3) needs testing.
--
Best regards,
Alexander Pyhalov
--- /usr/src/sbin/md5/md5.c     2012-06-06 21:42:10.901208101 +0400
+++ md5.c       2012-09-01 17:27:49.957655225 +0400
@@ -20,10 +20,13 @@
 #include <sys/cdefs.h>
 __FBSDID("$FreeBSD$");
 
+#include <sys/param.h>
 #include <sys/types.h>
 #include <sys/time.h>
 #include <sys/resource.h>
+#include <ctype.h>
 #include <err.h>
+#include <getopt.h>
 #include <md5.h>
 #include <ripemd.h>
 #include <sha.h>
@@ -41,6 +44,7 @@
 #define TEST_BLOCK_COUNT 100000
 #define MDTESTCOUNT 8
 
+int fflag;
 int qflag;
 int rflag;
 int sflag;
@@ -73,6 +77,8 @@
 static void MDTestSuite(Algorithm_t *);
 static void MDFilter(Algorithm_t *, int);
 static void usage(Algorithm_t *);
+static void ProcessCheckAgainstFile(char *filename, int *failed, int digest);
+static void strtoupper(char *s);
 
 typedef union {
        MD5_CTX md5;
@@ -85,6 +91,13 @@
        SHA256_DIGEST_LENGTH, RIPEMD160_DIGEST_LENGTH)*2+1 */
 #define HEX_DIGEST_LENGTH 65
 
+/* maximum length of string in controlsum file - digest plus file path
+       plus some dilimiters */
+#define MAX_STRING_LENGTH (HEX_DIGEST_LENGTH+MAXPATHLEN+64)
+
+/* maximum length of algorithm name */
+#define MAX_ALG_LENGTH 10
+
 /* algorithm function table */
 
 struct Algorithm_t Algorithm[] = {
@@ -126,6 +139,9 @@
        int     failed;
        unsigned        digest;
        const char*     progname;
+       struct option longopts[] = { 
+               { "check",no_argument,NULL,'f'}
+        };
 
        if ((progname = strrchr(argv[0], '/')) == NULL)
                progname = argv[0];
@@ -142,11 +158,14 @@
        failed = 0;
        checkAgainst = NULL;
        checksFailed = 0;
-       while ((ch = getopt(argc, argv, "c:pqrs:tx")) != -1)
+       while ((ch = getopt_long(argc, argv, "c:pfqrs:tx",longopts,NULL)) != -1)
                switch (ch) {
                case 'c':
                        checkAgainst = optarg;
                        break;
+               case 'f':
+                       fflag = 1;
+                       break;
                case 'p':
                        MDFilter(&Algorithm[digest], 1);
                        break;
@@ -174,29 +193,35 @@
 
        if (*argv) {
                do {
-                       p = Algorithm[digest].File(*argv, buf);
-                       if (!p) {
-                               warn("%s", *argv);
-                               failed++;
+                       if (fflag){
+                               ProcessCheckAgainstFile(*argv,&failed,digest);
                        } else {
-                               if (qflag)
-                                       printf("%s", p);
-                               else if (rflag)
-                                       printf("%s %s", p, *argv);
-                               else
-                                       printf("%s (%s) = %s",
-                                           Algorithm[digest].name, *argv, p);
-                               if (checkAgainst && strcmp(checkAgainst,p))
-                               {
-                                       checksFailed++;
-                                       if (!qflag)
-                                               printf(" [ Failed ]");
+                               p = Algorithm[digest].File(*argv, buf);
+                               if (!p) {
+                                       warn("%s", *argv);
+                                       failed++;
+                               } else {
+                                       if (qflag)
+                                               printf("%s", p);
+                                       else if (rflag)
+                                               printf("%s %s", p, *argv);
+                                       else
+                                               printf("%s (%s) = %s",
+                                                       Algorithm[digest].name, 
*argv, p);
+                                       if (checkAgainst && 
strcmp(checkAgainst,p))
+                                       {
+                                               checksFailed++;
+                                               if (!qflag)
+                                                       printf(" [ Failed ]");
+                                       }
+                                       printf("\n");
                                }
-                               printf("\n");
                        }
                } while (*++argv);
-       } else if (!sflag && (optind == 1 || qflag || rflag))
+       } else if (!fflag && !sflag && (optind == 1 || qflag || rflag))
                MDFilter(&Algorithm[digest], 0);
+       else if (fflag)
+               ProcessCheckAgainstFile(NULL,&failed,digest);
 
        if (failed != 0)
                return (1);
@@ -205,6 +230,135 @@
 
        return (0);
 }
+
+/*
+ * Reads a file with control sums and filenames and checks them
+ */
+static void
+ProcessCheckAgainstFile(char *filename, int *failed, int digest){
+       char    buf[HEX_DIGEST_LENGTH];
+       char    checkAgainstCur[HEX_DIGEST_LENGTH];
+       char    strar[MAX_STRING_LENGTH+1];
+       char    *cur;
+       char    *str;
+       char    curfname[MAXPATHLEN+1];
+       char    alg[MAX_ALG_LENGTH+1];
+       char    *p;
+       FILE    *fl;
+       int first,next,eq,len,parsed;
+
+       if(filename)
+               fl=fopen(filename,"r");
+       else {
+               fl=stdin;
+       }
+       if(fl){
+               str=&strar[0];
+               bzero(str,MAX_STRING_LENGTH);
+               while(fgets(str,MAX_STRING_LENGTH,fl)){
+                       parsed=0;
+                       bzero(checkAgainstCur,HEX_DIGEST_LENGTH);
+                        bzero(curfname,MAXPATHLEN);
+                       bzero(alg,MAX_ALG_LENGTH);
+
+                       while(isspace(*str)&& *str!='\0')
+                               str++;
+                       first=strcspn(str,"(");
+                       if(first) {
+                               cur=&str[first];
+
+                               next=strlen(str);
+                               while(next>first && str[next]!=')')
+                                 next--;
+                               
+                               if(first&&next && next>first && 
next-first<=MAXPATHLEN){
+                                 strncpy(curfname,&str[first+1],next-first);
+                                 curfname[next-first-1]='\0';
+                                 while(first>0 && isspace(str[first-1]))
+                                       first--;
+                                  if(first<=MAX_ALG_LENGTH){
+                                       strncpy(alg,str,first);
+                                       strtoupper(alg);
+                                       eq=strcspn(&str[next],"=");
+                                       eq++;
+                                       while(isspace(str[eq+next]) && 
str[eq+next]!='\0')
+                                               eq++;
+                                       len=strlen(str);
+                                       while(isspace(str[len])&& len>next)
+                                               len--;
+                                       if(len-next-eq<=HEX_DIGEST_LENGTH){
+                                               
strncpy(checkAgainstCur,&str[eq+next],len-eq-next);
+                                               
checkAgainstCur[len-eq-next-1]='\0';
+                                               parsed=1;
+                                       }
+                                       
+                                        
+                                 }
+
+                               } 
+                                       
+                       } 
+                       if(!parsed) {
+                               first=strcspn(str,"\t ");
+                               if(first && first<=HEX_DIGEST_LENGTH){
+                                       strncpy(checkAgainstCur,str,first);
+                                       checkAgainstCur[first]='\0';
+
+                                       str=&(str[first]);
+                                       while(isspace(*str)&&*str!='\0')
+                                               str++;
+                                       len=strlen(str);
+                                       if(len>MAXPATHLEN)
+                                               len=MAXPATHLEN;
+                                       strncpy(curfname,str,len);
+                                       curfname[len-1]='\0';
+                                       
strncpy(alg,Algorithm[digest].name,MAX_ALG_LENGTH);
+                                       parsed=1;
+                               }
+                       }
+                       if(parsed && 
!strncmp(alg,Algorithm[digest].name,MAX_ALG_LENGTH)) {
+                               p = Algorithm[digest].File(curfname, buf);
+                               if (!p) {       
+                                        warn("%s", curfname);
+                                               failed++;
+                                } else {
+                                       if (qflag)
+                                               printf("%s", p);
+                                        else if (rflag)
+                                                printf("%s %s", p, curfname);
+                                        else
+                                                printf("%s (%s) = %s",
+                                                        
Algorithm[digest].name, curfname, p);
+                                       if (strcmp(checkAgainstCur,p)) {
+                                          checksFailed++;
+                                          if (!qflag)
+                                              printf(" [ Failed ]");
+                                       }
+                                       putchar('\n');
+                               }
+                       } else {
+                               (*failed)++;
+                       }
+                       bzero(str,MAX_STRING_LENGTH);
+                }
+               fclose(fl);
+       } else {
+               (*failed)++;
+       }
+}
+
+/*
+ *  Convert strings to upper case 
+ */
+static void
+strtoupper(char *s){
+       int i;
+               
+       if(s){
+               for(i=0;s[i]!='\0';i++)
+                       s[i]=toupper(s[i]);
+       }
+}
 /*
  * Digests a string and prints the result.
  */
_______________________________________________
freebsd-bugs@freebsd.org mailing list
http://lists.freebsd.org/mailman/listinfo/freebsd-bugs
To unsubscribe, send any mail to "freebsd-bugs-unsubscr...@freebsd.org"

Reply via email to