summaryrefslogtreecommitdiffstats
path: root/usr.sbin/ckdist/ckdist.c
diff options
context:
space:
mode:
Diffstat (limited to 'usr.sbin/ckdist/ckdist.c')
-rw-r--r--usr.sbin/ckdist/ckdist.c445
1 files changed, 0 insertions, 445 deletions
diff --git a/usr.sbin/ckdist/ckdist.c b/usr.sbin/ckdist/ckdist.c
deleted file mode 100644
index dcaa9f3..0000000
--- a/usr.sbin/ckdist/ckdist.c
+++ /dev/null
@@ -1,445 +0,0 @@
-/*
- * Copyright (c) 1997 Robert Nordier
- * 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(S) ``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(S) 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.
- */
-
-#ifndef lint
-static const char rcsid[] =
- "$FreeBSD$";
-#endif /* not lint */
-
-#include <sys/types.h>
-#include <sys/stat.h>
-
-#include <err.h>
-#include <errno.h>
-#include <fcntl.h>
-#include <fts.h>
-#include <md5.h>
-#include <stdio.h>
-#include <stdint.h>
-#include <stdlib.h>
-#include <string.h>
-#include <unistd.h>
-
-extern int crc(int fd, uint32_t *cval, off_t *clen);
-
-#define DISTMD5 1 /* MD5 format */
-#define DISTINF 2 /* .inf format */
-#define DISTTYPES 2 /* types supported */
-
-#define E_UNKNOWN 1 /* Unknown format */
-#define E_BADMD5 2 /* Invalid MD5 format */
-#define E_BADINF 3 /* Invalid .inf format */
-#define E_NAME 4 /* Can't derive component name */
-#define E_LENGTH 5 /* Length mismatch */
-#define E_CHKSUM 6 /* Checksum mismatch */
-#define E_ERRNO 7 /* sys_errlist[errno] */
-
-#define isfatal(err) ((err) && (err) <= E_NAME)
-
-#define NAMESIZE 256 /* filename buffer size */
-#define MDSUMLEN 32 /* length of MD5 message digest */
-
-#define isstdin(path) ((path)[0] == '-' && !(path)[1])
-
-static const char *opt_dir; /* where to look for components */
-static const char *opt_name; /* name for accessing components */
-static int opt_all; /* report on all components */
-static int opt_ignore; /* ignore missing components */
-static int opt_recurse; /* search directories recursively */
-static int opt_silent; /* silent about inaccessible files */
-static int opt_type; /* dist type: md5 or inf */
-static int opt_exist; /* just verify existence */
-
-static int ckdist(const char *path, int type);
-static int chkmd5(FILE * fp, const char *path);
-static int chkinf(FILE * fp, const char *path);
-static int report(const char *path, const char *name, int error);
-static const char *distname(const char *path, const char *name,
- const char *ext);
-static const char *stripath(const char *path);
-static int distfile(const char *path);
-static int disttype(const char *name);
-static int fail(const char *path, const char *msg);
-static void usage(void);
-
-int
-main(int argc, char *argv[])
-{
- static char *arg[2];
- struct stat sb;
- FTS *ftsp;
- FTSENT *f;
- int rval, c, type;
-
- while ((c = getopt(argc, argv, "ad:in:rst:x")) != -1)
- switch (c) {
- case 'a':
- opt_all = 1;
- break;
- case 'd':
- opt_dir = optarg;
- break;
- case 'i':
- opt_ignore = 1;
- break;
- case 'n':
- opt_name = optarg;
- break;
- case 'r':
- opt_recurse = 1;
- break;
- case 's':
- opt_silent = 1;
- break;
- case 't':
- if ((opt_type = disttype(optarg)) == 0) {
- warnx("illegal argument to -t option");
- usage();
- }
- break;
- case 'x':
- opt_exist = 1;
- break;
- default:
- usage();
- }
- argc -= optind;
- argv += optind;
- if (argc < 1)
- usage();
- if (opt_dir) {
- if (stat(opt_dir, &sb))
- err(2, "%s", opt_dir);
- if (!S_ISDIR(sb.st_mode))
- errx(2, "%s: not a directory", opt_dir);
- }
- rval = 0;
- do {
- if (isstdin(*argv))
- rval |= ckdist(*argv, opt_type);
- else if (stat(*argv, &sb))
- rval |= fail(*argv, NULL);
- else if (S_ISREG(sb.st_mode))
- rval |= ckdist(*argv, opt_type);
- else {
- arg[0] = *argv;
- if ((ftsp = fts_open(arg, FTS_LOGICAL, NULL)) == NULL)
- err(2, "fts_open");
- while ((f = fts_read(ftsp)) != NULL)
- switch (f->fts_info) {
- case FTS_DC:
- rval = fail(f->fts_path, "Directory causes a cycle");
- break;
- case FTS_DNR:
- case FTS_ERR:
- case FTS_NS:
- rval = fail(f->fts_path, sys_errlist[f->fts_errno]);
- break;
- case FTS_D:
- if (!opt_recurse && f->fts_level > FTS_ROOTLEVEL &&
- fts_set(ftsp, f, FTS_SKIP))
- err(2, "fts_set");
- break;
- case FTS_F:
- if ((type = distfile(f->fts_name)) != 0 &&
- (!opt_type || type == opt_type))
- rval |= ckdist(f->fts_path, type);
- break;
- default: ;
- }
- if (errno)
- err(2, "fts_read");
- if (fts_close(ftsp))
- err(2, "fts_close");
- }
- } while (*++argv);
- return rval;
-}
-
-static int
-ckdist(const char *path, int type)
-{
- FILE *fp;
- int rval, c;
-
- if (isstdin(path)) {
- path = "(stdin)";
- fp = stdin;
- } else if ((fp = fopen(path, "r")) == NULL)
- return fail(path, NULL);
- if (!type) {
- if (fp != stdin)
- type = distfile(path);
- if (!type)
- if ((c = fgetc(fp)) != EOF) {
- type = c == 'M' ? DISTMD5 : c == 'P' ? DISTINF : 0;
- (void)ungetc(c, fp);
- }
- }
- switch (type) {
- case DISTMD5:
- rval = chkmd5(fp, path);
- break;
- case DISTINF:
- rval = chkinf(fp, path);
- break;
- default:
- rval = report(path, NULL, E_UNKNOWN);
- }
- if (ferror(fp))
- warn("%s", path);
- if (fp != stdin && fclose(fp))
- err(2, "%s", path);
- return rval;
-}
-
-static int
-chkmd5(FILE * fp, const char *path)
-{
- char buf[298]; /* "MD5 (NAMESIZE = MDSUMLEN" */
- char name[NAMESIZE + 1];
- char sum[MDSUMLEN + 1], chk[MDSUMLEN + 1];
- const char *dname;
- char *s;
- int rval, error, c, fd;
- char ch;
-
- rval = 0;
- while (fgets(buf, sizeof(buf), fp)) {
- dname = NULL;
- error = 0;
- if (((c = sscanf(buf, "MD5 (%256s = %32s%c", name, sum,
- &ch)) != 3 && (!feof(fp) || c != 2)) ||
- (c == 3 && ch != '\n') ||
- (s = strrchr(name, ')')) == NULL ||
- strlen(sum) != MDSUMLEN)
- error = E_BADMD5;
- else {
- *s = 0;
- if ((dname = distname(path, name, NULL)) == NULL)
- error = E_NAME;
- else if (opt_exist) {
- if ((fd = open(dname, O_RDONLY)) == -1)
- error = E_ERRNO;
- else if (close(fd))
- err(2, "%s", dname);
- } else if (!MD5File(dname, chk))
- error = E_ERRNO;
- else if (strcmp(chk, sum))
- error = E_CHKSUM;
- }
- if (opt_ignore && error == E_ERRNO && errno == ENOENT)
- continue;
- if (error || opt_all)
- rval |= report(path, dname, error);
- if (isfatal(error))
- break;
- }
- return rval;
-}
-
-static int
-chkinf(FILE * fp, const char *path)
-{
- char buf[30]; /* "cksum.2 = 10 6" */
- char ext[3];
- struct stat sb;
- const char *dname;
- off_t len;
- u_long sum;
- intmax_t sumlen;
- uint32_t chk;
- int rval, error, c, pieces, cnt, fd;
- char ch;
-
- rval = 0;
- for (cnt = -1; fgets(buf, sizeof(buf), fp); cnt++) {
- fd = -1;
- dname = NULL;
- error = 0;
- if (cnt == -1) {
- if ((c = sscanf(buf, "Pieces = %d%c", &pieces, &ch)) != 2 ||
- ch != '\n' || pieces < 1)
- error = E_BADINF;
- } else if (((c = sscanf(buf, "cksum.%2s = %lu %jd%c", ext, &sum,
- &sumlen, &ch)) != 4 &&
- (!feof(fp) || c != 3)) || (c == 4 && ch != '\n') ||
- ext[0] != 'a' + cnt / 26 || ext[1] != 'a' + cnt % 26)
- error = E_BADINF;
- else if ((dname = distname(fp == stdin ? NULL : path, NULL,
- ext)) == NULL)
- error = E_NAME;
- else if ((fd = open(dname, O_RDONLY)) == -1)
- error = E_ERRNO;
- else if (fstat(fd, &sb))
- error = E_ERRNO;
- else if (sb.st_size != (off_t)sumlen)
- error = E_LENGTH;
- else if (!opt_exist) {
- if (crc(fd, &chk, &len))
- error = E_ERRNO;
- else if (chk != sum)
- error = E_CHKSUM;
- }
- if (fd != -1 && close(fd))
- err(2, "%s", dname);
- if (opt_ignore && error == E_ERRNO && errno == ENOENT)
- continue;
- if (error || (opt_all && cnt >= 0))
- rval |= report(path, dname, error);
- if (isfatal(error))
- break;
- }
- return rval;
-}
-
-static int
-report(const char *path, const char *name, int error)
-{
- if (name)
- name = stripath(name);
- switch (error) {
- case E_UNKNOWN:
- printf("%s: Unknown format\n", path);
- break;
- case E_BADMD5:
- printf("%s: Invalid MD5 format\n", path);
- break;
- case E_BADINF:
- printf("%s: Invalid .inf format\n", path);
- break;
- case E_NAME:
- printf("%s: Can't derive component name\n", path);
- break;
- case E_LENGTH:
- printf("%s: %s: Size mismatch\n", path, name);
- break;
- case E_CHKSUM:
- printf("%s: %s: Checksum mismatch\n", path, name);
- break;
- case E_ERRNO:
- printf("%s: %s: %s\n", path, name, sys_errlist[errno]);
- break;
- default:
- printf("%s: %s: OK\n", path, name);
- }
- return error != 0;
-}
-
-static const char *
-distname(const char *path, const char *name, const char *ext)
-{
- static char buf[NAMESIZE];
- size_t plen, nlen;
- char *s;
-
- if (opt_name)
- name = opt_name;
- else if (!name) {
- if (!path)
- return NULL;
- name = stripath(path);
- }
- nlen = strlen(name);
- if (ext && nlen > 4 && name[nlen - 4] == '.' &&
- disttype(name + nlen - 3) == DISTINF)
- nlen -= 4;
- if (opt_dir) {
- path = opt_dir;
- plen = strlen(path);
- } else
- plen = path && (s = strrchr(path, '/')) != NULL ?
- (size_t)(s - path) : 0;
- if (plen + (plen > 0) + nlen + (ext ? 3 : 0) >= sizeof(buf))
- return NULL;
- s = buf;
- if (plen) {
- memcpy(s, path, plen);
- s += plen;
- *s++ = '/';
- }
- memcpy(s, name, nlen);
- s += nlen;
- if (ext) {
- *s++ = '.';
- memcpy(s, ext, 2);
- s += 2;
- }
- *s = 0;
- return buf;
-}
-
-static const char *
-stripath(const char *path)
-{
- const char *s;
-
- return ((s = strrchr(path, '/')) != NULL && s[1] ?
- s + 1 : path);
-}
-
-static int
-distfile(const char *path)
-{
- const char *s;
- int type;
-
- if ((type = disttype(path)) == DISTMD5 ||
- ((s = strrchr(path, '.')) != NULL && s > path &&
- (type = disttype(s + 1)) != 0))
- return type;
- return 0;
-}
-
-static int
-disttype(const char *name)
-{
- static const char dname[DISTTYPES][4] = {"md5", "inf"};
- int i;
-
- for (i = 0; i < DISTTYPES; i++)
- if (!strcmp(dname[i], name))
- return 1 + i;
- return 0;
-}
-
-static int
-fail(const char *path, const char *msg)
-{
- if (opt_silent)
- return 0;
- warnx("%s: %s", path, msg ? msg : sys_errlist[errno]);
- return 2;
-}
-
-static void
-usage(void)
-{
- fprintf(stderr,
- "usage: ckdist [-airsx] [-d dir] [-n name] [-t type] file ...\n");
- exit(2);
-}
OpenPOWER on IntegriCloud