Radish alpha
H
rad:z3QDZAW2FAfuLvihrhiyDC9fAD8G9
HardenedBSD Package Manager
Radicle
Git
Replace libsbuf with utstring.h to improve portability
Baptiste Daroussin committed 9 years ago
commit f93c04579b95bd99f4d2244a0c6d7fc4d56b90b5
parent 043e8f6
55 files changed +1772 -2526
modified external/Makefile.am
@@ -47,7 +47,6 @@ noinst_HEADERS= expat/amiga/expat_68k.h \
		libelf/libelf.h \
		libmachista/hashmap.h \
		libmachista/libmachista.h \
-
		libsbuf/sys/sbuf.h \
		libucl/klib/kvec.h \
		libucl/klib/khash.h \
		libucl/include/ucl.h \
@@ -63,6 +62,7 @@ noinst_HEADERS= expat/amiga/expat_68k.h \
		sqlite/sqlite3.h \
		uthash/uthash.h \
		uthash/utlist.h \
+
		uthash/utstring.h \
		include/tree.h \
		include/siphash.h \
		config.h \
@@ -75,14 +75,12 @@ noinst_HEADERS= expat/amiga/expat_68k.h \
DYNLIBS=		libucl.la \
			libsqlite.la \
			libexpat.la \
-
			libsbuf.la \
			libpicosat.la \
			libfetch.la \
			liblinenoise.la
noinst_LTLIBRARIES=	libucl_static.la \
			libsqlite_static.la \
			libexpat_static.la \
-
			libsbuf_static.la \
			libpicosat_static.la \
			libfetch_static.la \
			liblinenoise_static.la
@@ -168,13 +166,6 @@ libmachista_static_la_SOURCES= libmachista/libmachista.c \
libmachista_static_la_CFLAGS=	-I$(tip_srcdir)/external/libmachista -static
libmachista_static_la_LDFLAGS=	-all-static

-
libsbuf_la_SOURCES=	libsbuf/subr_sbuf.c
-
sbuf_common_CFLAGS=	-I$(top_srcdir)/external/libsbuf
-
libsbuf_la_CFLAGS=	$(sbuf_common_CFLAGS) -shared
-
libsbuf_static_la_SOURCES=	${libsbuf_la_SOURCES}
-
libsbuf_static_la_CFLAGS=	$(sbuf_common_CFLAGS) -static
-
libsbuf_static_la_LDFLAGS=	-all-static
-

liblinenoise_la_SOURCES=	linenoise/linenoise.c
liblinenoise_la_CFLAGS=	-shared
liblinenoise_static_la_SOURCES=	$(liblinenoise_la_SOURCES)
deleted external/libsbuf/subr_sbuf.c
@@ -1,880 +0,0 @@
-
/*-
-
 * Copyright (c) 2000-2008 Poul-Henning Kamp
-
 * Copyright (c) 2000-2008 Dag-Erling Coïdan Smørgrav
-
 * 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
-
 *    in this position and unchanged.
-
 * 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 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 AUTHOR OR CONTRIBUTORS BE LIABLE
-
 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
-
 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
-
 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
-
 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
-
 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
-
 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
-
 * SUCH DAMAGE.
-
 */
-

-
#include <sys/cdefs.h>
-
/* __FBSDID("$FreeBSD: head/sys/kern/subr_sbuf.c 288484 2015-10-02 09:23:14Z phk $"); */
-

-
#include <sys/param.h>
-
#ifndef roundup2
-
#define roundup2(x, y)  (((x)+((y)-1))&(~((y)-1))) /* if y is powers of two */
-
#endif
-

-

-
#ifdef _KERNEL
-
#include <sys/ctype.h>
-
#include <sys/errno.h>
-
#include <sys/kernel.h>
-
#include <sys/limits.h>
-
#include <sys/malloc.h>
-
#include <sys/systm.h>
-
#include <sys/uio.h>
-
#include <machine/stdarg.h>
-
#else /* _KERNEL */
-
#include <ctype.h>
-
#include <errno.h>
-
#include <limits.h>
-
#include <stdarg.h>
-
#include <stdio.h>
-
#include <stdlib.h>
-
#include <string.h>
-
#endif /* _KERNEL */
-

-
#include <sys/sbuf.h>
-

-
#ifdef _KERNEL
-
static MALLOC_DEFINE(M_SBUF, "sbuf", "string buffers");
-
#define	SBMALLOC(size)		malloc(size, M_SBUF, M_WAITOK|M_ZERO)
-
#define	SBFREE(buf)		free(buf, M_SBUF)
-
#else /* _KERNEL */
-
#define	KASSERT(e, m)
-
#define	SBMALLOC(size)		calloc(1, size)
-
#define	SBFREE(buf)		free(buf)
-
#endif /* _KERNEL */
-

-
/*
-
 * Predicates
-
 */
-
#define	SBUF_ISDYNAMIC(s)	((s)->s_flags & SBUF_DYNAMIC)
-
#define	SBUF_ISDYNSTRUCT(s)	((s)->s_flags & SBUF_DYNSTRUCT)
-
#define	SBUF_ISFINISHED(s)	((s)->s_flags & SBUF_FINISHED)
-
#define	SBUF_HASROOM(s)		((s)->s_len < (s)->s_size - 1)
-
#define	SBUF_FREESPACE(s)	((s)->s_size - ((s)->s_len + 1))
-
#define	SBUF_CANEXTEND(s)	((s)->s_flags & SBUF_AUTOEXTEND)
-
#define	SBUF_ISSECTION(s)	((s)->s_flags & SBUF_INSECTION)
-
#define	SBUF_NULINCLUDED(s)	((s)->s_flags & SBUF_INCLUDENUL)
-

-
/*
-
 * Set / clear flags
-
 */
-
#define	SBUF_SETFLAG(s, f)	do { (s)->s_flags |= (f); } while (0)
-
#define	SBUF_CLEARFLAG(s, f)	do { (s)->s_flags &= ~(f); } while (0)
-

-
#define	SBUF_MINSIZE		 2		/* Min is 1 byte + nulterm. */
-
#define	SBUF_MINEXTENDSIZE	16		/* Should be power of 2. */
-

-
#ifdef PAGE_SIZE
-
#define	SBUF_MAXEXTENDSIZE	PAGE_SIZE
-
#define	SBUF_MAXEXTENDINCR	PAGE_SIZE
-
#else
-
#define	SBUF_MAXEXTENDSIZE	4096
-
#define	SBUF_MAXEXTENDINCR	4096
-
#endif
-

-
/*
-
 * Debugging support
-
 */
-
#if defined(_KERNEL) && defined(INVARIANTS)
-

-
static void
-
_assert_sbuf_integrity(const char *fun, struct sbuf *s)
-
{
-

-
	KASSERT(s != NULL,
-
	    ("%s called with a NULL sbuf pointer", fun));
-
	KASSERT(s->s_buf != NULL,
-
	    ("%s called with uninitialized or corrupt sbuf", fun));
-
        if (SBUF_ISFINISHED(s) && SBUF_NULINCLUDED(s)) {
-
		KASSERT(s->s_len <= s->s_size,
-
		    ("wrote past end of sbuf (%jd >= %jd)",
-
		    (intmax_t)s->s_len, (intmax_t)s->s_size));
-
	} else {
-
		KASSERT(s->s_len < s->s_size,
-
		    ("wrote past end of sbuf (%jd >= %jd)",
-
		    (intmax_t)s->s_len, (intmax_t)s->s_size));
-
	}
-
}
-

-
static void
-
_assert_sbuf_state(const char *fun, struct sbuf *s, int state)
-
{
-

-
	KASSERT((s->s_flags & SBUF_FINISHED) == state,
-
	    ("%s called with %sfinished or corrupt sbuf", fun,
-
	    (state ? "un" : "")));
-
}
-

-
#define	assert_sbuf_integrity(s) _assert_sbuf_integrity(__func__, (s))
-
#define	assert_sbuf_state(s, i)	 _assert_sbuf_state(__func__, (s), (i))
-

-
#else /* _KERNEL && INVARIANTS */
-

-
#define	assert_sbuf_integrity(s) do { } while (0)
-
#define	assert_sbuf_state(s, i)	 do { } while (0)
-

-
#endif /* _KERNEL && INVARIANTS */
-

-
#ifdef CTASSERT
-
CTASSERT(powerof2(SBUF_MAXEXTENDSIZE));
-
CTASSERT(powerof2(SBUF_MAXEXTENDINCR));
-
#endif
-

-
static int
-
sbuf_extendsize(int size)
-
{
-
	int newsize;
-

-
	if (size < (int)SBUF_MAXEXTENDSIZE) {
-
		newsize = SBUF_MINEXTENDSIZE;
-
		while (newsize < size)
-
			newsize *= 2;
-
	} else {
-
		newsize = roundup2(size, SBUF_MAXEXTENDINCR);
-
	}
-
	KASSERT(newsize >= size, ("%s: %d < %d\n", __func__, newsize, size));
-
	return (newsize);
-
}
-

-
/*
-
 * Extend an sbuf.
-
 */
-
static int
-
sbuf_extend(struct sbuf *s, int addlen)
-
{
-
	char *newbuf;
-
	int newsize;
-

-
	if (!SBUF_CANEXTEND(s))
-
		return (-1);
-
	newsize = sbuf_extendsize(s->s_size + addlen);
-
	newbuf = SBMALLOC(newsize);
-
	if (newbuf == NULL)
-
		return (-1);
-
	memcpy(newbuf, s->s_buf, s->s_size);
-
	if (SBUF_ISDYNAMIC(s))
-
		SBFREE(s->s_buf);
-
	else
-
		SBUF_SETFLAG(s, SBUF_DYNAMIC);
-
	s->s_buf = newbuf;
-
	s->s_size = newsize;
-
	return (0);
-
}
-

-
/*
-
 * Initialize the internals of an sbuf.
-
 * If buf is non-NULL, it points to a static or already-allocated string
-
 * big enough to hold at least length characters.
-
 */
-
static struct sbuf *
-
sbuf_newbuf(struct sbuf *s, char *buf, int length, int flags)
-
{
-

-
	memset(s, 0, sizeof(*s));
-
	s->s_flags = flags;
-
	s->s_size = length;
-
	s->s_buf = buf;
-

-
	if ((s->s_flags & SBUF_AUTOEXTEND) == 0) {
-
		KASSERT(s->s_size >= SBUF_MINSIZE,
-
		    ("attempt to create an sbuf smaller than %d bytes",
-
		    SBUF_MINSIZE));
-
	}
-

-
	if (s->s_buf != NULL)
-
		return (s);
-

-
	if ((flags & SBUF_AUTOEXTEND) != 0)
-
		s->s_size = sbuf_extendsize(s->s_size);
-

-
	s->s_buf = SBMALLOC(s->s_size);
-
	if (s->s_buf == NULL)
-
		return (NULL);
-
	SBUF_SETFLAG(s, SBUF_DYNAMIC);
-
	return (s);
-
}
-

-
/*
-
 * Initialize an sbuf.
-
 * If buf is non-NULL, it points to a static or already-allocated string
-
 * big enough to hold at least length characters.
-
 */
-
struct sbuf *
-
sbuf_new(struct sbuf *s, char *buf, int length, int flags)
-
{
-

-
	KASSERT(length >= 0,
-
	    ("attempt to create an sbuf of negative length (%d)", length));
-
	KASSERT((flags & ~SBUF_USRFLAGMSK) == 0,
-
	    ("%s called with invalid flags", __func__));
-

-
	flags &= SBUF_USRFLAGMSK;
-
	if (s != NULL)
-
		return (sbuf_newbuf(s, buf, length, flags));
-

-
	s = SBMALLOC(sizeof(*s));
-
	if (s == NULL)
-
		return (NULL);
-
	if (sbuf_newbuf(s, buf, length, flags) == NULL) {
-
		SBFREE(s);
-
		return (NULL);
-
	}
-
	SBUF_SETFLAG(s, SBUF_DYNSTRUCT);
-
	return (s);
-
}
-

-
#ifdef _KERNEL
-
/*
-
 * Create an sbuf with uio data
-
 */
-
struct sbuf *
-
sbuf_uionew(struct sbuf *s, struct uio *uio, int *error)
-
{
-

-
	KASSERT(uio != NULL,
-
	    ("%s called with NULL uio pointer", __func__));
-
	KASSERT(error != NULL,
-
	    ("%s called with NULL error pointer", __func__));
-

-
	s = sbuf_new(s, NULL, uio->uio_resid + 1, 0);
-
	if (s == NULL) {
-
		*error = ENOMEM;
-
		return (NULL);
-
	}
-
	*error = uiomove(s->s_buf, uio->uio_resid, uio);
-
	if (*error != 0) {
-
		sbuf_delete(s);
-
		return (NULL);
-
	}
-
	s->s_len = s->s_size - 1;
-
	if (SBUF_ISSECTION(s))
-
		s->s_sect_len = s->s_size - 1;
-
	*error = 0;
-
	return (s);
-
}
-
#endif
-

-
int
-
sbuf_get_flags(struct sbuf *s)
-
{
-

-
	return (s->s_flags & SBUF_USRFLAGMSK);
-
}
-

-
void
-
sbuf_clear_flags(struct sbuf *s, int flags)
-
{
-

-
	s->s_flags &= ~(flags & SBUF_USRFLAGMSK);
-
}
-

-
void
-
sbuf_set_flags(struct sbuf *s, int flags)
-
{
-

-

-
	s->s_flags |= (flags & SBUF_USRFLAGMSK);
-
}
-

-
/*
-
 * Clear an sbuf and reset its position.
-
 */
-
void
-
sbuf_clear(struct sbuf *s)
-
{
-

-
	assert_sbuf_integrity(s);
-
	/* don't care if it's finished or not */
-

-
	SBUF_CLEARFLAG(s, SBUF_FINISHED);
-
	s->s_error = 0;
-
	s->s_len = 0;
-
	s->s_sect_len = 0;
-
}
-

-
/*
-
 * Set the sbuf's end position to an arbitrary value.
-
 * Effectively truncates the sbuf at the new position.
-
 */
-
int
-
sbuf_setpos(struct sbuf *s, ssize_t pos)
-
{
-

-
	assert_sbuf_integrity(s);
-
	assert_sbuf_state(s, 0);
-

-
	KASSERT(pos >= 0,
-
	    ("attempt to seek to a negative position (%jd)", (intmax_t)pos));
-
	KASSERT(pos < s->s_size,
-
	    ("attempt to seek past end of sbuf (%jd >= %jd)",
-
	    (intmax_t)pos, (intmax_t)s->s_size));
-
	KASSERT(!SBUF_ISSECTION(s),
-
	    ("attempt to seek when in a section"));
-

-
	if (pos < 0 || pos > s->s_len)
-
		return (-1);
-
	s->s_len = pos;
-
	return (0);
-
}
-

-
/*
-
 * Set up a drain function and argument on an sbuf to flush data to
-
 * when the sbuf buffer overflows.
-
 */
-
void
-
sbuf_set_drain(struct sbuf *s, sbuf_drain_func *func, void *ctx)
-
{
-

-
	assert_sbuf_state(s, 0);
-
	assert_sbuf_integrity(s);
-
	KASSERT(func == s->s_drain_func || s->s_len == 0,
-
	    ("Cannot change drain to %p on non-empty sbuf %p", func, s));
-
	s->s_drain_func = func;
-
	s->s_drain_arg = ctx;
-
}
-

-
/*
-
 * Call the drain and process the return.
-
 */
-
static int
-
sbuf_drain(struct sbuf *s)
-
{
-
	int len;
-

-
	KASSERT(s->s_len > 0, ("Shouldn't drain empty sbuf %p", s));
-
	KASSERT(s->s_error == 0, ("Called %s with error on %p", __func__, s));
-
	len = s->s_drain_func(s->s_drain_arg, s->s_buf, s->s_len);
-
	if (len < 0) {
-
		s->s_error = -len;
-
		return (s->s_error);
-
	}
-
	KASSERT(len > 0 && len <= s->s_len,
-
	    ("Bad drain amount %d for sbuf %p", len, s));
-
	s->s_len -= len;
-
	/*
-
	 * Fast path for the expected case where all the data was
-
	 * drained.
-
	 */
-
	if (s->s_len == 0)
-
		return (0);
-
	/*
-
	 * Move the remaining characters to the beginning of the
-
	 * string.
-
	 */
-
	memmove(s->s_buf, s->s_buf + len, s->s_len);
-
	return (0);
-
}
-

-
/*
-
 * Append bytes to an sbuf.  This is the core function for appending
-
 * to an sbuf and is the main place that deals with extending the
-
 * buffer and marking overflow.
-
 */
-
static void
-
sbuf_put_bytes(struct sbuf *s, const char *buf, size_t len)
-
{
-
	size_t n;
-

-
	assert_sbuf_integrity(s);
-
	assert_sbuf_state(s, 0);
-

-
	if (s->s_error != 0)
-
		return;
-
	while (len > 0) {
-
		if (SBUF_FREESPACE(s) <= 0) {
-
			/*
-
			 * If there is a drain, use it, otherwise extend the
-
			 * buffer.
-
			 */
-
			if (s->s_drain_func != NULL)
-
				(void)sbuf_drain(s);
-
			else if (sbuf_extend(s, len > INT_MAX ? INT_MAX : len)
-
			    < 0)
-
				s->s_error = ENOMEM;
-
			if (s->s_error != 0)
-
				return;
-
		}
-
		n = SBUF_FREESPACE(s);
-
		if (len < n)
-
			n = len;
-
		memcpy(&s->s_buf[s->s_len], buf, n);
-
		s->s_len += n;
-
		if (SBUF_ISSECTION(s))
-
			s->s_sect_len += n;
-
		len -= n;
-
		buf += n;
-
	}
-
}
-

-
static void
-
sbuf_put_byte(struct sbuf *s, char c)
-
{
-

-
	sbuf_put_bytes(s, &c, 1);
-
}
-

-
/*
-
 * Append a byte string to an sbuf.
-
 */
-
int
-
sbuf_bcat(struct sbuf *s, const void *buf, size_t len)
-
{
-

-
	sbuf_put_bytes(s, buf, len);
-
	if (s->s_error != 0)
-
		return (-1);
-
	return (0);
-
}
-

-
#ifdef _KERNEL
-
/*
-
 * Copy a byte string from userland into an sbuf.
-
 */
-
int
-
sbuf_bcopyin(struct sbuf *s, const void *uaddr, size_t len)
-
{
-

-
	assert_sbuf_integrity(s);
-
	assert_sbuf_state(s, 0);
-
	KASSERT(s->s_drain_func == NULL,
-
	    ("Nonsensical copyin to sbuf %p with a drain", s));
-

-
	if (s->s_error != 0)
-
		return (-1);
-
	if (len == 0)
-
		return (0);
-
	if (len > SBUF_FREESPACE(s)) {
-
		sbuf_extend(s, len - SBUF_FREESPACE(s));
-
		if (SBUF_FREESPACE(s) < len)
-
			len = SBUF_FREESPACE(s);
-
	}
-
	if (copyin(uaddr, s->s_buf + s->s_len, len) != 0)
-
		return (-1);
-
	s->s_len += len;
-

-
	return (0);
-
}
-
#endif
-

-
/*
-
 * Copy a byte string into an sbuf.
-
 */
-
int
-
sbuf_bcpy(struct sbuf *s, const void *buf, size_t len)
-
{
-

-
	assert_sbuf_integrity(s);
-
	assert_sbuf_state(s, 0);
-

-
	sbuf_clear(s);
-
	return (sbuf_bcat(s, buf, len));
-
}
-

-
/*
-
 * Append a string to an sbuf.
-
 */
-
int
-
sbuf_cat(struct sbuf *s, const char *str)
-
{
-
	size_t n;
-

-
	n = strlen(str);
-
	sbuf_put_bytes(s, str, n);
-
	if (s->s_error != 0)
-
		return (-1);
-
	return (0);
-
}
-

-
#ifdef _KERNEL
-
/*
-
 * Append a string from userland to an sbuf.
-
 */
-
int
-
sbuf_copyin(struct sbuf *s, const void *uaddr, size_t len)
-
{
-
	size_t done;
-

-
	assert_sbuf_integrity(s);
-
	assert_sbuf_state(s, 0);
-
	KASSERT(s->s_drain_func == NULL,
-
	    ("Nonsensical copyin to sbuf %p with a drain", s));
-

-
	if (s->s_error != 0)
-
		return (-1);
-

-
	if (len == 0)
-
		len = SBUF_FREESPACE(s);	/* XXX return 0? */
-
	if (len > SBUF_FREESPACE(s)) {
-
		sbuf_extend(s, len);
-
		if (SBUF_FREESPACE(s) < len)
-
			len = SBUF_FREESPACE(s);
-
	}
-
	switch (copyinstr(uaddr, s->s_buf + s->s_len, len + 1, &done)) {
-
	case ENAMETOOLONG:
-
		s->s_error = ENOMEM;
-
		/* fall through */
-
	case 0:
-
		s->s_len += done - 1;
-
		if (SBUF_ISSECTION(s))
-
			s->s_sect_len += done - 1;
-
		break;
-
	default:
-
		return (-1);	/* XXX */
-
	}
-

-
	return (done);
-
}
-
#endif
-

-
/*
-
 * Copy a string into an sbuf.
-
 */
-
int
-
sbuf_cpy(struct sbuf *s, const char *str)
-
{
-

-
	assert_sbuf_integrity(s);
-
	assert_sbuf_state(s, 0);
-

-
	sbuf_clear(s);
-
	return (sbuf_cat(s, str));
-
}
-

-
/*
-
 * Format the given argument list and append the resulting string to an sbuf.
-
 */
-
#ifdef _KERNEL
-

-
/*
-
 * Append a non-NUL character to an sbuf.  This prototype signature is
-
 * suitable for use with kvprintf(9).
-
 */
-
static void
-
sbuf_putc_func(int c, void *arg)
-
{
-

-
	if (c != '\0')
-
		sbuf_put_byte(arg, c);
-
}
-

-
int
-
sbuf_vprintf(struct sbuf *s, const char *fmt, va_list ap)
-
{
-

-
	assert_sbuf_integrity(s);
-
	assert_sbuf_state(s, 0);
-

-
	KASSERT(fmt != NULL,
-
	    ("%s called with a NULL format string", __func__));
-

-
	(void)kvprintf(fmt, sbuf_putc_func, s, 10, ap);
-
	if (s->s_error != 0)
-
		return (-1);
-
	return (0);
-
}
-
#else /* !_KERNEL */
-
int
-
sbuf_vprintf(struct sbuf *s, const char *fmt, va_list ap)
-
{
-
	va_list ap_copy;
-
	int error, len;
-

-
	assert_sbuf_integrity(s);
-
	assert_sbuf_state(s, 0);
-

-
	KASSERT(fmt != NULL,
-
	    ("%s called with a NULL format string", __func__));
-

-
	if (s->s_error != 0)
-
		return (-1);
-

-
	/*
-
	 * For the moment, there is no way to get vsnprintf(3) to hand
-
	 * back a character at a time, to push everything into
-
	 * sbuf_putc_func() as was done for the kernel.
-
	 *
-
	 * In userspace, while drains are useful, there's generally
-
	 * not a problem attempting to malloc(3) on out of space.  So
-
	 * expand a userland sbuf if there is not enough room for the
-
	 * data produced by sbuf_[v]printf(3).
-
	 */
-

-
	error = 0;
-
	do {
-
		va_copy(ap_copy, ap);
-
		len = vsnprintf(&s->s_buf[s->s_len], SBUF_FREESPACE(s) + 1,
-
		    fmt, ap_copy);
-
		if (len < 0) {
-
			s->s_error = errno;
-
			return (-1);
-
		}
-
		va_end(ap_copy);
-

-
		if (SBUF_FREESPACE(s) >= len)
-
			break;
-
		/* Cannot print with the current available space. */
-
		if (s->s_drain_func != NULL && s->s_len > 0)
-
			error = sbuf_drain(s);
-
		else
-
			error = sbuf_extend(s, len - SBUF_FREESPACE(s));
-
	} while (error == 0);
-

-
	/*
-
	 * s->s_len is the length of the string, without the terminating nul.
-
	 * When updating s->s_len, we must subtract 1 from the length that
-
	 * we passed into vsnprintf() because that length includes the
-
	 * terminating nul.
-
	 *
-
	 * vsnprintf() returns the amount that would have been copied,
-
	 * given sufficient space, so don't over-increment s_len.
-
	 */
-
	if (SBUF_FREESPACE(s) < len)
-
		len = SBUF_FREESPACE(s);
-
	s->s_len += len;
-
	if (SBUF_ISSECTION(s))
-
		s->s_sect_len += len;
-
	if (!SBUF_HASROOM(s) && !SBUF_CANEXTEND(s))
-
		s->s_error = ENOMEM;
-

-
	KASSERT(s->s_len < s->s_size,
-
	    ("wrote past end of sbuf (%d >= %d)", s->s_len, s->s_size));
-

-
	if (s->s_error != 0)
-
		return (-1);
-
	return (0);
-
}
-
#endif /* _KERNEL */
-

-
/*
-
 * Format the given arguments and append the resulting string to an sbuf.
-
 */
-
int
-
sbuf_printf(struct sbuf *s, const char *fmt, ...)
-
{
-
	va_list ap;
-
	int result;
-

-
	va_start(ap, fmt);
-
	result = sbuf_vprintf(s, fmt, ap);
-
	va_end(ap);
-
	return (result);
-
}
-

-
/*
-
 * Append a character to an sbuf.
-
 */
-
int
-
sbuf_putc(struct sbuf *s, int c)
-
{
-

-
	sbuf_put_byte(s, c);
-
	if (s->s_error != 0)
-
		return (-1);
-
	return (0);
-
}
-

-
/*
-
 * Trim whitespace characters from end of an sbuf.
-
 */
-
int
-
sbuf_trim(struct sbuf *s)
-
{
-

-
	assert_sbuf_integrity(s);
-
	assert_sbuf_state(s, 0);
-
	KASSERT(s->s_drain_func == NULL,
-
	    ("%s makes no sense on sbuf %p with drain", __func__, s));
-

-
	if (s->s_error != 0)
-
		return (-1);
-

-
	while (s->s_len > 0 && isspace(s->s_buf[s->s_len-1])) {
-
		--s->s_len;
-
		if (SBUF_ISSECTION(s))
-
			s->s_sect_len--;
-
	}
-

-
	return (0);
-
}
-

-
/*
-
 * Check if an sbuf has an error.
-
 */
-
int
-
sbuf_error(const struct sbuf *s)
-
{
-

-
	return (s->s_error);
-
}
-

-
/*
-
 * Finish off an sbuf.
-
 */
-
int
-
sbuf_finish(struct sbuf *s)
-
{
-

-
	assert_sbuf_integrity(s);
-
	assert_sbuf_state(s, 0);
-

-
	s->s_buf[s->s_len] = '\0';
-
	if (SBUF_NULINCLUDED(s))
-
		s->s_len++;
-
	if (s->s_drain_func != NULL) {
-
		while (s->s_len > 0 && s->s_error == 0)
-
			s->s_error = sbuf_drain(s);
-
	}
-
	SBUF_SETFLAG(s, SBUF_FINISHED);
-
#ifdef _KERNEL
-
	return (s->s_error);
-
#else
-
	if (s->s_error != 0) {
-
		errno = s->s_error;
-
		return (-1);
-
	}
-
	return (0);
-
#endif
-
}
-

-
/*
-
 * Return a pointer to the sbuf data.
-
 */
-
char *
-
sbuf_data(struct sbuf *s)
-
{
-

-
	assert_sbuf_integrity(s);
-
	assert_sbuf_state(s, SBUF_FINISHED);
-
	KASSERT(s->s_drain_func == NULL,
-
	    ("%s makes no sense on sbuf %p with drain", __func__, s));
-

-
	return (s->s_buf);
-
}
-

-
/*
-
 * Return the length of the sbuf data.
-
 */
-
ssize_t
-
sbuf_len(struct sbuf *s)
-
{
-

-
	assert_sbuf_integrity(s);
-
	/* don't care if it's finished or not */
-
	KASSERT(s->s_drain_func == NULL,
-
	    ("%s makes no sense on sbuf %p with drain", __func__, s));
-

-
	if (s->s_error != 0)
-
		return (-1);
-

-
	/* If finished, nulterm is already in len, else add one. */
-
	if (SBUF_NULINCLUDED(s) && !SBUF_ISFINISHED(s))
-
		return (s->s_len + 1);
-
	return (s->s_len);
-
}
-

-
/*
-
 * Clear an sbuf, free its buffer if necessary.
-
 */
-
void
-
sbuf_delete(struct sbuf *s)
-
{
-
	int isdyn;
-

-
	assert_sbuf_integrity(s);
-
	/* don't care if it's finished or not */
-

-
	if (SBUF_ISDYNAMIC(s))
-
		SBFREE(s->s_buf);
-
	isdyn = SBUF_ISDYNSTRUCT(s);
-
	memset(s, 0, sizeof(*s));
-
	if (isdyn)
-
		SBFREE(s);
-
}
-

-
/*
-
 * Check if an sbuf has been finished.
-
 */
-
int
-
sbuf_done(const struct sbuf *s)
-
{
-

-
	return (SBUF_ISFINISHED(s));
-
}
-

-
/*
-
 * Start a section.
-
 */
-
void
-
sbuf_start_section(struct sbuf *s, ssize_t *old_lenp)
-
{
-

-
	assert_sbuf_integrity(s);
-
	assert_sbuf_state(s, 0);
-

-
	if (!SBUF_ISSECTION(s)) {
-
		KASSERT(s->s_sect_len == 0,
-
		    ("s_sect_len != 0 when starting a section"));
-
		if (old_lenp != NULL)
-
			*old_lenp = -1;
-
		SBUF_SETFLAG(s, SBUF_INSECTION);
-
	} else {
-
		KASSERT(old_lenp != NULL,
-
		    ("s_sect_len should be saved when starting a subsection"));
-
		*old_lenp = s->s_sect_len;
-
		s->s_sect_len = 0;
-
	}
-
}
-

-
/*
-
 * End the section padding to the specified length with the specified
-
 * character.
-
 */
-
ssize_t
-
sbuf_end_section(struct sbuf *s, ssize_t old_len, size_t pad, int c)
-
{
-
	ssize_t len;
-

-
	assert_sbuf_integrity(s);
-
	assert_sbuf_state(s, 0);
-
	KASSERT(SBUF_ISSECTION(s),
-
	    ("attempt to end a section when not in a section"));
-

-
	if (pad > 1) {
-
		len = roundup(s->s_sect_len, pad) - s->s_sect_len;
-
		for (; s->s_error == 0 && len > 0; len--)
-
			sbuf_put_byte(s, c);
-
	}
-
	len = s->s_sect_len;
-
	if (old_len == -1) {
-
		s->s_sect_len = 0;
-
		SBUF_CLEARFLAG(s, SBUF_INSECTION);
-
	} else {
-
		s->s_sect_len += old_len;
-
	}
-
	if (s->s_error != 0)
-
		return (-1);
-
	return (len);
-
}
deleted external/libsbuf/sys/sbuf.h
@@ -1,111 +0,0 @@
-
/*-
-
 * Copyright (c) 2000-2008 Poul-Henning Kamp
-
 * Copyright (c) 2000-2008 Dag-Erling Coïdan Smørgrav
-
 * 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
-
 *    in this position and unchanged.
-
 * 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 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 AUTHOR 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.
-
 *
-
 *      $FreeBSD: head/sys/sys/sbuf.h 284192 2015-06-09 21:39:38Z ken $
-
 */
-

-
#ifndef _SYS_SBUF_H_
-
#define	_SYS_SBUF_H_
-

-
#include <sys/types.h>
-

-
struct sbuf;
-
typedef int (sbuf_drain_func)(void *, const char *, int);
-

-
/*
-
 * Structure definition
-
 */
-
struct sbuf {
-
	char		*s_buf;		/* storage buffer */
-
	sbuf_drain_func	*s_drain_func;	/* drain function */
-
	void		*s_drain_arg;	/* user-supplied drain argument */
-
	int		 s_error;	/* current error code */
-
	ssize_t		 s_size;	/* size of storage buffer */
-
	ssize_t		 s_len;		/* current length of string */
-
#define	SBUF_FIXEDLEN	0x00000000	/* fixed length buffer (default) */
-
#define	SBUF_AUTOEXTEND	0x00000001	/* automatically extend buffer */
-
#define	SBUF_INCLUDENUL	0x00000002	/* nulterm byte is counted in len */
-
#define	SBUF_USRFLAGMSK	0x0000ffff	/* mask of flags the user may specify */
-
#define	SBUF_DYNAMIC	0x00010000	/* s_buf must be freed */
-
#define	SBUF_FINISHED	0x00020000	/* set by sbuf_finish() */
-
#define	SBUF_DYNSTRUCT	0x00080000	/* sbuf must be freed */
-
#define	SBUF_INSECTION	0x00100000	/* set by sbuf_start_section() */
-
	int		 s_flags;	/* flags */
-
	ssize_t		 s_sect_len;	/* current length of section */
-
};
-

-
#ifndef HD_COLUMN_MASK
-
#define	HD_COLUMN_MASK	0xff
-
#define	HD_DELIM_MASK	0xff00
-
#define	HD_OMIT_COUNT	(1 << 16)
-
#define	HD_OMIT_HEX	(1 << 17)
-
#define	HD_OMIT_CHARS	(1 << 18)
-
#endif /* HD_COLUMN_MASK */
-

-
__BEGIN_DECLS
-
/*
-
 * API functions
-
 */
-
struct sbuf	*sbuf_new(struct sbuf *, char *, int, int);
-
#define		 sbuf_new_auto()				\
-
	sbuf_new(NULL, NULL, 0, SBUF_AUTOEXTEND)
-
int		 sbuf_get_flags(struct sbuf *);
-
void		 sbuf_clear_flags(struct sbuf *, int);
-
void		 sbuf_set_flags(struct sbuf *, int);
-
void		 sbuf_clear(struct sbuf *);
-
int		 sbuf_setpos(struct sbuf *, ssize_t);
-
int		 sbuf_bcat(struct sbuf *, const void *, size_t);
-
int		 sbuf_bcpy(struct sbuf *, const void *, size_t);
-
int		 sbuf_cat(struct sbuf *, const char *);
-
int		 sbuf_cpy(struct sbuf *, const char *);
-
int		 sbuf_printf(struct sbuf *, const char *, ...)
-
	__printflike(2, 3);
-
int		 sbuf_vprintf(struct sbuf *, const char *, __va_list)
-
	__printflike(2, 0);
-
int		 sbuf_putc(struct sbuf *, int);
-
void		 sbuf_set_drain(struct sbuf *, sbuf_drain_func *, void *);
-
int		 sbuf_trim(struct sbuf *);
-
int		 sbuf_error(const struct sbuf *);
-
int		 sbuf_finish(struct sbuf *);
-
char		*sbuf_data(struct sbuf *);
-
ssize_t		 sbuf_len(struct sbuf *);
-
int		 sbuf_done(const struct sbuf *);
-
void		 sbuf_delete(struct sbuf *);
-
void		 sbuf_start_section(struct sbuf *, ssize_t *);
-
ssize_t		 sbuf_end_section(struct sbuf *, ssize_t, size_t, int);
-
void		 sbuf_hexdump(struct sbuf *, const void *, int, const char *,
-
		     int);
-

-
#ifdef _KERNEL
-
struct uio;
-
struct sbuf	*sbuf_uionew(struct sbuf *, struct uio *, int *);
-
int		 sbuf_bcopyin(struct sbuf *, const void *, size_t);
-
int		 sbuf_copyin(struct sbuf *, const void *, size_t);
-
#endif
-
__END_DECLS
-

-
#endif
added external/uthash/utstring.h
@@ -0,0 +1,398 @@
+
/*
+
Copyright (c) 2008-2016, Troy D. Hanson   http://troydhanson.github.com/uthash/
+
All rights reserved.
+

+
Redistribution and use in source and binary forms, with or without
+
modification, are permitted provided that the following conditions are met:
+

+
    * Redistributions of source code must retain the above copyright
+
      notice, this list of conditions and the following disclaimer.
+

+
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS 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 COPYRIGHT OWNER
+
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.
+
*/
+

+
/* a dynamic string implementation using macros
+
 */
+
#ifndef UTSTRING_H
+
#define UTSTRING_H
+

+
#define UTSTRING_VERSION 2.0.1
+

+
#ifdef __GNUC__
+
#define _UNUSED_ __attribute__ ((__unused__))
+
#else
+
#define _UNUSED_
+
#endif
+

+
#include <stdlib.h>
+
#include <string.h>
+
#include <stdio.h>
+
#include <stdarg.h>
+

+
#ifndef oom
+
#define oom() exit(-1)
+
#endif
+

+
typedef struct {
+
    char *d;
+
    size_t n; /* allocd size */
+
    size_t i; /* index of first unused byte */
+
} UT_string;
+

+
#define utstring_reserve(s,amt)                            \
+
do {                                                       \
+
  if (((s)->n - (s)->i) < (size_t)(amt)) {                 \
+
    char *utstring_tmp = (char*)realloc(                   \
+
      (s)->d, (s)->n + (amt));                             \
+
    if (utstring_tmp == NULL) oom();                       \
+
    (s)->d = utstring_tmp;                                 \
+
    (s)->n += (amt);                                       \
+
  }                                                        \
+
} while(0)
+

+
#define utstring_init(s)                                   \
+
do {                                                       \
+
  (s)->n = 0; (s)->i = 0; (s)->d = NULL;                   \
+
  utstring_reserve(s,100);                                 \
+
  (s)->d[0] = '\0';                                        \
+
} while(0)
+

+
#define utstring_done(s)                                   \
+
do {                                                       \
+
  if ((s)->d != NULL) free((s)->d);                        \
+
  (s)->n = 0;                                              \
+
} while(0)
+

+
#define utstring_free(s)                                   \
+
do {                                                       \
+
  utstring_done(s);                                        \
+
  free(s);                                                 \
+
} while(0)
+

+
#define utstring_new(s)                                    \
+
do {                                                       \
+
   s = (UT_string*)calloc(sizeof(UT_string),1);            \
+
   if (!s) oom();                                          \
+
   utstring_init(s);                                       \
+
} while(0)
+

+
#define utstring_renew(s)                                  \
+
do {                                                       \
+
   if (s) {                                                \
+
     utstring_clear(s);                                    \
+
   } else {                                                \
+
     utstring_new(s);                                      \
+
   }                                                       \
+
} while(0)
+

+
#define utstring_clear(s)                                  \
+
do {                                                       \
+
  (s)->i = 0;                                              \
+
  (s)->d[0] = '\0';                                        \
+
} while(0)
+

+
#define utstring_bincpy(s,b,l)                             \
+
do {                                                       \
+
  utstring_reserve((s),(l)+1);                             \
+
  if (l) memcpy(&(s)->d[(s)->i], b, l);                    \
+
  (s)->i += (l);                                           \
+
  (s)->d[(s)->i]='\0';                                     \
+
} while(0)
+

+
#define utstring_concat(dst,src)                                 \
+
do {                                                             \
+
  utstring_reserve((dst),((src)->i)+1);                          \
+
  if ((src)->i) memcpy(&(dst)->d[(dst)->i], (src)->d, (src)->i); \
+
  (dst)->i += (src)->i;                                          \
+
  (dst)->d[(dst)->i]='\0';                                       \
+
} while(0)
+

+
#define utstring_len(s) ((unsigned)((s)->i))
+

+
#define utstring_body(s) ((s)->d)
+

+
_UNUSED_ static void utstring_printf_va(UT_string *s, const char *fmt, va_list ap) {
+
   int n;
+
   va_list cp;
+
   for (;;) {
+
#ifdef _WIN32
+
      cp = ap;
+
#else
+
      va_copy(cp, ap);
+
#endif
+
      n = vsnprintf (&s->d[s->i], s->n-s->i, fmt, cp);
+
      va_end(cp);
+

+
      if ((n > -1) && ((size_t) n < (s->n-s->i))) {
+
        s->i += n;
+
        return;
+
      }
+

+
      /* Else try again with more space. */
+
      if (n > -1) utstring_reserve(s,n+1); /* exact */
+
      else utstring_reserve(s,(s->n)*2);   /* 2x */
+
   }
+
}
+
#ifdef __GNUC__
+
/* support printf format checking (2=the format string, 3=start of varargs) */
+
static void utstring_printf(UT_string *s, const char *fmt, ...)
+
  __attribute__ (( format( printf, 2, 3) ));
+
#endif
+
_UNUSED_ static void utstring_printf(UT_string *s, const char *fmt, ...) {
+
   va_list ap;
+
   va_start(ap,fmt);
+
   utstring_printf_va(s,fmt,ap);
+
   va_end(ap);
+
}
+

+
/*******************************************************************************
+
 * begin substring search functions                                            *
+
 ******************************************************************************/
+
/* Build KMP table from left to right. */
+
_UNUSED_ static void _utstring_BuildTable(
+
    const char *P_Needle,
+
    size_t P_NeedleLen,
+
    long *P_KMP_Table)
+
{
+
    long i, j;
+

+
    i = 0;
+
    j = i - 1;
+
    P_KMP_Table[i] = j;
+
    while (i < (long) P_NeedleLen)
+
    {
+
        while ( (j > -1) && (P_Needle[i] != P_Needle[j]) )
+
        {
+
           j = P_KMP_Table[j];
+
        }
+
        i++;
+
        j++;
+
        if (i < (long) P_NeedleLen)
+
        {
+
            if (P_Needle[i] == P_Needle[j])
+
            {
+
                P_KMP_Table[i] = P_KMP_Table[j];
+
            }
+
            else
+
            {
+
                P_KMP_Table[i] = j;
+
            }
+
        }
+
        else
+
        {
+
            P_KMP_Table[i] = j;
+
        }
+
    }
+

+
    return;
+
}
+

+

+
/* Build KMP table from right to left. */
+
_UNUSED_ static void _utstring_BuildTableR(
+
    const char *P_Needle,
+
    size_t P_NeedleLen,
+
    long *P_KMP_Table)
+
{
+
    long i, j;
+

+
    i = P_NeedleLen - 1;
+
    j = i + 1;
+
    P_KMP_Table[i + 1] = j;
+
    while (i >= 0)
+
    {
+
        while ( (j < (long) P_NeedleLen) && (P_Needle[i] != P_Needle[j]) )
+
        {
+
           j = P_KMP_Table[j + 1];
+
        }
+
        i--;
+
        j--;
+
        if (i >= 0)
+
        {
+
            if (P_Needle[i] == P_Needle[j])
+
            {
+
                P_KMP_Table[i + 1] = P_KMP_Table[j + 1];
+
            }
+
            else
+
            {
+
                P_KMP_Table[i + 1] = j;
+
            }
+
        }
+
        else
+
        {
+
            P_KMP_Table[i + 1] = j;
+
        }
+
    }
+

+
    return;
+
}
+

+

+
/* Search data from left to right. ( Multiple search mode. ) */
+
_UNUSED_ static long _utstring_find(
+
    const char *P_Haystack,
+
    size_t P_HaystackLen,
+
    const char *P_Needle,
+
    size_t P_NeedleLen,
+
    long *P_KMP_Table)
+
{
+
    long i, j;
+
    long V_FindPosition = -1;
+

+
    /* Search from left to right. */
+
    i = j = 0;
+
    while ( (j < (int)P_HaystackLen) && (((P_HaystackLen - j) + i) >= P_NeedleLen) )
+
    {
+
        while ( (i > -1) && (P_Needle[i] != P_Haystack[j]) )
+
        {
+
            i = P_KMP_Table[i];
+
        }
+
        i++;
+
        j++;
+
        if (i >= (int)P_NeedleLen)
+
        {
+
            /* Found. */
+
            V_FindPosition = j - i;
+
            break;
+
        }
+
    }
+

+
    return V_FindPosition;
+
}
+

+

+
/* Search data from right to left. ( Multiple search mode. ) */
+
_UNUSED_ static long _utstring_findR(
+
    const char *P_Haystack,
+
    size_t P_HaystackLen,
+
    const char *P_Needle,
+
    size_t P_NeedleLen,
+
    long *P_KMP_Table)
+
{
+
    long i, j;
+
    long V_FindPosition = -1;
+

+
    /* Search from right to left. */
+
    j = (P_HaystackLen - 1);
+
    i = (P_NeedleLen - 1);
+
    while ( (j >= 0) && (j >= i) )
+
    {
+
        while ( (i < (int)P_NeedleLen) && (P_Needle[i] != P_Haystack[j]) )
+
        {
+
            i = P_KMP_Table[i + 1];
+
        }
+
        i--;
+
        j--;
+
        if (i < 0)
+
        {
+
            /* Found. */
+
            V_FindPosition = j + 1;
+
            break;
+
        }
+
    }
+

+
    return V_FindPosition;
+
}
+

+

+
/* Search data from left to right. ( One time search mode. ) */
+
_UNUSED_ static long utstring_find(
+
    UT_string *s,
+
    long P_StartPosition,   /* Start from 0. -1 means last position. */
+
    const char *P_Needle,
+
    size_t P_NeedleLen)
+
{
+
    long V_StartPosition;
+
    long V_HaystackLen;
+
    long *V_KMP_Table;
+
    long V_FindPosition = -1;
+

+
    if (P_StartPosition < 0)
+
    {
+
        V_StartPosition = s->i + P_StartPosition;
+
    }
+
    else
+
    {
+
        V_StartPosition = P_StartPosition;
+
    }
+
    V_HaystackLen = s->i - V_StartPosition;
+
    if ( (V_HaystackLen >= (long) P_NeedleLen) && (P_NeedleLen > 0) )
+
    {
+
        V_KMP_Table = (long *)malloc(sizeof(long) * (P_NeedleLen + 1));
+
        if (V_KMP_Table != NULL)
+
        {
+
            _utstring_BuildTable(P_Needle, P_NeedleLen, V_KMP_Table);
+

+
            V_FindPosition = _utstring_find(s->d + V_StartPosition,
+
                                            V_HaystackLen,
+
                                            P_Needle,
+
                                            P_NeedleLen,
+
                                            V_KMP_Table);
+
            if (V_FindPosition >= 0)
+
            {
+
                V_FindPosition += V_StartPosition;
+
            }
+

+
            free(V_KMP_Table);
+
        }
+
    }
+

+
    return V_FindPosition;
+
}
+

+

+
/* Search data from right to left. ( One time search mode. ) */
+
_UNUSED_ static long utstring_findR(
+
    UT_string *s,
+
    long P_StartPosition,   /* Start from 0. -1 means last position. */
+
    const char *P_Needle,
+
    size_t P_NeedleLen)
+
{
+
    long V_StartPosition;
+
    long V_HaystackLen;
+
    long *V_KMP_Table;
+
    long V_FindPosition = -1;
+

+
    if (P_StartPosition < 0)
+
    {
+
        V_StartPosition = s->i + P_StartPosition;
+
    }
+
    else
+
    {
+
        V_StartPosition = P_StartPosition;
+
    }
+
    V_HaystackLen = V_StartPosition + 1;
+
    if ( (V_HaystackLen >= (long) P_NeedleLen) && (P_NeedleLen > 0) )
+
    {
+
        V_KMP_Table = (long *)malloc(sizeof(long) * (P_NeedleLen + 1));
+
        if (V_KMP_Table != NULL)
+
        {
+
            _utstring_BuildTableR(P_Needle, P_NeedleLen, V_KMP_Table);
+

+
            V_FindPosition = _utstring_findR(s->d,
+
                                             V_HaystackLen,
+
                                             P_Needle,
+
                                             P_NeedleLen,
+
                                             V_KMP_Table);
+

+
            free(V_KMP_Table);
+
        }
+
    }
+

+
    return V_FindPosition;
+
}
+
/*******************************************************************************
+
 * end substring search functions                                              *
+
 ******************************************************************************/
+

+
#endif /* UTSTRING_H */
modified libpkg/Makefile.am
@@ -4,7 +4,6 @@ pkg_common_cflags= -I$(top_srcdir)/libpkg -I$(top_builddir)/libpkg \
			@LDNS_CFLAGS@ \
			-I$(top_srcdir)/external/libfetch \
			-I$(top_srcdir)/compat \
-
			-I$(top_srcdir)/external/libsbuf \
			-I$(top_srcdir)/external/expat/lib \
			-I$(top_srcdir)/external/libucl/include \
			-I$(top_srcdir)/external/libucl/klib \
@@ -82,7 +81,6 @@ libpkg_la_LIBADD= $(top_builddir)/compat/libbsd_compat.la \
			$(top_builddir)/external/libucl.la \
			$(top_builddir)/external/libsqlite.la \
			$(top_builddir)/external/libexpat.la \
-
			$(top_builddir)/external/libsbuf.la \
			$(top_builddir)/external/libpicosat.la \
			$(top_builddir)/external/libfetch.la \
			$(top_builddir)/external/liblinenoise.la \
@@ -128,7 +126,6 @@ libpkg_static_la_LIBADD= $(top_builddir)/external/libucl_static.la \
			$(top_builddir)/external/libsqlite_static.la \
			$(top_builddir)/external/libexpat_static.la \
			$(top_builddir)/external/libpicosat_static.la \
-
			$(top_builddir)/external/libsbuf_static.la \
			$(top_builddir)/external/libfetch_static.la \
			$(top_builddir)/external/liblinenoise_static.la \
			$(top_builddir)/external/blake2/libblake2_static.la \
modified libpkg/diff.c
@@ -19,10 +19,10 @@
** text files.
*/
#include <sys/types.h>
-
#include <sys/sbuf.h>

#include <string.h>
#include <stdlib.h>
+
#include <utstring.h>

#include "private/utils.h"

modified libpkg/fetch.c
@@ -333,7 +333,7 @@ start_ssh(struct pkg_repo *repo, struct url *u, off_t *sz)
	char *line = NULL;
	size_t linecap = 0;
	size_t linelen;
-
	struct sbuf *cmd = NULL;
+
	UT_string *cmd = NULL;
	const char *errstr;
	const char *ssh_args;
	int sshin[2];
@@ -364,25 +364,24 @@ start_ssh(struct pkg_repo *repo, struct url *u, off_t *sz)
				goto ssh_cleanup;
			}

-
			cmd = sbuf_new_auto();
-
			sbuf_cat(cmd, "/usr/bin/ssh -e none -T ");
+
			utstring_new(cmd);
+
			utstring_printf(cmd, "/usr/bin/ssh -e none -T ");
			if (ssh_args != NULL)
-
				sbuf_printf(cmd, "%s ", ssh_args);
+
				utstring_printf(cmd, "%s ", ssh_args);
			if ((repo->flags & REPO_FLAGS_USE_IPV4) == REPO_FLAGS_USE_IPV4)
-
				sbuf_cat(cmd, "-4 ");
+
				utstring_printf(cmd, "-4 ");
			else if ((repo->flags & REPO_FLAGS_USE_IPV6) == REPO_FLAGS_USE_IPV6)
-
				sbuf_cat(cmd, "-6 ");
+
				utstring_printf(cmd, "-6 ");
			if (u->port > 0)
-
				sbuf_printf(cmd, "-p %d ", u->port);
+
				utstring_printf(cmd, "-p %d ", u->port);
			if (u->user[0] != '\0')
-
				sbuf_printf(cmd, "%s@", u->user);
-
			sbuf_cat(cmd, u->host);
-
			sbuf_printf(cmd, " pkg ssh");
-
			sbuf_finish(cmd);
-
			pkg_debug(1, "Fetch: running '%s'", sbuf_data(cmd));
+
				utstring_printf(cmd, "%s@", u->user);
+
			utstring_printf(cmd, u->host);
+
			utstring_printf(cmd, " pkg ssh");
+
			pkg_debug(1, "Fetch: running '%s'", utstring_body(cmd));
			argv[0] = _PATH_BSHELL;
			argv[1] = "-c";
-
			argv[2] = sbuf_data(cmd);
+
			argv[2] = utstring_body(cmd);
			argv[3] = NULL;

			if (sshin[0] != STDIN_FILENO)
@@ -450,7 +449,7 @@ ssh_cleanup:
		repo->ssh = NULL;
	}
	if (cmd != NULL)
-
		sbuf_delete(cmd);
+
		utstring_free(cmd);
	free(line);
	return (retcode);
}
@@ -482,7 +481,7 @@ pkg_fetch_file_to_fd(struct pkg_repo *repo, const char *url, int dest,
	size_t		 left = 0;
	bool		 pkg_url_scheme = false;
	pid_t		 pid;
-
	struct sbuf	*fetchOpts = NULL;
+
	UT_string	*fetchOpts = NULL;
	struct passwd	*nobody;
	struct rlimit	rl_zero;

@@ -621,19 +620,19 @@ pkg_fetch_file_to_fd(struct pkg_repo *repo, const char *url, int dest,
			u->port = http_current->url->port;
		}

-
		fetchOpts = sbuf_new_auto();
-
		sbuf_cat(fetchOpts, "i");
+
		utstring_new(fetchOpts);
+
		utstring_printf(fetchOpts, "i");
		if (repo != NULL) {
			if ((repo->flags & REPO_FLAGS_USE_IPV4) ==
			    REPO_FLAGS_USE_IPV4)
-
				sbuf_cat(fetchOpts, "4");
+
				utstring_printf(fetchOpts, "4");
			else if ((repo->flags & REPO_FLAGS_USE_IPV6) ==
			    REPO_FLAGS_USE_IPV6)
-
				sbuf_cat(fetchOpts, "6");
+
				utstring_printf(fetchOpts, "6");
		}

		if (debug_level >= 4)
-
			sbuf_cat(fetchOpts, "v");
+
			utstring_printf(fetchOpts, "v");

		pkg_debug(1,"Fetch: fetching from: %s://%s%s%s%s with opts \"%s\"",
		    u->scheme,
@@ -641,14 +640,12 @@ pkg_fetch_file_to_fd(struct pkg_repo *repo, const char *url, int dest,
		    u->user[0] != '\0' ? "@" : "",
		    u->host,
		    u->doc,
-
		    sbuf_data(fetchOpts));
-

-
		sbuf_finish(fetchOpts);
+
		    utstring_body(fetchOpts));

		if (offset > 0)
			u->offset = offset;
-
		remote = fetchXGet(u, &st, sbuf_data(fetchOpts));
-
		sbuf_delete(fetchOpts);
+
		remote = fetchXGet(u, &st, utstring_body(fetchOpts));
+
		utstring_free(fetchOpts);
		if (remote == NULL) {
			if (fetchLastErrCode == FETCH_OK) {
				retcode = EPKG_UPTODATE;
modified libpkg/libpkg.ver
@@ -135,8 +135,8 @@ global:
	pkg_repos_activated_count;
	pkg_repos_total_count;
	pkg_requires;
-
	pkg_sbuf_printf;
-
	pkg_sbuf_vprintf;
+
	pkg_utstring_printf;
+
	pkg_utstring_vprintf;
	pkg_script_get;
	pkg_set2;
	pkg_set_debug_level;
modified libpkg/merge3.c
@@ -50,7 +50,7 @@
*/

#include <sys/types.h>
-
#include <sys/sbuf.h>
+
#include <utstring.h>

#include <string.h>
#include <stdlib.h>
@@ -113,7 +113,7 @@ static int sameEdit(
*/

static int
-
sbuf_copy_lines(struct sbuf *to, const char *from, int N)
+
buf_copy_lines(UT_string *to, const char *from, int N)
{
	int cnt = 0;
	int i;
@@ -132,7 +132,7 @@ sbuf_copy_lines(struct sbuf *to, const char *from, int N)
		i++;
	}
	if (to)
-
		sbuf_bcat(to, from, i);
+
		utstring_bincpy(to, from, i);
	return (i);
}

@@ -149,14 +149,14 @@ sbuf_copy_lines(struct sbuf *to, const char *from, int N)
** of conflicts is returns
*/
static int
-
sbuf_merge(char *pPivot, char *pV1, char *pV2, struct sbuf *pOut){
+
buf_merge(char *pPivot, char *pV1, char *pV2, UT_string *pOut){
  int *aC1;              /* Changes from pPivot to pV1 */
  int *aC2;              /* Changes from pPivot to pV2 */
  int i1, i2;            /* Index into aC1[] and aC2[] */
  int nCpy, nDel, nIns;  /* Number of lines to copy, delete, or insert */
  int limit1, limit2;    /* Sizes of aC1[] and aC2[] */

-
  sbuf_clear(pOut);         /* Merge results stored in pOut */
+
  utstring_clear(pOut);         /* Merge results stored in pOut */

  /* Compute the edits that occur from pPivot => pV1 (into aC1)
  ** and pPivot => pV2 (into aC2).  Each of the aC1 and aC2 arrays is
@@ -191,9 +191,9 @@ sbuf_merge(char *pPivot, char *pV1, char *pV2, struct sbuf *pOut){
    if( aC1[i1]>0 && aC2[i2]>0 ){
      /* Output text that is unchanged in both V1 and V2 */
      nCpy = min(aC1[i1], aC2[i2]);
-
      pPivot += sbuf_copy_lines(pOut, pPivot, nCpy);
-
      pV1 += sbuf_copy_lines(NULL, pV1, nCpy);
-
      pV2 += sbuf_copy_lines(NULL, pV2, nCpy);
+
      pPivot += buf_copy_lines(pOut, pPivot, nCpy);
+
      pV1 += buf_copy_lines(NULL, pV1, nCpy);
+
      pV2 += buf_copy_lines(NULL, pV2, nCpy);
      aC1[i1] -= nCpy;
      aC2[i2] -= nCpy;
    }else
@@ -201,9 +201,9 @@ sbuf_merge(char *pPivot, char *pV1, char *pV2, struct sbuf *pOut){
      /* Output edits to V2 that occurs within unchanged regions of V1 */
      nDel = aC2[i2+1];
      nIns = aC2[i2+2];
-
      pPivot += sbuf_copy_lines(NULL, pPivot, nDel);
-
      pV1 += sbuf_copy_lines(NULL, pV1, nDel);
-
      pV2 += sbuf_copy_lines(pOut, pV2, nIns);
+
      pPivot += buf_copy_lines(NULL, pPivot, nDel);
+
      pV1 += buf_copy_lines(NULL, pV1, nDel);
+
      pV2 += buf_copy_lines(pOut, pV2, nIns);
      aC1[i1] -= nDel;
      i2 += 3;
    }else
@@ -211,9 +211,9 @@ sbuf_merge(char *pPivot, char *pV1, char *pV2, struct sbuf *pOut){
      /* Output edits to V1 that occur within unchanged regions of V2 */
      nDel = aC1[i1+1];
      nIns = aC1[i1+2];
-
      pPivot += sbuf_copy_lines(NULL, pPivot, nDel);
-
      pV2 += sbuf_copy_lines(NULL, pV2, nDel);
-
      pV1 += sbuf_copy_lines(pOut, pV1, nIns);
+
      pPivot += buf_copy_lines(NULL, pPivot, nDel);
+
      pV2 += buf_copy_lines(NULL, pV2, nDel);
+
      pV1 += buf_copy_lines(pOut, pV1, nIns);
      aC2[i2] -= nDel;
      i1 += 3;
    }else
@@ -221,9 +221,9 @@ sbuf_merge(char *pPivot, char *pV1, char *pV2, struct sbuf *pOut){
      /* Output edits that are identical in both V1 and V2. */
      nDel = aC1[i1+1];
      nIns = aC1[i1+2];
-
      pPivot += sbuf_copy_lines(NULL, pPivot, nDel);
-
      pV1 += sbuf_copy_lines(pOut, pV1, nIns);
-
      pV2 += sbuf_copy_lines(NULL, pV2, nIns);
+
      pPivot += buf_copy_lines(NULL, pPivot, nDel);
+
      pV1 += buf_copy_lines(pOut, pV1, nIns);
+
      pV2 += buf_copy_lines(NULL, pV2, nIns);
      i1 += 3;
      i2 += 3;
    }else
@@ -243,9 +243,9 @@ sbuf_merge(char *pPivot, char *pV1, char *pV2, struct sbuf *pOut){
  ** insert.
  */
  if( i1<limit1 && aC1[i1+2]>0 ){
-
    sbuf_copy_lines(pOut, pV1, aC1[i1+2]);
+
    buf_copy_lines(pOut, pV1, aC1[i1+2]);
  }else if( i2<limit2 && aC2[i2+2]>0 ){
-
    sbuf_copy_lines(pOut, pV2, aC2[i2+2]);
+
    buf_copy_lines(pOut, pV2, aC2[i2+2]);
  }

  free(aC1);
@@ -274,11 +274,10 @@ int merge_3way(
  char *pPivot,       /* Common ancestor (older) */
  char *pV1,    /* Name of file for version merging into (mine) */
  char *pV2,          /* Version merging from (yours) */
-
  struct sbuf *pOut         /* Output written here */
+
  UT_string *pOut         /* Output written here */
){
  int rc;             /* Return code of subroutines and this routine */

-
  rc = sbuf_merge(pPivot, pV1, pV2, pOut);
-
  sbuf_finish(pOut);
+
  rc = buf_merge(pPivot, pV1, pV2, pOut);
  return rc;
}
modified libpkg/packing.c
@@ -304,7 +304,7 @@ packing_append_tree(struct packing *pack, const char *treepath,
	FTS *fts = NULL;
	FTSENT *fts_e = NULL;
	size_t treelen;
-
	struct sbuf *sb;
+
	UT_string *sb;
	char *paths[2] = { __DECONST(char *, treepath), NULL };

	treelen = strlen(treepath);
@@ -312,7 +312,7 @@ packing_append_tree(struct packing *pack, const char *treepath,
	if (fts == NULL)
		goto cleanup;

-
	sb = sbuf_new_auto();
+
	utstring_new(sb);
	while ((fts_e = fts_read(fts)) != NULL) {
		switch(fts_e->fts_info) {
		case FTS_D:
@@ -323,15 +323,14 @@ packing_append_tree(struct packing *pack, const char *treepath,
			 /* Entries not within this tree are irrelevant. */
			 if (fts_e->fts_pathlen <= treelen)
				  break;
-
			 sbuf_clear(sb);
+
			 utstring_clear(sb);
			 /* Strip the prefix to obtain the target path */
			 if (newroot) /* Prepend a root if one is specified */
-
				  sbuf_cat(sb, newroot);
+
				  utstring_printf(sb, "%s", newroot);
			 /* +1 = skip trailing slash */
-
			 sbuf_cat(sb, fts_e->fts_path + treelen + 1);
-
			 sbuf_finish(sb);
+
			 utstring_printf(sb, "%s", fts_e->fts_path + treelen + 1);
			 packing_append_file_attr(pack, fts_e->fts_name,
-
			    sbuf_data(sb), NULL, NULL, 0, 0);
+
			    utstring_body(sb), NULL, NULL, 0, 0);
			 break;
		case FTS_DC:
		case FTS_DNR:
@@ -344,7 +343,7 @@ packing_append_tree(struct packing *pack, const char *treepath,
			 break;
		}
	}
-
	sbuf_free(sb);
+
	utstring_free(sb);
cleanup:
	fts_close(fts);
	return EPKG_OK;
modified libpkg/pkg.c
@@ -89,7 +89,8 @@ pkg_free(struct pkg *pkg)
	free(pkg->dep_formula);

	for (int i = 0; i < PKG_NUM_SCRIPTS; i++)
-
		sbuf_free(pkg->scripts[i]);
+
		if (pkg->scripts[i])
+
			utstring_free(pkg->scripts[i]);

	pkg_list_free(pkg, PKG_DEPS);
	pkg_list_free(pkg, PKG_RDEPS);
@@ -860,11 +861,10 @@ pkg_adddir_attr(struct pkg *pkg, const char *path, const char *uname,
int
pkg_addscript(struct pkg *pkg, const char *data, pkg_script type)
{
-
	struct sbuf **sbuf;

	assert(pkg != NULL);
-
	sbuf = &pkg->scripts[type];
-
	sbuf_set(sbuf, data);
+
	utstring_renew(pkg->scripts[type]);
+
	utstring_printf(pkg->scripts[type], "%s", data);

	return (EPKG_OK);
}
@@ -987,17 +987,14 @@ cleanup:
int
pkg_appendscript(struct pkg *pkg, const char *cmd, pkg_script type)
{
-
	struct sbuf **s;

	assert(pkg != NULL);
	assert(cmd != NULL && cmd[0] != '\0');

-
	if (pkg_script_get(pkg, type) == NULL)
-
		return (pkg_addscript(pkg, cmd, type));
+
	if (pkg->scripts[type] == NULL)
+
		utstring_new(pkg->scripts[type]);

-
	s = &pkg->scripts[type];
-
	sbuf_cat(*s, cmd);
-
	sbuf_finish(*s);
+
	utstring_printf(pkg->scripts[type], "%s", cmd);

	return (EPKG_OK);
}
modified libpkg/pkg.h.in
@@ -43,7 +43,6 @@ extern "C" {
#include <stdarg.h>
#include <stdbool.h>
#include <stdio.h>
-
#include <sys/sbuf.h>
#include <sysexits.h>

/* The expected name of the pkg(8) binary executable. */
@@ -1618,6 +1617,7 @@ int pkg_asprintf(char **ret, const char * restrict format, ...);
 */
int pkg_vasprintf(char **ret, const char * restrict format, va_list ap);

+
#if defined(UTSTRING_H)
/**
 * store data from pkg into sbuf as indicated by the format code format.
 * @param sbuf contains the result
@@ -1625,7 +1625,7 @@ int pkg_vasprintf(char **ret, const char * restrict format, va_list ap);
 * @param format String with embedded %-escapes indicating what to output
 * @return count of the number of characters in the result
 */
-
struct sbuf *pkg_sbuf_printf(struct sbuf * restrict sbuf,
+
UT_string *pkg_utstring_printf(UT_string * restrict sbuf,
	const char * restrict format, ...);

/**
@@ -1636,8 +1636,9 @@ struct sbuf *pkg_sbuf_printf(struct sbuf * restrict sbuf,
 * @param format String with embedded %-escapes indicating what to output
 * @return count of the number of characters in the result
 */
-
struct sbuf *pkg_sbuf_vprintf(struct sbuf * restrict sbuf,
+
UT_string *pkg_utstring_vprintf(UT_string * restrict sbuf,
	const char * restrict format, va_list ap);
+
#endif

bool pkg_has_message(struct pkg *p);
bool pkg_need_message(struct pkg *p, struct pkg *old);
@@ -1688,6 +1689,7 @@ int pkg_audit_load(struct pkg_audit *audit, const char *fname);
 */
int pkg_audit_process(struct pkg_audit *audit);

+
#if defined(UTSTRING_H)
/**
 * Check whether `pkg` is vulnerable against processed `audit` structure.
 * If a package is vulnerable, then `result` is set to sbuf describing the
@@ -1697,7 +1699,8 @@ int pkg_audit_process(struct pkg_audit *audit);
 * @return true and `*result` is set if a package is vulnerable
 */
bool pkg_audit_is_vulnerable(struct pkg_audit *audit, struct pkg *pkg,
-
		bool quiet, struct sbuf **result);
+
		bool quiet, UT_string **result);
+
#endif

void pkg_audit_free (struct pkg_audit *audit);
char *pkg_utils_tokenize(char **);
modified libpkg/pkg_add.c
@@ -42,6 +42,7 @@
#include <grp.h>
#include <sys/time.h>
#include <time.h>
+
#include <utstring.h>

#include "pkg.h"
#include "private/event.h"
@@ -108,7 +109,7 @@ attempt_to_merge(int rootfd, struct pkg_config_file *rcf, struct pkg *local,
    bool merge)
{
	const struct pkg_file *lf = NULL;
-
	struct sbuf *newconf;
+
	UT_string *newconf;
	struct pkg_config_file *lcf = NULL;

	char *localconf = NULL;
@@ -161,15 +162,14 @@ attempt_to_merge(int rootfd, struct pkg_config_file *rcf, struct pkg *local,
	}

	pkg_debug(1, "Attempting to merge %s", rcf->path);
-
	newconf = sbuf_new_auto();
+
	utstring_new(newconf);
	if (merge_3way(lcf->content, localconf, rcf->content, newconf) != 0) {
		pkg_emit_error("Impossible to merge configuration file");
	} else {
-
		sbuf_finish(newconf);
-
		rcf->newcontent = strdup(sbuf_data(newconf));
+
		rcf->newcontent = strdup(utstring_body(newconf));
		rcf->status = MERGE_SUCCESS;
	}
-
	sbuf_delete(newconf);
+
	utstring_free(newconf);
	free(localconf);
}

@@ -931,7 +931,7 @@ pkg_add_common(struct pkgdb *db, const char *path, unsigned flags,
	struct archive		*a;
	struct archive_entry	*ae;
	struct pkg		*pkg = NULL;
-
	struct sbuf		*message;
+
	UT_string		*message;
	struct pkg_message	*msg;
	const char		*msgstr;
	bool			 extract = true;
@@ -1087,7 +1087,7 @@ cleanup_reg:
	}

	if (pkg->message != NULL)
-
		message = sbuf_new_auto();
+
		utstring_new(message);
	LL_FOREACH(pkg->message, msg) {
		msgstr = NULL;
		if (msg->type == PKG_MESSAGE_ALWAYS) {
@@ -1114,19 +1114,18 @@ cleanup_reg:
			msgstr = msg->str;
		}
		if (msgstr != NULL) {
-
			if (sbuf_len(message) == 0) {
-
				pkg_sbuf_printf(message, "Message from "
+
			if (utstring_len(message) == 0) {
+
				pkg_utstring_printf(message, "Message from "
				    "%n-%v:\n", pkg, pkg);
			}
-
			sbuf_printf(message, "%s\n", msgstr);
+
			utstring_printf(message, "%s\n", msgstr);
		}
	}
	if (pkg->message != NULL) {
-
		if (sbuf_len(message) > 0) {
-
			sbuf_finish(message);
-
			pkg_emit_message(sbuf_data(message));
+
		if (utstring_len(message) > 0) {
+
			pkg_emit_message(utstring_body(message));
		}
-
		sbuf_delete(message);
+
		utstring_free(message);
	}

	cleanup:
modified libpkg/pkg_attributes.c
@@ -141,10 +141,7 @@ pkg_script_get(struct pkg const * const p, pkg_script i)
	if (p->scripts[i] == NULL)
		return (NULL);

-
	if (sbuf_done(p->scripts[i]) == 0)
-
		sbuf_finish(p->scripts[i]);
-

-
	return (sbuf_data(p->scripts[i]));
+
	return (utstring_body(p->scripts[i]));
}

/*
modified libpkg/pkg_audit.c
@@ -722,58 +722,57 @@ pkg_audit_version_match(const char *pkgversion, struct pkg_audit_version *v)
}

static void
-
pkg_audit_print_versions(struct pkg_audit_entry *e, struct sbuf *sb)
+
pkg_audit_print_versions(struct pkg_audit_entry *e, UT_string *sb)
{
	struct pkg_audit_versions_range *vers;

-
	sbuf_cat(sb, "Affected versions:\n");
+
	utstring_printf(sb, "%s", "Affected versions:\n");
	LL_FOREACH(e->versions, vers) {
		if (vers->v1.type > 0 && vers->v2.type > 0)
-
			sbuf_printf(sb, "%s %s : %s %s\n",
+
			utstring_printf(sb, "%s %s : %s %s\n",
				vop_names[vers->v1.type], vers->v1.version,
				vop_names[vers->v2.type], vers->v2.version);
		else if (vers->v1.type > 0)
-
			sbuf_printf(sb, "%s %s\n",
+
			utstring_printf(sb, "%s %s\n",
				vop_names[vers->v1.type], vers->v1.version);
		else
-
			sbuf_printf(sb, "%s %s\n",
+
			utstring_printf(sb, "%s %s\n",
				vop_names[vers->v2.type], vers->v2.version);
	}
}

static void
-
pkg_audit_print_entry(struct pkg_audit_entry *e, struct sbuf *sb,
+
pkg_audit_print_entry(struct pkg_audit_entry *e, UT_string *sb,
	const char *pkgname, const char *pkgversion, bool quiet)
{
	struct pkg_audit_cve *cve;

	if (quiet) {
		if (pkgversion != NULL)
-
			sbuf_printf(sb, "%s-%s\n", pkgname, pkgversion);
+
			utstring_printf(sb, "%s-%s\n", pkgname, pkgversion);
		else
-
			sbuf_printf(sb, "%s\n", pkgname);
-
		sbuf_finish(sb);
+
			utstring_printf(sb, "%s\n", pkgname);
	} else {
		if (pkgversion != NULL)
-
			sbuf_printf(sb, "%s-%s is vulnerable:\n", pkgname, pkgversion);
+
			utstring_printf(sb, "%s-%s is vulnerable:\n", pkgname, pkgversion);
		else {
-
			sbuf_printf(sb, "%s is vulnerable:\n", pkgname);
+
			utstring_printf(sb, "%s is vulnerable:\n", pkgname);
			pkg_audit_print_versions(e, sb);
		}

-
		sbuf_printf(sb, "%s\n", e->desc);
+
		utstring_printf(sb, "%s\n", e->desc);
		/* XXX: for vulnxml we should use more clever approach indeed */
		if (e->cve) {
			cve = e->cve;
			while (cve) {
-
				sbuf_printf(sb, "CVE: %s\n", cve->cvename);
+
				utstring_printf(sb, "CVE: %s\n", cve->cvename);
				cve = cve->next;
			}
		}
		if (e->url)
-
			sbuf_printf(sb, "WWW: %s\n\n", e->url);
+
			utstring_printf(sb, "WWW: %s\n\n", e->url);
		else if (e->id)
-
			sbuf_printf(sb,
+
			utstring_printf(sb,
				"WWW: https://vuxml.FreeBSD.org/freebsd/%s.html\n\n",
				e->id);
	}
@@ -781,11 +780,11 @@ pkg_audit_print_entry(struct pkg_audit_entry *e, struct sbuf *sb,

bool
pkg_audit_is_vulnerable(struct pkg_audit *audit, struct pkg *pkg,
-
		bool quiet, struct sbuf **result)
+
		bool quiet, UT_string **result)
{
	struct pkg_audit_entry *e;
	struct pkg_audit_versions_range *vers;
-
	struct sbuf *sb;
+
	UT_string *sb;
	struct pkg_audit_item *a;
	bool res = false, res1, res2;

@@ -794,7 +793,7 @@ pkg_audit_is_vulnerable(struct pkg_audit *audit, struct pkg *pkg,

	a = audit->items;
	a += audit_entry_first_byte_idx[(size_t)pkg->name[0]];
-
	sb = sbuf_new_auto();
+
	utstring_new(sb);

	for (; (e = a->e) != NULL; a += a->next_pfx_incr) {
		int cmp;
@@ -843,11 +842,9 @@ pkg_audit_is_vulnerable(struct pkg_audit *audit, struct pkg *pkg,

out:
	if (res) {
-
		sbuf_finish(sb);
		*result = sb;
-
	}
-
	else {
-
		sbuf_delete(sb);
+
	} else {
+
		utstring_free(sb);
	}

	return (res);
modified libpkg/pkg_config.c
@@ -845,7 +845,7 @@ pkg_ini(const char *path, const char *reposdir, pkg_init_flags flags)
	const ucl_object_t *cur, *object;
	ucl_object_t *obj = NULL, *o, *ncfg;
	ucl_object_iter_t it = NULL;
-
	struct sbuf *ukey = NULL;
+
	UT_string *ukey = NULL;
	bool fatal_errors = false;
	int conffd = -1;
	char *tmp = NULL;
@@ -977,22 +977,21 @@ pkg_ini(const char *path, const char *reposdir, pkg_init_flags flags)
		close(conffd);

	ncfg = NULL;
-
	ukey = sbuf_new_auto();
+
	utstring_new(ukey);
	while (obj != NULL && (cur = ucl_iterate_object(obj, &it, true))) {
-
		sbuf_reset(ukey);
+
		utstring_clear(ukey);
		key = ucl_object_key(cur);
		for (i = 0; key[i] != '\0'; i++)
-
			sbuf_putc(ukey, toupper(key[i]));
-
		sbuf_finish(ukey);
-
		object = ucl_object_find_keyl(config, sbuf_data(ukey), sbuf_len(ukey));
-

-
		if (strncasecmp(sbuf_data(ukey), "PACKAGESITE", sbuf_len(ukey))
-
		    == 0 || strncasecmp(sbuf_data(ukey), "PUBKEY",
-
		    sbuf_len(ukey)) == 0 || strncasecmp(sbuf_data(ukey),
-
		    "MIRROR_TYPE", sbuf_len(ukey)) == 0) {
+
			utstring_printf(ukey, "%c", toupper(key[i]));
+
		object = ucl_object_find_keyl(config, utstring_body(ukey), utstring_len(ukey));
+

+
		if (strncasecmp(utstring_body(ukey), "PACKAGESITE", utstring_len(ukey))
+
		    == 0 || strncasecmp(utstring_body(ukey), "PUBKEY",
+
		    utstring_len(ukey)) == 0 || strncasecmp(utstring_body(ukey),
+
		    "MIRROR_TYPE", utstring_len(ukey)) == 0) {
			pkg_emit_error("%s in pkg.conf is no longer "
			    "supported.  Convert to the new repository style."
-
			    "  See pkg.conf(5)", sbuf_data(ukey));
+
			    "  See pkg.conf(5)", utstring_body(ukey));
			fatal_errors = true;
			continue;
		}
@@ -1008,9 +1007,9 @@ pkg_ini(const char *path, const char *reposdir, pkg_init_flags flags)

		if (ncfg == NULL)
			ncfg = ucl_object_typed_new(UCL_OBJECT);
-
		ucl_object_insert_key(ncfg, ucl_object_copy(cur), sbuf_data(ukey), sbuf_len(ukey), true);
+
		ucl_object_insert_key(ncfg, ucl_object_copy(cur), utstring_body(ukey), utstring_len(ukey), true);
	}
-
	sbuf_delete(ukey);
+
	utstring_free(ukey);

	if (fatal_errors) {
		ucl_object_unref(ncfg);
modified libpkg/pkg_create.c
@@ -120,17 +120,17 @@ pkg_create_from_dir(struct pkg *pkg, const char *root,
	 * Register shared libraries used by the package if
	 * SHLIBS enabled in conf.  Deletes shlib info if not.
	 */
-
	struct sbuf *b = sbuf_new_auto();
+
	UT_string *b;
+
	utstring_new(b);

	pkg_analyse_files(NULL, pkg, root);

-
	pkg_emit_manifest_sbuf(pkg, b, PKG_MANIFEST_EMIT_COMPACT, NULL);
-
	packing_append_buffer(pkg_archive, sbuf_data(b), "+COMPACT_MANIFEST", sbuf_len(b));
-
	sbuf_clear(b);
-
	pkg_emit_manifest_sbuf(pkg, b, 0, NULL);
-
	sbuf_finish(b);
-
	packing_append_buffer(pkg_archive, sbuf_data(b), "+MANIFEST", sbuf_len(b));
-
	sbuf_delete(b);
+
	pkg_emit_manifest_buf(pkg, b, PKG_MANIFEST_EMIT_COMPACT, NULL);
+
	packing_append_buffer(pkg_archive, utstring_body(b), "+COMPACT_MANIFEST", utstring_len(b));
+
	utstring_clear(b);
+
	pkg_emit_manifest_buf(pkg, b, 0, NULL);
+
	packing_append_buffer(pkg_archive, utstring_body(b), "+MANIFEST", utstring_len(b));
+
	utstring_free(b);

	counter_init("packing files", nfiles);

modified libpkg/pkg_delete.c
@@ -38,6 +38,7 @@
#include <unistd.h>
#include <stdlib.h>
#include <fcntl.h>
+
#include <utstring.h>

#include <bsd_compat.h>

@@ -57,7 +58,7 @@ int
pkg_delete(struct pkg *pkg, struct pkgdb *db, unsigned flags)
{
	struct pkg_message	*msg;
-
	struct sbuf	*message;
+
	UT_string	*message = NULL;
	int		 ret;
	bool		 handle_rc = false;
	const unsigned load_flags = PKG_LOAD_RDEPS|PKG_LOAD_FILES|PKG_LOAD_DIRS|
@@ -113,23 +114,21 @@ pkg_delete(struct pkg *pkg, struct pkgdb *db, unsigned flags)

	if ((flags & PKG_DELETE_UPGRADE) == 0) {
		pkg_emit_deinstall_finished(pkg);
-
		if (pkg->message != NULL)
-
			message = sbuf_new_auto();
+
		utstring_renew(message);
		LL_FOREACH(pkg->message, msg) {
			if (msg->type == PKG_MESSAGE_REMOVE) {
-
				if (sbuf_len(message) == 0) {
-
					pkg_sbuf_printf(message, "Message from "
+
				if (utstring_len(message) == 0) {
+
					pkg_utstring_printf(message, "Message from "
					    "%n-%v:\n", pkg, pkg);
				}
-
				sbuf_printf(message, "%s\n", msg->str);
+
				utstring_printf(message, "%s\n", msg->str);
			}
		}
		if (pkg->message != NULL) {
-
			if (sbuf_len(message) > 0) {
-
				sbuf_finish(message);
-
				pkg_emit_message(sbuf_data(message));
+
			if (utstring_len(message) > 0) {
+
				pkg_emit_message(utstring_body(message));
			}
-
			sbuf_delete(message);
+
			utstring_free(message);
		}

	}
modified libpkg/pkg_event.c
@@ -29,6 +29,7 @@
#include <errno.h>
#include <string.h>
#include <syslog.h>
+
#include <utstring.h>

#include "pkg.h"
#include "private/pkg.h"
@@ -38,18 +39,17 @@ static pkg_event_cb _cb = NULL;
static void *_data = NULL;

static char *
-
sbuf_json_escape(struct sbuf *buf, const char *str)
+
buf_json_escape(UT_string *buf, const char *str)
{
-
	sbuf_clear(buf);
+
	utstring_clear(buf);
	while (str != NULL && *str != '\0') {
		if (*str == '"' || *str == '\\')
-
			sbuf_putc(buf, '\\');
-
		sbuf_putc(buf, *str);
+
			utstring_printf(buf, "%c", '\\');
+
		utstring_printf(buf, "%c", *str);
		str++;
	}
-
	sbuf_finish(buf);

-
	return (sbuf_data(buf));
+
	return (utstring_body(buf));
}

static void
@@ -57,42 +57,42 @@ pipeevent(struct pkg_event *ev)
{
	int i;
	struct pkg_dep *dep = NULL;
-
	struct sbuf *msg, *buf;
+
	UT_string *msg, *buf;
	struct pkg_event_conflict *cur_conflict;
	if (eventpipe < 0)
		return;

-
	msg = sbuf_new_auto();
-
	buf = sbuf_new_auto();
+
	utstring_new(msg);
+
	utstring_new(buf);

	switch(ev->type) {
	case PKG_EVENT_ERRNO:
-
		sbuf_printf(msg, "{ \"type\": \"ERROR\", "
+
		utstring_printf(msg, "{ \"type\": \"ERROR\", "
		    "\"data\": {"
		    "\"msg\": \"%s(%s): %s\","
		    "\"errno\": %d}}",
-
		    sbuf_json_escape(buf, ev->e_errno.func),
-
		    sbuf_json_escape(buf, ev->e_errno.arg),
-
		    sbuf_json_escape(buf, strerror(ev->e_errno.no)),
+
		    buf_json_escape(buf, ev->e_errno.func),
+
		    buf_json_escape(buf, ev->e_errno.arg),
+
		    buf_json_escape(buf, strerror(ev->e_errno.no)),
		    ev->e_errno.no);
		break;
	case PKG_EVENT_ERROR:
-
		sbuf_printf(msg, "{ \"type\": \"ERROR\", "
+
		utstring_printf(msg, "{ \"type\": \"ERROR\", "
		    "\"data\": {\"msg\": \"%s\"}}",
-
		    sbuf_json_escape(buf, ev->e_pkg_error.msg));
+
		    buf_json_escape(buf, ev->e_pkg_error.msg));
		break;
	case PKG_EVENT_NOTICE:
-
		sbuf_printf(msg, "{ \"type\": \"NOTICE\", "
+
		utstring_printf(msg, "{ \"type\": \"NOTICE\", "
		    "\"data\": {\"msg\": \"%s\"}}",
-
		    sbuf_json_escape(buf, ev->e_pkg_notice.msg));
+
		    buf_json_escape(buf, ev->e_pkg_notice.msg));
		break;
	case PKG_EVENT_DEVELOPER_MODE:
-
		sbuf_printf(msg, "{ \"type\": \"ERROR\", "
+
		utstring_printf(msg, "{ \"type\": \"ERROR\", "
		    "\"data\": {\"msg\": \"DEVELOPER_MODE: %s\"}}",
-
		    sbuf_json_escape(buf, ev->e_pkg_error.msg));
+
		    buf_json_escape(buf, ev->e_pkg_error.msg));
		break;
	case PKG_EVENT_UPDATE_ADD:
-
		sbuf_printf(msg, "{ \"type\": \"INFO_UPDATE_ADD\", "
+
		utstring_printf(msg, "{ \"type\": \"INFO_UPDATE_ADD\", "
		    "\"data\": { "
		    "\"fetched\": %d, "
		    "\"total\": %d"
@@ -102,7 +102,7 @@ pipeevent(struct pkg_event *ev)
		    );
		break;
	case PKG_EVENT_UPDATE_REMOVE:
-
		sbuf_printf(msg, "{ \"type\": \"INFO_UPDATE_REMOVE\", "
+
		utstring_printf(msg, "{ \"type\": \"INFO_UPDATE_REMOVE\", "
		    "\"data\": { "
		    "\"fetched\": %d, "
		    "\"total\": %d"
@@ -112,44 +112,44 @@ pipeevent(struct pkg_event *ev)
		    );
		break;
	case PKG_EVENT_FETCH_BEGIN:
-
		sbuf_printf(msg, "{ \"type\": \"INFO_FETCH_BEGIN\", "
+
		utstring_printf(msg, "{ \"type\": \"INFO_FETCH_BEGIN\", "
		    "\"data\": { "
		    "\"url\": \"%s\" "
		    "}}",
-
		    sbuf_json_escape(buf, ev->e_fetching.url)
+
		    buf_json_escape(buf, ev->e_fetching.url)
		    );
		break;
	case PKG_EVENT_FETCH_FINISHED:
-
		sbuf_printf(msg, "{ \"type\": \"INFO_FETCH_FINISHED\", "
+
		utstring_printf(msg, "{ \"type\": \"INFO_FETCH_FINISHED\", "
		    "\"data\": { "
		    "\"url\": \"%s\" "
		    "}}",
-
		    sbuf_json_escape(buf, ev->e_fetching.url)
+
		    buf_json_escape(buf, ev->e_fetching.url)
		    );
		break;
	case PKG_EVENT_INSTALL_BEGIN:
-
		pkg_sbuf_printf(msg, "{ \"type\": \"INFO_INSTALL_BEGIN\", "
+
		pkg_utstring_printf(msg, "{ \"type\": \"INFO_INSTALL_BEGIN\", "
		    "\"data\": { "
		    "\"pkgname\": \"%n\", "
		    "\"pkgversion\": \"%v\""
		    "}}", ev->e_install_begin.pkg, ev->e_install_begin.pkg);
		break;
	case PKG_EVENT_EXTRACT_BEGIN:
-
		pkg_sbuf_printf(msg, "{ \"type\": \"INFO_EXTRACT_BEGIN\", "
+
		pkg_utstring_printf(msg, "{ \"type\": \"INFO_EXTRACT_BEGIN\", "
		    "\"data\": { "
		    "\"pkgname\": \"%n\", "
		    "\"pkgversion\": \"%v\""
		    "}}", ev->e_extract_begin.pkg, ev->e_extract_begin.pkg);
		break;
	case PKG_EVENT_EXTRACT_FINISHED:
-
		pkg_sbuf_printf(msg, "{ \"type\": \"INFO_EXTRACT_FINISHED\", "
+
		pkg_utstring_printf(msg, "{ \"type\": \"INFO_EXTRACT_FINISHED\", "
		    "\"data\": { "
		    "\"pkgname\": \"%n\", "
		    "\"pkgversion\": \"%v\""
		    "}}", ev->e_extract_finished.pkg, ev->e_extract_finished.pkg);
		break;
	case PKG_EVENT_INSTALL_FINISHED:
-
		pkg_sbuf_printf(msg, "{ \"type\": \"INFO_INSTALL_FINISHED\", "
+
		pkg_utstring_printf(msg, "{ \"type\": \"INFO_INSTALL_FINISHED\", "
		    "\"data\": { "
		    "\"pkgname\": \"%n\", "
		    "\"pkgversion\": \"%v\", "
@@ -158,15 +158,15 @@ pipeevent(struct pkg_event *ev)
		    ev->e_install_finished.pkg,
		    ev->e_install_finished.pkg,
			ev->e_install_finished.pkg->message ?
-
				sbuf_json_escape(buf, ev->e_install_finished.pkg->message->str) :
+
				buf_json_escape(buf, ev->e_install_finished.pkg->message->str) :
				"");
		break;
	case PKG_EVENT_INTEGRITYCHECK_BEGIN:
-
		sbuf_printf(msg, "{ \"type\": \"INFO_INTEGRITYCHECK_BEGIN\", "
+
		utstring_printf(msg, "{ \"type\": \"INFO_INTEGRITYCHECK_BEGIN\", "
		    "\"data\": {}}");
		break;
	case PKG_EVENT_INTEGRITYCHECK_CONFLICT:
-
		sbuf_printf(msg, "{ \"type\": \"INFO_INTEGRITYCHECK_CONFLICT\","
+
		utstring_printf(msg, "{ \"type\": \"INFO_INTEGRITYCHECK_CONFLICT\","
			"\"data\": { "
			"\"pkguid\": \"%s\", "
			"\"pkgpath\": \"%s\", "
@@ -176,25 +176,25 @@ pipeevent(struct pkg_event *ev)
		cur_conflict = ev->e_integrity_conflict.conflicts;
		while (cur_conflict != NULL) {
			if (cur_conflict->next != NULL) {
-
				sbuf_printf(msg, "{\"uid\":\"%s\"},",
+
				utstring_printf(msg, "{\"uid\":\"%s\"},",
						cur_conflict->uid);
			}
			else {
-
				sbuf_printf(msg, "{\"uid\":\"%s\"}",
+
				utstring_printf(msg, "{\"uid\":\"%s\"}",
						cur_conflict->uid);
				break;
			}
			cur_conflict = cur_conflict->next;
		}
-
		sbuf_cat(msg, "]}}");
+
		utstring_printf(msg, "%s", "]}}");
		break;
	case PKG_EVENT_INTEGRITYCHECK_FINISHED:
-
		sbuf_printf(msg, "{ \"type\": \"INFO_INTEGRITYCHECK_FINISHED\", "
+
		utstring_printf(msg, "{ \"type\": \"INFO_INTEGRITYCHECK_FINISHED\", "
		    "\"data\": {\"conflicting\": %d}}",
		    ev->e_integrity_finished.conflicting);
		break;
	case PKG_EVENT_DEINSTALL_BEGIN:
-
		pkg_sbuf_printf(msg, "{ \"type\": \"INFO_DEINSTALL_BEGIN\", "
+
		pkg_utstring_printf(msg, "{ \"type\": \"INFO_DEINSTALL_BEGIN\", "
		    "\"data\": { "
		    "\"pkgname\": \"%n\", "
		    "\"pkgversion\": \"%v\""
@@ -203,7 +203,7 @@ pipeevent(struct pkg_event *ev)
		    ev->e_deinstall_begin.pkg);
		break;
	case PKG_EVENT_DEINSTALL_FINISHED:
-
		pkg_sbuf_printf(msg, "{ \"type\": \"INFO_DEINSTALL_FINISHED\", "
+
		pkg_utstring_printf(msg, "{ \"type\": \"INFO_DEINSTALL_FINISHED\", "
		    "\"data\": { "
		    "\"pkgname\": \"%n\", "
		    "\"pkgversion\": \"%v\""
@@ -212,7 +212,7 @@ pipeevent(struct pkg_event *ev)
		    ev->e_deinstall_finished.pkg);
		break;
	case PKG_EVENT_UPGRADE_BEGIN:
-
		pkg_sbuf_printf(msg, "{ \"type\": \"INFO_UPGRADE_BEGIN\", "
+
		pkg_utstring_printf(msg, "{ \"type\": \"INFO_UPGRADE_BEGIN\", "
		    "\"data\": { "
		    "\"pkgname\": \"%n\", "
		    "\"pkgversion\": \"%v\" ,"
@@ -223,7 +223,7 @@ pipeevent(struct pkg_event *ev)
		    ev->e_upgrade_begin.n);
		break;
	case PKG_EVENT_UPGRADE_FINISHED:
-
		pkg_sbuf_printf(msg, "{ \"type\": \"INFO_UPGRADE_FINISHED\", "
+
		pkg_utstring_printf(msg, "{ \"type\": \"INFO_UPGRADE_FINISHED\", "
		    "\"data\": { "
		    "\"pkgname\": \"%n\", "
		    "\"pkgversion\": \"%v\" ,"
@@ -234,7 +234,7 @@ pipeevent(struct pkg_event *ev)
		    ev->e_upgrade_finished.n);
		break;
	case PKG_EVENT_LOCKED:
-
		pkg_sbuf_printf(msg, "{ \"type\": \"ERROR_LOCKED\", "
+
		pkg_utstring_printf(msg, "{ \"type\": \"ERROR_LOCKED\", "
		    "\"data\": { "
		    "\"pkgname\": \"%n\", "
		    "\"pkgversion\": \"%n\""
@@ -243,7 +243,7 @@ pipeevent(struct pkg_event *ev)
		    ev->e_locked.pkg);
		break;
	case PKG_EVENT_REQUIRED:
-
		pkg_sbuf_printf(msg, "{ \"type\": \"ERROR_REQUIRED\", "
+
		pkg_utstring_printf(msg, "{ \"type\": \"ERROR_REQUIRED\", "
		    "\"data\": { "
		    "\"pkgname\": \"%n\", "
		    "\"pkgversion\": \"%v\", "
@@ -253,14 +253,15 @@ pipeevent(struct pkg_event *ev)
		    ev->e_required.pkg,
		    ev->e_required.force == 1 ? "true": "false");
		while (pkg_rdeps(ev->e_required.pkg, &dep) == EPKG_OK)
-
			sbuf_printf(msg, "{ \"pkgname\": \"%s\", "
+
			utstring_printf(msg, "{ \"pkgname\": \"%s\", "
			    "\"pkgversion\": \"%s\" }, ",
			    dep->name, dep->version);
-
		sbuf_setpos(msg, sbuf_len(msg) - 2);
-
		sbuf_cat(msg, "]}}");
+
		msg->i -= 2;
+
		msg->d[msg->i] = '\0';
+
		utstring_printf(msg, "%s", "]}}");
		break;
	case PKG_EVENT_ALREADY_INSTALLED:
-
		pkg_sbuf_printf(msg, "{ \"type\": \"ERROR_ALREADY_INSTALLED\", "
+
		pkg_utstring_printf(msg, "{ \"type\": \"ERROR_ALREADY_INSTALLED\", "
		    "\"data\": { "
		    "\"pkgname\": \"%n\", "
		    "\"pkgversion\": \"%v\""
@@ -269,7 +270,7 @@ pipeevent(struct pkg_event *ev)
		    ev->e_already_installed.pkg);
		break;
	case PKG_EVENT_MISSING_DEP:
-
		sbuf_printf(msg, "{ \"type\": \"ERROR_MISSING_DEP\", "
+
		utstring_printf(msg, "{ \"type\": \"ERROR_MISSING_DEP\", "
		    "\"data\": { "
		    "\"depname\": \"%s\", "
		    "\"depversion\": \"%s\""
@@ -278,22 +279,22 @@ pipeevent(struct pkg_event *ev)
		    ev->e_missing_dep.dep->version);
		break;
	case PKG_EVENT_NOREMOTEDB:
-
		sbuf_printf(msg, "{ \"type\": \"ERROR_NOREMOTEDB\", "
+
		utstring_printf(msg, "{ \"type\": \"ERROR_NOREMOTEDB\", "
		    "\"data\": { "
		    "\"url\": \"%s\" "
		    "}}" ,
		    ev->e_remotedb.repo);
		break;
	case PKG_EVENT_NOLOCALDB:
-
		sbuf_printf(msg, "{ \"type\": \"ERROR_NOLOCALDB\", "
+
		utstring_printf(msg, "{ \"type\": \"ERROR_NOLOCALDB\", "
		    "\"data\": {} ");
		break;
	case PKG_EVENT_NEWPKGVERSION:
-
		sbuf_printf(msg, "{ \"type\": \"INFO_NEWPKGVERSION\", "
+
		utstring_printf(msg, "{ \"type\": \"INFO_NEWPKGVERSION\", "
		    "\"data\": {} ");
		break;
	case PKG_EVENT_FILE_MISMATCH:
-
		pkg_sbuf_printf(msg, "{ \"type\": \"ERROR_FILE_MISMATCH\", "
+
		pkg_utstring_printf(msg, "{ \"type\": \"ERROR_FILE_MISMATCH\", "
		    "\"data\": { "
		    "\"pkgname\": \"%n\", "
		    "\"pkgversion\": \"%v\", "
@@ -301,41 +302,41 @@ pipeevent(struct pkg_event *ev)
		    "}}",
		    ev->e_file_mismatch.pkg,
		    ev->e_file_mismatch.pkg,
-
		    sbuf_json_escape(buf, ev->e_file_mismatch.file->path));
+
		    buf_json_escape(buf, ev->e_file_mismatch.file->path));
		break;
	case PKG_EVENT_PLUGIN_ERRNO:
-
		sbuf_printf(msg, "{ \"type\": \"ERROR_PLUGIN\", "
+
		utstring_printf(msg, "{ \"type\": \"ERROR_PLUGIN\", "
		    "\"data\": {"
		    "\"plugin\": \"%s\", "
		    "\"msg\": \"%s(%s): %s\","
		    "\"errno\": %d"
		    "}}",
		    pkg_plugin_get(ev->e_plugin_errno.plugin, PKG_PLUGIN_NAME),
-
		    sbuf_json_escape(buf, ev->e_plugin_errno.func),
-
		    sbuf_json_escape(buf, ev->e_plugin_errno.arg),
-
		    sbuf_json_escape(buf, strerror(ev->e_plugin_errno.no)),
+
		    buf_json_escape(buf, ev->e_plugin_errno.func),
+
		    buf_json_escape(buf, ev->e_plugin_errno.arg),
+
		    buf_json_escape(buf, strerror(ev->e_plugin_errno.no)),
		    ev->e_plugin_errno.no);
		break;
	case PKG_EVENT_PLUGIN_ERROR:
-
		sbuf_printf(msg, "{ \"type\": \"ERROR_PLUGIN\", "
+
		utstring_printf(msg, "{ \"type\": \"ERROR_PLUGIN\", "
		    "\"data\": {"
		    "\"plugin\": \"%s\", "
		    "\"msg\": \"%s\""
		    "}}",
		    pkg_plugin_get(ev->e_plugin_error.plugin, PKG_PLUGIN_NAME),
-
		    sbuf_json_escape(buf, ev->e_plugin_error.msg));
+
		    buf_json_escape(buf, ev->e_plugin_error.msg));
		break;
	case PKG_EVENT_PLUGIN_INFO:
-
		sbuf_printf(msg, "{ \"type\": \"INFO_PLUGIN\", "
+
		utstring_printf(msg, "{ \"type\": \"INFO_PLUGIN\", "
		    "\"data\": {"
		    "\"plugin\": \"%s\", "
		    "\"msg\": \"%s\""
		    "}}",
		    pkg_plugin_get(ev->e_plugin_info.plugin, PKG_PLUGIN_NAME),
-
		    sbuf_json_escape(buf, ev->e_plugin_info.msg));
+
		    buf_json_escape(buf, ev->e_plugin_info.msg));
		break;
	case PKG_EVENT_INCREMENTAL_UPDATE:
-
		sbuf_printf(msg, "{ \"type\": \"INFO_INCREMENTAL_UPDATE\", "
+
		utstring_printf(msg, "{ \"type\": \"INFO_INCREMENTAL_UPDATE\", "
		    "\"data\": {"
		        "\"name\": \"%s\", "
			"\"processed\": %d"
@@ -343,7 +344,7 @@ pipeevent(struct pkg_event *ev)
			ev->e_incremental_update.processed);
		break;
	case PKG_EVENT_QUERY_YESNO:
-
		sbuf_printf(msg, "{ \"type\": \"QUERY_YESNO\", "
+
		utstring_printf(msg, "{ \"type\": \"QUERY_YESNO\", "
		    "\"data\": {"
			"\"msg\": \"%s\","
			"\"default\": \"%d\""
@@ -351,7 +352,7 @@ pipeevent(struct pkg_event *ev)
			ev->e_query_yesno.deft);
		break;
	case PKG_EVENT_QUERY_SELECT:
-
		sbuf_printf(msg, "{ \"type\": \"QUERY_SELECT\", "
+
		utstring_printf(msg, "{ \"type\": \"QUERY_SELECT\", "
		    "\"data\": {"
			"\"msg\": \"%s\","
			"\"ncnt\": \"%d\","
@@ -362,18 +363,18 @@ pipeevent(struct pkg_event *ev)
			ev->e_query_select.deft);
		for (i = 0; i < ev->e_query_select.ncnt - 1; i++)
		{
-
			sbuf_printf(msg, "{ \"text\": \"%s\" },",
+
			utstring_printf(msg, "{ \"text\": \"%s\" },",
				ev->e_query_select.items[i]);
		}
-
		sbuf_printf(msg, "{ \"text\": \"%s\" } ] }}",
+
		utstring_printf(msg, "{ \"text\": \"%s\" } ] }}",
			ev->e_query_select.items[i]);
		break;
	case PKG_EVENT_PROGRESS_START:
-
		sbuf_printf(msg, "{ \"type\": \"INFO_PROGRESS_START\", "
+
		utstring_printf(msg, "{ \"type\": \"INFO_PROGRESS_START\", "
		  "\"data\": {}}");
		break;
	case PKG_EVENT_PROGRESS_TICK:
-
		sbuf_printf(msg, "{ \"type\": \"INFO_PROGRESS_TICK\", "
+
		utstring_printf(msg, "{ \"type\": \"INFO_PROGRESS_TICK\", "
		  "\"data\": { \"current\": %ld, \"total\" : %ld}}",
		  ev->e_progress_tick.current, ev->e_progress_tick.total);
		break;
@@ -383,10 +384,9 @@ pipeevent(struct pkg_event *ev)
	default:
		break;
	}
-
	sbuf_finish(msg);
-
	dprintf(eventpipe, "%s\n", sbuf_data(msg));
-
	sbuf_delete(msg);
-
	sbuf_delete(buf);
+
	dprintf(eventpipe, "%s\n", utstring_body(msg));
+
	utstring_free(msg);
+
	utstring_free(buf);
}

void
modified libpkg/pkg_jobs.c
@@ -805,13 +805,13 @@ pkg_jobs_try_remote_candidate(struct pkg_jobs *j, const char *pattern,
				PKG_LOAD_SHLIBS_REQUIRED|PKG_LOAD_SHLIBS_PROVIDED|
				PKG_LOAD_ANNOTATIONS|PKG_LOAD_CONFLICTS;
	int rc = EPKG_FATAL;
-
	struct sbuf *qmsg;
+
	UT_string *qmsg;
	struct pkg_job_universe_item *unit;

	if ((it = pkgdb_repo_query(j->db, pattern, m, j->reponame)) == NULL)
		return (EPKG_FATAL);

-
	qmsg = sbuf_new_auto();
+
	utstring_new(qmsg);

	while (it != NULL && pkgdb_it_next(it, &p, flags) == EPKG_OK) {
		if (pkg_jobs_has_replacement(j, p->uid)) {
@@ -819,10 +819,9 @@ pkg_jobs_try_remote_candidate(struct pkg_jobs *j, const char *pattern,
			continue;
		}

-
		sbuf_printf(qmsg, "%s has no direct installation candidates, change it to "
+
		utstring_printf(qmsg, "%s has no direct installation candidates, change it to "
				"%s? ", uid, p->uid);
-
		sbuf_finish(qmsg);
-
		if (pkg_emit_query_yesno(true, sbuf_data(qmsg))) {
+
		if (pkg_emit_query_yesno(true, utstring_body(qmsg))) {
			/* Change the origin of the local package */
			pkg_validate(p, j->db);
			unit = pkg_jobs_universe_find(j->universe, uid);
@@ -840,13 +839,13 @@ pkg_jobs_try_remote_candidate(struct pkg_jobs *j, const char *pattern,
			}
			break;
		}
-
		sbuf_reset(qmsg);
+
		utstring_clear(qmsg);
	}


	pkg_free(p);

-
	sbuf_free(qmsg);
+
	utstring_free(qmsg);
	pkgdb_it_free(it);

	return (rc);
modified libpkg/pkg_manifest.c
@@ -27,7 +27,6 @@
 */

#include <sys/types.h>
-
#include <sys/sbuf.h>
#include <stddef.h>

#include <assert.h>
@@ -252,40 +251,39 @@ pkg_manifest_keys_free(struct pkg_manifest_key *key)
}

static int
-
urlencode(const char *src, struct sbuf **dest)
+
urlencode(const char *src, UT_string **dest)
{
	size_t len;
	size_t i;

-
	sbuf_init(dest);
+
	utstring_renew(*dest);

	len = strlen(src);
	for (i = 0; i < len; i++) {
		if (!isascii(src[i]) || src[i] == '%')
-
			sbuf_printf(*dest, "%%%.2x", (unsigned char)src[i]);
+
			utstring_printf(*dest, "%%%.2x", (unsigned char)src[i]);
		else
-
			sbuf_putc(*dest, src[i]);
+
			utstring_printf(*dest, "%c", src[i]);
	}
-
	sbuf_finish(*dest);

	return (EPKG_OK);
}


static int
-
urldecode(const char *src, struct sbuf **dest)
+
urldecode(const char *src, UT_string **dest)
{
	size_t len;
	size_t i;
	char c;
	char hex[] = {'\0', '\0', '\0'};

-
	sbuf_init(dest);
+
	utstring_renew(*dest);

	len = strlen(src);
	for (i = 0; i < len; i++) {
		if (src[i] != '%') {
-
			sbuf_putc(*dest, src[i]);
+
			utstring_printf(*dest, "%c", src[i]);
		} else {
			if (i + 2 > len) {
				pkg_emit_error("unexpected end of string");
@@ -301,13 +299,12 @@ urldecode(const char *src, struct sbuf **dest)
				 * if it fails consider this is not a urlencoded
				 * information
				 */
-
				sbuf_printf(*dest, "%%%s", hex);
+
				utstring_printf(*dest, "%%%s", hex);
			} else {
-
				sbuf_putc(*dest, c);
+
				utstring_printf(*dest, "%c", c);
			}
		}
	}
-
	sbuf_finish(*dest);

	return (EPKG_OK);
}
@@ -341,7 +338,7 @@ pkg_string(struct pkg *pkg, const ucl_object_t *obj, uint32_t offset)
{
	const char *str;
	char **dest;
-
	struct sbuf *buf = NULL;
+
	UT_string *buf = NULL;

	str = ucl_object_tostring_forced(obj);

@@ -363,8 +360,7 @@ pkg_string(struct pkg *pkg, const ucl_object_t *obj, uint32_t offset)

		if (offset & STRING_FLAG_URLDECODE) {
			urldecode(str, &buf);
-
			sbuf_finish(buf);
-
			str = sbuf_data(buf);
+
			str = utstring_body(buf);
		}

		/* Remove flags from the offset */
@@ -373,7 +369,7 @@ pkg_string(struct pkg *pkg, const ucl_object_t *obj, uint32_t offset)
		*dest = strdup(str);

		if (buf) {
-
			sbuf_delete(buf);
+
			utstring_free(buf);
		}
	}

@@ -494,7 +490,7 @@ pkg_array(struct pkg *pkg, const ucl_object_t *obj, uint32_t attr)
static int
pkg_obj(struct pkg *pkg, const ucl_object_t *obj, uint32_t attr)
{
-
	struct sbuf *tmp = NULL;
+
	UT_string *tmp = NULL;
	const ucl_object_t *cur;
	ucl_object_iter_t it = NULL;
	pkg_script script_type;
@@ -524,12 +520,12 @@ pkg_obj(struct pkg *pkg, const ucl_object_t *obj, uint32_t attr)
		case PKG_DIRECTORIES:
			if (cur->type == UCL_BOOLEAN) {
				urldecode(key, &tmp);
-
				pkg_adddir(pkg, sbuf_data(tmp), false);
+
				pkg_adddir(pkg, utstring_body(tmp), false);
			} else if (cur->type == UCL_OBJECT) {
				pkg_set_dirs_from_object(pkg, cur);
			} else if (cur->type == UCL_STRING) {
				urldecode(key, &tmp);
-
				pkg_adddir(pkg, sbuf_data(tmp), false);
+
				pkg_adddir(pkg, utstring_body(tmp), false);
			} else {
				pkg_emit_error("Skipping malformed directories %s",
				    key);
@@ -539,7 +535,7 @@ pkg_obj(struct pkg *pkg, const ucl_object_t *obj, uint32_t attr)
			if (cur->type == UCL_STRING) {
				buf = ucl_object_tolstring(cur, &len);
				urldecode(key, &tmp);
-
				pkg_addfile(pkg, sbuf_data(tmp), len >= 2 ? buf : NULL, false);
+
				pkg_addfile(pkg, utstring_body(tmp), len >= 2 ? buf : NULL, false);
			} else if (cur->type == UCL_OBJECT)
				pkg_set_files_from_object(pkg, cur);
			else
@@ -585,7 +581,7 @@ pkg_obj(struct pkg *pkg, const ucl_object_t *obj, uint32_t attr)
				}

				urldecode(ucl_object_tostring(cur), &tmp);
-
				pkg_addscript(pkg, sbuf_data(tmp), script_type);
+
				pkg_addscript(pkg, utstring_body(tmp), script_type);
			}
			break;
		case PKG_ANNOTATIONS:
@@ -598,7 +594,8 @@ pkg_obj(struct pkg *pkg, const ucl_object_t *obj, uint32_t attr)
		}
	}

-
	sbuf_free(tmp);
+
	if (tmp)
+
		utstring_free(tmp);

	return (EPKG_OK);
}
@@ -619,7 +616,7 @@ pkg_set_files_from_object(struct pkg *pkg, const ucl_object_t *obj)
	const char *gname = NULL;
	void *set = NULL;
	mode_t perm = 0;
-
	struct sbuf *fname = NULL;
+
	UT_string *fname = NULL;
	const char *key, *okey;

	okey = ucl_object_key(obj);
@@ -646,13 +643,13 @@ pkg_set_files_from_object(struct pkg *pkg, const ucl_object_t *obj)
				perm = getmode(set, 0);
		} else {
			pkg_debug(1, "Skipping unknown key for file(%s): %s",
-
			    sbuf_data(fname), key);
+
			    utstring_body(fname), key);
		}
	}

-
	pkg_addfile_attr(pkg, sbuf_data(fname), sum, uname, gname, perm, 0,
+
	pkg_addfile_attr(pkg, utstring_body(fname), sum, uname, gname, perm, 0,
	    false);
-
	sbuf_delete(fname);
+
	utstring_free(fname);

	return (EPKG_OK);
}
@@ -666,7 +663,7 @@ pkg_set_dirs_from_object(struct pkg *pkg, const ucl_object_t *obj)
	const char *gname = NULL;
	void *set;
	mode_t perm = 0;
-
	struct sbuf *dirname = NULL;
+
	UT_string *dirname = NULL;
	const char *key, *okey;

	okey = ucl_object_key(obj);
@@ -692,12 +689,12 @@ pkg_set_dirs_from_object(struct pkg *pkg, const ucl_object_t *obj)
			/* ignore on purpose : compatibility*/
		} else {
			pkg_debug(1, "Skipping unknown key for dir(%s): %s",
-
			    sbuf_data(dirname), key);
+
			    utstring_body(dirname), key);
		}
	}

-
	pkg_adddir_attr(pkg, sbuf_data(dirname), uname, gname, perm, 0, false);
-
	sbuf_delete(dirname);
+
	pkg_adddir_attr(pkg, utstring_body(dirname), uname, gname, perm, 0, false);
+
	utstring_free(dirname);

	return (EPKG_OK);
}
@@ -907,7 +904,7 @@ pkg_emit_filelist(struct pkg *pkg, FILE *f)
{
	ucl_object_t *obj = NULL, *seq;
	struct pkg_file *file = NULL;
-
	struct sbuf *b = NULL;
+
	UT_string *b = NULL;

	obj = ucl_object_typed_new(UCL_OBJECT);
	ucl_object_insert_key(obj, ucl_object_fromstring(pkg->origin), "origin", 6, false);
@@ -919,7 +916,7 @@ pkg_emit_filelist(struct pkg *pkg, FILE *f)
		urlencode(file->path, &b);
		if (seq == NULL)
			seq = ucl_object_typed_new(UCL_ARRAY);
-
		ucl_array_append(seq, ucl_object_fromlstring(sbuf_data(b), sbuf_len(b)));
+
		ucl_array_append(seq, ucl_object_fromlstring(utstring_body(b), utstring_len(b)));
	}
	if (seq != NULL)
		ucl_object_insert_key(obj, seq, "files", 5, false);
@@ -927,7 +924,7 @@ pkg_emit_filelist(struct pkg *pkg, FILE *f)
	ucl_object_emit_file(obj, UCL_EMIT_JSON_COMPACT, f);

	if (b != NULL)
-
		sbuf_delete(b);
+
		utstring_free(b);

	ucl_object_unref(obj);

@@ -944,7 +941,7 @@ pkg_emit_object(struct pkg *pkg, short flags)
	struct pkg_dir		*dir      = NULL;
	struct pkg_conflict	*conflict = NULL;
	struct pkg_config_file	*cf       = NULL;
-
	struct sbuf		*tmpsbuf  = NULL;
+
	UT_string		*tmpsbuf  = NULL;
	char			*buf;
	int i;
	const char *script_types = NULL;
@@ -1019,7 +1016,7 @@ pkg_emit_object(struct pkg *pkg, short flags)
	if (pkg->desc != NULL) {
		urlencode(pkg->desc, &tmpsbuf);
		ucl_object_insert_key(top,
-
			ucl_object_fromstring_common(sbuf_data(tmpsbuf), sbuf_len(tmpsbuf), UCL_STRING_TRIM),
+
			ucl_object_fromstring_common(utstring_body(tmpsbuf), utstring_len(tmpsbuf), UCL_STRING_TRIM),
			"desc", 4, false);
	}

@@ -1163,7 +1160,7 @@ pkg_emit_object(struct pkg *pkg, short flags)
					map = ucl_object_typed_new(UCL_OBJECT);
				ucl_object_insert_key(map,
				    ucl_object_fromstring(file->sum),
-
				    sbuf_data(tmpsbuf), sbuf_len(tmpsbuf), true);
+
				    utstring_body(tmpsbuf), utstring_len(tmpsbuf), true);
			}
			if (map)
				ucl_object_insert_key(top, map, "files", 5, false);
@@ -1174,7 +1171,7 @@ pkg_emit_object(struct pkg *pkg, short flags)
				urlencode(cf->path, &tmpsbuf);
				if (seq == NULL)
					seq = ucl_object_typed_new(UCL_ARRAY);
-
				ucl_array_append(seq, ucl_object_fromstring(sbuf_data(tmpsbuf)));
+
				ucl_array_append(seq, ucl_object_fromstring(utstring_body(tmpsbuf)));
			}
			if (seq)
				ucl_object_insert_key(top, seq, "config", 6, false);
@@ -1187,7 +1184,7 @@ pkg_emit_object(struct pkg *pkg, short flags)
					map = ucl_object_typed_new(UCL_OBJECT);
				ucl_object_insert_key(map,
				    ucl_object_fromstring("y"),
-
				    sbuf_data(tmpsbuf), sbuf_len(tmpsbuf), true);
+
				    utstring_body(tmpsbuf), utstring_len(tmpsbuf), true);
			}
			if (map)
				ucl_object_insert_key(top, map, "directories", 11, false);
@@ -1232,8 +1229,8 @@ pkg_emit_object(struct pkg *pkg, short flags)
			if (map == NULL)
				map = ucl_object_typed_new(UCL_OBJECT);
			ucl_object_insert_key(map,
-
			    ucl_object_fromstring_common(sbuf_data(tmpsbuf),
-
			        sbuf_len(tmpsbuf), UCL_STRING_TRIM),
+
			    ucl_object_fromstring_common(utstring_body(tmpsbuf),
+
			        utstring_len(tmpsbuf), UCL_STRING_TRIM),
			    script_types, 0, true);
		}
		if (map)
@@ -1248,27 +1245,27 @@ pkg_emit_object(struct pkg *pkg, short flags)
	}

	if (tmpsbuf != NULL)
-
		sbuf_delete(tmpsbuf);
+
		utstring_free(tmpsbuf);

	return (top);
}


static int
-
emit_manifest(struct pkg *pkg, struct sbuf **out, short flags)
+
emit_manifest(struct pkg *pkg, UT_string **out, short flags)
{
	ucl_object_t *top;

	top = pkg_emit_object(pkg, flags);

	if ((flags & PKG_MANIFEST_EMIT_PRETTY) == PKG_MANIFEST_EMIT_PRETTY)
-
		ucl_object_emit_sbuf(top, UCL_EMIT_YAML, out);
+
		ucl_object_emit_buf(top, UCL_EMIT_YAML, out);
	else if ((flags & PKG_MANIFEST_EMIT_UCL) == PKG_MANIFEST_EMIT_UCL)
-
		ucl_object_emit_sbuf(top, UCL_EMIT_CONFIG, out);
+
		ucl_object_emit_buf(top, UCL_EMIT_CONFIG, out);
	else if ((flags & PKG_MANIFEST_EMIT_JSON) == PKG_MANIFEST_EMIT_JSON)
-
		ucl_object_emit_sbuf(top, UCL_EMIT_JSON, out);
+
		ucl_object_emit_buf(top, UCL_EMIT_JSON, out);
	else
-
		ucl_object_emit_sbuf(top, UCL_EMIT_JSON_COMPACT, out);
+
		ucl_object_emit_buf(top, UCL_EMIT_JSON_COMPACT, out);

	ucl_object_unref(top);

@@ -1289,13 +1286,13 @@ pkg_emit_manifest_digest(const unsigned char *digest, size_t len, char *hexdiges
/*
 * This routine is able to output to either a (FILE *) or a (struct sbuf *). It
 * exist only to avoid code duplication and should not be called except from
-
 * pkg_emit_manifest_file() and pkg_emit_manifest_sbuf().
+
 * pkg_emit_manifest_file() and pkg_emit_manifest_buf().
 */
static int
pkg_emit_manifest_generic(struct pkg *pkg, void *out, short flags,
-
	    char **pdigest, bool out_is_a_sbuf)
+
	    char **pdigest, bool out_is_a_buf)
{
-
	struct sbuf *output = NULL;
+
	UT_string *output = NULL;
	unsigned char digest[SHA256_BLOCK_SIZE];
	SHA256_CTX *sign_ctx = NULL;
	int rc;
@@ -1306,16 +1303,16 @@ pkg_emit_manifest_generic(struct pkg *pkg, void *out, short flags,
		sha256_init(sign_ctx);
	}

-
	if (out_is_a_sbuf)
+
	if (out_is_a_buf)
		output = out;

	rc = emit_manifest(pkg, &output, flags);

	if (sign_ctx != NULL)
-
		sha256_update(sign_ctx, sbuf_data(output), sbuf_len(output));
+
		sha256_update(sign_ctx, utstring_body(output), utstring_len(output));

-
	if (!out_is_a_sbuf)
-
		fprintf(out, "%s\n", sbuf_data(output));
+
	if (!out_is_a_buf)
+
		fprintf(out, "%s\n", utstring_body(output));

	if (pdigest != NULL) {
		sha256_final(sign_ctx, digest);
@@ -1323,8 +1320,8 @@ pkg_emit_manifest_generic(struct pkg *pkg, void *out, short flags,
		free(sign_ctx);
	}

-
	if (!out_is_a_sbuf)
-
		sbuf_free(output);
+
	if (!out_is_a_buf)
+
		utstring_free(output);

	return (rc);
}
@@ -1337,7 +1334,7 @@ pkg_emit_manifest_file(struct pkg *pkg, FILE *f, short flags, char **pdigest)
}

int
-
pkg_emit_manifest_sbuf(struct pkg *pkg, struct sbuf *b, short flags, char **pdigest)
+
pkg_emit_manifest_buf(struct pkg *pkg, UT_string *b, short flags, char **pdigest)
{

	return (pkg_emit_manifest_generic(pkg, b, flags, pdigest, true));
@@ -1346,19 +1343,19 @@ pkg_emit_manifest_sbuf(struct pkg *pkg, struct sbuf *b, short flags, char **pdig
int
pkg_emit_manifest(struct pkg *pkg, char **dest, short flags, char **pdigest)
{
-
	struct sbuf *b = sbuf_new_auto();
+
	UT_string *b;
	int rc;

-
	rc = pkg_emit_manifest_sbuf(pkg, b, flags, pdigest);
+
	utstring_new(b);
+
	rc = pkg_emit_manifest_buf(pkg, b, flags, pdigest);

	if (rc != EPKG_OK) {
-
		sbuf_delete(b);
+
		utstring_free(b);
		return (rc);
	}

-
	sbuf_finish(b);
-
	*dest = strdup(sbuf_data(b));
-
	sbuf_delete(b);
+
	*dest = strdup(utstring_body(b));
+
	utstring_free(b);

	return (rc);
}
modified libpkg/pkg_ports.c
@@ -166,23 +166,6 @@ free_file_attr(struct file_attr *a)
	free(a);
}

-
static void
-
sbuf_append(struct sbuf *buf, __unused const char *comment, const char *str, ...)
-
{
-
	va_list ap;
-

-
	va_start(ap, str);
-
	sbuf_vprintf(buf, str, ap);
-
	va_end(ap);
-
}
-

-
#define post_unexec_append(buf, str, ...) \
-
	sbuf_append(buf, "unexec", str, __VA_ARGS__)
-
#define pre_unexec_append(buf, str, ...) \
-
	sbuf_append(buf, "unexec", str, __VA_ARGS__)
-
#define exec_append(buf, str, ...) \
-
	sbuf_append(buf, "exec", str, __VA_ARGS__)
-

static int
setprefix(struct plist *p, char *line, struct file_attr *a)
{
@@ -198,9 +181,9 @@ setprefix(struct plist *p, char *line, struct file_attr *a)

	p->slash = p->prefix[strlen(p->prefix) -1] == '/' ? "" : "/";

-
	exec_append(p->post_install_buf, "cd %s\n", p->prefix);
-
	pre_unexec_append(p->pre_deinstall_buf, "cd %s\n", p->prefix);
-
	post_unexec_append(p->post_deinstall_buf, "cd %s\n", p->prefix);
+
	utstring_printf(p->post_install_buf, "cd %s\n", p->prefix);
+
	utstring_printf(p->pre_deinstall_buf, "cd %s\n", p->prefix);
+
	utstring_printf(p->post_deinstall_buf, "cd %s\n", p->prefix);

	free_file_attr(a);

@@ -607,16 +590,16 @@ meta_exec(struct plist *p, char *line, struct file_attr *a, exec_t type)

	switch (type) {
	case PREEXEC:
-
		sbuf_printf(p->pre_install_buf, "%s\n", cmd);
+
		utstring_printf(p->pre_install_buf, "%s\n", cmd);
		break;
	case POSTEXEC:
-
		sbuf_printf(p->post_install_buf, "%s\n", cmd);
+
		utstring_printf(p->post_install_buf, "%s\n", cmd);
		break;
	case PREUNEXEC:
-
		sbuf_printf(p->pre_deinstall_buf, "%s\n", cmd);
+
		utstring_printf(p->pre_deinstall_buf, "%s\n", cmd);
		break;
	case POSTUNEXEC:
-
		sbuf_printf(p->post_deinstall_buf, "%s\n", cmd);
+
		utstring_printf(p->post_deinstall_buf, "%s\n", cmd);
		break;
	case UNEXEC:
		comment[0] = '\0';
@@ -646,10 +629,10 @@ meta_exec(struct plist *p, char *line, struct file_attr *a, exec_t type)

		if (should_be_post(cmd, p)) {
			if (comment[0] != '#')
-
				post_unexec_append(p->post_deinstall_buf,
+
				utstring_printf(p->post_deinstall_buf,
				    "%s%s\n", comment, cmd);
		} else {
-
			pre_unexec_append(p->pre_deinstall_buf, "%s%s\n", comment, cmd);
+
			utstring_printf(p->pre_deinstall_buf, "%s%s\n", comment, cmd);
		}
		if (comment[0] == '#') {
			buf = cmd;
@@ -693,7 +676,7 @@ meta_exec(struct plist *p, char *line, struct file_attr *a, exec_t type)
		}
		break;
	case EXEC:
-
		exec_append(p->post_install_buf, "%s\n", cmd);
+
		utstring_printf(p->post_install_buf, "%s\n", cmd);
		break;
	}

@@ -909,7 +892,7 @@ apply_keyword_file(ucl_object_t *obj, struct plist *p, char *line, struct file_a
		if (format_exec_cmd(&cmd, ucl_object_tostring(o), p->prefix,
		    p->last_file, line, argc, args) != EPKG_OK)
			goto keywords_cleanup;
-
		sbuf_printf(p->pre_install_buf, "%s\n", cmd);
+
		utstring_printf(p->pre_install_buf, "%s\n", cmd);
		free(cmd);
	}

@@ -917,7 +900,7 @@ apply_keyword_file(ucl_object_t *obj, struct plist *p, char *line, struct file_a
		if (format_exec_cmd(&cmd, ucl_object_tostring(o), p->prefix,
		    p->last_file, line, argc, args) != EPKG_OK)
			goto keywords_cleanup;
-
		sbuf_printf(p->post_install_buf, "%s\n", cmd);
+
		utstring_printf(p->post_install_buf, "%s\n", cmd);
		free(cmd);
	}

@@ -925,7 +908,7 @@ apply_keyword_file(ucl_object_t *obj, struct plist *p, char *line, struct file_a
		if (format_exec_cmd(&cmd, ucl_object_tostring(o), p->prefix,
		    p->last_file, line, argc, args) != EPKG_OK)
			goto keywords_cleanup;
-
		sbuf_printf(p->pre_deinstall_buf, "%s\n", cmd);
+
		utstring_printf(p->pre_deinstall_buf, "%s\n", cmd);
		free(cmd);
	}

@@ -933,7 +916,7 @@ apply_keyword_file(ucl_object_t *obj, struct plist *p, char *line, struct file_a
		if (format_exec_cmd(&cmd, ucl_object_tostring(o), p->prefix,
		    p->last_file, line, argc, args) != EPKG_OK)
			goto keywords_cleanup;
-
		sbuf_printf(p->post_deinstall_buf, "%s\n", cmd);
+
		utstring_printf(p->post_deinstall_buf, "%s\n", cmd);
		free(cmd);
	}

@@ -941,7 +924,7 @@ apply_keyword_file(ucl_object_t *obj, struct plist *p, char *line, struct file_a
		if (format_exec_cmd(&cmd, ucl_object_tostring(o), p->prefix,
		    p->last_file, line, argc, args) != EPKG_OK)
			goto keywords_cleanup;
-
		sbuf_printf(p->pre_deinstall_buf, "%s\n", cmd);
+
		utstring_printf(p->pre_deinstall_buf, "%s\n", cmd);
		free(cmd);
	}

@@ -949,7 +932,7 @@ apply_keyword_file(ucl_object_t *obj, struct plist *p, char *line, struct file_a
		if (format_exec_cmd(&cmd, ucl_object_tostring(o), p->prefix,
		    p->last_file, line, argc, args) != EPKG_OK)
			goto keywords_cleanup;
-
		sbuf_printf(p->post_deinstall_buf, "%s\n", cmd);
+
		utstring_printf(p->post_deinstall_buf, "%s\n", cmd);
		free(cmd);
	}

@@ -1154,11 +1137,10 @@ parse_keywords(struct plist *plist, char *keyword, char *line)
}

static void
-
flush_script_buffer(struct sbuf *buf, struct pkg *p, int type)
+
flush_script_buffer(UT_string *buf, struct pkg *p, int type)
{
-
	if (sbuf_len(buf) > 0) {
-
		sbuf_finish(buf);
-
		pkg_appendscript(p, sbuf_data(buf), type);
+
	if (utstring_len(buf) > 0) {
+
		pkg_appendscript(p, utstring_body(buf), type);
	}
}

@@ -1232,12 +1214,12 @@ plist_new(struct pkg *pkg, const char *stage)
	p->uname = strdup("root");
	p->gname = strdup("wheel");

-
	p->pre_install_buf = sbuf_new_auto();
-
	p->post_install_buf = sbuf_new_auto();
-
	p->pre_deinstall_buf = sbuf_new_auto();
-
	p->post_deinstall_buf = sbuf_new_auto();
-
	p->pre_upgrade_buf = sbuf_new_auto();
-
	p->post_upgrade_buf = sbuf_new_auto();
+
	utstring_new(p->pre_install_buf);
+
	utstring_new(p->post_install_buf);
+
	utstring_new(p->pre_deinstall_buf);
+
	utstring_new(p->post_deinstall_buf);
+
	utstring_new(p->pre_upgrade_buf);
+
	utstring_new(p->post_upgrade_buf);
	p->hardlinks = kh_init_hardlinks();

	populate_keywords(p);
@@ -1260,12 +1242,12 @@ plist_free(struct plist *p)
	free(p->post_patterns.patterns);
	kh_destroy_hardlinks(p->hardlinks);

-
	sbuf_delete(p->post_deinstall_buf);
-
	sbuf_delete(p->post_install_buf);
-
	sbuf_delete(p->post_upgrade_buf);
-
	sbuf_delete(p->pre_deinstall_buf);
-
	sbuf_delete(p->pre_install_buf);
-
	sbuf_delete(p->pre_upgrade_buf);
+
	utstring_free(p->post_deinstall_buf);
+
	utstring_free(p->post_install_buf);
+
	utstring_free(p->post_upgrade_buf);
+
	utstring_free(p->pre_deinstall_buf);
+
	utstring_free(p->pre_install_buf);
+
	utstring_free(p->pre_upgrade_buf);

	free(p);
}
@@ -1330,7 +1312,7 @@ pkg_add_port(struct pkgdb *db, struct pkg *pkg, const char *input_path,
{
	const char *location;
	int rc = EPKG_OK;
-
	struct sbuf *message;
+
	UT_string *message;
	struct pkg_message *msg;

	location = reloc;
@@ -1362,19 +1344,18 @@ pkg_add_port(struct pkgdb *db, struct pkg *pkg, const char *input_path,
	if (rc == EPKG_OK) {
		pkg_emit_install_finished(pkg, NULL);
		if (pkg->message != NULL)
-
			message = sbuf_new_auto();
+
			utstring_new(message);
		LL_FOREACH(pkg->message, msg) {
			if (msg->type == PKG_MESSAGE_ALWAYS ||
			    msg->type == PKG_MESSAGE_INSTALL) {
-
				sbuf_printf(message, "%s\n", msg->str);
+
				utstring_printf(message, "%s\n", msg->str);
			}
		}
		if (pkg->message != NULL) {
-
			if (sbuf_len(message) > 0) {
-
				sbuf_finish(message);
-
				pkg_emit_message(sbuf_data(message));
+
			if (utstring_len(message) > 0) {
+
				pkg_emit_message(utstring_body(message));
			}
-
			sbuf_delete(message);
+
			utstring_free(message);
		}
	}

modified libpkg/pkg_printf.c
@@ -27,7 +27,6 @@

#include "bsd_compat.h"
#include <sys/types.h>
-
#include <sys/sbuf.h>
#include <sys/stat.h>

#include <assert.h>
@@ -38,6 +37,7 @@
#include <string.h>
#include <time.h>
#include <utlist.h>
+
#include <utstring.h>

#include "pkg.h"
#include <private/pkg_printf.h>
@@ -167,7 +167,7 @@ struct pkg_printf_fmt {
	bool		 has_trailer;
	bool		 struct_pkg; /* or else a sub-type? */
	unsigned	 context;
-
	struct sbuf	*(*fmt_handler)(struct sbuf *, const void *,
+
	UT_string	*(*fmt_handler)(UT_string *, const void *,
					struct percent_esc *);
};

@@ -829,8 +829,8 @@ static const struct pkg_printf_fmt fmt[] = {
 * packages.  Optionally accepts per-field format in %{ %| %} Default
 * %{%An: %Av\n%|%}
 */  
-
struct sbuf *
-
format_annotations(struct sbuf *sbuf, const void *data, struct percent_esc *p)
+
UT_string *
+
format_annotations(UT_string *buf, const void *data, struct percent_esc *p)
{
	const struct pkg	*pkg = data;
	struct pkg_kv		*kv;
@@ -838,44 +838,44 @@ format_annotations(struct sbuf *sbuf, const void *data, struct percent_esc *p)

	if (p->flags & (PP_ALTERNATE_FORM1|PP_ALTERNATE_FORM2)) {
		LL_COUNT(pkg->annotations, kv, count);
-
		return (list_count(sbuf, count, p));
+
		return (list_count(buf, count, p));
	} else {
		set_list_defaults(p, "%An: %Av\n", "");

		count = 1;
		LL_FOREACH(pkg->annotations, kv) {
			if (count > 1)
-
				iterate_item(sbuf, pkg, sbuf_data(p->sep_fmt),
+
				iterate_item(buf, pkg, utstring_body(p->sep_fmt),
					     kv, count, PP_A);

-
			iterate_item(sbuf, pkg, sbuf_data(p->item_fmt),
+
			iterate_item(buf, pkg, utstring_body(p->item_fmt),
				     kv, count, PP_A);
			count++;
		}
	}
-
	return (sbuf);
+
	return (buf);
}

/*
 * %An -- Annotation tag name.
 */
-
struct sbuf *
-
format_annotation_name(struct sbuf *sbuf, const void *data, struct percent_esc *p)
+
UT_string *
+
format_annotation_name(UT_string *buf, const void *data, struct percent_esc *p)
{
	const struct pkg_kv	*kv = data;

-
	return (string_val(sbuf, kv->key, p));
+
	return (string_val(buf, kv->key, p));
}

/*
 * %Av -- Annotation value.
 */
-
struct sbuf *
-
format_annotation_value(struct sbuf *sbuf, const void *data, struct percent_esc *p)
+
UT_string *
+
format_annotation_value(UT_string *buf, const void *data, struct percent_esc *p)
{
	const struct pkg_kv	*kv = data;

-
	return (string_val(sbuf, kv->value, p));
+
	return (string_val(buf, kv->value, p));
}

/*
@@ -883,43 +883,43 @@ format_annotation_value(struct sbuf *sbuf, const void *data, struct percent_esc
 * binaries in the pkg.  Optionally accepts per-field format in %{ %|
 * %}.  Default %{%Bn\n%|%}
 */
-
struct sbuf *
-
format_shlibs_required(struct sbuf *sbuf, const void *data, struct percent_esc *p)
+
UT_string *
+
format_shlibs_required(UT_string *buf, const void *data, struct percent_esc *p)
{
	const struct pkg	*pkg = data;

	if (p->flags & (PP_ALTERNATE_FORM1|PP_ALTERNATE_FORM2))
-
		return (list_count(sbuf, pkg_list_count(pkg, PKG_SHLIBS_REQUIRED), p));
+
		return (list_count(buf, pkg_list_count(pkg, PKG_SHLIBS_REQUIRED), p));
	else {
-
		char	*buf = NULL;
+
		char	*buffer = NULL;
		int			 count;

		set_list_defaults(p, "%Bn\n", "");

		count = 1;
-
		while (pkg_shlibs_required(pkg, &buf) == EPKG_OK) {
+
		while (pkg_shlibs_required(pkg, &buffer) == EPKG_OK) {
			if (count > 1)
-
				iterate_item(sbuf, pkg, sbuf_data(p->sep_fmt),
-
					     buf, count, PP_B);
+
				iterate_item(buf, pkg, utstring_body(p->sep_fmt),
+
					     buffer, count, PP_B);

-
			iterate_item(sbuf, pkg, sbuf_data(p->item_fmt),
-
				     buf, count, PP_B);
+
			iterate_item(buf, pkg, utstring_body(p->item_fmt),
+
				     buffer, count, PP_B);
			count++;
		}
	}
-
	return (sbuf);
+
	return (buf);
}

/*
 * %Bn -- Required Shared Library name or %bn -- Provided Shared
 * Library name
 */
-
struct sbuf *
-
format_shlib_name(struct sbuf *sbuf, const void *data, struct percent_esc *p)
+
UT_string *
+
format_shlib_name(UT_string *buf, const void *data, struct percent_esc *p)
{
	const char	*shlib = data;

-
	return (string_val(sbuf, shlib, p));
+
	return (string_val(buf, shlib, p));
}

/*
@@ -928,41 +928,41 @@ format_shlib_name(struct sbuf *sbuf, const void *data, struct percent_esc *p)
 * Optionally accepts per-field format in %{ %| %}, where %n is
 * replaced by the category name.  Default %{%Cn%|, %}
 */
-
struct sbuf *
-
format_categories(struct sbuf *sbuf, const void *data, struct percent_esc *p)
+
UT_string *
+
format_categories(UT_string *buf, const void *data, struct percent_esc *p)
{
	const struct pkg	*pkg = data;
	int			 count = 0;
	char			*cat;

	if (p->flags & (PP_ALTERNATE_FORM1|PP_ALTERNATE_FORM2)) {
-
		return (list_count(sbuf, pkg_list_count(pkg, PKG_CATEGORIES), p));
+
		return (list_count(buf, pkg_list_count(pkg, PKG_CATEGORIES), p));
	} else {
		set_list_defaults(p, "%Cn", ", ");

		count = 1;
		kh_each_value(pkg->categories, cat, {
			if (count > 1)
-
				iterate_item(sbuf, pkg, sbuf_data(p->sep_fmt),
+
				iterate_item(buf, pkg, utstring_body(p->sep_fmt),
				    cat, count, PP_C);

-
			iterate_item(sbuf, pkg, sbuf_data(p->item_fmt), cat,
+
			iterate_item(buf, pkg, utstring_body(p->item_fmt), cat,
			    count, PP_C);
			count++;
		});
	}
-
	return (sbuf);
+
	return (buf);
}

/*
 * %Cn -- Category name.
 */
-
struct sbuf *
-
format_category_name(struct sbuf *sbuf, const void *data, struct percent_esc *p)
+
UT_string *
+
format_category_name(UT_string *buf, const void *data, struct percent_esc *p)
{
	const char *cat = data;

-
	return (string_val(sbuf, cat, p));
+
	return (string_val(buf, cat, p));
}

/*
@@ -971,13 +971,13 @@ format_category_name(struct sbuf *sbuf, const void *data, struct percent_esc *p)
 * %{ %| %}, where %Dn is replaced by the directory name.  Default
 * %{%Dn\n%|%}
 */
-
struct sbuf *
-
format_directories(struct sbuf *sbuf, const void *data, struct percent_esc *p)
+
UT_string *
+
format_directories(UT_string *buf, const void *data, struct percent_esc *p)
{
	const struct pkg	*pkg = data;

	if (p->flags & (PP_ALTERNATE_FORM1|PP_ALTERNATE_FORM2))
-
		return (list_count(sbuf, pkg_list_count(pkg, PKG_DIRS), p));
+
		return (list_count(buf, pkg_list_count(pkg, PKG_DIRS), p));
	else {
		struct pkg_dir	*dir = NULL;
		int		 count;
@@ -987,62 +987,62 @@ format_directories(struct sbuf *sbuf, const void *data, struct percent_esc *p)
		count = 1;
		while (pkg_dirs(pkg, &dir) == EPKG_OK) {
			if (count > 1)
-
				iterate_item(sbuf, pkg, sbuf_data(p->sep_fmt),
+
				iterate_item(buf, pkg, utstring_body(p->sep_fmt),
					     dir, count, PP_D);

-
			iterate_item(sbuf, pkg, sbuf_data(p->item_fmt),
+
			iterate_item(buf, pkg, utstring_body(p->item_fmt),
				     dir, count, PP_D);
			count++;
		}
	}
-
	return (sbuf);
+
	return (buf);
}

/*
 * %Dg -- Directory group. TODO: numeric gid
 */
-
struct sbuf *
-
format_directory_group(struct sbuf *sbuf, const void *data,
+
UT_string *
+
format_directory_group(UT_string *buf, const void *data,
		       struct percent_esc *p)
{
	const struct pkg_dir	*dir = data;

-
	return (string_val(sbuf, dir->gname, p));
+
	return (string_val(buf, dir->gname, p));
}

/*
 * %Dn -- Directory path name.
 */
-
struct sbuf *
-
format_directory_path(struct sbuf *sbuf, const void *data, struct percent_esc *p)
+
UT_string *
+
format_directory_path(UT_string *buf, const void *data, struct percent_esc *p)
{
	const struct pkg_dir	*dir = data;

-
	return (string_val(sbuf, dir->path, p));
+
	return (string_val(buf, dir->path, p));
}

/*
 * %Dp -- Directory permissions.
 */
-
struct sbuf *
-
format_directory_perms(struct sbuf *sbuf, const void *data,
+
UT_string *
+
format_directory_perms(UT_string *buf, const void *data,
		       struct percent_esc *p)
{
	const struct pkg_dir	*dir = data;

-
	return (mode_val(sbuf, dir->perm, p));
+
	return (mode_val(buf, dir->perm, p));
}

/*
 * %Du -- Directory user. TODO: numeric UID
 */
-
struct sbuf *
-
format_directory_user(struct sbuf *sbuf, const void *data,
+
UT_string *
+
format_directory_user(UT_string *buf, const void *data,
		      struct percent_esc *p)
{
	const struct pkg_dir	*dir = data;

-
	return (string_val(sbuf, dir->uname, p));
+
	return (string_val(buf, dir->uname, p));
}

/*
@@ -1051,13 +1051,13 @@ format_directory_user(struct sbuf *sbuf, const void *data,
 * %}, where %n is replaced by the filename, %s by the checksum, etc.
 * Default %{%Fn\n%|%}
 */
-
struct sbuf *
-
format_files(struct sbuf *sbuf, const void *data, struct percent_esc *p)
+
UT_string *
+
format_files(UT_string *buf, const void *data, struct percent_esc *p)
{
	const struct pkg	*pkg = data;

	if (p->flags & (PP_ALTERNATE_FORM1|PP_ALTERNATE_FORM2))
-
		return (list_count(sbuf, pkg_list_count(pkg, PKG_FILES), p));
+
		return (list_count(buf, pkg_list_count(pkg, PKG_FILES), p));
	else {
		struct pkg_file	*file = NULL;
		int		 count;
@@ -1067,70 +1067,70 @@ format_files(struct sbuf *sbuf, const void *data, struct percent_esc *p)
		count = 1;
		LL_FOREACH(pkg->files, file) {
			if (count > 1)
-
				iterate_item(sbuf, pkg, sbuf_data(p->sep_fmt),
+
				iterate_item(buf, pkg, utstring_body(p->sep_fmt),
					     file, count, PP_F);

-
			iterate_item(sbuf, pkg, sbuf_data(p->item_fmt),
+
			iterate_item(buf, pkg, utstring_body(p->item_fmt),
				     file, count, PP_F);
			count++;
		}
	}
-
	return (sbuf);
+
	return (buf);
}

/*
 * %Fg -- File group.
 */
-
struct sbuf *
-
format_file_group(struct sbuf *sbuf, const void *data, struct percent_esc *p)
+
UT_string *
+
format_file_group(UT_string *buf, const void *data, struct percent_esc *p)
{
	const struct pkg_file	*file = data;

-
	return (string_val(sbuf, file->gname, p));
+
	return (string_val(buf, file->gname, p));
}

/*
 * %Fn -- File path name.
 */
-
struct sbuf *
-
format_file_path(struct sbuf *sbuf, const void *data, struct percent_esc *p)
+
UT_string *
+
format_file_path(UT_string *buf, const void *data, struct percent_esc *p)
{
	const struct pkg_file	*file = data;

-
	return (string_val(sbuf, file->path, p));
+
	return (string_val(buf, file->path, p));
}

/*
 * %Fp -- File permissions.
 */
-
struct sbuf *
-
format_file_perms(struct sbuf *sbuf, const void *data, struct percent_esc *p)
+
UT_string *
+
format_file_perms(UT_string *buf, const void *data, struct percent_esc *p)
{
	const struct pkg_file	*file = data;

-
	return (mode_val(sbuf, file->perm, p));
+
	return (mode_val(buf, file->perm, p));
}

/*
 * %Fs -- File SHA256 Checksum.
 */
-
struct sbuf *
-
format_file_sha256(struct sbuf *sbuf, const void *data, struct percent_esc *p)
+
UT_string *
+
format_file_sha256(UT_string *buf, const void *data, struct percent_esc *p)
{
	const struct pkg_file	*file = data;

-
	return (string_val(sbuf, file->sum, p));
+
	return (string_val(buf, file->sum, p));
}

/*
 * %Fu -- File user.
 */
-
struct sbuf *
-
format_file_user(struct sbuf *sbuf, const void *data, struct percent_esc *p)
+
UT_string *
+
format_file_user(UT_string *buf, const void *data, struct percent_esc *p)
{
	const struct pkg_file	*file = data;

-
	return (string_val(sbuf, file->uname, p));
+
	return (string_val(buf, file->uname, p));
}

/*
@@ -1139,13 +1139,13 @@ format_file_user(struct sbuf *sbuf, const void *data, struct percent_esc *p)
 * groupname or %#Gn by the gid -- a line from
 * /etc/group. Default %{%Gn\n%|%}
 */
-
struct sbuf *
-
format_groups(struct sbuf *sbuf, const void *data, struct percent_esc *p)
+
UT_string *
+
format_groups(UT_string *buf, const void *data, struct percent_esc *p)
{
	const struct pkg	*pkg = data;

	if (p->flags & (PP_ALTERNATE_FORM1|PP_ALTERNATE_FORM2))
-
		return (list_count(sbuf, pkg_list_count(pkg, PKG_GROUPS), p));
+
		return (list_count(buf, pkg_list_count(pkg, PKG_GROUPS), p));
	else {
		char	*group = NULL;
		int	 count;
@@ -1155,37 +1155,37 @@ format_groups(struct sbuf *sbuf, const void *data, struct percent_esc *p)
		count = 1;
		while(pkg_groups(pkg, &group) == EPKG_OK) {
			if (count > 1)
-
				iterate_item(sbuf, pkg, sbuf_data(p->sep_fmt),
+
				iterate_item(buf, pkg, utstring_body(p->sep_fmt),
					     group, count, PP_G);

-
			iterate_item(sbuf, pkg, sbuf_data(p->item_fmt),
+
			iterate_item(buf, pkg, utstring_body(p->item_fmt),
				     group, count, PP_G);
			count++;
		}
	}
-
	return (sbuf);
+
	return (buf);
}

/*
 * %Gn -- Group name.
 */
-
struct sbuf *
-
format_group_name(struct sbuf *sbuf, const void *data, struct percent_esc *p)
+
UT_string *
+
format_group_name(UT_string *buf, const void *data, struct percent_esc *p)
{
	const char	*group = data;

-
	return (string_val(sbuf, group, p));
+
	return (string_val(buf, group, p));
}

/*
 * %I -- Row counter (integer*). Usually used only in per-field format.
 */
-
struct sbuf *
-
format_row_counter(struct sbuf *sbuf, const void *data, struct percent_esc *p)
+
UT_string *
+
format_row_counter(UT_string *buf, const void *data, struct percent_esc *p)
{
	const int *counter = data;

-
	return (int_val(sbuf, *counter, p));
+
	return (int_val(buf, *counter, p));
}

/*
@@ -1193,93 +1193,92 @@ format_row_counter(struct sbuf *sbuf, const void *data, struct percent_esc *p)
 * following per-field format in %{ %| %} where %Ln is replaced by the
 * license name and %l by the license logic.  Default %{%n%| %l %}
 */
-
struct sbuf *
-
format_licenses(struct sbuf *sbuf, const void *data, struct percent_esc *p)
+
UT_string *
+
format_licenses(UT_string *buf, const void *data, struct percent_esc *p)
{
	const struct pkg	*pkg = data;
	char			*lic;
	int			 count = 0;

	if (p->flags & (PP_ALTERNATE_FORM1|PP_ALTERNATE_FORM2)) {
-
		return (list_count(sbuf, pkg_list_count(pkg, PKG_LICENSES), p));
+
		return (list_count(buf, pkg_list_count(pkg, PKG_LICENSES), p));
	} else {
		set_list_defaults(p, "%Ln", " %l ");

		count = 1;
		kh_each_value(pkg->licenses, lic, {
			if (count > 1)
-
				iterate_item(sbuf, pkg, sbuf_data(p->sep_fmt),
+
				iterate_item(buf, pkg, utstring_body(p->sep_fmt),
				    lic, count, PP_L);

-
			iterate_item(sbuf, pkg, sbuf_data(p->item_fmt), lic,
+
			iterate_item(buf, pkg, utstring_body(p->item_fmt), lic,
			    count, PP_L);
			count++;
		});
	}
-
	return (sbuf);
+
	return (buf);
}

/*
 * %Ln -- License name.
 */
-
struct sbuf *
-
format_license_name(struct sbuf *sbuf, const void *data, struct percent_esc *p)
+
UT_string *
+
format_license_name(UT_string *buf, const void *data, struct percent_esc *p)
{
	const char *lic = data;

-
	return (string_val(sbuf, lic, p));
+
	return (string_val(buf, lic, p));
}

/*
 * %M -- Pkg message. string.  Accepts field-width, left-align
 */
-
struct sbuf *
-
format_message(struct sbuf *sbuf, const void *data, struct percent_esc *p)
+
UT_string *
+
format_message(UT_string *buffer, const void *data, struct percent_esc *p)
{
-
	struct sbuf		*buf, *bufmsg;
+
	UT_string		*buf, *bufmsg;
	const struct pkg	*pkg = data;
	struct pkg_message	*msg;
	char			*message;

-
	bufmsg = sbuf_new_auto();
+
	utstring_new(bufmsg);
	LL_FOREACH(pkg->message, msg) {
-
		if (sbuf_len(bufmsg) > 0)
-
			sbuf_putc(bufmsg, '\n');
+
		if (utstring_len(bufmsg) > 0)
+
			utstring_printf(bufmsg, "%c", '\n');
		switch(msg->type) {
		case PKG_MESSAGE_ALWAYS:
-
			sbuf_printf(bufmsg, "Always:\n");
+
			utstring_printf(bufmsg, "Always:\n");
			break;
		case PKG_MESSAGE_UPGRADE:
-
			sbuf_printf(bufmsg, "On upgrade");
+
			utstring_printf(bufmsg, "On upgrade");
			if (msg->minimum_version != NULL ||
			    msg->maximum_version != NULL) {
-
				sbuf_printf(bufmsg, " from %s", pkg->name);
+
				utstring_printf(bufmsg, " from %s", pkg->name);
			}
			if (msg->minimum_version != NULL) {
-
				sbuf_printf(bufmsg, ">%s", msg->minimum_version);
+
				utstring_printf(bufmsg, ">%s", msg->minimum_version);
			}
			if (msg->maximum_version != NULL) {
-
				sbuf_printf(bufmsg, "<%s", msg->maximum_version);
+
				utstring_printf(bufmsg, "<%s", msg->maximum_version);
			}
-
			sbuf_printf(bufmsg, ":\n");
+
			utstring_printf(bufmsg, ":\n");
			break;
		case PKG_MESSAGE_INSTALL:
-
			sbuf_printf(bufmsg, "On install:\n");
+
			utstring_printf(bufmsg, "On install:\n");
			break;
		case PKG_MESSAGE_REMOVE:
-
			sbuf_printf(bufmsg, "On remove:\n");
+
			utstring_printf(bufmsg, "On remove:\n");
			break;
		}
-
		sbuf_printf(bufmsg, "%s\n", msg->str);
+
		utstring_printf(bufmsg, "%s\n", msg->str);
	}
-
	sbuf_finish(bufmsg);
-
	if (sbuf_len(bufmsg) == 0)
+
	if (utstring_len(bufmsg) == 0)
		message = NULL;
	else
-
		message = sbuf_data(bufmsg);
+
		message = utstring_body(bufmsg);

-
	buf = string_val(sbuf, message, p);
-
	sbuf_delete(bufmsg);
+
	buf = string_val(buffer, message, p);
+
	utstring_free(bufmsg);

	return (buf);
}
@@ -1287,8 +1286,8 @@ format_message(struct sbuf *sbuf, const void *data, struct percent_esc *p)
/*
 * %N -- Repository identity. string.  Accepts field-width, left-align
 */
-
struct sbuf *
-
format_repo_ident(struct sbuf *sbuf, const void *data, struct percent_esc *p)
+
UT_string *
+
format_repo_ident(UT_string *buf, const void *data, struct percent_esc *p)
{
	const struct pkg	*pkg = data;
	const char		*reponame;
@@ -1299,7 +1298,7 @@ format_repo_ident(struct sbuf *sbuf, const void *data, struct percent_esc *p)
		if (reponame == NULL)
			reponame = "unknown-repository";
	}
-
	return (string_val(sbuf, reponame, p));
+
	return (string_val(buf, reponame, p));
}

/*
@@ -1307,13 +1306,13 @@ format_repo_ident(struct sbuf *sbuf, const void *data, struct percent_esc *p)
 * following per-field format in %{ %| %}, where %On is replaced by the
 * option name and %Ov by the value.  Default %{%On %Ov\n%|%}
 */ 
-
struct sbuf *
-
format_options(struct sbuf *sbuf, const void *data, struct percent_esc *p)
+
UT_string *
+
format_options(UT_string *buf, const void *data, struct percent_esc *p)
{
	const struct pkg	*pkg = data;

	if (p->flags & (PP_ALTERNATE_FORM1|PP_ALTERNATE_FORM2))
-
		return (list_count(sbuf, pkg_list_count(pkg, PKG_OPTIONS), p));
+
		return (list_count(buf, pkg_list_count(pkg, PKG_OPTIONS), p));
	else {
		struct pkg_option	*opt = NULL;
		int			 count;
@@ -1323,81 +1322,81 @@ format_options(struct sbuf *sbuf, const void *data, struct percent_esc *p)
		count = 1;
		while (pkg_options(pkg, &opt) == EPKG_OK) {
			if (count > 1)
-
				iterate_item(sbuf, pkg, sbuf_data(p->sep_fmt),
+
				iterate_item(buf, pkg, utstring_body(p->sep_fmt),
					     opt, count, PP_O);

-
			iterate_item(sbuf, pkg, sbuf_data(p->item_fmt),
+
			iterate_item(buf, pkg, utstring_body(p->item_fmt),
				     opt, count, PP_O);
			count++;
		}
	}
-
	return (sbuf);
+
	return (buf);
}

/*
 * %On -- Option name.
 */
-
struct sbuf *
-
format_option_name(struct sbuf *sbuf, const void *data, struct percent_esc *p)
+
UT_string *
+
format_option_name(UT_string *buf, const void *data, struct percent_esc *p)
{
	const struct pkg_option	*option = data;

-
	return (string_val(sbuf, option->key, p));
+
	return (string_val(buf, option->key, p));
}

/*
 * %Ov -- Option value.
 */
-
struct sbuf *
-
format_option_value(struct sbuf *sbuf, const void *data, struct percent_esc *p)
+
UT_string *
+
format_option_value(UT_string *buf, const void *data, struct percent_esc *p)
{
	const struct pkg_option	*option = data;

-
	return (string_val(sbuf, option->value, p));
+
	return (string_val(buf, option->value, p));
}

/*
 * %Od -- Option default value.
 */
-
struct sbuf *
-
format_option_default(struct sbuf *sbuf, const void *data, struct percent_esc *p)
+
UT_string *
+
format_option_default(UT_string *buf, const void *data, struct percent_esc *p)
{
	const struct pkg_option	*option = data;

-
	return (string_val(sbuf, option->value, p));
+
	return (string_val(buf, option->value, p));
}

/*
 * %OD -- Option description
 */
-
struct sbuf *
-
format_option_description(struct sbuf *sbuf, const void *data, struct percent_esc *p)
+
UT_string *
+
format_option_description(UT_string *buf, const void *data, struct percent_esc *p)
{
	const struct pkg_option	*option = data;

-
	return (string_val(sbuf, option->description, p));
+
	return (string_val(buf, option->description, p));
}

/*
 * %R -- Repo path. string.
 */
-
struct sbuf *
-
format_repo_path(struct sbuf *sbuf, const void *data, struct percent_esc *p)
+
UT_string *
+
format_repo_path(UT_string *buf, const void *data, struct percent_esc *p)
{
	const struct pkg	*pkg = data;

-
	return (string_val(sbuf, pkg->repopath, p));
+
	return (string_val(buf, pkg->repopath, p));
}

/*
 * %S -- Character string.
 */
-
struct sbuf *
-
format_char_string(struct sbuf *sbuf, const void *data, struct percent_esc *p)
+
UT_string *
+
format_char_string(UT_string *buf, const void *data, struct percent_esc *p)
{
	const char	*charstring = data;

-
	return (string_val(sbuf, charstring, p));
+
	return (string_val(buf, charstring, p));
}

/*
@@ -1406,13 +1405,13 @@ format_char_string(struct sbuf *sbuf, const void *data, struct percent_esc *p)
 * username or %#Un by the uid -- a line from
 * /etc/passwd. Default %{%Un\n%|%}
 */
-
struct sbuf *
-
format_users(struct sbuf *sbuf, const void *data, struct percent_esc *p)
+
UT_string *
+
format_users(UT_string *buf, const void *data, struct percent_esc *p)
{
	const struct pkg	*pkg = data;

	if (p->flags & (PP_ALTERNATE_FORM1|PP_ALTERNATE_FORM2))
-
		return (list_count(sbuf, pkg_list_count(pkg, PKG_USERS), p));
+
		return (list_count(buf, pkg_list_count(pkg, PKG_USERS), p));
	else {
		char	*user = NULL;
		int	 count;
@@ -1422,37 +1421,37 @@ format_users(struct sbuf *sbuf, const void *data, struct percent_esc *p)
		count = 1;
		while (pkg_users(pkg, &user) == EPKG_OK) {
			if (count > 1)
-
				iterate_item(sbuf, pkg, sbuf_data(p->sep_fmt),
+
				iterate_item(buf, pkg, utstring_body(p->sep_fmt),
					     user, count, PP_U);

-
			iterate_item(sbuf, pkg, sbuf_data(p->item_fmt),
+
			iterate_item(buf, pkg, utstring_body(p->item_fmt),
				     user, count, PP_U);
			count++;
		}
	}
-
	return (sbuf);
+
	return (buf);
}

/*
 * %Un -- User name.
 */
-
struct sbuf *
-
format_user_name(struct sbuf *sbuf, const void *data, struct percent_esc *p)
+
UT_string *
+
format_user_name(UT_string *buf, const void *data, struct percent_esc *p)
{
	const char	*user = data;

-
	return (string_val(sbuf, user, p));
+
	return (string_val(buf, user, p));
}

/*
 * %V -- Old package version. string. Accepts field width, left align
 */
-
struct sbuf *
-
format_old_version(struct sbuf *sbuf, const void *data, struct percent_esc *p)
+
UT_string *
+
format_old_version(UT_string *buf, const void *data, struct percent_esc *p)
{
	const struct pkg	*pkg = data;

-
	return (string_val(sbuf, pkg->old_version, p));
+
	return (string_val(buf, pkg->old_version, p));
}

/*
@@ -1460,13 +1459,13 @@ format_old_version(struct sbuf *sbuf, const void *data, struct percent_esc *p)
 * binaries in the pkg.  Optionally accepts per-field format in %{ %|
 * %}.  Default %{%Yn\n%|%}
 */
-
struct sbuf *
-
format_required(struct sbuf *sbuf, const void *data, struct percent_esc *p)
+
UT_string *
+
format_required(UT_string *buf, const void *data, struct percent_esc *p)
{
	const struct pkg	*pkg = data;

	if (p->flags & (PP_ALTERNATE_FORM1|PP_ALTERNATE_FORM2))
-
		return (list_count(sbuf, pkg_list_count(pkg, PKG_REQUIRES), p));
+
		return (list_count(buf, pkg_list_count(pkg, PKG_REQUIRES), p));
	else {
		char	*provide = NULL;
		int	 count;
@@ -1476,38 +1475,38 @@ format_required(struct sbuf *sbuf, const void *data, struct percent_esc *p)
		count = 1;
		while (pkg_requires(pkg, &provide) == EPKG_OK) {
			if (count > 1)
-
				iterate_item(sbuf, pkg, sbuf_data(p->sep_fmt),
+
				iterate_item(buf, pkg, utstring_body(p->sep_fmt),
					     provide, count, PP_Y);

-
			iterate_item(sbuf, pkg, sbuf_data(p->item_fmt),
+
			iterate_item(buf, pkg, utstring_body(p->item_fmt),
				     provide, count, PP_Y);
			count++;
		}
	}
-
	return (sbuf);
+
	return (buf);
}

/*
 * %Yn -- Required name or %yn -- Provided name
 */
-
struct sbuf *
-
format_provide_name(struct sbuf *sbuf, const void *data, struct percent_esc *p)
+
UT_string *
+
format_provide_name(UT_string *buf, const void *data, struct percent_esc *p)
{
	const char	*provide = data;

-
	return (string_val(sbuf, provide, p));
+
	return (string_val(buf, provide, p));
}
/*
 * %a -- Autoremove flag. boolean.  Accepts field-width, left-align.
 * Standard form: 0, 1.  Alternate form1: no, yes.  Alternate form2:
 * false, true
 */
-
struct sbuf *
-
format_autoremove(struct sbuf *sbuf, const void *data, struct percent_esc *p)
+
UT_string *
+
format_autoremove(UT_string *buf, const void *data, struct percent_esc *p)
{
	const struct pkg	*pkg = data;

-
	return (bool_val(sbuf, pkg->automatic, p));
+
	return (bool_val(buf, pkg->automatic, p));
}


@@ -1516,13 +1515,13 @@ format_autoremove(struct sbuf *sbuf, const void *data, struct percent_esc *p)
 * binaries in the pkg.  Optionally accepts per-field format in %{ %|
 * %}, where %n is replaced by the shlib name.  Default %{%bn\n%|%}
 */
-
struct sbuf *
-
format_shlibs_provided(struct sbuf *sbuf, const void *data, struct percent_esc *p)
+
UT_string *
+
format_shlibs_provided(UT_string *buf, const void *data, struct percent_esc *p)
{
	const struct pkg	*pkg = data;

	if (p->flags & (PP_ALTERNATE_FORM1|PP_ALTERNATE_FORM2))
-
		return (list_count(sbuf, pkg_list_count(pkg, PKG_SHLIBS_PROVIDED), p));
+
		return (list_count(buf, pkg_list_count(pkg, PKG_SHLIBS_PROVIDED), p));
	else {
		char	*shlib = NULL;
		int	 count;
@@ -1532,26 +1531,26 @@ format_shlibs_provided(struct sbuf *sbuf, const void *data, struct percent_esc *
		count = 1;
		while (pkg_shlibs_provided(pkg, &shlib) == EPKG_OK) {
			if (count > 1)
-
				iterate_item(sbuf, pkg, sbuf_data(p->sep_fmt),
+
				iterate_item(buf, pkg, utstring_body(p->sep_fmt),
					     shlib, count, PP_b);

-
			iterate_item(sbuf, pkg, sbuf_data(p->item_fmt),
+
			iterate_item(buf, pkg, utstring_body(p->item_fmt),
				     shlib, count, PP_b);
			count++;
		}
	}
-
	return (sbuf);
+
	return (buf);
}

/*
 * %c -- Comment. string.  Accepts field-width, left-align
 */
-
struct sbuf *
-
format_comment(struct sbuf *sbuf, const void *data, struct percent_esc *p)
+
UT_string *
+
format_comment(UT_string *buf, const void *data, struct percent_esc *p)
{
	const struct pkg	*pkg = data;

-
	return (string_val(sbuf, pkg->comment, p));
+
	return (string_val(buf, pkg->comment, p));
}

/*
@@ -1559,13 +1558,13 @@ format_comment(struct sbuf *sbuf, const void *data, struct percent_esc *p)
 * per-field format string in %{ %| %} using any pkg_printf() *scalar*
 * formats. Defaults to printing "%dn-%dv\n" for each dependency.
 */
-
struct sbuf *
-
format_dependencies(struct sbuf *sbuf, const void *data, struct percent_esc *p)
+
UT_string *
+
format_dependencies(UT_string *buf, const void *data, struct percent_esc *p)
{
	const struct pkg	*pkg = data;

	if (p->flags & (PP_ALTERNATE_FORM1|PP_ALTERNATE_FORM2))
-
		return (list_count(sbuf, pkg_list_count(pkg, PKG_DEPS), p));
+
		return (list_count(buf, pkg_list_count(pkg, PKG_DEPS), p));
	else {
		struct pkg_dep	*dep = NULL;
		int		 count;
@@ -1575,74 +1574,74 @@ format_dependencies(struct sbuf *sbuf, const void *data, struct percent_esc *p)
		count = 1;
		while (pkg_deps(pkg, &dep) == EPKG_OK) {
			if (count > 1)
-
				iterate_item(sbuf, pkg, sbuf_data(p->sep_fmt),
+
				iterate_item(buf, pkg, utstring_body(p->sep_fmt),
					     dep, count, PP_d);

-
			iterate_item(sbuf, pkg, sbuf_data(p->item_fmt),
+
			iterate_item(buf, pkg, utstring_body(p->item_fmt),
				     dep, count, PP_d);
			count++;
		}
	}
-
	return (sbuf);
+
	return (buf);
}

/*
 * %dk -- Dependency lock status or %rk -- Requirement lock status.
 */
-
struct sbuf *
-
format_dependency_lock(struct sbuf *sbuf, const void *data,
+
UT_string *
+
format_dependency_lock(UT_string *buf, const void *data,
		       struct percent_esc *p)
{
	const struct pkg_dep	*dep = data;

-
	return (bool_val(sbuf, pkg_dep_is_locked(dep), p));
+
	return (bool_val(buf, pkg_dep_is_locked(dep), p));
}

/*
 * %dn -- Dependency name or %rn -- Requirement name.
 */
-
struct sbuf *
-
format_dependency_name(struct sbuf *sbuf, const void *data,
+
UT_string *
+
format_dependency_name(UT_string *buf, const void *data,
		       struct percent_esc *p)
{
	const struct pkg_dep	*dep = data;

-
	return (string_val(sbuf, dep->name, p));
+
	return (string_val(buf, dep->name, p));
}

/*
 * %do -- Dependency origin or %ro -- Requirement origin.
 */
-
struct sbuf *
-
format_dependency_origin(struct sbuf *sbuf, const void *data,
+
UT_string *
+
format_dependency_origin(UT_string *buf, const void *data,
			 struct percent_esc *p)
{
	const struct pkg_dep	*dep = data;

-
	return (string_val(sbuf, dep->origin, p));
+
	return (string_val(buf, dep->origin, p));
}

/*
 * %dv -- Dependency version or %rv -- Requirement version.
 */
-
struct sbuf *
-
format_dependency_version(struct sbuf *sbuf, const void *data,
+
UT_string *
+
format_dependency_version(UT_string *buf, const void *data,
			  struct percent_esc *p)
{
	const struct pkg_dep	*dep = data;

-
	return (string_val(sbuf, dep->version, p));
+
	return (string_val(buf, dep->version, p));
}

/*
 * %e -- Description. string. Accepts field-width, left-align
 */
-
struct sbuf *
-
format_description(struct sbuf *sbuf, const void *data, struct percent_esc *p)
+
UT_string *
+
format_description(UT_string *buf, const void *data, struct percent_esc *p)
{
	const struct pkg	*pkg = data;

-
	return (string_val(sbuf, pkg->desc, p));
+
	return (string_val(buf, pkg->desc, p));
}

/*
@@ -1650,12 +1649,12 @@ format_description(struct sbuf *sbuf, const void *data, struct percent_esc *p)
 * Standard form: 0, 1.  Alternate form1: no, yes.  Alternate form2:
 * false, true
 */
-
struct sbuf *
-
format_lock_status(struct sbuf *sbuf, const void *data, struct percent_esc *p)
+
UT_string *
+
format_lock_status(UT_string *buf, const void *data, struct percent_esc *p)
{
	const struct pkg	*pkg = data;

-
	return (bool_val(sbuf, pkg->locked, p));
+
	return (bool_val(buf, pkg->locked, p));
}

/*
@@ -1663,67 +1662,67 @@ format_lock_status(struct sbuf *sbuf, const void *data, struct percent_esc *p)
 * Standard form: and, or, single. Alternate form 1: &, |, ''.
 * Alternate form 2: &&, ||, ==
 */
-
struct sbuf *
-
format_license_logic(struct sbuf *sbuf, const void *data, struct percent_esc *p)
+
UT_string *
+
format_license_logic(UT_string *buf, const void *data, struct percent_esc *p)
{
	const struct pkg	*pkg = data;

-
	return (liclog_val(sbuf, pkg->licenselogic, p));
+
	return (liclog_val(buf, pkg->licenselogic, p));
}

/*
 * %m -- Maintainer e-mail address. string.  Accepts field-width, left-align
 */
-
struct sbuf *
-
format_maintainer(struct sbuf *sbuf, const void *data, struct percent_esc *p)
+
UT_string *
+
format_maintainer(UT_string *buf, const void *data, struct percent_esc *p)
{
	const struct pkg	*pkg = data;

-
	return (string_val(sbuf, pkg->maintainer, p));
+
	return (string_val(buf, pkg->maintainer, p));
}

/*
 * %n -- Package name. string.  Accepts field-width, left-align
 */
-
struct sbuf *
-
format_name(struct sbuf *sbuf, const void *data, struct percent_esc *p)
+
UT_string *
+
format_name(UT_string *buf, const void *data, struct percent_esc *p)
{
	const struct pkg	*pkg = data;

-
	return (string_val(sbuf, pkg->name, p));
+
	return (string_val(buf, pkg->name, p));
}

/*
 * %o -- Package origin. string.  Accepts field-width, left-align
 */
-
struct sbuf *
-
format_origin(struct sbuf *sbuf, const void *data, struct percent_esc *p)
+
UT_string *
+
format_origin(UT_string *buf, const void *data, struct percent_esc *p)
{
	const struct pkg	*pkg = data;

-
	return (string_val(sbuf, pkg->origin, p));
+
	return (string_val(buf, pkg->origin, p));
}

/*
 * %p -- Installation prefix. string. Accepts field-width, left-align
 */
-
struct sbuf *
-
format_prefix(struct sbuf *sbuf, const void *data, struct percent_esc *p)
+
UT_string *
+
format_prefix(UT_string *buf, const void *data, struct percent_esc *p)
{
	const struct pkg	*pkg = data;

-
	return (string_val(sbuf, pkg->prefix, p));
+
	return (string_val(buf, pkg->prefix, p));
}

/*
 * %q -- pkg architecture a.k.a ABI string.  Accepts field-width, left-align
 */
-
struct sbuf *
-
format_architecture(struct sbuf *sbuf, const void *data, struct percent_esc *p)
+
UT_string *
+
format_architecture(UT_string *buf, const void *data, struct percent_esc *p)
{
	const struct pkg	*pkg = data;

-
	return (string_val(sbuf, pkg->arch, p));
+
	return (string_val(buf, pkg->arch, p));
}

/*
@@ -1731,13 +1730,13 @@ format_architecture(struct sbuf *sbuf, const void *data, struct percent_esc *p)
 * per-field format string in %{ %| %} using any pkg_printf() *scalar*
 * formats. Defaults to printing "%{%rn-%rv\n%|%}" for each dependency.
 */
-
struct sbuf *
-
format_requirements(struct sbuf *sbuf, const void *data, struct percent_esc *p)
+
UT_string *
+
format_requirements(UT_string *buf, const void *data, struct percent_esc *p)
{
	const struct pkg	*pkg = data;

	if (p->flags & (PP_ALTERNATE_FORM1|PP_ALTERNATE_FORM2))
-
		return(list_count(sbuf, pkg_list_count(pkg, PKG_RDEPS), p));
+
		return(list_count(buf, pkg_list_count(pkg, PKG_RDEPS), p));
	else {
		struct pkg_dep	*req = NULL;
		int		 count;
@@ -1747,15 +1746,15 @@ format_requirements(struct sbuf *sbuf, const void *data, struct percent_esc *p)
		count = 1;
		while (pkg_rdeps(pkg, &req) == EPKG_OK) {
			if (count > 1)
-
				iterate_item(sbuf, pkg, sbuf_data(p->sep_fmt),
+
				iterate_item(buf, pkg, utstring_body(p->sep_fmt),
					     req, count, PP_r);

-
			iterate_item(sbuf, pkg, sbuf_data(p->item_fmt),
+
			iterate_item(buf, pkg, utstring_body(p->item_fmt),
				     req, count, PP_r);
			count++;
		}
	}
-
	return (sbuf);
+
	return (buf);
}

/*
@@ -1765,12 +1764,12 @@ format_requirements(struct sbuf *sbuf, const void *data, struct percent_esc *p)
 * exponents (k, M, G).  Alternate form 2, ditto, but using binary
 * scale prefixes (ki, Mi, Gi etc.)
 */
-
struct sbuf *
-
format_flatsize(struct sbuf *sbuf, const void *data, struct percent_esc *p)
+
UT_string *
+
format_flatsize(UT_string *buf, const void *data, struct percent_esc *p)
{
	const struct pkg	*pkg = data;

-
	return (int_val(sbuf, pkg->flatsize, p));
+
	return (int_val(buf, pkg->flatsize, p));
}

/*
@@ -1779,56 +1778,56 @@ format_flatsize(struct sbuf *sbuf, const void *data, struct percent_esc *p)
 * format string in %{ %}.  Default is to print seconds-since-epoch as
 * an integer applying our integer format modifiers.
 */
-
struct sbuf *
-
format_install_tstamp(struct sbuf *sbuf, const void *data, struct percent_esc *p)
+
UT_string *
+
format_install_tstamp(UT_string *buf, const void *data, struct percent_esc *p)
{
	const struct pkg	*pkg = data;

-
	if (sbuf_len(p->item_fmt) == 0)
-
		return (int_val(sbuf, pkg->timestamp, p));
+
	if (utstring_len(p->item_fmt) == 0)
+
		return (int_val(buf, pkg->timestamp, p));
	else {
-
		char	 buf[1024];
+
		char	 buffer[1024];
		time_t	 tsv;

		tsv = (time_t)pkg->timestamp;
-
		strftime(buf, sizeof(buf), sbuf_data(p->item_fmt),
+
		strftime(buffer, sizeof(buffer), utstring_body(p->item_fmt),
			 localtime(&tsv));
-
		sbuf_cat(sbuf, buf); 
+
		utstring_printf(buf, "%s", buffer);
	}
-
	return (sbuf);
+
	return (buf);
}

/*
 * %v -- Package version. string. Accepts field width, left align
 */
-
struct sbuf *
-
format_version(struct sbuf *sbuf, const void *data, struct percent_esc *p)
+
UT_string *
+
format_version(UT_string *buf, const void *data, struct percent_esc *p)
{
	const struct pkg	*pkg = data;

-
	return (string_val(sbuf, pkg->version, p));
+
	return (string_val(buf, pkg->version, p));
}

/*
 * %u -- Package checksum. string. Accepts field width, left align
 */
-
struct sbuf *
-
format_checksum(struct sbuf *sbuf, const void *data, struct percent_esc *p)
+
UT_string *
+
format_checksum(UT_string *buf, const void *data, struct percent_esc *p)
{
	const struct pkg	*pkg = data;

-
	return (string_val(sbuf, pkg->sum, p));
+
	return (string_val(buf, pkg->sum, p));
}

/*
 * %w -- Home page URL.  string.  Accepts field width, left align
 */
-
struct sbuf *
-
format_home_url(struct sbuf *sbuf, const void *data, struct percent_esc *p)
+
UT_string *
+
format_home_url(UT_string *buf, const void *data, struct percent_esc *p)
{
	const struct pkg	*pkg = data;

-
	return (string_val(sbuf, pkg->www, p));
+
	return (string_val(buf, pkg->www, p));
}

/*
@@ -1838,12 +1837,12 @@ format_home_url(struct sbuf *sbuf, const void *data, struct percent_esc *p)
 * exponents (k, M, G).  Alternate form 2, ditto, but using binary
 * scale prefixes (ki, Mi, Gi etc.)
 */
-
struct sbuf *
-
format_pkgsize(struct sbuf *sbuf, const void *data, struct percent_esc *p)
+
UT_string *
+
format_pkgsize(UT_string *buf, const void *data, struct percent_esc *p)
{
	const struct pkg	*pkg = data;

-
	return (int_val(sbuf, pkg->pkgsize, p));
+
	return (int_val(buf, pkg->pkgsize, p));
}

/*
@@ -1851,13 +1850,13 @@ format_pkgsize(struct sbuf *sbuf, const void *data, struct percent_esc *p)
 * binaries in the pkg.  Optionally accepts per-field format in %{ %|
 * %}.  Default %{%yn\n%|%}
 */
-
struct sbuf *
-
format_provided(struct sbuf *sbuf, const void *data, struct percent_esc *p)
+
UT_string *
+
format_provided(UT_string *buf, const void *data, struct percent_esc *p)
{
	const struct pkg	*pkg = data;

	if (p->flags & (PP_ALTERNATE_FORM1|PP_ALTERNATE_FORM2))
-
		return (list_count(sbuf, pkg_list_count(pkg, PKG_PROVIDES), p));
+
		return (list_count(buf, pkg_list_count(pkg, PKG_PROVIDES), p));
	else {
		char	*provide = NULL;
		int	 count;
@@ -1867,22 +1866,22 @@ format_provided(struct sbuf *sbuf, const void *data, struct percent_esc *p)
		count = 1;
		while (pkg_provides(pkg, &provide) == EPKG_OK) {
			if (count > 1)
-
				iterate_item(sbuf, pkg, sbuf_data(p->sep_fmt),
+
				iterate_item(buf, pkg, utstring_body(p->sep_fmt),
					     provide, count, PP_y);

-
			iterate_item(sbuf, pkg, sbuf_data(p->item_fmt),
+
			iterate_item(buf, pkg, utstring_body(p->item_fmt),
				     provide, count, PP_y);
			count++;
		}
	}
-
	return (sbuf);
+
	return (buf);
}

/*
 * %z -- Package short checksum. string. Accepts field width, left align
 */
-
struct sbuf *
-
format_short_checksum(struct sbuf *sbuf, const void *data, struct percent_esc *p)
+
UT_string *
+
format_short_checksum(UT_string *buf, const void *data, struct percent_esc *p)
{
	const struct pkg	*pkg = data;
	char	 csum[PKG_FILE_CKSUM_CHARS + 1];
@@ -1895,28 +1894,28 @@ format_short_checksum(struct sbuf *sbuf, const void *data, struct percent_esc *p
	memcpy(csum, pkg->sum, slen);
	csum[slen] = '\0';

-
	return (string_val(sbuf, csum, p));
+
	return (string_val(buf, csum, p));
}
/*
 * %% -- Output a literal '%' character
 */
-
struct sbuf *
-
format_literal_percent(struct sbuf *sbuf, __unused const void *data,
+
UT_string *
+
format_literal_percent(UT_string *buf, __unused const void *data,
		       __unused struct percent_esc *p)
{
-
	sbuf_putc(sbuf, '%');
-
	return (sbuf);
+
	utstring_printf(buf, "%c", '%');
+
	return (buf);
}

/*
 * Unknown format code -- return NULL to signal upper layers to pass
 * the text through unchanged.
 */
-
struct sbuf *
-
format_unknown(struct sbuf *sbuf, __unused const void *data,
+
UT_string *
+
format_unknown(UT_string *buf, __unused const void *data,
		       __unused struct percent_esc *p)
{
-
	sbuf_putc(sbuf, '%');
+
	utstring_printf(buf, "%c", '%');
	return (NULL);
}

@@ -1925,12 +1924,12 @@ format_unknown(struct sbuf *sbuf, __unused const void *data,
struct percent_esc *
new_percent_esc(void)
{
-
	struct percent_esc	*p; 
+
	struct percent_esc	*p;

	p = calloc(1, sizeof(struct percent_esc));
	if (p != NULL) {
-
		p->item_fmt = sbuf_new_auto();
-
		p->sep_fmt = sbuf_new_auto();
+
		utstring_new(p->item_fmt);
+
		utstring_new(p->sep_fmt);
	}
	if (p == NULL || p->item_fmt == NULL || p->sep_fmt == NULL) {
		/* out of memory */
@@ -1946,11 +1945,8 @@ clear_percent_esc(struct percent_esc *p)
	p->flags = 0;
	p->width = 0;
	p->trailer_status = 0;
-
	sbuf_clear(p->item_fmt);
-
	sbuf_finish(p->item_fmt);
-

-
	sbuf_clear(p->sep_fmt);
-
	sbuf_finish(p->sep_fmt);
+
	utstring_clear(p->item_fmt);
+
	utstring_clear(p->sep_fmt);

	p->fmt_code = '\0';

@@ -1962,9 +1958,9 @@ free_percent_esc(struct percent_esc *p)
{
	if (p) {
		if (p->item_fmt)
-
			sbuf_delete(p->item_fmt);
+
			utstring_free(p->item_fmt);
		if (p->sep_fmt)
-
			sbuf_delete(p->sep_fmt);
+
			utstring_free(p->sep_fmt);
		free(p);
	}
	return;
@@ -2039,8 +2035,8 @@ gen_format(char *buf, size_t buflen, unsigned flags, const char *tail)
}


-
struct sbuf *
-
human_number(struct sbuf *sbuf, int64_t number, struct percent_esc *p)
+
UT_string *
+
human_number(UT_string *buf, int64_t number, struct percent_esc *p)
{
	double		 num;
	int		 sign;
@@ -2115,17 +2111,17 @@ human_number(struct sbuf *sbuf, int64_t number, struct percent_esc *p)
			precision = 0;
	}

-
	sbuf_printf(sbuf, format, width, precision, num * sign);
+
	utstring_printf(buf, format, width, precision, num * sign);

	if (scale > 0)
-
		sbuf_printf(sbuf, "%s",
+
		utstring_printf(buf, "%s",
		    bin_scale ? bin_pfx[scale] : si_pfx[scale]);

-
	return (sbuf);
+
	return (buf);
}

-
struct sbuf *
-
string_val(struct sbuf *sbuf, const char *str, struct percent_esc *p)
+
UT_string *
+
string_val(UT_string *buf, const char *str, struct percent_esc *p)
{
	char	format[16];

@@ -2142,15 +2138,15 @@ string_val(struct sbuf *sbuf, const char *str, struct percent_esc *p)
	if (gen_format(format, sizeof(format), p->flags, "s") == NULL)
		return (NULL);

-
	sbuf_printf(sbuf, format, p->width, str);
-
	return (sbuf);
+
	utstring_printf(buf, format, p->width, str);
+
	return (buf);
}

-
struct sbuf *
-
int_val(struct sbuf *sbuf, int64_t value, struct percent_esc *p)
+
UT_string *
+
int_val(UT_string *buf, int64_t value, struct percent_esc *p)
{
	if (p->flags & (PP_ALTERNATE_FORM1|PP_ALTERNATE_FORM2))
-
		return (human_number(sbuf, value, p));
+
		return (human_number(buf, value, p));
	else {
		char	 format[16];

@@ -2158,13 +2154,13 @@ int_val(struct sbuf *sbuf, int64_t value, struct percent_esc *p)
		    == NULL)
			return (NULL);

-
		sbuf_printf(sbuf, format, p->width, value);
+
		utstring_printf(buf, format, p->width, value);
	}
-
	return (sbuf);
+
	return (buf);
}

-
struct sbuf *
-
bool_val(struct sbuf *sbuf, bool value, struct percent_esc *p)
+
UT_string *
+
bool_val(UT_string *buf, bool value, struct percent_esc *p)
{
	static const char	*boolean_str[2][3] = {
		[false]	= { "false", "no",  ""    },
@@ -2181,11 +2177,11 @@ bool_val(struct sbuf *sbuf, bool value, struct percent_esc *p)

	p->flags &= ~(PP_ALTERNATE_FORM1|PP_ALTERNATE_FORM2);

-
	return (string_val(sbuf, boolean_str[value][alternate], p));
+
	return (string_val(buf, boolean_str[value][alternate], p));
}

-
struct sbuf *
-
mode_val(struct sbuf *sbuf, mode_t mode, struct percent_esc *p)
+
UT_string *
+
mode_val(UT_string *buf, mode_t mode, struct percent_esc *p)
{
	/*
         * Print mode as an octal integer '%o' by default.
@@ -2199,7 +2195,7 @@ mode_val(struct sbuf *sbuf, mode_t mode, struct percent_esc *p)

		strmode(mode, modebuf);

-
		return (string_val(sbuf, modebuf, p));
+
		return (string_val(buf, modebuf, p));
	} else {
		char	format[16];

@@ -2221,13 +2217,13 @@ mode_val(struct sbuf *sbuf, mode_t mode, struct percent_esc *p)
		    == NULL)
			return (NULL);

-
		sbuf_printf(sbuf, format, p->width, mode);
+
		utstring_printf(buf, format, p->width, mode);
	}
-
	return (sbuf);
+
	return (buf);
}

-
struct sbuf *
-
liclog_val(struct sbuf *sbuf, lic_t licenselogic, struct percent_esc *p)
+
UT_string *
+
liclog_val(UT_string *buf, lic_t licenselogic, struct percent_esc *p)
{
	int			 alternate;
	int			 llogic = PP_LIC_SINGLE;
@@ -2259,11 +2255,11 @@ liclog_val(struct sbuf *sbuf, lic_t licenselogic, struct percent_esc *p)

	p->flags &= ~(PP_ALTERNATE_FORM1|PP_ALTERNATE_FORM2);

-
	return (string_val(sbuf, liclog_str[llogic][alternate], p));
+
	return (string_val(buf, liclog_str[llogic][alternate], p));
}

-
struct sbuf *
-
list_count(struct sbuf *sbuf, int64_t count, struct percent_esc *p)
+
UT_string *
+
list_count(UT_string *buf, int64_t count, struct percent_esc *p)
{
	/* Convert to 0 or 1 for %?X */
	if (p->flags & PP_ALTERNATE_FORM1)
@@ -2272,7 +2268,7 @@ list_count(struct sbuf *sbuf, int64_t count, struct percent_esc *p)
	/* Turn off %#X and %?X flags, then print as a normal integer */
	p->flags &= ~(PP_ALTERNATE_FORM1|PP_ALTERNATE_FORM2);

-
	return (int_val(sbuf, count, p));
+
	return (int_val(buf, count, p));
}

struct percent_esc *
@@ -2280,20 +2276,18 @@ set_list_defaults(struct percent_esc *p, const char *item_fmt,
		  const char *sep_fmt)
{
	if ((p->trailer_status & ITEM_FMT_SET) != ITEM_FMT_SET) {
-
		sbuf_cat(p->item_fmt, item_fmt);
-
		sbuf_finish(p->item_fmt);
+
		utstring_printf(p->item_fmt, "%s", item_fmt);
		p->trailer_status |= ITEM_FMT_SET;
	}
	if ((p->trailer_status & SEP_FMT_SET) != SEP_FMT_SET) {
-
		sbuf_cat(p->sep_fmt, sep_fmt);
-
		sbuf_finish(p->sep_fmt);
+
		utstring_printf(p->sep_fmt, "%s", sep_fmt);
		p->trailer_status |= SEP_FMT_SET;
	}
	return (p);
}

-
struct sbuf *
-
iterate_item(struct sbuf *sbuf, const struct pkg *pkg, const char *format,
+
UT_string *
+
iterate_item(UT_string *buf, const struct pkg *pkg, const char *format,
	     const void *data, int count, unsigned context)
{
	const char		*f;
@@ -2305,31 +2299,31 @@ iterate_item(struct sbuf *sbuf, const struct pkg *pkg, const char *format,
	p = new_percent_esc();

	if (p == NULL) {
-
		sbuf_clear(sbuf);
-
		return (sbuf);	/* Out of memory */
+
		utstring_clear(buf);
+
		return (buf);	/* Out of memory */
	}

	while ( *f != '\0' ) {
		switch(*f) {
		case '%':
-
			f = process_format_trailer(sbuf, p, f, pkg, data, count, context);
+
			f = process_format_trailer(buf, p, f, pkg, data, count, context);
			break;
		case '\\':
-
			f = process_escape(sbuf, f);
+
			f = process_escape(buf, f);
			break;
		default:
-
			sbuf_putc(sbuf, *f);
+
			utstring_printf(buf, "%c", *f);
			f++;
			break;
		}
		if (f == NULL) {
-
			sbuf_clear(sbuf);
+
			utstring_clear(buf);
			break;	/* Out of memory */
		}
	}

	free_percent_esc(p);
-
	return (sbuf);
+
	return (buf);
}

const char *
@@ -2458,7 +2452,7 @@ format_trailer(const char *f, struct percent_esc *p)
				f1 = f2 + 2;
				break;
			}
-
			sbuf_putc(p->item_fmt, *f2);
+
			utstring_printf(p->item_fmt, "%c", *f2);
		}


@@ -2472,7 +2466,7 @@ format_trailer(const char *f, struct percent_esc *p)
					f1 = f2 + 2;
					break;
				}
-
				sbuf_putc(p->sep_fmt, *f2);
+
				utstring_printf(p->sep_fmt, "%c", *f2);
			}
			
		}
@@ -2480,11 +2474,9 @@ format_trailer(const char *f, struct percent_esc *p)
		if (done) {
			f = f1;
		} else {
-
			sbuf_clear(p->item_fmt);
-
			sbuf_clear(p->sep_fmt);
+
			utstring_clear(p->item_fmt);
+
			utstring_clear(p->sep_fmt);
		}
-
		sbuf_finish(p->item_fmt);
-
		sbuf_finish(p->sep_fmt);
	}

	return (f);
@@ -2548,7 +2540,7 @@ parse_format(const char *f, unsigned context, struct percent_esc *p)
}

const char*
-
maybe_read_hex_byte(struct sbuf *sbuf, const char *f)
+
maybe_read_hex_byte(UT_string *buf, const char *f)
{
	/* Hex escapes are of the form \xNN -- always two hex digits */

@@ -2680,19 +2672,19 @@ maybe_read_hex_byte(struct sbuf *sbuf, const char *f)
			break;
		}

-
		sbuf_putc(sbuf, val);
+
		utstring_printf(buf, "%c", val);
		f++;
	} else {
		/* Pass through unchanged if it's not a recognizable
		   hex byte. */
-
		sbuf_putc(sbuf, '\\');
-
		sbuf_putc(sbuf, 'x');
+
		utstring_printf(buf, "%c", '\\');
+
		utstring_printf(buf, "%c", 'x');
	}
	return (f);
}

const char*
-
read_oct_byte(struct sbuf *sbuf, const char *f)
+
read_oct_byte(UT_string *buf, const char *f)
{
	int	val = 0;
	int	count = 0;
@@ -2734,55 +2726,55 @@ read_oct_byte(struct sbuf *sbuf, const char *f)
		f++;
	} 
done:
-
	sbuf_putc(sbuf, val);
+
	utstring_printf(buf, "%c", val);

	return (f);
}

const char *
-
process_escape(struct sbuf *sbuf, const char *f)
+
process_escape(UT_string *buf, const char *f)
{
	f++;			/* Eat the \ */

	switch (*f) {
	case 'a':
-
		sbuf_putc(sbuf, '\a');
+
		utstring_printf(buf, "%c", '\a');
		f++;
		break;
	case 'b':
-
		sbuf_putc(sbuf, '\b');
+
		utstring_printf(buf, "%c", '\b');
		f++;
		break;
	case 'f':
-
		sbuf_putc(sbuf, '\f');
+
		utstring_printf(buf, "%c", '\f');
		f++;
		break;
	case 'n':
-
		sbuf_putc(sbuf, '\n');
+
		utstring_printf(buf, "%c", '\n');
		f++;
		break;
	case 't':
-
		sbuf_putc(sbuf, '\t');
+
		utstring_printf(buf, "%c", '\t');
		f++;
		break;
	case 'v':
-
		sbuf_putc(sbuf, '\v');
+
		utstring_printf(buf, "%c", '\v');
		f++;
		break;
	case '\'':
-
		sbuf_putc(sbuf, '\'');
+
		utstring_printf(buf, "%c", '\'');
		f++;
		break;
	case '"':
-
		sbuf_putc(sbuf, '"');
+
		utstring_printf(buf, "%c", '"');
		f++;
		break;
	case '\\':
-
		sbuf_putc(sbuf, '\\');
+
		utstring_printf(buf, "%c", '\\');
		f++;
		break;
	case 'x':		/* Hex escape: \xNN */
-
		f = maybe_read_hex_byte(sbuf, f);
+
		f = maybe_read_hex_byte(buf, f);
		break;
	case '0':
	case '1':
@@ -2792,12 +2784,12 @@ process_escape(struct sbuf *sbuf, const char *f)
	case '5':
	case '6':
	case '7':		/* Oct escape: all fall through */
-
		f = read_oct_byte(sbuf, f);
+
		f = read_oct_byte(buf, f);
		break;
	default:		/* If it's not a recognised escape,
				   leave f pointing at the escaped
				   character */
-
		sbuf_putc(sbuf, '\\');
+
		utstring_printf(buf, "%c", '\\');
		break;
	}

@@ -2805,24 +2797,24 @@ process_escape(struct sbuf *sbuf, const char *f)
}

const char *
-
process_format_trailer(struct sbuf *sbuf, struct percent_esc *p,
+
process_format_trailer(UT_string *buf, struct percent_esc *p,
		       const char *f, const struct pkg *pkg, 
		       const void *data, int count, unsigned context)
{
	const char		*fstart;
-
	struct sbuf		*s;
+
	UT_string		*s;

	fstart = f;
	f = parse_format(f, context, p);

	if (p->fmt_code == PP_ROW_COUNTER)
-
		s = fmt[p->fmt_code].fmt_handler(sbuf, &count, p);
+
		s = fmt[p->fmt_code].fmt_handler(buf, &count, p);
	else if (p->fmt_code > PP_LAST_FORMAT)
-
		s = fmt[p->fmt_code].fmt_handler(sbuf, NULL, p);
+
		s = fmt[p->fmt_code].fmt_handler(buf, NULL, p);
	else if (fmt[p->fmt_code].struct_pkg)
-
		s = fmt[p->fmt_code].fmt_handler(sbuf, pkg, p);
+
		s = fmt[p->fmt_code].fmt_handler(buf, pkg, p);
	else
-
		s = fmt[p->fmt_code].fmt_handler(sbuf, data, p);
+
		s = fmt[p->fmt_code].fmt_handler(buf, data, p);


	if (s == NULL) {
@@ -2835,12 +2827,12 @@ process_format_trailer(struct sbuf *sbuf, struct percent_esc *p,
}

const char *
-
process_format_main(struct sbuf *sbuf, struct percent_esc *p,
+
process_format_main(UT_string *buf, struct percent_esc *p,
		const char *fstart, const char *fend, void *data)
{
-
	struct sbuf		*s;
+
	UT_string		*s;

-
	s = fmt[p->fmt_code].fmt_handler(sbuf, data, p);
+
	s = fmt[p->fmt_code].fmt_handler(buf, data, p);

	clear_percent_esc(p);

@@ -2876,20 +2868,19 @@ pkg_printf(const char * restrict format, ...)
int
pkg_vprintf(const char * restrict format, va_list ap)
{
-
	struct sbuf	*sbuf;
+
	UT_string	*buf;
	int		 count;

-
	sbuf  = sbuf_new_auto();
+
	utstring_new(buf);

-
	if (sbuf)
-
		sbuf = pkg_sbuf_vprintf(sbuf, format, ap);
-
	if (sbuf && sbuf_len(sbuf) >= 0) {
-
		sbuf_finish(sbuf);
-
		count = printf("%s", sbuf_data(sbuf));
+
	if (buf)
+
		buf = pkg_utstring_vprintf(buf, format, ap);
+
	if (buf && utstring_len(buf) >= 0) {
+
		count = printf("%s", utstring_body(buf));
	} else
		count = -1;
-
	if (sbuf)
-
		sbuf_delete(sbuf);
+
	if (buf)
+
		utstring_free(buf);
	return (count);
}

@@ -2921,20 +2912,19 @@ pkg_fprintf(FILE * restrict stream, const char * restrict format, ...)
int
pkg_vfprintf(FILE * restrict stream, const char * restrict format, va_list ap)
{
-
	struct sbuf	*sbuf;
+
	UT_string	*buf;
	int		 count;

-
	sbuf  = sbuf_new_auto();
+
	utstring_new(buf);

-
	if (sbuf)
-
		sbuf = pkg_sbuf_vprintf(sbuf, format, ap);
-
	if (sbuf && sbuf_len(sbuf) >= 0) {
-
		sbuf_finish(sbuf);
-
		count = fprintf(stream, "%s", sbuf_data(sbuf));
+
	if (buf)
+
		buf = pkg_utstring_vprintf(buf, format, ap);
+
	if (buf && utstring_len(buf) >= 0) {
+
		count = fprintf(stream, "%s", utstring_body(buf));
	} else
		count = -1;
-
	if (sbuf)
-
		sbuf_delete(sbuf);
+
	if (buf)
+
		utstring_free(buf);
	return (count);
}

@@ -2970,20 +2960,19 @@ pkg_dprintf(int fd, const char * restrict format, ...)
int
pkg_vdprintf(int fd, const char * restrict format, va_list ap)
{
-
	struct sbuf	*sbuf;
+
	UT_string	*buf;
	int		 count;

-
	sbuf  = sbuf_new_auto();
+
	utstring_new(buf);

-
	if (sbuf)
-
		sbuf = pkg_sbuf_vprintf(sbuf, format, ap);
-
	if (sbuf && sbuf_len(sbuf) >= 0) {
-
		sbuf_finish(sbuf);
-
		count = dprintf(fd, "%s", sbuf_data(sbuf));
+
	if (buf)
+
		buf = pkg_utstring_vprintf(buf, format, ap);
+
	if (buf && utstring_len(buf) >= 0) {
+
		count = dprintf(fd, "%s", utstring_body(buf));
	} else 
		count = -1;
-
	if (sbuf)
-
		sbuf_delete(sbuf);
+
	if (buf)
+
		utstring_free(buf);
	return (count);
}

@@ -3024,20 +3013,19 @@ int
pkg_vsnprintf(char * restrict str, size_t size, const char * restrict format,
	     va_list ap)
{
-
	struct sbuf	*sbuf;
+
	UT_string	*buf;
	int		 count;

-
	sbuf  = sbuf_new_auto();
+
	utstring_new(buf);

-
	if (sbuf)
-
		sbuf = pkg_sbuf_vprintf(sbuf, format, ap);
-
	if (sbuf && sbuf_len(sbuf) >= 0) {
-
		sbuf_finish(sbuf);
-
		count = snprintf(str, size, "%s", sbuf_data(sbuf));
+
	if (buf)
+
		buf = pkg_utstring_vprintf(buf, format, ap);
+
	if (buf && utstring_len(buf) >= 0) {
+
		count = snprintf(str, size, "%s", utstring_body(buf));
	} else
		count = -1;
-
	if (sbuf)
-
		sbuf_delete(sbuf);
+
	if (buf)
+
		utstring_free(buf);

	return (count);
}
@@ -3076,69 +3064,68 @@ pkg_asprintf(char **ret, const char * restrict format, ...)
int
pkg_vasprintf(char **ret, const char * restrict format, va_list ap)
{
-
	struct sbuf	*sbuf;
+
	UT_string	*buf;
	int		 count;

-
	sbuf  = sbuf_new_auto();
+
	utstring_new(buf);

-
	if (sbuf)
-
		sbuf = pkg_sbuf_vprintf(sbuf, format, ap);
-
	if (sbuf && sbuf_len(sbuf) >= 0) {
-
		sbuf_finish(sbuf);
-
		count = asprintf(ret, "%s", sbuf_data(sbuf));
+
	if (buf)
+
		buf = pkg_utstring_vprintf(buf, format, ap);
+
	if (buf && utstring_len(buf) >= 0) {
+
		count = asprintf(ret, "%s", utstring_body(buf));
	} else {
		count = -1;
		*ret = NULL;
	}
-
	if (sbuf)
-
		sbuf_delete(sbuf);
+
	if (buf)
+
		utstring_free(buf);
	return (count);
}

/**
-
 * store data from pkg into sbuf as indicated by the format code format.
-
 * @param sbuf contains the result
+
 * store data from pkg into buf as indicated by the format code format.
+
 * @param buf contains the result
 * @param ... Varargs list of struct pkg etc. supplying the data
 * @param format String with embedded %-escapes indicating what to output
 * @return count of the number of characters in the result
 */
-
struct sbuf *
-
pkg_sbuf_printf(struct sbuf * restrict sbuf, const char *restrict format, ...)
+
UT_string *
+
pkg_utstring_printf(UT_string * restrict buf, const char *restrict format, ...)
{
	va_list		 ap;

	va_start(ap, format);
-
	sbuf = pkg_sbuf_vprintf(sbuf, format, ap);
+
	buf = pkg_utstring_vprintf(buf, format, ap);
	va_end(ap);

-
	return (sbuf);
+
	return (buf);
}

/**
-
 * store data from pkg into sbuf as indicated by the format code format.
+
 * store data from pkg into buf as indicated by the format code format.
 * This is the core function called by all the other pkg_printf() family.
-
 * @param sbuf contains the result
+
 * @param buf contains the result
 * @param ap Arglist with struct pkg etc. supplying the data
 * @param format String with embedded %-escapes indicating what to output
 * @return count of the number of characters in the result
 */
-
struct sbuf *
-
pkg_sbuf_vprintf(struct sbuf * restrict sbuf, const char * restrict format,
+
UT_string *
+
pkg_utstring_vprintf(UT_string * restrict buf, const char * restrict format,
		 va_list ap)
{
	const char		*f, *fend;
	struct percent_esc	*p;
	void		*data;

-
	assert(sbuf != NULL);
+
	assert(buf != NULL);
	assert(format != NULL);

	f = format;
	p = new_percent_esc();

	if (p == NULL) {
-
		sbuf_clear(sbuf);
-
		return (sbuf);	/* Out of memory */
+
		utstring_clear(buf);
+
		return (buf);	/* Out of memory */
	}

	while ( *f != '\0' ) {
@@ -3150,24 +3137,24 @@ pkg_sbuf_vprintf(struct sbuf * restrict sbuf, const char * restrict format,
				data = va_arg(ap, void *);
			else
				data = NULL;
-
			f = process_format_main(sbuf, p, f, fend, data);
+
			f = process_format_main(buf, p, f, fend, data);
			break;
		case '\\':
-
			f = process_escape(sbuf, f);
+
			f = process_escape(buf, f);
			break;
		default:
-
			sbuf_putc(sbuf, *f);
+
			utstring_printf(buf, "%c", *f);
			f++;
			break;
		}
		if (f == NULL) {
-
			sbuf_clear(sbuf);
+
			utstring_clear(buf);
			break;	/* Error: out of memory */
		}
	}

	free_percent_esc(p);
-
	return (sbuf);
+
	return (buf);
}
/*
 * That's All Folks!
modified libpkg/pkg_repo_create.c
@@ -294,13 +294,14 @@ pkg_create_repo_worker(struct pkg_fts_item *start, size_t nelts,
	char digestbuf[1024];
	struct iovec iov[2];
	struct msghdr msg;
-

-
	struct sbuf *b = sbuf_new_auto();
+
	UT_string *b;
+
	
+
	utstring_new(b);

	mfd = open(mlfile, O_APPEND|O_CREAT|O_WRONLY, 00644);
	if (mfd == -1) {
		pkg_emit_errno("pkg_create_repo_worker", "open");
-
		sbuf_delete(b);
+
		utstring_free(b);
		return (EPKG_FATAL);
	}

@@ -308,7 +309,7 @@ pkg_create_repo_worker(struct pkg_fts_item *start, size_t nelts,
		ffd = open(flfile, O_APPEND|O_CREAT|O_WRONLY, 00644);
		if (ffd == -1) {
			close(mfd);
-
			sbuf_delete(b);
+
			utstring_free(b);
			pkg_emit_errno("pkg_create_repo_worker", "open");
			return (EPKG_FATAL);
		}
@@ -318,7 +319,7 @@ pkg_create_repo_worker(struct pkg_fts_item *start, size_t nelts,
	switch(pid) {
	case -1:
		pkg_emit_errno("pkg_create_repo_worker", "fork");
-
		sbuf_delete(b);
+
		utstring_free(b);
		close(mfd);
		if (read_files)
			close(ffd);
@@ -328,7 +329,7 @@ pkg_create_repo_worker(struct pkg_fts_item *start, size_t nelts,
		break;
	default:
		/* Parent */
-
		sbuf_delete(b);
+
		utstring_free(b);
		close(mfd);
		if (read_files)
			close(ffd);
@@ -367,13 +368,13 @@ pkg_create_repo_worker(struct pkg_fts_item *start, size_t nelts,
			/*
			 * TODO: use pkg_checksum for new manifests
			 */
-
			sbuf_clear(b);
+
			utstring_clear(b);
			if (legacy)
-
				pkg_emit_manifest_sbuf(pkg, b, PKG_MANIFEST_EMIT_COMPACT, &mdigest);
+
				pkg_emit_manifest_buf(pkg, b, PKG_MANIFEST_EMIT_COMPACT, &mdigest);
			else {
				mdigest = malloc(pkg_checksum_type_size(meta->digest_format));

-
				pkg_emit_manifest_sbuf(pkg, b, PKG_MANIFEST_EMIT_COMPACT, NULL);
+
				pkg_emit_manifest_buf(pkg, b, PKG_MANIFEST_EMIT_COMPACT, NULL);
				if (pkg_checksum_generate(pkg, mdigest,
				     pkg_checksum_type_size(meta->digest_format),
				     meta->digest_format) != EPKG_OK) {
@@ -383,8 +384,7 @@ pkg_create_repo_worker(struct pkg_fts_item *start, size_t nelts,
					goto cleanup;
				}
			}
-
			mlen = sbuf_len(b);
-
			sbuf_finish(b);
+
			mlen = utstring_len(b);

			if (flock(mfd, LOCK_EX) == -1) {
				pkg_emit_errno("pkg_create_repo_worker", "flock");
@@ -394,8 +394,8 @@ pkg_create_repo_worker(struct pkg_fts_item *start, size_t nelts,

			mpos = lseek(mfd, 0, SEEK_END);

-
			iov[0].iov_base = sbuf_data(b);
-
			iov[0].iov_len = sbuf_len(b);
+
			iov[0].iov_base = utstring_body(b);
+
			iov[0].iov_len = utstring_len(b);
			iov[1].iov_base = (void *)"\n";
			iov[1].iov_len = 1;

@@ -447,7 +447,7 @@ pkg_create_repo_worker(struct pkg_fts_item *start, size_t nelts,
cleanup:
	pkg_manifest_keys_free(keys);

-
	sbuf_delete(b);
+
	utstring_free(b);
	write(pip, ".\n", 2);
	close(pip);
	close(mfd);
@@ -857,12 +857,12 @@ cleanup:


static int
-
pkg_repo_sign(char *path, char **argv, int argc, struct sbuf **sig, struct sbuf **cert)
+
pkg_repo_sign(char *path, char **argv, int argc, UT_string **sig, UT_string **cert)
{
	FILE *fp;
	char *sha256;
-
	struct sbuf *cmd = NULL;
-
	struct sbuf *buf = NULL;
+
	UT_string *cmd = NULL;
+
	UT_string *buf = NULL;
	char *line = NULL;
	size_t linecap = 0;
	ssize_t linelen;
@@ -872,17 +872,16 @@ pkg_repo_sign(char *path, char **argv, int argc, struct sbuf **sig, struct sbuf
	if (!sha256)
		return (EPKG_FATAL);

-
	cmd = sbuf_new_auto();
+
	utstring_new(cmd);

	for (i = 0; i < argc; i++) {
		if (strspn(argv[i], " \t\n") > 0)
-
			sbuf_printf(cmd, " \"%s\" ", argv[i]);
+
			utstring_printf(cmd, " \"%s\" ", argv[i]);
		else
-
			sbuf_printf(cmd, " %s ", argv[i]);
+
			utstring_printf(cmd, " %s ", argv[i]);
	}
-
	sbuf_finish(cmd);

-
	if ((fp = popen(sbuf_data(cmd), "r+")) == NULL) {
+
	if ((fp = popen(utstring_body(cmd), "r+")) == NULL) {
		ret = EPKG_FATAL;
		goto done;
	}
@@ -890,9 +889,9 @@ pkg_repo_sign(char *path, char **argv, int argc, struct sbuf **sig, struct sbuf
	fprintf(fp, "%s\n", sha256);

	if (*sig == NULL)
-
		*sig = sbuf_new_auto();
+
		utstring_new(*sig);
	if (*cert == NULL)
-
		*cert = sbuf_new_auto();
+
		utstring_new(*cert);

	while ((linelen = getline(&line, &linecap, fp)) > 0 ) {
		if (strcmp(line, "SIGNATURE\n") == 0) {
@@ -905,7 +904,7 @@ pkg_repo_sign(char *path, char **argv, int argc, struct sbuf **sig, struct sbuf
			break;
		}
		if (buf != NULL)
-
			sbuf_bcat(buf, line, linelen);
+
			utstring_printf(buf, "%s", line);
	}

	if (pclose(fp) != 0) {
@@ -913,15 +912,15 @@ pkg_repo_sign(char *path, char **argv, int argc, struct sbuf **sig, struct sbuf
		goto done;
	}

-
	if (sbuf_data(*sig)[sbuf_len(*sig) -1 ] == '\n')
-
		sbuf_setpos(*sig, sbuf_len(*sig) -1);
+
	if (utstring_body(*sig)[utstring_len(*sig) -1 ] == '\n') {
+
		(*sig)->i--;
+
		(*sig)->d[(*sig)->i] = '\0';
+
	}

-
	sbuf_finish(*sig);
-
	sbuf_finish(*cert);
done:
	free(sha256);
	if (cmd)
-
		sbuf_delete(cmd);
+
		utstring_free(cmd);

	return (ret);
}
@@ -935,7 +934,7 @@ pkg_repo_pack_db(const char *name, const char *archive, char *path,
	unsigned char *sigret = NULL;
	unsigned int siglen = 0;
	char fname[MAXPATHLEN];
-
	struct sbuf *sig, *pub;
+
	UT_string *sig, *pub;
	int ret = EPKG_OK;

	sig = NULL;
@@ -961,13 +960,13 @@ pkg_repo_pack_db(const char *name, const char *archive, char *path,
		}

		snprintf(fname, sizeof(fname), "%s.sig", name);
-
		if (packing_append_buffer(pack, sbuf_data(sig), fname, sbuf_len(sig)) != EPKG_OK) {
+
		if (packing_append_buffer(pack, utstring_body(sig), fname, utstring_len(sig)) != EPKG_OK) {
			ret = EPKG_FATAL;
			goto out;
		}

		snprintf(fname, sizeof(fname), "%s.pub", name);
-
		if (packing_append_buffer(pack, sbuf_data(pub), fname, sbuf_len(pub)) != EPKG_OK) {
+
		if (packing_append_buffer(pack, utstring_body(pub), fname, utstring_len(pub)) != EPKG_OK) {
			ret = EPKG_FATAL;
			goto out;
		}
@@ -980,9 +979,9 @@ out:
	unlink(path);
	free(sigret);
	if (sig != NULL)
-
		sbuf_delete(sig);
+
		utstring_free(sig);
	if (pub != NULL)
-
		sbuf_delete(pub);
+
		utstring_free(pub);

	return (ret);
}
modified libpkg/pkg_solve.c
@@ -206,11 +206,11 @@ pkg_solve_problem_free(struct pkg_solve_problem *problem)
} while (0)

static void
-
pkg_print_rule_sbuf(struct pkg_solve_rule *rule, struct sbuf *sb)
+
pkg_print_rule_buf(struct pkg_solve_rule *rule, UT_string *sb)
{
	struct pkg_solve_item *it = rule->items, *key_elt = NULL;

-
	sbuf_printf(sb, "%s rule: ", rule_reasons[rule->reason]);
+
	utstring_printf(sb, "%s rule: ", rule_reasons[rule->reason]);
	switch(rule->reason) {
	case PKG_RULE_DEPEND:
		LL_FOREACH(rule->items, it) {
@@ -220,25 +220,25 @@ pkg_print_rule_sbuf(struct pkg_solve_rule *rule, struct sbuf *sb)
			}
		}
		if (key_elt) {
-
			sbuf_printf(sb, "package %s%s depends on: ", key_elt->var->uid,
+
			utstring_printf(sb, "package %s%s depends on: ", key_elt->var->uid,
				(key_elt->var->unit->pkg->type == PKG_INSTALLED) ? "(l)" : "(r)");
		}
		LL_FOREACH(rule->items, it) {
			if (it != key_elt) {
-
				sbuf_printf(sb, "%s%s", it->var->uid,
+
				utstring_printf(sb, "%s%s", it->var->uid,
					(it->var->unit->pkg->type == PKG_INSTALLED) ? "(l)" : "(r)");
			}
		}
		break;
	case PKG_RULE_UPGRADE_CONFLICT:
-
		sbuf_printf(sb, "upgrade local %s-%s to remote %s-%s",
+
		utstring_printf(sb, "upgrade local %s-%s to remote %s-%s",
			it->var->uid, it->var->unit->pkg->version,
			it->next->var->uid, it->next->var->unit->pkg->version);
		break;
	case PKG_RULE_EXPLICIT_CONFLICT:
-
		sbuf_printf(sb, "The following packages conflict with each other: ");
+
		utstring_printf(sb, "The following packages conflict with each other: ");
		LL_FOREACH(rule->items, it) {
-
			sbuf_printf(sb, "%s-%s%s%s", it->var->unit->pkg->uid, it->var->unit->pkg->version,
+
			utstring_printf(sb, "%s-%s%s%s", it->var->unit->pkg->uid, it->var->unit->pkg->version,
				(it->var->unit->pkg->type == PKG_INSTALLED) ? "(l)" : "(r)",
				it->next ? ", " : "");
		}
@@ -251,45 +251,43 @@ pkg_print_rule_sbuf(struct pkg_solve_rule *rule, struct sbuf *sb)
			}
		}
		if (key_elt) {
-
			sbuf_printf(sb, "package %s%s depends on a requirement provided by: ",
+
			utstring_printf(sb, "package %s%s depends on a requirement provided by: ",
				key_elt->var->uid,
				(key_elt->var->unit->pkg->type == PKG_INSTALLED) ? "(l)" : "(r)");
		}
		LL_FOREACH(rule->items, it) {
			if (it != key_elt) {
-
				sbuf_printf(sb, "%s%s", it->var->uid,
+
				utstring_printf(sb, "%s%s", it->var->uid,
					(it->var->unit->pkg->type == PKG_INSTALLED) ? "(l)" : "(r)");
			}
		}
		break;
	case PKG_RULE_REQUEST_CONFLICT:
-
		sbuf_printf(sb, "The following packages in request are candidates for installation: ");
+
		utstring_printf(sb, "The following packages in request are candidates for installation: ");
		LL_FOREACH(rule->items, it) {
-
			sbuf_printf(sb, "%s-%s%s", it->var->uid, it->var->unit->pkg->version,
+
			utstring_printf(sb, "%s-%s%s", it->var->uid, it->var->unit->pkg->version,
					it->next ? ", " : "");
		}
		break;
	default:
		break;
	}
-

-
	sbuf_finish(sb);
}

static void
pkg_debug_print_rule(struct pkg_solve_rule *rule)
{
-
	struct sbuf *sb;
+
	UT_string *sb;

	if (debug_level < 3)
		return;

-
	sb = sbuf_new_auto();
+
	utstring_new(sb);

-
	pkg_print_rule_sbuf(rule, sb);
+
	pkg_print_rule_buf(rule, sb);

-
	pkg_debug(2, "%s", sbuf_data(sb));
-
	sbuf_delete(sb);
+
	pkg_debug(2, "%s", utstring_body(sb));
+
	utstring_free(sb);
}

static int
@@ -1128,7 +1126,8 @@ reiterate:

		if (attempt >= 10) {
			pkg_emit_error("Cannot solve problem using SAT solver");
-
			struct sbuf *sb = sbuf_new_auto();
+
			UT_string *sb;
+
			utstring_new(sb);

			while (*failed) {
				var = &problem->variables[abs(*failed) - 1];
@@ -1138,26 +1137,25 @@ reiterate:
					if (rule->reason != PKG_RULE_DEPEND) {
						LL_FOREACH(rule->items, item) {
							if (item->var == var) {
-
								pkg_print_rule_sbuf(rule, sb);
-
								sbuf_putc(sb, '\n');
+
								pkg_print_rule_buf(rule, sb);
+
								utstring_printf(sb, "%c", '\n');
								break;
							}
						}
					}
				}

-
				sbuf_printf(sb, "cannot %s package %s, remove it from request? ",
+
				utstring_printf(sb, "cannot %s package %s, remove it from request? ",
						var->flags & PKG_VAR_INSTALL ? "install" : "remove", var->uid);
-
				sbuf_finish(sb);

-
				if (pkg_emit_query_yesno(true, sbuf_data(sb))) {
+
				if (pkg_emit_query_yesno(true, utstring_body(sb))) {
					var->flags |= PKG_VAR_FAILED;
				}

				failed++;
				need_reiterate = true;
			}
-
			sbuf_reset(sb);
+
			utstring_clear(sb);
		} else {
			pkg_emit_notice("Cannot solve problem using SAT solver, trying another plan");
			var = &problem->variables[abs(*failed) - 1];
modified libpkg/pkgdb.c
@@ -3013,20 +3013,20 @@ pkgdb_stats(struct pkgdb *db, pkg_stats_t type)
{
	sqlite3_stmt	*stmt = NULL;
	int64_t		 stats = 0;
-
	struct sbuf	*sql = NULL;
+
	UT_string	*sql = NULL;
	int		 ret;
	struct _pkg_repo_list_item *rit;

	assert(db != NULL);

-
	sql = sbuf_new_auto();
+
	utstring_new(sql);

	switch(type) {
	case PKG_STATS_LOCAL_COUNT:
-
		sbuf_printf(sql, "SELECT COUNT(id) FROM main.packages;");
+
		utstring_printf(sql, "SELECT COUNT(id) FROM main.packages;");
		break;
	case PKG_STATS_LOCAL_SIZE:
-
		sbuf_printf(sql, "SELECT SUM(flatsize) FROM main.packages;");
+
		utstring_printf(sql, "SELECT SUM(flatsize) FROM main.packages;");
		break;
	case PKG_STATS_REMOTE_UNIQUE:
	case PKG_STATS_REMOTE_COUNT:
@@ -3047,12 +3047,11 @@ pkgdb_stats(struct pkgdb *db, pkg_stats_t type)
		break;
	}

-
	sbuf_finish(sql);
-
	pkg_debug(4, "Pkgdb: running '%s'", sbuf_data(sql));
-
	ret = sqlite3_prepare_v2(db->sqlite, sbuf_data(sql), -1, &stmt, NULL);
+
	pkg_debug(4, "Pkgdb: running '%s'", utstring_body(sql));
+
	ret = sqlite3_prepare_v2(db->sqlite, utstring_body(sql), -1, &stmt, NULL);
	if (ret != SQLITE_OK) {
-
		ERROR_SQLITE(db->sqlite, sbuf_data(sql));
-
		sbuf_free(sql);
+
		ERROR_SQLITE(db->sqlite, utstring_body(sql));
+
		utstring_free(sql);
		return (-1);
	}

@@ -3063,7 +3062,7 @@ pkgdb_stats(struct pkgdb *db, pkg_stats_t type)
	sqlite3_finalize(stmt);

remote:
-
	sbuf_free(sql);
+
	utstring_free(sql);

	return (stats);
}
modified libpkg/plugins.c
@@ -53,7 +53,7 @@ struct plugin_hook {
};

struct pkg_plugin {
-
	struct sbuf *fields[PLUGIN_NUMFIELDS];
+
	UT_string *fields[PLUGIN_NUMFIELDS];
	void *lh;						/* library handle */
	bool parsed;
	struct plugin_hook *hooks;
@@ -89,7 +89,7 @@ plug_free(struct pkg_plugin *p)
	unsigned int i;

	for (i = 0; i < PLUGIN_NUMFIELDS; i++)
-
		sbuf_delete(p->fields[i]);
+
		utstring_free(p->fields[i]);

	pkg_plugin_hook_free(p);
	free(p);
@@ -154,7 +154,9 @@ pkg_plugin_set(struct pkg_plugin *p, pkg_plugin_key key, const char *str)
{
	assert(p != NULL);

-
	return (sbuf_set(&p->fields[key], str));
+
	utstring_renew(p->fields[key]);
+
	utstring_printf(p->fields[key], str);
+
	return (EPKG_OK);
}

const char *
@@ -165,10 +167,7 @@ pkg_plugin_get(struct pkg_plugin *p, pkg_plugin_key key)
	if (p->fields[key] == NULL)
		return (NULL);

-
	if (sbuf_done(p->fields[key]) == 0)
-
		sbuf_finish(p->fields[key]);
-

-
	return (sbuf_data(p->fields[key]));
+
	return (utstring_body(p->fields[key]));
}

int
modified libpkg/private/pkg.h
@@ -34,7 +34,6 @@

#include <sys/param.h>
#include <sys/cdefs.h>
-
#include <sys/sbuf.h>
#include <sys/types.h>

#include <archive.h>
@@ -42,6 +41,7 @@
#include <stdbool.h>
#include <uthash.h>
#include <utlist.h>
+
#include <utstring.h>
#include <ucl.h>

#include "private/utils.h"
@@ -223,7 +223,7 @@ extern bool developer_mode;
extern const char *pkg_rootdir;
extern int rootfd;
extern int cachedirfd;
-
extern int pkg_dbdirfd;
+
extern int dbdirfd;

struct pkg_repo_it;
struct pkg_repo;
@@ -241,7 +241,7 @@ struct pkg {
	bool		 automatic;
	bool		 vital;
	int64_t		 id;
-
	struct sbuf	*scripts[PKG_NUM_SCRIPTS];
+
	UT_string	*scripts[PKG_NUM_SCRIPTS];
	char			*name;
	char			*origin;
	char			*version;
@@ -541,12 +541,12 @@ struct plist {
	char last_file[MAXPATHLEN];
	const char *stage;
	char prefix[MAXPATHLEN];
-
	struct sbuf *pre_install_buf;
-
	struct sbuf *post_install_buf;
-
	struct sbuf *pre_deinstall_buf;
-
	struct sbuf *post_deinstall_buf;
-
	struct sbuf *pre_upgrade_buf;
-
	struct sbuf *post_upgrade_buf;
+
	UT_string *pre_install_buf;
+
	UT_string *post_install_buf;
+
	UT_string *pre_deinstall_buf;
+
	UT_string *post_deinstall_buf;
+
	UT_string *pre_upgrade_buf;
+
	UT_string *post_upgrade_buf;
	struct pkg *pkg;
	char *uname;
	char *gname;
@@ -709,11 +709,11 @@ int pkgdb_is_dir_used(struct pkgdb *db, struct pkg *p, const char *dir, int64_t
int pkgdb_file_set_cksum(struct pkgdb *db, struct pkg_file *file, const char *sha256);


-
int pkg_emit_manifest_sbuf(struct pkg*, struct sbuf *, short, char **);
+
int pkg_emit_manifest_buf(struct pkg*, UT_string *, short, char **);
int pkg_emit_filelist(struct pkg *, FILE *);

-
bool ucl_object_emit_sbuf(const ucl_object_t *obj, enum ucl_emitter emit_type,
-
    struct sbuf **buf);
+
bool ucl_object_emit_buf(const ucl_object_t *obj, enum ucl_emitter emit_type,
+
    UT_string **buf);
bool ucl_object_emit_file(const ucl_object_t *obj, enum ucl_emitter emit_type,
    FILE *);

modified libpkg/private/pkg_jobs.h
@@ -24,7 +24,6 @@
#define PKG_JOBS_H_

#include <sys/cdefs.h>
-
#include <sys/sbuf.h>
#include <sys/types.h>

#include <stdbool.h>
modified libpkg/private/pkg_printf.h
@@ -159,79 +159,79 @@ struct percent_esc {
	unsigned	 flags;
	int		 width;
	unsigned	 trailer_status;
-
	struct sbuf	*item_fmt;
-
	struct sbuf	*sep_fmt;
+
	UT_string	*item_fmt;
+
	UT_string	*sep_fmt;
	fmt_code_t	 fmt_code;
};

/* Format handler function prototypes */

-
_static struct sbuf *format_annotation_name(struct sbuf *, const void *, struct percent_esc *);
-
_static struct sbuf *format_annotation_value(struct sbuf *, const void *, struct percent_esc *);
-
_static struct sbuf *format_annotations(struct sbuf *, const void *, struct percent_esc *);
-
_static struct sbuf *format_shlibs_required(struct sbuf *, const void *, struct percent_esc *);
-
_static struct sbuf *format_shlib_name(struct sbuf *, const void *, struct percent_esc *);
-
_static struct sbuf *format_categories(struct sbuf *, const void *, struct percent_esc *);
-
_static struct sbuf *format_category_name(struct sbuf *, const void *, struct percent_esc *);
-
_static struct sbuf *format_directories(struct sbuf *, const void *, struct percent_esc *);
-
_static struct sbuf *format_directory_group(struct sbuf *, const void *, struct percent_esc *);
-
_static struct sbuf *format_directory_path(struct sbuf *, const void *, struct percent_esc *);
-
_static struct sbuf *format_directory_perms(struct sbuf *, const void *, struct percent_esc *);
-
_static struct sbuf *format_directory_user(struct sbuf *, const void *, struct percent_esc *);
-
_static struct sbuf *format_files(struct sbuf *, const void *, struct percent_esc *);
-
_static struct sbuf *format_file_group(struct sbuf *, const void *, struct percent_esc *);
-
_static struct sbuf *format_file_path(struct sbuf *, const void *, struct percent_esc *);
-
_static struct sbuf *format_file_perms(struct sbuf *, const void *, struct percent_esc *);
-
_static struct sbuf *format_file_sha256(struct sbuf *, const void *, struct percent_esc *);
-
_static struct sbuf *format_file_user(struct sbuf *, const void *, struct percent_esc *);
-
_static struct sbuf *format_groups(struct sbuf *, const void *, struct percent_esc *);
-
_static struct sbuf *format_group_gidstr(struct sbuf *, const void *, struct percent_esc *);
-
_static struct sbuf *format_group_name(struct sbuf *, const void *, struct percent_esc *);
-
_static struct sbuf *format_row_counter(struct sbuf *, const void *, struct percent_esc *);
-
_static struct sbuf *format_licenses(struct sbuf *, const void *, struct percent_esc *);
-
_static struct sbuf *format_license_name(struct sbuf *, const void *, struct percent_esc *);
-
_static struct sbuf *format_message(struct sbuf *, const void *, struct percent_esc *);
-
_static struct sbuf *format_repo_ident(struct sbuf *, const void *, struct percent_esc *);
-
_static struct sbuf *format_options(struct sbuf *, const void *, struct percent_esc *);
-
_static struct sbuf *format_option_name(struct sbuf *, const void *, struct percent_esc *);
-
_static struct sbuf *format_option_value(struct sbuf *, const void *, struct percent_esc *);
-
_static struct sbuf *format_option_default(struct sbuf *, const void *, struct percent_esc *);
-
_static struct sbuf *format_option_description(struct sbuf *, const void *, struct percent_esc *);
-
_static struct sbuf *format_repo_path(struct sbuf *, const void *, struct percent_esc *);
-
_static struct sbuf *format_char_string(struct sbuf *, const void *, struct percent_esc *);
-
_static struct sbuf *format_users(struct sbuf *, const void *, struct percent_esc *);
-
_static struct sbuf *format_user_name(struct sbuf *, const void *, struct percent_esc *);
-
_static struct sbuf *format_user_uidstr(struct sbuf *, const void *, struct percent_esc *);
-
_static struct sbuf *format_old_version(struct sbuf *, const void *, struct percent_esc *);
-
_static struct sbuf *format_autoremove(struct sbuf *, const void *, struct percent_esc *);
-
_static struct sbuf *format_shlibs_provided(struct sbuf *, const void *, struct percent_esc *);
-
_static struct sbuf *format_comment(struct sbuf *, const void *, struct percent_esc *);
-
_static struct sbuf *format_dependencies(struct sbuf *, const void *, struct percent_esc *);
-
_static struct sbuf *format_dependency_lock(struct sbuf *, const void *, struct percent_esc *);
-
_static struct sbuf *format_dependency_name(struct sbuf *, const void *, struct percent_esc *);
-
_static struct sbuf *format_dependency_origin(struct sbuf *, const void *, struct percent_esc *);
-
_static struct sbuf *format_dependency_version(struct sbuf *, const void *, struct percent_esc *);
-
_static struct sbuf *format_description(struct sbuf *, const void *, struct percent_esc *);
-
_static struct sbuf *format_lock_status(struct sbuf *, const void *, struct percent_esc *);
-
_static struct sbuf *format_license_logic(struct sbuf *, const void *, struct percent_esc *);
-
_static struct sbuf *format_maintainer(struct sbuf *, const void *, struct percent_esc *);
-
_static struct sbuf *format_name(struct sbuf *, const void *, struct percent_esc *);
-
_static struct sbuf *format_origin(struct sbuf *, const void *, struct percent_esc *);
-
_static struct sbuf *format_prefix(struct sbuf *, const void *, struct percent_esc *);
-
_static struct sbuf *format_architecture(struct sbuf *, const void *, struct percent_esc *);
-
_static struct sbuf *format_requirements(struct sbuf *, const void *, struct percent_esc *);
-
_static struct sbuf *format_flatsize(struct sbuf *, const void *, struct percent_esc *);
-
_static struct sbuf *format_install_tstamp(struct sbuf *, const void *, struct percent_esc *);
-
_static struct sbuf *format_checksum(struct sbuf *, const void *, struct percent_esc *);
-
_static struct sbuf *format_version(struct sbuf *, const void *, struct percent_esc *);
-
_static struct sbuf *format_home_url(struct sbuf *, const void *, struct percent_esc *);
-
_static struct sbuf *format_pkgsize(struct sbuf *, const void *, struct percent_esc *);
-
_static struct sbuf *format_short_checksum(struct sbuf *, const void *, struct percent_esc *);
-
_static struct sbuf *format_literal_percent(struct sbuf *, __unused const void *, __unused struct percent_esc *);
-
_static struct sbuf *format_unknown(struct sbuf *, __unused const void *, __unused struct percent_esc *);
-
_static struct sbuf *format_provided(struct sbuf *, const void *, struct percent_esc *);
-
_static struct sbuf *format_required(struct sbuf *, const void *, struct percent_esc *);
-
_static struct sbuf *format_provide_name(struct sbuf *, const void *, struct percent_esc *);
+
_static UT_string *format_annotation_name(UT_string *, const void *, struct percent_esc *);
+
_static UT_string *format_annotation_value(UT_string *, const void *, struct percent_esc *);
+
_static UT_string *format_annotations(UT_string *, const void *, struct percent_esc *);
+
_static UT_string *format_shlibs_required(UT_string *, const void *, struct percent_esc *);
+
_static UT_string *format_shlib_name(UT_string *, const void *, struct percent_esc *);
+
_static UT_string *format_categories(UT_string *, const void *, struct percent_esc *);
+
_static UT_string *format_category_name(UT_string *, const void *, struct percent_esc *);
+
_static UT_string *format_directories(UT_string *, const void *, struct percent_esc *);
+
_static UT_string *format_directory_group(UT_string *, const void *, struct percent_esc *);
+
_static UT_string *format_directory_path(UT_string *, const void *, struct percent_esc *);
+
_static UT_string *format_directory_perms(UT_string *, const void *, struct percent_esc *);
+
_static UT_string *format_directory_user(UT_string *, const void *, struct percent_esc *);
+
_static UT_string *format_files(UT_string *, const void *, struct percent_esc *);
+
_static UT_string *format_file_group(UT_string *, const void *, struct percent_esc *);
+
_static UT_string *format_file_path(UT_string *, const void *, struct percent_esc *);
+
_static UT_string *format_file_perms(UT_string *, const void *, struct percent_esc *);
+
_static UT_string *format_file_sha256(UT_string *, const void *, struct percent_esc *);
+
_static UT_string *format_file_user(UT_string *, const void *, struct percent_esc *);
+
_static UT_string *format_groups(UT_string *, const void *, struct percent_esc *);
+
_static UT_string *format_group_gidstr(UT_string *, const void *, struct percent_esc *);
+
_static UT_string *format_group_name(UT_string *, const void *, struct percent_esc *);
+
_static UT_string *format_row_counter(UT_string *, const void *, struct percent_esc *);
+
_static UT_string *format_licenses(UT_string *, const void *, struct percent_esc *);
+
_static UT_string *format_license_name(UT_string *, const void *, struct percent_esc *);
+
_static UT_string *format_message(UT_string *, const void *, struct percent_esc *);
+
_static UT_string *format_repo_ident(UT_string *, const void *, struct percent_esc *);
+
_static UT_string *format_options(UT_string *, const void *, struct percent_esc *);
+
_static UT_string *format_option_name(UT_string *, const void *, struct percent_esc *);
+
_static UT_string *format_option_value(UT_string *, const void *, struct percent_esc *);
+
_static UT_string *format_option_default(UT_string *, const void *, struct percent_esc *);
+
_static UT_string *format_option_description(UT_string *, const void *, struct percent_esc *);
+
_static UT_string *format_repo_path(UT_string *, const void *, struct percent_esc *);
+
_static UT_string *format_char_string(UT_string *, const void *, struct percent_esc *);
+
_static UT_string *format_users(UT_string *, const void *, struct percent_esc *);
+
_static UT_string *format_user_name(UT_string *, const void *, struct percent_esc *);
+
_static UT_string *format_user_uidstr(UT_string *, const void *, struct percent_esc *);
+
_static UT_string *format_old_version(UT_string *, const void *, struct percent_esc *);
+
_static UT_string *format_autoremove(UT_string *, const void *, struct percent_esc *);
+
_static UT_string *format_shlibs_provided(UT_string *, const void *, struct percent_esc *);
+
_static UT_string *format_comment(UT_string *, const void *, struct percent_esc *);
+
_static UT_string *format_dependencies(UT_string *, const void *, struct percent_esc *);
+
_static UT_string *format_dependency_lock(UT_string *, const void *, struct percent_esc *);
+
_static UT_string *format_dependency_name(UT_string *, const void *, struct percent_esc *);
+
_static UT_string *format_dependency_origin(UT_string *, const void *, struct percent_esc *);
+
_static UT_string *format_dependency_version(UT_string *, const void *, struct percent_esc *);
+
_static UT_string *format_description(UT_string *, const void *, struct percent_esc *);
+
_static UT_string *format_lock_status(UT_string *, const void *, struct percent_esc *);
+
_static UT_string *format_license_logic(UT_string *, const void *, struct percent_esc *);
+
_static UT_string *format_maintainer(UT_string *, const void *, struct percent_esc *);
+
_static UT_string *format_name(UT_string *, const void *, struct percent_esc *);
+
_static UT_string *format_origin(UT_string *, const void *, struct percent_esc *);
+
_static UT_string *format_prefix(UT_string *, const void *, struct percent_esc *);
+
_static UT_string *format_architecture(UT_string *, const void *, struct percent_esc *);
+
_static UT_string *format_requirements(UT_string *, const void *, struct percent_esc *);
+
_static UT_string *format_flatsize(UT_string *, const void *, struct percent_esc *);
+
_static UT_string *format_install_tstamp(UT_string *, const void *, struct percent_esc *);
+
_static UT_string *format_checksum(UT_string *, const void *, struct percent_esc *);
+
_static UT_string *format_version(UT_string *, const void *, struct percent_esc *);
+
_static UT_string *format_home_url(UT_string *, const void *, struct percent_esc *);
+
_static UT_string *format_pkgsize(UT_string *, const void *, struct percent_esc *);
+
_static UT_string *format_short_checksum(UT_string *, const void *, struct percent_esc *);
+
_static UT_string *format_literal_percent(UT_string *, __unused const void *, __unused struct percent_esc *);
+
_static UT_string *format_unknown(UT_string *, __unused const void *, __unused struct percent_esc *);
+
_static UT_string *format_provided(UT_string *, const void *, struct percent_esc *);
+
_static UT_string *format_required(UT_string *, const void *, struct percent_esc *);
+
_static UT_string *format_provide_name(UT_string *, const void *, struct percent_esc *);

/* Other static function prototypes */

@@ -241,19 +241,19 @@ _static void free_percent_esc(struct percent_esc *);

_static char *gen_format(char *, size_t, unsigned, const char *);

-
_static struct sbuf *human_number(struct sbuf *, int64_t, struct percent_esc *);
-
_static struct sbuf *string_val(struct sbuf *, const char *,
+
_static UT_string *human_number(UT_string *, int64_t, struct percent_esc *);
+
_static UT_string *string_val(UT_string *, const char *,
			       struct percent_esc *);
-
_static struct sbuf *int_val(struct sbuf *, int64_t, struct percent_esc *);
-
_static struct sbuf *bool_val(struct sbuf *, bool, struct percent_esc *);
-
_static struct sbuf *mode_val(struct sbuf *, mode_t, struct percent_esc *);
-
_static struct sbuf *liclog_val(struct sbuf *, lic_t, struct percent_esc *);
-
_static struct sbuf *list_count(struct sbuf *, int64_t, struct percent_esc *);
+
_static UT_string *int_val(UT_string *, int64_t, struct percent_esc *);
+
_static UT_string *bool_val(UT_string *, bool, struct percent_esc *);
+
_static UT_string *mode_val(UT_string *, mode_t, struct percent_esc *);
+
_static UT_string *liclog_val(UT_string *, lic_t, struct percent_esc *);
+
_static UT_string *list_count(UT_string *, int64_t, struct percent_esc *);

_static struct percent_esc *set_list_defaults(struct percent_esc *,
					      const char *, const char *);

-
_static struct sbuf *iterate_item(struct sbuf *, const struct pkg *,
+
_static UT_string *iterate_item(UT_string *, const struct pkg *,
				  const char *, const void *, int, unsigned);

_static const char *field_modifier(const char *, struct percent_esc *);
@@ -262,14 +262,14 @@ _static const char *format_code(const char *, unsigned , struct percent_esc *);
_static const char *format_trailer(const char *, struct percent_esc *);
_static const char *parse_format(const char *, unsigned, struct percent_esc *);

-
_static const char *maybe_read_hex_byte(struct sbuf *, const char *);
-
_static const char *read_oct_byte(struct sbuf *, const char *);
-
_static const char *process_escape(struct sbuf *, const char *);
+
_static const char *maybe_read_hex_byte(UT_string *, const char *);
+
_static const char *read_oct_byte(UT_string *, const char *);
+
_static const char *process_escape(UT_string *, const char *);

-
_static const char *process_format_trailer(struct sbuf *, struct percent_esc *,
+
_static const char *process_format_trailer(UT_string *, struct percent_esc *,
					   const char *, const struct pkg *,
					   const void *, int, unsigned);
-
_static const char *process_format_main(struct sbuf *, struct percent_esc *,
+
_static const char *process_format_main(UT_string *, struct percent_esc *,
					const char *, const char *, void *);

#endif
modified libpkg/private/utils.h
@@ -29,13 +29,13 @@
#define _PKG_UTIL_H

#include <sys/types.h>
-
#include <sys/sbuf.h>
#include <sys/stat.h>
#include <sys/param.h>
#include <uthash.h>
#include <ucl.h>
#include <khash.h>
#include <pkg.h>
+
#include <utstring.h>

#define STARTS_WITH(string, needle) (strncasecmp(string, needle, strlen(needle)) == 0)
#define RELATIVE_PATH(p) (p + (*p == '/' ? 1 : 0))
@@ -63,10 +63,6 @@ struct dns_srvinfo {
struct rsa_key;

int32_t string_hash_func(const char *);
-
void sbuf_init(struct sbuf **);
-
int sbuf_set(struct sbuf **, const char *);
-
void sbuf_reset(struct sbuf *);
-
void sbuf_free(struct sbuf *);

int mkdirs(const char *path);
int file_to_buffer(const char *, char **, off_t *);
@@ -101,7 +97,7 @@ pid_t process_spawn_pipe(FILE *inout[2], const char *command);

void *parse_mode(const char *str);
int *text_diff(char *a, char *b);
-
int merge_3way(char *pivot, char *v1, char *v2, struct sbuf *out);
+
int merge_3way(char *pivot, char *v1, char *v2, UT_string *out);
bool string_end_with(const char *path, const char *str);
bool mkdirat_p(int fd, const char *path);

modified libpkg/repo/binary/query.c
@@ -105,7 +105,7 @@ pkg_repo_binary_query(struct pkg_repo *repo, const char *pattern, match_t match)
{
	sqlite3 *sqlite = PRIV_GET(repo);
	sqlite3_stmt	*stmt = NULL;
-
	struct sbuf	*sql = NULL;
+
	UT_string	*sql = NULL;
	const char	*comp = NULL;
	int		 ret;
	char		 basesql[BUFSIZ] = ""
@@ -118,27 +118,26 @@ pkg_repo_binary_query(struct pkg_repo *repo, const char *pattern, match_t match)
	if (match != MATCH_ALL && (pattern == NULL || pattern[0] == '\0'))
		return (NULL);

-
	sql = sbuf_new_auto();
+
	utstring_new(sql);
	comp = pkgdb_get_pattern_query(pattern, match);
	if (comp && comp[0])
		strlcat(basesql, comp, sizeof(basesql));

-
	sbuf_printf(sql, basesql, repo->name);
+
	utstring_printf(sql, basesql, repo->name);

-
	sbuf_cat(sql, " ORDER BY name;");
-
	sbuf_finish(sql);
+
	utstring_printf(sql, "%s", " ORDER BY name;");

-
	pkg_debug(4, "Pkgdb: running '%s' query for %s", sbuf_data(sql),
+
	pkg_debug(4, "Pkgdb: running '%s' query for %s", utstring_body(sql),
	     pattern == NULL ? "all": pattern);
-
	ret = sqlite3_prepare_v2(sqlite, sbuf_data(sql), sbuf_len(sql), &stmt,
+
	ret = sqlite3_prepare_v2(sqlite, utstring_body(sql), utstring_len(sql), &stmt,
	    NULL);
	if (ret != SQLITE_OK) {
-
		ERROR_SQLITE(sqlite, sbuf_data(sql));
-
		sbuf_delete(sql);
+
		ERROR_SQLITE(sqlite, utstring_body(sql));
+
		utstring_free(sql);
		return (NULL);
	}

-
	sbuf_delete(sql);
+
	utstring_free(sql);

	if (match != MATCH_ALL && match != MATCH_CONDITION)
		sqlite3_bind_text(stmt, 1, pattern, -1, SQLITE_TRANSIENT);
@@ -151,7 +150,7 @@ pkg_repo_binary_shlib_provide(struct pkg_repo *repo, const char *require)
{
	sqlite3_stmt	*stmt;
	sqlite3 *sqlite = PRIV_GET(repo);
-
	struct sbuf	*sql = NULL;
+
	UT_string	*sql = NULL;
	int		 ret;
	const char	 basesql[] = ""
			"SELECT p.id, p.origin, p.name, p.version, p.comment, "
@@ -164,20 +163,18 @@ pkg_repo_binary_shlib_provide(struct pkg_repo *repo, const char *require)
			"WHERE ps.shlib_id IN (SELECT id FROM shlibs WHERE "
			"name BETWEEN ?1 AND ?1 || '.9');";

-
	sql = sbuf_new_auto();
-
	sbuf_printf(sql, basesql, repo->name);
+
	utstring_new(sql);
+
	utstring_printf(sql, basesql, repo->name);

-
	sbuf_finish(sql);
-

-
	pkg_debug(4, "Pkgdb: running '%s'", sbuf_data(sql));
-
	ret = sqlite3_prepare_v2(sqlite, sbuf_data(sql), -1, &stmt, NULL);
+
	pkg_debug(4, "Pkgdb: running '%s'", utstring_body(sql));
+
	ret = sqlite3_prepare_v2(sqlite, utstring_body(sql), -1, &stmt, NULL);
	if (ret != SQLITE_OK) {
-
		ERROR_SQLITE(sqlite, sbuf_data(sql));
-
		sbuf_delete(sql);
+
		ERROR_SQLITE(sqlite, utstring_body(sql));
+
		utstring_free(sql);
		return (NULL);
	}

-
	sbuf_delete(sql);
+
	utstring_free(sql);

	sqlite3_bind_text(stmt, 1, require, -1, SQLITE_TRANSIENT);

@@ -189,7 +186,7 @@ pkg_repo_binary_provide(struct pkg_repo *repo, const char *require)
{
	sqlite3_stmt	*stmt;
	sqlite3 *sqlite = PRIV_GET(repo);
-
	struct sbuf	*sql = NULL;
+
	UT_string	*sql = NULL;
	int		 ret;
	const char	 basesql[] = ""
			"SELECT p.id, p.origin, p.name, p.version, p.comment, "
@@ -202,20 +199,18 @@ pkg_repo_binary_provide(struct pkg_repo *repo, const char *require)
			"WHERE ps.provide_id IN (SELECT id from provides WHERE "
			"provide = ?1 );";

-
	sql = sbuf_new_auto();
-
	sbuf_printf(sql, basesql, repo->name);
-

-
	sbuf_finish(sql);
+
	utstring_new(sql);
+
	utstring_printf(sql, basesql, repo->name);

-
	pkg_debug(4, "Pkgdb: running '%s'", sbuf_data(sql));
-
	ret = sqlite3_prepare_v2(sqlite, sbuf_data(sql), -1, &stmt, NULL);
+
	pkg_debug(4, "Pkgdb: running '%s'", utstring_body(sql));
+
	ret = sqlite3_prepare_v2(sqlite, utstring_body(sql), -1, &stmt, NULL);
	if (ret != SQLITE_OK) {
-
		ERROR_SQLITE(sqlite, sbuf_data(sql));
-
		sbuf_delete(sql);
+
		ERROR_SQLITE(sqlite, utstring_body(sql));
+
		utstring_free(sql);
		return (NULL);
	}

-
	sbuf_delete(sql);
+
	utstring_free(sql);

	sqlite3_bind_text(stmt, 1, require, -1, SQLITE_TRANSIENT);

@@ -227,7 +222,7 @@ pkg_repo_binary_shlib_require(struct pkg_repo *repo, const char *provide)
{
	sqlite3_stmt	*stmt;
	sqlite3 *sqlite = PRIV_GET(repo);
-
	struct sbuf	*sql = NULL;
+
	UT_string	*sql = NULL;
	int		 ret;
	const char	 basesql[] = ""
			"SELECT p.id, p.origin, p.name, p.version, p.comment, "
@@ -239,20 +234,18 @@ pkg_repo_binary_shlib_require(struct pkg_repo *repo, const char *provide)
			"p.id = ps.package_id "
			"WHERE ps.shlib_id = (SELECT id FROM shlibs WHERE name=?1);";

-
	sql = sbuf_new_auto();
-
	sbuf_printf(sql, basesql, repo->name);
+
	utstring_new(sql);
+
	utstring_printf(sql, basesql, repo->name);

-
	sbuf_finish(sql);
-

-
	pkg_debug(4, "Pkgdb: running '%s'", sbuf_data(sql));
-
	ret = sqlite3_prepare_v2(sqlite, sbuf_data(sql), -1, &stmt, NULL);
+
	pkg_debug(4, "Pkgdb: running '%s'", utstring_body(sql));
+
	ret = sqlite3_prepare_v2(sqlite, utstring_body(sql), -1, &stmt, NULL);
	if (ret != SQLITE_OK) {
-
		ERROR_SQLITE(sqlite, sbuf_data(sql));
-
		sbuf_delete(sql);
+
		ERROR_SQLITE(sqlite, utstring_body(sql));
+
		utstring_free(sql);
		return (NULL);
	}

-
	sbuf_delete(sql);
+
	utstring_free(sql);

	pkg_debug(1, "> loading provides");
	sqlite3_bind_text(stmt, 1, provide, -1, SQLITE_TRANSIENT);
@@ -265,7 +258,7 @@ pkg_repo_binary_require(struct pkg_repo *repo, const char *provide)
{
	sqlite3_stmt	*stmt;
	sqlite3 *sqlite = PRIV_GET(repo);
-
	struct sbuf	*sql = NULL;
+
	UT_string	*sql = NULL;
	int		 ret;
	const char	 basesql[] = ""
			"SELECT p.id, p.origin, p.name, p.version, p.comment, "
@@ -277,20 +270,18 @@ pkg_repo_binary_require(struct pkg_repo *repo, const char *provide)
			"p.id = ps.package_id "
			"WHERE ps.require_id = (SELECT id FROM requires WHERE require=?1);";

-
	sql = sbuf_new_auto();
-
	sbuf_printf(sql, basesql, repo->name);
-

-
	sbuf_finish(sql);
+
	utstring_new(sql);
+
	utstring_printf(sql, basesql, repo->name);

-
	pkg_debug(4, "Pkgdb: running '%s'", sbuf_data(sql));
-
	ret = sqlite3_prepare_v2(sqlite, sbuf_data(sql), -1, &stmt, NULL);
+
	pkg_debug(4, "Pkgdb: running '%s'", utstring_body(sql));
+
	ret = sqlite3_prepare_v2(sqlite, utstring_body(sql), -1, &stmt, NULL);
	if (ret != SQLITE_OK) {
-
		ERROR_SQLITE(sqlite, sbuf_data(sql));
-
		sbuf_delete(sql);
+
		ERROR_SQLITE(sqlite, utstring_body(sql));
+
		utstring_free(sql);
		return (NULL);
	}

-
	sbuf_delete(sql);
+
	utstring_free(sql);

	sqlite3_bind_text(stmt, 1, provide, -1, SQLITE_TRANSIENT);

@@ -327,7 +318,7 @@ pkg_repo_binary_search_how(match_t match)
}

static int
-
pkg_repo_binary_build_search_query(struct sbuf *sql, match_t match,
+
pkg_repo_binary_build_search_query(UT_string *sql, match_t match,
    pkgdb_field field, pkgdb_field sort)
{
	const char	*how = NULL;
@@ -358,7 +349,7 @@ pkg_repo_binary_build_search_query(struct sbuf *sql, match_t match,
	}

	if (what != NULL && how != NULL)
-
		sbuf_printf(sql, how, what);
+
		utstring_printf(sql, how, what);

	switch (sort) {
	case FIELD_NONE:
@@ -382,7 +373,7 @@ pkg_repo_binary_build_search_query(struct sbuf *sql, match_t match,
	}

	if (orderby != NULL)
-
		sbuf_cat(sql, orderby);
+
		utstring_printf(sql, "%s", orderby);

	return (EPKG_OK);
}
@@ -393,7 +384,7 @@ pkg_repo_binary_search(struct pkg_repo *repo, const char *pattern, match_t match
{
	sqlite3 *sqlite = PRIV_GET(repo);
	sqlite3_stmt	*stmt = NULL;
-
	struct sbuf	*sql = NULL;
+
	UT_string	*sql = NULL;
	int		 ret;
	const char	*multireposql = ""
		"SELECT id, origin, name, version, comment, "
@@ -405,25 +396,24 @@ pkg_repo_binary_search(struct pkg_repo *repo, const char *pattern, match_t match
	if (pattern == NULL || pattern[0] == '\0')
		return (NULL);

-
	sql = sbuf_new_auto();
-
	sbuf_printf(sql, multireposql, repo->name, repo->url);
+
	utstring_new(sql);
+
	utstring_printf(sql, multireposql, repo->name, repo->url);

	/* close the UNIONs and build the search query */
-
	sbuf_cat(sql, "WHERE ");
+
	utstring_printf(sql, "%s", "WHERE ");

	pkg_repo_binary_build_search_query(sql, match, field, sort);
-
	sbuf_cat(sql, ";");
-
	sbuf_finish(sql);
+
	utstring_printf(sql, "%s", ";");

-
	pkg_debug(4, "Pkgdb: running '%s'", sbuf_data(sql));
-
	ret = sqlite3_prepare_v2(sqlite, sbuf_data(sql), -1, &stmt, NULL);
+
	pkg_debug(4, "Pkgdb: running '%s'", utstring_body(sql));
+
	ret = sqlite3_prepare_v2(sqlite, utstring_body(sql), -1, &stmt, NULL);
	if (ret != SQLITE_OK) {
-
		ERROR_SQLITE(sqlite, sbuf_data(sql));
-
		sbuf_delete(sql);
+
		ERROR_SQLITE(sqlite, utstring_body(sql));
+
		utstring_free(sql);
		return (NULL);
	}

-
	sbuf_delete(sql);
+
	utstring_free(sql);

	sqlite3_bind_text(stmt, 1, pattern, -1, SQLITE_TRANSIENT);

@@ -482,10 +472,10 @@ pkg_repo_binary_stat(struct pkg_repo *repo, pkg_stats_t type)
	sqlite3 *sqlite = PRIV_GET(repo);
	sqlite3_stmt	*stmt = NULL;
	int64_t		 stats = 0;
-
	struct sbuf	*sql = NULL;
+
	UT_string	*sql = NULL;
	int		 ret;

-
	sql = sbuf_new_auto();
+
	utstring_new(sql);

	switch(type) {
	case PKG_STATS_LOCAL_COUNT:
@@ -495,24 +485,23 @@ pkg_repo_binary_stat(struct pkg_repo *repo, pkg_stats_t type)
		goto out;
		break;
	case PKG_STATS_REMOTE_UNIQUE:
-
		sbuf_printf(sql, "SELECT COUNT(id) FROM main.packages;");
+
		utstring_printf(sql, "SELECT COUNT(id) FROM main.packages;");
		break;
	case PKG_STATS_REMOTE_COUNT:
-
		sbuf_printf(sql, "SELECT COUNT(id) FROM main.packages;");
+
		utstring_printf(sql, "SELECT COUNT(id) FROM main.packages;");
		break;
	case PKG_STATS_REMOTE_SIZE:
-
		sbuf_printf(sql, "SELECT SUM(pkgsize) FROM main.packages;");
+
		utstring_printf(sql, "SELECT SUM(pkgsize) FROM main.packages;");
		break;
	case PKG_STATS_REMOTE_REPOS:
		goto out;
		break;
	}

-
	sbuf_finish(sql);
-
	pkg_debug(4, "binary_repo: running '%s'", sbuf_data(sql));
-
	ret = sqlite3_prepare_v2(sqlite, sbuf_data(sql), -1, &stmt, NULL);
+
	pkg_debug(4, "binary_repo: running '%s'", utstring_body(sql));
+
	ret = sqlite3_prepare_v2(sqlite, utstring_body(sql), -1, &stmt, NULL);
	if (ret != SQLITE_OK) {
-
		ERROR_SQLITE(sqlite, sbuf_data(sql));
+
		ERROR_SQLITE(sqlite, utstring_body(sql));
		goto out;
	}

@@ -521,7 +510,7 @@ pkg_repo_binary_stat(struct pkg_repo *repo, pkg_stats_t type)
	}

out:
-
	sbuf_free(sql);
+
	utstring_free(sql);
	if (stmt != NULL)
		sqlite3_finalize(stmt);

modified libpkg/scripts.c
@@ -40,6 +40,7 @@
#include <stdlib.h>
#include <limits.h>
#include <string.h>
+
#include <utstring.h>

#include "pkg.h"
#include "private/pkg.h"
@@ -50,7 +51,7 @@ extern char **environ;
int
pkg_script_run(struct pkg * const pkg, pkg_script type)
{
-
	struct sbuf * const script_cmd = sbuf_new_auto();
+
	UT_string *script_cmd;
	size_t i, j;
	int error, pstat;
	pid_t pid;
@@ -86,8 +87,10 @@ pkg_script_run(struct pkg * const pkg, pkg_script type)
		{"POST-DEINSTALL", PKG_SCRIPT_DEINSTALL, PKG_SCRIPT_POST_DEINSTALL},
	};

+
	utstring_new(script_cmd);
+

	if (!pkg_object_bool(pkg_config_get("RUN_SCRIPTS"))) {
-
		sbuf_delete(script_cmd);
+
		utstring_free(script_cmd);
		return (EPKG_OK);
	}

@@ -106,25 +109,23 @@ pkg_script_run(struct pkg * const pkg, pkg_script type)
		if (pkg_script_get(pkg, j) == NULL)
			continue;
		if (j == map[i].a || j == map[i].b) {
-
			sbuf_reset(script_cmd);
+
			utstring_clear(script_cmd);
			setenv("PKG_PREFIX", pkg->prefix, 1);
			if (pkg_rootdir == NULL)
				pkg_rootdir = "/";
			setenv("PKG_ROOTDIR", pkg_rootdir, 1);
			debug = pkg_object_bool(pkg_config_get("DEBUG_SCRIPTS"));
			if (debug)
-
				sbuf_printf(script_cmd, "set -x\n");
-
			pkg_sbuf_printf(script_cmd, "set -- %n-%v", pkg, pkg);
+
				utstring_printf(script_cmd, "set -x\n");
+
			pkg_utstring_printf(script_cmd, "set -- %n-%v", pkg, pkg);

			if (j == map[i].b) {
				/* add arg **/
-
				sbuf_cat(script_cmd, " ");
-
				sbuf_cat(script_cmd, map[i].arg);
+
				utstring_printf(script_cmd, " %s", map[i].arg);
			}

-
			sbuf_cat(script_cmd, "\n");
-
			sbuf_cat(script_cmd, pkg_script_get(pkg, j));
-
			sbuf_finish(script_cmd);
+
			utstring_printf(script_cmd, "\n%s",
+
			    utstring_body(pkg->scripts[j]));

			/* Determine the maximum argument length for the given
			   script to determine if /bin/sh -c can be used, or
@@ -137,8 +138,8 @@ pkg_script_run(struct pkg * const pkg, pkg_script type)
				argmax -= strlen(*ep) + 1 + sizeof(*ep);
			argmax -= 1 + sizeof(*ep);

-
			pkg_debug(3, "Scripts: executing\n--- BEGIN ---\n%s\nScripts: --- END ---", sbuf_data(script_cmd));
-
			if (sbuf_len(script_cmd) > argmax) {
+
			pkg_debug(3, "Scripts: executing\n--- BEGIN ---\n%s\nScripts: --- END ---", utstring_body(script_cmd));
+
			if (utstring_len(script_cmd) > argmax) {
				if (pipe(stdin_pipe) < 0) {
					ret = EPKG_FATAL;
					goto cleanup;
@@ -157,7 +158,7 @@ pkg_script_run(struct pkg * const pkg, pkg_script type)
			} else {
				argv[0] = _PATH_BSHELL;
				argv[1] = "-c";
-
				argv[2] = sbuf_data(script_cmd);
+
				argv[2] = utstring_body(script_cmd);
				argv[3] = NULL;

				use_pipe = 0;
@@ -174,8 +175,8 @@ pkg_script_run(struct pkg * const pkg, pkg_script type)
			}

			if (use_pipe) {
-
				script_cmd_p = sbuf_data(script_cmd);
-
				script_cmd_len = sbuf_len(script_cmd);
+
				script_cmd_p = utstring_body(script_cmd);
+
				script_cmd_len = utstring_len(script_cmd);
				while (script_cmd_len > 0) {
					if ((bytes_written = write(stdin_pipe[1], script_cmd_p,
					    script_cmd_len)) == -1) {
@@ -207,7 +208,7 @@ pkg_script_run(struct pkg * const pkg, pkg_script type)

cleanup:

-
	sbuf_delete(script_cmd);
+
	utstring_free(script_cmd);
	if (stdin_pipe[0] != -1)
		close(stdin_pipe[0]);
	if (stdin_pipe[1] != -1)
modified libpkg/utils.c
@@ -53,45 +53,6 @@
#include "private/event.h"
#include "private/utils.h"

-
void
-
sbuf_init(struct sbuf **buf)
-
{
-
	if (*buf == NULL)
-
		*buf = sbuf_new_auto();
-
	else
-
		sbuf_clear(*buf);
-
}
-

-
int
-
sbuf_set(struct sbuf **buf, const char *str)
-
{
-
	if (*buf == NULL)
-
		*buf = sbuf_new_auto();
-

-
	if (str == NULL)
-
		return (-1);
-

-
	sbuf_cpy(*buf, str);
-
	sbuf_finish(*buf);
-
	return (0);
-
}
-

-
void
-
sbuf_reset(struct sbuf *buf)
-
{
-
	if (buf != NULL) {
-
		sbuf_clear(buf);
-
		sbuf_finish(buf);
-
	}
-
}
-

-
void
-
sbuf_free(struct sbuf *buf)
-
{
-
	if (buf != NULL)
-
		sbuf_delete(buf);
-
}
-

int
mkdirs(const char *_path)
{
@@ -225,38 +186,38 @@ int
format_exec_cmd(char **dest, const char *in, const char *prefix,
    const char *plist_file, char *line, int argc, char **argv)
{
-
	struct sbuf *buf = sbuf_new_auto();
+
	UT_string *buf;
	char path[MAXPATHLEN];
	char *cp;
	size_t sz;

+
	utstring_new(buf);
+

	while (in[0] != '\0') {
		if (in[0] != '%') {
-
			sbuf_putc(buf, in[0]);
+
			utstring_printf(buf, "%c", in[0]);
			in++;
			continue;
		}
		in++;
		switch(in[0]) {
		case 'D':
-
			sbuf_cat(buf, prefix);
+
			utstring_printf(buf, "%s", prefix);
			break;
		case 'F':
			if (plist_file == NULL || plist_file[0] == '\0') {
				pkg_emit_error("No files defined %%F couldn't "
				    "be expanded, ignoring %s", in);
-
				sbuf_finish(buf);
-
				sbuf_free(buf);
+
				utstring_free(buf);
				return (EPKG_FATAL);
			}
-
			sbuf_cat(buf, plist_file);
+
			utstring_printf(buf, plist_file);
			break;
		case 'f':
			if (plist_file == NULL || plist_file[0] == '\0') {
				pkg_emit_error("No files defined %%f couldn't "
				    "be expanded, ignoring %s", in);
-
				sbuf_finish(buf);
-
				sbuf_free(buf);
+
				utstring_free(buf);
				return (EPKG_FATAL);
			}
			if (prefix[strlen(prefix) - 1] == '/')
@@ -267,14 +228,13 @@ format_exec_cmd(char **dest, const char *in, const char *prefix,
				    prefix, plist_file);
			cp = strrchr(path, '/');
			cp ++;
-
			sbuf_cat(buf, cp);
+
			utstring_printf(buf, cp);
			break;
		case 'B':
			if (plist_file == NULL || plist_file[0] == '\0') {
				pkg_emit_error("No files defined %%B couldn't "
				    "be expanded, ignoring %s", in);
-
				sbuf_finish(buf);
-
				sbuf_free(buf);
+
				utstring_free(buf);
				return (EPKG_FATAL);
			}
			if (prefix[strlen(prefix) - 1] == '/')
@@ -285,14 +245,14 @@ format_exec_cmd(char **dest, const char *in, const char *prefix,
				    plist_file);
			cp = strrchr(path, '/');
			cp[0] = '\0';
-
			sbuf_cat(buf, path);
+
			utstring_printf(buf, path);
			break;
		case '%':
-
			sbuf_putc(buf, '%');
+
			utstring_printf(buf, "%c", '%');
			break;
		case '@':
			if (line != NULL) {
-
				sbuf_cat(buf, line);
+
				utstring_printf(buf, line);
				break;
			}

@@ -302,7 +262,7 @@ format_exec_cmd(char **dest, const char *in, const char *prefix,
			 * exists
			 */
		case '#':
-
			sbuf_putc(buf, argc);
+
			utstring_printf(buf, "%c", argc);
			break;
		default:
			if ((sz = strspn(in, "0123456789")) > 0) {
@@ -311,25 +271,22 @@ format_exec_cmd(char **dest, const char *in, const char *prefix,
					pkg_emit_error("Requesting argument "
					    "%%%d while only %d arguments are"
					    " available", pos, argc);
-
					sbuf_finish(buf);
-
					sbuf_free(buf);
+
					utstring_free(buf);
					return (EPKG_FATAL);
				}
-
				sbuf_cat(buf, argv[pos -1]);
+
				utstring_printf(buf, argv[pos -1]);
				in += sz -1;
				break;
			}
-
			sbuf_putc(buf, '%');
-
			sbuf_putc(buf, in[0]);
+
			utstring_printf(buf, "%c%c", '%', in[0]);
			break;
		}

		in++;
	}

-
	sbuf_finish(buf);
-
	*dest = strdup(sbuf_data(buf));
-
	sbuf_free(buf);
+
	*dest = strdup(utstring_body(buf));
+
	utstring_free(buf);
	
	return (EPKG_OK);
}
@@ -532,49 +489,49 @@ ucl_file_append_double(double val, void *data)
}

static int
-
ucl_sbuf_append_character(unsigned char c, size_t len, void *data)
+
ucl_buf_append_character(unsigned char c, size_t len, void *data)
{
-
	struct sbuf *buf = data;
+
	UT_string *buf = data;
	size_t i;

	for (i = 0; i < len; i++)
-
		sbuf_putc(buf, c);
+
		utstring_printf(buf, "%c", c);

	return (0);
}

static int
-
ucl_sbuf_append_len(const unsigned char *str, size_t len, void *data)
+
ucl_buf_append_len(const unsigned char *str, size_t len, void *data)
{
-
	struct sbuf *buf = data;
+
	UT_string *buf = data;

-
	sbuf_bcat(buf, str, len);
+
	utstring_bincpy(buf, str, len);

	return (0);
}

static int
-
ucl_sbuf_append_int(int64_t val, void *data)
+
ucl_buf_append_int(int64_t val, void *data)
{
-
	struct sbuf *buf = data;
+
	UT_string *buf = data;

-
	sbuf_printf(buf, "%"PRId64, val);
+
	utstring_printf(buf, "%"PRId64, val);

	return (0);
}

static int
-
ucl_sbuf_append_double(double val, void *data)
+
ucl_buf_append_double(double val, void *data)
{
-
	struct sbuf *buf = data;
+
	UT_string *buf = data;
	const double delta = 0.0000001;

	if (val == (double)(int)val) {
-
		sbuf_printf(buf, "%.1lf", val);
+
		utstring_printf(buf, "%.1lf", val);
	} else if (fabs(val - (double)(int)val) < delta) {
-
		sbuf_printf(buf, "%.*lg", DBL_DIG, val);
+
		utstring_printf(buf, "%.*lg", DBL_DIG, val);
	} else {
-
		sbuf_printf(buf, "%lf", val);
+
		utstring_printf(buf, "%lf", val);
	}

	return (0);
@@ -597,31 +554,28 @@ ucl_object_emit_file(const ucl_object_t *obj, enum ucl_emitter emit_type,
	func.ud = out;

	return (ucl_object_emit_full(obj, emit_type, &func, NULL));
-

-

}

bool
-
ucl_object_emit_sbuf(const ucl_object_t *obj, enum ucl_emitter emit_type,
-
                     struct sbuf **buf)
+
ucl_object_emit_buf(const ucl_object_t *obj, enum ucl_emitter emit_type,
+
                     UT_string **buf)
{
	bool ret = false;
	struct ucl_emitter_functions func = {
-
		.ucl_emitter_append_character = ucl_sbuf_append_character,
-
		.ucl_emitter_append_len = ucl_sbuf_append_len,
-
		.ucl_emitter_append_int = ucl_sbuf_append_int,
-
		.ucl_emitter_append_double = ucl_sbuf_append_double
+
		.ucl_emitter_append_character = ucl_buf_append_character,
+
		.ucl_emitter_append_len = ucl_buf_append_len,
+
		.ucl_emitter_append_int = ucl_buf_append_int,
+
		.ucl_emitter_append_double = ucl_buf_append_double
	};

	if (*buf == NULL)
-
		*buf = sbuf_new_auto();
+
		utstring_new(*buf);
	else
-
		sbuf_clear(*buf);
+
		utstring_clear(*buf);

	func.ud = *buf;

	ret = ucl_object_emit_full(obj, emit_type, &func, NULL);
-
	sbuf_finish(*buf);

	return (ret);
}
modified src/add.c
@@ -26,7 +26,6 @@
 */

#include <sys/param.h>
-
#include <sys/sbuf.h>

#include <err.h>
#include <errno.h>
@@ -37,6 +36,7 @@
#include <sysexits.h>
#include <unistd.h>
#include <getopt.h>
+
#include <utstring.h>

#include <pkg.h>

@@ -66,7 +66,7 @@ int
exec_add(int argc, char **argv)
{
	struct pkgdb *db = NULL;
-
	struct sbuf *failedpkgs = NULL;
+
	UT_string *failedpkgs = NULL;
	char path[MAXPATHLEN];
	char *file;
	int retcode;
@@ -141,7 +141,7 @@ exec_add(int argc, char **argv)
		return (EX_TEMPFAIL);
	}

-
	failedpkgs = sbuf_new_auto();
+
	utstring_new(failedpkgs);
	pkg_manifest_keys_new(&keys);
	for (i = 0; i < argc; i++) {
		if (is_url(argv[i]) == EPKG_OK) {
@@ -164,9 +164,9 @@ exec_add(int argc, char **argv)
				warn("%s", file);
				if (errno == ENOENT)
					warnx("Was 'pkg install %s' meant?", file);
-
				sbuf_cat(failedpkgs, argv[i]);
+
				utstring_printf(failedpkgs, argv[i]);
				if (i != argc - 1)
-
					sbuf_printf(failedpkgs, ", ");
+
					utstring_printf(failedpkgs, ", ");
				failedpkgcount++;
				continue;
			}
@@ -174,9 +174,9 @@ exec_add(int argc, char **argv)
		}

		if ((retcode = pkg_add(db, file, f, keys, location)) != EPKG_OK) {
-
			sbuf_cat(failedpkgs, argv[i]);
+
			utstring_printf(failedpkgs, argv[i]);
			if (i != argc - 1)
-
				sbuf_printf(failedpkgs, ", ");
+
				utstring_printf(failedpkgs, ", ");
			failedpkgcount++;
		}

@@ -189,15 +189,13 @@ exec_add(int argc, char **argv)
	pkgdb_close(db);
	
	if(failedpkgcount > 0) {
-
		sbuf_finish(failedpkgs);
-
		printf("\nFailed to install the following %d package(s): %s\n", failedpkgcount, sbuf_data(failedpkgs));
+
		printf("\nFailed to install the following %d package(s): %s\n", failedpkgcount, utstring_body(failedpkgs));
		retcode = EPKG_FATAL;
	}
-
	sbuf_delete(failedpkgs);
+
	utstring_free(failedpkgs);

	if (messages != NULL) {
-
		sbuf_finish(messages);
-
		printf("%s", sbuf_data(messages));
+
		printf("%s", utstring_body(messages));
	}

	return (retcode == EPKG_OK ? EX_OK : EX_SOFTWARE);
modified src/alias.c
@@ -25,7 +25,6 @@
 */

#include <sys/param.h>
-
#include <sys/sbuf.h>

#include <err.h>
#include <errno.h>
@@ -35,6 +34,7 @@
#include <sysexits.h>
#include <unistd.h>
#include <getopt.h>
+
#include <utstring.h>

#include <pkg.h>

modified src/annotate.c
@@ -29,7 +29,6 @@
#endif

#include <sys/types.h>
-
#include <sys/sbuf.h>

#include <err.h>
#include <getopt.h>
@@ -38,6 +37,7 @@
#include <string.h>
#include <sysexits.h>
#include <unistd.h>
+
#include <utstring.h>

#include <pkg.h>

@@ -163,13 +163,13 @@ do_show(struct pkg *pkg, const char *tag)
}


-
static struct sbuf *
+
static UT_string *
read_input(void)
{
-
	struct sbuf	*input;
+
	UT_string	*input;
	int		 ch;

-
	input = sbuf_new_auto();
+
	utstring_new(input);

	for (;;) {
		ch = getc(stdin);
@@ -179,14 +179,8 @@ read_input(void)
			if (ferror(stdin))
				err(EX_NOINPUT, "Failed to read stdin");
		}
-
		sbuf_putc(input, ch);
+
		utstring_printf(input, "%c", ch);
	}
-
#ifdef __DragonFly__
-
	sbuf_finish(input);
-
#else
-
	if (sbuf_finish(input) != 0)
-
		err(EX_DATAERR, "Could not read value data");
-
#endif

	return (input);
}
@@ -201,7 +195,7 @@ exec_annotate(int argc, char **argv)
	const char	*tag;
	const char	*value;
	const char	*pkgname;
-
	struct sbuf	*input    = NULL;
+
	UT_string	*input    = NULL;
	int		 ch;
	int		 match    = MATCH_EXACT;
	int		 retcode;
@@ -296,7 +290,7 @@ exec_annotate(int argc, char **argv)
	if ((action == ADD || action == MODIFY) && value == NULL) {
		/* try and read data for the value from stdin. */
		input = read_input();
-
		value = sbuf_data(input);
+
		value = utstring_body(input);
	}

	if (lock_type == PKGDB_LOCK_EXCLUSIVE)
@@ -324,7 +318,7 @@ exec_annotate(int argc, char **argv)
	retcode = pkgdb_open(&db, PKGDB_DEFAULT);
	if (retcode != EPKG_OK) {
		if (input != NULL)
-
			sbuf_delete(input);
+
			utstring_free(input);
		return (EX_IOERR);
	}

@@ -376,7 +370,7 @@ cleanup:
	pkgdb_release_lock(db, PKGDB_LOCK_EXCLUSIVE);
	pkgdb_close(db);
	if (input != NULL)
-
		sbuf_delete(input);
+
		utstring_free(input);

	return (exitcode);
}
modified src/audit.c
@@ -45,6 +45,7 @@
#include <unistd.h>
#include <sysexits.h>
#include <khash.h>
+
#include <utstring.h>

#ifdef HAVE_SYS_CAPSICUM_H
#include <sys/capsicum.h>
@@ -81,7 +82,7 @@ add_to_check(kh_pkgs_t *check, struct pkg *pkg)
}

static void
-
print_recursive_rdeps(kh_pkgs_t *head, struct pkg *p, struct sbuf *sb,
+
print_recursive_rdeps(kh_pkgs_t *head, struct pkg *p, UT_string *sb,
    kh_pkgs_t *seen, bool top)
{
	struct pkg_dep *dep = NULL;
@@ -97,9 +98,9 @@ print_recursive_rdeps(kh_pkgs_t *head, struct pkg *p, struct sbuf *sb,
			if (h != kh_end(head)) {
				kh_put_pkgs(seen, name, &ret);
				if (!top)
-
					sbuf_cat(sb, ", ");
+
					utstring_printf(sb, ", ");

-
				sbuf_cat(sb, name);
+
				utstring_printf(sb, name);

				print_recursive_rdeps(head, kh_val(head, h), sb, seen, false);

@@ -123,7 +124,7 @@ exec_audit(int argc, char **argv)
	bool			 fetch = false, recursive = false;
	int			 ch, i;
	int			 ret = EX_OK;
-
	struct sbuf		*sb;
+
	UT_string		*sb;
	kh_pkgs_t		*check = NULL;

	struct option longopts[] = {
@@ -276,22 +277,21 @@ exec_audit(int argc, char **argv)
		kh_foreach_value(check, pkg, {
			if (pkg_audit_is_vulnerable(audit, pkg, quiet, &sb)) {
				vuln ++;
-
				printf("%s", sbuf_data(sb));
+
				printf("%s", utstring_body(sb));

				if (recursive) {
					const char *name;
					kh_pkgs_t *seen = kh_init_pkgs();

					pkg_get(pkg, PKG_NAME, &name);
-
					sbuf_clear(sb);
-
					sbuf_printf(sb, "Packages that depend on %s: ", name);
+
					utstring_clear(sb);
+
					utstring_printf(sb, "Packages that depend on %s: ", name);
					print_recursive_rdeps(check, pkg , sb, seen, true);
-
					sbuf_finish(sb);
-
					printf("%s\n\n", sbuf_data(sb));
+
					printf("%s\n\n", utstring_body(sb));

					kh_destroy_pkgs(seen);
				}
-
				sbuf_delete(sb);
+
				utstring_free(sb);
			}
			pkg_free(pkg);
		});
modified src/check.c
@@ -29,7 +29,6 @@

#include <sys/param.h>
#include <sys/queue.h>
-
#include <sys/sbuf.h>

#include <err.h>
#include <assert.h>
@@ -53,14 +52,14 @@ struct deps_entry {
};

static int check_deps(struct pkgdb *db, struct pkg *pkg, struct deps_entry **dh,
-
    bool noinstall, struct sbuf *out);
+
    bool noinstall, UT_string *out);
static void add_missing_dep(struct pkg_dep *d, struct deps_entry **dh, int *nbpkgs);
static void deps_free(struct deps_entry *dh);
static int fix_deps(struct pkgdb *db, struct deps_entry *dh, int nbpkgs);
static void check_summary(struct pkgdb *db, struct deps_entry *dh);

static int
-
check_deps(struct pkgdb *db, struct pkg *p, struct deps_entry **dh, bool noinstall, struct sbuf *out)
+
check_deps(struct pkgdb *db, struct pkg *p, struct deps_entry **dh, bool noinstall, UT_string *out)
{
	struct pkg_dep *dep = NULL;
	struct pkgdb_it *it;
@@ -74,9 +73,9 @@ check_deps(struct pkgdb *db, struct pkg *p, struct deps_entry **dh, bool noinsta
		/* do we have a missing dependency? */
		if (pkg_is_installed(db, pkg_dep_name(dep)) != EPKG_OK) {
			if (quiet)
-
				pkg_sbuf_printf(out, "%n\t%sn\n", p, dep);
+
				pkg_utstring_printf(out, "%n\t%sn\n", p, dep);
			else
-
				pkg_sbuf_printf(out, "%n has a missing dependency: %dn\n",
+
				pkg_utstring_printf(out, "%n has a missing dependency: %dn\n",
				    p, dep);
			if (!noinstall)
				add_missing_dep(dep, dh, &nbpkgs);
@@ -93,9 +92,9 @@ check_deps(struct pkgdb *db, struct pkg *p, struct deps_entry **dh, bool noinsta
		}
		pkgdb_it_free(it);
		if (quiet)
-
			pkg_sbuf_printf(out, "%n\t%S\n", p, buf);
+
			pkg_utstring_printf(out, "%n\t%S\n", p, buf);
		else
-
			pkg_sbuf_printf(out, "%n is missing a required shared library: %S\n",
+
			pkg_utstring_printf(out, "%n is missing a required shared library: %S\n",
			    p, buf);
	}

@@ -109,9 +108,9 @@ check_deps(struct pkgdb *db, struct pkg *p, struct deps_entry **dh, bool noinsta
		}
		pkgdb_it_free(it);
		if (quiet)
-
			pkg_sbuf_printf(out, "%n\tS\n", p, buf);
+
			pkg_utstring_printf(out, "%n\tS\n", p, buf);
		else
-
			pkg_sbuf_printf(out, "%n has a missing requirement: %S\n",
+
			pkg_utstring_printf(out, "%n has a missing requirement: %S\n",
			    p, buf);
	}

@@ -274,7 +273,7 @@ exec_check(int argc, char **argv)
	struct pkg *pkg = NULL;
	struct pkgdb_it *it = NULL;
	struct pkgdb *db = NULL;
-
	struct sbuf *msg = NULL;
+
	UT_string *msg = NULL;
	match_t match = MATCH_EXACT;
	int flags = PKG_LOAD_BASIC;
	int ret, rc = EX_OK;
@@ -420,22 +419,22 @@ exec_check(int argc, char **argv)
		}

		if (msg == NULL)
-
			msg = sbuf_new_auto();
+
			utstring_new(msg);
		if (!verbose) {
			if (!quiet) {
				if (match == MATCH_ALL)
					progressbar_start("Checking all packages");
				else {
-
					sbuf_printf(msg, "Checking %s", argv[i]);
-
					sbuf_finish(msg);
-
					progressbar_start(sbuf_data(msg));
+
					utstring_printf(msg, "Checking %s", argv[i]);
+
					progressbar_start(utstring_body(msg));
				}
			}
			processed = 0;
			total = pkgdb_it_count(it);
		}

-
		struct sbuf *out = sbuf_new_auto();
+
		UT_string *out;
+
		utstring_new(out);
		while (pkgdb_it_next(it, &pkg, flags) == EPKG_OK) {
			if (!quiet) {
				if (!verbose)
@@ -443,9 +442,9 @@ exec_check(int argc, char **argv)
				else {
					++nbdone;
					job_status_begin(msg);
-
					pkg_sbuf_printf(msg, "Checking %n-%v:",
+
					pkg_utstring_printf(msg, "Checking %n-%v:",
					    pkg, pkg);
-
					sbuf_flush(msg);
+
					utstring_flush(msg);
				}
			}

@@ -510,13 +509,12 @@ exec_check(int argc, char **argv)
		}
		if (!quiet && !verbose)
			progressbar_tick(processed, total);
-
		if (sbuf_len(out) > 0) {
-
			sbuf_finish(out);
-
			printf("%s", sbuf_data(out));
+
		if (utstring_len(out) > 0) {
+
			printf("%s", utstring_body(out));
		}
-
		sbuf_delete(out);
+
		utstring_free(out);
		if (msg != NULL) {
-
			sbuf_delete(msg);
+
			utstring_free(msg);
			msg = NULL;
		}

@@ -550,7 +548,7 @@ cleanup:
	if (!verbose)
		progressbar_stop();
	if (msg != NULL)
-
		sbuf_delete(msg);
+
		utstring_free(msg);
	deps_free(dh);
	pkg_free(pkg);
	pkgdb_release_lock(db, PKGDB_LOCK_ADVISORY);
modified src/convert.c
@@ -28,7 +28,6 @@

#include <sys/param.h>
#include <sys/stat.h>
-
#include <sys/sbuf.h>

#include <err.h>
#include <errno.h>
modified src/delete.c
@@ -224,8 +224,7 @@ exec_delete(int argc, char **argv)
		goto cleanup;

	if (messages != NULL) {
-
		sbuf_finish(messages);
-
		printf("%s", sbuf_data(messages));
+
		printf("%s", utstring_body(messages));
	}
	pkgdb_compact(db);

modified src/event.c
@@ -54,14 +54,15 @@
#include <kvec.h>

#include <bsd_compat.h>
+
#include <utstring.h>

#include "pkg.h"
#include "pkgcli.h"

#define STALL_TIME 5

-
struct sbuf *messages = NULL;
-
struct sbuf *conflicts = NULL;
+
UT_string *messages = NULL;
+
UT_string *conflicts = NULL;

struct cleanup {
	void *data;
@@ -69,7 +70,7 @@ struct cleanup {
};

static char *progress_message = NULL;
-
static struct sbuf *msg_buf = NULL;
+
static UT_string *msg_buf = NULL;
static int last_progress_percent = -1;
static bool progress_started = false;
static bool progress_interrupted = false;
@@ -170,20 +171,19 @@ format_size_SI(char *buf, int size, off_t bytes)
}

void
-
job_status_end(struct sbuf *msg)
+
job_status_end(UT_string *msg)
{
-
	sbuf_finish(msg);
-
	printf("%s\n", sbuf_data(msg));
-
	/*printf("\033]0; %s\007", sbuf_data(msg));*/
-
	sbuf_clear(msg);
+
	printf("%s\n", utstring_body(msg));
+
	/*printf("\033]0; %s\007", utstring_body(msg));*/
+
	utstring_clear(msg);
}

void
-
job_status_begin(struct sbuf *msg)
+
job_status_begin(UT_string *msg)
{
	int n;

-
	sbuf_clear(msg);
+
	utstring_clear(msg);
#ifdef HAVE_LIBJAIL
	static char hostname[MAXHOSTNAMELEN] = "";
	static int jailed = -1;
@@ -200,7 +200,7 @@ job_status_begin(struct sbuf *msg)
		if (hostname[0] == '\0')
			gethostname(hostname, sizeof(hostname));

-
		sbuf_printf(msg, "[%s] ", hostname);
+
		utstring_printf(msg, "[%s] ", hostname);
	}
#endif

@@ -209,16 +209,16 @@ job_status_begin(struct sbuf *msg)
		if (add_deps_depth > 1) {
			for (n = 0; n < (2 * add_deps_depth); ++n) {
				if (n % 4 == 0 && n < (2 * add_deps_depth))
-
					sbuf_cat(msg, "|");
+
					utstring_printf(msg, "|");
				else
-
					sbuf_cat(msg, " ");
+
					utstring_printf(msg, " ");
			}
		}
-
		sbuf_cat(msg, "`-- ");
+
		utstring_printf(msg, "`-- ");
	}

	if (nbactions > 0 && nbdone > 0)
-
		sbuf_printf(msg, "[%d/%d] ", nbdone, nbactions);
+
		utstring_printf(msg, "[%d/%d] ", nbdone, nbactions);
}

static int
@@ -397,8 +397,7 @@ progressbar_start(const char *pmsg)
	if (pmsg != NULL)
		progress_message = strdup(pmsg);
	else {
-
		sbuf_finish(msg_buf);
-
		progress_message = strdup(sbuf_data(msg_buf));
+
		progress_message = strdup(utstring_body(msg_buf));
	}
	last_progress_percent = -1;
	last_tick = 0;
@@ -584,7 +583,7 @@ event_callback(void *data, struct pkg_event *ev)
	char trunc_filename[42] = { 0 };

	if (msg_buf == NULL) {
-
		msg_buf = sbuf_new_auto();
+
		utstring_new(msg_buf);
	}

	/*
@@ -644,7 +643,7 @@ event_callback(void *data, struct pkg_event *ev)
			trunc_filename[40] = '*';
		job_status_begin(msg_buf);
		progress_debit = true;
-
		sbuf_printf(msg_buf, "%-41s", trunc_filename);
+
		utstring_printf(msg_buf, "%-41s", trunc_filename);

		break;
	case PKG_EVENT_FETCH_FINISHED:
@@ -656,10 +655,9 @@ event_callback(void *data, struct pkg_event *ev)
		job_status_begin(msg_buf);

		pkg = ev->e_install_begin.pkg;
-
		pkg_sbuf_printf(msg_buf, "Installing %n-%v...\n", pkg,
+
		pkg_utstring_printf(msg_buf, "Installing %n-%v...\n", pkg,
		    pkg);
-
		sbuf_finish(msg_buf);
-
		printf("%s", sbuf_data(msg_buf));
+
		printf("%s", utstring_body(msg_buf));
		break;
	case PKG_EVENT_INSTALL_FINISHED:
		if (quiet)
@@ -672,7 +670,7 @@ event_callback(void *data, struct pkg_event *ev)
		else {
			job_status_begin(msg_buf);
			pkg = ev->e_install_begin.pkg;
-
			pkg_sbuf_printf(msg_buf, "Extracting %n-%v", pkg, pkg);
+
			pkg_utstring_printf(msg_buf, "Extracting %n-%v", pkg, pkg);
		}
		break;
	case PKG_EVENT_EXTRACT_FINISHED:
@@ -693,9 +691,7 @@ event_callback(void *data, struct pkg_event *ev)
			break;
		printf(" done (%d conflicting)\n", ev->e_integrity_finished.conflicting);
		if (conflicts != NULL) {
-
			sbuf_finish(conflicts);
-
			printf("%s", sbuf_data(conflicts));
-
			sbuf_delete(conflicts);
+
			printf("%s", utstring_body(conflicts));
			conflicts = NULL;
		}
		break;
@@ -723,9 +719,8 @@ event_callback(void *data, struct pkg_event *ev)
		job_status_begin(msg_buf);

		pkg = ev->e_install_begin.pkg;
-
		pkg_sbuf_printf(msg_buf, "Deinstalling %n-%v...\n", pkg, pkg);
-
		sbuf_finish(msg_buf);
-
		printf("%s", sbuf_data(msg_buf));
+
		pkg_utstring_printf(msg_buf, "Deinstalling %n-%v...\n", pkg, pkg);
+
		printf("%s", utstring_body(msg_buf));
		break;
	case PKG_EVENT_DEINSTALL_FINISHED:
		if (quiet)
@@ -737,7 +732,7 @@ event_callback(void *data, struct pkg_event *ev)
		else {
			job_status_begin(msg_buf);
			pkg = ev->e_install_begin.pkg;
-
			pkg_sbuf_printf(msg_buf, "Deleting files for %n-%v",
+
			pkg_utstring_printf(msg_buf, "Deleting files for %n-%v",
			    pkg, pkg);
		}
		break;
@@ -753,20 +748,19 @@ event_callback(void *data, struct pkg_event *ev)

		switch (pkg_version_change_between(pkg_new, pkg_old)) {
		case PKG_DOWNGRADE:
-
			pkg_sbuf_printf(msg_buf, "Downgrading %n from %v to %v...\n",
+
			pkg_utstring_printf(msg_buf, "Downgrading %n from %v to %v...\n",
			    pkg_new, pkg_old, pkg_new);
			break;
		case PKG_REINSTALL:
-
			pkg_sbuf_printf(msg_buf, "Reinstalling %n-%v...\n",
+
			pkg_utstring_printf(msg_buf, "Reinstalling %n-%v...\n",
		    pkg_old, pkg_old);
			break;
		case PKG_UPGRADE:
-
			pkg_sbuf_printf(msg_buf, "Upgrading %n from %v to %v...\n",
+
			pkg_utstring_printf(msg_buf, "Upgrading %n from %v to %v...\n",
			    pkg_new, pkg_old, pkg_new);
			break;
		}
-
		sbuf_finish(msg_buf);
-
		printf("%s", sbuf_data(msg_buf));
+
		printf("%s", utstring_body(msg_buf));
		break;
	case PKG_EVENT_UPGRADE_FINISHED:
		if (quiet)
@@ -879,20 +873,18 @@ event_callback(void *data, struct pkg_event *ev)
		    ev->e_progress_tick.total);
		break;
	case PKG_EVENT_BACKUP:
-
		sbuf_cat(msg_buf, "Backing up");
-
		sbuf_finish(msg_buf);
+
		utstring_printf(msg_buf, "Backing up");
		break;
	case PKG_EVENT_RESTORE:
-
		sbuf_cat(msg_buf, "Restoring");
-
		sbuf_finish(msg_buf);
+
		utstring_printf(msg_buf, "Restoring");
		break;
	case PKG_EVENT_NEW_ACTION:
		nbdone++;
		break;
	case PKG_EVENT_MESSAGE:
		if (messages == NULL)
-
			messages = sbuf_new_auto();
-
		sbuf_cat(messages, ev->e_pkg_message.msg);
+
			utstring_new(messages);
+
		utstring_printf(messages, ev->e_pkg_message.msg);
		break;
	case PKG_EVENT_CLEANUP_CALLBACK_REGISTER:
		if (!signal_handler_installed) {
@@ -919,23 +911,23 @@ event_callback(void *data, struct pkg_event *ev)
		break;
	case PKG_EVENT_CONFLICTS:
		if (conflicts == NULL) {
-
			conflicts = sbuf_new_auto();
+
			utstring_new(conflicts);
		}
-
		pkg_sbuf_printf(conflicts, "  - %n-%v",
+
		pkg_utstring_printf(conflicts, "  - %n-%v",
		    ev->e_conflicts.p1, ev->e_conflicts.p1);
		if (pkg_repos_total_count() > 1) {
			pkg_get(ev->e_conflicts.p1, PKG_REPONAME, &reponame);
-
			sbuf_printf(conflicts, " [%s]",
+
			utstring_printf(conflicts, " [%s]",
			    reponame == NULL ? "installed" : reponame);
		}
-
		pkg_sbuf_printf(conflicts, " conflicts with %n-%v",
+
		pkg_utstring_printf(conflicts, " conflicts with %n-%v",
		    ev->e_conflicts.p2, ev->e_conflicts.p2);
		if (pkg_repos_total_count() > 1) {
			pkg_get(ev->e_conflicts.p2, PKG_REPONAME, &reponame);
-
			sbuf_printf(conflicts, " [%s]",
+
			utstring_printf(conflicts, " [%s]",
			    reponame == NULL ? "installed" : reponame);
		}
-
		sbuf_printf(conflicts, " on %s\n",
+
		utstring_printf(conflicts, " on %s\n",
		    ev->e_conflicts.path);
		break;
	default:
modified src/install.c
@@ -253,8 +253,7 @@ exec_install(int argc, char **argv)
		}

		if (messages != NULL) {
-
			sbuf_finish(messages);
-
			printf("%s", sbuf_data(messages));
+
			printf("%s", utstring_body(messages));
		}
		break;
	}
modified src/main.c
@@ -37,7 +37,6 @@

#include <sys/stat.h>
#include <sys/queue.h>
-
#include <sys/sbuf.h>
#include <sys/types.h>
#include <sys/wait.h>
#ifdef __FreeBSD__
modified src/pkgcli.h
@@ -29,6 +29,7 @@
#define _PKGCLI_H

#include <stdint.h>
+
#include <utstring.h>
#include <bsd_compat.h>

#define pkg_warnx(fmt, ...) pkg_fprintf(stderr, "%S: " fmt, getprogname(), __VA_ARGS__, -1)
@@ -268,18 +269,18 @@ int info_flags(uint64_t opt, bool remote);
void print_info(struct pkg * const pkg, uint64_t opt);
int print_jobs_summary(struct pkg_jobs *j, const char *msg, ...);

-
void job_status_begin(struct sbuf *);
-
void job_status_end(struct sbuf *);
+
void job_status_begin(UT_string *);
+
void job_status_end(UT_string *);

int event_callback(void *data, struct pkg_event *ev);
void progressbar_start(const char *pmsg);
void progressbar_tick(int64_t current, int64_t total);
void progressbar_stop(void);

-
void sbuf_flush(struct sbuf *buf);
+
void utstring_flush(UT_string *buf);
void drop_privileges(void);

-
extern struct sbuf *messages;
+
extern UT_string *messages;


/* pkg-query / pkg-rquery */
@@ -291,7 +292,7 @@ struct query_flags {
};

void print_query(struct pkg *pkg, char *qstr, char multiline);
-
int format_sql_condition(const char *str, struct sbuf *sqlcond,
+
int format_sql_condition(const char *str, UT_string *sqlcond,
			 bool for_remote);
int analyse_query_string(char *qstr, struct query_flags *q_flags,
			 const unsigned int q_flags_len, int *flags,
modified src/query.c
@@ -28,19 +28,19 @@
 */

#include <sys/types.h>
-
#include <sys/sbuf.h>

#include <ctype.h>
#include <err.h>
#include <getopt.h>
#include <inttypes.h>
-
#include <pkg.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sysexits.h>
#include <unistd.h>

+
#include <utstring.h>
+
#include <pkg.h>
#include "pkgcli.h"

static struct query_flags accepted_query_flags[] = {
@@ -78,101 +78,101 @@ static struct query_flags accepted_query_flags[] = {
};

static void
-
format_str(struct pkg *pkg, struct sbuf *dest, const char *qstr, const void *data)
+
format_str(struct pkg *pkg, UT_string *dest, const char *qstr, const void *data)
{
	bool automatic;
	bool locked;
	bool vital;

-
	sbuf_clear(dest);
+
	utstring_clear(dest);

	while (qstr[0] != '\0') {
		if (qstr[0] == '%') {
			qstr++;
			switch (qstr[0]) {
			case 'n':
-
				pkg_sbuf_printf(dest, "%n", pkg);
+
				pkg_utstring_printf(dest, "%n", pkg);
				break;
			case 'v':
-
				pkg_sbuf_printf(dest, "%v", pkg);
+
				pkg_utstring_printf(dest, "%v", pkg);
				break;
			case 'o':
-
				pkg_sbuf_printf(dest, "%o", pkg);
+
				pkg_utstring_printf(dest, "%o", pkg);
				break;
			case 'R':
-
				pkg_sbuf_printf(dest, "%N", pkg);
+
				pkg_utstring_printf(dest, "%N", pkg);
				break;
			case 'p':
-
				pkg_sbuf_printf(dest, "%p", pkg);
+
				pkg_utstring_printf(dest, "%p", pkg);
				break;
			case 'm':
-
				pkg_sbuf_printf(dest, "%m", pkg);
+
				pkg_utstring_printf(dest, "%m", pkg);
				break;
			case 'c':
-
				pkg_sbuf_printf(dest, "%c", pkg);
+
				pkg_utstring_printf(dest, "%c", pkg);
				break;
			case 'w':
-
				pkg_sbuf_printf(dest, "%w", pkg);
+
				pkg_utstring_printf(dest, "%w", pkg);
				break;
			case 'a':
				pkg_get(pkg, PKG_AUTOMATIC, &automatic);
-
				sbuf_printf(dest, "%d", automatic);
+
				utstring_printf(dest, "%d", automatic);
				break;
			case 'k':
				pkg_get(pkg, PKG_LOCKED, &locked);
-
				sbuf_printf(dest, "%d", locked);
+
				utstring_printf(dest, "%d", locked);
				break;
			case 't':
-
				pkg_sbuf_printf(dest, "%t", pkg);
+
				pkg_utstring_printf(dest, "%t", pkg);
				break;
			case 's':
				qstr++;
				if (qstr[0] == 'h') 
-
					pkg_sbuf_printf(dest, "%#sB", pkg);
+
					pkg_utstring_printf(dest, "%#sB", pkg);
			        else if (qstr[0] == 'b')
-
					pkg_sbuf_printf(dest, "%s", pkg);
+
					pkg_utstring_printf(dest, "%s", pkg);
				break;
			case 'e':
-
				pkg_sbuf_printf(dest, "%e", pkg);
+
				pkg_utstring_printf(dest, "%e", pkg);
				break;
			case '?':
				qstr++;
				switch (qstr[0]) {
				case 'd':
-
					pkg_sbuf_printf(dest, "%?d", pkg);
+
					pkg_utstring_printf(dest, "%?d", pkg);
					break;
				case 'r':
-
					pkg_sbuf_printf(dest, "%?r", pkg);
+
					pkg_utstring_printf(dest, "%?r", pkg);
					break;
				case 'C':
-
					pkg_sbuf_printf(dest, "%?C", pkg);
+
					pkg_utstring_printf(dest, "%?C", pkg);
					break;
				case 'F':
-
					pkg_sbuf_printf(dest, "%?F", pkg);
+
					pkg_utstring_printf(dest, "%?F", pkg);
					break;
				case 'O':
-
					pkg_sbuf_printf(dest, "%?O", pkg);
+
					pkg_utstring_printf(dest, "%?O", pkg);
					break;
				case 'D':
-
					pkg_sbuf_printf(dest, "%?D", pkg);
+
					pkg_utstring_printf(dest, "%?D", pkg);
					break;
				case 'L':
-
					pkg_sbuf_printf(dest, "%?L", pkg);
+
					pkg_utstring_printf(dest, "%?L", pkg);
					break;
				case 'U':
-
					pkg_sbuf_printf(dest, "%?U", pkg);
+
					pkg_utstring_printf(dest, "%?U", pkg);
					break;
				case 'G':
-
					pkg_sbuf_printf(dest, "%?G", pkg);
+
					pkg_utstring_printf(dest, "%?G", pkg);
					break;
				case 'B':
-
					pkg_sbuf_printf(dest, "%?B", pkg);
+
					pkg_utstring_printf(dest, "%?B", pkg);
					break;
				case 'b':
-
					pkg_sbuf_printf(dest, "%?b", pkg);
+
					pkg_utstring_printf(dest, "%?b", pkg);
					break;
				case 'A':
-
					pkg_sbuf_printf(dest, "%?A", pkg);
+
					pkg_utstring_printf(dest, "%?A", pkg);
					break;
				}
				break;
@@ -180,162 +180,161 @@ format_str(struct pkg *pkg, struct sbuf *dest, const char *qstr, const void *dat
				qstr++;
				switch (qstr[0]) {
				case 'd':
-
					pkg_sbuf_printf(dest, "%#d", pkg);
+
					pkg_utstring_printf(dest, "%#d", pkg);
					break;
				case 'r':
-
					pkg_sbuf_printf(dest, "%#r", pkg);
+
					pkg_utstring_printf(dest, "%#r", pkg);
					break;
				case 'C':
-
					pkg_sbuf_printf(dest, "%#C", pkg);
+
					pkg_utstring_printf(dest, "%#C", pkg);
					break;
				case 'F':
-
					pkg_sbuf_printf(dest, "%#F", pkg);
+
					pkg_utstring_printf(dest, "%#F", pkg);
					break;
				case 'O':
-
					pkg_sbuf_printf(dest, "%#O", pkg);
+
					pkg_utstring_printf(dest, "%#O", pkg);
					break;
				case 'D':
-
					pkg_sbuf_printf(dest, "%#D", pkg);
+
					pkg_utstring_printf(dest, "%#D", pkg);
					break;
				case 'L':
-
					pkg_sbuf_printf(dest, "%#L", pkg);
+
					pkg_utstring_printf(dest, "%#L", pkg);
					break;
				case 'U':
-
					pkg_sbuf_printf(dest, "%#U", pkg);
+
					pkg_utstring_printf(dest, "%#U", pkg);
					break;
				case 'G':
-
					pkg_sbuf_printf(dest, "%#G", pkg);
+
					pkg_utstring_printf(dest, "%#G", pkg);
					break;
				case 'B':
-
					pkg_sbuf_printf(dest, "%#B", pkg);
+
					pkg_utstring_printf(dest, "%#B", pkg);
					break;
				case 'b':
-
					pkg_sbuf_printf(dest, "%#b", pkg);
+
					pkg_utstring_printf(dest, "%#b", pkg);
					break;
				case 'A':
-
					pkg_sbuf_printf(dest, "%#A", pkg);
+
					pkg_utstring_printf(dest, "%#A", pkg);
					break;
				}
				break;
			case 'q':
-
				pkg_sbuf_printf(dest, "%q", pkg);
+
				pkg_utstring_printf(dest, "%q", pkg);
				break;
			case 'l':
-
				pkg_sbuf_printf(dest, "%l", pkg);
+
				pkg_utstring_printf(dest, "%l", pkg);
				break;
			case 'd':
				qstr++;
				if (qstr[0] == 'n')
-
					pkg_sbuf_printf(dest, "%dn", data);
+
					pkg_utstring_printf(dest, "%dn", data);
				else if (qstr[0] == 'o')
-
					pkg_sbuf_printf(dest, "%do", data);
+
					pkg_utstring_printf(dest, "%do", data);
				else if (qstr[0] == 'v')
-
					pkg_sbuf_printf(dest, "%dv", data);
+
					pkg_utstring_printf(dest, "%dv", data);
				break;
			case 'r':
				qstr++;
				if (qstr[0] == 'n')
-
					pkg_sbuf_printf(dest, "%rn", data);
+
					pkg_utstring_printf(dest, "%rn", data);
				else if (qstr[0] == 'o')
-
					pkg_sbuf_printf(dest, "%ro", data);
+
					pkg_utstring_printf(dest, "%ro", data);
				else if (qstr[0] == 'v')
-
					pkg_sbuf_printf(dest, "%rv", data);
+
					pkg_utstring_printf(dest, "%rv", data);
				break;
			case 'C':
-
				pkg_sbuf_printf(dest, "%Cn", data);
+
				pkg_utstring_printf(dest, "%Cn", data);
				break;
			case 'F':
				qstr++;
				if (qstr[0] == 'p')
-
					pkg_sbuf_printf(dest, "%Fn", data);
+
					pkg_utstring_printf(dest, "%Fn", data);
				else if (qstr[0] == 's')
-
					pkg_sbuf_printf(dest, "%Fs", data);
+
					pkg_utstring_printf(dest, "%Fs", data);
				break;
			case 'O':
				qstr++;
				if (qstr[0] == 'k')
-
					pkg_sbuf_printf(dest, "%On", data);
+
					pkg_utstring_printf(dest, "%On", data);
				else if (qstr[0] == 'v')
-
					pkg_sbuf_printf(dest, "%Ov", data);
+
					pkg_utstring_printf(dest, "%Ov", data);
				else if (qstr[0] == 'd') /* default value */
-
					pkg_sbuf_printf(dest, "%Od", data);
+
					pkg_utstring_printf(dest, "%Od", data);
				else if (qstr[0] == 'D') /* description */
-
					pkg_sbuf_printf(dest, "%OD", data);
+
					pkg_utstring_printf(dest, "%OD", data);
				break;
			case 'D':
-
				pkg_sbuf_printf(dest, "%Dn", data);
+
				pkg_utstring_printf(dest, "%Dn", data);
				break;
			case 'L':
-
				pkg_sbuf_printf(dest, "%Ln", data);
+
				pkg_utstring_printf(dest, "%Ln", data);
				break;
			case 'U':
-
				pkg_sbuf_printf(dest, "%Un", data);
+
				pkg_utstring_printf(dest, "%Un", data);
				break;
			case 'G':
-
				pkg_sbuf_printf(dest, "%Gn", data);
+
				pkg_utstring_printf(dest, "%Gn", data);
				break;
			case 'B':
-
				pkg_sbuf_printf(dest, "%Bn", data);
+
				pkg_utstring_printf(dest, "%Bn", data);
				break;
			case 'b':
-
				pkg_sbuf_printf(dest, "%bn", data);
+
				pkg_utstring_printf(dest, "%bn", data);
				break;
			case 'A':
				qstr++;
				if (qstr[0] == 't')
-
					pkg_sbuf_printf(dest, "%An", data);
+
					pkg_utstring_printf(dest, "%An", data);
				else if (qstr[0] == 'v')
-
					pkg_sbuf_printf(dest, "%Av", data);
+
					pkg_utstring_printf(dest, "%Av", data);
				break;
			case 'M':
				if (pkg_has_message(pkg))
-
					pkg_sbuf_printf(dest, "%M", pkg);
+
					pkg_utstring_printf(dest, "%M", pkg);
				break;
			case 'V':
				pkg_get(pkg, PKG_VITAL, &vital);
-
				sbuf_printf(dest, "%d", vital);
+
				utstring_printf(dest, "%d", vital);
				break;
			case '%':
-
				sbuf_putc(dest, '%');
+
				utstring_printf(dest, "%c", '%');
				break;
			}
		} else  if (qstr[0] == '\\') {
			qstr++;
			switch (qstr[0]) {
			case 'n':
-
				sbuf_putc(dest, '\n');
+
				utstring_printf(dest, "%c", '\n');
				break;
			case 'a':
-
				sbuf_putc(dest, '\a');
+
				utstring_printf(dest, "%c", '\a');
				break;
			case 'b':
-
				sbuf_putc(dest, '\b');
+
				utstring_printf(dest, "%c", '\b');
				break;
			case 'f':
-
				sbuf_putc(dest, '\f');
+
				utstring_printf(dest, "%c", '\f');
				break;
			case 'r':
-
				sbuf_putc(dest, '\r');
+
				utstring_printf(dest, "%c", '\r');
				break;
			case '\\':
-
				sbuf_putc(dest, '\\');
+
				utstring_printf(dest, "%c", '\\');
				break;
			case 't':
-
				sbuf_putc(dest, '\t');
+
				utstring_printf(dest, "%c", '\t');
				break;
			}
		} else {
-
			sbuf_putc(dest, qstr[0]);
+
			utstring_printf(dest, "%c", qstr[0]);
		}
		qstr++;
	}
-
	sbuf_finish(dest);
}

void
print_query(struct pkg *pkg, char *qstr, char multiline)
{
-
	struct sbuf		*output = sbuf_new_auto();
+
	UT_string		*output;
	struct pkg_dep		*dep    = NULL;
	struct pkg_option	*option = NULL;
	struct pkg_file		*file   = NULL;
@@ -343,93 +342,95 @@ print_query(struct pkg *pkg, char *qstr, char multiline)
	char			*buf;
	struct pkg_kv		*kv;

+
	utstring_new(output);
+

	switch (multiline) {
	case 'd':
		while (pkg_deps(pkg, &dep) == EPKG_OK) {
			format_str(pkg, output, qstr, dep);
-
			printf("%s\n", sbuf_data(output));
+
			printf("%s\n", utstring_body(output));
		}
		break;
	case 'r':
		while (pkg_rdeps(pkg, &dep) == EPKG_OK) {
			format_str(pkg, output, qstr, dep);
-
			printf("%s\n", sbuf_data(output));
+
			printf("%s\n", utstring_body(output));
		}
		break;
	case 'C':
		buf = NULL;
		while (pkg_categories(pkg, &buf) == EPKG_OK) {
			format_str(pkg, output, qstr, buf);
-
			printf("%s\n", sbuf_data(output));
+
			printf("%s\n", utstring_body(output));
		}
		break;
	case 'O':
		while (pkg_options(pkg, &option) == EPKG_OK) {
			format_str(pkg, output, qstr, option);
-
			printf("%s\n", sbuf_data(output));
+
			printf("%s\n", utstring_body(output));
		}
		break;
	case 'F':
		while (pkg_files(pkg, &file) == EPKG_OK) {
			format_str(pkg, output, qstr, file);
-
			printf("%s\n", sbuf_data(output));
+
			printf("%s\n", utstring_body(output));
		}
		break;
	case 'D':
		while (pkg_dirs(pkg, &dir) == EPKG_OK) {
			format_str(pkg, output, qstr, dir);
-
			printf("%s\n", sbuf_data(output));
+
			printf("%s\n", utstring_body(output));
		}
		break;
	case 'L':
		buf = NULL;
		while (pkg_licenses(pkg, &buf) == EPKG_OK) {
			format_str(pkg, output, qstr, buf);
-
			printf("%s\n", sbuf_data(output));
+
			printf("%s\n", utstring_body(output));
		}
		break;
	case 'U':
		buf = NULL;
		while (pkg_users(pkg, &buf) == EPKG_OK) {
			format_str(pkg, output, qstr, buf);
-
			printf("%s\n", sbuf_data(output));
+
			printf("%s\n", utstring_body(output));
		}
		break;
	case 'G':
		buf = NULL;
		while (pkg_groups(pkg, &buf) == EPKG_OK) {
			format_str(pkg, output, qstr, buf);
-
			printf("%s\n", sbuf_data(output));
+
			printf("%s\n", utstring_body(output));
		}
		break;
	case 'B':
		buf = NULL;
		while (pkg_shlibs_required(pkg, &buf) == EPKG_OK) {
			format_str(pkg, output, qstr, buf);
-
			printf("%s\n", sbuf_data(output));
+
			printf("%s\n", utstring_body(output));
		}
		break;
	case 'b':
		buf = NULL;
		while (pkg_shlibs_provided(pkg, &buf) == EPKG_OK) {
			format_str(pkg, output, qstr, buf);
-
			printf("%s\n", sbuf_data(output));
+
			printf("%s\n", utstring_body(output));
		}
		break;
	case 'A':
		pkg_get(pkg, PKG_ANNOTATIONS, &kv);
		while (kv != NULL) {
			format_str(pkg, output, qstr, kv);
-
			printf("%s\n", sbuf_data(output));
+
			printf("%s\n", utstring_body(output));
			kv = kv->next;
		}
		break;
	default:
		format_str(pkg, output, qstr, dep);
-
		printf("%s\n", sbuf_data(output));
+
		printf("%s\n", utstring_body(output));
		break;
	}
-
	sbuf_delete(output);
+
	utstring_free(output);
}

typedef enum {
@@ -446,82 +447,82 @@ typedef enum {
} state_t;

int
-
format_sql_condition(const char *str, struct sbuf *sqlcond, bool for_remote)
+
format_sql_condition(const char *str, UT_string *sqlcond, bool for_remote)
{
	state_t state = NONE;
	unsigned int bracket_level = 0;
	const char *sqlop;

-
	sbuf_cat(sqlcond, " WHERE ");
+
	utstring_printf(sqlcond, " WHERE ");
	while (str[0] != '\0') {
		if (state == NONE) {
			if (str[0] == '%') {
				str++;
				switch (str[0]) {
				case 'n':
-
					sbuf_cat(sqlcond, "name");
+
					utstring_printf(sqlcond, "name");
					state = OPERATOR_STRING;
					break;
				case 'o':
-
					sbuf_cat(sqlcond, "origin");
+
					utstring_printf(sqlcond, "origin");
					state = OPERATOR_STRING;
					break;
				case 'p':
-
					sbuf_cat(sqlcond, "prefix");
+
					utstring_printf(sqlcond, "prefix");
					state = OPERATOR_STRING;
					break;
				case 'm':
-
					sbuf_cat(sqlcond, "maintainer");
+
					utstring_printf(sqlcond, "maintainer");
					state = OPERATOR_STRING;
					break;
				case 'c':
-
					sbuf_cat(sqlcond, "comment");
+
					utstring_printf(sqlcond, "comment");
					state = OPERATOR_STRING;
					break;
				case 'w':
-
					sbuf_cat(sqlcond, "www");
+
					utstring_printf(sqlcond, "www");
					state = OPERATOR_STRING;
					break;
				case 's':
-
					sbuf_cat(sqlcond, "flatsize");
+
					utstring_printf(sqlcond, "flatsize");
					state = OPERATOR_INT;
					break;
				case 'a':
					if (for_remote)
						goto bad_option;
-
					sbuf_cat(sqlcond, "automatic");
+
					utstring_printf(sqlcond, "automatic");
					state = OPERATOR_INT;
					break;
				case 'q':
-
					sbuf_cat(sqlcond, "arch");
+
					utstring_printf(sqlcond, "arch");
					state = OPERATOR_STRING;
					break;
				case 'k':
					if (for_remote)
						goto bad_option;
-
					sbuf_cat(sqlcond, "locked");
+
					utstring_printf(sqlcond, "locked");
					state = OPERATOR_INT;
					break;
				case 'M':
					if (for_remote)
						goto bad_option;
-
					sbuf_cat(sqlcond, "message");
+
					utstring_printf(sqlcond, "message");
					state = OPERATOR_STRING;
					break;
				case 't':
					if (for_remote)
						goto bad_option;
-
					sbuf_cat(sqlcond, "time");
+
					utstring_printf(sqlcond, "time");
					state = OPERATOR_INT;
					break;
				case 'e':
-
					sbuf_cat(sqlcond, "desc");
+
					utstring_printf(sqlcond, "desc");
					state = OPERATOR_STRING;
					break;
				case 'V':
					if (for_remote)
						goto bad_option;
-
					sbuf_cat(sqlcond, "vital");
+
					utstring_printf(sqlcond, "vital");
					state = OPERATOR_INT;
					break;
				case '#': /* FALLTHROUGH */
@@ -530,48 +531,48 @@ format_sql_condition(const char *str, struct sbuf *sqlcond, bool for_remote)
					str++;
					switch (str[0]) {
						case 'd':
-
							sbuf_printf(sqlcond, "(SELECT %s FROM deps AS d WHERE d.package_id=p.id)", sqlop);
+
							utstring_printf(sqlcond, "(SELECT %s FROM deps AS d WHERE d.package_id=p.id)", sqlop);
							break;
						case 'r':
-
							sbuf_printf(sqlcond, "(SELECT %s FROM deps AS d WHERE d.origin=p.origin)", sqlop);
+
							utstring_printf(sqlcond, "(SELECT %s FROM deps AS d WHERE d.origin=p.origin)", sqlop);
							break;
						case 'C':
-
							sbuf_printf(sqlcond, "(SELECT %s FROM pkg_categories AS d WHERE d.package_id=p.id)", sqlop);
+
							utstring_printf(sqlcond, "(SELECT %s FROM pkg_categories AS d WHERE d.package_id=p.id)", sqlop);
							break;
						case 'F':
							if (for_remote)
								goto bad_option;
-
							sbuf_printf(sqlcond, "(SELECT %s FROM files AS d WHERE d.package_id=p.id)", sqlop);
+
							utstring_printf(sqlcond, "(SELECT %s FROM files AS d WHERE d.package_id=p.id)", sqlop);
							break;
						case 'O':
-
							sbuf_printf(sqlcond, "(SELECT %s FROM pkg_option AS d WHERE d.package_id=p.id)", sqlop);
+
							utstring_printf(sqlcond, "(SELECT %s FROM pkg_option AS d WHERE d.package_id=p.id)", sqlop);
							break;
						case 'D':
							if (for_remote)
								goto bad_option;
-
							sbuf_printf(sqlcond, "(SELECT %s FROM pkg_directories AS d WHERE d.package_id=p.id)", sqlop);
+
							utstring_printf(sqlcond, "(SELECT %s FROM pkg_directories AS d WHERE d.package_id=p.id)", sqlop);
							break;
						case 'L':
-
							sbuf_printf(sqlcond, "(SELECT %s FROM pkg_licenses AS d WHERE d.package_id=p.id)", sqlop);
+
							utstring_printf(sqlcond, "(SELECT %s FROM pkg_licenses AS d WHERE d.package_id=p.id)", sqlop);
							break;
						case 'U':
							if (for_remote)
								goto bad_option;
-
							sbuf_printf(sqlcond, "(SELECT %s FROM pkg_users AS d WHERE d.package_id=p.id)", sqlop);
+
							utstring_printf(sqlcond, "(SELECT %s FROM pkg_users AS d WHERE d.package_id=p.id)", sqlop);
							break;
						case 'G':
							if (for_remote)
								goto bad_option;
-
							sbuf_printf(sqlcond, "(SELECT %s FROM pkg_groups AS d WHERE d.package_id=p.id)", sqlop);
+
							utstring_printf(sqlcond, "(SELECT %s FROM pkg_groups AS d WHERE d.package_id=p.id)", sqlop);
							break;
						case 'B':
-
							sbuf_printf(sqlcond, "(SELECT %s FROM pkg_shlibs_required AS d WHERE d.package_id=p.id)", sqlop);
+
							utstring_printf(sqlcond, "(SELECT %s FROM pkg_shlibs_required AS d WHERE d.package_id=p.id)", sqlop);
							break;
						case 'b':
-
							sbuf_printf(sqlcond, "(SELECT %s FROM pkg_shlibs_provided AS d WHERE d.package_id=p.id)", sqlop);
+
							utstring_printf(sqlcond, "(SELECT %s FROM pkg_shlibs_provided AS d WHERE d.package_id=p.id)", sqlop);
							break;
						case 'A':
-
							sbuf_printf(sqlcond, "(SELECT %s FROM pkg_annotation AS d WHERE d.package_id=p.id)", sqlop);
+
							utstring_printf(sqlcond, "(SELECT %s FROM pkg_annotation AS d WHERE d.package_id=p.id)", sqlop);
							break;
						default:
							goto bad_option;
@@ -587,7 +588,7 @@ bad_option:
				switch (str[0]) {
				case '(':
					bracket_level++;
-
					sbuf_putc(sqlcond, str[0]);
+
					utstring_printf(sqlcond, "%c", str[0]);
					break;
				case ' ':
				case '\t':
@@ -605,7 +606,7 @@ bad_option:
					return (EPKG_FATAL);
				}
				bracket_level--;
-
				sbuf_putc(sqlcond, str[0]);
+
				utstring_printf(sqlcond, "%c", str[0]);
				break;
			case ' ':
			case '\t':
@@ -614,7 +615,7 @@ bad_option:
				if (str[1] == '|') {
					str++;
					state = NONE;
-
					sbuf_cat(sqlcond, " OR ");
+
					utstring_printf(sqlcond, " OR ");
					break;
				} else {
					fprintf(stderr, "unexpected character %c\n", str[1]);
@@ -624,7 +625,7 @@ bad_option:
				if (str[1] == '&') {
					str++;
					state = NONE;
-
					sbuf_cat(sqlcond, " AND ");
+
					utstring_printf(sqlcond, " AND ");
					break;
				} else {
					fprintf(stderr, "unexpected character %c\n", str[1]);
@@ -644,17 +645,17 @@ bad_option:
					return (EPKG_FATAL);
				}
				state = NEXT_IS_STRING;
-
				sbuf_cat(sqlcond, " GLOB ");
+
				utstring_printf(sqlcond, " GLOB ");
			} else if (str[0] == '>' || str[0] == '<') {
				if (state != OPERATOR_INT) {
					fprintf(stderr, "> expected only for integers\n");
					return (EPKG_FATAL);
				}
				state = NEXT_IS_INT;
-
				sbuf_putc(sqlcond, str[0]);
+
				utstring_printf(sqlcond, "%c", str[0]);
				if (str[1] == '=') {
					str++;
-
					sbuf_putc(sqlcond, str[0]);
+
					utstring_printf(sqlcond, "%c", str[0]);
				}
			} else if (str[0] == '=') {
				if (state == OPERATOR_STRING) {
@@ -662,17 +663,17 @@ bad_option:
				} else {
					state = NEXT_IS_INT;
				}
-
				sbuf_putc(sqlcond, str[0]);
+
				utstring_printf(sqlcond, "%c", str[0]);
				if (str[1] == '=') {
					str++;
-
					sbuf_putc(sqlcond, str[0]);
+
					utstring_printf(sqlcond, "%c", str[0]);
				}
			} else if (str[0] == '!') {
				if (str[1] == '=') {
-
					sbuf_putc(sqlcond, str[0]);
-
					sbuf_putc(sqlcond, str[1]);
+
					utstring_printf(sqlcond, "%c", str[0]);
+
					utstring_printf(sqlcond, "%c", str[1]);
				} else if (str[1] == '~') {
-
					sbuf_cat(sqlcond, " NOT GLOB ");
+
					utstring_printf(sqlcond, " NOT GLOB ");
				} else {
					fprintf(stderr, "expecting = or ~ after !\n");
					return (EPKG_FATAL);
@@ -700,14 +701,14 @@ bad_option:
						state = STRING;
						str--;
					}
-
					sbuf_putc(sqlcond, '\'');
+
					utstring_printf(sqlcond, "%c", '\'');
				} else {
					if (!isdigit(str[0])) {
						fprintf(stderr, "a number is expected, got: %c\n", str[0]);
						return (EPKG_FATAL);
					}
					state = INT;
-
					sbuf_putc(sqlcond, str[0]);
+
					utstring_printf(sqlcond, "%c", str[0]);
				}
			}
		} else if (state == INT) {
@@ -715,26 +716,26 @@ bad_option:
				state = POST_EXPR;
				str--;
			} else {
-
				sbuf_putc(sqlcond, str[0]);
+
				utstring_printf(sqlcond, "%c", str[0]);
			}
		} else if (state == STRING || state == QUOTEDSTRING || state == SQUOTEDSTRING) {
			if ((state == STRING && isspace(str[0])) ||
			    (state == QUOTEDSTRING && str[0] == '"') ||
			    (state == SQUOTEDSTRING && str[0] == '\'')) {
-
				sbuf_putc(sqlcond, '\'');
+
				utstring_printf(sqlcond, "%c", '\'');
				state = POST_EXPR;
			} else {
-
				sbuf_putc(sqlcond, str[0]);
+
				utstring_printf(sqlcond, "%c", str[0]);
				if (str[0] == '\'')
-
					sbuf_putc(sqlcond, str[0]);
+
					utstring_printf(sqlcond, "%c", str[0]);
				else if (str[0] == '%' && for_remote)
-
					sbuf_putc(sqlcond, str[0]);
+
					utstring_printf(sqlcond, "%c", str[0]);
			}
		}
		str++;
	}
	if (state == STRING) {
-
		sbuf_putc(sqlcond, '\'');
+
		utstring_printf(sqlcond, "%c", '\'');
		state = POST_EXPR;
	}

@@ -862,7 +863,7 @@ exec_query(int argc, char **argv)
	int			 i;
	char			 multiline = 0;
	char			*condition = NULL;
-
	struct sbuf		*sqlcond = NULL;
+
	UT_string		*sqlcond = NULL;
	const unsigned int	 q_flags_len = NELEM(accepted_query_flags);

	struct option longopts[] = {
@@ -940,12 +941,11 @@ exec_query(int argc, char **argv)
	}

	if (condition != NULL) {
-
		sqlcond = sbuf_new_auto();
+
		utstring_new(sqlcond);
		if (format_sql_condition(condition, sqlcond, false) != EPKG_OK) {
-
			sbuf_delete(sqlcond);
+
			utstring_free(sqlcond);
			return (EX_USAGE);
		}
-
		sbuf_finish(sqlcond);
	}

	ret = pkgdb_access(PKGDB_MODE_READ, PKGDB_DB_LOCAL);
@@ -973,7 +973,7 @@ exec_query(int argc, char **argv)
	if (match == MATCH_ALL || match == MATCH_CONDITION) {
		const char *condition_sql = NULL;
		if (match == MATCH_CONDITION && sqlcond)
-
			condition_sql = sbuf_data(sqlcond);
+
			condition_sql = utstring_body(sqlcond);
		if ((it = pkgdb_query(db, condition_sql, match)) == NULL)
			return (EX_IOERR);

modified src/register.c
@@ -344,8 +344,7 @@ exec_register(int argc, char **argv)
	retcode = pkg_add_port(db, pkg, input_path, location, testing_mode);

	if (!legacy && retcode == EPKG_OK && messages != NULL) {
-
		sbuf_finish(messages);
-
		printf("%s\n", sbuf_data(messages));
+
		printf("%s\n", utstring_body(messages));
	}

	pkg_free(pkg);
modified src/rquery.c
@@ -28,12 +28,12 @@
 */

#include <sys/types.h>
-
#include <sys/sbuf.h>

#include <ctype.h>
#include <err.h>
#include <getopt.h>
#include <inttypes.h>
+
#include <utstring.h>
#include <pkg.h>
#include <stdio.h>
#include <stdlib.h>
@@ -117,7 +117,7 @@ exec_rquery(int argc, char **argv)
	char			 multiline = 0;
	char			*condition = NULL;
	const char		*portsdir;
-
	struct sbuf		*sqlcond = NULL;
+
	UT_string		*sqlcond = NULL;
	const unsigned int	 q_flags_len = NELEM(accepted_rquery_flags);
	const char		*reponame = NULL;
	bool			 onematched = false;
@@ -200,23 +200,22 @@ exec_rquery(int argc, char **argv)
		return (EX_USAGE);

	if (condition != NULL) {
-
		sqlcond = sbuf_new_auto();
+
		utstring_new(sqlcond);
		if (format_sql_condition(condition, sqlcond, true) != EPKG_OK) {
-
			sbuf_delete(sqlcond);
+
			utstring_free(sqlcond);
			return (EX_USAGE);
		}
-
		sbuf_finish(sqlcond);
	}

	ret = pkgdb_access(PKGDB_MODE_READ, PKGDB_DB_REPO);
	if (ret == EPKG_ENOACCESS) {
		warnx("Insufficient privileges to query the package database");
		if (sqlcond != NULL)
-
			sbuf_delete(sqlcond);
+
			utstring_free(sqlcond);
		return (EX_NOPERM);
	} else if (ret != EPKG_OK) {
		if (sqlcond != NULL)
-
			sbuf_delete(sqlcond);
+
			utstring_free(sqlcond);
		return (EX_IOERR);
	}

@@ -225,7 +224,7 @@ exec_rquery(int argc, char **argv)
	quiet = true;
	if (auto_update && (ret = pkgcli_update(false, false, reponame)) != EPKG_OK) {
		if (sqlcond != NULL)
-
			sbuf_delete(sqlcond);
+
			utstring_free(sqlcond);
		return (ret);
	}
	quiet = old_quiet;
@@ -233,7 +232,7 @@ exec_rquery(int argc, char **argv)
	ret = pkgdb_open_all(&db, PKGDB_REMOTE, reponame);
	if (ret != EPKG_OK) {
		if (sqlcond != NULL)
-
			sbuf_delete(sqlcond);
+
			utstring_free(sqlcond);
		return (EX_IOERR);
	}
	drop_privileges();
@@ -244,10 +243,10 @@ exec_rquery(int argc, char **argv)
	if (match == MATCH_ALL || match == MATCH_CONDITION) {
		const char *condition_sql = NULL;
		if (match == MATCH_CONDITION && sqlcond)
-
			condition_sql = sbuf_data(sqlcond);
+
			condition_sql = utstring_body(sqlcond);
		if ((it = pkgdb_repo_query(db, condition_sql, match, reponame)) == NULL) {
			if (sqlcond != NULL)
-
				sbuf_delete(sqlcond);
+
				utstring_free(sqlcond);
			return (EX_IOERR);
		}

@@ -268,7 +267,7 @@ exec_rquery(int argc, char **argv)

			if ((it = pkgdb_repo_query(db, pkgname, match, reponame)) == NULL) {
				if (sqlcond != NULL)
-
					sbuf_delete(sqlcond);
+
					utstring_free(sqlcond);
				return (EX_IOERR);
			}

@@ -292,7 +291,7 @@ exec_rquery(int argc, char **argv)
	}

	if (sqlcond != NULL)
-
		sbuf_delete(sqlcond);
+
		utstring_free(sqlcond);
	pkg_free(pkg);
	pkgdb_close(db);

modified src/upgrade.c
@@ -208,8 +208,7 @@ exec_upgrade(int argc, char **argv)
		}

		if (messages != NULL) {
-
			sbuf_finish(messages);
-
			printf("%s", sbuf_data(messages));
+
			printf("%s", utstring_body(messages));
		}
		break;
	}
modified src/utils.c
@@ -996,11 +996,10 @@ print_jobs_summary(struct pkg_jobs *jobs, const char *msg, ...)
}

void
-
sbuf_flush(struct sbuf *buf)
+
utstring_flush(UT_string *buf)
{
-
	sbuf_finish(buf);
-
	printf("%s", sbuf_data(buf));
-
	sbuf_clear(buf);
+
	printf("%s", utstring_body(buf));
+
	utstring_clear(buf);
}

void
modified src/version.c
@@ -30,7 +30,6 @@
 */

#include <sys/param.h>
-
#include <sys/sbuf.h>
#include <sys/utsname.h>
#include <sys/wait.h>

@@ -50,6 +49,7 @@
#include <sys/types.h>
#include <sys/stat.h>
#include <khash.h>
+
#include <utstring.h>

#include "pkgcli.h"

@@ -563,7 +563,7 @@ cleanup:
}

static int
-
exec_buf(struct sbuf *res, char **argv) {
+
exec_buf(UT_string *res, char **argv) {
	char buf[BUFSIZ];
	int spawn_err;
	pid_t pid;
@@ -597,9 +597,9 @@ exec_buf(struct sbuf *res, char **argv) {

	close(pfd[1]);

-
	sbuf_clear(res);
+
	utstring_clear(res);
	while ((r = read(pfd[0], buf, BUFSIZ)) > 0)
-
		sbuf_bcat(res, buf, r);
+
		utstring_bincpy(res, buf, r);

	close(pfd[0]);
	while (waitpid(pid, &pstat, 0) == -1) {
@@ -607,22 +607,20 @@ exec_buf(struct sbuf *res, char **argv) {
			return (-1);
	}

-
	sbuf_finish(res);
-

-
	return (sbuf_len(res));
+
	return (utstring_len(res));
}

static struct category *
category_new(char *categorypath, const char *category)
{
	struct category	*cat = NULL;
-
	struct sbuf	*makecmd;
+
	UT_string	*makecmd;
	char		*results, *d, *key;
	char		*argv[5];
	int		 ret;
	khint_t		 k;

-
	makecmd = sbuf_new_auto();
+
	utstring_new(makecmd);

	argv[0] = "make";
	argv[1] = "-C";
@@ -633,7 +631,7 @@ category_new(char *categorypath, const char *category)
	if (exec_buf(makecmd, argv) <= 0)
		goto cleanup;

-
	results = sbuf_data(makecmd);
+
	results = utstring_body(makecmd);

	if (categories == NULL)
		categories = kh_init_categories();
@@ -657,7 +655,7 @@ category_new(char *categorypath, const char *category)
	}

cleanup:
-
	sbuf_delete(makecmd);
+
	utstring_free(makecmd);

	return (cat);
}
@@ -697,7 +695,7 @@ validate_origin(const char *portsdir, const char *origin)
}

static const char *
-
port_version(struct sbuf *cmd, const char *portsdir, const char *origin)
+
port_version(UT_string *cmd, const char *portsdir, const char *origin)
{
	char	*output;
	char	*version = NULL;
@@ -708,17 +706,16 @@ port_version(struct sbuf *cmd, const char *portsdir, const char *origin)
	   version from the port itself. */

	if (validate_origin(portsdir, origin)) {
-
		sbuf_printf(cmd, "%s/%s", portsdir, origin);
-
		sbuf_finish(cmd);
+
		utstring_printf(cmd, "%s/%s", portsdir, origin);

		argv[0] = "make";
		argv[1] = "-C";
-
		argv[2] = sbuf_data(cmd);
+
		argv[2] = utstring_body(cmd);
		argv[3] = "-VPKGVERSION";
		argv[4] = NULL;

		if (exec_buf(cmd, argv) != 0) {
-
			output = sbuf_data(cmd);
+
			output = utstring_body(cmd);
			version = strsep(&output, "\n");
		}
	}
@@ -733,7 +730,7 @@ do_source_ports(unsigned int opt, char limchar, char *pattern, match_t match,
	struct pkgdb	*db = NULL;
	struct pkgdb_it	*it = NULL;
	struct pkg	*pkg = NULL;
-
	struct sbuf	*cmd;
+
	UT_string	*cmd;
	const char	*name;
	const char	*origin;
	const char	*version;
@@ -760,7 +757,7 @@ do_source_ports(unsigned int opt, char limchar, char *pattern, match_t match,
	if ((it = pkgdb_query(db, pattern, match)) == NULL)
			goto cleanup;

-
	cmd = sbuf_new_auto();
+
	utstring_new(cmd);

	while (pkgdb_it_next(it, &pkg, PKG_LOAD_BASIC) == EPKG_OK) {
		pkg_get(pkg, PKG_NAME, &name, PKG_ORIGIN, &origin);
@@ -777,10 +774,10 @@ do_source_ports(unsigned int opt, char limchar, char *pattern, match_t match,

		version = port_version(cmd, portsdir, origin);
		print_version(pkg, "port", version, limchar, opt);
-
		sbuf_clear(cmd);
+
		utstring_clear(cmd);
	}

-
	sbuf_delete(cmd);
+
	utstring_free(cmd);

cleanup:
	pkgdb_release_lock(db, PKGDB_LOCK_READONLY);
modified tests/Makefile.am
@@ -1,7 +1,6 @@
AUTOMAKE_OPTIONS=	subdir-objects

GENERIC_LDADD=	$(top_builddir)/libpkg/libpkg_static.la \
-
		$(top_builddir)/external/libsbuf_static.la \
		$(top_builddir)/compat/libbsd_compat.la \
		$(top_builddir)/external/libfetch_static.la \
		@LDNS_LIBS@ \
@@ -32,8 +31,7 @@ PUBLIC_INCS= -DTESTING \
		-I$(top_srcdir)/compat \
		-I$(top_srcdir)/libpkg \
		-I/usr/local/include
-
PRIVATE_INCS=	-I$(top_srcdir)/external/libsbuf \
-
		-I$(top_srcdir)/external/sqlite \
+
PRIVATE_INCS=	-I$(top_srcdir)/external/sqlite \
		-I$(top_srcdir)/external/uthash \
		-I$(top_srcdir)/external/libucl/include \
		-I$(top_srcdir)/external/libucl/klib \
@@ -47,8 +45,7 @@ pkg_printf_CFLAGS= $(PRIVATE_INCS)
pkg_printf_LDADD=	$(GENERIC_LDADD)

pkg_validation_SOURCES=	lib/pkg_validation.c
-
pkg_validation_CFLAGS=	$(PUBLIC_INCS) \
-
			-I$(top_srcdir)/external/libsbuf
+
pkg_validation_CFLAGS=	$(PRIVATE_INCS)
pkg_validation_LDADD=	$(GENERIC_LDADD)

plist_SOURCES=		lib/plist.c
modified tests/lib/merge.c
@@ -27,7 +27,7 @@
#include <atf-c.h>
#include <sys/types.h>
#include <private/utils.h>
-
#include <sys/sbuf.h>
+
#include <utstring.h>

ATF_TC(merge);

@@ -39,39 +39,40 @@ ATF_TC_HEAD(merge, tc)

ATF_TC_BODY(merge, tc)
{
-
	struct sbuf *b = sbuf_new_auto();
+
	UT_string *b;
+
	utstring_new(b);
	char *pivot = "test1\ntest2\n";
	char *modified = "test1\n#test2\n";
	char *new = "test1\ntest2\ntest3\n";

	ATF_REQUIRE_EQ(merge_3way(pivot, modified, new, b), 0);
-
	ATF_REQUIRE_STREQ(sbuf_data(b), "test1\n#test2\ntest3\n");
+
	ATF_REQUIRE_STREQ(utstring_body(b), "test1\n#test2\ntest3\n");

-
	sbuf_clear(b);
+
	utstring_clear(b);
	pivot = "test1\ntest2";
	modified = "test1\n#test2";
	new = "test1\ntest2\ntest3";

	ATF_REQUIRE_EQ(merge_3way(pivot, modified, new, b), 0);
-
	ATF_REQUIRE_STREQ(sbuf_data(b), "test1\n#test2test3");
+
	ATF_REQUIRE_STREQ(utstring_body(b), "test1\n#test2test3");

-
	sbuf_clear(b);
+
	utstring_clear(b);
	pivot = "test1\ntest2";
	modified = "test1\n";
	new = "test1\ntest2\ntest3";

	ATF_REQUIRE_EQ(merge_3way(pivot, modified, new, b), 0);
-
	ATF_REQUIRE_STREQ(sbuf_data(b), "test1\ntest3");
+
	ATF_REQUIRE_STREQ(utstring_body(b), "test1\ntest3");

-
	sbuf_clear(b);
+
	utstring_clear(b);
	pivot = "test1\ntest2\ntest3";
	modified = "test1\na\ntest2\ntest3";
	new = "test1\ntest2\ntest3";

	ATF_REQUIRE_EQ(merge_3way(pivot, modified, new, b), 0);
-
	ATF_REQUIRE_STREQ(sbuf_data(b), "test1\na\ntest2\ntest3");
+
	ATF_REQUIRE_STREQ(utstring_body(b), "test1\na\ntest2\ntest3");

-
	sbuf_delete(b);
+
	utstring_free(b);
}

ATF_TP_ADD_TCS(tp)
modified tests/lib/pkg_printf_test.c
@@ -27,6 +27,7 @@
#include <string.h>

#include <atf-c.h>
+
#include <utstring.h>
#include <pkg.h>
#include <private/pkg_printf.h>

@@ -133,7 +134,7 @@ ATF_TC_HEAD(human_number, tc)
}
ATF_TC_BODY(human_number, tc)
{
-
	struct sbuf		*sbuf;
+
	UT_string		*buf;
	struct percent_esc	*p;
	int			 i;

@@ -307,22 +308,22 @@ ATF_TC_BODY(human_number, tc)
		{ -1,                  NULL,     0, 0, },
	};

-
	sbuf = sbuf_new_auto();
+
	utstring_new(buf);
	p = new_percent_esc();

-
	ATF_REQUIRE_EQ(sbuf != NULL, true);
+
	ATF_REQUIRE_EQ(buf != NULL, true);
	ATF_REQUIRE_EQ(p != NULL, true);

	for (i = 0; hn_test_vals[i].out != NULL; i++) {
		p->width = hn_test_vals[i].width;
		p->flags = hn_test_vals[i].flags;
-
		sbuf = human_number(sbuf, hn_test_vals[i].in, p);
-
		ATF_CHECK_STREQ(sbuf_data(sbuf), hn_test_vals[i].out);
-
		sbuf_clear(sbuf);
+
		buf = human_number(buf, hn_test_vals[i].in, p);
+
		ATF_CHECK_STREQ(utstring_body(buf), hn_test_vals[i].out);
+
		utstring_clear(buf);
	}

	free_percent_esc(p);
-
	sbuf_delete(sbuf);
+
	utstring_free(buf);
}

ATF_TC(string_val);
@@ -333,7 +334,7 @@ ATF_TC_HEAD(string_val, tc)
}
ATF_TC_BODY(string_val, tc)
{
-
	struct sbuf		*sbuf;
+
	UT_string		*buf;
	struct percent_esc	*p;
	int			 i;

@@ -391,22 +392,22 @@ ATF_TC_BODY(string_val, tc)
		{ NULL, NULL, 0, 0, },
	};

-
	sbuf = sbuf_new_auto();
+
	utstring_new(buf);
	p = new_percent_esc();

-
	ATF_REQUIRE_EQ(sbuf != NULL, true);
+
	ATF_REQUIRE_EQ(buf != NULL, true);
	ATF_REQUIRE_EQ(p != NULL, true);

	for (i = 0; sv_test_vals[i].out != NULL; i++) {
		p->width = sv_test_vals[i].width;
		p->flags = sv_test_vals[i].flags;
-
		sbuf = string_val(sbuf, sv_test_vals[i].in, p);
-
		ATF_CHECK_STREQ(sbuf_data(sbuf), sv_test_vals[i].out);
-
		sbuf_clear(sbuf);
+
		buf = string_val(buf, sv_test_vals[i].in, p);
+
		ATF_CHECK_STREQ(utstring_body(buf), sv_test_vals[i].out);
+
		utstring_clear(buf);
	}

	free_percent_esc(p);
-
	sbuf_delete(sbuf);
+
	utstring_free(buf);
}

ATF_TC(int_val);
@@ -417,7 +418,7 @@ ATF_TC_HEAD(int_val, tc)
}
ATF_TC_BODY(int_val, tc)
{
-
	struct sbuf		*sbuf;
+
	UT_string		*buf;
	struct percent_esc	*p;
	int			 i;

@@ -631,22 +632,22 @@ ATF_TC_BODY(int_val, tc)
		{ -1, NULL, 0, 0, },
	}; 

-
	sbuf = sbuf_new_auto();
+
	utstring_new(buf);
	p = new_percent_esc();

-
	ATF_REQUIRE_EQ(sbuf != NULL, true);
+
	ATF_REQUIRE_EQ(buf != NULL, true);
	ATF_REQUIRE_EQ(p != NULL, true);

	for (i = 0; iv_test_vals[i].out != NULL; i++) {
		p->width = iv_test_vals[i].width;
		p->flags = iv_test_vals[i].flags;
-
		sbuf = int_val(sbuf, iv_test_vals[i].in, p);
-
		ATF_CHECK_STREQ(sbuf_data(sbuf), iv_test_vals[i].out);
-
		sbuf_clear(sbuf);
+
		buf = int_val(buf, iv_test_vals[i].in, p);
+
		ATF_CHECK_STREQ(utstring_body(buf), iv_test_vals[i].out);
+
		utstring_clear(buf);
	}

	free_percent_esc(p);
-
	sbuf_delete(sbuf);
+
	utstring_free(buf);
}

ATF_TC(bool_val);
@@ -657,7 +658,7 @@ ATF_TC_HEAD(bool_val, tc)
}
ATF_TC_BODY(bool_val, tc)
{
-
	struct sbuf		*sbuf;
+
	UT_string		*buf;
	struct percent_esc	*p;
	int			 i;

@@ -684,22 +685,22 @@ ATF_TC_BODY(bool_val, tc)
		{ false, NULL, 0, 0, },
	};

-
	sbuf = sbuf_new_auto();
+
	utstring_new(buf);
	p = new_percent_esc();

-
	ATF_REQUIRE_EQ(sbuf != NULL, true);
+
	ATF_REQUIRE_EQ(buf != NULL, true);
	ATF_REQUIRE_EQ(p != NULL, true);

	for (i = 0; bv_test_vals[i].out != NULL; i++) {
		p->width = bv_test_vals[i].width;
		p->flags = bv_test_vals[i].flags;
-
		sbuf = bool_val(sbuf, bv_test_vals[i].in, p);
-
		ATF_CHECK_STREQ(sbuf_data(sbuf), bv_test_vals[i].out);
-
		sbuf_clear(sbuf);
+
		buf = bool_val(buf, bv_test_vals[i].in, p);
+
		ATF_CHECK_STREQ(utstring_body(buf), bv_test_vals[i].out);
+
		utstring_clear(buf);
	}

	free_percent_esc(p);
-
	sbuf_delete(sbuf);
+
	utstring_free(buf);
}

ATF_TC(mode_val);
@@ -710,7 +711,7 @@ ATF_TC_HEAD(mode_val, tc)
}
ATF_TC_BODY(mode_val, tc)
{
-
	struct sbuf		*sbuf;
+
	UT_string		*buf;
	struct percent_esc	*p;
	int			 i;

@@ -803,22 +804,22 @@ ATF_TC_BODY(mode_val, tc)
		{ 0, NULL, 0, 0, },
	};

-
	sbuf = sbuf_new_auto();
+
	utstring_new(buf);
	p = new_percent_esc();

-
	ATF_REQUIRE_EQ(sbuf != NULL, true);
+
	ATF_REQUIRE_EQ(buf != NULL, true);
	ATF_REQUIRE_EQ(p != NULL, true);

	for (i = 0; mv_test_vals[i].out != NULL; i++) {
		p->width = mv_test_vals[i].width;
		p->flags = mv_test_vals[i].flags;
-
		sbuf = mode_val(sbuf, mv_test_vals[i].in, p);
-
		ATF_CHECK_STREQ(sbuf_data(sbuf), mv_test_vals[i].out);
-
		sbuf_clear(sbuf);
+
		buf = mode_val(buf, mv_test_vals[i].in, p);
+
		ATF_CHECK_STREQ(utstring_body(buf), mv_test_vals[i].out);
+
		utstring_clear(buf);
	}

	free_percent_esc(p);
-
	sbuf_delete(sbuf);
+
	utstring_free(buf);
}
	
ATF_TC(liclog_val);
@@ -829,7 +830,7 @@ ATF_TC_HEAD(liclog_val, tc)
}
ATF_TC_BODY(liclog_val, tc)
{
-
	struct sbuf		*sbuf;
+
	UT_string		*buf;
	struct percent_esc	*p;
	int			 i;

@@ -859,22 +860,22 @@ ATF_TC_BODY(liclog_val, tc)
		{ 0, NULL, 0, 0, },
	};

-
	sbuf = sbuf_new_auto();
+
	utstring_new(buf);
	p = new_percent_esc();

-
	ATF_REQUIRE_EQ(sbuf != NULL, true);
+
	ATF_REQUIRE_EQ(buf != NULL, true);
	ATF_REQUIRE_EQ(p != NULL, true);

	for (i = 0; lv_test_vals[i].out != NULL; i++) {
		p->width = lv_test_vals[i].width;
		p->flags = lv_test_vals[i].flags;
-
		sbuf = liclog_val(sbuf, lv_test_vals[i].in, p);
-
		ATF_CHECK_STREQ(sbuf_data(sbuf), lv_test_vals[i].out);
-
		sbuf_clear(sbuf);
+
		buf = liclog_val(buf, lv_test_vals[i].in, p);
+
		ATF_CHECK_STREQ(utstring_body(buf), lv_test_vals[i].out);
+
		utstring_clear(buf);
	}

	free_percent_esc(p);
-
	sbuf_delete(sbuf);
+
	utstring_free(buf);
}

ATF_TC(list_count);
@@ -885,7 +886,7 @@ ATF_TC_HEAD(list_count, tc)
}
ATF_TC_BODY(list_count, tc)
{
-
	struct sbuf		*sbuf;
+
	UT_string		*buf;
	struct percent_esc	*p;
	int			 i;

@@ -907,22 +908,22 @@ ATF_TC_BODY(list_count, tc)
		{ 0, NULL, 0, 0, },
	};

-
	sbuf = sbuf_new_auto();
+
	utstring_new(buf);
	p = new_percent_esc();

-
	ATF_REQUIRE_EQ(sbuf != NULL, true);
+
	ATF_REQUIRE_EQ(buf != NULL, true);
	ATF_REQUIRE_EQ(p != NULL, true);

	for (i = 0; lc_test_vals[i].out != NULL; i++) {
		p->width = lc_test_vals[i].width;
		p->flags = lc_test_vals[i].flags;
-
		sbuf = list_count(sbuf, lc_test_vals[i].in, p);
-
		ATF_CHECK_STREQ(sbuf_data(sbuf), lc_test_vals[i].out);
-
		sbuf_clear(sbuf);
+
		buf = list_count(buf, lc_test_vals[i].in, p);
+
		ATF_CHECK_STREQ(utstring_body(buf), lc_test_vals[i].out);
+
		utstring_clear(buf);
	}

	free_percent_esc(p);
-
	sbuf_delete(sbuf);
+
	utstring_free(buf);
}

ATF_TC(maybe_read_hex_byte);
@@ -933,13 +934,13 @@ ATF_TC_HEAD(maybe_read_hex_byte, tc)
}
ATF_TC_BODY(maybe_read_hex_byte, tc)
{
-
	struct sbuf	*sbuf;
+
	UT_string	*buf;
	const char	*f;
	int		 i;

	struct mrhb_test_vals {
		const char *in;
-
		const char *out; /* What gets written to the sbuf */
+
		const char *out; /* What gets written to the buf */
		ptrdiff_t   fend_offset; /* Where f is left pointing */
		char	    fend_val; /* expected first char in fend */
	} mrhb_test_vals[] = {
@@ -1002,15 +1003,14 @@ ATF_TC_BODY(maybe_read_hex_byte, tc)
		{ NULL,   NULL,    0, '\0', },
	};

-
	sbuf = sbuf_new_auto();
+
	utstring_new(buf);

-
	ATF_REQUIRE_EQ(sbuf != NULL, true);
+
	ATF_REQUIRE_EQ(buf != NULL, true);

	for (i = 0; mrhb_test_vals[i].in != NULL; i++) {
-
		f = maybe_read_hex_byte(sbuf, mrhb_test_vals[i].in);
-
		sbuf_finish(sbuf);
+
		f = maybe_read_hex_byte(buf, mrhb_test_vals[i].in);

-
		ATF_CHECK_STREQ_MSG(sbuf_data(sbuf), mrhb_test_vals[i].out,
+
		ATF_CHECK_STREQ_MSG(utstring_body(buf), mrhb_test_vals[i].out,
				    "(test %d)", i);
		ATF_CHECK_EQ_MSG(f - mrhb_test_vals[i].in,
				 mrhb_test_vals[i].fend_offset,
@@ -1018,10 +1018,10 @@ ATF_TC_BODY(maybe_read_hex_byte, tc)
		ATF_CHECK_EQ_MSG(*f, mrhb_test_vals[i].fend_val,
				 "(test %d)", i);
		
-
		sbuf_clear(sbuf);
+
		utstring_clear(buf);
	}

-
	sbuf_delete(sbuf);
+
	utstring_free(buf);
}


@@ -1033,13 +1033,13 @@ ATF_TC_HEAD(read_oct_byte, tc)
}
ATF_TC_BODY(read_oct_byte, tc)
{
-
	struct sbuf	*sbuf;
+
	UT_string	*buf;
	const char	*f;
	int		 i;

	struct rob_test_vals {
		const char *in;
-
		const char *out; /* What gets written to the sbuf */
+
		const char *out; /* What gets written to the buf */
		ptrdiff_t   fend_offset; /* Where f is left pointing */
		char	    fend_val; /* expected first char in fend */
	} rob_test_vals[] = {
@@ -1109,15 +1109,14 @@ ATF_TC_BODY(read_oct_byte, tc)
		{ NULL,   NULL,    0, '\0', },
	};

-
	sbuf = sbuf_new_auto();
+
	utstring_new(buf);

-
	ATF_REQUIRE_EQ(sbuf != NULL, true);
+
	ATF_REQUIRE_EQ(buf != NULL, true);

	for (i = 0; rob_test_vals[i].in != NULL; i++) {
-
		f = read_oct_byte(sbuf, rob_test_vals[i].in);
-
		sbuf_finish(sbuf);
+
		f = read_oct_byte(buf, rob_test_vals[i].in);

-
		ATF_CHECK_STREQ_MSG(sbuf_data(sbuf), rob_test_vals[i].out,
+
		ATF_CHECK_STREQ_MSG(utstring_body(buf), rob_test_vals[i].out,
				    "(test %d)", i);
		ATF_CHECK_EQ_MSG(f - rob_test_vals[i].in,
				 rob_test_vals[i].fend_offset,
@@ -1125,10 +1124,10 @@ ATF_TC_BODY(read_oct_byte, tc)
		ATF_CHECK_EQ_MSG(*f, rob_test_vals[i].fend_val,
				 "(test %d)", i);
		
-
		sbuf_clear(sbuf);
+
		utstring_clear(buf);
	}

-
	sbuf_delete(sbuf);
+
	utstring_free(buf);
}

ATF_TC(process_escape);
@@ -1139,13 +1138,13 @@ ATF_TC_HEAD(process_escape, tc)
}
ATF_TC_BODY(process_escape, tc)
{
-
	struct sbuf	*sbuf;
+
	UT_string	*buf;
	const char	*f;
	int		 i;

	struct pe_test_vals {
		const char *in;
-
		const char *out; /* What gets written to the sbuf */
+
		const char *out; /* What gets written to the buf */
		ptrdiff_t   fend_offset; /* Where f is left pointing */
		char	    fend_val; /* expected first char in fend */
	} pe_test_vals[] = {
@@ -1176,15 +1175,14 @@ ATF_TC_BODY(process_escape, tc)
		{ NULL,   NULL,    0, '\0', },
	};

-
	sbuf = sbuf_new_auto();
+
	utstring_new(buf);

-
	ATF_REQUIRE_EQ(sbuf != NULL, true);
+
	ATF_REQUIRE_EQ(buf != NULL, true);

	for (i = 0; pe_test_vals[i].in != NULL; i++) {
-
		f = process_escape(sbuf, pe_test_vals[i].in);
-
		sbuf_finish(sbuf);
+
		f = process_escape(buf, pe_test_vals[i].in);

-
		ATF_CHECK_STREQ_MSG(sbuf_data(sbuf), pe_test_vals[i].out,
+
		ATF_CHECK_STREQ_MSG(utstring_body(buf), pe_test_vals[i].out,
				    "(test %d)", i);
		ATF_CHECK_EQ_MSG(f - pe_test_vals[i].in,
				 pe_test_vals[i].fend_offset,
@@ -1192,10 +1190,10 @@ ATF_TC_BODY(process_escape, tc)
		ATF_CHECK_EQ_MSG(*f, pe_test_vals[i].fend_val,
				 "(test %d)", i);
		
-
		sbuf_clear(sbuf);
+
		utstring_clear(buf);
	}

-
	sbuf_delete(sbuf);
+
	utstring_free(buf);
}

ATF_TC(field_modifier);
@@ -2213,15 +2211,15 @@ ATF_TC_BODY(format_trailer, tc)
	ATF_REQUIRE_EQ(p != NULL, true);

	for (i = 0; ft_test_vals[i].in != NULL; i++) {
-
		sbuf_clear(p->item_fmt);
-
		sbuf_clear(p->sep_fmt);
+
		utstring_clear(p->item_fmt);
+
		utstring_clear(p->sep_fmt);

		f = format_trailer(ft_test_vals[i].in, p);

-
		ATF_CHECK_STREQ_MSG(sbuf_data(p->item_fmt),
+
		ATF_CHECK_STREQ_MSG(utstring_body(p->item_fmt),
				    ft_test_vals[i].item,
				    "(test %d)", i);
-
		ATF_CHECK_STREQ_MSG(sbuf_data(p->sep_fmt),
+
		ATF_CHECK_STREQ_MSG(utstring_body(p->sep_fmt),
				    ft_test_vals[i].sep,
				    "(test %d)", i);
		ATF_CHECK_EQ_MSG(f - ft_test_vals[i].in,
@@ -2292,10 +2290,10 @@ ATF_TC_BODY(parse_format, tc)
		ATF_CHECK_EQ_MSG(p->fmt_code, pf_test_vals[i].fmt_code,
				    "(test %d)", i);

-
		ATF_CHECK_STREQ_MSG(sbuf_data(p->item_fmt),
+
		ATF_CHECK_STREQ_MSG(utstring_body(p->item_fmt),
				    pf_test_vals[i].item,
				    "(test %d)", i);
-
		ATF_CHECK_STREQ_MSG(sbuf_data(p->sep_fmt),
+
		ATF_CHECK_STREQ_MSG(utstring_body(p->sep_fmt),
				    pf_test_vals[i].sep,
				    "(test %d)", i);
		ATF_CHECK_EQ_MSG(f - pf_test_vals[i].in,
modified tests/lib/pkg_validation.c
@@ -25,14 +25,14 @@
 */

#include <sys/types.h>
-
#include <sys/sbuf.h>

#include <string.h>

#include <atf-c.h>
+
#include <utstring.h>
#include <pkg.h>

-
struct sbuf *msg;
+
UT_string *msg;

ATF_TC(valid_installed);

@@ -47,9 +47,8 @@ event_callback(void *data, struct pkg_event *ev)
{
	switch (ev->type) {
	case PKG_EVENT_ERROR:
-
		sbuf_clear(msg);
-
		sbuf_printf(msg, "%s", ev->e_pkg_error.msg);
-
		sbuf_finish(msg);
+
		utstring_clear(msg);
+
		utstring_printf(msg, "%s", ev->e_pkg_error.msg);
		break;
	default:
		/* IGNORE */
@@ -62,43 +61,43 @@ event_callback(void *data, struct pkg_event *ev)
void
check_valid(struct pkg *p)
{
-
	msg = sbuf_new_auto();
+
	utstring_new(msg);

	ATF_REQUIRE_EQ(EPKG_FATAL, pkg_is_valid(p));
-
	ATF_REQUIRE_STREQ(sbuf_data(msg), "Invalid package: object has missing property origin");
+
	ATF_REQUIRE_STREQ(utstring_body(msg), "Invalid package: object has missing property origin");

	ATF_REQUIRE_EQ(EPKG_OK, pkg_set(p, PKG_ORIGIN, "test/bla"));
	ATF_REQUIRE_EQ(EPKG_FATAL, pkg_is_valid(p));
-
	ATF_REQUIRE_STREQ(sbuf_data(msg), "Invalid package: object has missing property name");
+
	ATF_REQUIRE_STREQ(utstring_body(msg), "Invalid package: object has missing property name");

	ATF_REQUIRE_EQ(EPKG_OK, pkg_set(p, PKG_NAME, "test"));
	ATF_REQUIRE_EQ(EPKG_FATAL, pkg_is_valid(p));
-
	ATF_REQUIRE_STREQ(sbuf_data(msg), "Invalid package: object has missing property comment");
+
	ATF_REQUIRE_STREQ(utstring_body(msg), "Invalid package: object has missing property comment");

	ATF_REQUIRE_EQ(EPKG_OK, pkg_set(p, PKG_COMMENT, "test comment"));
	ATF_REQUIRE_EQ(EPKG_FATAL, pkg_is_valid(p));
-
	ATF_REQUIRE_STREQ(sbuf_data(msg), "Invalid package: object has missing property version");
+
	ATF_REQUIRE_STREQ(utstring_body(msg), "Invalid package: object has missing property version");

	ATF_REQUIRE_EQ(EPKG_OK, pkg_set(p, PKG_VERSION, "1.1.0"));
	ATF_REQUIRE_EQ(EPKG_FATAL, pkg_is_valid(p));
-
	ATF_REQUIRE_STREQ(sbuf_data(msg), "Invalid package: object has missing property desc");
+
	ATF_REQUIRE_STREQ(utstring_body(msg), "Invalid package: object has missing property desc");

	ATF_REQUIRE_EQ(EPKG_OK, pkg_set(p, PKG_DESC, "test description"));
	ATF_REQUIRE_EQ(EPKG_FATAL, pkg_is_valid(p));
-
	ATF_REQUIRE_STREQ(sbuf_data(msg), "Invalid package: object has missing property maintainer");
+
	ATF_REQUIRE_STREQ(utstring_body(msg), "Invalid package: object has missing property maintainer");

	ATF_REQUIRE_EQ(EPKG_OK, pkg_set(p, PKG_MAINTAINER, "tester"));
	ATF_REQUIRE_EQ(EPKG_FATAL, pkg_is_valid(p));
-
	ATF_REQUIRE_STREQ(sbuf_data(msg), "Invalid package: object has missing property www");
+
	ATF_REQUIRE_STREQ(utstring_body(msg), "Invalid package: object has missing property www");

	ATF_REQUIRE_EQ(EPKG_OK, pkg_set(p, PKG_WWW, "test website"));
	ATF_REQUIRE_EQ(EPKG_FATAL, pkg_is_valid(p));
-
	ATF_REQUIRE_STREQ(sbuf_data(msg), "Invalid package: object has missing property prefix");
+
	ATF_REQUIRE_STREQ(utstring_body(msg), "Invalid package: object has missing property prefix");

	ATF_REQUIRE_EQ(EPKG_OK, pkg_set(p, PKG_PREFIX, "/usr/local"));
	ATF_REQUIRE_EQ(EPKG_OK, pkg_is_valid(p));

-
	sbuf_delete(msg);
+
	utstring_free(msg);
}

ATF_TC_BODY(valid_installed, tc)