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"