diff --git a/sbin/md5/md5.c b/sbin/md5/md5.c --- a/sbin/md5/md5.c +++ b/sbin/md5/md5.c @@ -158,6 +158,45 @@ MD5Update(c, data, len); } +struct chksumrec { + char *filename; + char *chksum; + struct chksumrec *next; +}; + +static struct chksumrec *head; + +static int gnu_check(const char *checksumsfile) +{ + FILE *inp; + char sum[257]; /* 1024 bit hash as hex number string */ + char file[1025]; /* MAXPATHLEN + 1 to allow for leading '*' */ + int lineno; + struct chksumrec *rec; + + if ((inp = fopen(checksumsfile, "r")) == NULL) + err(3, "%s", checksumsfile); + head = NULL; + lineno = 1; + while (!feof(inp)) { + if (fscanf(inp, "%256s %1024s\n", sum, file) != 2) { + errx(3, "malformed input line %d", lineno); + } + rec = malloc(sizeof (*rec)); + if (rec == NULL) + errx(1, "malloc failed"); + rec->chksum = strdup(sum); + rec->filename = strdup(*file == '*' ? file + 1 : file); + if (rec->chksum == NULL || rec->filename == NULL) + errx(1, "malloc failed"); + rec->next = head; + head = rec; + lineno++; + } + fclose(inp); + return (lineno - 1); +} + /* Main driver. Arguments (may be any combination): @@ -180,6 +219,8 @@ unsigned digest; char *progname; bool gnu_emu = false; + struct chksumrec *rec; + int numrecs; if ((progname = strrchr(argv[0], '/')) == NULL) progname = argv[0]; @@ -221,8 +262,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 +300,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 +331,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);