Commit Diff


commit - ad324bf53a11587dc227a2c00b65020595aa18dc
commit + dd038bc6ec835ad3fd3c0b5303b8af9ad506c8cc
blob - eecd321da5ab5335eee50eef2c98ad64e4a941c2
blob + 4feb81eb19b25dc2dbaf0653514c832fb3a674c4
--- .gitignore
+++ .gitignore
@@ -1 +1,33 @@
+**/Makefile
+**/Makefile.in
 **/obj
+*.core
+*.o
+*~
+.ccls-cache/
+.deps/
+aclocal.m4
+autom4te.cache/
+compat/.dirstamp
+compat/libopenbsd-compat.a
+config.log
+config.status
+configure
+core
+etc/
+got/got
+lib/.dirstamp
+libexec/got-fetch-pack/got-fetch-pack
+libexec/got-index-pack/got-index-pack
+libexec/got-read-blob/got-read-blob
+libexec/got-read-commit/got-read-commit
+libexec/got-read-gitconfig/got-read-gitconfig
+libexec/got-read-gotconfig/got-read-gotconfig
+libexec/got-read-gotconfig/parse.c
+libexec/got-read-object/got-read-object
+libexec/got-read-pack/got-read-pack
+libexec/got-read-tag/got-read-tag
+libexec/got-read-tree/got-read-tree
+libexec/got-send-pack/got-send-pack
+tags
+tog/tog
blob - 5e96ac3cb604c6c6ffb943a5f7620395583905f4 (mode 644)
blob + /dev/null
--- Makefile
+++ /dev/null
@@ -1,38 +0,0 @@
-SUBDIR = libexec got tog gotadmin
-
-.PHONY: release dist
-
-.if make(regress) || make(obj) || make(clean) || make(release)
-SUBDIR += regress
-.endif
-
-.if make(clean) || make(obj) || make(release)
-SUBDIR += gotweb
-.endif
-
-.include "got-version.mk"
-
-release: clean
-	sed -i -e "s/_RELEASE=No/_RELEASE=Yes/" got-version.mk
-	${MAKE} dist
-	sed -i -e "s/_RELEASE=Yes/_RELEASE=No/" got-version.mk
-
-dist: clean
-	mkdir /tmp/got-${GOT_VERSION}
-	pax -rw * /tmp/got-${GOT_VERSION}
-	find /tmp/got-${GOT_VERSION} -name obj -type d -delete
-	rm /tmp/got-${GOT_VERSION}/got-dist.txt
-	tar -C /tmp -zcf got-${GOT_VERSION}.tar.gz got-${GOT_VERSION}
-	rm -rf /tmp/got-${GOT_VERSION}
-	tar -ztf got-${GOT_VERSION}.tar.gz | sed -e 's/^got-${GOT_VERSION}//' \
-		| sort > got-dist.txt.new
-	diff -u got-dist.txt got-dist.txt.new
-	rm got-dist.txt.new
-
-web:
-	${MAKE} -C gotweb
-
-web-install:
-	${MAKE} -C gotweb install
-
-.include <bsd.subdir.mk>
blob - /dev/null
blob + 4d15c9e720e7a7644d6983ae2ff9c92677aa1ea7 (mode 644)
--- /dev/null
+++ Makefile.am
@@ -0,0 +1,27 @@
+SUBDIRS = compat libexec got tog
+
+EXTRA_DIST = compat/*.[ch] \
+	     got/*.[15] \
+	     lib/*.[ch] \
+	     include/*.[ch] \
+	     tog/*.[15] \
+	     gotadmin/*.[15] \
+	     libexec
+
+AM_CPPFLAGS += -DGOT_VERSION='"@VERSION'" \
+	-DGOT_VERSION_NUMBER='"@VERSION"' \
+	-DGOT_LIBEXEC_DIR="${bindir}" \
+	-I$(top_srcdir)/lib \
+	-I$(top_srcdir)/compat \
+	-I$(top_srcdir)/include
+
+LDADD = $(LIBOBJS)
+
+# FIXME: enable via --enable-debug.  Hard-code for now.
+AM_CFLAGS += -g
+AM_CFLAGS += -Wno-long-long -Wall -W -Wformat=2
+AM_CFLAGS += -Wmissing-prototypes -Wstrict-prototypes -Wmissing-declarations
+AM_CFLAGS += -Wwrite-strings -Wshadow -Wpointer-arith -Wsign-compare
+AM_CFLAGS += -Wundef -Wbad-function-cast -Winline -Wcast-align
+AM_CFLAGS += -Wdeclaration-after-statement -Wno-pointer-sign -Wno-attributes
+AM_CFLAGS += -Wno-unused-result
blob - /dev/null
blob + c45f4472af3c2badce8145589e4e33fff3b66e60 (mode 644)
--- /dev/null
+++ README.portable
@@ -0,0 +1,48 @@
+README.portable
+===============
+
+This is the portable version of got[1] (Game of Trees), using autotools to
+provide the library checks required for Got's dependencies.
+
+Currently this has only been tested on Linux, although in theory this should
+still work on *BSD although the BSDs are already packaging Got via ports so
+this isn't a core focus of this portable repository, but patches to improve
+portability across systems are welcomed.
+
+DEPENDENCIES
+============
+
+Got requires the following libraries:
+
+* libncurses (for tog(1))
+* libmd (BSD's digest routines)
+* libcrypto (often via 'libssl-dev' for SHA1 routines)
+* libuuid (for UUID generation)
+* libz (for Z compression)
+
+Currently, these dependencies are searched for via pkg-config(1) which must
+also be installed.
+
+INSTALLATION
+============
+
+ $ autoreconf -i
+ $ ./configure && make
+ $ sudo make install
+
+TODO
+====
+
+This port is incomplete in that only got(1) and tog(1) have been ported.
+gotweb and the test suite (regress) have yet to be ported.
+
+configure.ac should start defining AC_ENABLE arguments to allow for
+finer-grained control of where to search for includes/libraries, etc.
+
+CONTACT
+=======
+
+Thomas Adam <thomas@xteddy.org>
+thomas_adam (#gameoftrees on irc.freenode.net)
+
+[1]  https://gameoftrees.org
blob - a53d25848b09acd89ddfa729b2104f4145517095 (mode 644)
blob + /dev/null
--- got/Makefile
+++ /dev/null
@@ -1,40 +0,0 @@
-.PATH:${.CURDIR}/../lib
-
-.include "../got-version.mk"
-
-PROG=		got
-SRCS=		got.c blame.c commit_graph.c delta.c diff.c \
-		diffreg.c error.c fileindex.c object.c object_cache.c \
-		object_idset.c object_parse.c opentemp.c path.c pack.c \
-		privsep.c reference.c repository.c sha1.c worktree.c \
-		inflate.c buf.c rcsutil.c diff3.c lockfile.c \
-		deflate.c object_create.c delta_cache.c fetch.c \
-		gotconfig.c diff_main.c diff_atomize_text.c \
-		diff_myers.c diff_output.c diff_output_plain.c \
-		diff_output_unidiff.c diff_output_edscript.c \
-		diff_patience.c send.c deltify.c pack_create.c dial.c
-
-MAN =		${PROG}.1 got-worktree.5 git-repository.5 got.conf.5
-
-CPPFLAGS = -I${.CURDIR}/../include -I${.CURDIR}/../lib
-
-.if defined(PROFILE)
-LDADD = -lutil_p -lz_p -lc_p
-.else
-LDADD = -lutil -lz
-.endif
-DPADD = ${LIBZ} ${LIBUTIL}
-
-.if ${GOT_RELEASE} != "Yes"
-NOMAN = Yes
-.endif
-
-realinstall:
-	${INSTALL} ${INSTALL_COPY} -o ${BINOWN} -g ${BINGRP} \
-	-m ${BINMODE} ${PROG} ${BINDIR}/${PROG}
-
-dist:
-	mkdir ../got-${GOT_VERSION}/got
-	cp ${SRCS} ${MAN} ../got-${GOT_VERSION}/got
-
-.include <bsd.prog.mk>
blob - /dev/null
blob + a82ceae6ec0e1c190faf5bf202acf3c63aaed985 (mode 644)
--- /dev/null
+++ got/Makefile.am
@@ -0,0 +1,59 @@
+bin_PROGRAMS = got
+
+got_SOURCES = got.c \
+	$(top_srcdir)/lib/blame.c \
+	$(top_srcdir)/lib/commit_graph.c \
+	$(top_srcdir)/lib/delta.c \
+	$(top_srcdir)/lib/diff.c \
+	$(top_srcdir)/lib/diffreg.c \
+	$(top_srcdir)/lib/error.c \
+	$(top_srcdir)/lib/fileindex.c \
+	$(top_srcdir)/lib/object.c \
+	$(top_srcdir)/lib/object_cache.c \
+	$(top_srcdir)/lib/object_idset.c \
+	$(top_srcdir)/lib/object_parse.c \
+	$(top_srcdir)/lib/opentemp.c \
+	$(top_srcdir)/lib/path.c \
+	$(top_srcdir)/lib/pack.c \
+	$(top_srcdir)/lib/privsep.c \
+	$(top_srcdir)/lib/reference.c \
+	$(top_srcdir)/lib/repository.c \
+	$(top_srcdir)/lib/sha1.c \
+	$(top_srcdir)/lib/worktree.c \
+	$(top_srcdir)/lib/inflate.c \
+	$(top_srcdir)/lib/buf.c \
+	$(top_srcdir)/lib/rcsutil.c \
+	$(top_srcdir)/lib/diff3.c \
+	$(top_srcdir)/lib/lockfile.c \
+	$(top_srcdir)/lib/deflate.c \
+	$(top_srcdir)/lib/object_create.c \
+	$(top_srcdir)/lib/delta_cache.c \
+	$(top_srcdir)/lib/fetch.c \
+	$(top_srcdir)/lib/gotconfig.c \
+	$(top_srcdir)/lib/diff_main.c \
+	$(top_srcdir)/lib/diff_atomize_text.c \
+	$(top_srcdir)/lib/diff_myers.c \
+	$(top_srcdir)/lib/diff_output.c \
+	$(top_srcdir)/lib/diff_output_plain.c \
+	$(top_srcdir)/lib/diff_output_unidiff.c \
+	$(top_srcdir)/lib/diff_output_edscript.c \
+	$(top_srcdir)/lib/diff_patience.c \
+	$(top_srcdir)/lib/send.c \
+	$(top_srcdir)/lib/deltify.c \
+	$(top_srcdir)/lib/pack_create.c \
+	$(top_srcdir)/lib/dial.c
+
+got_DEPENDENCIES = $(top_builddir)/compat/libopenbsd-compat.a
+
+man1_MANS = got.1
+
+AM_CPPFLAGS += -DGOT_VERSION='"@VERSION@"' \
+	-DGOT_VERSION_NUMBER='"@VERSION@"' \
+	-DGOT_LIBEXEC_DIR="${bindir}" \
+	-I$(top_srcdir) \
+	-I$(top_srcdir)/compat \
+	-I$(top_srcdir)/lib \
+	-I$(top_srcdir)/include \
+	-I.
+
+LDADD = -L$(top_builddir)/compat -lopenbsd-compat
blob - 4765f7e169b5a1009aa5f38fc148e35c702fda31
blob + 34411f6f1015b3063c7652f4227a107f42a77dfa
--- got/got.c
+++ got/got.c
@@ -16,7 +16,6 @@
  * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
  */
 
-#include <sys/queue.h>
 #include <sys/types.h>
 #include <sys/stat.h>
 #include <sys/wait.h>
@@ -37,7 +36,8 @@
 #include <paths.h>
 #include <regex.h>
 #include <getopt.h>
-#include <util.h>
+
+#include "got_compat.h"
 
 #include "got_version.h"
 #include "got_error.h"
blob - /dev/null
blob + bd5690e64116b0d1179fc55295f22a1748a20c18 (mode 644)
--- /dev/null
+++ compat/Makefile.am
@@ -0,0 +1,40 @@
+noinst_LIBRARIES = libopenbsd-compat.a
+
+AM_CPPFLAGS += -DGOT_VERSION='"@VERSION@"' \
+	-DGOT_VERSION_NUMBER='"@VERSION@"' \
+	-DGOT_LIBEXEC_DIR="${bindir}" \
+	-I$(top_srcdir) \
+	-I$(top_srcdir)/compat \
+	-I$(top_srcdir)/lib \
+	-I$(top_srcdir)/include \
+	-I.
+
+libopenbsd_compat_a_SOURCES =  \
+	asprintf.c \
+	base64.c \
+	closefrom.c \
+	fmt_scaled.c \
+	freezero.c \
+	getdtablecount.c \
+	getopt.c \
+	getprogname.c \
+	imsg-buffer.c \
+	imsg.c \
+	merge.c \
+	reallocarray.c \
+	recallocarray.c \
+	strlcat.c \
+	strlcpy.c \
+	strndup.c \
+	strnlen.c \
+	strsep.c \
+	strtonum.c \
+	uuid.c \
+	xmalloc.c
+
+EXTRA_DIST = \
+	$(top_srcdir)/include/got_compat.h \
+	imsg.h \
+	queue.h \
+	tree.h \
+	xmalloc.h
blob - /dev/null
blob + 34194b69d0c46f70a8b0d52de97293a36227c21f (mode 644)
--- /dev/null
+++ compat/asprintf.c
@@ -0,0 +1,64 @@
+/*
+ * Copyright (c) 2006 Nicholas Marriott <nicholas.marriott@gmail.com>
+ *
+ * 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 MIND, 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 <sys/types.h>
+
+#include <err.h>
+#include <stdarg.h>
+#include <stdio.h>
+#include <string.h>
+#include <stdlib.h>
+
+int
+asprintf(char **ret, const char *fmt, ...)
+{
+	va_list	ap;
+	int	n;
+
+	va_start(ap, fmt);
+	n = vasprintf(ret, fmt, ap);
+	va_end(ap);
+
+	return (n);
+}
+
+int
+vasprintf(char **ret, const char *fmt, va_list ap)
+{
+	int	 n;
+	va_list  ap2;
+
+	va_copy(ap2, ap);
+
+	if ((n = vsnprintf(NULL, 0, fmt, ap)) < 0)
+		goto error;
+
+	*ret = malloc(n + 1);
+	if (*ret == NULL)
+		errx(1, "vasprintf: malloc failed");
+	if ((n = vsnprintf(*ret, n + 1, fmt, ap2)) < 0) {
+		free(*ret);
+		goto error;
+	}
+	va_end(ap2);
+
+	return (n);
+
+error:
+	va_end(ap2);
+	*ret = NULL;
+	return (-1);
+}
blob - /dev/null
blob + e90696df6734e087c40036ab7e8b95e68aabe5e7 (mode 644)
--- /dev/null
+++ compat/base64.c
@@ -0,0 +1,315 @@
+/*	$OpenBSD: base64.c,v 1.8 2015/01/16 16:48:51 deraadt Exp $	*/
+
+/*
+ * Copyright (c) 1996 by Internet Software Consortium.
+ *
+ * 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 INTERNET SOFTWARE CONSORTIUM DISCLAIMS
+ * ALL WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL INTERNET SOFTWARE
+ * CONSORTIUM 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.
+ */
+
+/*
+ * Portions Copyright (c) 1995 by International Business Machines, Inc.
+ *
+ * International Business Machines, Inc. (hereinafter called IBM) grants
+ * permission under its copyrights to use, copy, modify, and distribute this
+ * Software with or without fee, provided that the above copyright notice and
+ * all paragraphs of this notice appear in all copies, and that the name of IBM
+ * not be used in connection with the marketing of any product incorporating
+ * the Software or modifications thereof, without specific, written prior
+ * permission.
+ *
+ * To the extent it has a right to do so, IBM grants an immunity from suit
+ * under its patents, if any, for the use, sale or manufacture of products to
+ * the extent that such products are used for performing Domain Name System
+ * dynamic updates in TCP/IP networks by means of the Software.  No immunity is
+ * granted for any product per se or for any other function of any product.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", AND IBM DISCLAIMS ALL WARRANTIES,
+ * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
+ * PARTICULAR PURPOSE.  IN NO EVENT SHALL IBM BE LIABLE FOR ANY SPECIAL,
+ * DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER ARISING
+ * OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE, EVEN
+ * IF IBM IS APPRISED OF THE POSSIBILITY OF SUCH DAMAGES.
+ */
+
+#include <sys/types.h>
+#include <sys/socket.h>
+#include <netinet/in.h>
+#include <arpa/inet.h>
+#include <arpa/nameser.h>
+
+#include <ctype.h>
+#include <resolv.h>
+#include <stdio.h>
+
+#include <stdlib.h>
+#include <string.h>
+
+static const char Base64[] =
+	"ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
+static const char Pad64 = '=';
+
+/* (From RFC1521 and draft-ietf-dnssec-secext-03.txt)
+   The following encoding technique is taken from RFC 1521 by Borenstein
+   and Freed.  It is reproduced here in a slightly edited form for
+   convenience.
+
+   A 65-character subset of US-ASCII is used, enabling 6 bits to be
+   represented per printable character. (The extra 65th character, "=",
+   is used to signify a special processing function.)
+
+   The encoding process represents 24-bit groups of input bits as output
+   strings of 4 encoded characters. Proceeding from left to right, a
+   24-bit input group is formed by concatenating 3 8-bit input groups.
+   These 24 bits are then treated as 4 concatenated 6-bit groups, each
+   of which is translated into a single digit in the base64 alphabet.
+
+   Each 6-bit group is used as an index into an array of 64 printable
+   characters. The character referenced by the index is placed in the
+   output string.
+
+                         Table 1: The Base64 Alphabet
+
+      Value Encoding  Value Encoding  Value Encoding  Value Encoding
+          0 A            17 R            34 i            51 z
+          1 B            18 S            35 j            52 0
+          2 C            19 T            36 k            53 1
+          3 D            20 U            37 l            54 2
+          4 E            21 V            38 m            55 3
+          5 F            22 W            39 n            56 4
+          6 G            23 X            40 o            57 5
+          7 H            24 Y            41 p            58 6
+          8 I            25 Z            42 q            59 7
+          9 J            26 a            43 r            60 8
+         10 K            27 b            44 s            61 9
+         11 L            28 c            45 t            62 +
+         12 M            29 d            46 u            63 /
+         13 N            30 e            47 v
+         14 O            31 f            48 w         (pad) =
+         15 P            32 g            49 x
+         16 Q            33 h            50 y
+
+   Special processing is performed if fewer than 24 bits are available
+   at the end of the data being encoded.  A full encoding quantum is
+   always completed at the end of a quantity.  When fewer than 24 input
+   bits are available in an input group, zero bits are added (on the
+   right) to form an integral number of 6-bit groups.  Padding at the
+   end of the data is performed using the '=' character.
+
+   Since all base64 input is an integral number of octets, only the
+         -------------------------------------------------                       
+   following cases can arise:
+   
+       (1) the final quantum of encoding input is an integral
+           multiple of 24 bits; here, the final unit of encoded
+	   output will be an integral multiple of 4 characters
+	   with no "=" padding,
+       (2) the final quantum of encoding input is exactly 8 bits;
+           here, the final unit of encoded output will be two
+	   characters followed by two "=" padding characters, or
+       (3) the final quantum of encoding input is exactly 16 bits;
+           here, the final unit of encoded output will be three
+	   characters followed by one "=" padding character.
+   */
+
+int
+b64_ntop(src, srclength, target, targsize)
+	u_char const *src;
+	size_t srclength;
+	char *target;
+	size_t targsize;
+{
+	size_t datalength = 0;
+	u_char input[3];
+	u_char output[4];
+	int i;
+
+	while (2 < srclength) {
+		input[0] = *src++;
+		input[1] = *src++;
+		input[2] = *src++;
+		srclength -= 3;
+
+		output[0] = input[0] >> 2;
+		output[1] = ((input[0] & 0x03) << 4) + (input[1] >> 4);
+		output[2] = ((input[1] & 0x0f) << 2) + (input[2] >> 6);
+		output[3] = input[2] & 0x3f;
+
+		if (datalength + 4 > targsize)
+			return (-1);
+		target[datalength++] = Base64[output[0]];
+		target[datalength++] = Base64[output[1]];
+		target[datalength++] = Base64[output[2]];
+		target[datalength++] = Base64[output[3]];
+	}
+    
+	/* Now we worry about padding. */
+	if (0 != srclength) {
+		/* Get what's left. */
+		input[0] = input[1] = input[2] = '\0';
+		for (i = 0; i < srclength; i++)
+			input[i] = *src++;
+	
+		output[0] = input[0] >> 2;
+		output[1] = ((input[0] & 0x03) << 4) + (input[1] >> 4);
+		output[2] = ((input[1] & 0x0f) << 2) + (input[2] >> 6);
+
+		if (datalength + 4 > targsize)
+			return (-1);
+		target[datalength++] = Base64[output[0]];
+		target[datalength++] = Base64[output[1]];
+		if (srclength == 1)
+			target[datalength++] = Pad64;
+		else
+			target[datalength++] = Base64[output[2]];
+		target[datalength++] = Pad64;
+	}
+	if (datalength >= targsize)
+		return (-1);
+	target[datalength] = '\0';	/* Returned value doesn't count \0. */
+	return (datalength);
+}
+
+/* skips all whitespace anywhere.
+   converts characters, four at a time, starting at (or after)
+   src from base - 64 numbers into three 8 bit bytes in the target area.
+   it returns the number of data bytes stored at the target, or -1 on error.
+ */
+
+int
+b64_pton(src, target, targsize)
+	char const *src;
+	u_char *target;
+	size_t targsize;
+{
+	int tarindex, state, ch;
+	u_char nextbyte;
+	char *pos;
+
+	state = 0;
+	tarindex = 0;
+
+	while ((ch = (unsigned char)*src++) != '\0') {
+		if (isspace(ch))	/* Skip whitespace anywhere. */
+			continue;
+
+		if (ch == Pad64)
+			break;
+
+		pos = strchr(Base64, ch);
+		if (pos == 0) 		/* A non-base64 character. */
+			return (-1);
+
+		switch (state) {
+		case 0:
+			if (target) {
+				if (tarindex >= targsize)
+					return (-1);
+				target[tarindex] = (pos - Base64) << 2;
+			}
+			state = 1;
+			break;
+		case 1:
+			if (target) {
+				if (tarindex >= targsize)
+					return (-1);
+				target[tarindex]   |=  (pos - Base64) >> 4;
+				nextbyte = ((pos - Base64) & 0x0f) << 4;
+				if (tarindex + 1 < targsize)
+					target[tarindex+1] = nextbyte;
+				else if (nextbyte)
+					return (-1);
+			}
+			tarindex++;
+			state = 2;
+			break;
+		case 2:
+			if (target) {
+				if (tarindex >= targsize)
+					return (-1);
+				target[tarindex]   |=  (pos - Base64) >> 2;
+				nextbyte = ((pos - Base64) & 0x03) << 6;
+				if (tarindex + 1 < targsize)
+					target[tarindex+1] = nextbyte;
+				else if (nextbyte)
+					return (-1);
+			}
+			tarindex++;
+			state = 3;
+			break;
+		case 3:
+			if (target) {
+				if (tarindex >= targsize)
+					return (-1);
+				target[tarindex] |= (pos - Base64);
+			}
+			tarindex++;
+			state = 0;
+			break;
+		}
+	}
+
+	/*
+	 * We are done decoding Base-64 chars.  Let's see if we ended
+	 * on a byte boundary, and/or with erroneous trailing characters.
+	 */
+
+	if (ch == Pad64) {			/* We got a pad char. */
+		ch = (unsigned char)*src++;	/* Skip it, get next. */
+		switch (state) {
+		case 0:		/* Invalid = in first position */
+		case 1:		/* Invalid = in second position */
+			return (-1);
+
+		case 2:		/* Valid, means one byte of info */
+			/* Skip any number of spaces. */
+			for (; ch != '\0'; ch = (unsigned char)*src++)
+				if (!isspace(ch))
+					break;
+			/* Make sure there is another trailing = sign. */
+			if (ch != Pad64)
+				return (-1);
+			ch = (unsigned char)*src++;		/* Skip the = */
+			/* Fall through to "single trailing =" case. */
+			/* FALLTHROUGH */
+
+		case 3:		/* Valid, means two bytes of info */
+			/*
+			 * We know this char is an =.  Is there anything but
+			 * whitespace after it?
+			 */
+			for (; ch != '\0'; ch = (unsigned char)*src++)
+				if (!isspace(ch))
+					return (-1);
+
+			/*
+			 * Now make sure for cases 2 and 3 that the "extra"
+			 * bits that slopped past the last full byte were
+			 * zeros.  If we don't check them, they become a
+			 * subliminal channel.
+			 */
+			if (target && tarindex < targsize &&
+			    target[tarindex] != 0)
+				return (-1);
+		}
+	} else {
+		/*
+		 * We ended by seeing the end of the string.  Make sure we
+		 * have no partial bytes lying around.
+		 */
+		if (state != 0)
+			return (-1);
+	}
+
+	return (tarindex);
+}
blob - /dev/null
blob + e024679deee4fc0821648c0095946edd4c4ab55e (mode 644)
--- /dev/null
+++ compat/closefrom.c
@@ -0,0 +1,107 @@
+/*
+ * Copyright (c) 2004-2005 Todd C. Miller <Todd.Miller@courtesan.com>
+ *
+ * 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.
+ */
+
+#ifndef HAVE_CLOSEFROM
+
+#include <sys/types.h>
+#include <sys/param.h>
+#include <unistd.h>
+#include <stdio.h>
+#ifdef HAVE_FCNTL_H
+# include <fcntl.h>
+#endif
+#include <limits.h>
+#include <stdlib.h>
+#include <stddef.h>
+#include <string.h>
+#include <unistd.h>
+#ifdef HAVE_DIRENT_H
+# include <dirent.h>
+# define NAMLEN(dirent) strlen((dirent)->d_name)
+#else
+# define dirent direct
+# define NAMLEN(dirent) (dirent)->d_namlen
+# ifdef HAVE_SYS_NDIR_H
+#  include <sys/ndir.h>
+# endif
+# ifdef HAVE_SYS_DIR_H
+#  include <sys/dir.h>
+# endif
+# ifdef HAVE_NDIR_H
+#  include <ndir.h>
+# endif
+#endif
+
+#ifndef OPEN_MAX
+# define OPEN_MAX	256
+#endif
+
+#if 0
+__unused static const char rcsid[] = "$Sudo: closefrom.c,v 1.11 2006/08/17 15:26:54 millert Exp $";
+#endif /* lint */
+
+/*
+ * Close all file descriptors greater than or equal to lowfd.
+ */
+#ifdef HAVE_FCNTL_CLOSEM
+void
+closefrom(int lowfd)
+{
+    (void) fcntl(lowfd, F_CLOSEM, 0);
+}
+#else
+void
+closefrom(int lowfd)
+{
+    long fd, maxfd;
+#if defined(HAVE_DIRFD) && defined(HAVE_PROC_PID)
+    char fdpath[PATH_MAX], *endp;
+    struct dirent *dent;
+    DIR *dirp;
+    int len;
+
+    /* Check for a /proc/$$/fd directory. */
+    len = snprintf(fdpath, sizeof(fdpath), "/proc/%ld/fd", (long)getpid());
+    if (len > 0 && (size_t)len <= sizeof(fdpath) && (dirp = opendir(fdpath))) {
+	while ((dent = readdir(dirp)) != NULL) {
+	    fd = strtol(dent->d_name, &endp, 10);
+	    if (dent->d_name != endp && *endp == '\0' &&
+		fd >= 0 && fd < INT_MAX && fd >= lowfd && fd != dirfd(dirp))
+		(void) close((int) fd);
+	}
+	(void) closedir(dirp);
+    } else
+#endif
+    {
+	/*
+	 * Fall back on sysconf() or getdtablesize().  We avoid checking
+	 * resource limits since it is possible to open a file descriptor
+	 * and then drop the rlimit such that it is below the open fd.
+	 */
+#ifdef HAVE_SYSCONF
+	maxfd = sysconf(_SC_OPEN_MAX);
+#else
+	maxfd = getdtablesize();
+#endif /* HAVE_SYSCONF */
+	if (maxfd < 0)
+	    maxfd = OPEN_MAX;
+
+	for (fd = lowfd; fd < maxfd; fd++)
+	    (void) close((int) fd);
+    }
+}
+#endif /* !HAVE_FCNTL_CLOSEM */
+#endif /* HAVE_CLOSEFROM */
blob - /dev/null
blob + e57caa8db22ae5173cdd8d48ea4380a6755e83d5 (mode 644)
--- /dev/null
+++ compat/fmt_scaled.c
@@ -0,0 +1,241 @@
+/*
+ * Copyright (c) 2001, 2002, 2003 Ian F. Darwin.  All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ * 3. The name of the author may not be used to endorse or promote products
+ *    derived from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+ * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+/*
+ * fmt_scaled: Format numbers scaled for human comprehension
+ * scan_scaled: Scan numbers in this format.
+ *
+ * "Human-readable" output uses 4 digits max, and puts a unit suffix at
+ * the end.  Makes output compact and easy-to-read esp. on huge disks.
+ * Formatting code was originally in OpenBSD "df", converted to library routine.
+ * Scanning code written for OpenBSD libutil.
+ */
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <errno.h>
+#include <string.h>
+#include <ctype.h>
+#include <limits.h>
+
+#include "got_compat.h"
+
+typedef enum {
+	NONE = 0, KILO = 1, MEGA = 2, GIGA = 3, TERA = 4, PETA = 5, EXA = 6
+} unit_type;
+
+/* These three arrays MUST be in sync!  XXX make a struct */
+static unit_type units[] = { NONE, KILO, MEGA, GIGA, TERA, PETA, EXA };
+static char scale_chars[] = "BKMGTPE";
+static long long scale_factors[] = {
+	1LL,
+	1024LL,
+	1024LL*1024,
+	1024LL*1024*1024,
+	1024LL*1024*1024*1024,
+	1024LL*1024*1024*1024*1024,
+	1024LL*1024*1024*1024*1024*1024,
+};
+#define	SCALE_LENGTH (sizeof(units)/sizeof(units[0]))
+
+#define MAX_DIGITS (SCALE_LENGTH * 3)	/* XXX strlen(sprintf("%lld", -1)? */
+
+/* Convert the given input string "scaled" into numeric in "result".
+ * Return 0 on success, -1 and errno set on error.
+ */
+int
+scan_scaled(char *scaled, long long *result)
+{
+	char *p = scaled;
+	int sign = 0;
+	unsigned int i, ndigits = 0, fract_digits = 0;
+	long long scale_fact = 1, whole = 0, fpart = 0;
+
+	/* Skip leading whitespace */
+	while (isascii(*p) && isspace(*p))
+		++p;
+
+	/* Then at most one leading + or - */
+	while (*p == '-' || *p == '+') {
+		if (*p == '-') {
+			if (sign) {
+				errno = EINVAL;
+				return -1;
+			}
+			sign = -1;
+			++p;
+		} else if (*p == '+') {
+			if (sign) {
+				errno = EINVAL;
+				return -1;
+			}
+			sign = +1;
+			++p;
+		}
+	}
+
+	/* Main loop: Scan digits, find decimal point, if present.
+	 * We don't allow exponentials, so no scientific notation
+	 * (but note that E for Exa might look like e to some!).
+	 * Advance 'p' to end, to get scale factor.
+	 */
+	for (; isascii(*p) && (isdigit(*p) || *p=='.'); ++p) {
+		if (*p == '.') {
+			if (fract_digits > 0) {	/* oops, more than one '.' */
+				errno = EINVAL;
+				return -1;
+			}
+			fract_digits = 1;
+			continue;
+		}
+
+		i = (*p) - '0';			/* whew! finally a digit we can use */
+		if (fract_digits > 0) {
+			if (fract_digits >= MAX_DIGITS-1)
+				/* ignore extra fractional digits */
+				continue;
+			fract_digits++;		/* for later scaling */
+			fpart *= 10;
+			fpart += i;
+		} else {				/* normal digit */
+			if (++ndigits >= MAX_DIGITS) {
+				errno = ERANGE;
+				return -1;
+			}
+			whole *= 10;
+			whole += i;
+		}
+	}
+
+	if (sign) {
+		whole *= sign;
+		fpart *= sign;
+	}
+
+	/* If no scale factor given, we're done. fraction is discarded. */
+	if (!*p) {
+		*result = whole;
+		return 0;
+	}
+
+	/* Validate scale factor, and scale whole and fraction by it. */
+	for (i = 0; i < SCALE_LENGTH; i++) {
+
+		/* Are we there yet? */
+		if (*p == scale_chars[i] ||
+			*p == tolower(scale_chars[i])) {
+
+			/* If it ends with alphanumerics after the scale char, bad. */
+			if (isalnum(*(p+1))) {
+				errno = EINVAL;
+				return -1;
+			}
+			scale_fact = scale_factors[i];
+
+			/* scale whole part */
+			whole *= scale_fact;
+
+			/* truncate fpart so it does't overflow.
+			 * then scale fractional part.
+			 */
+			while (fpart >= LLONG_MAX / scale_fact) {
+				fpart /= 10;
+				fract_digits--;
+			}
+			fpart *= scale_fact;
+			if (fract_digits > 0) {
+				for (i = 0; i < fract_digits -1; i++)
+					fpart /= 10;
+			}
+			whole += fpart;
+			*result = whole;
+			return 0;
+		}
+	}
+	errno = ERANGE;
+	return -1;
+}
+
+/* Format the given "number" into human-readable form in "result".
+ * Result must point to an allocated buffer of length FMT_SCALED_STRSIZE.
+ * Return 0 on success, -1 and errno set if error.
+ */
+int
+fmt_scaled(long long number, char *result)
+{
+	long long abval, fract = 0;
+	unsigned int i;
+	unit_type unit = NONE;
+
+	abval = llabs(number);
+
+	/* Not every negative long long has a positive representation.
+	 * Also check for numbers that are just too darned big to format
+	 */
+	if (abval < 0 || abval / 1024 >= scale_factors[SCALE_LENGTH-1]) {
+		errno = ERANGE;
+		return -1;
+	}
+
+	/* scale whole part; get unscaled fraction */
+	for (i = 0; i < SCALE_LENGTH; i++) {
+		if (abval/1024 < scale_factors[i]) {
+			unit = units[i];
+			fract = (i == 0) ? 0 : abval % scale_factors[i];
+			number /= scale_factors[i];
+			if (i > 0)
+				fract /= scale_factors[i - 1];
+			break;
+		}
+	}
+
+	fract = (10 * fract + 512) / 1024;
+	/* if the result would be >= 10, round main number */
+	if (fract == 10) {
+		if (number >= 0)
+			number++;
+		else
+			number--;
+		fract = 0;
+	}
+
+	if (number == 0)
+		strlcpy(result, "0B", FMT_SCALED_STRSIZE);
+	else if (unit == NONE || number >= 100 || number <= -100) {
+		if (fract >= 5) {
+			if (number >= 0)
+				number++;
+			else
+				number--;
+		}
+		(void)snprintf(result, FMT_SCALED_STRSIZE, "%lld%c",
+			number, scale_chars[unit]);
+	} else
+		(void)snprintf(result, FMT_SCALED_STRSIZE, "%lld.%1lld%c",
+			number, fract, scale_chars[unit]);
+
+	return 0;
+}
blob - /dev/null
blob + cda032f843afb37af44708f986f44df483720d62 (mode 644)
--- /dev/null
+++ compat/freezero.c
@@ -0,0 +1,29 @@
+/*
+ * Copyright (c) 2017 Nicholas Marriott <nicholas.marriott@gmail.com>
+ *
+ * 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 MIND, 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 <sys/types.h>
+
+#include <stdlib.h>
+#include <string.h>
+
+void
+freezero(void *ptr, size_t size)
+{
+	if (ptr != NULL) {
+		memset(ptr, 0, size);
+		free(ptr);
+	}
+}
blob - /dev/null
blob + 57c76d897057d97623c0046415f2a5caa7f62e53 (mode 644)
--- /dev/null
+++ compat/getdtablecount.c
@@ -0,0 +1,48 @@
+/*
+ * Copyright (c) 2017 Nicholas Marriott <nicholas.marriott@gmail.com>
+ *
+ * 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 MIND, 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 <sys/types.h>
+
+#include <glob.h>
+#include <unistd.h>
+
+void fatal(const char *, ...);
+void fatalx(const char *, ...);
+
+#ifdef HAVE_PROC_PID
+int
+getdtablecount(void)
+{
+	char	path[PATH_MAX];
+	glob_t	g;
+	int	n = 0;
+
+	if (snprintf(path, sizeof path, "/proc/%ld/fd/*", (long)getpid()) < 0) {
+		fprintf(stderr, "snprintf overflow");
+		exit (1);
+	}
+	if (glob(path, 0, NULL, &g) == 0)
+		n = g.gl_pathc;
+	globfree(&g);
+	return (n);
+}
+#else
+int
+getdtablecount(void)
+{
+	return (0);
+}
+#endif
blob - /dev/null
blob + 8fb5fec63f8b4d8c0162285ace7b93a93e74c436 (mode 644)
--- /dev/null
+++ compat/getopt.c
@@ -0,0 +1,115 @@
+/*
+ * Copyright (c) 1987, 1993, 1994
+ *	The Regents of the University of California.  All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ * 3. Neither the name of the University nor the names of its contributors
+ *    may be used to endorse or promote products derived from this software
+ *    without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+/* OPENBSD ORIGINAL: lib/libc/stdlib/getopt.c */
+
+#include "got_compat.h"
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+
+int	BSDopterr = 1,		/* if error message should be printed */
+	BSDoptind = 1,		/* index into parent argv vector */
+	BSDoptopt,		/* character checked for validity */
+	BSDoptreset;		/* reset getopt */
+char	*BSDoptarg;		/* argument associated with option */
+
+#define	BADCH	(int)'?'
+#define	BADARG	(int)':'
+#define	EMSG	""
+
+/*
+ * getopt --
+ *	Parse argc/argv argument vector.
+ */
+int
+BSDgetopt(int nargc, char *const *nargv, const char *ostr)
+{
+	static const char *place = EMSG;	/* option letter processing */
+	char *oli;				/* option letter list index */
+
+	if (ostr == NULL)
+		return (-1);
+
+	if (BSDoptreset || !*place) {		/* update scanning pointer */
+		BSDoptreset = 0;
+		if (BSDoptind >= nargc || *(place = nargv[BSDoptind]) != '-') {
+			place = EMSG;
+			return (-1);
+		}
+		if (place[1] && *++place == '-') {	/* found "--" */
+			if (place[1])
+				return (BADCH);
+			++BSDoptind;
+			place = EMSG;
+			return (-1);
+		}
+	}					/* option letter okay? */
+	if ((BSDoptopt = (int)*place++) == (int)':' ||
+	    !(oli = strchr(ostr, BSDoptopt))) {
+		/*
+		 * if the user didn't specify '-' as an option,
+		 * assume it means -1.
+		 */
+		if (BSDoptopt == (int)'-')
+			return (-1);
+		if (!*place)
+			++BSDoptind;
+		if (BSDopterr && *ostr != ':')
+			(void)fprintf(stderr,
+			    "%s: unknown option -- %c\n", getprogname(),
+			    BSDoptopt);
+		return (BADCH);
+	}
+	if (*++oli != ':') {			/* don't need argument */
+		BSDoptarg = NULL;
+		if (!*place)
+			++BSDoptind;
+	}
+	else {					/* need an argument */
+		if (*place)			/* no white space */
+			BSDoptarg = (char *)place;
+		else if (nargc <= ++BSDoptind) {	/* no arg */
+			place = EMSG;
+			if (*ostr == ':')
+				return (BADARG);
+			if (BSDopterr)
+				(void)fprintf(stderr,
+				    "%s: option requires an argument -- %c\n",
+				    getprogname(), BSDoptopt);
+			return (BADCH);
+		}
+		else				/* white space */
+			BSDoptarg = nargv[BSDoptind];
+		place = EMSG;
+		++BSDoptind;
+	}
+	return (BSDoptopt);			/* dump back option letter */
+}
blob - /dev/null
blob + 1dc2f493577b073fa65b7544928ff6ff61c1c2e6 (mode 644)
--- /dev/null
+++ compat/getprogname.c
@@ -0,0 +1,41 @@
+/*
+ * Copyright (c) 2016 Nicholas Marriott <nicholas.marriott@gmail.com>
+ *
+ * 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 MIND, 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 <sys/types.h>
+
+#include <errno.h>
+
+#if defined(HAVE_PROGRAM_INVOCATION_SHORT_NAME)
+const char *
+getprogname(void)
+{
+	return (program_invocation_short_name);
+}
+#elif defined(HAVE___PROGNAME)
+const char *
+getprogname(void)
+{
+	extern char	*__progname;
+
+	return (__progname);
+}
+#else
+const char *
+getprogname(void)
+{
+	return ("got");
+}
+#endif
blob - /dev/null
blob + 37a41157a351f7ae2bd273a91c7e879e2391bccc (mode 644)
--- /dev/null
+++ compat/imsg-buffer.c
@@ -0,0 +1,309 @@
+/*	$OpenBSD: imsg-buffer.c,v 1.11 2017/12/14 09:27:44 kettenis Exp $	*/
+
+/*
+ * Copyright (c) 2003, 2004 Henning Brauer <henning@openbsd.org>
+ *
+ * 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 <sys/types.h>
+#include <sys/socket.h>
+#include <sys/uio.h>
+
+#include <limits.h>
+#include <errno.h>
+#include <stdlib.h>
+#include <string.h>
+#include <unistd.h>
+
+#include "got_compat.h"
+#include "xmalloc.h"
+
+static int	ibuf_realloc(struct ibuf *, size_t);
+static void	ibuf_enqueue(struct msgbuf *, struct ibuf *);
+static void	ibuf_dequeue(struct msgbuf *, struct ibuf *);
+
+struct ibuf *
+ibuf_open(size_t len)
+{
+	struct ibuf	*buf;
+
+	if ((buf = calloc(1, sizeof(struct ibuf))) == NULL)
+		return (NULL);
+	if ((buf->buf = malloc(len)) == NULL) {
+		free(buf);
+		return (NULL);
+	}
+	buf->size = buf->max = len;
+	buf->fd = -1;
+
+	return (buf);
+}
+
+struct ibuf *
+ibuf_dynamic(size_t len, size_t max)
+{
+	struct ibuf	*buf;
+
+	if (max < len)
+		return (NULL);
+
+	if ((buf = ibuf_open(len)) == NULL)
+		return (NULL);
+
+	if (max > 0)
+		buf->max = max;
+
+	return (buf);
+}
+
+static int
+ibuf_realloc(struct ibuf *buf, size_t len)
+{
+	u_char	*b;
+
+	/* on static buffers max is eq size and so the following fails */
+	if (buf->wpos + len > buf->max) {
+		errno = ERANGE;
+		return (-1);
+	}
+
+	b = xrecallocarray(buf->buf, buf->size, buf->wpos + len, 1);
+	if (b == NULL)
+		return (-1);
+	buf->buf = b;
+	buf->size = buf->wpos + len;
+
+	return (0);
+}
+
+int
+ibuf_add(struct ibuf *buf, const void *data, size_t len)
+{
+	if (buf->wpos + len > buf->size)
+		if (ibuf_realloc(buf, len) == -1)
+			return (-1);
+
+	memcpy(buf->buf + buf->wpos, data, len);
+	buf->wpos += len;
+	return (0);
+}
+
+void *
+ibuf_reserve(struct ibuf *buf, size_t len)
+{
+	void	*b;
+
+	if (buf->wpos + len > buf->size)
+		if (ibuf_realloc(buf, len) == -1)
+			return (NULL);
+
+	b = buf->buf + buf->wpos;
+	buf->wpos += len;
+	return (b);
+}
+
+void *
+ibuf_seek(struct ibuf *buf, size_t pos, size_t len)
+{
+	/* only allowed to seek in already written parts */
+	if (pos + len > buf->wpos)
+		return (NULL);
+
+	return (buf->buf + pos);
+}
+
+size_t
+ibuf_size(struct ibuf *buf)
+{
+	return (buf->wpos);
+}
+
+size_t
+ibuf_left(struct ibuf *buf)
+{
+	return (buf->max - buf->wpos);
+}
+
+void
+ibuf_close(struct msgbuf *msgbuf, struct ibuf *buf)
+{
+	ibuf_enqueue(msgbuf, buf);
+}
+
+int
+ibuf_write(struct msgbuf *msgbuf)
+{
+	struct iovec	 iov[IOV_MAX];
+	struct ibuf	*buf;
+	unsigned int	 i = 0;
+	ssize_t	n;
+
+	memset(&iov, 0, sizeof(iov));
+	TAILQ_FOREACH(buf, &msgbuf->bufs, entry) {
+		if (i >= IOV_MAX)
+			break;
+		iov[i].iov_base = buf->buf + buf->rpos;
+		iov[i].iov_len = buf->wpos - buf->rpos;
+		i++;
+	}
+
+again:
+	if ((n = writev(msgbuf->fd, iov, i)) == -1) {
+		if (errno == EINTR)
+			goto again;
+		if (errno == ENOBUFS)
+			errno = EAGAIN;
+		return (-1);
+	}
+
+	if (n == 0) {			/* connection closed */
+		errno = 0;
+		return (0);
+	}
+
+	msgbuf_drain(msgbuf, n);
+
+	return (1);
+}
+
+void
+ibuf_free(struct ibuf *buf)
+{
+	if (buf == NULL)
+		return;
+	freezero(buf->buf, buf->size);
+	free(buf);
+}
+
+void
+msgbuf_init(struct msgbuf *msgbuf)
+{
+	msgbuf->queued = 0;
+	msgbuf->fd = -1;
+	TAILQ_INIT(&msgbuf->bufs);
+}
+
+void
+msgbuf_drain(struct msgbuf *msgbuf, size_t n)
+{
+	struct ibuf	*buf, *next;
+
+	for (buf = TAILQ_FIRST(&msgbuf->bufs); buf != NULL && n > 0;
+	    buf = next) {
+		next = TAILQ_NEXT(buf, entry);
+		if (buf->rpos + n >= buf->wpos) {
+			n -= buf->wpos - buf->rpos;
+			ibuf_dequeue(msgbuf, buf);
+		} else {
+			buf->rpos += n;
+			n = 0;
+		}
+	}
+}
+
+void
+msgbuf_clear(struct msgbuf *msgbuf)
+{
+	struct ibuf	*buf;
+
+	while ((buf = TAILQ_FIRST(&msgbuf->bufs)) != NULL)
+		ibuf_dequeue(msgbuf, buf);
+}
+
+int
+msgbuf_write(struct msgbuf *msgbuf)
+{
+	struct iovec	 iov[IOV_MAX];
+	struct ibuf	*buf;
+	unsigned int	 i = 0;
+	ssize_t		 n;
+	struct msghdr	 msg;
+	struct cmsghdr	*cmsg;
+	union {
+		struct cmsghdr	hdr;
+		char		buf[CMSG_SPACE(sizeof(int))];
+	} cmsgbuf;
+
+	memset(&iov, 0, sizeof(iov));
+	memset(&msg, 0, sizeof(msg));
+	memset(&cmsgbuf, 0, sizeof(cmsgbuf));
+	TAILQ_FOREACH(buf, &msgbuf->bufs, entry) {
+		if (i >= IOV_MAX)
+			break;
+		iov[i].iov_base = buf->buf + buf->rpos;
+		iov[i].iov_len = buf->wpos - buf->rpos;
+		i++;
+		if (buf->fd != -1)
+			break;
+	}
+
+	msg.msg_iov = iov;
+	msg.msg_iovlen = i;
+
+	if (buf != NULL && buf->fd != -1) {
+		msg.msg_control = (caddr_t)&cmsgbuf.buf;
+		msg.msg_controllen = sizeof(cmsgbuf.buf);
+		cmsg = CMSG_FIRSTHDR(&msg);
+		cmsg->cmsg_len = CMSG_LEN(sizeof(int));
+		cmsg->cmsg_level = SOL_SOCKET;
+		cmsg->cmsg_type = SCM_RIGHTS;
+		*(int *)CMSG_DATA(cmsg) = buf->fd;
+	}
+
+again:
+	if ((n = sendmsg(msgbuf->fd, &msg, 0)) == -1) {
+		if (errno == EINTR)
+			goto again;
+		if (errno == ENOBUFS)
+			errno = EAGAIN;
+		return (-1);
+	}
+
+	if (n == 0) {			/* connection closed */
+		errno = 0;
+		return (0);
+	}
+
+	/*
+	 * assumption: fd got sent if sendmsg sent anything
+	 * this works because fds are passed one at a time
+	 */
+	if (buf != NULL && buf->fd != -1) {
+		close(buf->fd);
+		buf->fd = -1;
+	}
+
+	msgbuf_drain(msgbuf, n);
+
+	return (1);
+}
+
+static void
+ibuf_enqueue(struct msgbuf *msgbuf, struct ibuf *buf)
+{
+	TAILQ_INSERT_TAIL(&msgbuf->bufs, buf, entry);
+	msgbuf->queued++;
+}
+
+static void
+ibuf_dequeue(struct msgbuf *msgbuf, struct ibuf *buf)
+{
+	TAILQ_REMOVE(&msgbuf->bufs, buf, entry);
+
+	if (buf->fd != -1)
+		close(buf->fd);
+
+	msgbuf->queued--;
+	ibuf_free(buf);
+}
blob - /dev/null
blob + d76f4872c286711fa86a454e4b465ae4ceb051a0 (mode 644)
--- /dev/null
+++ compat/imsg.c
@@ -0,0 +1,302 @@
+/*	$OpenBSD: imsg.c,v 1.16 2017/12/14 09:27:44 kettenis Exp $	*/
+
+/*
+ * Copyright (c) 2003, 2004 Henning Brauer <henning@openbsd.org>
+ *
+ * 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 <sys/types.h>
+#include <sys/socket.h>
+#include <sys/uio.h>
+
+#include <errno.h>
+#include <stdlib.h>
+#include <string.h>
+#include <unistd.h>
+
+#include "got_compat.h"
+#include "imsg.h"
+
+int	 imsg_fd_overhead = 0;
+
+static int	 imsg_get_fd(struct imsgbuf *);
+
+void
+imsg_init(struct imsgbuf *ibuf, int fd)
+{
+	msgbuf_init(&ibuf->w);
+	memset(&ibuf->r, 0, sizeof(ibuf->r));
+	ibuf->fd = fd;
+	ibuf->w.fd = fd;
+	ibuf->pid = getpid();
+	TAILQ_INIT(&ibuf->fds);
+}
+
+ssize_t
+imsg_read(struct imsgbuf *ibuf)
+{
+	struct msghdr		 msg;
+	struct cmsghdr		*cmsg;
+	union {
+		struct cmsghdr hdr;
+		char	buf[CMSG_SPACE(sizeof(int) * 1)];
+	} cmsgbuf;
+	struct iovec		 iov;
+	ssize_t			 n = -1;
+	int			 fd;
+	struct imsg_fd		*ifd;
+
+	memset(&msg, 0, sizeof(msg));
+	memset(&cmsgbuf, 0, sizeof(cmsgbuf));
+
+	iov.iov_base = ibuf->r.buf + ibuf->r.wpos;
+	iov.iov_len = sizeof(ibuf->r.buf) - ibuf->r.wpos;
+	msg.msg_iov = &iov;
+	msg.msg_iovlen = 1;
+	msg.msg_control = &cmsgbuf.buf;
+	msg.msg_controllen = sizeof(cmsgbuf.buf);
+
+	if ((ifd = calloc(1, sizeof(struct imsg_fd))) == NULL)
+		return (-1);
+
+again:
+	if (getdtablecount() + imsg_fd_overhead +
+	    (int)((CMSG_SPACE(sizeof(int))-CMSG_SPACE(0))/sizeof(int))
+	    >= getdtablesize()) {
+		errno = EAGAIN;
+		free(ifd);
+		return (-1);
+	}
+
+	if ((n = recvmsg(ibuf->fd, &msg, 0)) == -1) {
+		if (errno == EINTR)
+			goto again;
+		goto fail;
+	}
+
+	ibuf->r.wpos += n;
+
+	for (cmsg = CMSG_FIRSTHDR(&msg); cmsg != NULL;
+	    cmsg = CMSG_NXTHDR(&msg, cmsg)) {
+		if (cmsg->cmsg_level == SOL_SOCKET &&
+		    cmsg->cmsg_type == SCM_RIGHTS) {
+			int i;
+			int j;
+
+			/*
+			 * We only accept one file descriptor.  Due to C
+			 * padding rules, our control buffer might contain
+			 * more than one fd, and we must close them.
+			 */
+			j = ((char *)cmsg + cmsg->cmsg_len -
+			    (char *)CMSG_DATA(cmsg)) / sizeof(int);
+			for (i = 0; i < j; i++) {
+				fd = ((int *)CMSG_DATA(cmsg))[i];
+				if (ifd != NULL) {
+					ifd->fd = fd;
+					TAILQ_INSERT_TAIL(&ibuf->fds, ifd,
+					    entry);
+					ifd = NULL;
+				} else
+					close(fd);
+			}
+		}
+		/* we do not handle other ctl data level */
+	}
+
+fail:
+	free(ifd);
+	return (n);
+}
+
+ssize_t
+imsg_get(struct imsgbuf *ibuf, struct imsg *imsg)
+{
+	size_t			 av, left, datalen;
+
+	av = ibuf->r.wpos;
+
+	if (IMSG_HEADER_SIZE > av)
+		return (0);
+
+	memcpy(&imsg->hdr, ibuf->r.buf, sizeof(imsg->hdr));
+	if (imsg->hdr.len < IMSG_HEADER_SIZE ||
+	    imsg->hdr.len > MAX_IMSGSIZE) {
+		errno = ERANGE;
+		return (-1);
+	}
+	if (imsg->hdr.len > av)
+		return (0);
+	datalen = imsg->hdr.len - IMSG_HEADER_SIZE;
+	ibuf->r.rptr = ibuf->r.buf + IMSG_HEADER_SIZE;
+	if (datalen == 0)
+		imsg->data = NULL;
+	else if ((imsg->data = malloc(datalen)) == NULL)
+		return (-1);
+
+	if (imsg->hdr.flags & IMSGF_HASFD)
+		imsg->fd = imsg_get_fd(ibuf);
+	else
+		imsg->fd = -1;
+
+	memcpy(imsg->data, ibuf->r.rptr, datalen);
+
+	if (imsg->hdr.len < av) {
+		left = av - imsg->hdr.len;
+		memmove(&ibuf->r.buf, ibuf->r.buf + imsg->hdr.len, left);
+		ibuf->r.wpos = left;
+	} else
+		ibuf->r.wpos = 0;
+
+	return (datalen + IMSG_HEADER_SIZE);
+}
+
+int
+imsg_compose(struct imsgbuf *ibuf, uint32_t type, uint32_t peerid, pid_t pid,
+    int fd, const void *data, uint16_t datalen)
+{
+	struct ibuf	*wbuf;
+
+	if ((wbuf = imsg_create(ibuf, type, peerid, pid, datalen)) == NULL)
+		return (-1);
+
+	if (imsg_add(wbuf, data, datalen) == -1)
+		return (-1);
+
+	wbuf->fd = fd;
+
+	imsg_close(ibuf, wbuf);
+
+	return (1);
+}
+
+int
+imsg_composev(struct imsgbuf *ibuf, uint32_t type, uint32_t peerid, pid_t pid,
+    int fd, const struct iovec *iov, int iovcnt)
+{
+	struct ibuf	*wbuf;
+	int		 i, datalen = 0;
+
+	for (i = 0; i < iovcnt; i++)
+		datalen += iov[i].iov_len;
+
+	if ((wbuf = imsg_create(ibuf, type, peerid, pid, datalen)) == NULL)
+		return (-1);
+
+	for (i = 0; i < iovcnt; i++)
+		if (imsg_add(wbuf, iov[i].iov_base, iov[i].iov_len) == -1)
+			return (-1);
+
+	wbuf->fd = fd;
+
+	imsg_close(ibuf, wbuf);
+
+	return (1);
+}
+
+/* ARGSUSED */
+struct ibuf *
+imsg_create(struct imsgbuf *ibuf, uint32_t type, uint32_t peerid, pid_t pid,
+    uint16_t datalen)
+{
+	struct ibuf	*wbuf;
+	struct imsg_hdr	 hdr;
+
+	datalen += IMSG_HEADER_SIZE;
+	if (datalen > MAX_IMSGSIZE) {
+		errno = ERANGE;
+		return (NULL);
+	}
+
+	hdr.type = type;
+	hdr.flags = 0;
+	hdr.peerid = peerid;
+	if ((hdr.pid = pid) == 0)
+		hdr.pid = ibuf->pid;
+	if ((wbuf = ibuf_dynamic(datalen, MAX_IMSGSIZE)) == NULL) {
+		return (NULL);
+	}
+	if (imsg_add(wbuf, &hdr, sizeof(hdr)) == -1)
+		return (NULL);
+
+	return (wbuf);
+}
+
+int
+imsg_add(struct ibuf *msg, const void *data, uint16_t datalen)
+{
+	if (datalen)
+		if (ibuf_add(msg, data, datalen) == -1) {
+			ibuf_free(msg);
+			return (-1);
+		}
+	return (datalen);
+}
+
+void
+imsg_close(struct imsgbuf *ibuf, struct ibuf *msg)
+{
+	struct imsg_hdr	*hdr;
+
+	hdr = (struct imsg_hdr *)msg->buf;
+
+	hdr->flags &= ~IMSGF_HASFD;
+	if (msg->fd != -1)
+		hdr->flags |= IMSGF_HASFD;
+
+	hdr->len = (uint16_t)msg->wpos;
+
+	ibuf_close(&ibuf->w, msg);
+}
+
+void
+imsg_free(struct imsg *imsg)
+{
+	freezero(imsg->data, imsg->hdr.len - IMSG_HEADER_SIZE);
+}
+
+static int
+imsg_get_fd(struct imsgbuf *ibuf)
+{
+	int		 fd;
+	struct imsg_fd	*ifd;
+
+	if ((ifd = TAILQ_FIRST(&ibuf->fds)) == NULL)
+		return (-1);
+
+	fd = ifd->fd;
+	TAILQ_REMOVE(&ibuf->fds, ifd, entry);
+	free(ifd);
+
+	return (fd);
+}
+
+int
+imsg_flush(struct imsgbuf *ibuf)
+{
+	while (ibuf->w.queued)
+		if (msgbuf_write(&ibuf->w) <= 0)
+			return (-1);
+	return (0);
+}
+
+void
+imsg_clear(struct imsgbuf *ibuf)
+{
+	int	fd;
+
+	msgbuf_clear(&ibuf->w);
+	while ((fd = imsg_get_fd(ibuf)) != -1)
+		close(fd);
+}
blob - /dev/null
blob + dab6b00d1883af65ccb962fb88ef793964ac2379 (mode 644)
--- /dev/null
+++ compat/imsg.h
@@ -0,0 +1,114 @@
+/*	$OpenBSD: imsg.h,v 1.4 2017/03/24 09:34:12 nicm Exp $	*/
+
+/*
+ * Copyright (c) 2006, 2007 Pierre-Yves Ritschard <pyr@openbsd.org>
+ * Copyright (c) 2006, 2007, 2008 Reyk Floeter <reyk@openbsd.org>
+ * Copyright (c) 2003, 2004 Henning Brauer <henning@openbsd.org>
+ *
+ * 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.
+ */
+
+#ifndef _IMSG_H_
+#define _IMSG_H_
+
+
+#define IBUF_READ_SIZE		65535
+#define IMSG_HEADER_SIZE	sizeof(struct imsg_hdr)
+#define MAX_IMSGSIZE		16384
+
+#include <stdint.h>
+
+struct ibuf {
+	TAILQ_ENTRY(ibuf)	 entry;
+	u_char			*buf;
+	size_t			 size;
+	size_t			 max;
+	size_t			 wpos;
+	size_t			 rpos;
+	int			 fd;
+};
+
+struct msgbuf {
+	TAILQ_HEAD(, ibuf)	 bufs;
+	uint32_t		 queued;
+	int			 fd;
+};
+
+struct ibuf_read {
+	u_char			 buf[IBUF_READ_SIZE];
+	u_char			*rptr;
+	size_t			 wpos;
+};
+
+struct imsg_fd {
+	TAILQ_ENTRY(imsg_fd)	entry;
+	int			fd;
+};
+
+struct imsgbuf {
+	TAILQ_HEAD(, imsg_fd)	 fds;
+	struct ibuf_read	 r;
+	struct msgbuf		 w;
+	int			 fd;
+	pid_t			 pid;
+};
+
+#define IMSGF_HASFD	1
+
+struct imsg_hdr {
+	uint32_t	 type;
+	uint16_t	 len;
+	uint16_t	 flags;
+	uint32_t	 peerid;
+	uint32_t	 pid;
+};
+
+struct imsg {
+	struct imsg_hdr	 hdr;
+	int		 fd;
+	void		*data;
+};
+
+
+/* buffer.c */
+struct ibuf	*ibuf_open(size_t);
+struct ibuf	*ibuf_dynamic(size_t, size_t);
+int		 ibuf_add(struct ibuf *, const void *, size_t);
+void		*ibuf_reserve(struct ibuf *, size_t);
+void		*ibuf_seek(struct ibuf *, size_t, size_t);
+size_t		 ibuf_size(struct ibuf *);
+size_t		 ibuf_left(struct ibuf *);
+void		 ibuf_close(struct msgbuf *, struct ibuf *);
+int		 ibuf_write(struct msgbuf *);
+void		 ibuf_free(struct ibuf *);
+void		 msgbuf_init(struct msgbuf *);
+void		 msgbuf_clear(struct msgbuf *);
+int		 msgbuf_write(struct msgbuf *);
+void		 msgbuf_drain(struct msgbuf *, size_t);
+
+/* imsg.c */
+void	 imsg_init(struct imsgbuf *, int);
+ssize_t	 imsg_read(struct imsgbuf *);
+ssize_t	 imsg_get(struct imsgbuf *, struct imsg *);
+int	 imsg_compose(struct imsgbuf *, uint32_t, uint32_t, pid_t, int,
+	    const void *, uint16_t);
+int	 imsg_composev(struct imsgbuf *, uint32_t, uint32_t,  pid_t, int,
+	    const struct iovec *, int);
+struct ibuf *imsg_create(struct imsgbuf *, uint32_t, uint32_t, pid_t, uint16_t);
+int	 imsg_add(struct ibuf *, const void *, uint16_t);
+void	 imsg_close(struct imsgbuf *, struct ibuf *);
+void	 imsg_free(struct imsg *);
+int	 imsg_flush(struct imsgbuf *);
+void	 imsg_clear(struct imsgbuf *);
+
+#endif
blob - /dev/null
blob + 4834ccc2e643d986015bbd581d0a192499b372d9 (mode 644)
--- /dev/null
+++ compat/merge.c
@@ -0,0 +1,343 @@
+/*-
+ * Copyright (c) 1992, 1993
+ *	The Regents of the University of California.  All rights reserved.
+ *
+ * This code is derived from software contributed to Berkeley by
+ * Peter McIlroy.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ * 4. Neither the name of the University nor the names of its contributors
+ *    may be used to endorse or promote products derived from this software
+ *    without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#include <sys/cdefs.h>
+
+#include "got_compat.h"
+
+/*
+ * Hybrid exponential search/linear search merge sort with hybrid
+ * natural/pairwise first pass.  Requires about .3% more comparisons
+ * for random data than LSMS with pairwise first pass alone.
+ * It works for objects as small as two bytes.
+ */
+
+#define NATURAL
+#define THRESHOLD 16	/* Best choice for natural merge cut-off. */
+
+/* #define NATURAL to get hybrid natural merge.
+ * (The default is pairwise merging.)
+ */
+
+#include <sys/types.h>
+
+#include <errno.h>
+#include <stdlib.h>
+#include <string.h>
+
+static void setup(unsigned char *, unsigned char *, size_t, size_t,
+    int (*)(const void *, const void *));
+static void insertionsort(unsigned char *, size_t, size_t,
+    int (*)(const void *, const void *));
+
+#define ISIZE sizeof(int)
+#define PSIZE sizeof(unsigned char *)
+#define ICOPY_LIST(src, dst, last)				\
+	do							\
+	*(int*)dst = *(int*)src, src += ISIZE, dst += ISIZE;	\
+	while(src < last)
+#define ICOPY_ELT(src, dst, i)					\
+	do							\
+	*(int*) dst = *(int*) src, src += ISIZE, dst += ISIZE;	\
+	while (i -= ISIZE)
+
+#define CCOPY_LIST(src, dst, last)		\
+	do					\
+		*dst++ = *src++;		\
+	while (src < last)
+#define CCOPY_ELT(src, dst, i)			\
+	do					\
+		*dst++ = *src++;		\
+	while (i -= 1)
+
+/*
+ * Find the next possible pointer head.  (Trickery for forcing an array
+ * to do double duty as a linked list when objects do not align with word
+ * boundaries.
+ */
+/* Assumption: PSIZE is a power of 2. */
+#define EVAL(p) (unsigned char **)					\
+	((unsigned char *)0 +						\
+	 (((unsigned char *)p + PSIZE - 1 -				\
+	   (unsigned char *)0) & ~(PSIZE - 1)))
+
+/*
+ * Arguments are as for qsort.
+ */
+int
+mergesort(void *base, size_t nmemb, size_t size,
+	int (*cmp)(const void *, const void *))
+{
+	size_t i;
+	int sense;
+	int big, iflag;
+	unsigned char *f1, *f2, *t, *b, *tp2, *q, *l1, *l2;
+	unsigned char *list2, *list1, *p2, *p, *last, **p1;
+
+	if (size < PSIZE / 2) {		/* Pointers must fit into 2 * size. */
+		errno = EINVAL;
+		return (-1);
+	}
+
+	if (nmemb == 0)
+		return (0);
+
+	/*
+	 * XXX
+	 * Stupid subtraction for the Cray.
+	 */
+	iflag = 0;
+	if (!(size % ISIZE) && !(((char *)base - (char *)0) % ISIZE))
+		iflag = 1;
+
+	if ((list2 = malloc(nmemb * size + PSIZE)) == NULL)
+		return (-1);
+
+	list1 = base;
+	setup(list1, list2, nmemb, size, cmp);
+	last = list2 + nmemb * size;
+	i = big = 0;
+	while (*EVAL(list2) != last) {
+	    l2 = list1;
+	    p1 = EVAL(list1);
+	    for (tp2 = p2 = list2; p2 != last; p1 = EVAL(l2)) {
+	    	p2 = *EVAL(p2);
+	    	f1 = l2;
+	    	f2 = l1 = list1 + (p2 - list2);
+	    	if (p2 != last)
+	    		p2 = *EVAL(p2);
+	    	l2 = list1 + (p2 - list2);
+	    	while (f1 < l1 && f2 < l2) {
+	    		if ((*cmp)(f1, f2) <= 0) {
+	    			q = f2;
+	    			b = f1, t = l1;
+	    			sense = -1;
+	    		} else {
+	    			q = f1;
+	    			b = f2, t = l2;
+	    			sense = 0;
+	    		}
+	    		if (!big) {	/* here i = 0 */
+				while ((b += size) < t && cmp(q, b) >sense)
+	    				if (++i == 6) {
+	    					big = 1;
+	    					goto EXPONENTIAL;
+	    				}
+	    		} else {
+EXPONENTIAL:	    		for (i = size; ; i <<= 1)
+	    				if ((p = (b + i)) >= t) {
+	    					if ((p = t - size) > b &&
+						    (*cmp)(q, p) <= sense)
+	    						t = p;
+	    					else
+	    						b = p;
+	    					break;
+	    				} else if ((*cmp)(q, p) <= sense) {
+	    					t = p;
+	    					if (i == size)
+	    						big = 0;
+	    					goto FASTCASE;
+	    				} else
+	    					b = p;
+				while (t > b+size) {
+	    				i = (((t - b) / size) >> 1) * size;
+	    				if ((*cmp)(q, p = b + i) <= sense)
+	    					t = p;
+	    				else
+	    					b = p;
+	    			}
+	    			goto COPY;
+FASTCASE:	    		while (i > size)
+	    				if ((*cmp)(q,
+	    					p = b + (i >>= 1)) <= sense)
+	    					t = p;
+	    				else
+	    					b = p;
+COPY:	    			b = t;
+	    		}
+	    		i = size;
+	    		if (q == f1) {
+	    			if (iflag) {
+	    				ICOPY_LIST(f2, tp2, b);
+	    				ICOPY_ELT(f1, tp2, i);
+	    			} else {
+	    				CCOPY_LIST(f2, tp2, b);
+	    				CCOPY_ELT(f1, tp2, i);
+	    			}
+	    		} else {
+	    			if (iflag) {
+	    				ICOPY_LIST(f1, tp2, b);
+	    				ICOPY_ELT(f2, tp2, i);
+	    			} else {
+	    				CCOPY_LIST(f1, tp2, b);
+	    				CCOPY_ELT(f2, tp2, i);
+	    			}
+	    		}
+	    	}
+	    	if (f2 < l2) {
+	    		if (iflag)
+	    			ICOPY_LIST(f2, tp2, l2);
+	    		else
+	    			CCOPY_LIST(f2, tp2, l2);
+	    	} else if (f1 < l1) {
+	    		if (iflag)
+	    			ICOPY_LIST(f1, tp2, l1);
+	    		else
+	    			CCOPY_LIST(f1, tp2, l1);
+	    	}
+	    	*p1 = l2;
+	    }
+	    tp2 = list1;	/* swap list1, list2 */
+	    list1 = list2;
+	    list2 = tp2;
+	    last = list2 + nmemb*size;
+	}
+	if (base == list2) {
+		memmove(list2, list1, nmemb*size);
+		list2 = list1;
+	}
+	free(list2);
+	return (0);
+}
+
+#define	swap(a, b) {					\
+		s = b;					\
+		i = size;				\
+		do {					\
+			tmp = *a; *a++ = *s; *s++ = tmp; \
+		} while (--i);				\
+		a -= size;				\
+	}
+#define reverse(bot, top) {				\
+	s = top;					\
+	do {						\
+		i = size;				\
+		do {					\
+			tmp = *bot; *bot++ = *s; *s++ = tmp; \
+		} while (--i);				\
+		s -= size2;				\
+	} while(bot < s);				\
+}
+
+/*
+ * Optional hybrid natural/pairwise first pass.  Eats up list1 in runs of
+ * increasing order, list2 in a corresponding linked list.  Checks for runs
+ * when THRESHOLD/2 pairs compare with same sense.  (Only used when NATURAL
+ * is defined.  Otherwise simple pairwise merging is used.)
+ */
+static void
+setup(unsigned char *list1, unsigned char *list2, size_t n, size_t size,
+	int (*cmp)(const void *, const void *))
+{
+	int i, length, size2, tmp, sense;
+	unsigned char *f1, *f2, *s, *l2, *last, *p2;
+
+	size2 = size*2;
+	if (n <= 5) {
+		insertionsort(list1, n, size, cmp);
+		*EVAL(list2) = (unsigned char*) list2 + n*size;
+		return;
+	}
+	/*
+	 * Avoid running pointers out of bounds; limit n to evens
+	 * for simplicity.
+	 */
+	i = 4 + (n & 1);
+	insertionsort(list1 + (n - i) * size, i, size, cmp);
+	last = list1 + size * (n - i);
+	*EVAL(list2 + (last - list1)) = list2 + n * size;
+
+#ifdef NATURAL
+	p2 = list2;
+	f1 = list1;
+	sense = (cmp(f1, f1 + size) > 0);
+	for (; f1 < last; sense = !sense) {
+		length = 2;
+					/* Find pairs with same sense. */
+		for (f2 = f1 + size2; f2 < last; f2 += size2) {
+			if ((cmp(f2, f2+ size) > 0) != sense)
+				break;
+			length += 2;
+		}
+		if (length < THRESHOLD) {		/* Pairwise merge */
+			do {
+				p2 = *EVAL(p2) = f1 + size2 - list1 + list2;
+				if (sense > 0)
+					swap (f1, f1 + size);
+			} while ((f1 += size2) < f2);
+		} else {				/* Natural merge */
+			l2 = f2;
+			for (f2 = f1 + size2; f2 < l2; f2 += size2) {
+				if ((cmp(f2-size, f2) > 0) != sense) {
+					p2 = *EVAL(p2) = f2 - list1 + list2;
+					if (sense > 0)
+						reverse(f1, f2-size);
+					f1 = f2;
+				}
+			}
+			if (sense > 0)
+				reverse (f1, f2-size);
+			f1 = f2;
+			if (f2 < last || cmp(f2 - size, f2) > 0)
+				p2 = *EVAL(p2) = f2 - list1 + list2;
+			else
+				p2 = *EVAL(p2) = list2 + n*size;
+		}
+	}
+#else		/* pairwise merge only. */
+	for (f1 = list1, p2 = list2; f1 < last; f1 += size2) {
+		p2 = *EVAL(p2) = p2 + size2;
+		if (cmp (f1, f1 + size) > 0)
+			swap(f1, f1 + size);
+	}
+#endif /* NATURAL */
+}
+
+/*
+ * This is to avoid out-of-bounds addresses in sorting the
+ * last 4 elements.
+ */
+static void
+insertionsort(unsigned char *a, size_t n, size_t size,
+	int (*cmp)(const void *, const void *))
+{
+	unsigned char *ai, *s, *t, *u, tmp;
+	int i;
+
+	for (ai = a+size; --n >= 1; ai += size)
+		for (t = ai; t > a; t -= size) {
+			u = t - size;
+			if (cmp(u, t) <= 0)
+				break;
+			swap(u, t);
+		}
+}
blob - /dev/null
blob + bc1568be67482bf033c0da484f8bd9fd41426d03 (mode 644)
--- /dev/null
+++ compat/queue.h
@@ -0,0 +1,631 @@
+/*	$OpenBSD: queue.h,v 1.46 2020/12/30 13:33:12 millert Exp $	*/
+/*	$NetBSD: queue.h,v 1.11 1996/05/16 05:17:14 mycroft Exp $	*/
+
+/*
+ * Copyright (c) 1991, 1993
+ *	The Regents of the University of California.  All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ * 3. Neither the name of the University nor the names of its contributors
+ *    may be used to endorse or promote products derived from this software
+ *    without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ *	@(#)queue.h	8.5 (Berkeley) 8/20/94
+ */
+
+#ifndef	_SYS_QUEUE_H_
+#define	_SYS_QUEUE_H_
+
+/*
+ * This file defines five types of data structures: singly-linked lists,
+ * lists, simple queues, tail queues and XOR simple queues.
+ *
+ *
+ * A singly-linked list is headed by a single forward pointer. The elements
+ * are singly linked for minimum space and pointer manipulation overhead at
+ * the expense of O(n) removal for arbitrary elements. New elements can be
+ * added to the list after an existing element or at the head of the list.
+ * Elements being removed from the head of the list should use the explicit
+ * macro for this purpose for optimum efficiency. A singly-linked list may
+ * only be traversed in the forward direction.  Singly-linked lists are ideal
+ * for applications with large datasets and few or no removals or for
+ * implementing a LIFO queue.
+ *
+ * A list is headed by a single forward pointer (or an array of forward
+ * pointers for a hash table header). The elements are doubly linked
+ * so that an arbitrary element can be removed without a need to
+ * traverse the list. New elements can be added to the list before
+ * or after an existing element or at the head of the list. A list
+ * may only be traversed in the forward direction.
+ *
+ * A simple queue is headed by a pair of pointers, one to the head of the
+ * list and the other to the tail of the list. The elements are singly
+ * linked to save space, so elements can only be removed from the
+ * head of the list. New elements can be added to the list before or after
+ * an existing element, at the head of the list, or at the end of the
+ * list. A simple queue may only be traversed in the forward direction.
+ *
+ * A tail queue is headed by a pair of pointers, one to the head of the
+ * list and the other to the tail of the list. The elements are doubly
+ * linked so that an arbitrary element can be removed without a need to
+ * traverse the list. New elements can be added to the list before or
+ * after an existing element, at the head of the list, or at the end of
+ * the list. A tail queue may be traversed in either direction.
+ *
+ * An XOR simple queue is used in the same way as a regular simple queue.
+ * The difference is that the head structure also includes a "cookie" that
+ * is XOR'd with the queue pointer (first, last or next) to generate the
+ * real pointer value.
+ *
+ * For details on the use of these macros, see the queue(3) manual page.
+ */
+
+#if defined(QUEUE_MACRO_DEBUG) || (defined(_KERNEL) && defined(DIAGNOSTIC))
+#define _Q_INVALID ((void *)-1)
+#define _Q_INVALIDATE(a) (a) = _Q_INVALID
+#else
+#define _Q_INVALIDATE(a)
+#endif
+
+/*
+ * Singly-linked List definitions.
+ */
+#define SLIST_HEAD(name, type)						\
+struct name {								\
+	struct type *slh_first;	/* first element */			\
+}
+
+#define	SLIST_HEAD_INITIALIZER(head)					\
+	{ NULL }
+
+#define SLIST_ENTRY(type)						\
+struct {								\
+	struct type *sle_next;	/* next element */			\
+}
+
+/*
+ * Singly-linked List access methods.
+ */
+#define	SLIST_FIRST(head)	((head)->slh_first)
+#define	SLIST_END(head)		NULL
+#define	SLIST_EMPTY(head)	(SLIST_FIRST(head) == SLIST_END(head))
+#define	SLIST_NEXT(elm, field)	((elm)->field.sle_next)
+
+#define	SLIST_FOREACH(var, head, field)					\
+	for((var) = SLIST_FIRST(head);					\
+	    (var) != SLIST_END(head);					\
+	    (var) = SLIST_NEXT(var, field))
+
+#define	SLIST_FOREACH_SAFE(var, head, field, tvar)			\
+	for ((var) = SLIST_FIRST(head);				\
+	    (var) && ((tvar) = SLIST_NEXT(var, field), 1);		\
+	    (var) = (tvar))
+
+/*
+ * Singly-linked List functions.
+ */
+#define	SLIST_INIT(head) {						\
+	SLIST_FIRST(head) = SLIST_END(head);				\
+}
+
+#define	SLIST_INSERT_AFTER(slistelm, elm, field) do {			\
+	(elm)->field.sle_next = (slistelm)->field.sle_next;		\
+	(slistelm)->field.sle_next = (elm);				\
+} while (0)
+
+#define	SLIST_INSERT_HEAD(head, elm, field) do {			\
+	(elm)->field.sle_next = (head)->slh_first;			\
+	(head)->slh_first = (elm);					\
+} while (0)
+
+#define	SLIST_REMOVE_AFTER(elm, field) do {				\
+	(elm)->field.sle_next = (elm)->field.sle_next->field.sle_next;	\
+} while (0)
+
+#define	SLIST_REMOVE_HEAD(head, field) do {				\
+	(head)->slh_first = (head)->slh_first->field.sle_next;		\
+} while (0)
+
+#define SLIST_REMOVE(head, elm, type, field) do {			\
+	if ((head)->slh_first == (elm)) {				\
+		SLIST_REMOVE_HEAD((head), field);			\
+	} else {							\
+		struct type *curelm = (head)->slh_first;		\
+									\
+		while (curelm->field.sle_next != (elm))			\
+			curelm = curelm->field.sle_next;		\
+		curelm->field.sle_next =				\
+		    curelm->field.sle_next->field.sle_next;		\
+	}								\
+	_Q_INVALIDATE((elm)->field.sle_next);				\
+} while (0)
+
+/*
+ * List definitions.
+ */
+#define LIST_HEAD(name, type)						\
+struct name {								\
+	struct type *lh_first;	/* first element */			\
+}
+
+#define LIST_HEAD_INITIALIZER(head)					\
+	{ NULL }
+
+#define LIST_ENTRY(type)						\
+struct {								\
+	struct type *le_next;	/* next element */			\
+	struct type **le_prev;	/* address of previous next element */	\
+}
+
+/*
+ * List access methods.
+ */
+#define	LIST_FIRST(head)		((head)->lh_first)
+#define	LIST_END(head)			NULL
+#define	LIST_EMPTY(head)		(LIST_FIRST(head) == LIST_END(head))
+#define	LIST_NEXT(elm, field)		((elm)->field.le_next)
+
+#define LIST_FOREACH(var, head, field)					\
+	for((var) = LIST_FIRST(head);					\
+	    (var)!= LIST_END(head);					\
+	    (var) = LIST_NEXT(var, field))
+
+#define	LIST_FOREACH_SAFE(var, head, field, tvar)			\
+	for ((var) = LIST_FIRST(head);				\
+	    (var) && ((tvar) = LIST_NEXT(var, field), 1);		\
+	    (var) = (tvar))
+
+/*
+ * List functions.
+ */
+#define	LIST_INIT(head) do {						\
+	LIST_FIRST(head) = LIST_END(head);				\
+} while (0)
+
+#define LIST_INSERT_AFTER(listelm, elm, field) do {			\
+	if (((elm)->field.le_next = (listelm)->field.le_next) != NULL)	\
+		(listelm)->field.le_next->field.le_prev =		\
+		    &(elm)->field.le_next;				\
+	(listelm)->field.le_next = (elm);				\
+	(elm)->field.le_prev = &(listelm)->field.le_next;		\
+} while (0)
+
+#define	LIST_INSERT_BEFORE(listelm, elm, field) do {			\
+	(elm)->field.le_prev = (listelm)->field.le_prev;		\
+	(elm)->field.le_next = (listelm);				\
+	*(listelm)->field.le_prev = (elm);				\
+	(listelm)->field.le_prev = &(elm)->field.le_next;		\
+} while (0)
+
+#define LIST_INSERT_HEAD(head, elm, field) do {				\
+	if (((elm)->field.le_next = (head)->lh_first) != NULL)		\
+		(head)->lh_first->field.le_prev = &(elm)->field.le_next;\
+	(head)->lh_first = (elm);					\
+	(elm)->field.le_prev = &(head)->lh_first;			\
+} while (0)
+
+#define LIST_REMOVE(elm, field) do {					\
+	if ((elm)->field.le_next != NULL)				\
+		(elm)->field.le_next->field.le_prev =			\
+		    (elm)->field.le_prev;				\
+	*(elm)->field.le_prev = (elm)->field.le_next;			\
+	_Q_INVALIDATE((elm)->field.le_prev);				\
+	_Q_INVALIDATE((elm)->field.le_next);				\
+} while (0)
+
+#define LIST_REPLACE(elm, elm2, field) do {				\
+	if (((elm2)->field.le_next = (elm)->field.le_next) != NULL)	\
+		(elm2)->field.le_next->field.le_prev =			\
+		    &(elm2)->field.le_next;				\
+	(elm2)->field.le_prev = (elm)->field.le_prev;			\
+	*(elm2)->field.le_prev = (elm2);				\
+	_Q_INVALIDATE((elm)->field.le_prev);				\
+	_Q_INVALIDATE((elm)->field.le_next);				\
+} while (0)
+
+/*
+ * Simple queue definitions.
+ */
+#define SIMPLEQ_HEAD(name, type)					\
+struct name {								\
+	struct type *sqh_first;	/* first element */			\
+	struct type **sqh_last;	/* addr of last next element */		\
+}
+
+#define SIMPLEQ_HEAD_INITIALIZER(head)					\
+	{ NULL, &(head).sqh_first }
+
+#define SIMPLEQ_ENTRY(type)						\
+struct {								\
+	struct type *sqe_next;	/* next element */			\
+}
+
+/*
+ * Simple queue access methods.
+ */
+#define	SIMPLEQ_FIRST(head)	    ((head)->sqh_first)
+#define	SIMPLEQ_END(head)	    NULL
+#define	SIMPLEQ_EMPTY(head)	    (SIMPLEQ_FIRST(head) == SIMPLEQ_END(head))
+#define	SIMPLEQ_NEXT(elm, field)    ((elm)->field.sqe_next)
+
+#define SIMPLEQ_FOREACH(var, head, field)				\
+	for((var) = SIMPLEQ_FIRST(head);				\
+	    (var) != SIMPLEQ_END(head);					\
+	    (var) = SIMPLEQ_NEXT(var, field))
+
+#define	SIMPLEQ_FOREACH_SAFE(var, head, field, tvar)			\
+	for ((var) = SIMPLEQ_FIRST(head);				\
+	    (var) && ((tvar) = SIMPLEQ_NEXT(var, field), 1);		\
+	    (var) = (tvar))
+
+/*
+ * Simple queue functions.
+ */
+#define	SIMPLEQ_INIT(head) do {						\
+	(head)->sqh_first = NULL;					\
+	(head)->sqh_last = &(head)->sqh_first;				\
+} while (0)
+
+#define SIMPLEQ_INSERT_HEAD(head, elm, field) do {			\
+	if (((elm)->field.sqe_next = (head)->sqh_first) == NULL)	\
+		(head)->sqh_last = &(elm)->field.sqe_next;		\
+	(head)->sqh_first = (elm);					\
+} while (0)
+
+#define SIMPLEQ_INSERT_TAIL(head, elm, field) do {			\
+	(elm)->field.sqe_next = NULL;					\
+	*(head)->sqh_last = (elm);					\
+	(head)->sqh_last = &(elm)->field.sqe_next;			\
+} while (0)
+
+#define SIMPLEQ_INSERT_AFTER(head, listelm, elm, field) do {		\
+	if (((elm)->field.sqe_next = (listelm)->field.sqe_next) == NULL)\
+		(head)->sqh_last = &(elm)->field.sqe_next;		\
+	(listelm)->field.sqe_next = (elm);				\
+} while (0)
+
+#define SIMPLEQ_REMOVE_HEAD(head, field) do {			\
+	if (((head)->sqh_first = (head)->sqh_first->field.sqe_next) == NULL) \
+		(head)->sqh_last = &(head)->sqh_first;			\
+} while (0)
+
+#define SIMPLEQ_REMOVE_AFTER(head, elm, field) do {			\
+	if (((elm)->field.sqe_next = (elm)->field.sqe_next->field.sqe_next) \
+	    == NULL)							\
+		(head)->sqh_last = &(elm)->field.sqe_next;		\
+} while (0)
+
+#define SIMPLEQ_CONCAT(head1, head2) do {				\
+	if (!SIMPLEQ_EMPTY((head2))) {					\
+		*(head1)->sqh_last = (head2)->sqh_first;		\
+		(head1)->sqh_last = (head2)->sqh_last;			\
+		SIMPLEQ_INIT((head2));					\
+	}								\
+} while (0)
+
+/*
+ * XOR Simple queue definitions.
+ */
+#define XSIMPLEQ_HEAD(name, type)					\
+struct name {								\
+	struct type *sqx_first;	/* first element */			\
+	struct type **sqx_last;	/* addr of last next element */		\
+	unsigned long sqx_cookie;					\
+}
+
+#define XSIMPLEQ_ENTRY(type)						\
+struct {								\
+	struct type *sqx_next;	/* next element */			\
+}
+
+/*
+ * XOR Simple queue access methods.
+ */
+#define XSIMPLEQ_XOR(head, ptr)	    ((__typeof(ptr))((head)->sqx_cookie ^ \
+					(unsigned long)(ptr)))
+#define	XSIMPLEQ_FIRST(head)	    XSIMPLEQ_XOR(head, ((head)->sqx_first))
+#define	XSIMPLEQ_END(head)	    NULL
+#define	XSIMPLEQ_EMPTY(head)	    (XSIMPLEQ_FIRST(head) == XSIMPLEQ_END(head))
+#define	XSIMPLEQ_NEXT(head, elm, field)    XSIMPLEQ_XOR(head, ((elm)->field.sqx_next))
+
+
+#define XSIMPLEQ_FOREACH(var, head, field)				\
+	for ((var) = XSIMPLEQ_FIRST(head);				\
+	    (var) != XSIMPLEQ_END(head);				\
+	    (var) = XSIMPLEQ_NEXT(head, var, field))
+
+#define	XSIMPLEQ_FOREACH_SAFE(var, head, field, tvar)			\
+	for ((var) = XSIMPLEQ_FIRST(head);				\
+	    (var) && ((tvar) = XSIMPLEQ_NEXT(head, var, field), 1);	\
+	    (var) = (tvar))
+
+/*
+ * XOR Simple queue functions.
+ */
+#define	XSIMPLEQ_INIT(head) do {					\
+	arc4random_buf(&(head)->sqx_cookie, sizeof((head)->sqx_cookie)); \
+	(head)->sqx_first = XSIMPLEQ_XOR(head, NULL);			\
+	(head)->sqx_last = XSIMPLEQ_XOR(head, &(head)->sqx_first);	\
+} while (0)
+
+#define XSIMPLEQ_INSERT_HEAD(head, elm, field) do {			\
+	if (((elm)->field.sqx_next = (head)->sqx_first) ==		\
+	    XSIMPLEQ_XOR(head, NULL))					\
+		(head)->sqx_last = XSIMPLEQ_XOR(head, &(elm)->field.sqx_next); \
+	(head)->sqx_first = XSIMPLEQ_XOR(head, (elm));			\
+} while (0)
+
+#define XSIMPLEQ_INSERT_TAIL(head, elm, field) do {			\
+	(elm)->field.sqx_next = XSIMPLEQ_XOR(head, NULL);		\
+	*(XSIMPLEQ_XOR(head, (head)->sqx_last)) = XSIMPLEQ_XOR(head, (elm)); \
+	(head)->sqx_last = XSIMPLEQ_XOR(head, &(elm)->field.sqx_next);	\
+} while (0)
+
+#define XSIMPLEQ_INSERT_AFTER(head, listelm, elm, field) do {		\
+	if (((elm)->field.sqx_next = (listelm)->field.sqx_next) ==	\
+	    XSIMPLEQ_XOR(head, NULL))					\
+		(head)->sqx_last = XSIMPLEQ_XOR(head, &(elm)->field.sqx_next); \
+	(listelm)->field.sqx_next = XSIMPLEQ_XOR(head, (elm));		\
+} while (0)
+
+#define XSIMPLEQ_REMOVE_HEAD(head, field) do {				\
+	if (((head)->sqx_first = XSIMPLEQ_XOR(head,			\
+	    (head)->sqx_first)->field.sqx_next) == XSIMPLEQ_XOR(head, NULL)) \
+		(head)->sqx_last = XSIMPLEQ_XOR(head, &(head)->sqx_first); \
+} while (0)
+
+#define XSIMPLEQ_REMOVE_AFTER(head, elm, field) do {			\
+	if (((elm)->field.sqx_next = XSIMPLEQ_XOR(head,			\
+	    (elm)->field.sqx_next)->field.sqx_next)			\
+	    == XSIMPLEQ_XOR(head, NULL))				\
+		(head)->sqx_last = 					\
+		    XSIMPLEQ_XOR(head, &(elm)->field.sqx_next);		\
+} while (0)
+
+
+/*
+ * Tail queue definitions.
+ */
+#define TAILQ_HEAD(name, type)						\
+struct name {								\
+	struct type *tqh_first;	/* first element */			\
+	struct type **tqh_last;	/* addr of last next element */		\
+}
+
+#define TAILQ_HEAD_INITIALIZER(head)					\
+	{ NULL, &(head).tqh_first }
+
+#define TAILQ_ENTRY(type)						\
+struct {								\
+	struct type *tqe_next;	/* next element */			\
+	struct type **tqe_prev;	/* address of previous next element */	\
+}
+
+/*
+ * Tail queue access methods.
+ */
+#define	TAILQ_FIRST(head)		((head)->tqh_first)
+#define	TAILQ_END(head)			NULL
+#define	TAILQ_NEXT(elm, field)		((elm)->field.tqe_next)
+#define TAILQ_LAST(head, headname)					\
+	(*(((struct headname *)((head)->tqh_last))->tqh_last))
+/* XXX */
+#define TAILQ_PREV(elm, headname, field)				\
+	(*(((struct headname *)((elm)->field.tqe_prev))->tqh_last))
+#define	TAILQ_EMPTY(head)						\
+	(TAILQ_FIRST(head) == TAILQ_END(head))
+
+#define TAILQ_FOREACH(var, head, field)					\
+	for((var) = TAILQ_FIRST(head);					\
+	    (var) != TAILQ_END(head);					\
+	    (var) = TAILQ_NEXT(var, field))
+
+#define	TAILQ_FOREACH_SAFE(var, head, field, tvar)			\
+	for ((var) = TAILQ_FIRST(head);					\
+	    (var) != TAILQ_END(head) &&					\
+	    ((tvar) = TAILQ_NEXT(var, field), 1);			\
+	    (var) = (tvar))
+
+
+#define TAILQ_FOREACH_REVERSE(var, head, headname, field)		\
+	for((var) = TAILQ_LAST(head, headname);				\
+	    (var) != TAILQ_END(head);					\
+	    (var) = TAILQ_PREV(var, headname, field))
+
+#define	TAILQ_FOREACH_REVERSE_SAFE(var, head, headname, field, tvar)	\
+	for ((var) = TAILQ_LAST(head, headname);			\
+	    (var) != TAILQ_END(head) &&					\
+	    ((tvar) = TAILQ_PREV(var, headname, field), 1);		\
+	    (var) = (tvar))
+
+/*
+ * Tail queue functions.
+ */
+#define	TAILQ_INIT(head) do {						\
+	(head)->tqh_first = NULL;					\
+	(head)->tqh_last = &(head)->tqh_first;				\
+} while (0)
+
+#define TAILQ_INSERT_HEAD(head, elm, field) do {			\
+	if (((elm)->field.tqe_next = (head)->tqh_first) != NULL)	\
+		(head)->tqh_first->field.tqe_prev =			\
+		    &(elm)->field.tqe_next;				\
+	else								\
+		(head)->tqh_last = &(elm)->field.tqe_next;		\
+	(head)->tqh_first = (elm);					\
+	(elm)->field.tqe_prev = &(head)->tqh_first;			\
+} while (0)
+
+#define TAILQ_INSERT_TAIL(head, elm, field) do {			\
+	(elm)->field.tqe_next = NULL;					\
+	(elm)->field.tqe_prev = (head)->tqh_last;			\
+	*(head)->tqh_last = (elm);					\
+	(head)->tqh_last = &(elm)->field.tqe_next;			\
+} while (0)
+
+#define TAILQ_INSERT_AFTER(head, listelm, elm, field) do {		\
+	if (((elm)->field.tqe_next = (listelm)->field.tqe_next) != NULL)\
+		(elm)->field.tqe_next->field.tqe_prev =			\
+		    &(elm)->field.tqe_next;				\
+	else								\
+		(head)->tqh_last = &(elm)->field.tqe_next;		\
+	(listelm)->field.tqe_next = (elm);				\
+	(elm)->field.tqe_prev = &(listelm)->field.tqe_next;		\
+} while (0)
+
+#define	TAILQ_INSERT_BEFORE(listelm, elm, field) do {			\
+	(elm)->field.tqe_prev = (listelm)->field.tqe_prev;		\
+	(elm)->field.tqe_next = (listelm);				\
+	*(listelm)->field.tqe_prev = (elm);				\
+	(listelm)->field.tqe_prev = &(elm)->field.tqe_next;		\
+} while (0)
+
+#define TAILQ_REMOVE(head, elm, field) do {				\
+	if (((elm)->field.tqe_next) != NULL)				\
+		(elm)->field.tqe_next->field.tqe_prev =			\
+		    (elm)->field.tqe_prev;				\
+	else								\
+		(head)->tqh_last = (elm)->field.tqe_prev;		\
+	*(elm)->field.tqe_prev = (elm)->field.tqe_next;			\
+	_Q_INVALIDATE((elm)->field.tqe_prev);				\
+	_Q_INVALIDATE((elm)->field.tqe_next);				\
+} while (0)
+
+#define TAILQ_REPLACE(head, elm, elm2, field) do {			\
+	if (((elm2)->field.tqe_next = (elm)->field.tqe_next) != NULL)	\
+		(elm2)->field.tqe_next->field.tqe_prev =		\
+		    &(elm2)->field.tqe_next;				\
+	else								\
+		(head)->tqh_last = &(elm2)->field.tqe_next;		\
+	(elm2)->field.tqe_prev = (elm)->field.tqe_prev;			\
+	*(elm2)->field.tqe_prev = (elm2);				\
+	_Q_INVALIDATE((elm)->field.tqe_prev);				\
+	_Q_INVALIDATE((elm)->field.tqe_next);				\
+} while (0)
+
+#define TAILQ_CONCAT(head1, head2, field) do {				\
+	if (!TAILQ_EMPTY(head2)) {					\
+		*(head1)->tqh_last = (head2)->tqh_first;		\
+		(head2)->tqh_first->field.tqe_prev = (head1)->tqh_last;	\
+		(head1)->tqh_last = (head2)->tqh_last;			\
+		TAILQ_INIT((head2));					\
+	}								\
+} while (0)
+
+/*
+ * Singly-linked Tail queue declarations.
+ */
+#define	STAILQ_HEAD(name, type)						\
+struct name {								\
+	struct type *stqh_first;	/* first element */		\
+	struct type **stqh_last;	/* addr of last next element */	\
+}
+
+#define	STAILQ_HEAD_INITIALIZER(head)					\
+	{ NULL, &(head).stqh_first }
+
+#define	STAILQ_ENTRY(type)						\
+struct {								\
+	struct type *stqe_next;	/* next element */			\
+}
+
+/*
+ * Singly-linked Tail queue access methods.
+ */
+#define	STAILQ_FIRST(head)	((head)->stqh_first)
+#define	STAILQ_END(head)	NULL
+#define	STAILQ_EMPTY(head)	(STAILQ_FIRST(head) == STAILQ_END(head))
+#define	STAILQ_NEXT(elm, field)	((elm)->field.stqe_next)
+
+#define STAILQ_FOREACH(var, head, field)				\
+	for ((var) = STAILQ_FIRST(head);				\
+	    (var) != STAILQ_END(head);					\
+	    (var) = STAILQ_NEXT(var, field))
+
+#define	STAILQ_FOREACH_SAFE(var, head, field, tvar)			\
+	for ((var) = STAILQ_FIRST(head);				\
+	    (var) && ((tvar) = STAILQ_NEXT(var, field), 1);		\
+	    (var) = (tvar))
+
+/*
+ * Singly-linked Tail queue functions.
+ */
+#define	STAILQ_INIT(head) do {						\
+	STAILQ_FIRST((head)) = NULL;					\
+	(head)->stqh_last = &STAILQ_FIRST((head));			\
+} while (0)
+
+#define	STAILQ_INSERT_HEAD(head, elm, field) do {			\
+	if ((STAILQ_NEXT((elm), field) = STAILQ_FIRST((head))) == NULL)	\
+		(head)->stqh_last = &STAILQ_NEXT((elm), field);		\
+	STAILQ_FIRST((head)) = (elm);					\
+} while (0)
+
+#define	STAILQ_INSERT_TAIL(head, elm, field) do {			\
+	STAILQ_NEXT((elm), field) = NULL;				\
+	*(head)->stqh_last = (elm);					\
+	(head)->stqh_last = &STAILQ_NEXT((elm), field);			\
+} while (0)
+
+#define	STAILQ_INSERT_AFTER(head, listelm, elm, field) do {		\
+	if ((STAILQ_NEXT((elm), field) = STAILQ_NEXT((elm), field)) == NULL)\
+		(head)->stqh_last = &STAILQ_NEXT((elm), field);		\
+	STAILQ_NEXT((elm), field) = (elm);				\
+} while (0)
+
+#define STAILQ_REMOVE_HEAD(head, field) do {                            \
+	if ((STAILQ_FIRST((head)) =					\
+	    STAILQ_NEXT(STAILQ_FIRST((head)), field)) == NULL)		\
+		(head)->stqh_last = &STAILQ_FIRST((head));		\
+} while (0)
+
+#define STAILQ_REMOVE_AFTER(head, elm, field) do {                      \
+	if ((STAILQ_NEXT(elm, field) =					\
+	    STAILQ_NEXT(STAILQ_NEXT(elm, field), field)) == NULL)	\
+		(head)->stqh_last = &STAILQ_NEXT((elm), field);		\
+} while (0)
+
+#define	STAILQ_REMOVE(head, elm, type, field) do {			\
+	if (STAILQ_FIRST((head)) == (elm)) {				\
+		STAILQ_REMOVE_HEAD((head), field);			\
+	} else {							\
+		struct type *curelm = (head)->stqh_first;		\
+		while (STAILQ_NEXT(curelm, field) != (elm))		\
+			curelm = STAILQ_NEXT(curelm, field);		\
+		STAILQ_REMOVE_AFTER(head, curelm, field);		\
+	}								\
+} while (0)
+
+#define	STAILQ_CONCAT(head1, head2) do {				\
+	if (!STAILQ_EMPTY((head2))) {					\
+		*(head1)->stqh_last = (head2)->stqh_first;		\
+		(head1)->stqh_last = (head2)->stqh_last;		\
+		STAILQ_INIT((head2));					\
+	}								\
+} while (0)
+
+#define	STAILQ_LAST(head, type, field)					\
+	(STAILQ_EMPTY((head)) ?	NULL :					\
+	        ((struct type *)(void *)				\
+		((char *)((head)->stqh_last) - offsetof(struct type, field))))
+
+#endif	/* !_SYS_QUEUE_H_ */
blob - /dev/null
blob + 6f2f8e62c91be8d66e0c0d108846a5dd0a5e5231 (mode 644)
--- /dev/null
+++ compat/reallocarray.c
@@ -0,0 +1,40 @@
+/*	$OpenBSD: reallocarray.c,v 1.3 2015/09/13 08:31:47 guenther Exp $	*/
+/*
+ * Copyright (c) 2008 Otto Moerbeek <otto@drijf.net>
+ *
+ * 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 <sys/types.h>
+#include <errno.h>
+#include <stdint.h>
+#include <stdlib.h>
+
+#include "got_compat.h"
+
+/*
+ * This is sqrt(SIZE_MAX+1), as s1*s2 <= SIZE_MAX
+ * if both s1 < MUL_NO_OVERFLOW and s2 < MUL_NO_OVERFLOW
+ */
+#define MUL_NO_OVERFLOW	((size_t)1 << (sizeof(size_t) * 4))
+
+void *
+reallocarray(void *optr, size_t nmemb, size_t size)
+{
+	if ((nmemb >= MUL_NO_OVERFLOW || size >= MUL_NO_OVERFLOW) &&
+	    nmemb > 0 && SIZE_MAX / nmemb < size) {
+		errno = ENOMEM;
+		return NULL;
+	}
+	return realloc(optr, size * nmemb);
+}
blob - /dev/null
blob + 84d736bf96aa79d1cf9cc867ebaec29949c808cc (mode 644)
--- /dev/null
+++ compat/recallocarray.c
@@ -0,0 +1,80 @@
+/*	$OpenBSD: recallocarray.c,v 1.1 2017/03/06 18:44:21 otto Exp $	*/
+/*
+ * Copyright (c) 2008, 2017 Otto Moerbeek <otto@drijf.net>
+ *
+ * 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 <errno.h>
+#include <stdlib.h>
+#include <stdint.h>
+#include <string.h>
+#include <unistd.h>
+
+/*
+ * This is sqrt(SIZE_MAX+1), as s1*s2 <= SIZE_MAX
+ * if both s1 < MUL_NO_OVERFLOW and s2 < MUL_NO_OVERFLOW
+ */
+#define MUL_NO_OVERFLOW ((size_t)1 << (sizeof(size_t) * 4))
+
+void *
+recallocarray(void *ptr, size_t oldnmemb, size_t newnmemb, size_t size)
+{
+	size_t oldsize, newsize;
+	void *newptr;
+
+	if (ptr == NULL)
+		return calloc(newnmemb, size);
+
+	if ((newnmemb >= MUL_NO_OVERFLOW || size >= MUL_NO_OVERFLOW) &&
+	    newnmemb > 0 && SIZE_MAX / newnmemb < size) {
+		errno = ENOMEM;
+		return NULL;
+	}
+	newsize = newnmemb * size;
+
+	if ((oldnmemb >= MUL_NO_OVERFLOW || size >= MUL_NO_OVERFLOW) &&
+	    oldnmemb > 0 && SIZE_MAX / oldnmemb < size) {
+		errno = EINVAL;
+		return NULL;
+	}
+	oldsize = oldnmemb * size;
+
+	/*
+	 * Don't bother too much if we're shrinking just a bit,
+	 * we do not shrink for series of small steps, oh well.
+	 */
+	if (newsize <= oldsize) {
+		size_t d = oldsize - newsize;
+
+		if (d < oldsize / 2 && d < (size_t)getpagesize()) {
+			memset((char *)ptr + newsize, 0, d);
+			return ptr;
+		}
+	}
+
+	newptr = malloc(newsize);
+	if (newptr == NULL)
+		return NULL;
+
+	if (newsize > oldsize) {
+		memcpy(newptr, ptr, oldsize);
+		memset((char *)newptr + oldsize, 0, newsize - oldsize);
+	} else
+		memcpy(newptr, ptr, newsize);
+
+	explicit_bzero(ptr, oldsize);
+	free(ptr);
+
+	return newptr;
+}
blob - /dev/null
blob + ceab094411d2c2478012bcdfd621b1f674ef6422 (mode 644)
--- /dev/null
+++ compat/strlcat.c
@@ -0,0 +1,55 @@
+/*	$OpenBSD: strlcat.c,v 1.13 2005/08/08 08:05:37 espie Exp $	*/
+
+/*
+ * Copyright (c) 1998 Todd C. Miller <Todd.Miller@courtesan.com>
+ *
+ * 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 <sys/types.h>
+#include <string.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 */
+}
blob - /dev/null
blob + 110155f76fa25dcdc4dfcdc0db0d1bd028bb0aa8 (mode 644)
--- /dev/null
+++ compat/strlcpy.c
@@ -0,0 +1,51 @@
+/*	$OpenBSD: strlcpy.c,v 1.10 2005/08/08 08:05:37 espie Exp $	*/
+
+/*
+ * Copyright (c) 1998 Todd C. Miller <Todd.Miller@courtesan.com>
+ *
+ * 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 <sys/types.h>
+#include <string.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 && --n != 0) {
+		do {
+			if ((*d++ = *s++) == 0)
+				break;
+		} while (--n != 0);
+	}
+
+	/* 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 */
+}
blob - /dev/null
blob + f43ba6592f617c8acd2ad6edf44cf3516148781b (mode 644)
--- /dev/null
+++ compat/strndup.c
@@ -0,0 +1,39 @@
+/*	$OpenBSD: strndup.c,v 1.2 2015/08/31 02:53:57 guenther Exp $	*/
+
+/*
+ * Copyright (c) 2010 Todd C. Miller <Todd.Miller@courtesan.com>
+ *
+ * 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 <sys/types.h>
+
+#include <stddef.h>
+#include <stdlib.h>
+#include <string.h>
+
+char *
+strndup(const char *str, size_t maxlen)
+{
+	char *copy;
+	size_t len;
+
+	len = strnlen(str, maxlen);
+	copy = malloc(len + 1);
+	if (copy != NULL) {
+		(void)memcpy(copy, str, len);
+		copy[len] = '\0';
+	}
+
+	return copy;
+}
blob - /dev/null
blob + a2017e1972aa0aa29695180b7a5ee8ea29b5da7d (mode 644)
--- /dev/null
+++ compat/strnlen.c
@@ -0,0 +1,32 @@
+/*	$OpenBSD: strnlen.c,v 1.8 2016/10/16 17:37:39 dtucker Exp $	*/
+
+/*
+ * Copyright (c) 2010 Todd C. Miller <Todd.Miller@courtesan.com>
+ *
+ * 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 <sys/types.h>
+
+#include <string.h>
+
+size_t
+strnlen(const char *str, size_t maxlen)
+{
+	const char *cp;
+
+	for (cp = str; maxlen != 0 && *cp != '\0'; cp++, maxlen--)
+		;
+
+	return (size_t)(cp - str);
+}
blob - /dev/null
blob + c44bc5b2ac809c43f9ac2ad7ccd1dd0514c6bfc5 (mode 644)
--- /dev/null
+++ compat/strsep.c
@@ -0,0 +1,71 @@
+/*	$OpenBSD: strsep.c,v 1.6 2005/08/08 08:05:37 espie Exp $	*/
+
+/*-
+ * Copyright (c) 1990, 1993
+ *	The Regents of the University of California.  All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ * 3. Neither the name of the University nor the names of its contributors
+ *    may be used to endorse or promote products derived from this software
+ *    without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#include <string.h>
+#include <stdio.h>
+
+/*
+ * Get next token from string *stringp, where tokens are possibly-empty
+ * strings separated by characters from delim.
+ *
+ * Writes NULs into the string at *stringp to end tokens.
+ * delim need not remain constant from call to call.
+ * On return, *stringp points past the last NUL written (if there might
+ * be further tokens), or is NULL (if there are definitely no more tokens).
+ *
+ * If *stringp is NULL, strsep returns NULL.
+ */
+char *
+strsep(char **stringp, const char *delim)
+{
+	char *s;
+	const char *spanp;
+	int c, sc;
+	char *tok;
+
+	if ((s = *stringp) == NULL)
+		return (NULL);
+	for (tok = s;;) {
+		c = *s++;
+		spanp = delim;
+		do {
+			if ((sc = *spanp++) == c) {
+				if (c == 0)
+					s = NULL;
+				else
+					s[-1] = 0;
+				*stringp = s;
+				return (tok);
+			}
+		} while (sc != 0);
+	}
+	/* NOTREACHED */
+}
blob - /dev/null
blob + e426388ed0fac8fed17622cef39f64c3e6edfecd (mode 644)
--- /dev/null
+++ compat/strtonum.c
@@ -0,0 +1,65 @@
+/*	$OpenBSD: strtonum.c,v 1.6 2004/08/03 19:38:01 millert Exp $	*/
+
+/*
+ * Copyright (c) 2004 Ted Unangst and Todd Miller
+ * All rights reserved.
+ *
+ * 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 <errno.h>
+#include <limits.h>
+#include <stdlib.h>
+
+#define INVALID 	1
+#define TOOSMALL 	2
+#define TOOLARGE 	3
+
+long long
+strtonum(const char *numstr, long long minval, long long maxval,
+    const char **errstrp)
+{
+	long long ll = 0;
+	char *ep;
+	int error = 0;
+	struct errval {
+		const char *errstr;
+		int err;
+	} ev[4] = {
+		{ NULL,		0 },
+		{ "invalid",	EINVAL },
+		{ "too small",	ERANGE },
+		{ "too large",	ERANGE },
+	};
+
+	ev[0].err = errno;
+	errno = 0;
+	if (minval > maxval)
+		error = INVALID;
+	else {
+		ll = strtoll(numstr, &ep, 10);
+		if (numstr == ep || *ep != '\0')
+			error = INVALID;
+		else if ((ll == LLONG_MIN && errno == ERANGE) || ll < minval)
+			error = TOOSMALL;
+		else if ((ll == LLONG_MAX && errno == ERANGE) || ll > maxval)
+			error = TOOLARGE;
+	}
+	if (errstrp != NULL)
+		*errstrp = ev[error].errstr;
+	errno = ev[error].err;
+	if (error)
+		ll = 0;
+
+	return (ll);
+}
blob - /dev/null
blob + 80d0f53813442514d8861d9a152c34f6c7708c65 (mode 644)
--- /dev/null
+++ compat/tree.h
@@ -0,0 +1,748 @@
+/*	$OpenBSD: tree.h,v 1.13 2011/07/09 00:19:45 pirofti Exp $	*/
+/*
+ * Copyright 2002 Niels Provos <provos@citi.umich.edu>
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+ * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef	_SYS_TREE_H_
+#define	_SYS_TREE_H_
+
+/*
+ * This file defines data structures for different types of trees:
+ * splay trees and red-black trees.
+ *
+ * A splay tree is a self-organizing data structure.  Every operation
+ * on the tree causes a splay to happen.  The splay moves the requested
+ * node to the root of the tree and partly rebalances it.
+ *
+ * This has the benefit that request locality causes faster lookups as
+ * the requested nodes move to the top of the tree.  On the other hand,
+ * every lookup causes memory writes.
+ *
+ * The Balance Theorem bounds the total access time for m operations
+ * and n inserts on an initially empty tree as O((m + n)lg n).  The
+ * amortized cost for a sequence of m accesses to a splay tree is O(lg n);
+ *
+ * A red-black tree is a binary search tree with the node color as an
+ * extra attribute.  It fulfills a set of conditions:
+ *	- every search path from the root to a leaf consists of the
+ *	  same number of black nodes,
+ *	- each red node (except for the root) has a black parent,
+ *	- each leaf node is black.
+ *
+ * Every operation on a red-black tree is bounded as O(lg n).
+ * The maximum height of a red-black tree is 2lg (n+1).
+ */
+
+#define SPLAY_HEAD(name, type)						\
+struct name {								\
+	struct type *sph_root; /* root of the tree */			\
+}
+
+#define SPLAY_INITIALIZER(root)						\
+	{ NULL }
+
+#define SPLAY_INIT(root) do {						\
+	(root)->sph_root = NULL;					\
+} while (0)
+
+#define SPLAY_ENTRY(type)						\
+struct {								\
+	struct type *spe_left; /* left element */			\
+	struct type *spe_right; /* right element */			\
+}
+
+#define SPLAY_LEFT(elm, field)		(elm)->field.spe_left
+#define SPLAY_RIGHT(elm, field)		(elm)->field.spe_right
+#define SPLAY_ROOT(head)		(head)->sph_root
+#define SPLAY_EMPTY(head)		(SPLAY_ROOT(head) == NULL)
+
+/* SPLAY_ROTATE_{LEFT,RIGHT} expect that tmp hold SPLAY_{RIGHT,LEFT} */
+#define SPLAY_ROTATE_RIGHT(head, tmp, field) do {			\
+	SPLAY_LEFT((head)->sph_root, field) = SPLAY_RIGHT(tmp, field);	\
+	SPLAY_RIGHT(tmp, field) = (head)->sph_root;			\
+	(head)->sph_root = tmp;						\
+} while (0)
+	
+#define SPLAY_ROTATE_LEFT(head, tmp, field) do {			\
+	SPLAY_RIGHT((head)->sph_root, field) = SPLAY_LEFT(tmp, field);	\
+	SPLAY_LEFT(tmp, field) = (head)->sph_root;			\
+	(head)->sph_root = tmp;						\
+} while (0)
+
+#define SPLAY_LINKLEFT(head, tmp, field) do {				\
+	SPLAY_LEFT(tmp, field) = (head)->sph_root;			\
+	tmp = (head)->sph_root;						\
+	(head)->sph_root = SPLAY_LEFT((head)->sph_root, field);		\
+} while (0)
+
+#define SPLAY_LINKRIGHT(head, tmp, field) do {				\
+	SPLAY_RIGHT(tmp, field) = (head)->sph_root;			\
+	tmp = (head)->sph_root;						\
+	(head)->sph_root = SPLAY_RIGHT((head)->sph_root, field);	\
+} while (0)
+
+#define SPLAY_ASSEMBLE(head, node, left, right, field) do {		\
+	SPLAY_RIGHT(left, field) = SPLAY_LEFT((head)->sph_root, field);	\
+	SPLAY_LEFT(right, field) = SPLAY_RIGHT((head)->sph_root, field);\
+	SPLAY_LEFT((head)->sph_root, field) = SPLAY_RIGHT(node, field);	\
+	SPLAY_RIGHT((head)->sph_root, field) = SPLAY_LEFT(node, field);	\
+} while (0)
+
+/* Generates prototypes and inline functions */
+
+#define SPLAY_PROTOTYPE(name, type, field, cmp)				\
+void name##_SPLAY(struct name *, struct type *);			\
+void name##_SPLAY_MINMAX(struct name *, int);				\
+struct type *name##_SPLAY_INSERT(struct name *, struct type *);		\
+struct type *name##_SPLAY_REMOVE(struct name *, struct type *);		\
+									\
+/* Finds the node with the same key as elm */				\
+static __inline struct type *						\
+name##_SPLAY_FIND(struct name *head, struct type *elm)			\
+{									\
+	if (SPLAY_EMPTY(head))						\
+		return(NULL);						\
+	name##_SPLAY(head, elm);					\
+	if ((cmp)(elm, (head)->sph_root) == 0)				\
+		return (head->sph_root);				\
+	return (NULL);							\
+}									\
+									\
+static __inline struct type *						\
+name##_SPLAY_NEXT(struct name *head, struct type *elm)			\
+{									\
+	name##_SPLAY(head, elm);					\
+	if (SPLAY_RIGHT(elm, field) != NULL) {				\
+		elm = SPLAY_RIGHT(elm, field);				\
+		while (SPLAY_LEFT(elm, field) != NULL) {		\
+			elm = SPLAY_LEFT(elm, field);			\
+		}							\
+	} else								\
+		elm = NULL;						\
+	return (elm);							\
+}									\
+									\
+static __inline struct type *						\
+name##_SPLAY_MIN_MAX(struct name *head, int val)			\
+{									\
+	name##_SPLAY_MINMAX(head, val);					\
+        return (SPLAY_ROOT(head));					\
+}
+
+/* Main splay operation.
+ * Moves node close to the key of elm to top
+ */
+#define SPLAY_GENERATE(name, type, field, cmp)				\
+struct type *								\
+name##_SPLAY_INSERT(struct name *head, struct type *elm)		\
+{									\
+    if (SPLAY_EMPTY(head)) {						\
+	    SPLAY_LEFT(elm, field) = SPLAY_RIGHT(elm, field) = NULL;	\
+    } else {								\
+	    int __comp;							\
+	    name##_SPLAY(head, elm);					\
+	    __comp = (cmp)(elm, (head)->sph_root);			\
+	    if(__comp < 0) {						\
+		    SPLAY_LEFT(elm, field) = SPLAY_LEFT((head)->sph_root, field);\
+		    SPLAY_RIGHT(elm, field) = (head)->sph_root;		\
+		    SPLAY_LEFT((head)->sph_root, field) = NULL;		\
+	    } else if (__comp > 0) {					\
+		    SPLAY_RIGHT(elm, field) = SPLAY_RIGHT((head)->sph_root, field);\
+		    SPLAY_LEFT(elm, field) = (head)->sph_root;		\
+		    SPLAY_RIGHT((head)->sph_root, field) = NULL;	\
+	    } else							\
+		    return ((head)->sph_root);				\
+    }									\
+    (head)->sph_root = (elm);						\
+    return (NULL);							\
+}									\
+									\
+struct type *								\
+name##_SPLAY_REMOVE(struct name *head, struct type *elm)		\
+{									\
+	struct type *__tmp;						\
+	if (SPLAY_EMPTY(head))						\
+		return (NULL);						\
+	name##_SPLAY(head, elm);					\
+	if ((cmp)(elm, (head)->sph_root) == 0) {			\
+		if (SPLAY_LEFT((head)->sph_root, field) == NULL) {	\
+			(head)->sph_root = SPLAY_RIGHT((head)->sph_root, field);\
+		} else {						\
+			__tmp = SPLAY_RIGHT((head)->sph_root, field);	\
+			(head)->sph_root = SPLAY_LEFT((head)->sph_root, field);\
+			name##_SPLAY(head, elm);			\
+			SPLAY_RIGHT((head)->sph_root, field) = __tmp;	\
+		}							\
+		return (elm);						\
+	}								\
+	return (NULL);							\
+}									\
+									\
+void									\
+name##_SPLAY(struct name *head, struct type *elm)			\
+{									\
+	struct type __node, *__left, *__right, *__tmp;			\
+	int __comp;							\
+\
+	SPLAY_LEFT(&__node, field) = SPLAY_RIGHT(&__node, field) = NULL;\
+	__left = __right = &__node;					\
+\
+	while ((__comp = (cmp)(elm, (head)->sph_root))) {		\
+		if (__comp < 0) {					\
+			__tmp = SPLAY_LEFT((head)->sph_root, field);	\
+			if (__tmp == NULL)				\
+				break;					\
+			if ((cmp)(elm, __tmp) < 0){			\
+				SPLAY_ROTATE_RIGHT(head, __tmp, field);	\
+				if (SPLAY_LEFT((head)->sph_root, field) == NULL)\
+					break;				\
+			}						\
+			SPLAY_LINKLEFT(head, __right, field);		\
+		} else if (__comp > 0) {				\
+			__tmp = SPLAY_RIGHT((head)->sph_root, field);	\
+			if (__tmp == NULL)				\
+				break;					\
+			if ((cmp)(elm, __tmp) > 0){			\
+				SPLAY_ROTATE_LEFT(head, __tmp, field);	\
+				if (SPLAY_RIGHT((head)->sph_root, field) == NULL)\
+					break;				\
+			}						\
+			SPLAY_LINKRIGHT(head, __left, field);		\
+		}							\
+	}								\
+	SPLAY_ASSEMBLE(head, &__node, __left, __right, field);		\
+}									\
+									\
+/* Splay with either the minimum or the maximum element			\
+ * Used to find minimum or maximum element in tree.			\
+ */									\
+void name##_SPLAY_MINMAX(struct name *head, int __comp) \
+{									\
+	struct type __node, *__left, *__right, *__tmp;			\
+\
+	SPLAY_LEFT(&__node, field) = SPLAY_RIGHT(&__node, field) = NULL;\
+	__left = __right = &__node;					\
+\
+	while (1) {							\
+		if (__comp < 0) {					\
+			__tmp = SPLAY_LEFT((head)->sph_root, field);	\
+			if (__tmp == NULL)				\
+				break;					\
+			if (__comp < 0){				\
+				SPLAY_ROTATE_RIGHT(head, __tmp, field);	\
+				if (SPLAY_LEFT((head)->sph_root, field) == NULL)\
+					break;				\
+			}						\
+			SPLAY_LINKLEFT(head, __right, field);		\
+		} else if (__comp > 0) {				\
+			__tmp = SPLAY_RIGHT((head)->sph_root, field);	\
+			if (__tmp == NULL)				\
+				break;					\
+			if (__comp > 0) {				\
+				SPLAY_ROTATE_LEFT(head, __tmp, field);	\
+				if (SPLAY_RIGHT((head)->sph_root, field) == NULL)\
+					break;				\
+			}						\
+			SPLAY_LINKRIGHT(head, __left, field);		\
+		}							\
+	}								\
+	SPLAY_ASSEMBLE(head, &__node, __left, __right, field);		\
+}
+
+#define SPLAY_NEGINF	-1
+#define SPLAY_INF	1
+
+#define SPLAY_INSERT(name, x, y)	name##_SPLAY_INSERT(x, y)
+#define SPLAY_REMOVE(name, x, y)	name##_SPLAY_REMOVE(x, y)
+#define SPLAY_FIND(name, x, y)		name##_SPLAY_FIND(x, y)
+#define SPLAY_NEXT(name, x, y)		name##_SPLAY_NEXT(x, y)
+#define SPLAY_MIN(name, x)		(SPLAY_EMPTY(x) ? NULL	\
+					: name##_SPLAY_MIN_MAX(x, SPLAY_NEGINF))
+#define SPLAY_MAX(name, x)		(SPLAY_EMPTY(x) ? NULL	\
+					: name##_SPLAY_MIN_MAX(x, SPLAY_INF))
+
+#define SPLAY_FOREACH(x, name, head)					\
+	for ((x) = SPLAY_MIN(name, head);				\
+	     (x) != NULL;						\
+	     (x) = SPLAY_NEXT(name, head, x))
+
+/* Macros that define a red-black tree */
+#define RB_HEAD(name, type)						\
+struct name {								\
+	struct type *rbh_root; /* root of the tree */			\
+}
+
+#define RB_INITIALIZER(root)						\
+	{ NULL }
+
+#define RB_INIT(root) do {						\
+	(root)->rbh_root = NULL;					\
+} while (0)
+
+#define RB_BLACK	0
+#define RB_RED		1
+#define RB_ENTRY(type)							\
+struct {								\
+	struct type *rbe_left;		/* left element */		\
+	struct type *rbe_right;		/* right element */		\
+	struct type *rbe_parent;	/* parent element */		\
+	int rbe_color;			/* node color */		\
+}
+
+#define RB_LEFT(elm, field)		(elm)->field.rbe_left
+#define RB_RIGHT(elm, field)		(elm)->field.rbe_right
+#define RB_PARENT(elm, field)		(elm)->field.rbe_parent
+#define RB_COLOR(elm, field)		(elm)->field.rbe_color
+#define RB_ROOT(head)			(head)->rbh_root
+#define RB_EMPTY(head)			(RB_ROOT(head) == NULL)
+
+#define RB_SET(elm, parent, field) do {					\
+	RB_PARENT(elm, field) = parent;					\
+	RB_LEFT(elm, field) = RB_RIGHT(elm, field) = NULL;		\
+	RB_COLOR(elm, field) = RB_RED;					\
+} while (0)
+
+#define RB_SET_BLACKRED(black, red, field) do {				\
+	RB_COLOR(black, field) = RB_BLACK;				\
+	RB_COLOR(red, field) = RB_RED;					\
+} while (0)
+
+#ifndef RB_AUGMENT
+#define RB_AUGMENT(x)	do {} while (0)
+#endif
+
+#define RB_ROTATE_LEFT(head, elm, tmp, field) do {			\
+	(tmp) = RB_RIGHT(elm, field);					\
+	if ((RB_RIGHT(elm, field) = RB_LEFT(tmp, field))) {		\
+		RB_PARENT(RB_LEFT(tmp, field), field) = (elm);		\
+	}								\
+	RB_AUGMENT(elm);						\
+	if ((RB_PARENT(tmp, field) = RB_PARENT(elm, field))) {		\
+		if ((elm) == RB_LEFT(RB_PARENT(elm, field), field))	\
+			RB_LEFT(RB_PARENT(elm, field), field) = (tmp);	\
+		else							\
+			RB_RIGHT(RB_PARENT(elm, field), field) = (tmp);	\
+	} else								\
+		(head)->rbh_root = (tmp);				\
+	RB_LEFT(tmp, field) = (elm);					\
+	RB_PARENT(elm, field) = (tmp);					\
+	RB_AUGMENT(tmp);						\
+	if ((RB_PARENT(tmp, field)))					\
+		RB_AUGMENT(RB_PARENT(tmp, field));			\
+} while (0)
+
+#define RB_ROTATE_RIGHT(head, elm, tmp, field) do {			\
+	(tmp) = RB_LEFT(elm, field);					\
+	if ((RB_LEFT(elm, field) = RB_RIGHT(tmp, field))) {		\
+		RB_PARENT(RB_RIGHT(tmp, field), field) = (elm);		\
+	}								\
+	RB_AUGMENT(elm);						\
+	if ((RB_PARENT(tmp, field) = RB_PARENT(elm, field))) {		\
+		if ((elm) == RB_LEFT(RB_PARENT(elm, field), field))	\
+			RB_LEFT(RB_PARENT(elm, field), field) = (tmp);	\
+		else							\
+			RB_RIGHT(RB_PARENT(elm, field), field) = (tmp);	\
+	} else								\
+		(head)->rbh_root = (tmp);				\
+	RB_RIGHT(tmp, field) = (elm);					\
+	RB_PARENT(elm, field) = (tmp);					\
+	RB_AUGMENT(tmp);						\
+	if ((RB_PARENT(tmp, field)))					\
+		RB_AUGMENT(RB_PARENT(tmp, field));			\
+} while (0)
+
+/* Generates prototypes and inline functions */
+#define	RB_PROTOTYPE(name, type, field, cmp)				\
+	RB_PROTOTYPE_INTERNAL(name, type, field, cmp,)
+#define	RB_PROTOTYPE_STATIC(name, type, field, cmp)			\
+	RB_PROTOTYPE_INTERNAL(name, type, field, cmp, __attribute__((__unused__)) static)
+#define RB_PROTOTYPE_INTERNAL(name, type, field, cmp, attr)		\
+attr void name##_RB_INSERT_COLOR(struct name *, struct type *);		\
+attr void name##_RB_REMOVE_COLOR(struct name *, struct type *, struct type *);\
+attr struct type *name##_RB_REMOVE(struct name *, struct type *);	\
+attr struct type *name##_RB_INSERT(struct name *, struct type *);	\
+attr struct type *name##_RB_FIND(struct name *, struct type *);		\
+attr struct type *name##_RB_NFIND(struct name *, struct type *);	\
+attr struct type *name##_RB_NEXT(struct type *);			\
+attr struct type *name##_RB_PREV(struct type *);			\
+attr struct type *name##_RB_MINMAX(struct name *, int);			\
+									\
+
+/* Main rb operation.
+ * Moves node close to the key of elm to top
+ */
+#define	RB_GENERATE(name, type, field, cmp)				\
+	RB_GENERATE_INTERNAL(name, type, field, cmp,)
+#define	RB_GENERATE_STATIC(name, type, field, cmp)			\
+	RB_GENERATE_INTERNAL(name, type, field, cmp, __attribute__((__unused__)) static)
+#define RB_GENERATE_INTERNAL(name, type, field, cmp, attr)		\
+attr void								\
+name##_RB_INSERT_COLOR(struct name *head, struct type *elm)		\
+{									\
+	struct type *parent, *gparent, *tmp;				\
+	while ((parent = RB_PARENT(elm, field)) &&			\
+	    RB_COLOR(parent, field) == RB_RED) {			\
+		gparent = RB_PARENT(parent, field);			\
+		if (parent == RB_LEFT(gparent, field)) {		\
+			tmp = RB_RIGHT(gparent, field);			\
+			if (tmp && RB_COLOR(tmp, field) == RB_RED) {	\
+				RB_COLOR(tmp, field) = RB_BLACK;	\
+				RB_SET_BLACKRED(parent, gparent, field);\
+				elm = gparent;				\
+				continue;				\
+			}						\
+			if (RB_RIGHT(parent, field) == elm) {		\
+				RB_ROTATE_LEFT(head, parent, tmp, field);\
+				tmp = parent;				\
+				parent = elm;				\
+				elm = tmp;				\
+			}						\
+			RB_SET_BLACKRED(parent, gparent, field);	\
+			RB_ROTATE_RIGHT(head, gparent, tmp, field);	\
+		} else {						\
+			tmp = RB_LEFT(gparent, field);			\
+			if (tmp && RB_COLOR(tmp, field) == RB_RED) {	\
+				RB_COLOR(tmp, field) = RB_BLACK;	\
+				RB_SET_BLACKRED(parent, gparent, field);\
+				elm = gparent;				\
+				continue;				\
+			}						\
+			if (RB_LEFT(parent, field) == elm) {		\
+				RB_ROTATE_RIGHT(head, parent, tmp, field);\
+				tmp = parent;				\
+				parent = elm;				\
+				elm = tmp;				\
+			}						\
+			RB_SET_BLACKRED(parent, gparent, field);	\
+			RB_ROTATE_LEFT(head, gparent, tmp, field);	\
+		}							\
+	}								\
+	RB_COLOR(head->rbh_root, field) = RB_BLACK;			\
+}									\
+									\
+attr void								\
+name##_RB_REMOVE_COLOR(struct name *head, struct type *parent, struct type *elm) \
+{									\
+	struct type *tmp;						\
+	while ((elm == NULL || RB_COLOR(elm, field) == RB_BLACK) &&	\
+	    elm != RB_ROOT(head)) {					\
+		if (RB_LEFT(parent, field) == elm) {			\
+			tmp = RB_RIGHT(parent, field);			\
+			if (RB_COLOR(tmp, field) == RB_RED) {		\
+				RB_SET_BLACKRED(tmp, parent, field);	\
+				RB_ROTATE_LEFT(head, parent, tmp, field);\
+				tmp = RB_RIGHT(parent, field);		\
+			}						\
+			if ((RB_LEFT(tmp, field) == NULL ||		\
+			    RB_COLOR(RB_LEFT(tmp, field), field) == RB_BLACK) &&\
+			    (RB_RIGHT(tmp, field) == NULL ||		\
+			    RB_COLOR(RB_RIGHT(tmp, field), field) == RB_BLACK)) {\
+				RB_COLOR(tmp, field) = RB_RED;		\
+				elm = parent;				\
+				parent = RB_PARENT(elm, field);		\
+			} else {					\
+				if (RB_RIGHT(tmp, field) == NULL ||	\
+				    RB_COLOR(RB_RIGHT(tmp, field), field) == RB_BLACK) {\
+					struct type *oleft;		\
+					if ((oleft = RB_LEFT(tmp, field)))\
+						RB_COLOR(oleft, field) = RB_BLACK;\
+					RB_COLOR(tmp, field) = RB_RED;	\
+					RB_ROTATE_RIGHT(head, tmp, oleft, field);\
+					tmp = RB_RIGHT(parent, field);	\
+				}					\
+				RB_COLOR(tmp, field) = RB_COLOR(parent, field);\
+				RB_COLOR(parent, field) = RB_BLACK;	\
+				if (RB_RIGHT(tmp, field))		\
+					RB_COLOR(RB_RIGHT(tmp, field), field) = RB_BLACK;\
+				RB_ROTATE_LEFT(head, parent, tmp, field);\
+				elm = RB_ROOT(head);			\
+				break;					\
+			}						\
+		} else {						\
+			tmp = RB_LEFT(parent, field);			\
+			if (RB_COLOR(tmp, field) == RB_RED) {		\
+				RB_SET_BLACKRED(tmp, parent, field);	\
+				RB_ROTATE_RIGHT(head, parent, tmp, field);\
+				tmp = RB_LEFT(parent, field);		\
+			}						\
+			if ((RB_LEFT(tmp, field) == NULL ||		\
+			    RB_COLOR(RB_LEFT(tmp, field), field) == RB_BLACK) &&\
+			    (RB_RIGHT(tmp, field) == NULL ||		\
+			    RB_COLOR(RB_RIGHT(tmp, field), field) == RB_BLACK)) {\
+				RB_COLOR(tmp, field) = RB_RED;		\
+				elm = parent;				\
+				parent = RB_PARENT(elm, field);		\
+			} else {					\
+				if (RB_LEFT(tmp, field) == NULL ||	\
+				    RB_COLOR(RB_LEFT(tmp, field), field) == RB_BLACK) {\
+					struct type *oright;		\
+					if ((oright = RB_RIGHT(tmp, field)))\
+						RB_COLOR(oright, field) = RB_BLACK;\
+					RB_COLOR(tmp, field) = RB_RED;	\
+					RB_ROTATE_LEFT(head, tmp, oright, field);\
+					tmp = RB_LEFT(parent, field);	\
+				}					\
+				RB_COLOR(tmp, field) = RB_COLOR(parent, field);\
+				RB_COLOR(parent, field) = RB_BLACK;	\
+				if (RB_LEFT(tmp, field))		\
+					RB_COLOR(RB_LEFT(tmp, field), field) = RB_BLACK;\
+				RB_ROTATE_RIGHT(head, parent, tmp, field);\
+				elm = RB_ROOT(head);			\
+				break;					\
+			}						\
+		}							\
+	}								\
+	if (elm)							\
+		RB_COLOR(elm, field) = RB_BLACK;			\
+}									\
+									\
+attr struct type *							\
+name##_RB_REMOVE(struct name *head, struct type *elm)			\
+{									\
+	struct type *child, *parent, *old = elm;			\
+	int color;							\
+	if (RB_LEFT(elm, field) == NULL)				\
+		child = RB_RIGHT(elm, field);				\
+	else if (RB_RIGHT(elm, field) == NULL)				\
+		child = RB_LEFT(elm, field);				\
+	else {								\
+		struct type *left;					\
+		elm = RB_RIGHT(elm, field);				\
+		while ((left = RB_LEFT(elm, field)))			\
+			elm = left;					\
+		child = RB_RIGHT(elm, field);				\
+		parent = RB_PARENT(elm, field);				\
+		color = RB_COLOR(elm, field);				\
+		if (child)						\
+			RB_PARENT(child, field) = parent;		\
+		if (parent) {						\
+			if (RB_LEFT(parent, field) == elm)		\
+				RB_LEFT(parent, field) = child;		\
+			else						\
+				RB_RIGHT(parent, field) = child;	\
+			RB_AUGMENT(parent);				\
+		} else							\
+			RB_ROOT(head) = child;				\
+		if (RB_PARENT(elm, field) == old)			\
+			parent = elm;					\
+		(elm)->field = (old)->field;				\
+		if (RB_PARENT(old, field)) {				\
+			if (RB_LEFT(RB_PARENT(old, field), field) == old)\
+				RB_LEFT(RB_PARENT(old, field), field) = elm;\
+			else						\
+				RB_RIGHT(RB_PARENT(old, field), field) = elm;\
+			RB_AUGMENT(RB_PARENT(old, field));		\
+		} else							\
+			RB_ROOT(head) = elm;				\
+		RB_PARENT(RB_LEFT(old, field), field) = elm;		\
+		if (RB_RIGHT(old, field))				\
+			RB_PARENT(RB_RIGHT(old, field), field) = elm;	\
+		if (parent) {						\
+			left = parent;					\
+			do {						\
+				RB_AUGMENT(left);			\
+			} while ((left = RB_PARENT(left, field)));	\
+		}							\
+		goto color;						\
+	}								\
+	parent = RB_PARENT(elm, field);					\
+	color = RB_COLOR(elm, field);					\
+	if (child)							\
+		RB_PARENT(child, field) = parent;			\
+	if (parent) {							\
+		if (RB_LEFT(parent, field) == elm)			\
+			RB_LEFT(parent, field) = child;			\
+		else							\
+			RB_RIGHT(parent, field) = child;		\
+		RB_AUGMENT(parent);					\
+	} else								\
+		RB_ROOT(head) = child;					\
+color:									\
+	if (color == RB_BLACK)						\
+		name##_RB_REMOVE_COLOR(head, parent, child);		\
+	return (old);							\
+}									\
+									\
+/* Inserts a node into the RB tree */					\
+attr struct type *							\
+name##_RB_INSERT(struct name *head, struct type *elm)			\
+{									\
+	struct type *tmp;						\
+	struct type *parent = NULL;					\
+	int comp = 0;							\
+	tmp = RB_ROOT(head);						\
+	while (tmp) {							\
+		parent = tmp;						\
+		comp = (cmp)(elm, parent);				\
+		if (comp < 0)						\
+			tmp = RB_LEFT(tmp, field);			\
+		else if (comp > 0)					\
+			tmp = RB_RIGHT(tmp, field);			\
+		else							\
+			return (tmp);					\
+	}								\
+	RB_SET(elm, parent, field);					\
+	if (parent != NULL) {						\
+		if (comp < 0)						\
+			RB_LEFT(parent, field) = elm;			\
+		else							\
+			RB_RIGHT(parent, field) = elm;			\
+		RB_AUGMENT(parent);					\
+	} else								\
+		RB_ROOT(head) = elm;					\
+	name##_RB_INSERT_COLOR(head, elm);				\
+	return (NULL);							\
+}									\
+									\
+/* Finds the node with the same key as elm */				\
+attr struct type *							\
+name##_RB_FIND(struct name *head, struct type *elm)			\
+{									\
+	struct type *tmp = RB_ROOT(head);				\
+	int comp;							\
+	while (tmp) {							\
+		comp = cmp(elm, tmp);					\
+		if (comp < 0)						\
+			tmp = RB_LEFT(tmp, field);			\
+		else if (comp > 0)					\
+			tmp = RB_RIGHT(tmp, field);			\
+		else							\
+			return (tmp);					\
+	}								\
+	return (NULL);							\
+}									\
+									\
+/* Finds the first node greater than or equal to the search key */	\
+attr struct type *							\
+name##_RB_NFIND(struct name *head, struct type *elm)			\
+{									\
+	struct type *tmp = RB_ROOT(head);				\
+	struct type *res = NULL;					\
+	int comp;							\
+	while (tmp) {							\
+		comp = cmp(elm, tmp);					\
+		if (comp < 0) {						\
+			res = tmp;					\
+			tmp = RB_LEFT(tmp, field);			\
+		}							\
+		else if (comp > 0)					\
+			tmp = RB_RIGHT(tmp, field);			\
+		else							\
+			return (tmp);					\
+	}								\
+	return (res);							\
+}									\
+									\
+/* ARGSUSED */								\
+attr struct type *							\
+name##_RB_NEXT(struct type *elm)					\
+{									\
+	if (RB_RIGHT(elm, field)) {					\
+		elm = RB_RIGHT(elm, field);				\
+		while (RB_LEFT(elm, field))				\
+			elm = RB_LEFT(elm, field);			\
+	} else {							\
+		if (RB_PARENT(elm, field) &&				\
+		    (elm == RB_LEFT(RB_PARENT(elm, field), field)))	\
+			elm = RB_PARENT(elm, field);			\
+		else {							\
+			while (RB_PARENT(elm, field) &&			\
+			    (elm == RB_RIGHT(RB_PARENT(elm, field), field)))\
+				elm = RB_PARENT(elm, field);		\
+			elm = RB_PARENT(elm, field);			\
+		}							\
+	}								\
+	return (elm);							\
+}									\
+									\
+/* ARGSUSED */								\
+attr struct type *							\
+name##_RB_PREV(struct type *elm)					\
+{									\
+	if (RB_LEFT(elm, field)) {					\
+		elm = RB_LEFT(elm, field);				\
+		while (RB_RIGHT(elm, field))				\
+			elm = RB_RIGHT(elm, field);			\
+	} else {							\
+		if (RB_PARENT(elm, field) &&				\
+		    (elm == RB_RIGHT(RB_PARENT(elm, field), field)))	\
+			elm = RB_PARENT(elm, field);			\
+		else {							\
+			while (RB_PARENT(elm, field) &&			\
+			    (elm == RB_LEFT(RB_PARENT(elm, field), field)))\
+				elm = RB_PARENT(elm, field);		\
+			elm = RB_PARENT(elm, field);			\
+		}							\
+	}								\
+	return (elm);							\
+}									\
+									\
+attr struct type *							\
+name##_RB_MINMAX(struct name *head, int val)				\
+{									\
+	struct type *tmp = RB_ROOT(head);				\
+	struct type *parent = NULL;					\
+	while (tmp) {							\
+		parent = tmp;						\
+		if (val < 0)						\
+			tmp = RB_LEFT(tmp, field);			\
+		else							\
+			tmp = RB_RIGHT(tmp, field);			\
+	}								\
+	return (parent);						\
+}
+
+#define RB_NEGINF	-1
+#define RB_INF	1
+
+#define RB_INSERT(name, x, y)	name##_RB_INSERT(x, y)
+#define RB_REMOVE(name, x, y)	name##_RB_REMOVE(x, y)
+#define RB_FIND(name, x, y)	name##_RB_FIND(x, y)
+#define RB_NFIND(name, x, y)	name##_RB_NFIND(x, y)
+#define RB_NEXT(name, x, y)	name##_RB_NEXT(y)
+#define RB_PREV(name, x, y)	name##_RB_PREV(y)
+#define RB_MIN(name, x)		name##_RB_MINMAX(x, RB_NEGINF)
+#define RB_MAX(name, x)		name##_RB_MINMAX(x, RB_INF)
+
+#define RB_FOREACH(x, name, head)					\
+	for ((x) = RB_MIN(name, head);					\
+	     (x) != NULL;						\
+	     (x) = name##_RB_NEXT(x))
+
+#define RB_FOREACH_SAFE(x, name, head, y)				\
+	for ((x) = RB_MIN(name, head);					\
+	    ((x) != NULL) && ((y) = name##_RB_NEXT(x), 1);		\
+	     (x) = (y))
+
+#define RB_FOREACH_REVERSE(x, name, head)				\
+	for ((x) = RB_MAX(name, head);					\
+	     (x) != NULL;						\
+	     (x) = name##_RB_PREV(x))
+
+#define RB_FOREACH_REVERSE_SAFE(x, name, head, y)			\
+	for ((x) = RB_MAX(name, head);					\
+	    ((x) != NULL) && ((y) = name##_RB_PREV(x), 1);		\
+	     (x) = (y))
+
+#endif	/* _SYS_TREE_H_ */
blob - /dev/null
blob + a414fb2d276993a728b2857a8ee2ce9bc6a0fea6 (mode 644)
--- /dev/null
+++ compat/uuid.c
@@ -0,0 +1,39 @@
+#include <stdlib.h>
+#include <string.h>
+#include <stdint.h>
+#include <uuid/uuid.h>
+
+#include "got_compat.h"
+
+
+int32_t uuid_equal(struct uuid* a, struct uuid* b, uint32_t* unused)
+{
+	return (uuid_compare(*(uuid_t *)a, *(uuid_t *)b) == 0);
+}
+int32_t uuid_is_nil(struct uuid* uuid, uint32_t* unused)
+{
+	return uuid_is_null(*(uuid_t *)uuid);
+}
+void uuid_create(uuid_t *uuid, uint32_t* status)
+{
+	*status = uuid_s_ok;
+	return uuid_generate(*(uuid_t *)uuid);
+}
+void uuid_create_nil(struct uuid* uuid, uint32_t* unused)
+{
+	return uuid_clear(*(uuid_t *)uuid);
+}
+void uuid_from_string(const char* s, uuid_t *uuid, uint32_t *status)
+{
+  	*status = uuid_parse(s, *(uuid_t *)uuid);
+}
+void uuid_to_string(uuid_t *uuid, char** s, uint32_t *status)
+{
+	*s = malloc(36 + 1);  /* 36 byte uuid plus '\0' */
+	if (*s == NULL) {
+		fprintf(stderr, "uuid_to_string: fatal: malloc\n");
+		exit (1);
+	}
+	uuid_unparse(*(uuid_t *)uuid, *s);
+	*status = uuid_s_ok;
+}
blob - /dev/null
blob + 4cb3fee954c0994f90c6ad916cce9abc291f8614 (mode 644)
--- /dev/null
+++ compat/xmalloc.c
@@ -0,0 +1,185 @@
+/* $OpenBSD$ */
+
+/*
+ * Author: Tatu Ylonen <ylo@cs.hut.fi>
+ * Copyright (c) 1995 Tatu Ylonen <ylo@cs.hut.fi>, Espoo, Finland
+ *                    All rights reserved
+ * Versions of malloc and friends that check their results, and never return
+ * failure (they call fatalx if they encounter an error).
+ *
+ * As far as I am concerned, the code I have written for this software
+ * can be used freely for any purpose.  Any derived versions of this
+ * software must be clearly marked as such, and if the derived work is
+ * incompatible with the protocol description in the RFC file, it must be
+ * called by a name other than "ssh" or "Secure Shell".
+ */
+
+#include <errno.h>
+#include <limits.h>
+#include <stdint.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+
+#include "got_compat.h"
+
+#include "xmalloc.h"
+
+void *
+xmalloc(size_t size)
+{
+	void *ptr;
+
+	if (size == 0) {
+		fprintf(stderr,"xmalloc: zero size");
+		exit (1);
+	}
+	ptr = malloc(size);
+	if (ptr == NULL) {
+		fprintf(stderr, "xmalloc: allocating %zu bytes: %s",
+		    size, strerror(errno));
+		exit (1);
+	}
+	return ptr;
+}
+
+void *
+xcalloc(size_t nmemb, size_t size)
+{
+	void *ptr;
+
+	if (size == 0 || nmemb == 0)
+		fprintf(stderr,"xcalloc: zero size");
+	ptr = calloc(nmemb, size);
+	if (ptr == NULL) {
+		fprintf(stderr, "xcalloc: allocating %zu * %zu bytes: %s",
+		    nmemb, size, strerror(errno));
+		exit (1);
+	}
+	return ptr;
+}
+
+void *
+xrealloc(void *ptr, size_t size)
+{
+	return xreallocarray(ptr, 1, size);
+}
+
+void *
+xreallocarray(void *ptr, size_t nmemb, size_t size)
+{
+	void *new_ptr;
+
+	if (nmemb == 0 || size == 0) {
+		fprintf(stderr, "xreallocarray: zero size");
+		exit (1);
+	}
+	new_ptr = reallocarray(ptr, nmemb, size);
+	if (new_ptr == NULL) {
+		fprintf(stderr, "xreallocarray: allocating %zu * %zu bytes: %s",
+		    nmemb, size, strerror(errno));
+		exit (1);
+	}
+	return new_ptr;
+}
+
+void *
+xrecallocarray(void *ptr, size_t oldnmemb, size_t nmemb, size_t size)
+{
+	void *new_ptr;
+
+	if (nmemb == 0 || size == 0) {
+		fprintf(stderr,"xrecallocarray: zero size");
+		exit (1);
+	}
+	new_ptr = recallocarray(ptr, oldnmemb, nmemb, size);
+	if (new_ptr == NULL) {
+		fprintf(stderr,"xrecallocarray: allocating %zu * %zu bytes: %s",
+		    nmemb, size, strerror(errno));
+		exit (1);
+	}
+	return new_ptr;
+}
+
+char *
+xstrdup(const char *str)
+{
+	char *cp;
+
+	if ((cp = strdup(str)) == NULL) {
+		fprintf(stderr,"xstrdup: %s", strerror(errno));
+		exit (1);
+	}
+	return cp;
+}
+
+char *
+xstrndup(const char *str, size_t maxlen)
+{
+	char *cp;
+
+	if ((cp = strndup(str, maxlen)) == NULL) {
+		fprintf(stderr,"xstrndup: %s", strerror(errno));
+		exit (1);
+	}
+	return cp;
+}
+
+int
+xasprintf(char **ret, const char *fmt, ...)
+{
+	va_list ap;
+	int i;
+
+	va_start(ap, fmt);
+	i = xvasprintf(ret, fmt, ap);
+	va_end(ap);
+
+	return i;
+}
+
+int
+xvasprintf(char **ret, const char *fmt, va_list ap)
+{
+	int i;
+
+	i = vasprintf(ret, fmt, ap);
+
+	if (i == -1) {
+		fprintf(stderr,"xasprintf: %s", strerror(errno));
+		exit  (1);
+	}
+
+	return i;
+}
+
+int
+xsnprintf(char *str, size_t len, const char *fmt, ...)
+{
+	va_list ap;
+	int i;
+
+	va_start(ap, fmt);
+	i = xvsnprintf(str, len, fmt, ap);
+	va_end(ap);
+
+	return i;
+}
+
+int
+xvsnprintf(char *str, size_t len, const char *fmt, va_list ap)
+{
+	int i;
+
+	if (len > INT_MAX)
+		fprintf(stderr,"xsnprintf: len > INT_MAX");
+
+	i = vsnprintf(str, len, fmt, ap);
+
+	if (i < 0 || i >= (int)len) {
+		fprintf(stderr,"xsnprintf: overflow");
+		exit (1);
+	}
+
+	return i;
+}
blob - /dev/null
blob + 82a5624e6cff0daddb85ad48d75031abf9d728f0 (mode 644)
--- /dev/null
+++ compat/xmalloc.h
@@ -0,0 +1,48 @@
+/* $OpenBSD$ */
+
+/*
+ * Author: Tatu Ylonen <ylo@cs.hut.fi>
+ * Copyright (c) 1995 Tatu Ylonen <ylo@cs.hut.fi>, Espoo, Finland
+ *                    All rights reserved
+ * Created: Mon Mar 20 22:09:17 1995 ylo
+ *
+ * Versions of malloc and friends that check their results, and never return
+ * failure (they call fatal if they encounter an error).
+ *
+ * As far as I am concerned, the code I have written for this software
+ * can be used freely for any purpose.  Any derived versions of this
+ * software must be clearly marked as such, and if the derived work is
+ * incompatible with the protocol description in the RFC file, it must be
+ * called by a name other than "ssh" or "Secure Shell".
+ */
+
+#ifndef XMALLOC_H
+#define XMALLOC_H
+
+#include <stdarg.h>
+
+#if !defined(__bounded__)
+#define __bounded__(x, y, z)
+#endif
+
+void	*xmalloc(size_t);
+void	*xcalloc(size_t, size_t);
+void	*xrealloc(void *, size_t);
+void	*xreallocarray(void *, size_t, size_t);
+void	*xrecallocarray(void *, size_t, size_t, size_t);
+char	*xstrdup(const char *);
+char	*xstrndup(const char *, size_t);
+int	 xasprintf(char **, const char *, ...)
+		__attribute__((__format__ (printf, 2, 3)))
+		__attribute__((__nonnull__ (2)));
+int	 xvasprintf(char **, const char *, va_list)
+		__attribute__((__nonnull__ (2)));
+int	 xsnprintf(char *, size_t, const char *, ...)
+		__attribute__((__format__ (printf, 3, 4)))
+		__attribute__((__nonnull__ (3)))
+		__attribute__((__bounded__ (__string__, 1, 2)));
+int	 xvsnprintf(char *, size_t, const char *, va_list)
+		__attribute__((__nonnull__ (3)))
+		__attribute__((__bounded__ (__string__, 1, 2)));
+
+#endif	/* XMALLOC_H */
blob - /dev/null
blob + 4a32b53176f07eed16b613bb85a0eaa5ff2bfb65 (mode 644)
--- /dev/null
+++ configure.ac
@@ -0,0 +1,431 @@
+# Process this file with autoconf to produce a configure script.
+
+AC_PREREQ([2.69])
+AC_INIT([got-portable], [0.47], [thomas@xteddy.org])
+AC_CONFIG_AUX_DIR(etc)
+AC_CONFIG_SRCDIR([lib/rcsutil.h])
+AM_INIT_AUTOMAKE([foreign subdir-objects])
+
+GOT_RELEASE=No
+
+AC_DEFINE_UNQUOTED(VERSION, "$VERSION")
+AC_SUBST(VERSION)
+AC_SUBST(GOT_RELEASE)
+
+AC_CANONICAL_HOST
+
+# When CFLAGS isn't set at this stage and gcc is detected by the macro below,
+# autoconf will automatically use CFLAGS="-O2 -g". Prevent that by using an
+# empty default.
+: ${CFLAGS=""}
+
+# Save user CPPFLAGS, CFLAGS and LDFLAGS. We need to change them because
+# AC_CHECK_HEADER doesn't give us any other way to update the include
+# paths. But for Makefile.am we want to use AM_CPPFLAGS and friends.
+SAVED_CFLAGS="$CFLAGS"
+SAVED_CPPFLAGS="$CPPFLAGS"
+SAVED_LDFLAGS="$LDFLAGS"
+
+# Checks for programs.
+AC_PROG_CC
+AC_PROG_CPP
+AC_PROG_INSTALL
+AC_PROG_LN_S
+AC_PROG_MAKE_SET
+AC_PROG_YACC
+AC_PROG_RANLIB
+PKG_PROG_PKG_CONFIG
+AC_USE_SYSTEM_EXTENSIONS
+
+# Checks for header files.
+AC_CHECK_HEADERS([ \
+	fcntl.h \
+	langinfo.h \
+	limits.h \
+	locale.h \
+	netdb.h \
+	netinet/in.h \
+	paths.h \
+	stddef.h \
+	stdint.h \
+	stdlib.h \
+	string.h \
+	sys/ioctl.h \
+	sys/param.h \
+	sys/socket.h \
+	sys/time.h \
+	sys/tree.h \
+	util.h \
+	unistd.h \
+	wchar.h \
+])
+
+# Checks for typ edefs, structures, and compiler characteristics.
+AC_CHECK_HEADER_STDBOOL
+AC_C_INLINE
+AC_TYPE_INT64_T
+AC_TYPE_MODE_T
+AC_TYPE_OFF_T
+AC_TYPE_PID_T
+AC_TYPE_SIZE_T
+AC_TYPE_SSIZE_T
+AC_TYPE_UINT16_T
+AC_TYPE_UINT32_T
+AC_TYPE_UINT64_T
+AC_TYPE_UINT8_T
+
+# Look for library needed for flock.
+AC_SEARCH_LIBS(flock, bsd)
+
+# Checks for library functions.
+AC_FUNC_FORK
+AC_FUNC_FSEEKO
+AC_FUNC_LSTAT_FOLLOWS_SLASHED_SYMLINK
+AC_FUNC_MALLOC
+AC_FUNC_MMAP
+AC_FUNC_REALLOC
+AC_FUNC_STRERROR_R
+AC_FUNC_STRNLEN
+AC_CHECK_FUNCS([ \
+	dup2 \
+	flock \
+	getcwd \
+	localtime_r \
+	memchr \
+	memmove \
+	memset \
+	mkdir \
+	munmap \
+	nl_langinfo \
+	realpath \
+	regcomp \
+	rmdir \
+	setlocale \
+	socket \
+	strcasecmp \
+	strchr \
+	strcspn \
+	strdup \
+	strerror \
+	strlcpy \
+	strncasecmp \
+	strndup \
+	strrchr \
+	strspn \
+	strstr \
+	strtol \
+	strtoul \
+	wcwidth \
+])
+
+# Check for functions with a compatibility implementation.
+AC_REPLACE_FUNCS([ \
+	asprintf \
+	closefrom \
+	explicit_bzero \
+	fmt_scaled \
+	freezero \
+	getdtablecount \
+	getline \
+	getprogname \
+	recallocarray \
+	reallocarray \
+	strlcat \
+	strlcpy \
+	strndup \
+	strsep \
+	strtonum \
+])
+
+# Always use our getopt because 1) glibc's doesn't enforce argument order 2)
+# musl does not set optarg to NULL for flags without arguments (although it is
+# not required to, but it is helpful) 3) there are probably other weird
+# implementations.
+AC_LIBOBJ(getopt)
+
+# Clang sanitizers wrap reallocarray even if it isn't available on the target
+# system. When compiled it always returns NULL and crashes the program. To
+# detect this we need a more complicated test.
+AC_MSG_CHECKING([for working reallocarray])
+AC_RUN_IFELSE([AC_LANG_PROGRAM(
+		[#include <stdlib.h>],
+		[return (reallocarray(NULL, 1, 1) == NULL);]
+	)],
+	AC_MSG_RESULT(yes),
+	[AC_LIBOBJ(reallocarray) AC_MSG_RESULT([no])]
+)
+AC_MSG_CHECKING([for working recallocarray])
+AC_RUN_IFELSE([AC_LANG_PROGRAM(
+		[#include <stdlib.h>],
+		[return (recallocarray(NULL, 1, 1, 1) == NULL);]
+	)],
+	AC_MSG_RESULT(yes),
+	[AC_LIBOBJ(recallocarray) AC_MSG_RESULT([no])]
+)
+
+# Look for imsg_init in libutil.
+AC_SEARCH_LIBS(imsg_init, util, found_imsg_init=yes, found_imsg_init=no)
+if test "x$found_imsg_init" = xyes; then
+	AC_DEFINE(HAVE_IMSG)
+else
+	AC_LIBOBJ(imsg)
+	AC_LIBOBJ(imsg-buffer)
+fi
+
+# libcrypto (via libssl for SHA information)
+PKG_CHECK_MODULES(
+	LIBCRYPTO,
+	libcrypto,
+	[
+	 	AM_CFLAGS="$LIBCRYTPO_CFLAGS $AM_CFLAGS"
+		CFLAGS="$AM_CFLAGS $SAVED_CFLAGS"
+		LIBS="$LIBCRYPTO_LIBS $LIBS"
+		found_libcrypto=yes
+	],
+	[
+	 	AC_MSG_ERROR("*** couldn't find libcrypto via pkg-config")
+	]
+)
+
+AC_SEARCH_LIBS(uuid_create, , AC_DEFINE(HAVE_BSD_UUID))
+AC_SEARCH_LIBS(mergesort, , AC_DEFINE(HAVE_BSD_MERGESORT))
+
+PKG_CHECK_MODULES(
+	LIBUUID,
+	uuid,
+	[
+	 	AM_CFLAGS="$LIBUUID_CFLAGS $AM_CFLAGS"
+		CFLAGS="$AM_CFLAGS $SAVED_CFLAGS"
+		LIBS="$LIBUUID_LIBS $LIBS"
+		found_libuuid=yes
+	],
+	[
+	 	AC_MSG_ERROR("*** couldn't find libuuid via pkg-config")
+	]
+)
+
+
+PKG_CHECK_MODULES(
+	ZLIB,
+	zlib,
+	[
+	 	AM_CFLAGS="$ZLIB_CFLAGS $AM_CFLAGS"
+		CFLAGS="$AM_CFLAGS $SAVED_CFLAGS"
+		LIBS="$ZLIB_LIBS $LIBS"
+		found_zlib=yes
+	],
+	[
+	 	AC_MSG_ERROR("*** couldn't find zlib via pkg-config")
+	]
+)
+
+PKG_CHECK_MODULES(
+	LIBMD,
+	libmd,
+	[
+	 	AM_CFLAGS="$LIBMD_CFLAGS $AM_CFLAGS"
+		CFLAGS="$AM_CFLAGS $SAVED_CFLAGS"
+		LIBS="$LIBMD_LIBS $LIBS"
+	],
+	[
+	 	AC_MSG_ERROR("*** couldn't find libmd via pkg-config")
+	]
+)
+# libmd (uuid)
+# imsg
+# libbsd (some portability gloop)
+# lssl
+# lz
+# ldl *
+# rdynamic *
+
+# Check if libbsd is installed -- if we can use that version of sys/tree.h or
+# our own if not.
+PKG_CHECK_MODULES(
+	LIBBSD,
+	libbsd-overlay,
+	[
+		AM_CFLAGS="$LIBBSD_CFLAGS $AM_CFLAGS"
+		CFLAGS="$AM_CFLAGS $SAVED_CFLAGS"
+		LIBS="$LIBBSD_LIBS $LIBS"
+		found_libbsd=yes
+		AC_DEFINE(HAVE_LIBBSD)
+	],
+	[]
+)
+
+# Look for a suitable queue.h.  We hope libbsd is enough, but that is missing
+# SIMPLEQ.
+AC_CHECK_DECL(
+	SIMPLEQ_INIT,
+	found_queue_h=yes,
+	found_queue_h=no,
+	[#include <sys/queue.h>]
+)
+AC_CHECK_DECL(
+	TAILQ_CONCAT,
+	found_queue_h=yes,
+	found_queue_h=no,
+	[#include <sys/queue.h>]
+)
+AC_CHECK_DECL(
+	TAILQ_PREV,
+	found_queue_h=yes,
+	found_queue_h=no,
+	[#include <sys/queue.h>]
+)
+AC_CHECK_DECL(
+	TAILQ_REPLACE,
+	found_queue_h=yes,
+	found_queue_h=no,
+	[#include <sys/queue.h>]
+)
+AC_CHECK_DECL(
+	SIMPLEQ_ENTRY,
+	,
+	found_queue_h=no,
+	[#include <sys/queue.h>]
+)
+AC_CHECK_DECL(
+	TAILQ_FOREACH_SAFE,
+	,
+	found_queue_h=no,
+	[#include <sys/queue.h>]
+)
+if test "x$found_queue_h" = xyes; then
+	AC_DEFINE(HAVE_QUEUE_H)
+fi
+
+# Look for __progname.
+AC_MSG_CHECKING(for __progname)
+AC_LINK_IFELSE([AC_LANG_SOURCE(
+	[
+		#include <stdio.h>
+		#include <stdlib.h>
+		extern char *__progname;
+		int main(void) {
+			const char *cp = __progname;
+			printf("%s\n", cp);
+			exit(0);
+		}
+	])],
+	[AC_DEFINE(HAVE___PROGNAME) AC_MSG_RESULT(yes)],
+	AC_MSG_RESULT(no)
+)
+
+# Look for ncurses.
+PKG_CHECK_MODULES(
+	LIBTINFO,
+	tinfo,
+	found_ncurses=yes,
+	found_ncurses=no
+)
+if test "x$found_ncurses" = xno; then
+	PKG_CHECK_MODULES(
+		LIBNCURSES,
+		ncurses,
+		found_ncurses=yes,
+		found_ncurses=no
+	)
+fi
+if test "x$found_ncurses" = xno; then
+	PKG_CHECK_MODULES(
+		LIBNCURSES,
+		ncursesw,
+		found_ncurses=yes,
+		found_ncurses=no
+	)
+fi
+if test "x$found_ncurses" = xyes; then
+	AM_CFLAGS="$LIBNCURSES_CFLAGS $LIBTINFO_CFLAGS $AM_CFLAGS"
+	CFLAGS="$LIBNCURSES_CFLAGS $LIBTINFO_CFLAGS $CFLAGS"
+	LIBS="$LIBNCURSES_LIBS $LIBTINFO_LIBS $LIBS"
+else
+	# pkg-config didn't work, try ncurses.
+	AC_CHECK_LIB(
+		tinfo,
+		setupterm,
+		found_ncurses=yes,
+		found_ncurses=no
+	)
+	if test "x$found_ncurses" = xno; then
+		AC_CHECK_LIB(
+			ncurses,
+			setupterm,
+			found_ncurses=yes,
+			found_ncurses=no
+		)
+	fi
+	if test "x$found_ncurses" = xyes; then
+		AC_CHECK_HEADER(
+			ncurses.h,
+			LIBS="$LIBS -lncurses",
+			found_ncurses=no)
+	fi
+fi
+if test "x$found_ncurses" = xyes; then
+	AC_DEFINE(HAVE_NCURSES_H)
+else
+	# No ncurses, try curses.
+	AC_CHECK_LIB(
+		curses,
+		setupterm,
+		found_curses=yes,
+		found_curses=no
+	)
+	AC_CHECK_HEADER(
+		curses.h,
+		,
+		found_curses=no)
+	if test "x$found_curses" = xyes; then
+		LIBS="$LIBS -lcurses"
+		AC_DEFINE(HAVE_CURSES_H)
+	else
+		AC_MSG_ERROR("curses not found")
+	fi
+fi
+
+# Save our CFLAGS/CPPFLAGS/LDFLAGS for the Makefile and restore the old user
+# variables.
+AC_SUBST(AM_CPPFLAGS)
+CPPFLAGS="$SAVED_CPPFLAGS"
+AC_SUBST(AM_CFLAGS)
+CFLAGS="$SAVED_CFLAGS"
+AC_SUBST(AM_LDFLAGS)
+LDFLAGS="$SAVED_LDFLAGS"
+
+AC_CONFIG_FILES([Makefile
+		 compat/Makefile
+		 libexec/Makefile
+		 libexec/got-read-tree/Makefile
+		 libexec/got-fetch-pack/Makefile
+		 libexec/got-index-pack/Makefile
+		 libexec/got-read-blob/Makefile
+		 libexec/got-read-commit/Makefile
+		 libexec/got-read-gitconfig/Makefile
+		 libexec/got-read-gotconfig/Makefile
+		 libexec/got-read-object/Makefile
+		 libexec/got-read-pack/Makefile
+		 libexec/got-read-tag/Makefile
+		 libexec/got-send-pack/Makefile
+		 got/Makefile
+		 tog/Makefile])
+AC_OUTPUT
+
+#                tog/GNUMakefile])
+#                regress/GNUMakefile
+#                regress/cmdline/GNUMakefile
+#                regress/delta/GNUMakefile
+#                regress/fetch/GNUMakefile
+#                regress/idset/GNUMakefile
+#                regress/path/GNUMakefile
+#                 gotweb/GNUMakefile
+#                 gotweb/libexec/GNUMakefile
+#                 gotweb/libexec/got-read-blob/GNUMakefile
+#                 gotweb/libexec/got-read-commit/GNUMakefile
+#                 gotweb/libexec/got-read-gitconfig/GNUMakefile
+#                 gotweb/libexec/got-read-gotconfig/GNUMakefile
+#                 gotweb/libexec/got-read-object/GNUMakefile
+#                 gotweb/libexec/got-read-pack/GNUMakefile
+#                 gotweb/libexec/got-read-tag/GNUMakefile
+#                 gotweb/libexec/got-read-tree/GNUMakefile
blob - 7b22d4ac7703c85955d363ec5f1b20d4c17c9f5d
blob + 2df9fbb9372d0538377a14c4ea095f7a7ea90e95
--- gotweb/gotweb.c
+++ gotweb/gotweb.c
@@ -15,7 +15,6 @@
  * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
  */
 
-#include <sys/queue.h>
 #include <sys/stat.h>
 #include <sys/types.h>
 
blob - /dev/null
blob + 6270fd4e8165f8236d032b97398fed86ef03d723 (mode 644)
--- /dev/null
+++ include/got_compat.h
@@ -0,0 +1,213 @@
+#ifndef _GOT_COMPAT_H
+#define _GOT_COMPAT_H
+
+#include <sys/types.h>
+#include <sys/ioctl.h>
+#include <sys/uio.h>
+
+#include <fnmatch.h>
+#include <limits.h>
+#include <stdio.h>
+#include <stdint.h>
+
+/*
+#include <termios.h>
+#include <wchar.h>
+*/
+
+/* For flock. */
+#ifndef O_EXLOCK
+#define O_EXLOCK 0
+#endif
+
+#ifndef HAVE_FLOCK
+#define LOCK_SH 0
+#define LOCK_EX 0
+#define LOCK_NB 0
+#define flock(fd, op) (0)
+#else
+#include <sys/file.h>
+#endif
+
+#ifndef __dead
+#define __dead __attribute__ ((__noreturn__))
+#endif
+
+#ifndef __OpenBSD__
+#define pledge(s, p) (0)
+#define unveil(s, p) (0)
+#endif
+
+#ifndef INFTIM
+#define INFTIM -1
+#endif
+
+#ifndef HAVE_BSD_UUID
+#include <uuid/uuid.h>
+#define uuid_s_ok 0
+#define uuid_s_bad_version  1
+#define uuid_s_invalid_string_uuid 2
+#define uuid_s_no_memory  3
+
+/* Length of a node address (an IEEE 802 address). */
+#define _UUID_NODE_LEN  6
+
+struct uuid {
+	uint32_t time_low;
+	uint16_t time_mid;
+	uint16_t time_hi_and_version;
+	uint8_t  clock_seq_hi_and_reserved;
+	uint8_t  clock_seq_low;
+	uint8_t  node[_UUID_NODE_LEN];
+};
+
+int32_t uuid_equal(struct uuid *, struct uuid *, uint32_t *);
+int32_t uuid_is_nil(struct uuid *, uint32_t *);
+void uuid_create(uuid_t *, uint32_t *);
+void uuid_create_nil(struct uuid *, uint32_t *);
+void uuid_from_string(const char *, uuid_t *, uint32_t *);
+void uuid_to_string(uuid_t *, char **, uint32_t *);
+#endif
+
+#ifdef HAVE_STDINT_H
+#include <stdint.h>
+#else
+#include <inttypes.h>
+#endif
+
+#ifdef HAVE_QUEUE_H
+#include <sys/queue.h>
+#else
+#include "compat/queue.h"
+#endif
+
+#ifdef HAVE_TREE_H
+#include <sys/tree.h>
+#else
+#include "compat/tree.h"
+#endif
+
+#ifdef HAVE_UTIL_H
+#include <util.h>
+#endif
+
+#ifdef HAVE_LIBUTIL_H
+#include <libutil.h>
+#endif
+
+#ifdef HAVE_IMSG
+#else
+#include "compat/imsg.h"
+#endif
+
+#ifndef HAVE_ASPRINTF
+/* asprintf.c */
+int		 asprintf(char **, const char *, ...);
+int		 vasprintf(char **, const char *, va_list);
+#endif
+
+#ifndef HAVE_EXPLICIT_BZERO
+/* explicit_bzero.c */
+void		 explicit_bzero(void *, size_t);
+#endif
+
+#ifndef HAVE_GETDTABLECOUNT
+/* getdtablecount.c */
+int		 getdtablecount(void);
+#endif
+
+#ifndef HAVE_CLOSEFROM
+/* closefrom.c */
+//void		 closefrom(int);
+#define closefrom(fd) (closefrom(fd), 0)
+#endif
+
+#ifndef HAVE_STRSEP
+/* strsep.c */
+char		*strsep(char **, const char *);
+#endif
+
+#ifndef HAVE_STRTONUM
+/* strtonum.c */
+long long	 strtonum(const char *, long long, long long, const char **);
+#endif
+
+#ifndef HAVE_STRLCPY
+/* strlcpy.c */
+size_t	 	 strlcpy(char *, const char *, size_t);
+#endif
+
+#ifndef HAVE_STRLCAT
+/* strlcat.c */
+size_t	 	 strlcat(char *, const char *, size_t);
+#endif
+
+#ifndef HAVE_STRNLEN
+/* strnlen.c */
+size_t		 strnlen(const char *, size_t);
+#endif
+
+#ifndef HAVE_STRNDUP
+/* strndup.c */
+char		*strndup(const char *, size_t);
+#endif
+
+#ifndef HAVE_GETPROGNAME
+/* getprogname.c */
+const char	*getprogname(void);
+#endif
+
+#ifndef HAVE_GETLINE
+/* getline.c */
+ssize_t		 getline(char **, size_t *, FILE *);
+#endif
+
+#ifndef HAVE_FREEZERO
+/* freezero.c */
+void		 freezero(void *, size_t);
+#endif
+
+#ifndef HAVE_GETDTABLECOUNT
+/* getdtablecount.c */
+int		 getdtablecount(void);
+#endif
+
+#ifndef HAVE_REALLOCARRAY
+/* reallocarray.c */
+void		*reallocarray(void *, size_t, size_t);
+#endif
+
+#ifndef HAVE_RECALLOCARRAY
+/* recallocarray.c */
+void		*recallocarray(void *, size_t, size_t, size_t);
+#endif
+
+#ifndef HAVE_FMT_SCALED
+/* fmt_scaled.c */
+int fmt_scaled(long long, char *);
+int scan_scaled(char *, long long *);
+#define FMT_SCALED_STRSIZE	7  /* minus sign, 4 digits, suffix, null byte */
+
+#endif
+
+#ifndef HAVE_LIBBSD
+/* getopt.c */
+extern int	BSDopterr;
+extern int	BSDoptind;
+extern int	BSDoptopt;
+extern int	BSDoptreset;
+extern char    *BSDoptarg;
+int	BSDgetopt(int, char *const *, const char *);
+#define getopt(ac, av, o)  BSDgetopt(ac, av, o)
+#define opterr             BSDopterr
+#define optind             BSDoptind
+#define optopt             BSDoptopt
+#define optreset           BSDoptreset
+#define optarg             BSDoptarg
+#endif
+#endif
+
+#ifndef HAVE_BSD_MERGESORT
+/* mergesort.c */
+int mergesort(void *, size_t, size_t, int (*)(const void *, const void *));
+#endif
blob - 5eb5cc5ebde432af823128fc7227bf48b866369a
blob + 33a8b4f9b4f13aab5a6bec4715c0e5a7f6939061
--- include/got_error.h
+++ include/got_error.h
@@ -14,6 +14,8 @@
  * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
  * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
  */
+
+#include "got_compat.h"
 
 /* Error codes */
 #define GOT_ERR_OK		0
blob - 112da0c2e234000d38b2dea5c3b1112fa045b7a0
blob + e40991a834713fea7cac5b9d536165249b00acc4
--- lib/arraylist.h
+++ lib/arraylist.h
@@ -37,6 +37,9 @@
  *         printf("%s", foo_to_str(list.head[i]));
  * ARRAYLIST_FREE(list);
  */
+
+#include "got_compat.h"
+
 #define ARRAYLIST(MEMBER_TYPE) \
 	struct { \
 		MEMBER_TYPE *head; \
blob - 783c434b33577727fafbf7589d751e7601a9dcf7
blob + e59a64ac627c2f057a122da8629bdafe70f1b4bd
--- lib/blame.c
+++ lib/blame.c
@@ -15,7 +15,6 @@
  * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
  */
 
-#include <sys/queue.h>
 #include <sys/mman.h>
 #include <sys/stat.h>
 
@@ -26,8 +25,9 @@
 #include <stdlib.h>
 #include <time.h>
 #include <limits.h>
-#include <util.h>
 #include <zlib.h>
+
+#include "got_compat.h"
 
 #include "got_error.h"
 #include "got_object.h"
blob - f17dddcabf8aa19fd01c17dec68dc1a8ec2dd748
blob + 38acc9c78c5f563fd844785003973ca9c8bcd73e
--- lib/buf.c
+++ lib/buf.c
@@ -24,7 +24,6 @@
  * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  */
 
-#include <sys/queue.h>
 #include <sys/stat.h>
 
 #include <errno.h>
blob - 02b48fae94b68b2e73ce447027d7d94d3be3b6c5
blob + bf42765e12770cf525a5b72369096a45e33cde0f
--- lib/commit_graph.c
+++ lib/commit_graph.c
@@ -16,8 +16,6 @@
 
 #include <sys/types.h>
 #include <sys/stat.h>
-#include <sys/queue.h>
-#include <sys/stdint.h>
 
 #include <limits.h>
 #include <stdio.h>
@@ -26,6 +24,8 @@
 #include <sha1.h>
 #include <zlib.h>
 #include <ctype.h>
+
+#include "got_compat.h"
 
 #include "got_error.h"
 #include "got_object.h"
blob - 02f9a9d5925c144aab1275b46ce59112abff7023
blob + d98ac2f3491f673a1fcd85cd32e0d40a242d1e0d
--- lib/deflate.c
+++ lib/deflate.c
@@ -14,7 +14,6 @@
  * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
  */
 
-#include <sys/queue.h>
 
 #include <errno.h>
 #include <stdio.h>
blob - 13058972edf12022d3cb9a2b3ab0bd2c60c0ede9
blob + d9cd7b365f0040f867ceec9e6ac810fdf3a7f4ed
--- lib/delta.c
+++ lib/delta.c
@@ -14,7 +14,6 @@
  * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
  */
 
-#include <sys/queue.h>
 
 #include <stdio.h>
 #include <stdlib.h>
blob - a8493a5806aaa56fb238ea9b39b593a778931da1
blob + 1e84c72b2144ed7cfd8c7e6cc1053cee28f0f5b2
--- lib/delta_cache.c
+++ lib/delta_cache.c
@@ -14,7 +14,6 @@
  * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
  */
 
-#include <sys/queue.h>
 
 #include <stdlib.h>
 #include <string.h>
@@ -24,6 +23,8 @@
 #include <limits.h>
 #include <time.h>
 
+#include "got_compat.h"
+
 #include "got_object.h"
 #include "got_error.h"
 
blob - 0ffffe0f4e30bc85094fda4bfba4fc745011ab8a
blob + 9e3f821a1f3aac172264fa8c7455389773c8e3c9
--- lib/deltify.c
+++ lib/deltify.c
@@ -16,7 +16,6 @@
  */
 
 #include <sys/types.h>
-#include <sys/queue.h>
 
 #include <assert.h>
 #include <endian.h>
blob - 6c0be0af379525b0196b72464d3a886e439077d7
blob + ad6558823eb4a56f19fd34da7ba498efdc206421
--- lib/dial.c
+++ lib/dial.c
@@ -15,7 +15,6 @@
  * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
  */
 
-#include <sys/queue.h>
 #include <sys/types.h>
 #include <sys/socket.h>
 #include <netdb.h>
@@ -30,6 +29,8 @@
 #include "got_error.h"
 #include "got_path.h"
 
+#include "got_compat.h"
+
 #include "got_lib_dial.h"
 
 #ifndef nitems
blob - 54a0944d64ec3e964a3e3d8938d5cea99aaf76f6
blob + 869cbaa12c615c85191fd515a65c919ce654d5e1
--- lib/diff.c
+++ lib/diff.c
@@ -14,7 +14,6 @@
  * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
  */
 
-#include <sys/queue.h>
 #include <sys/stat.h>
 
 #include <stdio.h>
@@ -24,6 +23,8 @@
 #include <sha1.h>
 #include <zlib.h>
 
+#include "got_compat.h"
+
 #include "got_object.h"
 #include "got_repository.h"
 #include "got_error.h"
blob - 957c2c39351c73dff16d9995d46aa9be345f27ef
blob + 03b4c8dd4c7283f3a638694ce7a9fcc52f3280e0
--- lib/diff3.c
+++ lib/diff3.c
@@ -65,7 +65,6 @@
  */
 
 #include <sys/stat.h>
-#include <sys/queue.h>
 
 #include <ctype.h>
 #include <limits.h>
blob - 77f774c3d3737b31b6f815a4434406dd96458a69
blob + 11768b2c060a299839ae3a716d85f9324d6ce579
--- lib/diff_main.c
+++ lib/diff_main.c
@@ -16,7 +16,6 @@
  */
 
 
-#include <sys/queue.h>
 #include <ctype.h>
 #include <errno.h>
 #include <stdint.h>
@@ -32,6 +31,8 @@
 #include <arraylist.h>
 #include <diff_main.h>
 
+#include "got_compat.h"
+
 #include "diff_internal.h"
 #include "diff_debug.h"
 
blob - 7bfd862b598c07fd5e72ed48db149670ae49ffbb
blob + 167f59b96d9b235b94895fb2fbeb8c5aeb81ded9
--- lib/diffreg.c
+++ lib/diffreg.c
@@ -17,13 +17,14 @@
 
 #include <sys/mman.h>
 #include <sys/stat.h>
-#include <sys/queue.h>
 
 #include <errno.h>
 #include <stdio.h>
 #include <stdlib.h>
 #include <string.h>
 
+#include "got_compat.h"
+
 #include "got_object.h"
 #include "got_opentemp.h"
 #include "got_error.h"
blob - 72e00488bedc8ea49b3e20af7eb76ec82839bfa3
blob + 4ad6d22aa77f19cf6105fcd6bc22a98e92d55ef7
--- lib/error.c
+++ lib/error.c
@@ -14,7 +14,6 @@
  * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
  */
 
-#include <sys/queue.h>
 
 #include <errno.h>
 #include <limits.h>
@@ -26,6 +25,8 @@
 #include <zlib.h>
 #include <uuid.h>
 
+#include "got_compat.h"
+
 #include "got_error.h"
 #include "got_object.h"
 
blob - 5206b456ca799c99ae1e3454f99d30f377a63361
blob + ab84f74f3c3156397f41e92c01cebdbda2d6d79f
--- lib/fetch.c
+++ lib/fetch.c
@@ -16,7 +16,6 @@
 
 #include <sys/types.h>
 #include <sys/stat.h>
-#include <sys/queue.h>
 #include <sys/uio.h>
 #include <sys/socket.h>
 #include <sys/wait.h>
@@ -36,7 +35,6 @@
 #include <zlib.h>
 #include <ctype.h>
 #include <limits.h>
-#include <imsg.h>
 #include <time.h>
 #include <uuid.h>
 
blob - aec06af5925a0cd63ffc6b150466bad036d5abd8
blob + 71dbb004fec2b3779639139eebb46b7002be5611
--- lib/fileindex.c
+++ lib/fileindex.c
@@ -14,8 +14,6 @@
  * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
  */
 
-#include <sys/queue.h>
-#include <sys/tree.h>
 #include <sys/stat.h>
 
 #include <errno.h>
@@ -29,6 +27,8 @@
 #include <limits.h>
 #include <unistd.h>
 #include <uuid.h>
+
+#include "got_compat.h"
 
 #include "got_error.h"
 #include "got_object.h"
@@ -1099,7 +1099,7 @@ diff_fileindex_dir(struct got_fileindex *fileindex,
 			}
 			cmp = got_path_cmp((*ie)->path, de_path,
 			    got_fileindex_entry_path_len(*ie),
-			    strlen(path) + 1 + de->d_namlen);
+			    strlen(path) + 1 + strlen(de->d_name));
 			free(de_path);
 			if (cmp == 0) {
 				err = cb->diff_old_new(cb_arg, *ie, de, path,
blob - 9b99340d822a3a7c9e2470194986699e4657f604
blob + 5df90993cba5c1a4d76ffb9c84b57b860a51ed11
--- lib/gitconfig.c
+++ lib/gitconfig.c
@@ -27,7 +27,6 @@
  */
 
 #include <sys/types.h>
-#include <sys/queue.h>
 #include <sys/stat.h>
 
 #include <ctype.h>
@@ -39,6 +38,8 @@
 #include <unistd.h>
 #include <errno.h>
 
+#include "got_compat.h"
+
 #include "got_error.h"
 
 #include "got_lib_gitconfig.h"
blob - e84621dc25c55193b9782419f2eae52217f447c0
blob + 0a12db68e30bfecc944c4f8fb3458a22be23a38f
--- lib/gitproto.c
+++ lib/gitproto.c
@@ -15,7 +15,6 @@
  * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
  */
 
-#include <sys/queue.h>
 #include <sys/types.h>
 
 #include <ctype.h>
blob - ce62cbf5e948bfee2b29b0f0524208b1a15a93e9
blob + cac18a9032ae5241e86b3b7e955f292c35101fe1
--- lib/got_lib_privsep.h
+++ lib/got_lib_privsep.h
@@ -32,7 +32,7 @@
 #define GOT_IMSG_FD_CHILD (STDERR_FILENO + 1)
 
 #ifndef GOT_LIBEXECDIR
-#define GOT_LIBEXECDIR /usr/libexec
+#define GOT_LIBEXECDIR /usr/local/bin
 #endif
 
 /* Names of helper programs in libexec directory */
blob - 7133ec58bdbaf535f13ad65c71428d7eb891a975
blob + 7d5fed69d8e41b0563b8081619c094d338399d9f
--- lib/gotconfig.c
+++ lib/gotconfig.c
@@ -15,7 +15,6 @@
  */
 
 #include <sys/types.h>
-#include <sys/queue.h>
 #include <sys/uio.h>
 #include <sys/socket.h>
 
@@ -25,10 +24,11 @@
 #include <stdlib.h>
 #include <stdio.h>
 #include <stdint.h>
-#include <imsg.h>
 #include <sha1.h>
 #include <limits.h>
 
+#include "got_compat.h"
+
 #include "got_error.h"
 #include "got_object.h"
 #include "got_repository.h"
blob - e68e173747b3f8c673775b8a2b0926048e870407
blob + e72bf08569b2eb4b9cb8e28ced29141dd9e14bb7
--- lib/inflate.c
+++ lib/inflate.c
@@ -14,7 +14,6 @@
  * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
  */
 
-#include <sys/queue.h>
 
 #include <errno.h>
 #include <stdio.h>
blob - 846038c091fec21e8c028ab14a6fcdb0ea52c913
blob + 165216e417422d26d0b171457e55841b60a1fe94
--- lib/lockfile.c
+++ lib/lockfile.c
@@ -15,7 +15,6 @@
  */
 
 #include <sys/stat.h>
-#include <sys/queue.h>
 
 #include <errno.h>
 #include <fcntl.h>
blob - 66e51456da85f0477bef25d1074a69d766e38fe2
blob + eaea9d8f0365e98800abb62b9edfaaceb89bb84b
--- lib/object.c
+++ lib/object.c
@@ -16,7 +16,6 @@
 
 #include <sys/types.h>
 #include <sys/stat.h>
-#include <sys/queue.h>
 #include <sys/uio.h>
 #include <sys/socket.h>
 #include <sys/wait.h>
@@ -34,8 +33,9 @@
 #include <ctype.h>
 #include <libgen.h>
 #include <limits.h>
-#include <imsg.h>
 #include <time.h>
+
+#include "got_compat.h"
 
 #include "got_error.h"
 #include "got_object.h"
blob - 4ef1c3c68734fcfaa46bc785e8d103a58b652d01
blob + 117648fc324c5a4b533c596bf8201739199dc811
--- lib/object_cache.c
+++ lib/object_cache.c
@@ -15,7 +15,6 @@
  */
 
 #include <sys/time.h>
-#include <sys/queue.h>
 
 #include <stdio.h>
 #include <stdlib.h>
blob - 70dc0d95f90464c02d691b2e2157c818079650c3
blob + 4e86317f1d38e8899d2d7bcd6a35a17c6d03ae53
--- lib/object_create.c
+++ lib/object_create.c
@@ -16,7 +16,6 @@
 
 #include <sys/types.h>
 #include <sys/stat.h>
-#include <sys/queue.h>
 
 #include <ctype.h>
 #include <errno.h>
@@ -30,6 +29,8 @@
 #include <unistd.h>
 #include <zlib.h>
 
+#include "got_compat.h"
+
 #include "got_error.h"
 #include "got_object.h"
 #include "got_repository.h"
blob - 152534fe9ad8d3e39e0d2945b284bbae1f218a2f
blob + c11b7204cadf33408433ee5be41a74768088dfef
--- lib/object_idset.c
+++ lib/object_idset.c
@@ -14,8 +14,6 @@
  * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
  */
 
-#include <sys/queue.h>
-#include <sys/tree.h>
 
 #include <stdlib.h>
 #include <string.h>
@@ -25,6 +23,8 @@
 #include <limits.h>
 #include <time.h>
 
+#include "got_compat.h"
+
 #include "got_object.h"
 #include "got_error.h"
 
blob - 4c0fd4f7fc733881e493f8944da591fe3502b689
blob + 0bcee86b223c71a52037d7b42aced837c04d98b1
--- lib/object_parse.c
+++ lib/object_parse.c
@@ -16,7 +16,6 @@
 
 #include <sys/types.h>
 #include <sys/stat.h>
-#include <sys/queue.h>
 #include <sys/uio.h>
 #include <sys/socket.h>
 #include <sys/wait.h>
@@ -30,9 +29,10 @@
 #include <zlib.h>
 #include <ctype.h>
 #include <limits.h>
-#include <imsg.h>
 #include <time.h>
 #include <unistd.h>
+
+#include "got_compat.h"
 
 #include "got_error.h"
 #include "got_object.h"
blob - e998f5bc48549bbbbbffb5ff88ae18e3e21c8c6f
blob + 5e6ad4d2aa42f0b97318ff7e1e86b7e8c6ed7055
--- lib/opentemp.c
+++ lib/opentemp.c
@@ -20,6 +20,8 @@
 #include <string.h>
 #include <stdio.h>
 
+#include "got_compat.h"
+
 #include "got_opentemp.h"
 #include "got_error.h"
 
blob - b29f6d25ce45802ebffcccce90ca9975efdbf260
blob + 69694e82b0bb6192be25b3c8a2c84c45468e4e80
--- lib/pack.c
+++ lib/pack.c
@@ -16,7 +16,6 @@
 
 #include <sys/types.h>
 #include <sys/stat.h>
-#include <sys/queue.h>
 #include <sys/uio.h>
 #include <sys/mman.h>
 
@@ -31,7 +30,6 @@
 #include <endian.h>
 #include <unistd.h>
 #include <zlib.h>
-#include <imsg.h>
 
 #include "got_error.h"
 #include "got_object.h"
blob - 6f64f97e5ab0a743040b77f12b907d6537a7f7f5
blob + 49bed139e8532edec677f5d2b18e1f37a1a5746e
--- lib/pack_create.c
+++ lib/pack_create.c
@@ -16,12 +16,10 @@
  */
 
 #include <sys/types.h>
-#include <sys/queue.h>
 #include <sys/uio.h>
 #include <sys/stat.h>
 
 #include <stdint.h>
-#include <imsg.h>
 #include <stdio.h>
 #include <stdlib.h>
 #include <string.h>
blob - d94d085c6a81b1232aacfe54421d5ffa740b8393
blob + c35a92ea03b51f220e0188cf6a0c9afae627094f
--- lib/path.c
+++ lib/path.c
@@ -16,7 +16,6 @@
  * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
  */
 
-#include <sys/queue.h>
 #include <sys/stat.h>
 
 #include <errno.h>
@@ -30,6 +29,8 @@
 #include <dirent.h>
 #include <paths.h>
 
+#include "got_compat.h"
+
 #include "got_error.h"
 #include "got_path.h"
 
blob - 990151b1a2bdf4ad27602e91cfa25a19c9786813
blob + 05b4a3a90b306e5c0db905e4e1b4c938181dea9e
--- lib/privsep.c
+++ lib/privsep.c
@@ -16,7 +16,6 @@
  */
 
 #include <sys/types.h>
-#include <sys/queue.h>
 #include <sys/uio.h>
 #include <sys/wait.h>
 
@@ -29,11 +28,12 @@
 #include <errno.h>
 #include <stdint.h>
 #include <poll.h>
-#include <imsg.h>
 #include <sha1.h>
 #include <unistd.h>
 #include <zlib.h>
 #include <time.h>
+
+#include "got_compat.h"
 
 #include "got_object.h"
 #include "got_error.h"
blob - ac95dc7db2140ce4baaa2e286b3b6c3f6898a7fb
blob + 0697c0943c5bd5da8853f278f78f700caa4175df
--- lib/rcsutil.c
+++ lib/rcsutil.c
@@ -27,7 +27,6 @@
  * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  */
 
-#include <sys/queue.h>
 
 #include <ctype.h>
 #include <stdio.h>
@@ -35,6 +34,8 @@
 #include <string.h>
 #include <unistd.h>
 
+#include "got_compat.h"
+
 #include "buf.h"
 #include "rcsutil.h"
 
blob - fde331d19fb3c439f182eec39b182eb68efe2b4e
blob + 6ccff34b22c6c2a0f614e842066303d8c80da9b1
--- lib/reference.c
+++ lib/reference.c
@@ -15,7 +15,6 @@
  */
 
 #include <sys/types.h>
-#include <sys/queue.h>
 #include <sys/stat.h>
 
 #include <errno.h>
@@ -27,10 +26,11 @@
 #include <stdlib.h>
 #include <string.h>
 #include <unistd.h>
-#include <util.h>
 #include <zlib.h>
 #include <time.h>
 #include <libgen.h>
+
+#include "got_compat.h"
 
 #include "got_error.h"
 #include "got_object.h"
blob - aefced9489544735f291e942d94b7c3fb6fc5395
blob + 08f2da0fa31f815709a79732dbc9ae1114b527b3
--- lib/repository.c
+++ lib/repository.c
@@ -15,7 +15,6 @@
  */
 
 #include <sys/types.h>
-#include <sys/queue.h>
 #include <sys/uio.h>
 #include <sys/socket.h>
 #include <sys/stat.h>
@@ -38,9 +37,10 @@
 #include <errno.h>
 #include <libgen.h>
 #include <stdint.h>
-#include <imsg.h>
 #include <uuid.h>
 
+#include "got_compat.h"
+
 #include "got_error.h"
 #include "got_reference.h"
 #include "got_repository.h"
@@ -1015,7 +1015,8 @@ got_repo_search_packidx(struct got_packidx **packidx, 
 	while ((dent = readdir(packdir)) != NULL) {
 		int is_cached = 0;
 
-		if (!got_repo_is_packidx_filename(dent->d_name, dent->d_namlen))
+		if (!got_repo_is_packidx_filename(dent->d_name,
+		    strlen(dent->d_name)))
 			continue;
 
 		if (asprintf(&path_packidx, "%s/%s", GOT_OBJECTS_PACK_DIR,
@@ -1283,7 +1284,8 @@ match_packed_object(struct got_object_id **unique_id,
 		struct got_packidx *packidx;
 		struct got_object_qid *qid;
 
-		if (!got_repo_is_packidx_filename(dent->d_name, dent->d_namlen))
+		if (!got_repo_is_packidx_filename(dent->d_name,
+		    strlen(dent->d_name)))
 			continue;
 
 		if (asprintf(&path_packidx, "%s/%s", GOT_OBJECTS_PACK_DIR,
@@ -1959,7 +1961,8 @@ got_repo_get_packfile_info(int *npackfiles, int *nobje
 	}
 
 	while ((dent = readdir(packdir)) != NULL) {
-		if (!got_repo_is_packidx_filename(dent->d_name, dent->d_namlen))
+		if (!got_repo_is_packidx_filename(dent->d_name,
+		    strlen(dent->d_name)))
 			continue;
 
 		if (asprintf(&path_packidx, "%s/%s", GOT_OBJECTS_PACK_DIR,
blob - 865369efec481b7e7d68445a796d1a075ac52e70
blob + f6a3948b8c4a93bb072778425ca354c152dd54dc
--- lib/repository_admin.c
+++ lib/repository_admin.c
@@ -1236,7 +1236,8 @@ got_repo_remove_lonely_packidx(struct got_repository *
 				goto done;
 		}
 
-		if (!got_repo_is_packidx_filename(dent->d_name, dent->d_namlen))
+		if (!got_repo_is_packidx_filename(dent->d_name,
+		    strlen(dent->d_name)))
 			continue;
 
 		err = got_packidx_get_packfile_path(&pack_relpath,
blob - 439105b666bbf6eb9e40bf4c2cfa6b3c25e52eeb
blob + 6b14f325c677d19b2b5a068c142b1d40c812e58f
--- lib/send.c
+++ lib/send.c
@@ -17,7 +17,6 @@
 
 #include <sys/types.h>
 #include <sys/stat.h>
-#include <sys/queue.h>
 #include <sys/uio.h>
 #include <sys/socket.h>
 #include <sys/wait.h>
@@ -37,7 +36,6 @@
 #include <zlib.h>
 #include <ctype.h>
 #include <limits.h>
-#include <imsg.h>
 #include <time.h>
 #include <uuid.h>
 
blob - 167f4f59e0296904450ea74eff5e61a6cff74abb
blob + 7527e3f4c10ad222e8c0ccc0033c317cc384b6e5
--- lib/utf8.c
+++ lib/utf8.c
@@ -23,6 +23,8 @@
 #include <wchar.h>
 #include <langinfo.h>
 
+#include "got_compat.h"
+
 #include "got_error.h"
 #include "got_utf8.h"
 
blob - e8baa2aceccca3befe0c125fd5902bb082f1315f
blob + 264a17dbcf80c208a1facb0bd41b8a1ca780b455
--- lib/worktree.c
+++ lib/worktree.c
@@ -15,8 +15,6 @@
  */
 
 #include <sys/stat.h>
-#include <sys/queue.h>
-#include <sys/tree.h>
 
 #include <dirent.h>
 #include <limits.h>
@@ -32,8 +30,8 @@
 #include <zlib.h>
 #include <fnmatch.h>
 #include <libgen.h>
-#include <uuid.h>
-#include <util.h>
+
+#include "got_compat.h"
 
 #include "got_error.h"
 #include "got_repository.h"
blob - 3783b56689f6ab58fbacbd8f0f990a7154d90f61 (mode 644)
blob + /dev/null
--- libexec/Makefile
+++ /dev/null
@@ -1,5 +0,0 @@
-SUBDIR = got-read-blob got-read-commit got-read-object got-read-tree \
-	got-read-tag got-fetch-pack got-index-pack got-read-pack \
-	got-read-gitconfig got-read-gotconfig got-send-pack
-
-.include <bsd.subdir.mk>
blob - /dev/null
blob + f4ec33f6db6cadd71ad94f00067826723685e4ec (mode 644)
--- /dev/null
+++ libexec/Makefile.am
@@ -0,0 +1,11 @@
+SUBDIRS = got-fetch-pack \
+	  got-index-pack \
+	  got-read-blob \
+	  got-read-commit \
+	  got-read-gitconfig \
+	  got-read-gotconfig \
+	  got-read-object \
+	  got-read-pack \
+	  got-read-tag \
+	  got-read-tree \
+	  got-send-pack
blob - 7df6b00656bdfc711605a13a29e30f4b21aa2f3a (mode 644)
blob + /dev/null
--- libexec/got-fetch-pack/Makefile
+++ /dev/null
@@ -1,13 +0,0 @@
-.PATH:${.CURDIR}/../../lib
-
-.include "../../got-version.mk"
-
-PROG=		got-fetch-pack
-SRCS=		got-fetch-pack.c error.c inflate.c object_parse.c \
-		path.c privsep.c sha1.c pkt.c gitproto.c
-
-CPPFLAGS = -I${.CURDIR}/../../include -I${.CURDIR}/../../lib
-LDADD = -lutil -lz
-DPADD = ${LIBZ} ${LIBUTIL}
-
-.include <bsd.prog.mk>
blob - /dev/null
blob + 6bec7341a250fce2618dd09f083bd3b44d3d589f (mode 644)
--- /dev/null
+++ libexec/got-fetch-pack/Makefile.am
@@ -0,0 +1,24 @@
+bin_PROGRAMS = got-fetch-pack
+got_fetch_pack_SOURCES = \
+	got-fetch-pack.c \
+	$(top_srcdir)/lib/error.c \
+	$(top_srcdir)/lib/inflate.c \
+	$(top_srcdir)/lib/object_parse.c \
+	$(top_srcdir)/lib/path.c \
+	$(top_srcdir)/lib/privsep.c \
+	$(top_srcdir)/lib/sha1.c \
+	$(top_srcdir)/lib/pkt.c \
+	$(top_srcdir)/lib/gitproto.c
+
+got_fetch_pack_DEPENDENCIES = $(top_builddir)/compat/libopenbsd-compat.a
+
+AM_CPPFLAGS += -DGOT_VERSION='"@VERSION@"' \
+	-DGOT_VERSION_NUMBER='"@VERSION@"' \
+	-DGOT_LIBEXEC_DIR="${bindir}" \
+	-I$(top_srcdir) \
+	-I$(top_srcdir)/compat \
+	-I$(top_srcdir)/lib \
+	-I$(top_srcdir)/include \
+	-I.
+
+LDADD = -L$(top_builddir)/compat -lopenbsd-compat
blob - 15451b4e3f2c64f4522ab8457cb5e6151ed1e1f4
blob + 2b84c4fa3f8e08974358a499d31231a7047989d7
--- libexec/got-fetch-pack/got-fetch-pack.c
+++ libexec/got-fetch-pack/got-fetch-pack.c
@@ -15,14 +15,12 @@
  */
 
 #include <sys/types.h>
-#include <sys/queue.h>
 #include <sys/uio.h>
 #include <sys/time.h>
 #include <sys/stat.h>
 
 #include <stdint.h>
 #include <errno.h>
-#include <imsg.h>
 #include <limits.h>
 #include <signal.h>
 #include <stdio.h>
@@ -34,6 +32,8 @@
 #include <unistd.h>
 #include <zlib.h>
 #include <err.h>
+
+#include "got_compat.h"
 
 #include "got_error.h"
 #include "got_object.h"
blob - 483b83598ba5e1661ebbc0d8fb41bc95091a622b (mode 644)
blob + /dev/null
--- libexec/got-index-pack/Makefile
+++ /dev/null
@@ -1,13 +0,0 @@
-.PATH:${.CURDIR}/../../lib
-
-.include "../../got-version.mk"
-
-PROG=		got-index-pack
-SRCS=		got-index-pack.c error.c inflate.c object_parse.c object_idset.c \
-		delta_cache.c delta.c pack.c path.c privsep.c sha1.c
-
-CPPFLAGS = -I${.CURDIR}/../../include -I${.CURDIR}/../../lib
-LDADD = -lutil -lz
-DPADD = ${LIBZ} ${LIBUTIL}
-
-.include <bsd.prog.mk>
blob - /dev/null
blob + 21cc09d8b72e52bbb3671ba9d3b33efb9eb6d9df (mode 644)
--- /dev/null
+++ libexec/got-index-pack/Makefile.am
@@ -0,0 +1,25 @@
+bin_PROGRAMS = got-index-pack
+got_index_pack_SOURCES = got-index-pack.c \
+	$(top_srcdir)/lib/error.c \
+	$(top_srcdir)/lib/inflate.c \
+	$(top_srcdir)/lib/object_parse.c \
+	$(top_srcdir)/lib/object_idset.c \
+	$(top_srcdir)/lib/delta_cache.c \
+	$(top_srcdir)/lib/delta.c \
+	$(top_srcdir)/lib/pack.c \
+	$(top_srcdir)/lib/path.c \
+	$(top_srcdir)/lib/privsep.c \
+	$(top_srcdir)/lib/sha1.c
+
+got_index_pack_DEPENDENCIES = $(top_builddir)/compat/libopenbsd-compat.a
+
+AM_CPPFLAGS += -DGOT_VERSION='"@VERSION@"' \
+	-DGOT_VERSION_NUMBER='"@VERSION@"' \
+	-DGOT_LIBEXEC_DIR="${bindir}" \
+	-I$(top_srcdir) \
+	-I$(top_srcdir)/compat \
+	-I$(top_srcdir)/lib \
+	-I$(top_srcdir)/include \
+	-I.
+
+LDADD = -L$(top_builddir)/compat -lopenbsd-compat
blob - 6ba4490d952e266de433edbadd35609faaeff1bf
blob + 886a63ddb89f836df04c04f1dff94e3a6c4ea980
--- libexec/got-index-pack/got-index-pack.c
+++ libexec/got-index-pack/got-index-pack.c
@@ -15,7 +15,6 @@
  * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
  */
 
-#include <sys/queue.h>
 #include <sys/stat.h>
 #include <sys/time.h>
 #include <sys/types.h>
@@ -24,7 +23,6 @@
 
 #include <stdint.h>
 #include <errno.h>
-#include <imsg.h>
 #include <limits.h>
 #include <signal.h>
 #include <stdio.h>
@@ -42,6 +40,8 @@
 
 #include "got_error.h"
 #include "got_object.h"
+
+#include "got_compat.h"
 
 #include "got_lib_sha1.h"
 #include "got_lib_delta.h"
blob - 17ab97b2e8436f60a7500f7894295b56f5c3d9cc (mode 644)
blob + /dev/null
--- libexec/got-read-blob/Makefile
+++ /dev/null
@@ -1,13 +0,0 @@
-.PATH:${.CURDIR}/../../lib
-
-.include "../../got-version.mk"
-
-PROG=		got-read-blob
-SRCS=		got-read-blob.c error.c inflate.c object_parse.c \
-		path.c privsep.c sha1.c
-
-CPPFLAGS = -I${.CURDIR}/../../include -I${.CURDIR}/../../lib
-LDADD = -lutil -lz
-DPADD = ${LIBZ} ${LIBUTIL}
-
-.include <bsd.prog.mk>
blob - /dev/null
blob + 71a30282ee76458c64cd376e289eac1988ddca39 (mode 644)
--- /dev/null
+++ libexec/got-read-blob/Makefile.am
@@ -0,0 +1,21 @@
+bin_PROGRAMS = got-read-blob
+got_read_blob_SOURCES = got-read-blob.c \
+	$(top_srcdir)/lib/error.c \
+	$(top_srcdir)/lib/inflate.c \
+	$(top_srcdir)/lib/object_parse.c \
+	$(top_srcdir)/lib/path.c \
+	$(top_srcdir)/lib/privsep.c \
+	$(top_srcdir)/lib/sha1.c
+
+got_read_blob_DEPENDENCIES = $(top_builddir)/compat/libopenbsd-compat.a
+
+AM_CPPFLAGS += -DGOT_VERSION='"@VERSION@"' \
+	-DGOT_VERSION_NUMBER='"@VERSION@"' \
+	-DGOT_LIBEXEC_DIR="${bindir}" \
+	-I$(top_srcdir) \
+	-I$(top_srcdir)/compat \
+	-I$(top_srcdir)/lib \
+	-I$(top_srcdir)/include \
+	-I.
+
+LDADD = -L$(top_builddir)/compat -lopenbsd-compat
blob - c5a389ba424f515e20c4b3afb8f183a6b2cdd9ae
blob + 35d6fe9a97a0086757eab53417ef6e5414bcb01a
--- libexec/got-read-blob/got-read-blob.c
+++ libexec/got-read-blob/got-read-blob.c
@@ -15,12 +15,10 @@
  */
 
 #include <sys/types.h>
-#include <sys/queue.h>
 #include <sys/uio.h>
 #include <sys/time.h>
 
 #include <stdint.h>
-#include <imsg.h>
 #include <limits.h>
 #include <signal.h>
 #include <stdio.h>
@@ -30,6 +28,8 @@
 #include <unistd.h>
 #include <zlib.h>
 
+#include "got_compat.h"
+
 #include "got_error.h"
 #include "got_object.h"
 
blob - 3f6f7ca0174a2db300be5170c74fc6e3eaf3c94a (mode 644)
blob + /dev/null
--- libexec/got-read-commit/Makefile
+++ /dev/null
@@ -1,13 +0,0 @@
-.PATH:${.CURDIR}/../../lib
-
-.include "../../got-version.mk"
-
-PROG=		got-read-commit
-SRCS=		got-read-commit.c error.c inflate.c object_parse.c \
-		path.c privsep.c sha1.c
-
-CPPFLAGS = -I${.CURDIR}/../../include -I${.CURDIR}/../../lib
-LDADD = -lutil -lz
-DPADD = ${LIBZ} ${LIBUTIL}
-
-.include <bsd.prog.mk>
blob - /dev/null
blob + 0ab79163a4754972dc942087668756f1e00ebb0e (mode 644)
--- /dev/null
+++ libexec/got-read-commit/Makefile.am
@@ -0,0 +1,21 @@
+bin_PROGRAMS = got-read-commit
+got_read_commit_SOURCES = got-read-commit.c \
+	$(top_srcdir)/lib/error.c \
+	$(top_srcdir)/lib/inflate.c \
+	$(top_srcdir)/lib/object_parse.c \
+	$(top_srcdir)/lib/path.c \
+	$(top_srcdir)/lib/privsep.c \
+	$(top_srcdir)/lib/sha1.c
+
+got_read_commit_DEPENDENCIES = $(top_builddir)/compat/libopenbsd-compat.a
+
+AM_CPPFLAGS += -DGOT_VERSION='"@VERSION@"' \
+	-DGOT_VERSION_NUMBER='"@VERSION@"' \
+	-DGOT_LIBEXEC_DIR="${bindir}" \
+	-I$(top_srcdir) \
+	-I$(top_srcdir)/compat \
+	-I$(top_srcdir)/lib \
+	-I$(top_srcdir)/include \
+	-I.
+
+LDADD = -L$(top_builddir)/compat -lopenbsd-compat
blob - 867dc5954e47c0673e815db7c0e25ae703e11658
blob + 63723fc13f12844d56c1be7e4cef38be62a52937
--- libexec/got-read-commit/got-read-commit.c
+++ libexec/got-read-commit/got-read-commit.c
@@ -15,12 +15,10 @@
  */
 
 #include <sys/types.h>
-#include <sys/queue.h>
 #include <sys/uio.h>
 #include <sys/time.h>
 
 #include <stdint.h>
-#include <imsg.h>
 #include <limits.h>
 #include <signal.h>
 #include <stdio.h>
@@ -30,6 +28,8 @@
 #include <unistd.h>
 #include <zlib.h>
 
+#include "got_compat.h"
+
 #include "got_error.h"
 #include "got_object.h"
 
blob - f49bf06548491001d3b2fbc4da15ac568171dc17 (mode 644)
blob + /dev/null
--- libexec/got-read-gitconfig/Makefile
+++ /dev/null
@@ -1,13 +0,0 @@
-.PATH:${.CURDIR}/../../lib
-
-.include "../../got-version.mk"
-
-PROG=		got-read-gitconfig
-SRCS=		got-read-gitconfig.c error.c inflate.c object_parse.c \
-		path.c privsep.c sha1.c gitconfig.c
-
-CPPFLAGS = -I${.CURDIR}/../../include -I${.CURDIR}/../../lib
-LDADD = -lutil -lz
-DPADD = ${LIBZ} ${LIBUTIL}
-
-.include <bsd.prog.mk>
blob - /dev/null
blob + 903df75ca3c43917dd99eddace902298fcb693ed (mode 644)
--- /dev/null
+++ libexec/got-read-gitconfig/Makefile.am
@@ -0,0 +1,22 @@
+bin_PROGRAMS = got-read-gitconfig
+got_read_gitconfig_SOURCES = got-read-gitconfig.c \
+	$(top_srcdir)/lib/error.c \
+	$(top_srcdir)/lib/inflate.c \
+	$(top_srcdir)/lib/object_parse.c \
+	$(top_srcdir)/lib/path.c \
+	$(top_srcdir)/lib/privsep.c \
+	$(top_srcdir)/lib/sha1.c \
+	$(top_srcdir)/lib/gitconfig.c
+
+got_read_gitconfig_DEPENDENCIES = $(top_builddir)/compat/libopenbsd-compat.a
+
+AM_CPPFLAGS += -DGOT_VERSION='"@VERSION@"' \
+	-DGOT_VERSION_NUMBER='"@VERSION@"' \
+	-DGOT_LIBEXEC_DIR="${bindir}" \
+	-I$(top_srcdir) \
+	-I$(top_srcdir)/compat \
+	-I$(top_srcdir)/lib \
+	-I$(top_srcdir)/include \
+	-I.
+
+LDADD = -L$(top_builddir)/compat -lopenbsd-compat
blob - 3ce93f09be615d41528eb6af7e5f5a1bd77ce92f
blob + e295f14e62e3c0b1638ec35b5e3c065cf4464b14
--- libexec/got-read-gitconfig/got-read-gitconfig.c
+++ libexec/got-read-gitconfig/got-read-gitconfig.c
@@ -15,12 +15,10 @@
  */
 
 #include <sys/types.h>
-#include <sys/queue.h>
 #include <sys/uio.h>
 #include <sys/time.h>
 
 #include <stdint.h>
-#include <imsg.h>
 #include <limits.h>
 #include <signal.h>
 #include <stdio.h>
@@ -29,6 +27,8 @@
 #include <sha1.h>
 #include <unistd.h>
 #include <zlib.h>
+
+#include "got_compat.h"
 
 #include "got_error.h"
 #include "got_object.h"
blob - a683cf2ee1b6cf0753a4a7f2b006bfc29f853a8c (mode 644)
blob + /dev/null
--- libexec/got-read-gotconfig/Makefile
+++ /dev/null
@@ -1,13 +0,0 @@
-.PATH:${.CURDIR}/../../lib
-
-.include "../../got-version.mk"
-
-PROG=		got-read-gotconfig
-SRCS=		got-read-gotconfig.c error.c inflate.c object_parse.c \
-		path.c privsep.c sha1.c parse.y
-
-CPPFLAGS = -I${.CURDIR}/../../include -I${.CURDIR}/../../lib -I${.CURDIR}
-LDADD = -lutil -lz
-DPADD = ${LIBZ} ${LIBUTIL}
-
-.include <bsd.prog.mk>
blob - /dev/null
blob + 719564d719ca2122f6eac9b8c3ffef5ad8fddbb8 (mode 644)
--- /dev/null
+++ libexec/got-read-gotconfig/Makefile.am
@@ -0,0 +1,22 @@
+bin_PROGRAMS = got-read-gotconfig
+got_read_gotconfig_SOURCES = got-read-gotconfig.c \
+	$(top_srcdir)/lib/error.c \
+	$(top_srcdir)/lib/inflate.c \
+	$(top_srcdir)/lib/object_parse.c \
+	$(top_srcdir)/lib/path.c \
+	$(top_srcdir)/lib/privsep.c \
+	$(top_srcdir)/lib/sha1.c \
+	parse.y
+
+got_read_gotconfig_DEPENDENCIES = $(top_builddir)/compat/libopenbsd-compat.a
+
+AM_CPPFLAGS += -DGOT_VERSION='"@VERSION@"' \
+	-DGOT_VERSION_NUMBER='"@VERSION@"' \
+	-DGOT_LIBEXEC_DIR="${bindir}" \
+	-I$(top_srcdir) \
+	-I$(top_srcdir)/compat \
+	-I$(top_srcdir)/lib \
+	-I$(top_srcdir)/include \
+	-I.
+
+LDADD = -L$(top_builddir)/compat -lopenbsd-compat
blob - 3eb4560b62d19ac09c049067c235bc7051c1216c
blob + 39e02e68a0ab56940b556b9aaef010a796ac9449
--- libexec/got-read-gotconfig/got-read-gotconfig.c
+++ libexec/got-read-gotconfig/got-read-gotconfig.c
@@ -15,12 +15,10 @@
  */
 
 #include <sys/types.h>
-#include <sys/queue.h>
 #include <sys/uio.h>
 #include <sys/time.h>
 
 #include <stdint.h>
-#include <imsg.h>
 #include <limits.h>
 #include <signal.h>
 #include <stdio.h>
@@ -29,6 +27,8 @@
 #include <sha1.h>
 #include <unistd.h>
 #include <zlib.h>
+
+#include "got_compat.h"
 
 #include "got_error.h"
 #include "got_object.h"
blob - 6c97b602a6967eed43b39a0b6cd54fa267cebffe
blob + 80949f68d4cb084bcfc57b72d182891cd3c36c05
--- libexec/got-read-gotconfig/parse.y
+++ libexec/got-read-gotconfig/parse.y
@@ -23,7 +23,6 @@
 
 %{
 #include <sys/types.h>
-#include <sys/queue.h>
 
 #include <netdb.h>
 
@@ -36,6 +35,8 @@
 #include <stdlib.h>
 #include <string.h>
 
+#include "got_compat.h"
+
 #include "got_error.h"
 #include "gotconfig.h"
 
blob - 26342119d0b8e4f5207e3ae68b750ba176d0d374 (mode 644)
blob + /dev/null
--- libexec/got-read-object/Makefile
+++ /dev/null
@@ -1,13 +0,0 @@
-.PATH:${.CURDIR}/../../lib
-
-.include "../../got-version.mk"
-
-PROG=		got-read-object
-SRCS=		got-read-object.c error.c inflate.c object_parse.c \
-		path.c privsep.c sha1.c
-
-CPPFLAGS = -I${.CURDIR}/../../include -I${.CURDIR}/../../lib
-LDADD = -lutil -lz
-DPADD = ${LIBZ} ${LIBUTIL}
-
-.include <bsd.prog.mk>
blob - /dev/null
blob + 063d39691da2fdb2540c3a42fc2cd0ede7d60345 (mode 644)
--- /dev/null
+++ libexec/got-read-object/Makefile.am
@@ -0,0 +1,21 @@
+bin_PROGRAMS = got-read-object
+got_read_object_SOURCES = got-read-object.c \
+	$(top_srcdir)/lib/error.c \
+	$(top_srcdir)/lib/inflate.c \
+	$(top_srcdir)/lib/object_parse.c \
+	$(top_srcdir)/lib/path.c \
+	$(top_srcdir)/lib/privsep.c \
+	$(top_srcdir)/lib/sha1.c
+
+got_read_object_DEPENDENCIES = $(top_builddir)/compat/libopenbsd-compat.a
+
+AM_CPPFLAGS += -DGOT_VERSION='"@VERSION@"' \
+	-DGOT_VERSION_NUMBER='"@VERSION@"' \
+	-DGOT_LIBEXEC_DIR="${bindir}" \
+	-I$(top_srcdir) \
+	-I$(top_srcdir)/compat \
+	-I$(top_srcdir)/lib \
+	-I$(top_srcdir)/include \
+	-I.
+
+LDADD = -L$(top_builddir)/compat -lopenbsd-compat
blob - 4c0bf0f3e8dcb076c30c707c610ceca0aa0bdf80
blob + a59095676603202ad73ba5ae27415c88582791a7
--- libexec/got-read-object/got-read-object.c
+++ libexec/got-read-object/got-read-object.c
@@ -15,12 +15,10 @@
  */
 
 #include <sys/types.h>
-#include <sys/queue.h>
 #include <sys/uio.h>
 #include <sys/time.h>
 
 #include <stdint.h>
-#include <imsg.h>
 #include <limits.h>
 #include <signal.h>
 #include <stdio.h>
@@ -30,6 +28,8 @@
 #include <unistd.h>
 #include <zlib.h>
 
+#include "got_compat.h"
+
 #include "got_error.h"
 #include "got_object.h"
 
blob - 5fe2b7efcfad5831f504354f84e46082989a0d5f (mode 644)
blob + /dev/null
--- libexec/got-read-pack/Makefile
+++ /dev/null
@@ -1,14 +0,0 @@
-.PATH:${.CURDIR}/../../lib
-
-.include "../../got-version.mk"
-
-PROG=		got-read-pack
-SRCS=		got-read-pack.c delta.c error.c inflate.c object_cache.c \
-		object_idset.c object_parse.c opentemp.c pack.c path.c \
-		privsep.c sha1.c delta_cache.c
-
-CPPFLAGS = -I${.CURDIR}/../../include -I${.CURDIR}/../../lib
-LDADD = -lutil -lz
-DPADD = ${LIBZ} ${LIBUTIL}
-
-.include <bsd.prog.mk>
blob - /dev/null
blob + fe4f9d2dbb8eec3c662d4e74e633d41ed2b2b372 (mode 644)
--- /dev/null
+++ libexec/got-read-pack/Makefile.am
@@ -0,0 +1,27 @@
+bin_PROGRAMS = got-read-pack
+got_read_pack_SOURCES = got-read-pack.c \
+	$(top_srcdir)/lib/delta.c \
+	$(top_srcdir)/lib/delta_cache.c \
+	$(top_srcdir)/lib/error.c \
+	$(top_srcdir)/lib/inflate.c \
+	$(top_srcdir)/lib/object_parse.c \
+	$(top_srcdir)/lib/object_cache.c \
+	$(top_srcdir)/lib/object_idset.c \
+	$(top_srcdir)/lib/opentemp.c \
+	$(top_srcdir)/lib/pack.c \
+	$(top_srcdir)/lib/path.c \
+	$(top_srcdir)/lib/privsep.c \
+	$(top_srcdir)/lib/sha1.c
+
+got_read_pack_DEPENDENCIES = $(top_builddir)/compat/libopenbsd-compat.a
+
+AM_CPPFLAGS += -DGOT_VERSION='"@VERSION@"' \
+	-DGOT_VERSION_NUMBER='"@VERSION@"' \
+	-DGOT_LIBEXEC_DIR="${bindir}" \
+	-I$(top_srcdir) \
+	-I$(top_srcdir)/compat \
+	-I$(top_srcdir)/lib \
+	-I$(top_srcdir)/include \
+	-I.
+
+LDADD = -L$(top_builddir)/compat -lopenbsd-compat
blob - 8fdda11dc81d93858240483333f00089526064e5
blob + ead69bd509f8bf3acbbeae7e92de9002b0370ac7
--- libexec/got-read-pack/got-read-pack.c
+++ libexec/got-read-pack/got-read-pack.c
@@ -15,7 +15,6 @@
  */
 
 #include <sys/types.h>
-#include <sys/queue.h>
 #include <sys/uio.h>
 #include <sys/time.h>
 #include <sys/mman.h>
@@ -23,13 +22,14 @@
 #include <limits.h>
 #include <signal.h>
 #include <stdint.h>
-#include <imsg.h>
 #include <stdio.h>
 #include <stdlib.h>
 #include <string.h>
 #include <sha1.h>
 #include <unistd.h>
 #include <zlib.h>
+
+#include "got_compat.h"
 
 #include "got_error.h"
 #include "got_object.h"
blob - a8026e4c1b7f0f719d0b8d2cf3020f3ccbf0c333 (mode 644)
blob + /dev/null
--- libexec/got-read-tag/Makefile
+++ /dev/null
@@ -1,13 +0,0 @@
-.PATH:${.CURDIR}/../../lib
-
-.include "../../got-version.mk"
-
-PROG=		got-read-tag
-SRCS=		got-read-tag.c error.c inflate.c object_parse.c \
-		path.c privsep.c sha1.c
-
-CPPFLAGS = -I${.CURDIR}/../../include -I${.CURDIR}/../../lib
-LDADD = -lutil -lz
-DPADD = ${LIBZ} ${LIBUTIL}
-
-.include <bsd.prog.mk>
blob - /dev/null
blob + 112d9d90900d86f0692470a7bb9f5cf2c534143c (mode 644)
--- /dev/null
+++ libexec/got-read-tag/Makefile.am
@@ -0,0 +1,21 @@
+bin_PROGRAMS = got-read-tag
+got_read_tag_SOURCES = got-read-tag.c \
+	$(top_srcdir)/lib/error.c \
+	$(top_srcdir)/lib/inflate.c \
+	$(top_srcdir)/lib/object_parse.c \
+	$(top_srcdir)/lib/path.c \
+	$(top_srcdir)/lib/privsep.c \
+	$(top_srcdir)/lib/sha1.c
+
+got_read_tag_DEPENDENCIES = $(top_builddir)/compat/libopenbsd-compat.a
+
+AM_CPPFLAGS += -DGOT_VERSION='"@VERSION@"' \
+	-DGOT_VERSION_NUMBER='"@VERSION@"' \
+	-DGOT_LIBEXEC_DIR="${bindir}" \
+	-I$(top_srcdir) \
+	-I$(top_srcdir)/compat \
+	-I$(top_srcdir)/lib \
+	-I$(top_srcdir)/include \
+	-I.
+
+LDADD = -L$(top_builddir)/compat -lopenbsd-compat
blob - 54b081f2cd307441ac03be98dfdf41222edcf15c
blob + f2c0102bd3d4652d1971eb3fbf4cfb4cf094d224
--- libexec/got-read-tag/got-read-tag.c
+++ libexec/got-read-tag/got-read-tag.c
@@ -15,12 +15,10 @@
  */
 
 #include <sys/types.h>
-#include <sys/queue.h>
 #include <sys/uio.h>
 #include <sys/time.h>
 
 #include <stdint.h>
-#include <imsg.h>
 #include <limits.h>
 #include <signal.h>
 #include <stdio.h>
@@ -30,6 +28,8 @@
 #include <unistd.h>
 #include <zlib.h>
 
+#include "got_compat.h"
+
 #include "got_error.h"
 #include "got_object.h"
 
blob - 397775d14ef4989204d535d1101a64104e7a3c0f (mode 644)
blob + /dev/null
--- libexec/got-read-tree/Makefile
+++ /dev/null
@@ -1,13 +0,0 @@
-.PATH:${.CURDIR}/../../lib
-
-.include "../../got-version.mk"
-
-PROG=		got-read-tree
-SRCS=		got-read-tree.c error.c inflate.c object_parse.c \
-		path.c privsep.c sha1.c
-
-CPPFLAGS = -I${.CURDIR}/../../include -I${.CURDIR}/../../lib
-LDADD = -lutil -lz
-DPADD = ${LIBZ} ${LIBUTIL}
-
-.include <bsd.prog.mk>
blob - /dev/null
blob + 050827f6b6202583356080ee92f2d531fd3bf1a4 (mode 644)
--- /dev/null
+++ libexec/got-read-tree/Makefile.am
@@ -0,0 +1,21 @@
+bin_PROGRAMS = got-read-tree
+got_read_tree_SOURCES = got-read-tree.c \
+	$(top_srcdir)/lib/error.c \
+	$(top_srcdir)/lib/inflate.c \
+	$(top_srcdir)/lib/object_parse.c \
+	$(top_srcdir)/lib/path.c \
+	$(top_srcdir)/lib/privsep.c \
+	$(top_srcdir)/lib/sha1.c
+
+got_read_tree_DEPENDENCIES = $(top_builddir)/compat/libopenbsd-compat.a
+
+AM_CPPFLAGS += -DGOT_VERSION='"@VERSION@"' \
+	-DGOT_VERSION_NUMBER='"@VERSION@"' \
+	-DGOT_LIBEXEC_DIR="${bindir}" \
+	-I$(top_srcdir) \
+	-I$(top_srcdir)/compat \
+	-I$(top_srcdir)/lib \
+	-I$(top_srcdir)/include \
+	-I.
+
+LDADD = -L$(top_builddir)/compat -lopenbsd-compat
blob - 95e34c068c96ce1a4a00a1ea034531e243919dfd
blob + fad33d19b6531464a1a748fc33e8fa13babd68f4
--- libexec/got-read-tree/got-read-tree.c
+++ libexec/got-read-tree/got-read-tree.c
@@ -15,12 +15,10 @@
  */
 
 #include <sys/types.h>
-#include <sys/queue.h>
 #include <sys/uio.h>
 #include <sys/time.h>
 
 #include <stdint.h>
-#include <imsg.h>
 #include <limits.h>
 #include <signal.h>
 #include <stdio.h>
@@ -30,6 +28,8 @@
 #include <unistd.h>
 #include <zlib.h>
 
+#include "got_compat.h"
+
 #include "got_error.h"
 #include "got_object.h"
 #include "got_path.h"
blob - c4d5d83a73cd53d7437213cdf349daaec168facd (mode 644)
blob + /dev/null
--- libexec/got-send-pack/Makefile
+++ /dev/null
@@ -1,13 +0,0 @@
-.PATH:${.CURDIR}/../../lib
-
-.include "../../got-version.mk"
-
-PROG=		got-send-pack
-SRCS=		got-send-pack.c error.c inflate.c object_parse.c \
-		path.c privsep.c sha1.c pkt.c gitproto.c
-
-CPPFLAGS = -I${.CURDIR}/../../include -I${.CURDIR}/../../lib
-LDADD = -lutil -lz
-DPADD = ${LIBZ} ${LIBUTIL}
-
-.include <bsd.prog.mk>
blob - /dev/null
blob + 6140278235d28f1fe0fbf7e82ab390b3c57a7277 (mode 644)
--- /dev/null
+++ libexec/got-send-pack/Makefile.am
@@ -0,0 +1,24 @@
+bin_PROGRAMS = got-send-pack
+got_send_pack_SOURCES = \
+	got-send-pack.c \
+	$(top_srcdir)/lib/error.c \
+	$(top_srcdir)/lib/inflate.c \
+	$(top_srcdir)/lib/object_parse.c \
+	$(top_srcdir)/lib/path.c \
+	$(top_srcdir)/lib/privsep.c \
+	$(top_srcdir)/lib/sha1.c \
+	$(top_srcdir)/lib/pkt.c \
+	$(top_srcdir)/lib/gitproto.c
+
+got_send_pack_DEPENDENCIES = $(top_builddir)/compat/libopenbsd-compat.a
+
+AM_CPPFLAGS += -DGOT_VERSION='"@VERSION@"' \
+	-DGOT_VERSION_NUMBER='"@VERSION@"' \
+	-DGOT_LIBEXECDIR="${bindir}" \
+	-I$(top_srcdir) \
+	-I$(top_srcdir)/compat \
+	-I$(top_srcdir)/lib \
+	-I$(top_srcdir)/include \
+	-I.
+
+LDADD = -L$(top_builddir)/compat -lopenbsd-compat
blob - 366a7752b050575027ad23ce7530ed0f5655788d
blob + 8096c808058c2f8f54fa4bb9c8c5b039a8e5a7eb
--- libexec/got-send-pack/got-send-pack.c
+++ libexec/got-send-pack/got-send-pack.c
@@ -16,14 +16,12 @@
  */
 
 #include <sys/types.h>
-#include <sys/queue.h>
 #include <sys/uio.h>
 #include <sys/time.h>
 #include <sys/stat.h>
 
 #include <stdint.h>
 #include <errno.h>
-#include <imsg.h>
 #include <limits.h>
 #include <signal.h>
 #include <stdio.h>
blob - 984dc73376528f545472d7e802bb1dc495fb001d
blob + fcbe2c0855cdccdfd3b551ae89bcec14ffeaa248
--- regress/delta/delta_test.c
+++ regress/delta/delta_test.c
@@ -14,7 +14,6 @@
  * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
  */
 
-#include <sys/queue.h>
 
 #include <stdio.h>
 #include <stdlib.h>
blob - 66452392324de31782617407a330a0cf27630880
blob + 704d9aa3a0c64012553f250e3b775c3f6a243de2
--- regress/fetch/fetch_test.c
+++ regress/fetch/fetch_test.c
@@ -14,7 +14,6 @@
  * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
  */
 
-#include <sys/queue.h>
 
 #include <limits.h>
 #include <stdarg.h>
blob - 64c131e2e42815b06f5e84d8179dd9244cee3c1f
blob + e21dea5cf4e079df6f202da96e4df788c0664262
--- regress/idset/idset_test.c
+++ regress/idset/idset_test.c
@@ -14,7 +14,6 @@
  * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
  */
 
-#include <sys/queue.h>
 
 #include <limits.h>
 #include <stdarg.h>
blob - cb17e05405edca193cab8ab4da47e83af9ed79a6
blob + da527ce4cd11db7b8e05e2b3bec1039d48bba44e
--- regress/path/path_test.c
+++ regress/path/path_test.c
@@ -14,7 +14,6 @@
  * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
  */
 
-#include <sys/queue.h>
 
 #include <string.h>
 #include <stdlib.h>
blob - 0c38c99e81144fe6d7e8fc5915eab0302808bfc3 (mode 644)
blob + /dev/null
--- tog/Makefile
+++ /dev/null
@@ -1,35 +0,0 @@
-.PATH:${.CURDIR}/../lib
-
-.include "../got-version.mk"
-
-PROG=		tog
-SRCS=		tog.c blame.c commit_graph.c delta.c diff.c \
-		diffreg.c error.c fileindex.c object.c object_cache.c \
-		object_idset.c object_parse.c opentemp.c path.c pack.c \
-		privsep.c reference.c repository.c sha1.c worktree.c \
-		utf8.c inflate.c buf.c rcsutil.c diff3.c \
-		lockfile.c deflate.c object_create.c delta_cache.c \
-		gotconfig.c diff_main.c diff_atomize_text.c \
-		diff_myers.c diff_output.c diff_output_plain.c \
-		diff_output_unidiff.c diff_output_edscript.c \
-		diff_patience.c
-MAN =		${PROG}.1
-
-CPPFLAGS = -I${.CURDIR}/../include -I${.CURDIR}/../lib
-
-.if defined(PROFILE)
-LDADD = -lpanel_p -lncursesw_p -lutil_p -lz_p -lpthread_p -lc_p
-.else
-LDADD = -lpanel -lncursesw -lutil -lz -lpthread
-.endif
-DPADD = ${LIBZ} ${LIBUTIL}
-
-.if ${GOT_RELEASE} != "Yes"
-NOMAN = Yes
-.endif
-
-realinstall:
-	${INSTALL} ${INSTALL_COPY} -o ${BINOWN} -g ${BINGRP} \
-	-m ${BINMODE} ${PROG} ${BINDIR}/${PROG}
-
-.include <bsd.prog.mk>
blob - /dev/null
blob + 3f3825f3ab509f53cf1886193cccec03dfb99724 (mode 644)
--- /dev/null
+++ tog/Makefile.am
@@ -0,0 +1,57 @@
+bin_PROGRAMS = tog
+
+tog_SOURCES = tog.c \
+	$(top_srcdir)/lib/blame.c \
+	$(top_srcdir)/lib/commit_graph.c \
+	$(top_srcdir)/lib/delta.c \
+	$(top_srcdir)/lib/diff.c \
+	$(top_srcdir)/lib/diffreg.c \
+	$(top_srcdir)/lib/error.c \
+	$(top_srcdir)/lib/fileindex.c \
+	$(top_srcdir)/lib/object.c \
+	$(top_srcdir)/lib/object_cache.c \
+	$(top_srcdir)/lib/object_idset.c \
+	$(top_srcdir)/lib/object_parse.c \
+	$(top_srcdir)/lib/opentemp.c \
+	$(top_srcdir)/lib/path.c \
+	$(top_srcdir)/lib/pack.c \
+	$(top_srcdir)/lib/privsep.c \
+	$(top_srcdir)/lib/reference.c \
+	$(top_srcdir)/lib/repository.c \
+	$(top_srcdir)/lib/sha1.c \
+	$(top_srcdir)/lib/worktree.c \
+	$(top_srcdir)/lib/inflate.c \
+	$(top_srcdir)/lib/buf.c \
+	$(top_srcdir)/lib/rcsutil.c \
+	$(top_srcdir)/lib/diff3.c \
+	$(top_srcdir)/lib/lockfile.c \
+	$(top_srcdir)/lib/deflate.c \
+	$(top_srcdir)/lib/object_create.c \
+	$(top_srcdir)/lib/delta_cache.c \
+	$(top_srcdir)/lib/fetch.c \
+	$(top_srcdir)/lib/gotconfig.c \
+	$(top_srcdir)/lib/diff_main.c \
+	$(top_srcdir)/lib/diff_atomize_text.c \
+	$(top_srcdir)/lib/diff_myers.c \
+	$(top_srcdir)/lib/diff_output.c \
+	$(top_srcdir)/lib/diff_output_plain.c \
+	$(top_srcdir)/lib/diff_output_unidiff.c \
+	$(top_srcdir)/lib/diff_output_edscript.c \
+	$(top_srcdir)/lib/diff_patience.c \
+	$(top_srcdir)/lib/utf8.c \
+	$(top_srcdir)/lib/dial.c
+
+tog_DEPENDENCIES = $(top_builddir)/compat/libopenbsd-compat.a
+
+man1_MANS = tog.1
+
+AM_CPPFLAGS += -DGOT_VERSION='"@VERSION@"' \
+	-DGOT_VERSION_NUMBER='"@VERSION@"' \
+	-DGOT_LIBEXEC_DIR="${bindir}" \
+	-I$(top_srcdir) \
+	-I$(top_srcdir)/compat \
+	-I$(top_srcdir)/lib \
+	-I$(top_srcdir)/include \
+	-I.
+
+LDADD = -L$(top_builddir)/compat -lopenbsd-compat -lutil -lpanel -lncursesw -lpthread
blob - cbf77a99b234b7a155644a3abe25adda577f1a8d
blob + 9368c448d5fc066021785fa4c63cfc10e92e46ae
--- tog/tog.c
+++ tog/tog.c
@@ -14,13 +14,11 @@
  * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
  */
 
-#include <sys/queue.h>
 #include <sys/stat.h>
 #include <sys/ioctl.h>
 
 #include <ctype.h>
 #include <errno.h>
-#define _XOPEN_SOURCE_EXTENDED /* for ncurses wide-character functions */
 #include <curses.h>
 #include <panel.h>
 #include <locale.h>
@@ -40,6 +38,8 @@
 #include <regex.h>
 #include <sched.h>
 
+#include "got_compat.h"
+
 #include "got_version.h"
 #include "got_error.h"
 #include "got_object.h"
@@ -55,6 +55,9 @@
 #include "got_path.h"
 #include "got_worktree.h"
 
+//#define update_panels() (0)
+//#define doupdate() (0)
+
 #ifndef MIN
 #define	MIN(_a,_b) ((_a) < (_b) ? (_a) : (_b))
 #endif
@@ -1725,6 +1728,8 @@ draw_commits(struct tog_view *view)
 	}
 
 	view_vborder(view);
+	update_panels();
+	doupdate();
 done:
 	free(id_str);
 	free(refs_str);
@@ -2097,7 +2102,7 @@ stop_log_thread(struct tog_log_view_state *s)
 		if (errcode)
 			return got_error_set_errno(errcode,
 			    "pthread_mutex_lock");
-		s->thread = NULL;
+		s->thread = 0; //NULL;
 	}
 
 	if (s->thread_args.repo) {
@@ -2365,7 +2370,7 @@ show_log_view(struct tog_view *view)
 	const struct got_error *err;
 	struct tog_log_view_state *s = &view->state.log;
 
-	if (s->thread == NULL) {
+	if (s->thread == 0) { //NULL) {
 		int errcode = pthread_create(&s->thread, NULL, log_thread,
 		    &s->thread_args);
 		if (errcode)
@@ -4219,7 +4224,7 @@ stop_blame(struct tog_blame *blame)
 			    "pthread_mutex_lock");
 		if (err && err->code == GOT_ERR_ITER_COMPLETED)
 			err = NULL;
-		blame->thread = NULL;
+		blame->thread = 0; //NULL;
 	}
 	if (blame->thread_args.repo) {
 		const struct got_error *close_err;
@@ -4508,7 +4513,7 @@ show_blame_view(struct tog_view *view)
 	struct tog_blame_view_state *s = &view->state.blame;
 	int errcode;
 
-	if (s->blame.thread == NULL && !s->blame_complete) {
+	if (s->blame.thread != 0 && !s->blame_complete) {
 		errcode = pthread_create(&s->blame.thread, NULL, blame_thread,
 		    &s->blame.thread_args);
 		if (errcode)