Refactor cryptcheck() to allow multiple list-files and stdin

Previously, it was not possible to use

sha1sum test.c | sha1sum -c

because the program would not differenciate between an empty
argument and a non-specified argument.
Moreover, why not allow this?

sha1sum -c hashlist1 hashlist2

Digging deeper I found that using function pointers and a
modification in the crypt-backend might simplify the program
a lot by passing the argument-list to both cryptmain and
cryptcheck.
Allowing more than one list-file to be specified is also
consistent with what the other implementations support,
so we not only have simpler code, we also do not silently
break if there's a script around passing multiple files to
check.
This commit is contained in:
FRIGN 2015-03-01 22:51:52 +01:00
parent 0226c05105
commit 9b06720f62
6 changed files with 56 additions and 53 deletions

View File

@ -6,7 +6,7 @@ struct crypt_ops {
void *s;
};
int cryptcheck(char *, int, char **, struct crypt_ops *, uint8_t *, size_t);
int cryptcheck(int, char **, struct crypt_ops *, uint8_t *, size_t);
int cryptmain(int, char **, struct crypt_ops *, uint8_t *, size_t);
int cryptsum(struct crypt_ops *, FILE *, const char *, uint8_t *);
void mdprint(const uint8_t *, const char *, size_t);

View File

@ -37,27 +37,21 @@ mdcheckline(const char *s, uint8_t *md, size_t sz)
return (i == sz) ? 1 : 0;
}
int
cryptcheck(char *sumfile, int argc, char *argv[],
struct crypt_ops *ops, uint8_t *md, size_t sz)
{
FILE *cfp, *fp;
char *line = NULL, *file, *p;
int r, nonmatch = 0, formatsucks = 0, noread = 0, ret = 0;
static void
mdchecklist(FILE *listfp, struct crypt_ops *ops, uint8_t *md, size_t sz,
int *formatsucks, int *noread, int *nonmatch) {
FILE *fp;
size_t bufsiz = 0;
int r;
char *line = NULL, *file, *p;
if (!sumfile)
cfp = stdin;
else if (!(cfp = fopen(sumfile, "r")))
eprintf("fopen %s:", sumfile);
while (getline(&line, &bufsiz, cfp) != -1) {
while (getline(&line, &bufsiz, listfp) != -1) {
if (!(file = strstr(line, " "))) {
formatsucks++;
(*formatsucks)++;
continue;
}
if ((file - line) / 2 != sz) {
formatsucks++; /* checksum length mismatch */
(*formatsucks)++; /* checksum length mismatch */
continue;
}
*file = '\0';
@ -66,7 +60,7 @@ cryptcheck(char *sumfile, int argc, char *argv[],
*p = '\0';
if (!(fp = fopen(file, "r"))) {
weprintf("fopen %s:", file);
noread++;
(*noread)++;
continue;
}
cryptsum(ops, fp, file, md);
@ -75,33 +69,53 @@ cryptcheck(char *sumfile, int argc, char *argv[],
printf("%s: OK\n", file);
} else if (r == 0) {
printf("%s: FAILED\n", file);
nonmatch++;
(*nonmatch)++;
} else {
formatsucks++;
(*formatsucks)++;
}
fclose(fp);
}
if (sumfile)
fclose(cfp);
free(line);
if (formatsucks > 0) {
}
int
cryptcheck(int argc, char *argv[], struct crypt_ops *ops, uint8_t *md, size_t sz)
{
FILE *fp;
int formatsucks = 0, noread = 0, nonmatch = 0, ret = 0;
if (argc == 0) {
mdchecklist(stdin, ops, md, sz, &formatsucks, &noread, &nonmatch);
} else {
for (; argc > 0; argc--, argv++) {
if (!(fp = fopen(*argv, "r"))) {
weprintf("fopen %s:", *argv);
ret = 1;
continue;
}
mdchecklist(fp, ops, md, sz, &formatsucks, &noread, &nonmatch);
fclose(fp);
}
}
if (formatsucks) {
weprintf("%d lines are improperly formatted\n", formatsucks);
ret = 1;
}
if (noread > 0) {
if (noread) {
weprintf("%d listed file could not be read\n", noread);
ret = 1;
}
if (nonmatch > 0) {
if (nonmatch) {
weprintf("%d computed checksums did NOT match\n", nonmatch);
ret = 1;
}
return ret;
}
int
cryptmain(int argc, char *argv[],
struct crypt_ops *ops, uint8_t *md, size_t sz)
cryptmain(int argc, char *argv[], struct crypt_ops *ops, uint8_t *md, size_t sz)
{
FILE *fp;
int ret = 0;
@ -110,7 +124,7 @@ cryptmain(int argc, char *argv[],
cryptsum(ops, stdin, "<stdin>", md);
mdprint(md, "<stdin>", sz);
} else {
for (; argc > 0; argc--) {
for (; argc > 0; argc--, argv++) {
if (!(fp = fopen(*argv, "r"))) {
weprintf("fopen %s:", *argv);
ret = 1;
@ -121,7 +135,6 @@ cryptmain(int argc, char *argv[],
else
mdprint(md, *argv, sz);
fclose(fp);
argv++;
}
}
return ret;

View File

@ -24,20 +24,16 @@ usage(void)
int
main(int argc, char *argv[])
{
int (*cryptfunc)(int, char **, struct crypt_ops *, uint8_t *, size_t) = cryptmain;
uint8_t md[MD5_DIGEST_LENGTH];
char *checkfile = NULL;
int cflag = 0;
ARGBEGIN {
case 'c':
cflag = 1;
checkfile = ARGF();
cryptfunc = cryptcheck;
break;
default:
usage();
} ARGEND;
if (cflag)
return cryptcheck(checkfile, argc, argv, &md5_ops, md, sizeof(md));
return cryptmain(argc, argv, &md5_ops, md, sizeof(md));
return cryptfunc(argc, argv, &md5_ops, md, sizeof(md));
}

View File

@ -17,24 +17,22 @@ struct crypt_ops sha1_ops = {
static void
usage(void)
{
eprintf("usage: %s [-c] [file...]\n", argv0);
eprintf("usage: %s [-c] [file ...]\n", argv0);
}
int
main(int argc, char *argv[])
{
int (*cryptfunc)(int, char **, struct crypt_ops *, uint8_t *, size_t) = cryptmain;
uint8_t md[SHA1_DIGEST_LENGTH];
char *checkfile = NULL;
ARGBEGIN {
case 'c':
checkfile = ARGF();
cryptfunc = cryptcheck;
break;
default:
usage();
} ARGEND;
if (checkfile)
return cryptcheck(checkfile, argc, argv, &sha1_ops, md, sizeof(md));
return cryptmain(argc, argv, &sha1_ops, md, sizeof(md));
return cryptfunc(argc, argv, &sha1_ops, md, sizeof(md));
}

View File

@ -17,24 +17,22 @@ struct crypt_ops sha256_ops = {
static void
usage(void)
{
eprintf("usage: %s [-c] [file...]\n", argv0);
eprintf("usage: %s [-c] [file ...]\n", argv0);
}
int
main(int argc, char *argv[])
{
int (*cryptfunc)(int, char **, struct crypt_ops *, uint8_t *, size_t) = cryptmain;
uint8_t md[SHA256_DIGEST_LENGTH];
char *checkfile = NULL;
ARGBEGIN {
case 'c':
checkfile = ARGF();
cryptfunc = cryptcheck;
break;
default:
usage();
} ARGEND;
if (checkfile)
return cryptcheck(checkfile, argc, argv, &sha256_ops, md, sizeof(md));
return cryptmain(argc, argv, &sha256_ops, md, sizeof(md));
return cryptfunc(argc, argv, &sha256_ops, md, sizeof(md));
}

View File

@ -17,24 +17,22 @@ struct crypt_ops sha512_ops = {
static void
usage(void)
{
eprintf("usage: %s [-c] [file...]\n", argv0);
eprintf("usage: %s [-c] [file ...]\n", argv0);
}
int
main(int argc, char *argv[])
{
int (*cryptfunc)(int, char **, struct crypt_ops *, uint8_t *, size_t) = cryptmain;
uint8_t md[SHA512_DIGEST_LENGTH];
char *checkfile = NULL;
ARGBEGIN {
case 'c':
checkfile = ARGF();
cryptfunc = cryptcheck;
break;
default:
usage();
} ARGEND;
if (checkfile)
return cryptcheck(checkfile, argc, argv, &sha512_ops, md, sizeof(md));
return cryptmain(argc, argv, &sha512_ops, md, sizeof(md));
return cryptfunc(argc, argv, &sha512_ops, md, sizeof(md));
}