Page Menu
Home
FreeBSD
Search
Configure Global Search
Log In
Files
F131854018
D30812.id91085.diff
No One
Temporary
Actions
View File
Edit File
Delete File
View Transforms
Subscribe
Mute Notifications
Flag For Later
Award Token
Size
5 KB
Referenced Files
None
Subscribers
None
D30812.id91085.diff
View Options
diff --git a/sbin/md5/md5.c b/sbin/md5/md5.c
--- a/sbin/md5/md5.c
+++ b/sbin/md5/md5.c
@@ -152,12 +152,93 @@
(DIGEST_End*)&SKEIN1024_End, &SKEIN1024_Data, &SKEIN1024_Fd }
};
+static unsigned digest;
+static unsigned malformed;
+static bool gnu_emu = false;
+
static void
MD5_Update(MD5_CTX *c, const unsigned char *data, size_t len)
{
MD5Update(c, data, len);
}
+struct chksumrec {
+ char *filename;
+ char *chksum;
+ struct chksumrec *next;
+};
+
+static struct chksumrec *head = NULL;
+static struct chksumrec **next = &head;
+
+#define PADDING 7 /* extra padding for "SHA512t256 (...) = ...\n" style */
+#define CHKFILELINELEN (HEX_DIGEST_LENGTH + MAXPATHLEN + PADDING)
+
+static int gnu_check(const char *checksumsfile)
+{
+ FILE *inp;
+ char linebuf[CHKFILELINELEN];
+ int linelen;
+ int lineno;
+ char *filename;
+ char *hashstr;
+ struct chksumrec *rec;
+ const char *digestname;
+ int digestnamelen;
+ int hashstrlen;
+
+ if ((inp = fopen(checksumsfile, "r")) == NULL)
+ err(1, "%s", checksumsfile);
+ digestname = Algorithm[digest].name;
+ digestnamelen = strlen(digestname);
+ hashstrlen = strlen(*(Algorithm[digest].TestOutput[0]));
+ lineno = 1;
+ while (fgets(linebuf, sizeof(linebuf), inp) != NULL) {
+ linelen = strlen(linebuf) - 1;
+ if (linelen <= 0)
+ break;
+ if (linebuf[linelen] != '\n')
+ errx(1, "malformed input line %d (len=%d)", lineno, linelen);
+ linebuf[linelen] = '\0';
+ filename = linebuf + digestnamelen + 2;
+ hashstr = linebuf + linelen - hashstrlen;
+ /*
+ * supported formats:
+ * BSD: <DigestName> (<Filename>): <Digest>
+ * GNU: <Digest> [ *]<Filename>
+ */
+ if (linelen >= digestnamelen + hashstrlen + 6 &&
+ strncmp(linebuf, digestname, digestnamelen) == 0 &&
+ strncmp(filename - 2, " (", 2) == 0 &&
+ strncmp(hashstr - 4, ") = ", 4) == 0) {
+ *(hashstr - 4) = '\0';
+ } else if (linelen >= hashstrlen + 3 &&
+ linebuf[hashstrlen] == ' ' &&
+ (linebuf[hashstrlen] == ' ' ||
+ linebuf[hashstrlen] == '*')) {
+ linebuf[hashstrlen] = '\0';
+ hashstr = linebuf;
+ filename = linebuf + hashstrlen + 2;
+ } else {
+ malformed++;
+ continue;
+ }
+ rec = malloc(sizeof (*rec));
+ if (rec == NULL)
+ errx(1, "malloc failed");
+ rec->chksum = strdup(hashstr);
+ rec->filename = strdup(filename);
+ if (rec->chksum == NULL || rec->filename == NULL)
+ errx(1, "malloc failed");
+ rec->next = NULL;
+ *next = rec;
+ next = &rec->next;
+ lineno++;
+ }
+ fclose(inp);
+ return (lineno - 1);
+}
+
/* Main driver.
Arguments (may be any combination):
@@ -177,9 +258,9 @@
char *p, *string;
char buf[HEX_DIGEST_LENGTH];
size_t len;
- unsigned digest;
char *progname;
- bool gnu_emu = false;
+ struct chksumrec *rec;
+ int numrecs;
if ((progname = strrchr(argv[0], '/')) == NULL)
progname = argv[0];
@@ -199,13 +280,13 @@
*/
len = strlen(progname);
if (len > 3 && strcmp(progname + len - 3, "sum") == 0) {
- progname[len - 3] = '\0';
+ len -= 3;
rflag = 1;
gnu_emu = true;
}
for (digest = 0; digest < sizeof(Algorithm)/sizeof(*Algorithm); digest++)
- if (strcasecmp(Algorithm[digest].progname, progname) == 0)
+ if (strncasecmp(Algorithm[digest].progname, progname, len) == 0)
break;
if (digest == sizeof(Algorithm)/sizeof(*Algorithm))
@@ -221,8 +302,9 @@
break;
case 'c':
if (gnu_emu)
- errx(1, "-c check option not supported");
- checkAgainst = optarg;
+ numrecs = gnu_check(optarg);
+ else
+ checkAgainst = optarg;
break;
case 'p':
pflag = 1;
@@ -258,6 +340,16 @@
err(1, "unable to limit rights for stdio");
#endif
+ if (gnu_emu) {
+ argc = 0;
+ argv = (char**)calloc(sizeof(char *), numrecs + 1);
+ for (rec = head; rec != NULL; rec = rec->next) {
+ argv[argc] = rec->filename;
+ argc++;
+ }
+ rec = head;
+ }
+
if (*argv) {
do {
if ((fd = open(*argv, O_RDONLY)) < 0) {
@@ -279,6 +371,10 @@
err(1, "capsicum");
#endif
}
+ if (gnu_emu) {
+ checkAgainst = rec->chksum;
+ rec = rec->next;
+ }
p = Algorithm[digest].Fd(fd, buf);
(void)close(fd);
MDOutput(&Algorithm[digest], p, argv);
@@ -295,7 +391,12 @@
p = Algorithm[digest].Data(string, len, buf);
MDOutput(&Algorithm[digest], p, &string);
}
-
+ if (gnu_emu) {
+ if (malformed > 0)
+ warnx("WARNING: %d lines are improperly formatted", malformed);
+ if (checksFailed > 0)
+ warnx("WARNING: %d computed checksum did NOT match", checksFailed);
+ }
if (failed != 0)
return (1);
if (checksFailed != 0)
@@ -310,6 +411,8 @@
static void
MDOutput(const Algorithm_t *alg, char *p, char *argv[])
{
+ bool checkfailed = false;
+
if (p == NULL) {
warn("%s", *argv);
failed++;
@@ -318,21 +421,26 @@
* If argv is NULL we are reading from stdin, where the output
* format has always been just the hash.
*/
- if (qflag || argv == NULL)
+ if (qflag || argv == NULL) {
printf("%s", p);
- else if (rflag)
- printf("%s %s", p, *argv);
- else
- printf("%s (%s) = %s",
- alg->name, *argv, p);
- if (checkAgainst && strcasecmp(checkAgainst, p) != 0)
- {
- checksFailed++;
- if (!qflag)
- printf(" [ Failed ]");
+ } else if (gnu_emu) {
+ checkfailed = strcasecmp(checkAgainst, p) != 0;
+ printf("%s: %s", *argv, checkfailed ? "FAILED" : "OK");
+ } else {
+ if (rflag)
+ printf("%s %s", p, *argv);
+ else
+ printf("%s (%s) = %s", alg->name, *argv, p);
+ if (checkAgainst) {
+ checkfailed = strcasecmp(checkAgainst, p) != 0;
+ if (!qflag && checkfailed)
+ printf(" [ Failed ]");
+ }
}
printf("\n");
}
+ if (checkfailed)
+ checksFailed++;
}
/*
@@ -559,6 +667,9 @@
usage(const Algorithm_t *alg)
{
- fprintf(stderr, "usage: %s [-pqrtx] [-c string] [-s string] [files ...]\n", alg->progname);
+ if (gnu_emu)
+ fprintf(stderr, "usage: %ssum [-pqrtx] [-c file] [-s string] [files ...]\n", alg->progname);
+ else
+ fprintf(stderr, "usage: %s [-pqrtx] [-c string] [-s string] [files ...]\n", alg->progname);
exit(1);
}
File Metadata
Details
Attached
Mime Type
text/plain
Expires
Sun, Oct 12, 5:36 PM (1 h, 9 m)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
23633235
Default Alt Text
D30812.id91085.diff (5 KB)
Attached To
Mode
D30812: Add support for -c option to sha256sum et.al.
Attached
Detach File
Event Timeline
Log In to Comment