commit 027052f5e51dbdcdbe0a0ba6c09e21213df1fb77
Author: sin <[email protected]>
Date:   Mon Nov 17 16:48:01 2014 +0000

    Rename util/ to libutil/

diff --git a/Makefile b/Makefile
index ad280a3..0dfa38b 100644
--- a/Makefile
+++ b/Makefile
@@ -26,31 +26,31 @@ LIBUTFSRC =\
 
 LIBUTIL = libutil.a
 LIBUTILSRC =\
-       util/agetcwd.c\
-       util/agetline.c\
-       util/apathmax.c\
-       util/concat.c\
-       util/cp.c\
-       util/crypt.c\
-       util/ealloc.c\
-       util/enmasse.c\
-       util/eprintf.c\
-       util/eregcomp.c\
-       util/estrtod.c\
-       util/estrtol.c\
-       util/fnck.c\
-       util/getlines.c\
-       util/human.c\
-       util/md5.c\
-       util/mode.c\
-       util/putword.c\
-       util/recurse.c\
-       util/rm.c\
-       util/sha1.c\
-       util/sha256.c\
-       util/sha512.c\
-       util/strlcat.c\
-       util/strlcpy.c
+       libutil/agetcwd.c\
+       libutil/agetline.c\
+       libutil/apathmax.c\
+       libutil/concat.c\
+       libutil/cp.c\
+       libutil/crypt.c\
+       libutil/ealloc.c\
+       libutil/enmasse.c\
+       libutil/eprintf.c\
+       libutil/eregcomp.c\
+       libutil/estrtod.c\
+       libutil/estrtol.c\
+       libutil/fnck.c\
+       libutil/getlines.c\
+       libutil/human.c\
+       libutil/md5.c\
+       libutil/mode.c\
+       libutil/putword.c\
+       libutil/recurse.c\
+       libutil/rm.c\
+       libutil/sha1.c\
+       libutil/sha256.c\
+       libutil/sha512.c\
+       libutil/strlcat.c\
+       libutil/strlcpy.c
 
 LIB = $(LIBUTF) $(LIBUTIL)
 
@@ -168,7 +168,7 @@ uninstall:
 
 dist: clean
        mkdir -p sbase-$(VERSION)
-       cp -r LICENSE Makefile README TODO config.mk $(SRC) $(MAN) util $(HDR) 
sbase-$(VERSION)
+       cp -r LICENSE Makefile README TODO config.mk $(SRC) $(MAN) libutf 
libutil $(HDR) sbase-$(VERSION)
        tar -cf sbase-$(VERSION).tar sbase-$(VERSION)
        gzip sbase-$(VERSION).tar
        rm -rf sbase-$(VERSION)
diff --git a/libutil/agetcwd.c b/libutil/agetcwd.c
new file mode 100644
index 0000000..4ebdb89
--- /dev/null
+++ b/libutil/agetcwd.c
@@ -0,0 +1,18 @@
+/* See LICENSE file for copyright and license details. */
+#include <unistd.h>
+
+#include "../util.h"
+
+char *
+agetcwd(void)
+{
+       char *buf;
+       long size;
+
+       apathmax(&buf, &size);
+       if (!getcwd(buf, size))
+               eprintf("getcwd:");
+
+       return buf;
+}
+
diff --git a/libutil/agetline.c b/libutil/agetline.c
new file mode 100644
index 0000000..0953dac
--- /dev/null
+++ b/libutil/agetline.c
@@ -0,0 +1,13 @@
+/* See LICENSE file for copyright and license details. */
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+
+#include "../text.h"
+#include "../util.h"
+
+ssize_t
+agetline(char **p, size_t *size, FILE *fp)
+{
+       return getline(p, size, fp);
+}
diff --git a/libutil/apathmax.c b/libutil/apathmax.c
new file mode 100644
index 0000000..c570329
--- /dev/null
+++ b/libutil/apathmax.c
@@ -0,0 +1,22 @@
+/* See LICENSE file for copyright and license details. */
+#include <errno.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <unistd.h>
+
+#include "../util.h"
+
+void
+apathmax(char **p, long *size)
+{
+       errno = 0;
+
+       if ((*size = pathconf("/", _PC_PATH_MAX)) == -1) {
+               if (errno == 0) {
+                       *size = BUFSIZ;
+               } else {
+                       eprintf("pathconf:");
+               }
+       }
+       *p = emalloc(*size);
+}
diff --git a/libutil/concat.c b/libutil/concat.c
new file mode 100644
index 0000000..a276fbb
--- /dev/null
+++ b/libutil/concat.c
@@ -0,0 +1,20 @@
+/* See LICENSE file for copyright and license details. */
+#include <stdio.h>
+#include <unistd.h>
+
+#include "../text.h"
+#include "../util.h"
+
+void
+concat(FILE *fp1, const char *s1, FILE *fp2, const char *s2)
+{
+       char buf[BUFSIZ];
+       ssize_t n;
+
+       while ((n = read(fileno(fp1), buf, sizeof buf)) > 0) {
+               if (write(fileno(fp2), buf, n) != n)
+                       eprintf("%s: write error:", s2);
+       }
+       if (n < 0)
+               eprintf("%s: read error:", s1);
+}
diff --git a/libutil/cp.c b/libutil/cp.c
new file mode 100644
index 0000000..948337f
--- /dev/null
+++ b/libutil/cp.c
@@ -0,0 +1,151 @@
+/* See LICENSE file for copyright and license details. */
+#include <dirent.h>
+#include <errno.h>
+#include <fcntl.h>
+#include <limits.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <sys/stat.h>
+#include <sys/types.h>
+#include <unistd.h>
+#include <utime.h>
+
+#include "../fs.h"
+#include "../text.h"
+#include "../util.h"
+
+int cp_aflag = 0;
+int cp_dflag = 0;
+int cp_fflag = 0;
+int cp_pflag = 0;
+int cp_rflag = 0;
+int cp_vflag = 0;
+int cp_status = 0;
+
+int
+cp(const char *s1, const char *s2)
+{
+       FILE *f1, *f2;
+       char *ns1, *ns2;
+       long size1, size2;
+       struct dirent *d;
+       struct stat st;
+       struct utimbuf ut;
+       char buf[PATH_MAX];
+       DIR *dp;
+       int r;
+
+       if (cp_vflag)
+               printf("'%s' -> '%s'\n", s1, s2);
+
+       if (cp_dflag)
+               r = lstat(s1, &st);
+       else
+               r = stat(s1, &st);
+
+       if (r == 0) {
+               if (cp_dflag && S_ISLNK(st.st_mode)) {
+                       if (readlink(s1, buf, sizeof(buf) - 1) >= 0) {
+                               if (cp_fflag)
+                                       unlink(s2);
+                               if (symlink(buf, s2) != 0) {
+                                       weprintf("%s: can't create '%s'\n", 
argv0, s2);
+                                       cp_status = 1;
+                                       return 0;
+                               }
+                       }
+                       goto preserve;
+               }
+               if (S_ISDIR(st.st_mode)) {
+                       if (!cp_rflag)
+                               eprintf("%s: is a directory\n", s1);
+
+                       if (!(dp = opendir(s1)))
+                               eprintf("opendir %s:", s1);
+
+                       if (mkdir(s2, st.st_mode) == -1 && errno != EEXIST)
+                               eprintf("mkdir %s:", s2);
+
+                       apathmax(&ns1, &size1);
+                       apathmax(&ns2, &size2);
+                       while ((d = readdir(dp))) {
+                               if (strcmp(d->d_name, ".") && strcmp(d->d_name, 
"..")) {
+                                       r = snprintf(ns1, size1, "%s/%s", s1, 
d->d_name);
+                                       if (r >= size1 || r < 0) {
+                                               eprintf("%s/%s: filename too 
long\n",
+                                                       s1, d->d_name);
+                                       }
+                                       r = snprintf(ns2, size2, "%s/%s", s2, 
d->d_name);
+                                       if (r >= size2 || r < 0) {
+                                               eprintf("%s/%s: filename too 
long\n",
+                                                       s2, d->d_name);
+                                       }
+                                       fnck(ns1, ns2, cp);
+                               }
+                       }
+                       closedir(dp);
+                       free(ns1);
+                       free(ns2);
+                       goto preserve;
+               }
+       }
+
+       if (cp_aflag) {
+               if (S_ISBLK(st.st_mode) || S_ISCHR(st.st_mode) ||
+                  S_ISSOCK(st.st_mode) || S_ISFIFO(st.st_mode)) {
+                       unlink(s2);
+                       if (mknod(s2, st.st_mode, st.st_rdev) < 0) {
+                               weprintf("%s: can't create '%s':", argv0, s2);
+                               cp_status = 1;
+                               return 0;
+                       }
+                       goto preserve;
+               }
+       }
+
+       if (!(f1 = fopen(s1, "r"))) {
+               weprintf("fopen %s:", s1);
+               cp_status = 1;
+               return 0;
+       }
+
+       if (!(f2 = fopen(s2, "w"))) {
+               if (cp_fflag) {
+                       unlink(s2);
+                       if (!(f2 = fopen(s2, "w"))) {
+                               weprintf("fopen %s:", s2);
+                               cp_status = 1;
+                               return 0;
+                       }
+               } else {
+                       weprintf("fopen %s:", s2);
+                       cp_status = 1;
+                       return 0;
+               }
+       }
+       concat(f1, s1, f2, s2);
+       fchmod(fileno(f2), st.st_mode);
+       fclose(f2);
+       fclose(f1);
+
+preserve:
+       if (cp_aflag || cp_pflag) {
+               if (!(S_ISLNK(st.st_mode))) {
+                       /* timestamp */
+                       ut.actime = st.st_atime;
+                       ut.modtime = st.st_mtime;
+                       utime(s2, &ut);
+               }
+               /* preserve owner ? */
+               if (S_ISLNK(st.st_mode))
+                       r = lchown(s2, st.st_uid, st.st_gid);
+               else
+                       r = chown(s2, st.st_uid, st.st_gid);
+               if (r == -1) {
+                       weprintf("cp: can't preserve ownership of '%s':", s2);
+                       cp_status = 1;
+               }
+       }
+       return 0;
+}
diff --git a/libutil/crypt.c b/libutil/crypt.c
new file mode 100644
index 0000000..458f11c
--- /dev/null
+++ b/libutil/crypt.c
@@ -0,0 +1,156 @@
+/* See LICENSE file for copyright and license details. */
+#include <stdint.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+
+#include "../crypt.h"
+#include "../text.h"
+#include "../util.h"
+
+static int
+hexdec(int c)
+{
+       if (c >= '0' && c <= '9')
+               return c - '0';
+       else if (c >= 'A' && c <= 'F')
+               return c - 'A' + 10;
+       else if (c >= 'a' && c <= 'f')
+               return c - 'a' + 10;
+       return -1; /* unknown character */
+}
+
+static int
+mdcheckline(const char *s, uint8_t *md, size_t sz)
+{
+       size_t i;
+       int b1, b2;
+
+       for (i = 0; i < sz; i++) {
+               if (!*s || (b1 = hexdec(*s++)) < 0)
+                       return -1; /* invalid format */
+               if (!*s || (b2 = hexdec(*s++)) < 0)
+                       return -1; /* invalid format */
+               if ((uint8_t)((b1 << 4) | b2) != md[i])
+                       return 0; /* value mismatch */
+       }
+       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;
+       size_t bufsiz = 0;
+
+       if (!sumfile)
+               cfp = stdin;
+       else if (!(cfp = fopen(sumfile, "r")))
+               eprintf("fopen %s:", sumfile);
+
+       while (agetline(&line, &bufsiz, cfp) != -1) {
+               if (!(file = strstr(line, "  "))) {
+                       formatsucks++;
+                       continue;
+               }
+               if ((file - line) / 2 != sz) {
+                       formatsucks++; /* checksum length mismatch */
+                       continue;
+               }
+               *file = '\0';
+               file += 2;
+               for (p = file; *p && *p != '\n' && *p != '\r'; p++); /* strip 
newline */
+               *p = '\0';
+               if (!(fp = fopen(file, "r"))) {
+                       weprintf("fopen %s:", file);
+                       noread++;
+                       continue;
+               }
+               cryptsum(ops, fp, file, md);
+               r = mdcheckline(line, md, sz);
+               if (r == 1) {
+                       printf("%s: OK\n", file);
+               } else if (r == 0) {
+                       printf("%s: FAILED\n", file);
+                       nonmatch++;
+               } else {
+                       formatsucks++;
+               }
+               fclose(fp);
+       }
+       if (sumfile)
+               fclose(cfp);
+       free(line);
+       if (formatsucks > 0) {
+               weprintf("%d lines are improperly formatted\n", formatsucks);
+               ret = 1;
+       }
+       if (noread > 0) {
+               weprintf("%d listed file could not be read\n", noread);
+               ret = 1;
+       }
+       if (nonmatch > 0) {
+               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)
+{
+       FILE *fp;
+       int ret = 0;
+
+       if (argc == 0) {
+               cryptsum(ops, stdin, "<stdin>", md);
+               mdprint(md, "<stdin>", sz);
+       } else {
+               for (; argc > 0; argc--) {
+                       if (!(fp = fopen(*argv, "r"))) {
+                               weprintf("fopen %s:", *argv);
+                               ret = 1;
+                               continue;
+                       }
+                       if (cryptsum(ops, fp, *argv, md) == 1)
+                               ret = 1;
+                       else
+                               mdprint(md, *argv, sz);
+                       fclose(fp);
+                       argv++;
+               }
+       }
+       return ret;
+}
+
+int
+cryptsum(struct crypt_ops *ops, FILE *fp, const char *f,
+        uint8_t *md)
+{
+       uint8_t buf[BUFSIZ];
+       size_t n;
+
+       ops->init(ops->s);
+       while ((n = fread(buf, 1, sizeof(buf), fp)) > 0)
+               ops->update(ops->s, buf, n);
+       if (ferror(fp)) {
+               weprintf("%s: read error:", f);
+               return 1;
+       }
+       ops->sum(ops->s, md);
+       return 0;
+}
+
+void
+mdprint(const uint8_t *md, const char *f, size_t len)
+{
+       size_t i;
+
+       for (i = 0; i < len; i++)
+               printf("%02x", md[i]);
+       printf("  %s\n", f);
+}
diff --git a/libutil/ealloc.c b/libutil/ealloc.c
new file mode 100644
index 0000000..05bdd62
--- /dev/null
+++ b/libutil/ealloc.c
@@ -0,0 +1,47 @@
+/* See LICENSE file for copyright and license details. */
+#include <stdlib.h>
+#include <string.h>
+
+#include "../util.h"
+
+void *
+ecalloc(size_t nmemb, size_t size)
+{
+       void *p;
+
+       p = calloc(nmemb, size);
+       if (!p)
+               eprintf("calloc: out of memory\n");
+       return p;
+}
+
+void *
+emalloc(size_t size)
+{
+       void *p;
+
+       p = malloc(size);
+       if (!p)
+               eprintf("malloc: out of memory\n");
+       return p;
+}
+
+void *
+erealloc(void *p, size_t size)
+{
+       p = realloc(p, size);
+       if (!p)
+               eprintf("realloc: out of memory\n");
+       return p;
+}
+
+char *
+estrdup(const char *s)
+{
+       char *p;
+
+       p = strdup(s);
+       if (!p)
+               eprintf("strdup: out of memory\n");
+       return p;
+}
diff --git a/libutil/enmasse.c b/libutil/enmasse.c
new file mode 100644
index 0000000..7a2fa2a
--- /dev/null
+++ b/libutil/enmasse.c
@@ -0,0 +1,41 @@
+/* See LICENSE file for copyright and license details. */
+#include <libgen.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <sys/stat.h>
+#include <unistd.h>
+
+#include "../util.h"
+
+void
+enmasse(int argc, char *argv[], int (*fn)(const char *, const char *))
+{
+       char *buf, *dir;
+       int i, len;
+       long size;
+       struct stat st;
+       size_t dlen;
+
+       if (argc == 2 && !(stat(argv[1], &st) == 0 && S_ISDIR(st.st_mode))) {
+               fnck(argv[0], argv[1], fn);
+               return;
+       } else {
+               dir = (argc == 1) ? "." : argv[--argc];
+       }
+
+       apathmax(&buf, &size);
+       for (i = 0; i < argc; i++) {
+               dlen = strlen(dir);
+               if (dlen > 0 && dir[dlen - 1] == '/')
+                       len = snprintf(buf, size, "%s%s", dir, 
basename(argv[i]));
+               else
+                       len = snprintf(buf, size, "%s/%s", dir, 
basename(argv[i]));
+               if (len < 0 || len >= size) {
+                       eprintf("%s/%s: filename too long\n", dir,
+                               basename(argv[i]));
+               }
+               fnck(argv[i], buf, fn);
+       }
+       free(buf);
+}
diff --git a/libutil/eprintf.c b/libutil/eprintf.c
new file mode 100644
index 0000000..407c502
--- /dev/null
+++ b/libutil/eprintf.c
@@ -0,0 +1,67 @@
+/* See LICENSE file for copyright and license details. */
+#include <stdarg.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+
+#include "../util.h"
+
+char *argv0;
+
+static void venprintf(int, const char *, va_list);
+
+void
+eprintf(const char *fmt, ...)
+{
+       va_list ap;
+
+       va_start(ap, fmt);
+       venprintf(1, fmt, ap);
+       va_end(ap);
+}
+
+void
+enprintf(int status, const char *fmt, ...)
+{
+       va_list ap;
+
+       va_start(ap, fmt);
+       venprintf(status, fmt, ap);
+       va_end(ap);
+}
+
+void
+venprintf(int status, const char *fmt, va_list ap)
+{
+#ifdef DEBUG
+       fprintf(stderr, "%s: ", argv0);
+#endif
+
+       vfprintf(stderr, fmt, ap);
+
+       if (fmt[0] && fmt[strlen(fmt)-1] == ':') {
+               fputc(' ', stderr);
+               perror(NULL);
+       }
+
+       exit(status);
+}
+
+void
+weprintf(const char *fmt, ...)
+{
+       va_list ap;
+
+#ifdef DEBUG
+       fprintf(stderr, "%s: ", argv0);
+#endif
+
+       va_start(ap, fmt);
+       vfprintf(stderr, fmt, ap);
+       va_end(ap);
+
+       if (fmt[0] && fmt[strlen(fmt)-1] == ':') {
+               fputc(' ', stderr);
+               perror(NULL);
+       }
+}
diff --git a/libutil/eregcomp.c b/libutil/eregcomp.c
new file mode 100644
index 0000000..49c1bc5
--- /dev/null
+++ b/libutil/eregcomp.c
@@ -0,0 +1,25 @@
+#include <regex.h>
+#include <stdio.h>
+#include <sys/types.h>
+
+#include "../util.h"
+
+int
+enregcomp(int status, regex_t *preg, const char *regex, int cflags)
+{
+    char errbuf[BUFSIZ] = "";
+    int r;
+
+    if((r = regcomp(preg, regex, cflags)) == 0)
+        return r;
+
+    regerror(r, preg, errbuf, sizeof(errbuf));
+    enprintf(status, "invalid regex: %s\n", errbuf);
+    return r;
+}
+
+int
+eregcomp(regex_t *preg, const char *regex, int cflags)
+{
+       return enregcomp(1, preg, regex, cflags);
+}
diff --git a/libutil/estrtod.c b/libutil/estrtod.c
new file mode 100644
index 0000000..24e4fdc
--- /dev/null
+++ b/libutil/estrtod.c
@@ -0,0 +1,18 @@
+/* See LICENSE file for copyright and license details. */
+#include <errno.h>
+#include <stdio.h>
+#include <stdlib.h>
+
+#include "../util.h"
+
+double
+estrtod(const char *s)
+{
+       char *end;
+       double d;
+
+       d = strtod(s, &end);
+       if (end == s || *end != '\0')
+               eprintf("%s: not a real number\n", s);
+       return d;
+}
diff --git a/libutil/estrtol.c b/libutil/estrtol.c
new file mode 100644
index 0000000..74c7fb4
--- /dev/null
+++ b/libutil/estrtol.c
@@ -0,0 +1,27 @@
+/* See LICENSE file for copyright and license details. */
+#include <errno.h>
+#include <stdio.h>
+#include <stdlib.h>
+
+#include "../util.h"
+
+long
+estrtol(const char *s, int base)
+{
+       char *end;
+       long n;
+
+       errno = 0;
+       n = strtol(s, &end, base);
+       if (*end != '\0') {
+               if (base == 0)
+                       eprintf("%s: not an integer\n", s);
+               else
+                       eprintf("%s: not a base %d integer\n", s, base);
+       }
+       if (errno != 0)
+               eprintf("%s:", s);
+
+       return n;
+}
+
diff --git a/libutil/fnck.c b/libutil/fnck.c
new file mode 100644
index 0000000..8053267
--- /dev/null
+++ b/libutil/fnck.c
@@ -0,0 +1,20 @@
+/* See LICENSE file for copyright and license details. */
+#include <sys/stat.h>
+
+#include "../util.h"
+
+void
+fnck(const char *a, const char *b, int (*fn)(const char *, const char *))
+{
+       struct stat sta, stb;
+
+       if (stat(a, &sta) == 0
+                       && stat(b, &stb) == 0
+                       && sta.st_dev == stb.st_dev
+                       && sta.st_ino == stb.st_ino) {
+               eprintf("%s -> %s: same file\n", a, b);
+       }
+
+       if (fn(a, b) == -1)
+               eprintf("%s -> %s:", a, b);
+}
diff --git a/libutil/getlines.c b/libutil/getlines.c
new file mode 100644
index 0000000..df64544
--- /dev/null
+++ b/libutil/getlines.c
@@ -0,0 +1,27 @@
+/* See LICENSE file for copyright and license details. */
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+
+#include "../text.h"
+#include "../util.h"
+
+void
+getlines(FILE *fp, struct linebuf *b)
+{
+       char *line = NULL, **nline;
+       size_t size = 0, linelen;
+       ssize_t len;
+
+       while ((len = agetline(&line, &size, fp)) != -1) {
+               if (++b->nlines > b->capacity) {
+                       b->capacity += 512;
+                       nline = erealloc(b->lines, b->capacity * 
sizeof(*b->lines));
+                       b->lines = nline;
+               }
+               linelen = len + 1;
+               b->lines[b->nlines-1] = emalloc(linelen);
+               memcpy(b->lines[b->nlines-1], line, linelen);
+       }
+       free(line);
+}
diff --git a/libutil/human.c b/libutil/human.c
new file mode 100644
index 0000000..5527bce
--- /dev/null
+++ b/libutil/human.c
@@ -0,0 +1,22 @@
+/* See LICENSE file for copyright and license details. */
+#include <stdio.h>
+#include <string.h>
+
+#include "../util.h"
+
+char *
+humansize(double n)
+{
+       static char buf[16];
+       const char postfixes[] = "BKMGTPE";
+       size_t i;
+
+       for (i = 0; n >= 1024 && i < strlen(postfixes); i++)
+               n /= 1024;
+
+       if (!i)
+               snprintf(buf, sizeof(buf), "%lu", (unsigned long)n);
+       else
+               snprintf(buf, sizeof(buf), "%.1f%c", n, postfixes[i]);
+       return buf;
+}
diff --git a/libutil/md5.c b/libutil/md5.c
new file mode 100644
index 0000000..c7483ac
--- /dev/null
+++ b/libutil/md5.c
@@ -0,0 +1,148 @@
+/* public domain md5 implementation based on rfc1321 and libtomcrypt */
+#include <stdint.h>
+#include <string.h>
+
+#include "../md5.h"
+
+static uint32_t rol(uint32_t n, int k) { return (n << k) | (n >> (32-k)); }
+#define F(x,y,z) (z ^ (x & (y ^ z)))
+#define G(x,y,z) (y ^ (z & (y ^ x)))
+#define H(x,y,z) (x ^ y ^ z)
+#define I(x,y,z) (y ^ (x | ~z))
+#define FF(a,b,c,d,w,s,t) a += F(b,c,d) + w + t; a = rol(a,s) + b
+#define GG(a,b,c,d,w,s,t) a += G(b,c,d) + w + t; a = rol(a,s) + b
+#define HH(a,b,c,d,w,s,t) a += H(b,c,d) + w + t; a = rol(a,s) + b
+#define II(a,b,c,d,w,s,t) a += I(b,c,d) + w + t; a = rol(a,s) + b
+
+static const uint32_t tab[64] = {
+       0xd76aa478, 0xe8c7b756, 0x242070db, 0xc1bdceee, 0xf57c0faf, 0x4787c62a, 
0xa8304613, 0xfd469501,
+       0x698098d8, 0x8b44f7af, 0xffff5bb1, 0x895cd7be, 0x6b901122, 0xfd987193, 
0xa679438e, 0x49b40821,
+       0xf61e2562, 0xc040b340, 0x265e5a51, 0xe9b6c7aa, 0xd62f105d, 0x02441453, 
0xd8a1e681, 0xe7d3fbc8,
+       0x21e1cde6, 0xc33707d6, 0xf4d50d87, 0x455a14ed, 0xa9e3e905, 0xfcefa3f8, 
0x676f02d9, 0x8d2a4c8a,
+       0xfffa3942, 0x8771f681, 0x6d9d6122, 0xfde5380c, 0xa4beea44, 0x4bdecfa9, 
0xf6bb4b60, 0xbebfbc70,
+       0x289b7ec6, 0xeaa127fa, 0xd4ef3085, 0x04881d05, 0xd9d4d039, 0xe6db99e5, 
0x1fa27cf8, 0xc4ac5665,
+       0xf4292244, 0x432aff97, 0xab9423a7, 0xfc93a039, 0x655b59c3, 0x8f0ccc92, 
0xffeff47d, 0x85845dd1,
+       0x6fa87e4f, 0xfe2ce6e0, 0xa3014314, 0x4e0811a1, 0xf7537e82, 0xbd3af235, 
0x2ad7d2bb, 0xeb86d391
+};
+
+static void
+processblock(struct md5 *s, const uint8_t *buf)
+{
+       uint32_t i, W[16], a, b, c, d;
+
+       for (i = 0; i < 16; i++) {
+               W[i] = buf[4*i];
+               W[i] |= (uint32_t)buf[4*i+1]<<8;
+               W[i] |= (uint32_t)buf[4*i+2]<<16;
+               W[i] |= (uint32_t)buf[4*i+3]<<24;
+       }
+
+       a = s->h[0];
+       b = s->h[1];
+       c = s->h[2];
+       d = s->h[3];
+
+       i = 0;
+       while (i < 16) {
+               FF(a,b,c,d, W[i],  7, tab[i]); i++;
+               FF(d,a,b,c, W[i], 12, tab[i]); i++;
+               FF(c,d,a,b, W[i], 17, tab[i]); i++;
+               FF(b,c,d,a, W[i], 22, tab[i]); i++;
+       }
+       while (i < 32) {
+               GG(a,b,c,d, W[(5*i+1)%16],  5, tab[i]); i++;
+               GG(d,a,b,c, W[(5*i+1)%16],  9, tab[i]); i++;
+               GG(c,d,a,b, W[(5*i+1)%16], 14, tab[i]); i++;
+               GG(b,c,d,a, W[(5*i+1)%16], 20, tab[i]); i++;
+       }
+       while (i < 48) {
+               HH(a,b,c,d, W[(3*i+5)%16],  4, tab[i]); i++;
+               HH(d,a,b,c, W[(3*i+5)%16], 11, tab[i]); i++;
+               HH(c,d,a,b, W[(3*i+5)%16], 16, tab[i]); i++;
+               HH(b,c,d,a, W[(3*i+5)%16], 23, tab[i]); i++;
+       }
+       while (i < 64) {
+               II(a,b,c,d, W[7*i%16],  6, tab[i]); i++;
+               II(d,a,b,c, W[7*i%16], 10, tab[i]); i++;
+               II(c,d,a,b, W[7*i%16], 15, tab[i]); i++;
+               II(b,c,d,a, W[7*i%16], 21, tab[i]); i++;
+       }
+
+       s->h[0] += a;
+       s->h[1] += b;
+       s->h[2] += c;
+       s->h[3] += d;
+}
+
+static void
+pad(struct md5 *s)
+{
+       unsigned r = s->len % 64;
+
+       s->buf[r++] = 0x80;
+       if (r > 56) {
+               memset(s->buf + r, 0, 64 - r);
+               r = 0;
+               processblock(s, s->buf);
+       }
+       memset(s->buf + r, 0, 56 - r);
+       s->len *= 8;
+       s->buf[56] = s->len;
+       s->buf[57] = s->len >> 8;
+       s->buf[58] = s->len >> 16;
+       s->buf[59] = s->len >> 24;
+       s->buf[60] = s->len >> 32;
+       s->buf[61] = s->len >> 40;
+       s->buf[62] = s->len >> 48;
+       s->buf[63] = s->len >> 56;
+       processblock(s, s->buf);
+}
+
+void
+md5_init(void *ctx)
+{
+       struct md5 *s = ctx;
+       s->len = 0;
+       s->h[0] = 0x67452301;
+       s->h[1] = 0xefcdab89;
+       s->h[2] = 0x98badcfe;
+       s->h[3] = 0x10325476;
+}
+
+void
+md5_sum(void *ctx, uint8_t md[MD5_DIGEST_LENGTH])
+{
+       struct md5 *s = ctx;
+       int i;
+
+       pad(s);
+       for (i = 0; i < 4; i++) {
+               md[4*i] = s->h[i];
+               md[4*i+1] = s->h[i] >> 8;
+               md[4*i+2] = s->h[i] >> 16;
+               md[4*i+3] = s->h[i] >> 24;
+       }
+}
+
+void
+md5_update(void *ctx, const void *m, unsigned long len)
+{
+       struct md5 *s = ctx;
+       const uint8_t *p = m;
+       unsigned r = s->len % 64;
+
+       s->len += len;
+       if (r) {
+               if (len < 64 - r) {
+                       memcpy(s->buf + r, p, len);
+                       return;
+               }
+               memcpy(s->buf + r, p, 64 - r);
+               len -= 64 - r;
+               p += 64 - r;
+               processblock(s, s->buf);
+       }
+       for (; len >= 64; len -= 64, p += 64)
+               processblock(s, p);
+       memcpy(s->buf, p, len);
+}
diff --git a/libutil/mode.c b/libutil/mode.c
new file mode 100644
index 0000000..16347d8
--- /dev/null
+++ b/libutil/mode.c
@@ -0,0 +1,163 @@
+#include <stdlib.h>
+#include <string.h>
+#include <sys/stat.h>
+#include <unistd.h>
+
+#include "../util.h"
+
+mode_t
+getumask(void)
+{
+       mode_t mask = umask(0);
+       umask(mask);
+       return mask;
+}
+
+mode_t
+parsemode(const char *str, mode_t mode, mode_t mask)
+{
+       char *end;
+       const char *p = str;
+       int octal, op;
+       mode_t who, perm, clear;
+
+       octal = strtol(str, &end, 8);
+       if (*end == '\0') {
+               if (octal < 0 || octal > 07777) {
+                       eprintf("%s: invalid mode\n", str);
+                       return -1;
+               }
+               mode = 0;
+               if (octal & 04000) mode |= S_ISUID;
+               if (octal & 02000) mode |= S_ISGID;
+               if (octal & 01000) mode |= S_ISVTX;
+               if (octal & 00400) mode |= S_IRUSR;
+               if (octal & 00200) mode |= S_IWUSR;
+               if (octal & 00100) mode |= S_IXUSR;
+               if (octal & 00040) mode |= S_IRGRP;
+               if (octal & 00020) mode |= S_IWGRP;
+               if (octal & 00010) mode |= S_IXGRP;
+               if (octal & 00004) mode |= S_IROTH;
+               if (octal & 00002) mode |= S_IWOTH;
+               if (octal & 00001) mode |= S_IXOTH;
+               return mode;
+       }
+next:
+       /* first, determine which bits we will be modifying */
+       for (who = 0; *p; p++) {
+               switch (*p) {
+               /* masks */
+               case 'u':
+                       who |= S_IRWXU|S_ISUID;
+                       continue;
+               case 'g':
+                       who |= S_IRWXG|S_ISGID;
+                       continue;
+               case 'o':
+                       who |= S_IRWXO;
+                       continue;
+               case 'a':
+                       who |= S_IRWXU|S_ISUID|S_IRWXG|S_ISGID|S_IRWXO;
+                       continue;
+               }
+               break;
+       }
+       if (who) {
+               clear = who;
+       } else {
+               clear = S_ISUID|S_ISGID|S_ISVTX|S_IRWXU|S_IRWXG|S_IRWXO;
+               who = ~mask;
+       }
+       while (*p) {
+               switch (*p) {
+               /* opers */
+               case '=':
+               case '+':
+               case '-':
+                       op = (int)*p;
+                       break;
+               default:
+                       eprintf("%s: invalid mode\n", str);
+                       return -1;
+               }
+
+               perm = 0;
+               switch (*++p) {
+               /* copy */
+               case 'u':
+                       if (mode & S_IRUSR)
+                               perm |= S_IRUSR|S_IRGRP|S_IROTH;
+                       if (mode & S_IWUSR)
+                               perm |= S_IWUSR|S_IWGRP|S_IWOTH;
+                       if (mode & S_IXUSR)
+                               perm |= S_IXUSR|S_IXGRP|S_IXOTH;
+                       if (mode & S_ISUID)
+                               perm |= S_ISUID|S_ISGID;
+                       p++;
+                       break;
+               case 'g':
+                       if (mode & S_IRGRP)
+                               perm |= S_IRUSR|S_IRGRP|S_IROTH;
+                       if (mode & S_IWGRP)
+                               perm |= S_IWUSR|S_IWGRP|S_IWOTH;
+                       if (mode & S_IXGRP)
+                               perm |= S_IXUSR|S_IXGRP|S_IXOTH;
+                       if (mode & S_ISGID)
+                               perm |= S_ISUID|S_ISGID;
+                       p++;
+                       break;
+               case 'o':
+                       if (mode & S_IROTH)
+                               perm |= S_IRUSR|S_IRGRP|S_IROTH;
+                       if (mode & S_IWOTH)
+                               perm |= S_IWUSR|S_IWGRP|S_IWOTH;
+                       if (mode & S_IXOTH)
+                               perm |= S_IXUSR|S_IXGRP|S_IXOTH;
+                       p++;
+                       break;
+               default:
+                       for (; *p; p++) {
+                               switch (*p) {
+                               /* modes */
+                               case 'r':
+                                       perm |= S_IRUSR|S_IRGRP|S_IROTH;
+                                       break;
+                               case 'w':
+                                       perm |= S_IWUSR|S_IWGRP|S_IWOTH;
+                                       break;
+                               case 'x':
+                                       perm |= S_IXUSR|S_IXGRP|S_IXOTH;
+                                       break;
+                               case 's':
+                                       perm |= S_ISUID|S_ISGID;
+                                       break;
+                               case 't':
+                                       perm |= S_ISVTX;
+                                       break;
+                               default:
+                                       goto apply;
+                               }
+                       }
+               }
+
+       apply:
+               /* apply */
+               switch (op) {
+               case '=':
+                       mode &= ~clear;
+                       /* fallthrough */
+               case '+':
+                       mode |= perm & who;
+                       break;
+               case '-':
+                       mode &= ~(perm & who);
+                       break;
+               }
+               /* if we hit a comma, move on to the next clause */
+               if (*p == ',') {
+                       p++;
+                       goto next;
+               }
+       }
+       return mode;
+}
diff --git a/libutil/putword.c b/libutil/putword.c
new file mode 100644
index 0000000..c460703
--- /dev/null
+++ b/libutil/putword.c
@@ -0,0 +1,16 @@
+/* See LICENSE file for copyright and license details. */
+#include <stdio.h>
+
+#include "../util.h"
+
+void
+putword(const char *s)
+{
+       static int first = 1;
+
+       if (!first)
+               putchar(' ');
+
+       fputs(s, stdout);
+       first = 0;
+}
diff --git a/libutil/recurse.c b/libutil/recurse.c
new file mode 100644
index 0000000..318987d
--- /dev/null
+++ b/libutil/recurse.c
@@ -0,0 +1,42 @@
+/* See LICENSE file for copyright and license details. */
+#include <dirent.h>
+#include <limits.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <sys/stat.h>
+#include <sys/types.h>
+#include <unistd.h>
+
+#include "../util.h"
+
+void
+recurse(const char *path, void (*fn)(const char *))
+{
+       char buf[PATH_MAX];
+       struct dirent *d;
+       struct stat st;
+       DIR *dp;
+
+       if (lstat(path, &st) == -1 || S_ISDIR(st.st_mode) == 0)
+               return;
+
+       if (!(dp = opendir(path)))
+               eprintf("opendir %s:", path);
+
+       while ((d = readdir(dp))) {
+               if (strcmp(d->d_name, ".") == 0 ||
+                   strcmp(d->d_name, "..") == 0)
+                       continue;
+               if (strlcpy(buf, path, sizeof(buf)) >= sizeof(buf))
+                       eprintf("path too long\n");
+               if (buf[strlen(buf) - 1] != '/')
+                       if (strlcat(buf, "/", sizeof(buf)) >= sizeof(buf))
+                               eprintf("path too long\n");
+               if (strlcat(buf, d->d_name, sizeof(buf)) >= sizeof(buf))
+                       eprintf("path too long\n");
+               fn(buf);
+       }
+
+       closedir(dp);
+}
diff --git a/libutil/rm.c b/libutil/rm.c
new file mode 100644
index 0000000..a89b11c
--- /dev/null
+++ b/libutil/rm.c
@@ -0,0 +1,17 @@
+/* See LICENSE file for copyright and license details. */
+#include <stdio.h>
+
+#include "../fs.h"
+#include "../util.h"
+
+int rm_fflag = 0;
+int rm_rflag = 0;
+
+void
+rm(const char *path)
+{
+       if (rm_rflag)
+               recurse(path, rm);
+       if (remove(path) == -1 && !rm_fflag)
+               eprintf("remove %s:", path);
+}
diff --git a/libutil/sha1.c b/libutil/sha1.c
new file mode 100644
index 0000000..3d76a1b
--- /dev/null
+++ b/libutil/sha1.c
@@ -0,0 +1,144 @@
+/* public domain sha1 implementation based on rfc3174 and libtomcrypt */
+#include <stdint.h>
+#include <string.h>
+
+#include "../sha1.h"
+
+static uint32_t rol(uint32_t n, int k) { return (n << k) | (n >> (32-k)); }
+#define F0(b,c,d) (d ^ (b & (c ^ d)))
+#define F1(b,c,d) (b ^ c ^ d)
+#define F2(b,c,d) ((b & c) | (d & (b | c)))
+#define F3(b,c,d) (b ^ c ^ d)
+#define G0(a,b,c,d,e,i) e += rol(a,5)+F0(b,c,d)+W[i]+0x5A827999; b = rol(b,30)
+#define G1(a,b,c,d,e,i) e += rol(a,5)+F1(b,c,d)+W[i]+0x6ED9EBA1; b = rol(b,30)
+#define G2(a,b,c,d,e,i) e += rol(a,5)+F2(b,c,d)+W[i]+0x8F1BBCDC; b = rol(b,30)
+#define G3(a,b,c,d,e,i) e += rol(a,5)+F3(b,c,d)+W[i]+0xCA62C1D6; b = rol(b,30)
+
+static void
+processblock(struct sha1 *s, const uint8_t *buf)
+{
+       uint32_t W[80], a, b, c, d, e;
+       int i;
+
+       for (i = 0; i < 16; i++) {
+               W[i] = (uint32_t)buf[4*i]<<24;
+               W[i] |= (uint32_t)buf[4*i+1]<<16;
+               W[i] |= (uint32_t)buf[4*i+2]<<8;
+               W[i] |= buf[4*i+3];
+       }
+       for (; i < 80; i++)
+               W[i] = rol(W[i-3] ^ W[i-8] ^ W[i-14] ^ W[i-16], 1);
+       a = s->h[0];
+       b = s->h[1];
+       c = s->h[2];
+       d = s->h[3];
+       e = s->h[4];
+       for (i = 0; i < 20; ) {
+               G0(a,b,c,d,e,i++);
+               G0(e,a,b,c,d,i++);
+               G0(d,e,a,b,c,i++);
+               G0(c,d,e,a,b,i++);
+               G0(b,c,d,e,a,i++);
+       }
+       while (i < 40) {
+               G1(a,b,c,d,e,i++);
+               G1(e,a,b,c,d,i++);
+               G1(d,e,a,b,c,i++);
+               G1(c,d,e,a,b,i++);
+               G1(b,c,d,e,a,i++);
+       }
+       while (i < 60) {
+               G2(a,b,c,d,e,i++);
+               G2(e,a,b,c,d,i++);
+               G2(d,e,a,b,c,i++);
+               G2(c,d,e,a,b,i++);
+               G2(b,c,d,e,a,i++);
+       }
+       while (i < 80) {
+               G3(a,b,c,d,e,i++);
+               G3(e,a,b,c,d,i++);
+               G3(d,e,a,b,c,i++);
+               G3(c,d,e,a,b,i++);
+               G3(b,c,d,e,a,i++);
+       }
+       s->h[0] += a;
+       s->h[1] += b;
+       s->h[2] += c;
+       s->h[3] += d;
+       s->h[4] += e;
+}
+
+static void
+pad(struct sha1 *s)
+{
+       unsigned r = s->len % 64;
+
+       s->buf[r++] = 0x80;
+       if (r > 56) {
+               memset(s->buf + r, 0, 64 - r);
+               r = 0;
+               processblock(s, s->buf);
+       }
+       memset(s->buf + r, 0, 56 - r);
+       s->len *= 8;
+       s->buf[56] = s->len >> 56;
+       s->buf[57] = s->len >> 48;
+       s->buf[58] = s->len >> 40;
+       s->buf[59] = s->len >> 32;
+       s->buf[60] = s->len >> 24;
+       s->buf[61] = s->len >> 16;
+       s->buf[62] = s->len >> 8;
+       s->buf[63] = s->len;
+       processblock(s, s->buf);
+}
+
+void
+sha1_init(void *ctx)
+{
+       struct sha1 *s = ctx;
+
+       s->len = 0;
+       s->h[0] = 0x67452301;
+       s->h[1] = 0xEFCDAB89;
+       s->h[2] = 0x98BADCFE;
+       s->h[3] = 0x10325476;
+       s->h[4] = 0xC3D2E1F0;
+}
+
+void
+sha1_sum(void *ctx, uint8_t md[SHA1_DIGEST_LENGTH])
+{
+       struct sha1 *s = ctx;
+       int i;
+
+       pad(s);
+       for (i = 0; i < 5; i++) {
+               md[4*i] = s->h[i] >> 24;
+               md[4*i+1] = s->h[i] >> 16;
+               md[4*i+2] = s->h[i] >> 8;
+               md[4*i+3] = s->h[i];
+       }
+}
+
+void
+sha1_update(void *ctx, const void *m, unsigned long len)
+{
+       struct sha1 *s = ctx;
+       const uint8_t *p = m;
+       unsigned r = s->len % 64;
+
+       s->len += len;
+       if (r) {
+               if (len < 64 - r) {
+                       memcpy(s->buf + r, p, len);
+                       return;
+               }
+               memcpy(s->buf + r, p, 64 - r);
+               len -= 64 - r;
+               p += 64 - r;
+               processblock(s, s->buf);
+       }
+       for (; len >= 64; len -= 64, p += 64)
+               processblock(s, p);
+       memcpy(s->buf, p, len);
+}
diff --git a/libutil/sha256.c b/libutil/sha256.c
new file mode 100644
index 0000000..e30169b
--- /dev/null
+++ b/libutil/sha256.c
@@ -0,0 +1,148 @@
+/* public domain sha256 implementation based on fips180-3 */
+#include <ctype.h>
+#include <stdint.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+
+#include "../sha256.h"
+
+static uint32_t ror(uint32_t n, int k) { return (n >> k) | (n << (32-k)); }
+#define Ch(x,y,z)  (z ^ (x & (y ^ z)))
+#define Maj(x,y,z) ((x & y) | (z & (x | y)))
+#define S0(x)      (ror(x,2) ^ ror(x,13) ^ ror(x,22))
+#define S1(x)      (ror(x,6) ^ ror(x,11) ^ ror(x,25))
+#define R0(x)      (ror(x,7) ^ ror(x,18) ^ (x>>3))
+#define R1(x)      (ror(x,17) ^ ror(x,19) ^ (x>>10))
+
+static const uint32_t K[64] = {
+0x428a2f98, 0x71374491, 0xb5c0fbcf, 0xe9b5dba5, 0x3956c25b, 0x59f111f1, 
0x923f82a4, 0xab1c5ed5,
+0xd807aa98, 0x12835b01, 0x243185be, 0x550c7dc3, 0x72be5d74, 0x80deb1fe, 
0x9bdc06a7, 0xc19bf174,
+0xe49b69c1, 0xefbe4786, 0x0fc19dc6, 0x240ca1cc, 0x2de92c6f, 0x4a7484aa, 
0x5cb0a9dc, 0x76f988da,
+0x983e5152, 0xa831c66d, 0xb00327c8, 0xbf597fc7, 0xc6e00bf3, 0xd5a79147, 
0x06ca6351, 0x14292967,
+0x27b70a85, 0x2e1b2138, 0x4d2c6dfc, 0x53380d13, 0x650a7354, 0x766a0abb, 
0x81c2c92e, 0x92722c85,
+0xa2bfe8a1, 0xa81a664b, 0xc24b8b70, 0xc76c51a3, 0xd192e819, 0xd6990624, 
0xf40e3585, 0x106aa070,
+0x19a4c116, 0x1e376c08, 0x2748774c, 0x34b0bcb5, 0x391c0cb3, 0x4ed8aa4a, 
0x5b9cca4f, 0x682e6ff3,
+0x748f82ee, 0x78a5636f, 0x84c87814, 0x8cc70208, 0x90befffa, 0xa4506ceb, 
0xbef9a3f7, 0xc67178f2
+};
+
+static void
+processblock(struct sha256 *s, const uint8_t *buf)
+{
+       uint32_t W[64], t1, t2, a, b, c, d, e, f, g, h;
+       int i;
+
+       for (i = 0; i < 16; i++) {
+               W[i] = (uint32_t)buf[4*i]<<24;
+               W[i] |= (uint32_t)buf[4*i+1]<<16;
+               W[i] |= (uint32_t)buf[4*i+2]<<8;
+               W[i] |= buf[4*i+3];
+       }
+       for (; i < 64; i++)
+               W[i] = R1(W[i-2]) + W[i-7] + R0(W[i-15]) + W[i-16];
+       a = s->h[0];
+       b = s->h[1];
+       c = s->h[2];
+       d = s->h[3];
+       e = s->h[4];
+       f = s->h[5];
+       g = s->h[6];
+       h = s->h[7];
+       for (i = 0; i < 64; i++) {
+               t1 = h + S1(e) + Ch(e,f,g) + K[i] + W[i];
+               t2 = S0(a) + Maj(a,b,c);
+               h = g;
+               g = f;
+               f = e;
+               e = d + t1;
+               d = c;
+               c = b;
+               b = a;
+               a = t1 + t2;
+       }
+       s->h[0] += a;
+       s->h[1] += b;
+       s->h[2] += c;
+       s->h[3] += d;
+       s->h[4] += e;
+       s->h[5] += f;
+       s->h[6] += g;
+       s->h[7] += h;
+}
+
+static void
+pad(struct sha256 *s)
+{
+       unsigned r = s->len % 64;
+
+       s->buf[r++] = 0x80;
+       if (r > 56) {
+               memset(s->buf + r, 0, 64 - r);
+               r = 0;
+               processblock(s, s->buf);
+       }
+       memset(s->buf + r, 0, 56 - r);
+       s->len *= 8;
+       s->buf[56] = s->len >> 56;
+       s->buf[57] = s->len >> 48;
+       s->buf[58] = s->len >> 40;
+       s->buf[59] = s->len >> 32;
+       s->buf[60] = s->len >> 24;
+       s->buf[61] = s->len >> 16;
+       s->buf[62] = s->len >> 8;
+       s->buf[63] = s->len;
+       processblock(s, s->buf);
+}
+
+void
+sha256_init(void *ctx)
+{
+       struct sha256 *s = ctx;
+       s->len = 0;
+       s->h[0] = 0x6a09e667;
+       s->h[1] = 0xbb67ae85;
+       s->h[2] = 0x3c6ef372;
+       s->h[3] = 0xa54ff53a;
+       s->h[4] = 0x510e527f;
+       s->h[5] = 0x9b05688c;
+       s->h[6] = 0x1f83d9ab;
+       s->h[7] = 0x5be0cd19;
+}
+
+void
+sha256_sum(void *ctx, uint8_t md[SHA256_DIGEST_LENGTH])
+{
+       struct sha256 *s = ctx;
+       int i;
+
+       pad(s);
+       for (i = 0; i < 8; i++) {
+               md[4*i] = s->h[i] >> 24;
+               md[4*i+1] = s->h[i] >> 16;
+               md[4*i+2] = s->h[i] >> 8;
+               md[4*i+3] = s->h[i];
+       }
+}
+
+void
+sha256_update(void *ctx, const void *m, unsigned long len)
+{
+       struct sha256 *s = ctx;
+       const uint8_t *p = m;
+       unsigned r = s->len % 64;
+
+       s->len += len;
+       if (r) {
+               if (len < 64 - r) {
+                       memcpy(s->buf + r, p, len);
+                       return;
+               }
+               memcpy(s->buf + r, p, 64 - r);
+               len -= 64 - r;
+               p += 64 - r;
+               processblock(s, s->buf);
+       }
+       for (; len >= 64; len -= 64, p += 64)
+               processblock(s, p);
+       memcpy(s->buf, p, len);
+}
diff --git a/libutil/sha512.c b/libutil/sha512.c
new file mode 100644
index 0000000..efe4f91
--- /dev/null
+++ b/libutil/sha512.c
@@ -0,0 +1,169 @@
+/* public domain sha256 implementation based on fips180-3 */
+
+#include <ctype.h>
+#include <stdint.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+
+#include "../sha512.h"
+
+static uint64_t ror(uint64_t n, int k) { return (n >> k) | (n << (64-k)); }
+#define Ch(x,y,z)  (z ^ (x & (y ^ z)))
+#define Maj(x,y,z) ((x & y) | (z & (x | y)))
+#define S0(x)      (ror(x,28) ^ ror(x,34) ^ ror(x,39))
+#define S1(x)      (ror(x,14) ^ ror(x,18) ^ ror(x,41))
+#define R0(x)      (ror(x,1) ^ ror(x,8) ^ (x>>7))
+#define R1(x)      (ror(x,19) ^ ror(x,61) ^ (x>>6))
+
+static const uint64_t K[80] = {
+0x428a2f98d728ae22ULL, 0x7137449123ef65cdULL, 0xb5c0fbcfec4d3b2fULL, 
0xe9b5dba58189dbbcULL,
+0x3956c25bf348b538ULL, 0x59f111f1b605d019ULL, 0x923f82a4af194f9bULL, 
0xab1c5ed5da6d8118ULL,
+0xd807aa98a3030242ULL, 0x12835b0145706fbeULL, 0x243185be4ee4b28cULL, 
0x550c7dc3d5ffb4e2ULL,
+0x72be5d74f27b896fULL, 0x80deb1fe3b1696b1ULL, 0x9bdc06a725c71235ULL, 
0xc19bf174cf692694ULL,
+0xe49b69c19ef14ad2ULL, 0xefbe4786384f25e3ULL, 0x0fc19dc68b8cd5b5ULL, 
0x240ca1cc77ac9c65ULL,
+0x2de92c6f592b0275ULL, 0x4a7484aa6ea6e483ULL, 0x5cb0a9dcbd41fbd4ULL, 
0x76f988da831153b5ULL,
+0x983e5152ee66dfabULL, 0xa831c66d2db43210ULL, 0xb00327c898fb213fULL, 
0xbf597fc7beef0ee4ULL,
+0xc6e00bf33da88fc2ULL, 0xd5a79147930aa725ULL, 0x06ca6351e003826fULL, 
0x142929670a0e6e70ULL,
+0x27b70a8546d22ffcULL, 0x2e1b21385c26c926ULL, 0x4d2c6dfc5ac42aedULL, 
0x53380d139d95b3dfULL,
+0x650a73548baf63deULL, 0x766a0abb3c77b2a8ULL, 0x81c2c92e47edaee6ULL, 
0x92722c851482353bULL,
+0xa2bfe8a14cf10364ULL, 0xa81a664bbc423001ULL, 0xc24b8b70d0f89791ULL, 
0xc76c51a30654be30ULL,
+0xd192e819d6ef5218ULL, 0xd69906245565a910ULL, 0xf40e35855771202aULL, 
0x106aa07032bbd1b8ULL,
+0x19a4c116b8d2d0c8ULL, 0x1e376c085141ab53ULL, 0x2748774cdf8eeb99ULL, 
0x34b0bcb5e19b48a8ULL,
+0x391c0cb3c5c95a63ULL, 0x4ed8aa4ae3418acbULL, 0x5b9cca4f7763e373ULL, 
0x682e6ff3d6b2b8a3ULL,
+0x748f82ee5defb2fcULL, 0x78a5636f43172f60ULL, 0x84c87814a1f0ab72ULL, 
0x8cc702081a6439ecULL,
+0x90befffa23631e28ULL, 0xa4506cebde82bde9ULL, 0xbef9a3f7b2c67915ULL, 
0xc67178f2e372532bULL,
+0xca273eceea26619cULL, 0xd186b8c721c0c207ULL, 0xeada7dd6cde0eb1eULL, 
0xf57d4f7fee6ed178ULL,
+0x06f067aa72176fbaULL, 0x0a637dc5a2c898a6ULL, 0x113f9804bef90daeULL, 
0x1b710b35131c471bULL,
+0x28db77f523047d84ULL, 0x32caab7b40c72493ULL, 0x3c9ebe0a15c9bebcULL, 
0x431d67c49c100d4cULL,
+0x4cc5d4becb3e42b6ULL, 0x597f299cfc657e2aULL, 0x5fcb6fab3ad6faecULL, 
0x6c44198c4a475817ULL
+};
+
+static void
+processblock(struct sha512 *s, const uint8_t *buf)
+{
+       uint64_t W[80], t1, t2, a, b, c, d, e, f, g, h;
+       int i;
+
+       for (i = 0; i < 16; i++) {
+               W[i] = (uint64_t)buf[8*i]<<56;
+               W[i] |= (uint64_t)buf[8*i+1]<<48;
+               W[i] |= (uint64_t)buf[8*i+2]<<40;
+               W[i] |= (uint64_t)buf[8*i+3]<<32;
+               W[i] |= (uint64_t)buf[8*i+4]<<24;
+               W[i] |= (uint64_t)buf[8*i+5]<<16;
+               W[i] |= (uint64_t)buf[8*i+6]<<8;
+               W[i] |= buf[8*i+7];
+       }
+       for (; i < 80; i++)
+               W[i] = R1(W[i-2]) + W[i-7] + R0(W[i-15]) + W[i-16];
+       a = s->h[0];
+       b = s->h[1];
+       c = s->h[2];
+       d = s->h[3];
+       e = s->h[4];
+       f = s->h[5];
+       g = s->h[6];
+       h = s->h[7];
+       for (i = 0; i < 80; i++) {
+               t1 = h + S1(e) + Ch(e,f,g) + K[i] + W[i];
+               t2 = S0(a) + Maj(a,b,c);
+               h = g;
+               g = f;
+               f = e;
+               e = d + t1;
+               d = c;
+               c = b;
+               b = a;
+               a = t1 + t2;
+       }
+       s->h[0] += a;
+       s->h[1] += b;
+       s->h[2] += c;
+       s->h[3] += d;
+       s->h[4] += e;
+       s->h[5] += f;
+       s->h[6] += g;
+       s->h[7] += h;
+}
+
+static void
+pad(struct sha512 *s)
+{
+       unsigned r = s->len % 128;
+
+       s->buf[r++] = 0x80;
+       if (r > 112) {
+               memset(s->buf + r, 0, 128 - r);
+               r = 0;
+               processblock(s, s->buf);
+       }
+       memset(s->buf + r, 0, 120 - r);
+       s->len *= 8;
+       s->buf[120] = s->len >> 56;
+       s->buf[121] = s->len >> 48;
+       s->buf[122] = s->len >> 40;
+       s->buf[123] = s->len >> 32;
+       s->buf[124] = s->len >> 24;
+       s->buf[125] = s->len >> 16;
+       s->buf[126] = s->len >> 8;
+       s->buf[127] = s->len;
+       processblock(s, s->buf);
+}
+
+void
+sha512_init(void *ctx)
+{
+       struct sha512 *s = ctx;
+       s->len = 0;
+       s->h[0] = 0x6a09e667f3bcc908ULL;
+       s->h[1] = 0xbb67ae8584caa73bULL;
+       s->h[2] = 0x3c6ef372fe94f82bULL;
+       s->h[3] = 0xa54ff53a5f1d36f1ULL;
+       s->h[4] = 0x510e527fade682d1ULL;
+       s->h[5] = 0x9b05688c2b3e6c1fULL;
+       s->h[6] = 0x1f83d9abfb41bd6bULL;
+       s->h[7] = 0x5be0cd19137e2179ULL;
+}
+
+void
+sha512_sum(void *ctx, uint8_t md[SHA512_DIGEST_LENGTH])
+{
+       struct sha512 *s = ctx;
+       int i;
+
+       pad(s);
+       for (i = 0; i < 8; i++) {
+               md[8*i] = s->h[i] >> 56;
+               md[8*i+1] = s->h[i] >> 48;
+               md[8*i+2] = s->h[i] >> 40;
+               md[8*i+3] = s->h[i] >> 32;
+               md[8*i+4] = s->h[i] >> 24;
+               md[8*i+5] = s->h[i] >> 16;
+               md[8*i+6] = s->h[i] >> 8;
+               md[8*i+7] = s->h[i];
+       }
+}
+
+void
+sha512_update(void *ctx, const void *m, unsigned long len)
+{
+       struct sha512 *s = ctx;
+       const uint8_t *p = m;
+       unsigned r = s->len % 128;
+
+       s->len += len;
+       if (r) {
+               if (len < 128 - r) {
+                       memcpy(s->buf + r, p, len);
+                       return;
+               }
+               memcpy(s->buf + r, p, 128 - r);
+               len -= 128 - r;
+               p += 128 - r;
+               processblock(s, s->buf);
+       }
+       for (; len >= 128; len -= 128, p += 128)
+               processblock(s, p);
+       memcpy(s->buf, p, len);
+}
diff --git a/libutil/strlcat.c b/libutil/strlcat.c
new file mode 100644
index 0000000..9e2d251
--- /dev/null
+++ b/libutil/strlcat.c
@@ -0,0 +1,52 @@
+/*
+ * Copyright (c) 1998 Todd C. Miller <[email protected]>
+ *
+ * Permission to use, copy, modify, and distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice appear in all copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
+ * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
+ * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
+ * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ */
+
+#include <string.h>
+#include <sys/types.h>
+
+#include "../util.h"
+
+/*
+ * Appends src to string dst of size siz (unlike strncat, siz is the
+ * full size of dst, not space left). At most siz-1 characters
+ * will be copied. Always NUL terminates (unless siz <= strlen(dst)).
+ * Returns strlen(src) + MIN(siz, strlen(initial dst)).
+ * If retval >= siz, truncation occurred.
+ */
+size_t
+strlcat(char *dst, const char *src, size_t siz)
+{
+       char *d = dst;
+       const char *s = src;
+       size_t n = siz;
+       size_t dlen;
+       /* Find the end of dst and adjust bytes left but don't go past end */
+       while (n-- != 0 && *d != '\0')
+               d++;
+       dlen = d - dst;
+       n = siz - dlen;
+       if (n == 0)
+               return(dlen + strlen(s));
+       while (*s != '\0') {
+               if (n != 1) {
+                       *d++ = *s;
+                       n--;
+               }
+               s++;
+       }
+       *d = '\0';
+       return(dlen + (s - src)); /* count does not include NUL */
+}
diff --git a/libutil/strlcpy.c b/libutil/strlcpy.c
new file mode 100644
index 0000000..388b426
--- /dev/null
+++ b/libutil/strlcpy.c
@@ -0,0 +1,48 @@
+/*
+ * Copyright (c) 1998 Todd C. Miller <[email protected]>
+ *
+ * Permission to use, copy, modify, and distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice appear in all copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
+ * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
+ * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
+ * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ */
+
+#include <string.h>
+#include <sys/types.h>
+
+#include "../util.h"
+
+/*
+ * Copy src to string dst of size siz. At most siz-1 characters
+ * will be copied. Always NUL terminates (unless siz == 0).
+ * Returns strlen(src); if retval >= siz, truncation occurred.
+ */
+size_t
+strlcpy(char *dst, const char *src, size_t siz)
+{
+       char *d = dst;
+       const char *s = src;
+       size_t n = siz;
+       /* Copy as many bytes as will fit */
+       if (n != 0) {
+               while (--n != 0) {
+                       if ((*d++ = *s++) == '\0')
+                               break;
+               }
+       }
+       /* Not enough room in dst, add NUL and traverse rest of src */
+       if (n == 0) {
+               if (siz != 0)
+                       *d = '\0'; /* NUL-terminate dst */
+               while (*s++)
+                       ;
+       }
+       return(s - src - 1); /* count does not include NUL */
+}
diff --git a/util/agetcwd.c b/util/agetcwd.c
deleted file mode 100644
index 4ebdb89..0000000
--- a/util/agetcwd.c
+++ /dev/null
@@ -1,18 +0,0 @@
-/* See LICENSE file for copyright and license details. */
-#include <unistd.h>
-
-#include "../util.h"
-
-char *
-agetcwd(void)
-{
-       char *buf;
-       long size;
-
-       apathmax(&buf, &size);
-       if (!getcwd(buf, size))
-               eprintf("getcwd:");
-
-       return buf;
-}
-
diff --git a/util/agetline.c b/util/agetline.c
deleted file mode 100644
index 0953dac..0000000
--- a/util/agetline.c
+++ /dev/null
@@ -1,13 +0,0 @@
-/* See LICENSE file for copyright and license details. */
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-
-#include "../text.h"
-#include "../util.h"
-
-ssize_t
-agetline(char **p, size_t *size, FILE *fp)
-{
-       return getline(p, size, fp);
-}
diff --git a/util/apathmax.c b/util/apathmax.c
deleted file mode 100644
index c570329..0000000
--- a/util/apathmax.c
+++ /dev/null
@@ -1,22 +0,0 @@
-/* See LICENSE file for copyright and license details. */
-#include <errno.h>
-#include <stdio.h>
-#include <stdlib.h>
-#include <unistd.h>
-
-#include "../util.h"
-
-void
-apathmax(char **p, long *size)
-{
-       errno = 0;
-
-       if ((*size = pathconf("/", _PC_PATH_MAX)) == -1) {
-               if (errno == 0) {
-                       *size = BUFSIZ;
-               } else {
-                       eprintf("pathconf:");
-               }
-       }
-       *p = emalloc(*size);
-}
diff --git a/util/concat.c b/util/concat.c
deleted file mode 100644
index a276fbb..0000000
--- a/util/concat.c
+++ /dev/null
@@ -1,20 +0,0 @@
-/* See LICENSE file for copyright and license details. */
-#include <stdio.h>
-#include <unistd.h>
-
-#include "../text.h"
-#include "../util.h"
-
-void
-concat(FILE *fp1, const char *s1, FILE *fp2, const char *s2)
-{
-       char buf[BUFSIZ];
-       ssize_t n;
-
-       while ((n = read(fileno(fp1), buf, sizeof buf)) > 0) {
-               if (write(fileno(fp2), buf, n) != n)
-                       eprintf("%s: write error:", s2);
-       }
-       if (n < 0)
-               eprintf("%s: read error:", s1);
-}
diff --git a/util/cp.c b/util/cp.c
deleted file mode 100644
index 948337f..0000000
--- a/util/cp.c
+++ /dev/null
@@ -1,151 +0,0 @@
-/* See LICENSE file for copyright and license details. */
-#include <dirent.h>
-#include <errno.h>
-#include <fcntl.h>
-#include <limits.h>
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-#include <sys/stat.h>
-#include <sys/types.h>
-#include <unistd.h>
-#include <utime.h>
-
-#include "../fs.h"
-#include "../text.h"
-#include "../util.h"
-
-int cp_aflag = 0;
-int cp_dflag = 0;
-int cp_fflag = 0;
-int cp_pflag = 0;
-int cp_rflag = 0;
-int cp_vflag = 0;
-int cp_status = 0;
-
-int
-cp(const char *s1, const char *s2)
-{
-       FILE *f1, *f2;
-       char *ns1, *ns2;
-       long size1, size2;
-       struct dirent *d;
-       struct stat st;
-       struct utimbuf ut;
-       char buf[PATH_MAX];
-       DIR *dp;
-       int r;
-
-       if (cp_vflag)
-               printf("'%s' -> '%s'\n", s1, s2);
-
-       if (cp_dflag)
-               r = lstat(s1, &st);
-       else
-               r = stat(s1, &st);
-
-       if (r == 0) {
-               if (cp_dflag && S_ISLNK(st.st_mode)) {
-                       if (readlink(s1, buf, sizeof(buf) - 1) >= 0) {
-                               if (cp_fflag)
-                                       unlink(s2);
-                               if (symlink(buf, s2) != 0) {
-                                       weprintf("%s: can't create '%s'\n", 
argv0, s2);
-                                       cp_status = 1;
-                                       return 0;
-                               }
-                       }
-                       goto preserve;
-               }
-               if (S_ISDIR(st.st_mode)) {
-                       if (!cp_rflag)
-                               eprintf("%s: is a directory\n", s1);
-
-                       if (!(dp = opendir(s1)))
-                               eprintf("opendir %s:", s1);
-
-                       if (mkdir(s2, st.st_mode) == -1 && errno != EEXIST)
-                               eprintf("mkdir %s:", s2);
-
-                       apathmax(&ns1, &size1);
-                       apathmax(&ns2, &size2);
-                       while ((d = readdir(dp))) {
-                               if (strcmp(d->d_name, ".") && strcmp(d->d_name, 
"..")) {
-                                       r = snprintf(ns1, size1, "%s/%s", s1, 
d->d_name);
-                                       if (r >= size1 || r < 0) {
-                                               eprintf("%s/%s: filename too 
long\n",
-                                                       s1, d->d_name);
-                                       }
-                                       r = snprintf(ns2, size2, "%s/%s", s2, 
d->d_name);
-                                       if (r >= size2 || r < 0) {
-                                               eprintf("%s/%s: filename too 
long\n",
-                                                       s2, d->d_name);
-                                       }
-                                       fnck(ns1, ns2, cp);
-                               }
-                       }
-                       closedir(dp);
-                       free(ns1);
-                       free(ns2);
-                       goto preserve;
-               }
-       }
-
-       if (cp_aflag) {
-               if (S_ISBLK(st.st_mode) || S_ISCHR(st.st_mode) ||
-                  S_ISSOCK(st.st_mode) || S_ISFIFO(st.st_mode)) {
-                       unlink(s2);
-                       if (mknod(s2, st.st_mode, st.st_rdev) < 0) {
-                               weprintf("%s: can't create '%s':", argv0, s2);
-                               cp_status = 1;
-                               return 0;
-                       }
-                       goto preserve;
-               }
-       }
-
-       if (!(f1 = fopen(s1, "r"))) {
-               weprintf("fopen %s:", s1);
-               cp_status = 1;
-               return 0;
-       }
-
-       if (!(f2 = fopen(s2, "w"))) {
-               if (cp_fflag) {
-                       unlink(s2);
-                       if (!(f2 = fopen(s2, "w"))) {
-                               weprintf("fopen %s:", s2);
-                               cp_status = 1;
-                               return 0;
-                       }
-               } else {
-                       weprintf("fopen %s:", s2);
-                       cp_status = 1;
-                       return 0;
-               }
-       }
-       concat(f1, s1, f2, s2);
-       fchmod(fileno(f2), st.st_mode);
-       fclose(f2);
-       fclose(f1);
-
-preserve:
-       if (cp_aflag || cp_pflag) {
-               if (!(S_ISLNK(st.st_mode))) {
-                       /* timestamp */
-                       ut.actime = st.st_atime;
-                       ut.modtime = st.st_mtime;
-                       utime(s2, &ut);
-               }
-               /* preserve owner ? */
-               if (S_ISLNK(st.st_mode))
-                       r = lchown(s2, st.st_uid, st.st_gid);
-               else
-                       r = chown(s2, st.st_uid, st.st_gid);
-               if (r == -1) {
-                       weprintf("cp: can't preserve ownership of '%s':", s2);
-                       cp_status = 1;
-               }
-       }
-       return 0;
-}
diff --git a/util/crypt.c b/util/crypt.c
deleted file mode 100644
index 458f11c..0000000
--- a/util/crypt.c
+++ /dev/null
@@ -1,156 +0,0 @@
-/* See LICENSE file for copyright and license details. */
-#include <stdint.h>
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-
-#include "../crypt.h"
-#include "../text.h"
-#include "../util.h"
-
-static int
-hexdec(int c)
-{
-       if (c >= '0' && c <= '9')
-               return c - '0';
-       else if (c >= 'A' && c <= 'F')
-               return c - 'A' + 10;
-       else if (c >= 'a' && c <= 'f')
-               return c - 'a' + 10;
-       return -1; /* unknown character */
-}
-
-static int
-mdcheckline(const char *s, uint8_t *md, size_t sz)
-{
-       size_t i;
-       int b1, b2;
-
-       for (i = 0; i < sz; i++) {
-               if (!*s || (b1 = hexdec(*s++)) < 0)
-                       return -1; /* invalid format */
-               if (!*s || (b2 = hexdec(*s++)) < 0)
-                       return -1; /* invalid format */
-               if ((uint8_t)((b1 << 4) | b2) != md[i])
-                       return 0; /* value mismatch */
-       }
-       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;
-       size_t bufsiz = 0;
-
-       if (!sumfile)
-               cfp = stdin;
-       else if (!(cfp = fopen(sumfile, "r")))
-               eprintf("fopen %s:", sumfile);
-
-       while (agetline(&line, &bufsiz, cfp) != -1) {
-               if (!(file = strstr(line, "  "))) {
-                       formatsucks++;
-                       continue;
-               }
-               if ((file - line) / 2 != sz) {
-                       formatsucks++; /* checksum length mismatch */
-                       continue;
-               }
-               *file = '\0';
-               file += 2;
-               for (p = file; *p && *p != '\n' && *p != '\r'; p++); /* strip 
newline */
-               *p = '\0';
-               if (!(fp = fopen(file, "r"))) {
-                       weprintf("fopen %s:", file);
-                       noread++;
-                       continue;
-               }
-               cryptsum(ops, fp, file, md);
-               r = mdcheckline(line, md, sz);
-               if (r == 1) {
-                       printf("%s: OK\n", file);
-               } else if (r == 0) {
-                       printf("%s: FAILED\n", file);
-                       nonmatch++;
-               } else {
-                       formatsucks++;
-               }
-               fclose(fp);
-       }
-       if (sumfile)
-               fclose(cfp);
-       free(line);
-       if (formatsucks > 0) {
-               weprintf("%d lines are improperly formatted\n", formatsucks);
-               ret = 1;
-       }
-       if (noread > 0) {
-               weprintf("%d listed file could not be read\n", noread);
-               ret = 1;
-       }
-       if (nonmatch > 0) {
-               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)
-{
-       FILE *fp;
-       int ret = 0;
-
-       if (argc == 0) {
-               cryptsum(ops, stdin, "<stdin>", md);
-               mdprint(md, "<stdin>", sz);
-       } else {
-               for (; argc > 0; argc--) {
-                       if (!(fp = fopen(*argv, "r"))) {
-                               weprintf("fopen %s:", *argv);
-                               ret = 1;
-                               continue;
-                       }
-                       if (cryptsum(ops, fp, *argv, md) == 1)
-                               ret = 1;
-                       else
-                               mdprint(md, *argv, sz);
-                       fclose(fp);
-                       argv++;
-               }
-       }
-       return ret;
-}
-
-int
-cryptsum(struct crypt_ops *ops, FILE *fp, const char *f,
-        uint8_t *md)
-{
-       uint8_t buf[BUFSIZ];
-       size_t n;
-
-       ops->init(ops->s);
-       while ((n = fread(buf, 1, sizeof(buf), fp)) > 0)
-               ops->update(ops->s, buf, n);
-       if (ferror(fp)) {
-               weprintf("%s: read error:", f);
-               return 1;
-       }
-       ops->sum(ops->s, md);
-       return 0;
-}
-
-void
-mdprint(const uint8_t *md, const char *f, size_t len)
-{
-       size_t i;
-
-       for (i = 0; i < len; i++)
-               printf("%02x", md[i]);
-       printf("  %s\n", f);
-}
diff --git a/util/ealloc.c b/util/ealloc.c
deleted file mode 100644
index 05bdd62..0000000
--- a/util/ealloc.c
+++ /dev/null
@@ -1,47 +0,0 @@
-/* See LICENSE file for copyright and license details. */
-#include <stdlib.h>
-#include <string.h>
-
-#include "../util.h"
-
-void *
-ecalloc(size_t nmemb, size_t size)
-{
-       void *p;
-
-       p = calloc(nmemb, size);
-       if (!p)
-               eprintf("calloc: out of memory\n");
-       return p;
-}
-
-void *
-emalloc(size_t size)
-{
-       void *p;
-
-       p = malloc(size);
-       if (!p)
-               eprintf("malloc: out of memory\n");
-       return p;
-}
-
-void *
-erealloc(void *p, size_t size)
-{
-       p = realloc(p, size);
-       if (!p)
-               eprintf("realloc: out of memory\n");
-       return p;
-}
-
-char *
-estrdup(const char *s)
-{
-       char *p;
-
-       p = strdup(s);
-       if (!p)
-               eprintf("strdup: out of memory\n");
-       return p;
-}
diff --git a/util/enmasse.c b/util/enmasse.c
deleted file mode 100644
index 7a2fa2a..0000000
--- a/util/enmasse.c
+++ /dev/null
@@ -1,41 +0,0 @@
-/* See LICENSE file for copyright and license details. */
-#include <libgen.h>
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-#include <sys/stat.h>
-#include <unistd.h>
-
-#include "../util.h"
-
-void
-enmasse(int argc, char *argv[], int (*fn)(const char *, const char *))
-{
-       char *buf, *dir;
-       int i, len;
-       long size;
-       struct stat st;
-       size_t dlen;
-
-       if (argc == 2 && !(stat(argv[1], &st) == 0 && S_ISDIR(st.st_mode))) {
-               fnck(argv[0], argv[1], fn);
-               return;
-       } else {
-               dir = (argc == 1) ? "." : argv[--argc];
-       }
-
-       apathmax(&buf, &size);
-       for (i = 0; i < argc; i++) {
-               dlen = strlen(dir);
-               if (dlen > 0 && dir[dlen - 1] == '/')
-                       len = snprintf(buf, size, "%s%s", dir, 
basename(argv[i]));
-               else
-                       len = snprintf(buf, size, "%s/%s", dir, 
basename(argv[i]));
-               if (len < 0 || len >= size) {
-                       eprintf("%s/%s: filename too long\n", dir,
-                               basename(argv[i]));
-               }
-               fnck(argv[i], buf, fn);
-       }
-       free(buf);
-}
diff --git a/util/eprintf.c b/util/eprintf.c
deleted file mode 100644
index 407c502..0000000
--- a/util/eprintf.c
+++ /dev/null
@@ -1,67 +0,0 @@
-/* See LICENSE file for copyright and license details. */
-#include <stdarg.h>
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-
-#include "../util.h"
-
-char *argv0;
-
-static void venprintf(int, const char *, va_list);
-
-void
-eprintf(const char *fmt, ...)
-{
-       va_list ap;
-
-       va_start(ap, fmt);
-       venprintf(1, fmt, ap);
-       va_end(ap);
-}
-
-void
-enprintf(int status, const char *fmt, ...)
-{
-       va_list ap;
-
-       va_start(ap, fmt);
-       venprintf(status, fmt, ap);
-       va_end(ap);
-}
-
-void
-venprintf(int status, const char *fmt, va_list ap)
-{
-#ifdef DEBUG
-       fprintf(stderr, "%s: ", argv0);
-#endif
-
-       vfprintf(stderr, fmt, ap);
-
-       if (fmt[0] && fmt[strlen(fmt)-1] == ':') {
-               fputc(' ', stderr);
-               perror(NULL);
-       }
-
-       exit(status);
-}
-
-void
-weprintf(const char *fmt, ...)
-{
-       va_list ap;
-
-#ifdef DEBUG
-       fprintf(stderr, "%s: ", argv0);
-#endif
-
-       va_start(ap, fmt);
-       vfprintf(stderr, fmt, ap);
-       va_end(ap);
-
-       if (fmt[0] && fmt[strlen(fmt)-1] == ':') {
-               fputc(' ', stderr);
-               perror(NULL);
-       }
-}
diff --git a/util/eregcomp.c b/util/eregcomp.c
deleted file mode 100644
index 49c1bc5..0000000
--- a/util/eregcomp.c
+++ /dev/null
@@ -1,25 +0,0 @@
-#include <regex.h>
-#include <stdio.h>
-#include <sys/types.h>
-
-#include "../util.h"
-
-int
-enregcomp(int status, regex_t *preg, const char *regex, int cflags)
-{
-    char errbuf[BUFSIZ] = "";
-    int r;
-
-    if((r = regcomp(preg, regex, cflags)) == 0)
-        return r;
-
-    regerror(r, preg, errbuf, sizeof(errbuf));
-    enprintf(status, "invalid regex: %s\n", errbuf);
-    return r;
-}
-
-int
-eregcomp(regex_t *preg, const char *regex, int cflags)
-{
-       return enregcomp(1, preg, regex, cflags);
-}
diff --git a/util/estrtod.c b/util/estrtod.c
deleted file mode 100644
index 24e4fdc..0000000
--- a/util/estrtod.c
+++ /dev/null
@@ -1,18 +0,0 @@
-/* See LICENSE file for copyright and license details. */
-#include <errno.h>
-#include <stdio.h>
-#include <stdlib.h>
-
-#include "../util.h"
-
-double
-estrtod(const char *s)
-{
-       char *end;
-       double d;
-
-       d = strtod(s, &end);
-       if (end == s || *end != '\0')
-               eprintf("%s: not a real number\n", s);
-       return d;
-}
diff --git a/util/estrtol.c b/util/estrtol.c
deleted file mode 100644
index 74c7fb4..0000000
--- a/util/estrtol.c
+++ /dev/null
@@ -1,27 +0,0 @@
-/* See LICENSE file for copyright and license details. */
-#include <errno.h>
-#include <stdio.h>
-#include <stdlib.h>
-
-#include "../util.h"
-
-long
-estrtol(const char *s, int base)
-{
-       char *end;
-       long n;
-
-       errno = 0;
-       n = strtol(s, &end, base);
-       if (*end != '\0') {
-               if (base == 0)
-                       eprintf("%s: not an integer\n", s);
-               else
-                       eprintf("%s: not a base %d integer\n", s, base);
-       }
-       if (errno != 0)
-               eprintf("%s:", s);
-
-       return n;
-}
-
diff --git a/util/fnck.c b/util/fnck.c
deleted file mode 100644
index 8053267..0000000
--- a/util/fnck.c
+++ /dev/null
@@ -1,20 +0,0 @@
-/* See LICENSE file for copyright and license details. */
-#include <sys/stat.h>
-
-#include "../util.h"
-
-void
-fnck(const char *a, const char *b, int (*fn)(const char *, const char *))
-{
-       struct stat sta, stb;
-
-       if (stat(a, &sta) == 0
-                       && stat(b, &stb) == 0
-                       && sta.st_dev == stb.st_dev
-                       && sta.st_ino == stb.st_ino) {
-               eprintf("%s -> %s: same file\n", a, b);
-       }
-
-       if (fn(a, b) == -1)
-               eprintf("%s -> %s:", a, b);
-}
diff --git a/util/getlines.c b/util/getlines.c
deleted file mode 100644
index df64544..0000000
--- a/util/getlines.c
+++ /dev/null
@@ -1,27 +0,0 @@
-/* See LICENSE file for copyright and license details. */
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-
-#include "../text.h"
-#include "../util.h"
-
-void
-getlines(FILE *fp, struct linebuf *b)
-{
-       char *line = NULL, **nline;
-       size_t size = 0, linelen;
-       ssize_t len;
-
-       while ((len = agetline(&line, &size, fp)) != -1) {
-               if (++b->nlines > b->capacity) {
-                       b->capacity += 512;
-                       nline = erealloc(b->lines, b->capacity * 
sizeof(*b->lines));
-                       b->lines = nline;
-               }
-               linelen = len + 1;
-               b->lines[b->nlines-1] = emalloc(linelen);
-               memcpy(b->lines[b->nlines-1], line, linelen);
-       }
-       free(line);
-}
diff --git a/util/human.c b/util/human.c
deleted file mode 100644
index 5527bce..0000000
--- a/util/human.c
+++ /dev/null
@@ -1,22 +0,0 @@
-/* See LICENSE file for copyright and license details. */
-#include <stdio.h>
-#include <string.h>
-
-#include "../util.h"
-
-char *
-humansize(double n)
-{
-       static char buf[16];
-       const char postfixes[] = "BKMGTPE";
-       size_t i;
-
-       for (i = 0; n >= 1024 && i < strlen(postfixes); i++)
-               n /= 1024;
-
-       if (!i)
-               snprintf(buf, sizeof(buf), "%lu", (unsigned long)n);
-       else
-               snprintf(buf, sizeof(buf), "%.1f%c", n, postfixes[i]);
-       return buf;
-}
diff --git a/util/md5.c b/util/md5.c
deleted file mode 100644
index c7483ac..0000000
--- a/util/md5.c
+++ /dev/null
@@ -1,148 +0,0 @@
-/* public domain md5 implementation based on rfc1321 and libtomcrypt */
-#include <stdint.h>
-#include <string.h>
-
-#include "../md5.h"
-
-static uint32_t rol(uint32_t n, int k) { return (n << k) | (n >> (32-k)); }
-#define F(x,y,z) (z ^ (x & (y ^ z)))
-#define G(x,y,z) (y ^ (z & (y ^ x)))
-#define H(x,y,z) (x ^ y ^ z)
-#define I(x,y,z) (y ^ (x | ~z))
-#define FF(a,b,c,d,w,s,t) a += F(b,c,d) + w + t; a = rol(a,s) + b
-#define GG(a,b,c,d,w,s,t) a += G(b,c,d) + w + t; a = rol(a,s) + b
-#define HH(a,b,c,d,w,s,t) a += H(b,c,d) + w + t; a = rol(a,s) + b
-#define II(a,b,c,d,w,s,t) a += I(b,c,d) + w + t; a = rol(a,s) + b
-
-static const uint32_t tab[64] = {
-       0xd76aa478, 0xe8c7b756, 0x242070db, 0xc1bdceee, 0xf57c0faf, 0x4787c62a, 
0xa8304613, 0xfd469501,
-       0x698098d8, 0x8b44f7af, 0xffff5bb1, 0x895cd7be, 0x6b901122, 0xfd987193, 
0xa679438e, 0x49b40821,
-       0xf61e2562, 0xc040b340, 0x265e5a51, 0xe9b6c7aa, 0xd62f105d, 0x02441453, 
0xd8a1e681, 0xe7d3fbc8,
-       0x21e1cde6, 0xc33707d6, 0xf4d50d87, 0x455a14ed, 0xa9e3e905, 0xfcefa3f8, 
0x676f02d9, 0x8d2a4c8a,
-       0xfffa3942, 0x8771f681, 0x6d9d6122, 0xfde5380c, 0xa4beea44, 0x4bdecfa9, 
0xf6bb4b60, 0xbebfbc70,
-       0x289b7ec6, 0xeaa127fa, 0xd4ef3085, 0x04881d05, 0xd9d4d039, 0xe6db99e5, 
0x1fa27cf8, 0xc4ac5665,
-       0xf4292244, 0x432aff97, 0xab9423a7, 0xfc93a039, 0x655b59c3, 0x8f0ccc92, 
0xffeff47d, 0x85845dd1,
-       0x6fa87e4f, 0xfe2ce6e0, 0xa3014314, 0x4e0811a1, 0xf7537e82, 0xbd3af235, 
0x2ad7d2bb, 0xeb86d391
-};
-
-static void
-processblock(struct md5 *s, const uint8_t *buf)
-{
-       uint32_t i, W[16], a, b, c, d;
-
-       for (i = 0; i < 16; i++) {
-               W[i] = buf[4*i];
-               W[i] |= (uint32_t)buf[4*i+1]<<8;
-               W[i] |= (uint32_t)buf[4*i+2]<<16;
-               W[i] |= (uint32_t)buf[4*i+3]<<24;
-       }
-
-       a = s->h[0];
-       b = s->h[1];
-       c = s->h[2];
-       d = s->h[3];
-
-       i = 0;
-       while (i < 16) {
-               FF(a,b,c,d, W[i],  7, tab[i]); i++;
-               FF(d,a,b,c, W[i], 12, tab[i]); i++;
-               FF(c,d,a,b, W[i], 17, tab[i]); i++;
-               FF(b,c,d,a, W[i], 22, tab[i]); i++;
-       }
-       while (i < 32) {
-               GG(a,b,c,d, W[(5*i+1)%16],  5, tab[i]); i++;
-               GG(d,a,b,c, W[(5*i+1)%16],  9, tab[i]); i++;
-               GG(c,d,a,b, W[(5*i+1)%16], 14, tab[i]); i++;
-               GG(b,c,d,a, W[(5*i+1)%16], 20, tab[i]); i++;
-       }
-       while (i < 48) {
-               HH(a,b,c,d, W[(3*i+5)%16],  4, tab[i]); i++;
-               HH(d,a,b,c, W[(3*i+5)%16], 11, tab[i]); i++;
-               HH(c,d,a,b, W[(3*i+5)%16], 16, tab[i]); i++;
-               HH(b,c,d,a, W[(3*i+5)%16], 23, tab[i]); i++;
-       }
-       while (i < 64) {
-               II(a,b,c,d, W[7*i%16],  6, tab[i]); i++;
-               II(d,a,b,c, W[7*i%16], 10, tab[i]); i++;
-               II(c,d,a,b, W[7*i%16], 15, tab[i]); i++;
-               II(b,c,d,a, W[7*i%16], 21, tab[i]); i++;
-       }
-
-       s->h[0] += a;
-       s->h[1] += b;
-       s->h[2] += c;
-       s->h[3] += d;
-}
-
-static void
-pad(struct md5 *s)
-{
-       unsigned r = s->len % 64;
-
-       s->buf[r++] = 0x80;
-       if (r > 56) {
-               memset(s->buf + r, 0, 64 - r);
-               r = 0;
-               processblock(s, s->buf);
-       }
-       memset(s->buf + r, 0, 56 - r);
-       s->len *= 8;
-       s->buf[56] = s->len;
-       s->buf[57] = s->len >> 8;
-       s->buf[58] = s->len >> 16;
-       s->buf[59] = s->len >> 24;
-       s->buf[60] = s->len >> 32;
-       s->buf[61] = s->len >> 40;
-       s->buf[62] = s->len >> 48;
-       s->buf[63] = s->len >> 56;
-       processblock(s, s->buf);
-}
-
-void
-md5_init(void *ctx)
-{
-       struct md5 *s = ctx;
-       s->len = 0;
-       s->h[0] = 0x67452301;
-       s->h[1] = 0xefcdab89;
-       s->h[2] = 0x98badcfe;
-       s->h[3] = 0x10325476;
-}
-
-void
-md5_sum(void *ctx, uint8_t md[MD5_DIGEST_LENGTH])
-{
-       struct md5 *s = ctx;
-       int i;
-
-       pad(s);
-       for (i = 0; i < 4; i++) {
-               md[4*i] = s->h[i];
-               md[4*i+1] = s->h[i] >> 8;
-               md[4*i+2] = s->h[i] >> 16;
-               md[4*i+3] = s->h[i] >> 24;
-       }
-}
-
-void
-md5_update(void *ctx, const void *m, unsigned long len)
-{
-       struct md5 *s = ctx;
-       const uint8_t *p = m;
-       unsigned r = s->len % 64;
-
-       s->len += len;
-       if (r) {
-               if (len < 64 - r) {
-                       memcpy(s->buf + r, p, len);
-                       return;
-               }
-               memcpy(s->buf + r, p, 64 - r);
-               len -= 64 - r;
-               p += 64 - r;
-               processblock(s, s->buf);
-       }
-       for (; len >= 64; len -= 64, p += 64)
-               processblock(s, p);
-       memcpy(s->buf, p, len);
-}
diff --git a/util/mode.c b/util/mode.c
deleted file mode 100644
index 16347d8..0000000
--- a/util/mode.c
+++ /dev/null
@@ -1,163 +0,0 @@
-#include <stdlib.h>
-#include <string.h>
-#include <sys/stat.h>
-#include <unistd.h>
-
-#include "../util.h"
-
-mode_t
-getumask(void)
-{
-       mode_t mask = umask(0);
-       umask(mask);
-       return mask;
-}
-
-mode_t
-parsemode(const char *str, mode_t mode, mode_t mask)
-{
-       char *end;
-       const char *p = str;
-       int octal, op;
-       mode_t who, perm, clear;
-
-       octal = strtol(str, &end, 8);
-       if (*end == '\0') {
-               if (octal < 0 || octal > 07777) {
-                       eprintf("%s: invalid mode\n", str);
-                       return -1;
-               }
-               mode = 0;
-               if (octal & 04000) mode |= S_ISUID;
-               if (octal & 02000) mode |= S_ISGID;
-               if (octal & 01000) mode |= S_ISVTX;
-               if (octal & 00400) mode |= S_IRUSR;
-               if (octal & 00200) mode |= S_IWUSR;
-               if (octal & 00100) mode |= S_IXUSR;
-               if (octal & 00040) mode |= S_IRGRP;
-               if (octal & 00020) mode |= S_IWGRP;
-               if (octal & 00010) mode |= S_IXGRP;
-               if (octal & 00004) mode |= S_IROTH;
-               if (octal & 00002) mode |= S_IWOTH;
-               if (octal & 00001) mode |= S_IXOTH;
-               return mode;
-       }
-next:
-       /* first, determine which bits we will be modifying */
-       for (who = 0; *p; p++) {
-               switch (*p) {
-               /* masks */
-               case 'u':
-                       who |= S_IRWXU|S_ISUID;
-                       continue;
-               case 'g':
-                       who |= S_IRWXG|S_ISGID;
-                       continue;
-               case 'o':
-                       who |= S_IRWXO;
-                       continue;
-               case 'a':
-                       who |= S_IRWXU|S_ISUID|S_IRWXG|S_ISGID|S_IRWXO;
-                       continue;
-               }
-               break;
-       }
-       if (who) {
-               clear = who;
-       } else {
-               clear = S_ISUID|S_ISGID|S_ISVTX|S_IRWXU|S_IRWXG|S_IRWXO;
-               who = ~mask;
-       }
-       while (*p) {
-               switch (*p) {
-               /* opers */
-               case '=':
-               case '+':
-               case '-':
-                       op = (int)*p;
-                       break;
-               default:
-                       eprintf("%s: invalid mode\n", str);
-                       return -1;
-               }
-
-               perm = 0;
-               switch (*++p) {
-               /* copy */
-               case 'u':
-                       if (mode & S_IRUSR)
-                               perm |= S_IRUSR|S_IRGRP|S_IROTH;
-                       if (mode & S_IWUSR)
-                               perm |= S_IWUSR|S_IWGRP|S_IWOTH;
-                       if (mode & S_IXUSR)
-                               perm |= S_IXUSR|S_IXGRP|S_IXOTH;
-                       if (mode & S_ISUID)
-                               perm |= S_ISUID|S_ISGID;
-                       p++;
-                       break;
-               case 'g':
-                       if (mode & S_IRGRP)
-                               perm |= S_IRUSR|S_IRGRP|S_IROTH;
-                       if (mode & S_IWGRP)
-                               perm |= S_IWUSR|S_IWGRP|S_IWOTH;
-                       if (mode & S_IXGRP)
-                               perm |= S_IXUSR|S_IXGRP|S_IXOTH;
-                       if (mode & S_ISGID)
-                               perm |= S_ISUID|S_ISGID;
-                       p++;
-                       break;
-               case 'o':
-                       if (mode & S_IROTH)
-                               perm |= S_IRUSR|S_IRGRP|S_IROTH;
-                       if (mode & S_IWOTH)
-                               perm |= S_IWUSR|S_IWGRP|S_IWOTH;
-                       if (mode & S_IXOTH)
-                               perm |= S_IXUSR|S_IXGRP|S_IXOTH;
-                       p++;
-                       break;
-               default:
-                       for (; *p; p++) {
-                               switch (*p) {
-                               /* modes */
-                               case 'r':
-                                       perm |= S_IRUSR|S_IRGRP|S_IROTH;
-                                       break;
-                               case 'w':
-                                       perm |= S_IWUSR|S_IWGRP|S_IWOTH;
-                                       break;
-                               case 'x':
-                                       perm |= S_IXUSR|S_IXGRP|S_IXOTH;
-                                       break;
-                               case 's':
-                                       perm |= S_ISUID|S_ISGID;
-                                       break;
-                               case 't':
-                                       perm |= S_ISVTX;
-                                       break;
-                               default:
-                                       goto apply;
-                               }
-                       }
-               }
-
-       apply:
-               /* apply */
-               switch (op) {
-               case '=':
-                       mode &= ~clear;
-                       /* fallthrough */
-               case '+':
-                       mode |= perm & who;
-                       break;
-               case '-':
-                       mode &= ~(perm & who);
-                       break;
-               }
-               /* if we hit a comma, move on to the next clause */
-               if (*p == ',') {
-                       p++;
-                       goto next;
-               }
-       }
-       return mode;
-}
diff --git a/util/putword.c b/util/putword.c
deleted file mode 100644
index c460703..0000000
--- a/util/putword.c
+++ /dev/null
@@ -1,16 +0,0 @@
-/* See LICENSE file for copyright and license details. */
-#include <stdio.h>
-
-#include "../util.h"
-
-void
-putword(const char *s)
-{
-       static int first = 1;
-
-       if (!first)
-               putchar(' ');
-
-       fputs(s, stdout);
-       first = 0;
-}
diff --git a/util/recurse.c b/util/recurse.c
deleted file mode 100644
index 318987d..0000000
--- a/util/recurse.c
+++ /dev/null
@@ -1,42 +0,0 @@
-/* See LICENSE file for copyright and license details. */
-#include <dirent.h>
-#include <limits.h>
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-#include <sys/stat.h>
-#include <sys/types.h>
-#include <unistd.h>
-
-#include "../util.h"
-
-void
-recurse(const char *path, void (*fn)(const char *))
-{
-       char buf[PATH_MAX];
-       struct dirent *d;
-       struct stat st;
-       DIR *dp;
-
-       if (lstat(path, &st) == -1 || S_ISDIR(st.st_mode) == 0)
-               return;
-
-       if (!(dp = opendir(path)))
-               eprintf("opendir %s:", path);
-
-       while ((d = readdir(dp))) {
-               if (strcmp(d->d_name, ".") == 0 ||
-                   strcmp(d->d_name, "..") == 0)
-                       continue;
-               if (strlcpy(buf, path, sizeof(buf)) >= sizeof(buf))
-                       eprintf("path too long\n");
-               if (buf[strlen(buf) - 1] != '/')
-                       if (strlcat(buf, "/", sizeof(buf)) >= sizeof(buf))
-                               eprintf("path too long\n");
-               if (strlcat(buf, d->d_name, sizeof(buf)) >= sizeof(buf))
-                       eprintf("path too long\n");
-               fn(buf);
-       }
-
-       closedir(dp);
-}
diff --git a/util/rm.c b/util/rm.c
deleted file mode 100644
index a89b11c..0000000
--- a/util/rm.c
+++ /dev/null
@@ -1,17 +0,0 @@
-/* See LICENSE file for copyright and license details. */
-#include <stdio.h>
-
-#include "../fs.h"
-#include "../util.h"
-
-int rm_fflag = 0;
-int rm_rflag = 0;
-
-void
-rm(const char *path)
-{
-       if (rm_rflag)
-               recurse(path, rm);
-       if (remove(path) == -1 && !rm_fflag)
-               eprintf("remove %s:", path);
-}
diff --git a/util/sha1.c b/util/sha1.c
deleted file mode 100644
index 3d76a1b..0000000
--- a/util/sha1.c
+++ /dev/null
@@ -1,144 +0,0 @@
-/* public domain sha1 implementation based on rfc3174 and libtomcrypt */
-#include <stdint.h>
-#include <string.h>
-
-#include "../sha1.h"
-
-static uint32_t rol(uint32_t n, int k) { return (n << k) | (n >> (32-k)); }
-#define F0(b,c,d) (d ^ (b & (c ^ d)))
-#define F1(b,c,d) (b ^ c ^ d)
-#define F2(b,c,d) ((b & c) | (d & (b | c)))
-#define F3(b,c,d) (b ^ c ^ d)
-#define G0(a,b,c,d,e,i) e += rol(a,5)+F0(b,c,d)+W[i]+0x5A827999; b = rol(b,30)
-#define G1(a,b,c,d,e,i) e += rol(a,5)+F1(b,c,d)+W[i]+0x6ED9EBA1; b = rol(b,30)
-#define G2(a,b,c,d,e,i) e += rol(a,5)+F2(b,c,d)+W[i]+0x8F1BBCDC; b = rol(b,30)
-#define G3(a,b,c,d,e,i) e += rol(a,5)+F3(b,c,d)+W[i]+0xCA62C1D6; b = rol(b,30)
-
-static void
-processblock(struct sha1 *s, const uint8_t *buf)
-{
-       uint32_t W[80], a, b, c, d, e;
-       int i;
-
-       for (i = 0; i < 16; i++) {
-               W[i] = (uint32_t)buf[4*i]<<24;
-               W[i] |= (uint32_t)buf[4*i+1]<<16;
-               W[i] |= (uint32_t)buf[4*i+2]<<8;
-               W[i] |= buf[4*i+3];
-       }
-       for (; i < 80; i++)
-               W[i] = rol(W[i-3] ^ W[i-8] ^ W[i-14] ^ W[i-16], 1);
-       a = s->h[0];
-       b = s->h[1];
-       c = s->h[2];
-       d = s->h[3];
-       e = s->h[4];
-       for (i = 0; i < 20; ) {
-               G0(a,b,c,d,e,i++);
-               G0(e,a,b,c,d,i++);
-               G0(d,e,a,b,c,i++);
-               G0(c,d,e,a,b,i++);
-               G0(b,c,d,e,a,i++);
-       }
-       while (i < 40) {
-               G1(a,b,c,d,e,i++);
-               G1(e,a,b,c,d,i++);
-               G1(d,e,a,b,c,i++);
-               G1(c,d,e,a,b,i++);
-               G1(b,c,d,e,a,i++);
-       }
-       while (i < 60) {
-               G2(a,b,c,d,e,i++);
-               G2(e,a,b,c,d,i++);
-               G2(d,e,a,b,c,i++);
-               G2(c,d,e,a,b,i++);
-               G2(b,c,d,e,a,i++);
-       }
-       while (i < 80) {
-               G3(a,b,c,d,e,i++);
-               G3(e,a,b,c,d,i++);
-               G3(d,e,a,b,c,i++);
-               G3(c,d,e,a,b,i++);
-               G3(b,c,d,e,a,i++);
-       }
-       s->h[0] += a;
-       s->h[1] += b;
-       s->h[2] += c;
-       s->h[3] += d;
-       s->h[4] += e;
-}
-
-static void
-pad(struct sha1 *s)
-{
-       unsigned r = s->len % 64;
-
-       s->buf[r++] = 0x80;
-       if (r > 56) {
-               memset(s->buf + r, 0, 64 - r);
-               r = 0;
-               processblock(s, s->buf);
-       }
-       memset(s->buf + r, 0, 56 - r);
-       s->len *= 8;
-       s->buf[56] = s->len >> 56;
-       s->buf[57] = s->len >> 48;
-       s->buf[58] = s->len >> 40;
-       s->buf[59] = s->len >> 32;
-       s->buf[60] = s->len >> 24;
-       s->buf[61] = s->len >> 16;
-       s->buf[62] = s->len >> 8;
-       s->buf[63] = s->len;
-       processblock(s, s->buf);
-}
-
-void
-sha1_init(void *ctx)
-{
-       struct sha1 *s = ctx;
-
-       s->len = 0;
-       s->h[0] = 0x67452301;
-       s->h[1] = 0xEFCDAB89;
-       s->h[2] = 0x98BADCFE;
-       s->h[3] = 0x10325476;
-       s->h[4] = 0xC3D2E1F0;
-}
-
-void
-sha1_sum(void *ctx, uint8_t md[SHA1_DIGEST_LENGTH])
-{
-       struct sha1 *s = ctx;
-       int i;
-
-       pad(s);
-       for (i = 0; i < 5; i++) {
-               md[4*i] = s->h[i] >> 24;
-               md[4*i+1] = s->h[i] >> 16;
-               md[4*i+2] = s->h[i] >> 8;
-               md[4*i+3] = s->h[i];
-       }
-}
-
-void
-sha1_update(void *ctx, const void *m, unsigned long len)
-{
-       struct sha1 *s = ctx;
-       const uint8_t *p = m;
-       unsigned r = s->len % 64;
-
-       s->len += len;
-       if (r) {
-               if (len < 64 - r) {
-                       memcpy(s->buf + r, p, len);
-                       return;
-               }
-               memcpy(s->buf + r, p, 64 - r);
-               len -= 64 - r;
-               p += 64 - r;
-               processblock(s, s->buf);
-       }
-       for (; len >= 64; len -= 64, p += 64)
-               processblock(s, p);
-       memcpy(s->buf, p, len);
-}
diff --git a/util/sha256.c b/util/sha256.c
deleted file mode 100644
index e30169b..0000000
--- a/util/sha256.c
+++ /dev/null
@@ -1,148 +0,0 @@
-/* public domain sha256 implementation based on fips180-3 */
-#include <ctype.h>
-#include <stdint.h>
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-
-#include "../sha256.h"
-
-static uint32_t ror(uint32_t n, int k) { return (n >> k) | (n << (32-k)); }
-#define Ch(x,y,z)  (z ^ (x & (y ^ z)))
-#define Maj(x,y,z) ((x & y) | (z & (x | y)))
-#define S0(x)      (ror(x,2) ^ ror(x,13) ^ ror(x,22))
-#define S1(x)      (ror(x,6) ^ ror(x,11) ^ ror(x,25))
-#define R0(x)      (ror(x,7) ^ ror(x,18) ^ (x>>3))
-#define R1(x)      (ror(x,17) ^ ror(x,19) ^ (x>>10))
-
-static const uint32_t K[64] = {
-0x428a2f98, 0x71374491, 0xb5c0fbcf, 0xe9b5dba5, 0x3956c25b, 0x59f111f1, 
0x923f82a4, 0xab1c5ed5,
-0xd807aa98, 0x12835b01, 0x243185be, 0x550c7dc3, 0x72be5d74, 0x80deb1fe, 
0x9bdc06a7, 0xc19bf174,
-0xe49b69c1, 0xefbe4786, 0x0fc19dc6, 0x240ca1cc, 0x2de92c6f, 0x4a7484aa, 
0x5cb0a9dc, 0x76f988da,
-0x983e5152, 0xa831c66d, 0xb00327c8, 0xbf597fc7, 0xc6e00bf3, 0xd5a79147, 
0x06ca6351, 0x14292967,
-0x27b70a85, 0x2e1b2138, 0x4d2c6dfc, 0x53380d13, 0x650a7354, 0x766a0abb, 
0x81c2c92e, 0x92722c85,
-0xa2bfe8a1, 0xa81a664b, 0xc24b8b70, 0xc76c51a3, 0xd192e819, 0xd6990624, 
0xf40e3585, 0x106aa070,
-0x19a4c116, 0x1e376c08, 0x2748774c, 0x34b0bcb5, 0x391c0cb3, 0x4ed8aa4a, 
0x5b9cca4f, 0x682e6ff3,
-0x748f82ee, 0x78a5636f, 0x84c87814, 0x8cc70208, 0x90befffa, 0xa4506ceb, 
0xbef9a3f7, 0xc67178f2
-};
-
-static void
-processblock(struct sha256 *s, const uint8_t *buf)
-{
-       uint32_t W[64], t1, t2, a, b, c, d, e, f, g, h;
-       int i;
-
-       for (i = 0; i < 16; i++) {
-               W[i] = (uint32_t)buf[4*i]<<24;
-               W[i] |= (uint32_t)buf[4*i+1]<<16;
-               W[i] |= (uint32_t)buf[4*i+2]<<8;
-               W[i] |= buf[4*i+3];
-       }
-       for (; i < 64; i++)
-               W[i] = R1(W[i-2]) + W[i-7] + R0(W[i-15]) + W[i-16];
-       a = s->h[0];
-       b = s->h[1];
-       c = s->h[2];
-       d = s->h[3];
-       e = s->h[4];
-       f = s->h[5];
-       g = s->h[6];
-       h = s->h[7];
-       for (i = 0; i < 64; i++) {
-               t1 = h + S1(e) + Ch(e,f,g) + K[i] + W[i];
-               t2 = S0(a) + Maj(a,b,c);
-               h = g;
-               g = f;
-               f = e;
-               e = d + t1;
-               d = c;
-               c = b;
-               b = a;
-               a = t1 + t2;
-       }
-       s->h[0] += a;
-       s->h[1] += b;
-       s->h[2] += c;
-       s->h[3] += d;
-       s->h[4] += e;
-       s->h[5] += f;
-       s->h[6] += g;
-       s->h[7] += h;
-}
-
-static void
-pad(struct sha256 *s)
-{
-       unsigned r = s->len % 64;
-
-       s->buf[r++] = 0x80;
-       if (r > 56) {
-               memset(s->buf + r, 0, 64 - r);
-               r = 0;
-               processblock(s, s->buf);
-       }
-       memset(s->buf + r, 0, 56 - r);
-       s->len *= 8;
-       s->buf[56] = s->len >> 56;
-       s->buf[57] = s->len >> 48;
-       s->buf[58] = s->len >> 40;
-       s->buf[59] = s->len >> 32;
-       s->buf[60] = s->len >> 24;
-       s->buf[61] = s->len >> 16;
-       s->buf[62] = s->len >> 8;
-       s->buf[63] = s->len;
-       processblock(s, s->buf);
-}
-
-void
-sha256_init(void *ctx)
-{
-       struct sha256 *s = ctx;
-       s->len = 0;
-       s->h[0] = 0x6a09e667;
-       s->h[1] = 0xbb67ae85;
-       s->h[2] = 0x3c6ef372;
-       s->h[3] = 0xa54ff53a;
-       s->h[4] = 0x510e527f;
-       s->h[5] = 0x9b05688c;
-       s->h[6] = 0x1f83d9ab;
-       s->h[7] = 0x5be0cd19;
-}
-
-void
-sha256_sum(void *ctx, uint8_t md[SHA256_DIGEST_LENGTH])
-{
-       struct sha256 *s = ctx;
-       int i;
-
-       pad(s);
-       for (i = 0; i < 8; i++) {
-               md[4*i] = s->h[i] >> 24;
-               md[4*i+1] = s->h[i] >> 16;
-               md[4*i+2] = s->h[i] >> 8;
-               md[4*i+3] = s->h[i];
-       }
-}
-
-void
-sha256_update(void *ctx, const void *m, unsigned long len)
-{
-       struct sha256 *s = ctx;
-       const uint8_t *p = m;
-       unsigned r = s->len % 64;
-
-       s->len += len;
-       if (r) {
-               if (len < 64 - r) {
-                       memcpy(s->buf + r, p, len);
-                       return;
-               }
-               memcpy(s->buf + r, p, 64 - r);
-               len -= 64 - r;
-               p += 64 - r;
-               processblock(s, s->buf);
-       }
-       for (; len >= 64; len -= 64, p += 64)
-               processblock(s, p);
-       memcpy(s->buf, p, len);
-}
diff --git a/util/sha512.c b/util/sha512.c
deleted file mode 100644
index efe4f91..0000000
--- a/util/sha512.c
+++ /dev/null
@@ -1,169 +0,0 @@
-/* public domain sha256 implementation based on fips180-3 */
-
-#include <ctype.h>
-#include <stdint.h>
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-
-#include "../sha512.h"
-
-static uint64_t ror(uint64_t n, int k) { return (n >> k) | (n << (64-k)); }
-#define Ch(x,y,z)  (z ^ (x & (y ^ z)))
-#define Maj(x,y,z) ((x & y) | (z & (x | y)))
-#define S0(x)      (ror(x,28) ^ ror(x,34) ^ ror(x,39))
-#define S1(x)      (ror(x,14) ^ ror(x,18) ^ ror(x,41))
-#define R0(x)      (ror(x,1) ^ ror(x,8) ^ (x>>7))
-#define R1(x)      (ror(x,19) ^ ror(x,61) ^ (x>>6))
-
-static const uint64_t K[80] = {
-0x428a2f98d728ae22ULL, 0x7137449123ef65cdULL, 0xb5c0fbcfec4d3b2fULL, 
0xe9b5dba58189dbbcULL,
-0x3956c25bf348b538ULL, 0x59f111f1b605d019ULL, 0x923f82a4af194f9bULL, 
0xab1c5ed5da6d8118ULL,
-0xd807aa98a3030242ULL, 0x12835b0145706fbeULL, 0x243185be4ee4b28cULL, 
0x550c7dc3d5ffb4e2ULL,
-0x72be5d74f27b896fULL, 0x80deb1fe3b1696b1ULL, 0x9bdc06a725c71235ULL, 
0xc19bf174cf692694ULL,
-0xe49b69c19ef14ad2ULL, 0xefbe4786384f25e3ULL, 0x0fc19dc68b8cd5b5ULL, 
0x240ca1cc77ac9c65ULL,
-0x2de92c6f592b0275ULL, 0x4a7484aa6ea6e483ULL, 0x5cb0a9dcbd41fbd4ULL, 
0x76f988da831153b5ULL,
-0x983e5152ee66dfabULL, 0xa831c66d2db43210ULL, 0xb00327c898fb213fULL, 
0xbf597fc7beef0ee4ULL,
-0xc6e00bf33da88fc2ULL, 0xd5a79147930aa725ULL, 0x06ca6351e003826fULL, 
0x142929670a0e6e70ULL,
-0x27b70a8546d22ffcULL, 0x2e1b21385c26c926ULL, 0x4d2c6dfc5ac42aedULL, 
0x53380d139d95b3dfULL,
-0x650a73548baf63deULL, 0x766a0abb3c77b2a8ULL, 0x81c2c92e47edaee6ULL, 
0x92722c851482353bULL,
-0xa2bfe8a14cf10364ULL, 0xa81a664bbc423001ULL, 0xc24b8b70d0f89791ULL, 
0xc76c51a30654be30ULL,
-0xd192e819d6ef5218ULL, 0xd69906245565a910ULL, 0xf40e35855771202aULL, 
0x106aa07032bbd1b8ULL,
-0x19a4c116b8d2d0c8ULL, 0x1e376c085141ab53ULL, 0x2748774cdf8eeb99ULL, 
0x34b0bcb5e19b48a8ULL,
-0x391c0cb3c5c95a63ULL, 0x4ed8aa4ae3418acbULL, 0x5b9cca4f7763e373ULL, 
0x682e6ff3d6b2b8a3ULL,
-0x748f82ee5defb2fcULL, 0x78a5636f43172f60ULL, 0x84c87814a1f0ab72ULL, 
0x8cc702081a6439ecULL,
-0x90befffa23631e28ULL, 0xa4506cebde82bde9ULL, 0xbef9a3f7b2c67915ULL, 
0xc67178f2e372532bULL,
-0xca273eceea26619cULL, 0xd186b8c721c0c207ULL, 0xeada7dd6cde0eb1eULL, 
0xf57d4f7fee6ed178ULL,
-0x06f067aa72176fbaULL, 0x0a637dc5a2c898a6ULL, 0x113f9804bef90daeULL, 
0x1b710b35131c471bULL,
-0x28db77f523047d84ULL, 0x32caab7b40c72493ULL, 0x3c9ebe0a15c9bebcULL, 
0x431d67c49c100d4cULL,
-0x4cc5d4becb3e42b6ULL, 0x597f299cfc657e2aULL, 0x5fcb6fab3ad6faecULL, 
0x6c44198c4a475817ULL
-};
-
-static void
-processblock(struct sha512 *s, const uint8_t *buf)
-{
-       uint64_t W[80], t1, t2, a, b, c, d, e, f, g, h;
-       int i;
-
-       for (i = 0; i < 16; i++) {
-               W[i] = (uint64_t)buf[8*i]<<56;
-               W[i] |= (uint64_t)buf[8*i+1]<<48;
-               W[i] |= (uint64_t)buf[8*i+2]<<40;
-               W[i] |= (uint64_t)buf[8*i+3]<<32;
-               W[i] |= (uint64_t)buf[8*i+4]<<24;
-               W[i] |= (uint64_t)buf[8*i+5]<<16;
-               W[i] |= (uint64_t)buf[8*i+6]<<8;
-               W[i] |= buf[8*i+7];
-       }
-       for (; i < 80; i++)
-               W[i] = R1(W[i-2]) + W[i-7] + R0(W[i-15]) + W[i-16];
-       a = s->h[0];
-       b = s->h[1];
-       c = s->h[2];
-       d = s->h[3];
-       e = s->h[4];
-       f = s->h[5];
-       g = s->h[6];
-       h = s->h[7];
-       for (i = 0; i < 80; i++) {
-               t1 = h + S1(e) + Ch(e,f,g) + K[i] + W[i];
-               t2 = S0(a) + Maj(a,b,c);
-               h = g;
-               g = f;
-               f = e;
-               e = d + t1;
-               d = c;
-               c = b;
-               b = a;
-               a = t1 + t2;
-       }
-       s->h[0] += a;
-       s->h[1] += b;
-       s->h[2] += c;
-       s->h[3] += d;
-       s->h[4] += e;
-       s->h[5] += f;
-       s->h[6] += g;
-       s->h[7] += h;
-}
-
-static void
-pad(struct sha512 *s)
-{
-       unsigned r = s->len % 128;
-
-       s->buf[r++] = 0x80;
-       if (r > 112) {
-               memset(s->buf + r, 0, 128 - r);
-               r = 0;
-               processblock(s, s->buf);
-       }
-       memset(s->buf + r, 0, 120 - r);
-       s->len *= 8;
-       s->buf[120] = s->len >> 56;
-       s->buf[121] = s->len >> 48;
-       s->buf[122] = s->len >> 40;
-       s->buf[123] = s->len >> 32;
-       s->buf[124] = s->len >> 24;
-       s->buf[125] = s->len >> 16;
-       s->buf[126] = s->len >> 8;
-       s->buf[127] = s->len;
-       processblock(s, s->buf);
-}
-
-void
-sha512_init(void *ctx)
-{
-       struct sha512 *s = ctx;
-       s->len = 0;
-       s->h[0] = 0x6a09e667f3bcc908ULL;
-       s->h[1] = 0xbb67ae8584caa73bULL;
-       s->h[2] = 0x3c6ef372fe94f82bULL;
-       s->h[3] = 0xa54ff53a5f1d36f1ULL;
-       s->h[4] = 0x510e527fade682d1ULL;
-       s->h[5] = 0x9b05688c2b3e6c1fULL;
-       s->h[6] = 0x1f83d9abfb41bd6bULL;
-       s->h[7] = 0x5be0cd19137e2179ULL;
-}
-
-void
-sha512_sum(void *ctx, uint8_t md[SHA512_DIGEST_LENGTH])
-{
-       struct sha512 *s = ctx;
-       int i;
-
-       pad(s);
-       for (i = 0; i < 8; i++) {
-               md[8*i] = s->h[i] >> 56;
-               md[8*i+1] = s->h[i] >> 48;
-               md[8*i+2] = s->h[i] >> 40;
-               md[8*i+3] = s->h[i] >> 32;
-               md[8*i+4] = s->h[i] >> 24;
-               md[8*i+5] = s->h[i] >> 16;
-               md[8*i+6] = s->h[i] >> 8;
-               md[8*i+7] = s->h[i];
-       }
-}
-
-void
-sha512_update(void *ctx, const void *m, unsigned long len)
-{
-       struct sha512 *s = ctx;
-       const uint8_t *p = m;
-       unsigned r = s->len % 128;
-
-       s->len += len;
-       if (r) {
-               if (len < 128 - r) {
-                       memcpy(s->buf + r, p, len);
-                       return;
-               }
-               memcpy(s->buf + r, p, 128 - r);
-               len -= 128 - r;
-               p += 128 - r;
-               processblock(s, s->buf);
-       }
-       for (; len >= 128; len -= 128, p += 128)
-               processblock(s, p);
-       memcpy(s->buf, p, len);
-}
diff --git a/util/strlcat.c b/util/strlcat.c
deleted file mode 100644
index 9e2d251..0000000
--- a/util/strlcat.c
+++ /dev/null
@@ -1,52 +0,0 @@
-/*
- * Copyright (c) 1998 Todd C. Miller <[email protected]>
- *
- * Permission to use, copy, modify, and distribute this software for any
- * purpose with or without fee is hereby granted, provided that the above
- * copyright notice and this permission notice appear in all copies.
- *
- * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
- * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
- * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
- * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
- * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
- * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
- * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
- */
-
-#include <string.h>
-#include <sys/types.h>
-
-#include "../util.h"
-
-/*
- * Appends src to string dst of size siz (unlike strncat, siz is the
- * full size of dst, not space left). At most siz-1 characters
- * will be copied. Always NUL terminates (unless siz <= strlen(dst)).
- * Returns strlen(src) + MIN(siz, strlen(initial dst)).
- * If retval >= siz, truncation occurred.
- */
-size_t
-strlcat(char *dst, const char *src, size_t siz)
-{
-       char *d = dst;
-       const char *s = src;
-       size_t n = siz;
-       size_t dlen;
-       /* Find the end of dst and adjust bytes left but don't go past end */
-       while (n-- != 0 && *d != '\0')
-               d++;
-       dlen = d - dst;
-       n = siz - dlen;
-       if (n == 0)
-               return(dlen + strlen(s));
-       while (*s != '\0') {
-               if (n != 1) {
-                       *d++ = *s;
-                       n--;
-               }
-               s++;
-       }
-       *d = '\0';
-       return(dlen + (s - src)); /* count does not include NUL */
-}
diff --git a/util/strlcpy.c b/util/strlcpy.c
deleted file mode 100644
index 388b426..0000000
--- a/util/strlcpy.c
+++ /dev/null
@@ -1,48 +0,0 @@
-/*
- * Copyright (c) 1998 Todd C. Miller <[email protected]>
- *
- * Permission to use, copy, modify, and distribute this software for any
- * purpose with or without fee is hereby granted, provided that the above
- * copyright notice and this permission notice appear in all copies.
- *
- * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
- * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
- * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
- * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
- * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
- * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
- * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
- */
-
-#include <string.h>
-#include <sys/types.h>
-
-#include "../util.h"
-
-/*
- * Copy src to string dst of size siz. At most siz-1 characters
- * will be copied. Always NUL terminates (unless siz == 0).
- * Returns strlen(src); if retval >= siz, truncation occurred.
- */
-size_t
-strlcpy(char *dst, const char *src, size_t siz)
-{
-       char *d = dst;
-       const char *s = src;
-       size_t n = siz;
-       /* Copy as many bytes as will fit */
-       if (n != 0) {
-               while (--n != 0) {
-                       if ((*d++ = *s++) == '\0')
-                               break;
-               }
-       }
-       /* Not enough room in dst, add NUL and traverse rest of src */
-       if (n == 0) {
-               if (siz != 0)
-                       *d = '\0'; /* NUL-terminate dst */
-               while (*s++)
-                       ;
-       }
-       return(s - src - 1); /* count does not include NUL */
-}


Reply via email to