commit dd038bc6ec835ad3fd3c0b5303b8af9ad506c8cc from: Thomas Adam via: Thomas Adam date: Tue Sep 21 20:34:22 2021 UTC portable: initial Linux compilation This commit modifies the GoT main branch to be able to compile it under linux. 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 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_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 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 #include #include #include @@ -37,7 +36,8 @@ #include #include #include -#include + +#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 + * + * 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 + +#include +#include +#include +#include +#include + +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 +#include +#include +#include +#include + +#include +#include +#include + +#include +#include + +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 + * + * 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 +#include +#include +#include +#ifdef HAVE_FCNTL_H +# include +#endif +#include +#include +#include +#include +#include +#ifdef HAVE_DIRENT_H +# include +# define NAMLEN(dirent) strlen((dirent)->d_name) +#else +# define dirent direct +# define NAMLEN(dirent) (dirent)->d_namlen +# ifdef HAVE_SYS_NDIR_H +# include +# endif +# ifdef HAVE_SYS_DIR_H +# include +# endif +# ifdef HAVE_NDIR_H +# include +# 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 +#include +#include +#include +#include +#include + +#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 + * + * 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 + +#include +#include + +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 + * + * 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 + +#include +#include + +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 +#include +#include + +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 + * + * 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 + +#include + +#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 + * + * 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 +#include +#include + +#include +#include +#include +#include +#include + +#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 + * + * 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 +#include +#include + +#include +#include +#include +#include + +#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 + * Copyright (c) 2006, 2007, 2008 Reyk Floeter + * Copyright (c) 2003, 2004 Henning Brauer + * + * 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 + +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 + +#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 + +#include +#include +#include + +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 + * + * 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 +#include +#include +#include + +#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 + * + * 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 +#include +#include +#include +#include + +/* + * 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 + * + * 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 +#include + +/* + * 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 + * + * 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 +#include + +/* + * 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 + * + * 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 + +#include +#include +#include + +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 + * + * 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 + +#include + +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 +#include + +/* + * 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 +#include +#include + +#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 + * 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 +#include +#include +#include + +#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 + * Copyright (c) 1995 Tatu Ylonen , 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 +#include +#include +#include +#include +#include + +#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 + * Copyright (c) 1995 Tatu Ylonen , 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 + +#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 ], + [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 ], + [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 ] +) +AC_CHECK_DECL( + TAILQ_CONCAT, + found_queue_h=yes, + found_queue_h=no, + [#include ] +) +AC_CHECK_DECL( + TAILQ_PREV, + found_queue_h=yes, + found_queue_h=no, + [#include ] +) +AC_CHECK_DECL( + TAILQ_REPLACE, + found_queue_h=yes, + found_queue_h=no, + [#include ] +) +AC_CHECK_DECL( + SIMPLEQ_ENTRY, + , + found_queue_h=no, + [#include ] +) +AC_CHECK_DECL( + TAILQ_FOREACH_SAFE, + , + found_queue_h=no, + [#include ] +) +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 + #include + 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 #include #include 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 +#include +#include + +#include +#include +#include +#include + +/* +#include +#include +*/ + +/* 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 +#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 +#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 +#else +#include +#endif + +#ifdef HAVE_QUEUE_H +#include +#else +#include "compat/queue.h" +#endif + +#ifdef HAVE_TREE_H +#include +#else +#include "compat/tree.h" +#endif + +#ifdef HAVE_UTIL_H +#include +#endif + +#ifdef HAVE_LIBUTIL_H +#include +#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 #include #include @@ -26,8 +25,9 @@ #include #include #include -#include #include + +#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 #include #include blob - 02b48fae94b68b2e73ce447027d7d94d3be3b6c5 blob + bf42765e12770cf525a5b72369096a45e33cde0f --- lib/commit_graph.c +++ lib/commit_graph.c @@ -16,8 +16,6 @@ #include #include -#include -#include #include #include @@ -26,6 +24,8 @@ #include #include #include + +#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 #include #include 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 #include #include 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 #include #include @@ -24,6 +23,8 @@ #include #include +#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 -#include #include #include 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 #include #include #include @@ -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 #include #include @@ -24,6 +23,8 @@ #include #include +#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 -#include #include #include blob - 77f774c3d3737b31b6f815a4434406dd96458a69 blob + 11768b2c060a299839ae3a716d85f9324d6ce579 --- lib/diff_main.c +++ lib/diff_main.c @@ -16,7 +16,6 @@ */ -#include #include #include #include @@ -32,6 +31,8 @@ #include #include +#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 #include -#include #include #include #include #include +#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 #include #include @@ -26,6 +25,8 @@ #include #include +#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 #include -#include #include #include #include @@ -36,7 +35,6 @@ #include #include #include -#include #include #include 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 -#include #include #include @@ -29,6 +27,8 @@ #include #include #include + +#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 -#include #include #include @@ -39,6 +38,8 @@ #include #include +#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 #include #include 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 -#include #include #include @@ -25,10 +24,11 @@ #include #include #include -#include #include #include +#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 #include #include blob - 846038c091fec21e8c028ab14a6fcdb0ea52c913 blob + 165216e417422d26d0b171457e55841b60a1fe94 --- lib/lockfile.c +++ lib/lockfile.c @@ -15,7 +15,6 @@ */ #include -#include #include #include blob - 66e51456da85f0477bef25d1074a69d766e38fe2 blob + eaea9d8f0365e98800abb62b9edfaaceb89bb84b --- lib/object.c +++ lib/object.c @@ -16,7 +16,6 @@ #include #include -#include #include #include #include @@ -34,8 +33,9 @@ #include #include #include -#include #include + +#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 -#include #include #include blob - 70dc0d95f90464c02d691b2e2157c818079650c3 blob + 4e86317f1d38e8899d2d7bcd6a35a17c6d03ae53 --- lib/object_create.c +++ lib/object_create.c @@ -16,7 +16,6 @@ #include #include -#include #include #include @@ -30,6 +29,8 @@ #include #include +#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 -#include #include #include @@ -25,6 +23,8 @@ #include #include +#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 #include -#include #include #include #include @@ -30,9 +29,10 @@ #include #include #include -#include #include #include + +#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 #include +#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 #include -#include #include #include @@ -31,7 +30,6 @@ #include #include #include -#include #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 -#include #include #include #include -#include #include #include #include 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 #include #include @@ -30,6 +29,8 @@ #include #include +#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 -#include #include #include @@ -29,11 +28,12 @@ #include #include #include -#include #include #include #include #include + +#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 #include #include @@ -35,6 +34,8 @@ #include #include +#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 -#include #include #include @@ -27,10 +26,11 @@ #include #include #include -#include #include #include #include + +#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 -#include #include #include #include @@ -38,9 +37,10 @@ #include #include #include -#include #include +#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 #include -#include #include #include #include @@ -37,7 +36,6 @@ #include #include #include -#include #include #include blob - 167f4f59e0296904450ea74eff5e61a6cff74abb blob + 7527e3f4c10ad222e8c0ccc0033c317cc384b6e5 --- lib/utf8.c +++ lib/utf8.c @@ -23,6 +23,8 @@ #include #include +#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 -#include -#include #include #include @@ -32,8 +30,8 @@ #include #include #include -#include -#include + +#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 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 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 -#include #include #include #include #include #include -#include #include #include #include @@ -34,6 +32,8 @@ #include #include #include + +#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 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 #include #include #include @@ -24,7 +23,6 @@ #include #include -#include #include #include #include @@ -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 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 -#include #include #include #include -#include #include #include #include @@ -30,6 +28,8 @@ #include #include +#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 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 -#include #include #include #include -#include #include #include #include @@ -30,6 +28,8 @@ #include #include +#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 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 -#include #include #include #include -#include #include #include #include @@ -29,6 +27,8 @@ #include #include #include + +#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 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 -#include #include #include #include -#include #include #include #include @@ -29,6 +27,8 @@ #include #include #include + +#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 -#include #include @@ -36,6 +35,8 @@ #include #include +#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 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 -#include #include #include #include -#include #include #include #include @@ -30,6 +28,8 @@ #include #include +#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 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 -#include #include #include #include @@ -23,13 +22,14 @@ #include #include #include -#include #include #include #include #include #include #include + +#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 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 -#include #include #include #include -#include #include #include #include @@ -30,6 +28,8 @@ #include #include +#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 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 -#include #include #include #include -#include #include #include #include @@ -30,6 +28,8 @@ #include #include +#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 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 -#include #include #include #include #include #include -#include #include #include #include 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 #include #include 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 #include #include 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 #include #include 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 #include #include 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 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 #include #include #include #include -#define _XOPEN_SOURCE_EXTENDED /* for ncurses wide-character functions */ #include #include #include @@ -40,6 +38,8 @@ #include #include +#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)