mirror of
https://github.com/Stichting-MINIX-Research-Foundation/pkgsrc-ng.git
synced 2025-08-04 02:08:49 -04:00
208 lines
5.2 KiB
C
208 lines
5.2 KiB
C
/*-
|
|
* Copyright (c) 2013 Alistair Crooks <agc@NetBSD.org>
|
|
* All rights reserved.
|
|
*
|
|
* Redistribution and use in source and binary forms, with or without
|
|
* modification, are permitted provided that the following conditions
|
|
* are met:
|
|
* 1. Redistributions of source code must retain the above copyright
|
|
* notice, this list of conditions and the following disclaimer.
|
|
* 2. Redistributions in binary form must reproduce the above copyright
|
|
* notice, this list of conditions and the following disclaimer in the
|
|
* documentation and/or other materials provided with the distribution.
|
|
*
|
|
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
|
|
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
|
|
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
|
|
* IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
|
|
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
|
|
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
|
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
|
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
|
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
|
|
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
|
*/
|
|
#include <sys/types.h>
|
|
#include <sys/stat.h>
|
|
#include <sys/param.h>
|
|
|
|
#include <regex.h>
|
|
#include <stdio.h>
|
|
#include <stdlib.h>
|
|
#include <string.h>
|
|
#include <unistd.h>
|
|
|
|
#include "multigest.h"
|
|
|
|
|
|
#define MB(x) ((x) * 1024 * 1024)
|
|
|
|
/* read input into memory, and then multigest that */
|
|
static int
|
|
do_input(const char *alg, uint8_t *raw, const char *pat, const char *repl)
|
|
{
|
|
ssize_t rc;
|
|
size_t cc;
|
|
char *data;
|
|
|
|
if ((data = calloc(1, MB(4))) != NULL) {
|
|
for (cc = 0 ; cc < MB(4) ; cc += (size_t)rc) {
|
|
if ((rc = read(fileno(stdin), &data[cc], MB(4) - cc)) <= 0) {
|
|
break;
|
|
}
|
|
}
|
|
multigest_data(alg, data, cc, raw, pat, repl);
|
|
free(data);
|
|
return 1;
|
|
}
|
|
return 0;
|
|
}
|
|
|
|
/* get the substitution pattern from the arg */
|
|
static int
|
|
getsubst(const char *arg, char *from, size_t fromsize, char *to, size_t tosize)
|
|
{
|
|
const char *sep;
|
|
const char *sub;
|
|
size_t len;
|
|
|
|
for (sep = arg + 1 ; *sep && *sep != *arg ; sep++) {
|
|
if (*sep == '\\') {
|
|
sep += 1;
|
|
}
|
|
}
|
|
len = (size_t)(sep - arg) - 1;
|
|
len = MIN(fromsize - 1, len);
|
|
multigest_unpcstring(arg + 1, len, from, fromsize);
|
|
for (sub = ++sep ; *sep && *sep != *arg ; sep++) {
|
|
if (*sep == '\\') {
|
|
sep += 1;
|
|
}
|
|
}
|
|
len = (size_t)(sep - sub);
|
|
len = MIN(tosize - 1, len);
|
|
multigest_unpcstring(sub, len, to, tosize);
|
|
return 1;
|
|
}
|
|
|
|
/* verify contents of an existing dynamic digest file */
|
|
static int
|
|
read_check(const char *check)
|
|
{
|
|
struct stat st;
|
|
regmatch_t match[10];
|
|
regex_t r;
|
|
uint8_t raw[8192];
|
|
FILE *fp;
|
|
char *provided;
|
|
char calc[8192];
|
|
char from[128];
|
|
char to[128];
|
|
char *file;
|
|
char *subs;
|
|
char *alg;
|
|
char *in;
|
|
int ret;
|
|
|
|
regcomp(&r, "([^ ]+) \\(([^)]+)\\) \\((.*)\\) = ([0-9a-zA-Z]+)", REG_EXTENDED);
|
|
if ((fp = fopen(check, "r")) == NULL) {
|
|
fprintf(stderr, "can't check existing file '%s'\n", check);
|
|
return 0;
|
|
}
|
|
fstat(fileno(fp), &st);
|
|
if ((in = calloc(1, (size_t)(st.st_size + 1))) == NULL) {
|
|
fclose(fp);
|
|
return 0;
|
|
}
|
|
read(fileno(fp), in, (size_t)(st.st_size));
|
|
in[st.st_size] = 0x0;
|
|
fclose(fp);
|
|
if (regexec(&r, in, 10, match, 0) != 0) {
|
|
free(in);
|
|
return 0;
|
|
}
|
|
alg = &in[match[1].rm_so];
|
|
file = &in[match[2].rm_so];
|
|
subs = &in[match[3].rm_so];
|
|
provided = &in[match[4].rm_so];
|
|
in[match[1].rm_eo] = in[match[2].rm_eo] = in[match[3].rm_eo] = in[match[4].rm_eo] = 0x0;
|
|
getsubst(subs, from, sizeof(from), to, sizeof(to));
|
|
multigest_file(alg, file, raw, from, to);
|
|
multigest_format_hex(raw, alg, calc, sizeof(calc));
|
|
if ((ret = memcmp(calc, provided, (size_t)(match[4].rm_eo - match[4].rm_so))) != 0) {
|
|
fprintf(stderr, "multigest: provided digest: '%s', calculated digest: '%s'\n", provided, calc);
|
|
}
|
|
regfree(&r);
|
|
free(in);
|
|
return ret == 0;
|
|
}
|
|
|
|
int
|
|
main(int argc, char **argv)
|
|
{
|
|
const char *outname;
|
|
const char *format;
|
|
const char *check;
|
|
const char *alg;
|
|
const char *sub;
|
|
const char *sep;
|
|
uint8_t raw[8192];
|
|
char from[128];
|
|
char to[128];
|
|
int ok;
|
|
int i;
|
|
|
|
alg = "sha1";
|
|
format = "multigest";
|
|
sep = sub = outname = check = NULL;
|
|
from[0] = to[0] = 0x0;
|
|
while ((i = getopt(argc, argv, "F:S:a:c:o:rs:")) != -1) {
|
|
switch(i) {
|
|
case 'F':
|
|
format = optarg;
|
|
break;
|
|
case 'S':
|
|
sep = optarg;
|
|
break;
|
|
case 'a':
|
|
alg = optarg;
|
|
break;
|
|
case 'c':
|
|
check = optarg;
|
|
break;
|
|
case 'o':
|
|
outname = optarg;
|
|
break;
|
|
case 'r':
|
|
getsubst(sub = ",\\$(Id|NetBSD)[^\n]*\\$,\044NetBSD\044", from, sizeof(from), to, sizeof(to));
|
|
break;
|
|
case 's':
|
|
getsubst(sub = optarg, from, sizeof(from), to, sizeof(to));
|
|
break;
|
|
default:
|
|
break;
|
|
}
|
|
}
|
|
ok = 1;
|
|
if (check) {
|
|
if (!read_check(check)) {
|
|
ok = 0;
|
|
}
|
|
} else if (optind == argc) {
|
|
if (do_input(alg, raw, from, to)) {
|
|
multigest_print_hex(raw, alg, outname, NULL, sub, sep, format);
|
|
} else {
|
|
ok = 0;
|
|
}
|
|
} else {
|
|
for (i = optind ; i < argc ; i++) {
|
|
if (multigest_file(alg, argv[i], raw, from, to) == NULL) {
|
|
ok = 0;
|
|
} else {
|
|
multigest_print_hex(raw, alg, outname, argv[i], sub, sep, format);
|
|
}
|
|
}
|
|
}
|
|
exit((ok) ? EXIT_SUCCESS : EXIT_FAILURE);
|
|
}
|