Page Menu
Home
FreeBSD
Search
Configure Global Search
Log In
Files
F147669110
D30812.id91094.diff
No One
Temporary
Actions
View File
Edit File
Delete File
View Transforms
Subscribe
Mute Notifications
Flag For Later
Award Token
Size
7 KB
Referenced Files
None
Subscribers
None
D30812.id91094.diff
View Options
diff --git a/sbin/md5/md5.1 b/sbin/md5/md5.1
--- a/sbin/md5/md5.1
+++ b/sbin/md5/md5.1
@@ -1,5 +1,5 @@
.\" $FreeBSD$
-.Dd May 19, 2021
+.Dd June 19, 2021
.Dt MD5 1
.Os
.Sh NAME
@@ -15,6 +15,12 @@
.Op Fl s Ar string
.Op Ar
.Pp
+.Nm md5sum
+.Op Fl pqrtx
+.Op Fl c Ar file
+.Op Fl s Ar string
+.Op Ar
+.Pp
(All other hashes have the same options and usage.)
.Sh DESCRIPTION
The
@@ -75,13 +81,15 @@
.Nm -sum
programs.
.It Fl c Ar string
-Compare the digest of the file against this string.
+If the program was called with a name that does not end in "sum",
+compare the digest of the file against this string.
.Pq Note that this option is not yet useful if multiple files are specified.
-This option causes an error in for the
-.Nm -sum
-programs because it check the checksums listed in a file for the coreutils
-.Nm -sum
-programs that is not yet implemented.
+.It Fl c Ar file
+If the program was called with a name that does end in "sum", the file passed
+as argument must contain digest lines generated by the same digest algorithm
+with or without the
+.Fl r
+option.
.It Fl s Ar string
Print a checksum of the given
.Ar string .
diff --git a/sbin/md5/md5.c b/sbin/md5/md5.c
--- a/sbin/md5/md5.c
+++ b/sbin/md5/md5.c
@@ -53,6 +53,7 @@
#define TEST_BLOCK_COUNT 100000
#define MDTESTCOUNT 8
+static int cflag;
static int pflag;
static int qflag;
static int rflag;
@@ -152,12 +153,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] = '\0';
+ hashstr = linebuf;
+ filename = linebuf + hashstrlen + 1;
+ if (*filename == ' ' || *filename == '*')
+ filename++;
+ } 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 +259,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 +281,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))
@@ -220,9 +302,11 @@
case 'b':
break;
case 'c':
+ cflag = 1;
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 +342,20 @@
err(1, "unable to limit rights for stdio");
#endif
+ if (cflag && gnu_emu) {
+ /*
+ * Replace argv by an array of filenames from the digest file
+ */
+ argc = 0;
+ argv = (char**)calloc(sizeof(char *), numrecs + 1);
+ for (rec = head; rec != NULL; rec = rec->next) {
+ argv[argc] = rec->filename;
+ argc++;
+ }
+ argv[argc] = NULL;
+ rec = head;
+ }
+
if (*argv) {
do {
if ((fd = open(*argv, O_RDONLY)) < 0) {
@@ -279,11 +377,15 @@
err(1, "capsicum");
#endif
}
+ if (cflag && gnu_emu) {
+ checkAgainst = rec->chksum;
+ rec = rec->next;
+ }
p = Algorithm[digest].Fd(fd, buf);
(void)close(fd);
MDOutput(&Algorithm[digest], p, argv);
} while (*++argv);
- } else if (!sflag && !skip) {
+ } else if (!cflag && !sflag && !skip) {
#ifdef HAVE_CAPSICUM
if (caph_limit_stdin() < 0 || caph_enter() < 0)
err(1, "capsicum");
@@ -295,7 +397,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 +417,8 @@
static void
MDOutput(const Algorithm_t *alg, char *p, char *argv[])
{
+ bool checkfailed = false;
+
if (p == NULL) {
warn("%s", *argv);
failed++;
@@ -318,21 +427,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 (cflag && 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 +673,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
Fri, Mar 13, 6:38 PM (36 m, 40 s)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
29631634
Default Alt Text
D30812.id91094.diff (7 KB)
Attached To
Mode
D30812: Add support for -c option to sha256sum et.al.
Attached
Detach File
Event Timeline
Log In to Comment