Radish alpha
H
rad:z3QDZAW2FAfuLvihrhiyDC9fAD8G9
HardenedBSD Package Manager
Radicle
Git
Use open_memstream p1
Baptiste Daroussin committed 5 years ago
commit 383d27cfca197e2788c7c15a2decf12feff08c8c
parent 7b6819e
36 files changed +652 -570
modified libpkg/diff.c
@@ -22,7 +22,6 @@

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

#include "private/utils.h"
#include "xmalloc.h"
modified libpkg/fetch_libfetch.c
@@ -37,6 +37,7 @@
#include <fetch.h>
#include <paths.h>
#include <poll.h>
+
#include <xstring.h>

#include <bsd_compat.h>

@@ -90,7 +91,7 @@ static int
fetch_connect(struct pkg_repo *repo, struct url *u)
{
	struct url *repourl;
-
	UT_string *fetchOpts = NULL;
+
	xstring *fetchOpts = NULL;
	int64_t max_retry, retry;
	int64_t fetch_timeout;
	int retcode = EPKG_OK;
@@ -158,31 +159,32 @@ fetch_connect(struct pkg_repo *repo, struct url *u)
			u->doc = docpath;
			u->port = http_current->url->port;
		}
-
		utstring_new(fetchOpts);
-
		utstring_printf(fetchOpts, "i");
+
		fetchOpts = xstring_new();
+
		fprintf(fetchOpts->fp, "i");
		if (repo != NULL) {
			if ((repo->flags & REPO_FLAGS_USE_IPV4) ==
			    REPO_FLAGS_USE_IPV4)
-
				utstring_printf(fetchOpts, "4");
+
				fprintf(fetchOpts->fp, "4");
			else if ((repo->flags & REPO_FLAGS_USE_IPV6) ==
			    REPO_FLAGS_USE_IPV6)
-
				utstring_printf(fetchOpts, "6");
+
				fprintf(fetchOpts->fp, "6");
		}

		if (ctx.debug_level >= 4)
-
			utstring_printf(fetchOpts, "v");
+
			fprintf(fetchOpts->fp, "v");

+
		fflush(fetchOpts->fp);
		pkg_debug(1,"Fetch: fetching from: %s://%s%s%s%s with opts \"%s\"",
		    u->scheme,
		    u->user,
		    u->user[0] != '\0' ? "@" : "",
		    u->host,
		    u->doc,
-
		    utstring_body(fetchOpts));
+
		    fetchOpts->buf);

-
		repo->fh = fetchXGet(u, &st, utstring_body(fetchOpts));
+
		repo->fh = fetchXGet(u, &st, fetchOpts->buf);
		u->ims_time = st.mtime;
-
		utstring_free(fetchOpts);
+
		xstring_free(fetchOpts);
		if (repo->fh == NULL) {
			if (fetchLastErrCode == FETCH_OK) {
				retcode = EPKG_UPTODATE;
modified libpkg/fetch_ssh.c
@@ -56,7 +56,7 @@ ssh_connect(struct pkg_repo *repo, struct url *u)
	size_t linecap = 0;
	int sshin[2];
	int sshout[2];
-
	UT_string *cmd = NULL;
+
	xstring *cmd = NULL;
	int retcode = EPKG_FATAL;
	const char *ssh_args;
	const char *argv[4];
@@ -82,26 +82,27 @@ ssh_connect(struct pkg_repo *repo, struct url *u)
			goto ssh_cleanup;
		}

-
		utstring_new(cmd);
-
		utstring_printf(cmd, "/usr/bin/ssh -e none -T ");
+
		cmd = xstring_new();
+
		fprintf(cmd->fp, "/usr/bin/ssh -e none -T ");

		ssh_args = pkg_object_string(pkg_config_get("PKG_SSH_ARGS"));
		if (ssh_args != NULL)
-
			utstring_printf(cmd, "%s ", ssh_args);
+
			fprintf(cmd->fp, "%s ", ssh_args);
		if ((repo->flags & REPO_FLAGS_USE_IPV4) == REPO_FLAGS_USE_IPV4)
-
			utstring_printf(cmd, "-4 ");
+
			fprintf(cmd->fp, "-4 ");
		else if ((repo->flags & REPO_FLAGS_USE_IPV6) == REPO_FLAGS_USE_IPV6)
-
			utstring_printf(cmd, "-6 ");
+
			fprintf(cmd->fp, "-6 ");
		if (u->port > 0)
-
			utstring_printf(cmd, "-p %d ", u->port);
+
			fprintf(cmd->fp, "-p %d ", u->port);
		if (u->user[0] != '\0')
-
			utstring_printf(cmd, "%s@", u->user);
-
		utstring_printf(cmd, "%s", u->host);
-
		utstring_printf(cmd, " pkg ssh");
-
		pkg_debug(1, "Fetch: running '%s'", utstring_body(cmd));
+
			fprintf(cmd->fp, "%s@", u->user);
+
		fprintf(cmd->fp, "%s", u->host);
+
		fprintf(cmd->fp, " pkg ssh");
+
		fflush(cmd->fp);
+
		pkg_debug(1, "Fetch: running '%s'", cmd->buf);
		argv[0] = _PATH_BSHELL;
		argv[1] = "-c";
-
		argv[2] = utstring_body(cmd);
+
		argv[2] = cmd->buf;
		argv[3] = NULL;

		if (sshin[0] != STDIN_FILENO)
modified libpkg/lua_scripts.c
@@ -41,7 +41,7 @@

#include <errno.h>
#include <poll.h>
-
#include <utstring.h>
+
#include <xstring.h>
#include <lauxlib.h>
#include <lualib.h>
#include <fcntl.h>
@@ -59,33 +59,34 @@ stack_dump(lua_State *L)
{
	int i;
	int top = lua_gettop(L);
-
	UT_string *stack;
+
	xstring *stack;

-
	utstring_new(stack);
+
	stack = xstring_new();

-
	utstring_printf(stack, "\nLua Stack\n---------\n");
-
	utstring_printf(stack, "\tType   Data\n\t-----------\n" );
+
	fprintf(stack->fp, "\nLua Stack\n---------\n");
+
	fprintf(stack->fp, "\tType   Data\n\t-----------\n" );

	for (i = 1; i <= top; i++) {  /* repeat for each level */
		int t = lua_type(L, i);
-
		utstring_printf(stack, "%i", i);
+
		fprintf(stack->fp, "%i", i);
		switch (t) {
		case LUA_TSTRING:  /* strings */
-
			utstring_printf(stack, "\tString: `%s'\n", lua_tostring(L, i));
+
			fprintf(stack->fp, "\tString: `%s'\n", lua_tostring(L, i));
			break;
		case LUA_TBOOLEAN:  /* booleans */
-
			utstring_printf(stack, "\tBoolean: %s", lua_toboolean(L, i) ? "\ttrue\n" : "\tfalse\n");
+
			fprintf(stack->fp, "\tBoolean: %s", lua_toboolean(L, i) ? "\ttrue\n" : "\tfalse\n");
			break;
		case LUA_TNUMBER:  /* numbers */
-
			utstring_printf(stack, "\tNumber: %g\n", lua_tonumber(L, i));
+
			fprintf(stack->fp, "\tNumber: %g\n", lua_tonumber(L, i));
			break;
		default:  /* other values */
-
			utstring_printf(stack, "\tOther: %s\n", lua_typename(L, t));
+
			fprintf(stack->fp, "\tOther: %s\n", lua_typename(L, t));
			break;
		}
	}
-
	pkg_emit_error("%s\n", utstring_body(stack));
-
	utstring_free(stack);
+
	fflush(stack->fp);
+
	pkg_emit_error("%s\n", stack->buf);
+
	xstring_free(stack);

	return (0);
}
modified libpkg/packing.c
@@ -270,7 +270,7 @@ packing_append_tree(struct packing *pack, const char *treepath,
	FTS *fts = NULL;
	FTSENT *fts_e = NULL;
	size_t treelen;
-
	UT_string *sb;
+
	xstring *sb;
	char *paths[2] = { __DECONST(char *, treepath), NULL };

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

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

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

	pkg_list_free(pkg, PKG_DEPS);
	pkg_list_free(pkg, PKG_RDEPS);
@@ -819,8 +818,8 @@ pkg_addscript(struct pkg *pkg, const char *data, pkg_script type)
{

	assert(pkg != NULL);
-
	utstring_renew(pkg->scripts[type]);
-
	utstring_printf(pkg->scripts[type], "%s", data);
+
	xstring_renew(pkg->scripts[type]);
+
	fprintf(pkg->scripts[type]->fp, "%s", data);

	return (EPKG_OK);
}
@@ -931,9 +930,9 @@ pkg_appendscript(struct pkg *pkg, const char *cmd, pkg_script type)
	assert(cmd != NULL && cmd[0] != '\0');

	if (pkg->scripts[type] == NULL)
-
		utstring_new(pkg->scripts[type]);
+
		pkg->scripts[type] = xstring_new();

-
	utstring_printf(pkg->scripts[type], "%s", cmd);
+
	fprintf(pkg->scripts[type]->fp, "%s", cmd);

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

/* The expected name of the pkg(8) binary executable. */
#ifndef PKG_EXEC_NAME
@@ -1671,7 +1672,7 @@ int pkg_audit_load(struct pkg_audit *audit, const char *fname);
 */
int pkg_audit_process(struct pkg_audit *audit);

-
#if defined(UTSTRING_H)
+
#if defined(__XSTRING_H_)
/**
 * Check whether `pkg` is vulnerable against processed `audit` structure.
 * If a package is vulnerable, then `result` is set to sbuf describing the
@@ -1681,7 +1682,7 @@ 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, UT_string **result, int *affected);
+
		bool quiet, xstring **result, int *affected);
#endif

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

#include "pkg.h"
#include "private/event.h"
@@ -1035,7 +1035,7 @@ pkg_add_common(struct pkgdb *db, const char *path, unsigned flags,
	struct archive		*a;
	struct archive_entry	*ae;
	struct pkg		*pkg = NULL;
-
	UT_string		*message;
+
	xstring			*message = NULL;
	struct pkg_message	*msg;
	struct pkg_file		*f;
	const char		*msgstr;
@@ -1200,8 +1200,6 @@ cleanup_reg:
			pkg_emit_install_finished(pkg, local);
	}

-
	if (pkg->message != NULL)
-
		utstring_new(message);
	LL_FOREACH(pkg->message, msg) {
		msgstr = NULL;
		if (msg->type == PKG_MESSAGE_ALWAYS) {
@@ -1228,18 +1226,18 @@ cleanup_reg:
			msgstr = msg->str;
		}
		if (msgstr != NULL) {
-
			if (utstring_len(message) == 0) {
-
				pkg_utstring_printf(message, "=====\nMessage from "
+
			if (message == NULL) {
+
				message = xstring_new();
+
				pkg_fprintf(message->fp, "=====\nMessage from "
				    "%n-%v:\n\n", pkg, pkg);
			}
-
			utstring_printf(message, "--\n%s\n", msgstr);
+
			fprintf(message->fp, "--\n%s\n", msgstr);
		}
	}
-
	if (pkg->message != NULL) {
-
		if (utstring_len(message) > 0) {
-
			pkg_emit_message(utstring_body(message));
-
		}
-
		utstring_free(message);
+
	if (pkg->message != NULL && message != NULL) {
+
		fflush(message->fp);
+
		pkg_emit_message(message->buf);
+
		xstring_free(message);
	}

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

-
	return (utstring_body(p->scripts[i]));
+
	fflush(p->scripts[i]->fp);
+
	return (p->scripts[i]->buf);
}

/*
modified libpkg/pkg_audit.c
@@ -36,6 +36,7 @@
#include <stdio.h>
#include <string.h>
#include <utlist.h>
+
#include <xstring.h>

#include <yxml.h>

@@ -379,7 +380,7 @@ struct vulnxml_userdata {
	struct pkg_audit_entry *cur_entry;
	struct pkg_audit *audit;
	enum vulnxml_parse_state state;
-
	UT_string *content;
+
	xstring *content;
	int range_num;
	enum vulnxml_parse_attribute_state attr;
};
@@ -448,18 +449,19 @@ vulnxml_end_element(struct vulnxml_userdata *ud, yxml_t *xml)
	struct pkg_audit_versions_range *vers;
	int range_type = -1;

+
	fflush(ud->content->fp);
	if (ud->state == VULNXML_PARSE_VULN && strcasecmp(xml->elem, "vuxml") == 0) {
		pkg_audit_expand_entry(ud->cur_entry, &ud->audit->entries);
		ud->state = VULNXML_PARSE_INIT;
	}
	else if (ud->state == VULNXML_PARSE_TOPIC && strcasecmp(xml->elem, "vuln") == 0) {
-
		ud->cur_entry->desc = xstrdup(utstring_body(ud->content));
+
		ud->cur_entry->desc = xstrdup(ud->content->buf);
		ud->state = VULNXML_PARSE_VULN;
	}
	else if (ud->state == VULNXML_PARSE_CVE && strcasecmp(xml->elem, "references") == 0) {
		entry = ud->cur_entry;
		cve = xmalloc(sizeof(struct pkg_audit_cve));
-
		cve->cvename = xstrdup(utstring_body(ud->content));
+
		cve->cvename = xstrdup(ud->content->buf);
		LL_PREPEND(entry->cve, cve);
		ud->state = VULNXML_PARSE_VULN;
	}
@@ -467,7 +469,7 @@ vulnxml_end_element(struct vulnxml_userdata *ud, yxml_t *xml)
		ud->state = VULNXML_PARSE_VULN;
	}
	else if (ud->state == VULNXML_PARSE_PACKAGE_NAME && strcasecmp(xml->elem, "package") == 0) {
-
		ud->cur_entry->packages->names->pkgname = xstrdup(utstring_body(ud->content));
+
		ud->cur_entry->packages->names->pkgname = xstrdup(ud->content->buf);
		ud->state = VULNXML_PARSE_PACKAGE;
	}
	else if (ud->state == VULNXML_PARSE_RANGE && strcasecmp(xml->elem, "package") == 0) {
@@ -497,15 +499,15 @@ vulnxml_end_element(struct vulnxml_userdata *ud, yxml_t *xml)
	if (range_type > 0) {
		vers = ud->cur_entry->packages->versions;
		if (ud->range_num == 1) {
-
			vers->v1.version = xstrdup(utstring_body(ud->content));
+
			vers->v1.version = xstrdup(ud->content->buf);
			vers->v1.type = range_type;
		}
		else if (ud->range_num == 2) {
-
			vers->v2.version = xstrdup(utstring_body(ud->content));
+
			vers->v2.version = xstrdup(ud->content->buf);
			vers->v2.type = range_type;
		}
	}
-
	utstring_clear(ud->content);
+
	xstring_reset(ud->content);
}

static void
@@ -521,18 +523,19 @@ vulnxml_start_attribute(struct vulnxml_userdata *ud, yxml_t *xml)
static void
vulnxml_end_attribute(struct vulnxml_userdata *ud, yxml_t *xml __unused)
{
+
	fflush(ud->content->fp);
	if (ud->state == VULNXML_PARSE_VULN && ud->attr == VULNXML_ATTR_VID) {
-
		ud->cur_entry->id = xstrdup(utstring_body(ud->content));
+
		ud->cur_entry->id = xstrdup(ud->content->buf);
		ud->attr = VULNXML_ATTR_NONE;
	}
-
	utstring_clear(ud->content);
+
	xstring_reset(ud->content);
}

static void
vulnxml_val_attribute(struct vulnxml_userdata *ud, yxml_t *xml)
{
	if (ud->state == VULNXML_PARSE_VULN && ud->attr == VULNXML_ATTR_VID) {
-
		utstring_printf(ud->content, "%s", xml->data);
+
		fprintf(ud->content->fp, "%s", xml->data);
	}
}

@@ -555,7 +558,7 @@ vulnxml_handle_data(struct vulnxml_userdata *ud, yxml_t *xml)
	case VULNXML_PARSE_RANGE_LT:
	case VULNXML_PARSE_RANGE_LE:
	case VULNXML_PARSE_RANGE_EQ:
-
		utstring_printf(ud->content, "%s", xml->data);
+
		fprintf(ud->content->fp, "%s", xml->data);
		break;
	}
}
@@ -575,7 +578,7 @@ pkg_audit_parse_vulnxml(struct pkg_audit *audit)
	ud.audit = audit;
	ud.range_num = 0;
	ud.state = VULNXML_PARSE_INIT;
-
	utstring_new(ud.content);
+
	ud.content = xstring_new();

	walk = audit->map;
	end = walk + audit->len;
@@ -622,7 +625,7 @@ pkg_audit_parse_vulnxml(struct pkg_audit *audit)
	else
		pkg_emit_error("Invalid end of XML");
out:
-
	utstring_free(ud.content);
+
	xstring_free(ud.content);

	return (ret);
}
@@ -768,57 +771,57 @@ pkg_audit_version_match(const char *pkgversion, struct pkg_audit_version *v)
}

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

-
	utstring_printf(sb, "%s", "Affected versions:\n");
+
	fprintf(sb->fp, "%s", "Affected versions:\n");
	LL_FOREACH(e->versions, vers) {
		if (vers->v1.type > 0 && vers->v2.type > 0)
-
			utstring_printf(sb, "%s %s : %s %s\n",
+
			fprintf(sb->fp, "%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)
-
			utstring_printf(sb, "%s %s\n",
+
			fprintf(sb->fp, "%s %s\n",
				vop_names[vers->v1.type], vers->v1.version);
		else
-
			utstring_printf(sb, "%s %s\n",
+
			fprintf(sb->fp, "%s %s\n",
				vop_names[vers->v2.type], vers->v2.version);
	}
}

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

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

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

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

@@ -839,7 +842,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]];
-
	utstring_new(sb);
+
	sb = xstring_new();

	for (; (e = a->e) != NULL; a += a->next_pfx_incr) {
		int cmp;
@@ -896,7 +899,7 @@ out:
	if (res) {
		*result = sb;
	} else {
-
		utstring_free(sb);
+
		xstring_free(sb);
	}

	return (res);
modified libpkg/pkg_checksum.c
@@ -274,10 +274,12 @@ pkg_checksum_generate(struct pkg *pkg, char *dest, size_t destlen,

	if (inc_scripts) {
		for (int i = 0; i < PKG_NUM_SCRIPTS; i++) {
-
			if (pkg->scripts[i] != NULL)
+
			if (pkg->scripts[i] != NULL) {
+
				fflush(pkg->scripts[i]->fp);
				pkg_checksum_add_entry("script",
-
				    utstring_body(pkg->scripts[i]),
+
				    pkg->scripts[i]->buf,
				    &entries);
+
			}
		}
		for (int i = 0; i < PKG_NUM_LUA_SCRIPTS; i++) {
			if (pkg->lua_scripts[i] != NULL)
modified libpkg/pkg_create.c
@@ -125,15 +125,16 @@ 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.
	 */
-
	UT_string *b;
-
	utstring_new(b);
+
	xstring *b = xstring_new();

	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);
+
	fflush(b->fp);
+
	packing_append_buffer(pkg_archive, b->buf, "+COMPACT_MANIFEST", strlen(b->buf));
+
	xstring_reset(b);
	pkg_emit_manifest_buf(pkg, b, 0, NULL);
-
	packing_append_buffer(pkg_archive, utstring_body(b), "+MANIFEST", utstring_len(b));
-
	utstring_free(b);
+
	fflush(b->fp);
+
	packing_append_buffer(pkg_archive, b->buf, "+MANIFEST", strlen(b->buf));
+
	xstring_free(b);

	counter_init("packing files", nfiles);

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

#include <bsd_compat.h>

@@ -58,11 +57,12 @@ int
pkg_delete(struct pkg *pkg, struct pkgdb *db, unsigned flags)
{
	struct pkg_message	*msg;
-
	UT_string	*message = NULL;
+
	xstring		*message = NULL;
	int		 ret;
	bool		 handle_rc = false;
	const unsigned load_flags = PKG_LOAD_RDEPS|PKG_LOAD_FILES|PKG_LOAD_DIRS|
					PKG_LOAD_SCRIPTS|PKG_LOAD_ANNOTATIONS|PKG_LOAD_LUA_SCRIPTS;
+
	bool		head = true;

	assert(pkg != NULL);
	assert(db != NULL);
@@ -116,22 +116,22 @@ pkg_delete(struct pkg *pkg, struct pkgdb *db, unsigned flags)

	if ((flags & PKG_DELETE_UPGRADE) == 0) {
		pkg_emit_deinstall_finished(pkg);
-
		utstring_renew(message);
		LL_FOREACH(pkg->message, msg) {
			if (msg->type == PKG_MESSAGE_REMOVE) {
-
				if (utstring_len(message) == 0) {
-
					pkg_utstring_printf(message, "Message from "
+
				if (message == NULL) {
+
					message = xstring_new();
+
					pkg_fprintf(message->fp, "Message from "
					    "%n-%v:\n", pkg, pkg);
+
					head = false;
				}
-
				utstring_printf(message, "%s\n", msg->str);
+
				fprintf(message->fp, "%s\n", msg->str);
			}
		}
-
		if (pkg->message != NULL) {
-
			if (utstring_len(message) > 0) {
-
				pkg_emit_message(utstring_body(message));
-
			}
+
		if (pkg->message != NULL && message != NULL) {
+
			fflush(message->fp);
+
			pkg_emit_message(message->buf);
+
			xstring_free(message);
		}
-
		utstring_free(message);

	}

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

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

static char *
-
buf_json_escape(UT_string *buf, const char *str)
+
buf_json_escape(const char *str)
{
-
	utstring_clear(buf);
+
	xstring *buf = xstring_new();
+

	while (str != NULL && *str != '\0') {
		if (*str == '"' || *str == '\\')
-
			utstring_printf(buf, "%c", '\\');
-
		utstring_printf(buf, "%c", *str);
+
			fprintf(buf->fp, "%c", '\\');
+
		fprintf(buf->fp, "%c", *str);
		str++;
	}

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

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

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

	switch(ev->type) {
	case PKG_EVENT_ERRNO:
-
		utstring_printf(msg, "{ \"type\": \"ERROR\", "
+
		fprintf(msg->fp, "{ \"type\": \"ERROR\", "
		    "\"data\": {"
		    "\"msg\": \"%s(%s): %s\","
		    "\"errno\": %d}}",
-
		    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)),
+
		    buf_json_escape(ev->e_errno.func),
+
		    buf_json_escape(ev->e_errno.arg),
+
		    buf_json_escape(strerror(ev->e_errno.no)),
		    ev->e_errno.no);
		break;
	case PKG_EVENT_ERROR:
-
		utstring_printf(msg, "{ \"type\": \"ERROR\", "
+
		fprintf(msg->fp, "{ \"type\": \"ERROR\", "
		    "\"data\": {\"msg\": \"%s\"}}",
-
		    buf_json_escape(buf, ev->e_pkg_error.msg));
+
		    buf_json_escape(ev->e_pkg_error.msg));
		break;
	case PKG_EVENT_NOTICE:
-
		utstring_printf(msg, "{ \"type\": \"NOTICE\", "
+
		fprintf(msg->fp, "{ \"type\": \"NOTICE\", "
		    "\"data\": {\"msg\": \"%s\"}}",
-
		    buf_json_escape(buf, ev->e_pkg_notice.msg));
+
		    buf_json_escape(ev->e_pkg_notice.msg));
		break;
	case PKG_EVENT_DEVELOPER_MODE:
-
		utstring_printf(msg, "{ \"type\": \"ERROR\", "
+
		fprintf(msg->fp, "{ \"type\": \"ERROR\", "
		    "\"data\": {\"msg\": \"DEVELOPER_MODE: %s\"}}",
-
		    buf_json_escape(buf, ev->e_pkg_error.msg));
+
		    buf_json_escape(ev->e_pkg_error.msg));
		break;
	case PKG_EVENT_UPDATE_ADD:
-
		utstring_printf(msg, "{ \"type\": \"INFO_UPDATE_ADD\", "
+
		fprintf(msg->fp, "{ \"type\": \"INFO_UPDATE_ADD\", "
		    "\"data\": { "
		    "\"fetched\": %d, "
		    "\"total\": %d"
@@ -102,7 +102,7 @@ pipeevent(struct pkg_event *ev)
		    );
		break;
	case PKG_EVENT_UPDATE_REMOVE:
-
		utstring_printf(msg, "{ \"type\": \"INFO_UPDATE_REMOVE\", "
+
		fprintf(msg->fp, "{ \"type\": \"INFO_UPDATE_REMOVE\", "
		    "\"data\": { "
		    "\"fetched\": %d, "
		    "\"total\": %d"
@@ -112,44 +112,44 @@ pipeevent(struct pkg_event *ev)
		    );
		break;
	case PKG_EVENT_FETCH_BEGIN:
-
		utstring_printf(msg, "{ \"type\": \"INFO_FETCH_BEGIN\", "
+
		fprintf(msg->fp, "{ \"type\": \"INFO_FETCH_BEGIN\", "
		    "\"data\": { "
		    "\"url\": \"%s\" "
		    "}}",
-
		    buf_json_escape(buf, ev->e_fetching.url)
+
		    buf_json_escape(ev->e_fetching.url)
		    );
		break;
	case PKG_EVENT_FETCH_FINISHED:
-
		utstring_printf(msg, "{ \"type\": \"INFO_FETCH_FINISHED\", "
+
		fprintf(msg->fp, "{ \"type\": \"INFO_FETCH_FINISHED\", "
		    "\"data\": { "
		    "\"url\": \"%s\" "
		    "}}",
-
		    buf_json_escape(buf, ev->e_fetching.url)
+
		    buf_json_escape(ev->e_fetching.url)
		    );
		break;
	case PKG_EVENT_INSTALL_BEGIN:
-
		pkg_utstring_printf(msg, "{ \"type\": \"INFO_INSTALL_BEGIN\", "
+
		pkg_fprintf(msg->fp, "{ \"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_utstring_printf(msg, "{ \"type\": \"INFO_EXTRACT_BEGIN\", "
+
		pkg_fprintf(msg->fp, "{ \"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_utstring_printf(msg, "{ \"type\": \"INFO_EXTRACT_FINISHED\", "
+
		pkg_fprintf(msg->fp, "{ \"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_utstring_printf(msg, "{ \"type\": \"INFO_INSTALL_FINISHED\", "
+
		pkg_fprintf(msg->fp, "{ \"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 ?
-
				buf_json_escape(buf, ev->e_install_finished.pkg->message->str) :
+
				buf_json_escape(ev->e_install_finished.pkg->message->str) :
				"");
		break;
	case PKG_EVENT_INTEGRITYCHECK_BEGIN:
-
		utstring_printf(msg, "{ \"type\": \"INFO_INTEGRITYCHECK_BEGIN\", "
+
		fprintf(msg->fp, "{ \"type\": \"INFO_INTEGRITYCHECK_BEGIN\", "
		    "\"data\": {}}");
		break;
	case PKG_EVENT_INTEGRITYCHECK_CONFLICT:
-
		utstring_printf(msg, "{ \"type\": \"INFO_INTEGRITYCHECK_CONFLICT\","
+
		fprintf(msg->fp, "{ \"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) {
-
				utstring_printf(msg, "{\"uid\":\"%s\"},",
+
				fprintf(msg->fp, "{\"uid\":\"%s\"},",
						cur_conflict->uid);
			}
			else {
-
				utstring_printf(msg, "{\"uid\":\"%s\"}",
+
				fprintf(msg->fp, "{\"uid\":\"%s\"}",
						cur_conflict->uid);
				break;
			}
			cur_conflict = cur_conflict->next;
		}
-
		utstring_printf(msg, "%s", "]}}");
+
		fprintf(msg->fp, "%s", "]}}");
		break;
	case PKG_EVENT_INTEGRITYCHECK_FINISHED:
-
		utstring_printf(msg, "{ \"type\": \"INFO_INTEGRITYCHECK_FINISHED\", "
+
		fprintf(msg->fp, "{ \"type\": \"INFO_INTEGRITYCHECK_FINISHED\", "
		    "\"data\": {\"conflicting\": %d}}",
		    ev->e_integrity_finished.conflicting);
		break;
	case PKG_EVENT_DEINSTALL_BEGIN:
-
		pkg_utstring_printf(msg, "{ \"type\": \"INFO_DEINSTALL_BEGIN\", "
+
		pkg_fprintf(msg->fp, "{ \"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_utstring_printf(msg, "{ \"type\": \"INFO_DEINSTALL_FINISHED\", "
+
		pkg_fprintf(msg->fp, "{ \"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_utstring_printf(msg, "{ \"type\": \"INFO_UPGRADE_BEGIN\", "
+
		pkg_fprintf(msg->fp, "{ \"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_utstring_printf(msg, "{ \"type\": \"INFO_UPGRADE_FINISHED\", "
+
		pkg_fprintf(msg->fp, "{ \"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_utstring_printf(msg, "{ \"type\": \"ERROR_LOCKED\", "
+
		pkg_fprintf(msg->fp, "{ \"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_utstring_printf(msg, "{ \"type\": \"ERROR_REQUIRED\", "
+
		pkg_fprintf(msg->fp, "{ \"type\": \"ERROR_REQUIRED\", "
		    "\"data\": { "
		    "\"pkgname\": \"%n\", "
		    "\"pkgversion\": \"%v\", "
@@ -253,15 +253,16 @@ 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)
-
			utstring_printf(msg, "{ \"pkgname\": \"%s\", "
+
			fprintf(msg->fp, "{ \"pkgname\": \"%s\", "
			    "\"pkgversion\": \"%s\" }, ",
			    dep->name, dep->version);
-
		msg->i -= 2;
-
		msg->d[msg->i] = '\0';
-
		utstring_printf(msg, "%s", "]}}");
+
		int c = 0;
+
		ungetc(c, msg->fp);
+
		ungetc(c, msg->fp);
+
		fprintf(msg->fp, "%s", "]}}");
		break;
	case PKG_EVENT_ALREADY_INSTALLED:
-
		pkg_utstring_printf(msg, "{ \"type\": \"ERROR_ALREADY_INSTALLED\", "
+
		pkg_fprintf(msg->fp, "{ \"type\": \"ERROR_ALREADY_INSTALLED\", "
		    "\"data\": { "
		    "\"pkgname\": \"%n\", "
		    "\"pkgversion\": \"%v\""
@@ -270,7 +271,7 @@ pipeevent(struct pkg_event *ev)
		    ev->e_already_installed.pkg);
		break;
	case PKG_EVENT_MISSING_DEP:
-
		utstring_printf(msg, "{ \"type\": \"ERROR_MISSING_DEP\", "
+
		fprintf(msg->fp, "{ \"type\": \"ERROR_MISSING_DEP\", "
		    "\"data\": { "
		    "\"depname\": \"%s\", "
		    "\"depversion\": \"%s\""
@@ -279,22 +280,22 @@ pipeevent(struct pkg_event *ev)
		    ev->e_missing_dep.dep->version);
		break;
	case PKG_EVENT_NOREMOTEDB:
-
		utstring_printf(msg, "{ \"type\": \"ERROR_NOREMOTEDB\", "
+
		fprintf(msg->fp, "{ \"type\": \"ERROR_NOREMOTEDB\", "
		    "\"data\": { "
		    "\"url\": \"%s\" "
		    "}}" ,
		    ev->e_remotedb.repo);
		break;
	case PKG_EVENT_NOLOCALDB:
-
		utstring_printf(msg, "{ \"type\": \"ERROR_NOLOCALDB\", "
+
		fprintf(msg->fp, "{ \"type\": \"ERROR_NOLOCALDB\", "
		    "\"data\": {}} ");
		break;
	case PKG_EVENT_NEWPKGVERSION:
-
		utstring_printf(msg, "{ \"type\": \"INFO_NEWPKGVERSION\", "
+
		fprintf(msg->fp, "{ \"type\": \"INFO_NEWPKGVERSION\", "
		    "\"data\": {}} ");
		break;
	case PKG_EVENT_FILE_MISMATCH:
-
		pkg_utstring_printf(msg, "{ \"type\": \"ERROR_FILE_MISMATCH\", "
+
		pkg_fprintf(msg->fp, "{ \"type\": \"ERROR_FILE_MISMATCH\", "
		    "\"data\": { "
		    "\"pkgname\": \"%n\", "
		    "\"pkgversion\": \"%v\", "
@@ -302,41 +303,41 @@ pipeevent(struct pkg_event *ev)
		    "}}",
		    ev->e_file_mismatch.pkg,
		    ev->e_file_mismatch.pkg,
-
		    buf_json_escape(buf, ev->e_file_mismatch.file->path));
+
		    buf_json_escape(ev->e_file_mismatch.file->path));
		break;
	case PKG_EVENT_PLUGIN_ERRNO:
-
		utstring_printf(msg, "{ \"type\": \"ERROR_PLUGIN\", "
+
		fprintf(msg->fp, "{ \"type\": \"ERROR_PLUGIN\", "
		    "\"data\": {"
		    "\"plugin\": \"%s\", "
		    "\"msg\": \"%s(%s): %s\","
		    "\"errno\": %d"
		    "}}",
		    pkg_plugin_get(ev->e_plugin_errno.plugin, PKG_PLUGIN_NAME),
-
		    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)),
+
		    buf_json_escape(ev->e_plugin_errno.func),
+
		    buf_json_escape(ev->e_plugin_errno.arg),
+
		    buf_json_escape(strerror(ev->e_plugin_errno.no)),
		    ev->e_plugin_errno.no);
		break;
	case PKG_EVENT_PLUGIN_ERROR:
-
		utstring_printf(msg, "{ \"type\": \"ERROR_PLUGIN\", "
+
		fprintf(msg->fp, "{ \"type\": \"ERROR_PLUGIN\", "
		    "\"data\": {"
		    "\"plugin\": \"%s\", "
		    "\"msg\": \"%s\""
		    "}}",
		    pkg_plugin_get(ev->e_plugin_error.plugin, PKG_PLUGIN_NAME),
-
		    buf_json_escape(buf, ev->e_plugin_error.msg));
+
		    buf_json_escape(ev->e_plugin_error.msg));
		break;
	case PKG_EVENT_PLUGIN_INFO:
-
		utstring_printf(msg, "{ \"type\": \"INFO_PLUGIN\", "
+
		fprintf(msg->fp, "{ \"type\": \"INFO_PLUGIN\", "
		    "\"data\": {"
		    "\"plugin\": \"%s\", "
		    "\"msg\": \"%s\""
		    "}}",
		    pkg_plugin_get(ev->e_plugin_info.plugin, PKG_PLUGIN_NAME),
-
		    buf_json_escape(buf, ev->e_plugin_info.msg));
+
		    buf_json_escape(ev->e_plugin_info.msg));
		break;
	case PKG_EVENT_INCREMENTAL_UPDATE:
-
		utstring_printf(msg, "{ \"type\": \"INFO_INCREMENTAL_UPDATE\", "
+
		fprintf(msg->fp, "{ \"type\": \"INFO_INCREMENTAL_UPDATE\", "
		    "\"data\": {"
		        "\"name\": \"%s\", "
			"\"processed\": %d"
@@ -344,7 +345,7 @@ pipeevent(struct pkg_event *ev)
			ev->e_incremental_update.processed);
		break;
	case PKG_EVENT_QUERY_YESNO:
-
		utstring_printf(msg, "{ \"type\": \"QUERY_YESNO\", "
+
		fprintf(msg->fp, "{ \"type\": \"QUERY_YESNO\", "
		    "\"data\": {"
			"\"msg\": \"%s\","
			"\"default\": \"%d\""
@@ -352,7 +353,7 @@ pipeevent(struct pkg_event *ev)
			ev->e_query_yesno.deft);
		break;
	case PKG_EVENT_QUERY_SELECT:
-
		utstring_printf(msg, "{ \"type\": \"QUERY_SELECT\", "
+
		fprintf(msg->fp, "{ \"type\": \"QUERY_SELECT\", "
		    "\"data\": {"
			"\"msg\": \"%s\","
			"\"ncnt\": \"%d\","
@@ -363,18 +364,18 @@ pipeevent(struct pkg_event *ev)
			ev->e_query_select.deft);
		for (i = 0; i < ev->e_query_select.ncnt - 1; i++)
		{
-
			utstring_printf(msg, "{ \"text\": \"%s\" },",
+
			fprintf(msg->fp, "{ \"text\": \"%s\" },",
				ev->e_query_select.items[i]);
		}
-
		utstring_printf(msg, "{ \"text\": \"%s\" } ] }}",
+
		fprintf(msg->fp, "{ \"text\": \"%s\" } ] }}",
			ev->e_query_select.items[i]);
		break;
	case PKG_EVENT_PROGRESS_START:
-
		utstring_printf(msg, "{ \"type\": \"INFO_PROGRESS_START\", "
+
		fprintf(msg->fp, "{ \"type\": \"INFO_PROGRESS_START\", "
		  "\"data\": {}}");
		break;
	case PKG_EVENT_PROGRESS_TICK:
-
		utstring_printf(msg, "{ \"type\": \"INFO_PROGRESS_TICK\", "
+
		fprintf(msg->fp, "{ \"type\": \"INFO_PROGRESS_TICK\", "
		  "\"data\": { \"current\": %jd, \"total\" : %jd}}",
		  (intmax_t)ev->e_progress_tick.current,
		  (intmax_t)ev->e_progress_tick.total);
@@ -385,9 +386,9 @@ pipeevent(struct pkg_event *ev)
	default:
		break;
	}
-
	dprintf(ctx.eventpipe, "%s\n", utstring_body(msg));
-
	utstring_free(msg);
-
	utstring_free(buf);
+
	fflush(msg->fp);
+
	dprintf(ctx.eventpipe, "%s\n", msg->buf);
+
	xstring_free(msg);
}

void
modified libpkg/pkg_jobs.c
@@ -809,23 +809,23 @@ 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;
-
	UT_string *qmsg;
+
	xstring *qmsg = NULL;
	struct pkg_job_universe_item *unit;

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

-
	utstring_new(qmsg);
-

	while (it != NULL && pkgdb_it_next(it, &p, flags) == EPKG_OK) {
+
		xstring_renew(qmsg);
		if (pkg_jobs_has_replacement(j, p->uid)) {
			pkg_debug(1, "replacement %s is already used", p->uid);
			continue;
		}

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


	pkg_free(p);

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

	return (rc);
modified libpkg/pkg_manifest.c
@@ -1315,7 +1315,7 @@ pkg_emit_object(struct pkg *pkg, short flags)


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

@@ -1355,7 +1355,7 @@ static int
pkg_emit_manifest_generic(struct pkg *pkg, void *out, short flags,
	    char **pdigest, bool out_is_a_buf)
{
-
	UT_string *output = NULL;
+
	xstring *output = NULL;
	unsigned char digest[SHA256_BLOCK_SIZE];
	SHA256_CTX *sign_ctx = NULL;
	int rc;
@@ -1371,11 +1371,12 @@ pkg_emit_manifest_generic(struct pkg *pkg, void *out, short flags,

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

+
	fflush(output->fp);
	if (sign_ctx != NULL)
-
		sha256_update(sign_ctx, utstring_body(output), utstring_len(output));
+
		sha256_update(sign_ctx, output->buf, strlen(output->buf));

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

	if (pdigest != NULL) {
		sha256_final(sign_ctx, digest);
@@ -1384,7 +1385,7 @@ pkg_emit_manifest_generic(struct pkg *pkg, void *out, short flags,
	}

	if (!out_is_a_buf)
-
		utstring_free(output);
+
		xstring_free(output);

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

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

	return (pkg_emit_manifest_generic(pkg, b, flags, pdigest, true));
@@ -1406,19 +1407,18 @@ pkg_emit_manifest_buf(struct pkg *pkg, UT_string *b, short flags, char **pdigest
int
pkg_emit_manifest(struct pkg *pkg, char **dest, short flags, char **pdigest)
{
-
	UT_string *b;
+
	xstring *b;
	int rc;

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

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

-
	*dest = xstrdup(utstring_body(b));
-
	utstring_free(b);
+
	*dest = xstring_get(b);

	return (rc);
}
modified libpkg/pkg_ports.c
@@ -185,9 +185,9 @@ setprefix(struct plist *p, char *line, struct file_attr *a __unused)

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

-
	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);
+
	fprintf(p->post_install_buf->fp, "cd %s\n", p->prefix);
+
	fprintf(p->pre_deinstall_buf->fp, "cd %s\n", p->prefix);
+
	fprintf(p->post_deinstall_buf->fp, "cd %s\n", p->prefix);

	return (EPKG_OK);
}
@@ -548,16 +548,16 @@ meta_exec(struct plist *p, char *line, struct file_attr *a, exec_t type)

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

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

@@ -858,16 +858,16 @@ append_script(struct plist *p, pkg_script t, const char *cmd)
{
	switch (t) {
	case PKG_SCRIPT_PRE_INSTALL:
-
		utstring_printf(p->pre_install_buf, "%s\n", cmd);
+
		fprintf(p->pre_install_buf->fp, "%s\n", cmd);
		break;
	case PKG_SCRIPT_POST_INSTALL:
-
		utstring_printf(p->post_install_buf, "%s\n", cmd);
+
		fprintf(p->post_install_buf->fp, "%s\n", cmd);
		break;
	case PKG_SCRIPT_PRE_DEINSTALL:
-
		utstring_printf(p->pre_deinstall_buf, "%s\n", cmd);
+
		fprintf(p->pre_deinstall_buf->fp, "%s\n", cmd);
		break;
	case PKG_SCRIPT_POST_DEINSTALL:
-
		utstring_printf(p->post_deinstall_buf, "%s\n", cmd);
+
		fprintf(p->post_deinstall_buf->fp, "%s\n", cmd);
		break;
	}
}
@@ -1121,10 +1121,11 @@ end:
}

static void
-
flush_script_buffer(UT_string *buf, struct pkg *p, int type)
+
flush_script_buffer(xstring *buf, struct pkg *p, int type)
{
-
	if (utstring_len(buf) > 0) {
-
		pkg_appendscript(p, utstring_body(buf), type);
+
	fflush(buf->fp);
+
	if (buf->buf[0] != '\0') {
+
		pkg_appendscript(p, buf->buf, type);
	}
}

@@ -1207,10 +1208,10 @@ plist_new(struct pkg *pkg, const char *stage)
	p->uname = xstrdup("root");
	p->gname = xstrdup("wheel");

-
	utstring_new(p->pre_install_buf);
-
	utstring_new(p->post_install_buf);
-
	utstring_new(p->pre_deinstall_buf);
-
	utstring_new(p->post_deinstall_buf);
+
	p->pre_install_buf = xstring_new();
+
	p->post_install_buf = xstring_new();
+
	p->pre_deinstall_buf = xstring_new();
+
	p->post_deinstall_buf = xstring_new();
	p->hardlinks = kh_init_hardlinks();

	populate_keywords(p);
@@ -1238,10 +1239,10 @@ plist_free(struct plist *p)
	free(p->post_patterns.patterns);
	kh_destroy_hardlinks(p->hardlinks);

-
	utstring_free(p->post_deinstall_buf);
-
	utstring_free(p->post_install_buf);
-
	utstring_free(p->pre_deinstall_buf);
-
	utstring_free(p->pre_install_buf);
+
	xstring_free(p->post_deinstall_buf);
+
	xstring_free(p->post_install_buf);
+
	xstring_free(p->pre_deinstall_buf);
+
	xstring_free(p->pre_install_buf);

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

	if (pkg_is_installed(db, pkg->name) != EPKG_END) {
@@ -1411,18 +1412,19 @@ 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)
-
			utstring_new(message);
+
			message = xstring_new();
		LL_FOREACH(pkg->message, msg) {
			if (msg->type == PKG_MESSAGE_ALWAYS ||
			    msg->type == PKG_MESSAGE_INSTALL) {
-
				utstring_printf(message, "%s\n", msg->str);
+
				fprintf(message->fp, "%s\n", msg->str);
			}
		}
		if (pkg->message != NULL) {
-
			if (utstring_len(message) > 0) {
-
				pkg_emit_message(utstring_body(message));
+
			fflush(message->fp);
+
			if (message->buf[0] != '\0') {
+
				pkg_emit_message(message->buf);
			}
-
			utstring_free(message);
+
			xstring_free(message);
		}
	}

modified libpkg/pkg_repo_create.c
@@ -329,25 +329,25 @@ pkg_create_repo_worker(struct pkg_fts_item *start, size_t nelts,
	struct pkg_manifest_key *keys = NULL;
	char *mdigest = NULL;
	char digestbuf[1024];
-
	UT_string *b;
+
	xstring *b;
	struct iovec iov[2];
	char buf[1024];
	char *w;

-
	utstring_new(b);
+
	b = xstring_new();

	pid = fork();
	switch(pid) {
	case -1:
		pkg_emit_errno("pkg_create_repo_worker", "fork");
-
		utstring_free(b);
+
		xstring_free(b);
		return (EPKG_FATAL);
		break;
	case 0:
		break;
	default:
		/* Parent */
-
		utstring_free(b);
+
		xstring_free(b);
		return (EPKG_OK);
		break;
	}
@@ -388,7 +388,7 @@ pkg_create_repo_worker(struct pkg_fts_item *start, size_t nelts,
			/*
			 * TODO: use pkg_checksum for new manifests
			 */
-
			utstring_clear(b);
+
			xstring_reset(b);
			mdigest = xmalloc(pkg_checksum_type_size(meta->digest_format));

			pkg_emit_manifest_buf(pkg, b, PKG_MANIFEST_EMIT_COMPACT, NULL);
@@ -403,7 +403,8 @@ pkg_create_repo_worker(struct pkg_fts_item *start, size_t nelts,
					goto cleanup;
				}
			}
-
			mlen = utstring_len(b);
+
			fflush(b->fp);
+
			mlen = strlen(b->buf);

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

			mpos = lseek(mfd, 0, SEEK_END);

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

@@ -466,7 +467,7 @@ pkg_create_repo_worker(struct pkg_fts_item *start, size_t nelts,

cleanup:
	pkg_manifest_keys_free(keys);
-
	utstring_free(b);
+
	xstring_free(b);
	close(pip);
	free(mdigest);

modified libpkg/private/pkg.h
@@ -277,7 +277,7 @@ struct pkg {
	bool		 automatic;
	bool		 vital;
	int64_t		 id;
-
	UT_string	*scripts[PKG_NUM_SCRIPTS];
+
	xstring		*scripts[PKG_NUM_SCRIPTS];
	struct pkg_lua_script	*lua_scripts[PKG_NUM_LUA_SCRIPTS];
	char			*name;
	char			*origin;
@@ -616,10 +616,10 @@ struct plist {
	bool in_include;
	int plistdirfd;
	char prefix[MAXPATHLEN];
-
	UT_string *pre_install_buf;
-
	UT_string *post_install_buf;
-
	UT_string *pre_deinstall_buf;
-
	UT_string *post_deinstall_buf;
+
	xstring *pre_install_buf;
+
	xstring *post_install_buf;
+
	xstring *pre_deinstall_buf;
+
	xstring *post_deinstall_buf;
	struct pkg *pkg;
	char *uname;
	char *gname;
@@ -784,11 +784,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_buf(struct pkg*, UT_string *, short, char **);
+
int pkg_emit_manifest_buf(struct pkg*, xstring *, short, char **);
int pkg_emit_filelist(struct pkg *, FILE *);

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

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

#include "pkg.h"
#include "private/pkg.h"
@@ -53,8 +53,8 @@ extern char **environ;
int
pkg_script_run(struct pkg * const pkg, pkg_script type, bool upgrade)
{
-
	UT_string *script_cmd;
-
	size_t i, j;
+
	xstring *script_cmd = NULL;
+
	size_t i, j, script_len;
	int error, pstat;
	pid_t pid;
	const char *script_cmd_p;
@@ -67,7 +67,6 @@ pkg_script_run(struct pkg * const pkg, pkg_script type, bool upgrade)
	bool use_pipe = 0;
	bool debug = false;
	ssize_t bytes_written;
-
	size_t script_cmd_len;
	long argmax;
	int cur_pipe[2];
#ifdef PROC_REAP_KILL
@@ -94,10 +93,7 @@ pkg_script_run(struct pkg * const pkg, pkg_script type, bool upgrade)
		{"POST-DEINSTALL", PKG_SCRIPT_DEINSTALL, PKG_SCRIPT_POST_DEINSTALL},
	};

-
	utstring_new(script_cmd);
-

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

@@ -116,7 +112,7 @@ pkg_script_run(struct pkg * const pkg, pkg_script type, bool upgrade)
		if (pkg_script_get(pkg, j) == NULL)
			continue;
		if (j == map[i].a || j == map[i].b) {
-
			utstring_clear(script_cmd);
+
			xstring_renew(script_cmd);
			if (upgrade) {
				setenv("PKG_UPGRADE", "true", 1);
			}
@@ -126,16 +122,15 @@ pkg_script_run(struct pkg * const pkg, pkg_script type, bool upgrade)
			setenv("PKG_ROOTDIR", ctx.pkg_rootdir, 1);
			debug = pkg_object_bool(pkg_config_get("DEBUG_SCRIPTS"));
			if (debug)
-
				utstring_printf(script_cmd, "set -x\n");
-
			pkg_utstring_printf(script_cmd, "set -- %n-%v", pkg, pkg);
+
				fprintf(script_cmd->fp, "set -x\n");
+
			pkg_fprintf(script_cmd->fp, "set -- %n-%v", pkg, pkg);

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

-
			utstring_printf(script_cmd, "\n%s",
-
			    utstring_body(pkg->scripts[j]));
+
			fprintf(script_cmd->fp, "\n%s", pkg->scripts[j]->buf);

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

-
			pkg_debug(3, "Scripts: executing\n--- BEGIN ---\n%s\nScripts: --- END ---", utstring_body(script_cmd));
+
			fflush(script_cmd->fp);
+
			script_len = strlen(script_cmd->buf);
+
			pkg_debug(3, "Scripts: executing\n--- BEGIN ---\n%s\nScripts: --- END ---", script_cmd->buf);
			posix_spawn_file_actions_init(&action);
			if (get_socketpair(cur_pipe) == -1) {
				pkg_emit_errno("pkg_script_run", "socketpair");
@@ -167,7 +164,7 @@ pkg_script_run(struct pkg * const pkg, pkg_script type, bool upgrade)
				if (i != cur_pipe[0])
					posix_spawn_file_actions_addclose(&action, i);
			}
-
			if (utstring_len(script_cmd) > argmax) {
+
			if (script_len > argmax) {
				if (pipe(stdin_pipe) < 0) {
					ret = EPKG_FATAL;
					posix_spawn_file_actions_destroy(&action);
@@ -200,7 +197,7 @@ pkg_script_run(struct pkg * const pkg, pkg_script type, bool upgrade)

				argv[0] = _PATH_BSHELL;
				argv[1] = "-c";
-
				argv[2] = utstring_body(script_cmd);
+
				argv[2] = script_cmd->buf;
				argv[3] = NULL;

				use_pipe = 0;
@@ -221,18 +218,17 @@ pkg_script_run(struct pkg * const pkg, pkg_script type, bool upgrade)
			if (fd != -1)
				close(fd);
			if (use_pipe) {
-
				script_cmd_p = utstring_body(script_cmd);
-
				script_cmd_len = utstring_len(script_cmd);
-
				while (script_cmd_len > 0) {
+
				script_cmd_p = script_cmd->buf;
+
				while (script_len > 0) {
					if ((bytes_written = write(stdin_pipe[1], script_cmd_p,
-
					    script_cmd_len)) == -1) {
+
					    script_len)) == -1) {
						if (errno == EINTR)
							continue;
						ret = EPKG_FATAL;
						goto cleanup;
					}
					script_cmd_p += bytes_written;
-
					script_cmd_len -= bytes_written;
+
					script_len -= bytes_written;
				}
				close(stdin_pipe[1]);
			}
@@ -312,7 +308,7 @@ pkg_script_run(struct pkg * const pkg, pkg_script type, bool upgrade)
cleanup:

	free(line);
-
	utstring_free(script_cmd);
+
	xstring_free(script_cmd);
	if (stdin_pipe[0] != -1)
		close(stdin_pipe[0]);
	if (stdin_pipe[1] != -1)
modified libpkg/utils.c
@@ -553,11 +553,11 @@ ucl_file_append_double(double val, void *data)
static int
ucl_buf_append_character(unsigned char c, size_t len, void *data)
{
-
	UT_string *buf = data;
+
	xstring *buf = data;
	size_t i;

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

	return (0);
}
@@ -565,9 +565,9 @@ ucl_buf_append_character(unsigned char c, size_t len, void *data)
static int
ucl_buf_append_len(const unsigned char *str, size_t len, void *data)
{
-
	UT_string *buf = data;
+
	xstring *buf = data;

-
	utstring_bincpy(buf, str, len);
+
	fprintf(buf->fp, "%.*s", len, str);

	return (0);
}
@@ -575,9 +575,9 @@ ucl_buf_append_len(const unsigned char *str, size_t len, void *data)
static int
ucl_buf_append_int(int64_t val, void *data)
{
-
	UT_string *buf = data;
+
	xstring *buf = data;

-
	utstring_printf(buf, "%"PRId64, val);
+
	fprintf(buf->fp, "%"PRId64, val);

	return (0);
}
@@ -585,15 +585,15 @@ ucl_buf_append_int(int64_t val, void *data)
static int
ucl_buf_append_double(double val, void *data)
{
-
	UT_string *buf = data;
+
	xstring *buf = data;
	const double delta = 0.0000001;

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

	return (0);
@@ -620,7 +620,7 @@ ucl_object_emit_file(const ucl_object_t *obj, enum ucl_emitter emit_type,

bool
ucl_object_emit_buf(const ucl_object_t *obj, enum ucl_emitter emit_type,
-
                     UT_string **buf)
+
                     xstring **buf)
{
	bool ret = false;
	struct ucl_emitter_functions func = {
@@ -630,10 +630,7 @@ ucl_object_emit_buf(const ucl_object_t *obj, enum ucl_emitter emit_type,
		.ucl_emitter_append_double = ucl_buf_append_double
	};

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

	func.ud = *buf;

modified libpkg/xmalloc.h
@@ -1,7 +1,9 @@
#ifndef XMALLOC_H
#define XMALLOC_H

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

static inline void *xmalloc(size_t size)
{
added libpkg/xstring.h
@@ -0,0 +1,67 @@
+
#ifndef __XSTRING_H_
+
#define __XSTRING_H_
+

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

+
struct xstring {
+
	char* buf;
+
	size_t size;
+
	FILE* fp;
+
};
+

+
typedef struct xstring xstring;
+

+
static inline xstring *
+
xstring_new(void)
+
{
+
	xstring *str;
+

+
	str = calloc(1, sizeof(*str));
+
	if (str == NULL)
+
		abort();
+
	str->fp = open_memstream(&str->buf, &str->size);
+
	if (str->fp == NULL)
+
		abort();
+

+
	return (str);
+
}
+

+
static inline void
+
xstring_reset(xstring *str)
+
{
+
	memset(str->buf, 0, str->size);
+
	rewind(str->fp);
+

+
}
+

+
static inline void
+
xstring_free(xstring *str)
+
{
+
	if (str == NULL)
+
		return;
+
	fclose(str->fp);
+
	free(str->buf);
+
	free(str);
+
}
+

+
#define xstring_renew(s)      \
+
do {                          \
+
   if (s) {                   \
+
     xstring_reset(s);        \
+
   } else {                   \
+
     s = xstring_new();       \
+
   }                          \
+
} while(0)
+

+
static inline char *
+
xstring_get(xstring *str)
+
{
+
	char *ret = str->buf;
+
	fclose(str->fp);
+
	free(str);
+
	return (ret);
+
}
+

+
#endif
modified src/add.c
@@ -36,7 +36,7 @@
#include <sysexits.h>
#include <unistd.h>
#include <getopt.h>
-
#include <utstring.h>
+
#include <xstring.h>

#include <pkg.h>

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

-
	utstring_new(failedpkgs);
+
	failedpkgs = xstring_new();
	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);
-
				utstring_printf(failedpkgs, "%s", argv[i]);
+
				fprintf(failedpkgs->fp, "%s", argv[i]);
				if (i != argc - 1)
-
					utstring_printf(failedpkgs, ", ");
+
					fprintf(failedpkgs->fp, ", ");
				failedpkgcount++;
				continue;
			}
@@ -174,9 +174,9 @@ exec_add(int argc, char **argv)
		}

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

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

	if (messages != NULL) {
-
		printf("%s", utstring_body(messages));
+
		fflush(messages->fp);
+
		printf("%s", messages->buf);
	}

	return (retcode == EPKG_OK ? EX_OK : EX_SOFTWARE);
modified src/audit.c
@@ -45,7 +45,7 @@
#include <unistd.h>
#include <sysexits.h>
#include <khash.h>
-
#include <utstring.h>
+
#include <xstring.h>

#ifdef HAVE_SYS_CAPSICUM_H
#include <sys/capsicum.h>
@@ -82,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, UT_string *sb,
+
print_recursive_rdeps(kh_pkgs_t *head, struct pkg *p, xstring *sb,
    kh_pkgs_t *seen, bool top)
{
	struct pkg_dep *dep = NULL;
@@ -101,9 +101,9 @@ print_recursive_rdeps(kh_pkgs_t *head, struct pkg *p, UT_string *sb,

		kh_put_pkgs(seen, name, &ret);
		if (!top)
-
			utstring_printf(sb, ", ");
+
			fprintf(sb->fp, ", ");

-
		utstring_printf(sb, "%s", name);
+
		fprintf(sb->fp, "%s", name);

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

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

	struct option longopts[] = {
@@ -279,21 +279,24 @@ exec_audit(int argc, char **argv)
		kh_foreach_value(check, pkg, {
			if (pkg_audit_is_vulnerable(audit, pkg, quiet, &sb, &affected)) {
				vuln ++;
-
				printf("%s", utstring_body(sb));
+
				fflush(sb->fp);
+
				printf("%s", sb->buf);

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

					pkg_get(pkg, PKG_NAME, &name);
-
					utstring_clear(sb);
-
					utstring_printf(sb, "Packages that depend on %s: ", name);
+
					xstring_reset(sb);
+
					printf("Packages that depend on %s: ", name);
+
					fprintf(sb->fp, "Packages that depend on %s: ", name);
+
					fflush(sb->fp);
					print_recursive_rdeps(check, pkg , sb, seen, true);
-
					printf("%s\n\n", utstring_body(sb));
+
					printf("%s\n\n", sb->buf);

					kh_destroy_pkgs(seen);
				}
-
				utstring_free(sb);
+
				xstring_free(sb);
			}
			pkg_free(pkg);
		});
modified src/check.c
@@ -53,14 +53,14 @@ struct deps_entry {
};

static int check_deps(struct pkgdb *db, struct pkg *pkg, struct deps_entry **dh,
-
    bool noinstall, UT_string *out);
+
    bool noinstall, xstring *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, UT_string *out)
+
check_deps(struct pkgdb *db, struct pkg *p, struct deps_entry **dh, bool noinstall, xstring *out)
{
	struct pkg_dep *dep = NULL;
	struct pkgdb_it *it;
@@ -74,9 +74,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_utstring_printf(out, "%n\t%sn\n", p, dep);
+
				pkg_fprintf(out->fp, "%n\t%sn\n", p, dep);
			else
-
				pkg_utstring_printf(out, "%n has a missing dependency: %dn\n",
+
				pkg_fprintf(out->fp, "%n has a missing dependency: %dn\n",
				    p, dep);
			if (!noinstall)
				add_missing_dep(dep, dh, &nbpkgs);
@@ -93,9 +93,9 @@ check_deps(struct pkgdb *db, struct pkg *p, struct deps_entry **dh, bool noinsta
		}
		pkgdb_it_free(it);
		if (quiet)
-
			pkg_utstring_printf(out, "%n\t%S\n", p, buf);
+
			pkg_fprintf(out->fp, "%n\t%S\n", p, buf);
		else
-
			pkg_utstring_printf(out, "%n is missing a required shared library: %S\n",
+
			pkg_fprintf(out->fp, "%n is missing a required shared library: %S\n",
			    p, buf);
	}

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

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

		if (msg == NULL)
-
			utstring_new(msg);
+
			msg = xstring_new();
		if (!verbose) {
			if (!quiet) {
				if (match == MATCH_ALL)
					progressbar_start("Checking all packages");
				else {
-
					utstring_printf(msg, "Checking %s", argv[i]);
-
					progressbar_start(utstring_body(msg));
+
					fprintf(msg->fp, "Checking %s", argv[i]);
+
					fflush(msg->fp);
+
					progressbar_start(msg->buf);
				}
			}
			processed = 0;
			total = pkgdb_it_count(it);
		}

-
		UT_string *out;
-
		utstring_new(out);
+
		xstring *out = xstring_new();
		while (pkgdb_it_next(it, &pkg, flags) == EPKG_OK) {
			if (!quiet) {
				if (!verbose)
@@ -446,9 +446,11 @@ exec_check(int argc, char **argv)
				else {
					++nbdone;
					job_status_begin(msg);
-
					pkg_utstring_printf(msg, "Checking %n-%v:",
+
					pkg_fprintf(msg->fp, "Checking %n-%v:",
					    pkg, pkg);
-
					utstring_flush(msg);
+
					fflush(msg->fp);
+
					printf("%s", msg->buf);
+
					xstring_reset(msg);
				}
			}

@@ -513,14 +515,13 @@ exec_check(int argc, char **argv)
		}
		if (!quiet && !verbose)
			progressbar_tick(processed, total);
-
		if (utstring_len(out) > 0) {
-
			printf("%s", utstring_body(out));
-
		}
-
		utstring_free(out);
-
		if (msg != NULL) {
-
			utstring_free(msg);
-
			msg = NULL;
+
		fflush(out->fp);
+
		if (out->buf[0] != '\0') {
+
			printf("%s", out->buf);
		}
+
		xstring_free(out);
+
		xstring_free(msg);
+
		msg = NULL;

		if (dcheck && nbpkgs > 0 && !noinstall) {
			printf("\n>>> Missing package dependencies were detected.\n");
@@ -551,8 +552,7 @@ exec_check(int argc, char **argv)
cleanup:
	if (!verbose)
		progressbar_stop();
-
	if (msg != NULL)
-
		utstring_free(msg);
+
	xstring_free(msg);
	deps_free(dh);
	pkg_free(pkg);
	pkgdb_release_lock(db, PKGDB_LOCK_ADVISORY);
modified src/delete.c
@@ -241,7 +241,8 @@ exec_delete(int argc, char **argv)
		goto cleanup;

	if (messages != NULL) {
-
		printf("%s", utstring_body(messages));
+
		fflush(messages->fp);
+
		printf("%s", messages->buf);
	}
	pkgdb_compact(db);

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

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

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

#define STALL_TIME 5

-
UT_string *messages = NULL;
-
UT_string *conflicts = NULL;
+
xstring *messages = NULL;
+
xstring *conflicts = NULL;

struct cleanup {
	void *data;
@@ -73,7 +72,7 @@ struct cleanup {
};

static char *progress_message = NULL;
-
static UT_string *msg_buf = NULL;
+
static xstring *msg_buf = NULL;
static int last_progress_percent = -1;
static bool progress_started = false;
static bool progress_interrupted = false;
@@ -128,19 +127,19 @@ format_rate_SI(char *buf, int size, off_t bytes)
}

void
-
job_status_end(UT_string *msg)
+
job_status_end(xstring *msg)
{
-
	printf("%s\n", utstring_body(msg));
-
	/*printf("\033]0; %s\007", utstring_body(msg));*/
-
	utstring_clear(msg);
+
	fflush(msg->fp);
+
	printf("%s\n", msg->buf);
+
	xstring_reset(msg);
}

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

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

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

@@ -166,16 +165,16 @@ job_status_begin(UT_string *msg)
		if (add_deps_depth > 1) {
			for (n = 0; n < (2 * add_deps_depth); ++n) {
				if (n % 4 == 0 && n < (2 * add_deps_depth))
-
					utstring_printf(msg, "|");
+
					fprintf(msg->fp, "|");
				else
-
					utstring_printf(msg, " ");
+
					fprintf(msg->fp, " ");
			}
		}
-
		utstring_printf(msg, "`-- ");
+
		fprintf(msg->fp, "`-- ");
	}

	if ((nbtodl > 0 || nbactions > 0) && nbdone > 0)
-
		utstring_printf(msg, "[%d/%d] ", nbdone, (nbtodl) ? nbtodl : nbactions);
+
		fprintf(msg->fp, "[%d/%d] ", nbdone, (nbtodl) ? nbtodl : nbactions);
	if (nbtodl > 0 && nbtodl == nbdone) {
		nbtodl = 0;
		nbdone = 0;
@@ -358,7 +357,8 @@ progressbar_start(const char *pmsg)
	if (pmsg != NULL)
		progress_message = strdup(pmsg);
	else {
-
		progress_message = strdup(utstring_body(msg_buf));
+
		fflush(msg_buf->fp);
+
		progress_message = strdup(msg_buf->buf);
	}
	last_progress_percent = -1;
	last_tick = 0;
@@ -541,7 +541,7 @@ event_callback(void *data, struct pkg_event *ev)
	const char *filename, *reponame;

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

	/*
@@ -600,7 +600,7 @@ event_callback(void *data, struct pkg_event *ev)
		}
		job_status_begin(msg_buf);
		progress_debit = true;
-
		utstring_printf(msg_buf, "Fetching %s", filename);
+
		fprintf(msg_buf->fp, "Fetching %s", filename);
		break;
	case PKG_EVENT_FETCH_FINISHED:
		progress_debit = false;
@@ -611,9 +611,10 @@ event_callback(void *data, struct pkg_event *ev)
		job_status_begin(msg_buf);

		pkg = ev->e_install_begin.pkg;
-
		pkg_utstring_printf(msg_buf, "Installing %n-%v...\n", pkg,
+
		pkg_fprintf(msg_buf->fp, "Installing %n-%v...\n", pkg,
		    pkg);
-
		printf("%s", utstring_body(msg_buf));
+
		fflush(msg_buf->fp);
+
		printf("%s", msg_buf->buf);
		break;
	case PKG_EVENT_INSTALL_FINISHED:
		if (quiet)
@@ -625,7 +626,8 @@ event_callback(void *data, struct pkg_event *ev)
		else {
			job_status_begin(msg_buf);
			pkg = ev->e_install_begin.pkg;
-
			pkg_utstring_printf(msg_buf, "Extracting %n-%v", pkg, pkg);
+
			pkg_fprintf(msg_buf->fp, "Extracting %n-%v", pkg, pkg);
+
			fflush(msg_buf->fp);
		}
		break;
	case PKG_EVENT_EXTRACT_FINISHED:
@@ -646,7 +648,9 @@ event_callback(void *data, struct pkg_event *ev)
			break;
		printf(" done (%d conflicting)\n", ev->e_integrity_finished.conflicting);
		if (conflicts != NULL) {
-
			printf("%s", utstring_body(conflicts));
+
			fflush(conflicts->fp);
+
			printf("%s", conflicts->buf);
+
			xstring_free(conflicts);
			conflicts = NULL;
		}
		break;
@@ -674,8 +678,9 @@ event_callback(void *data, struct pkg_event *ev)
		job_status_begin(msg_buf);

		pkg = ev->e_install_begin.pkg;
-
		pkg_utstring_printf(msg_buf, "Deinstalling %n-%v...\n", pkg, pkg);
-
		printf("%s", utstring_body(msg_buf));
+
		pkg_fprintf(msg_buf->fp, "Deinstalling %n-%v...\n", pkg, pkg);
+
		fflush(msg_buf->fp);
+
		printf("%s", msg_buf->buf);
		break;
	case PKG_EVENT_DEINSTALL_FINISHED:
		if (quiet)
@@ -687,7 +692,7 @@ event_callback(void *data, struct pkg_event *ev)
		else {
			job_status_begin(msg_buf);
			pkg = ev->e_install_begin.pkg;
-
			pkg_utstring_printf(msg_buf, "Deleting files for %n-%v",
+
			pkg_fprintf(msg_buf->fp, "Deleting files for %n-%v",
			    pkg, pkg);
		}
		break;
@@ -703,19 +708,20 @@ event_callback(void *data, struct pkg_event *ev)

		switch (pkg_version_change_between(pkg_new, pkg_old)) {
		case PKG_DOWNGRADE:
-
			pkg_utstring_printf(msg_buf, "Downgrading %n from %v to %v...\n",
+
			pkg_fprintf(msg_buf->fp, "Downgrading %n from %v to %v...\n",
			    pkg_new, pkg_old, pkg_new);
			break;
		case PKG_REINSTALL:
-
			pkg_utstring_printf(msg_buf, "Reinstalling %n-%v...\n",
+
			pkg_fprintf(msg_buf->fp, "Reinstalling %n-%v...\n",
		    pkg_old, pkg_old);
			break;
		case PKG_UPGRADE:
-
			pkg_utstring_printf(msg_buf, "Upgrading %n from %v to %v...\n",
+
			pkg_fprintf(msg_buf->fp, "Upgrading %n from %v to %v...\n",
			    pkg_new, pkg_old, pkg_new);
			break;
		}
-
		printf("%s", utstring_body(msg_buf));
+
		fflush(msg_buf->fp);
+
		printf("%s", msg_buf->buf);
		break;
	case PKG_EVENT_UPGRADE_FINISHED:
		if (quiet)
@@ -827,18 +833,18 @@ event_callback(void *data, struct pkg_event *ev)
		    ev->e_progress_tick.total);
		break;
	case PKG_EVENT_BACKUP:
-
		utstring_printf(msg_buf, "Backing up");
+
		fprintf(msg_buf->fp, "Backing up");
		break;
	case PKG_EVENT_RESTORE:
-
		utstring_printf(msg_buf, "Restoring");
+
		fprintf(msg_buf->fp, "Restoring");
		break;
	case PKG_EVENT_NEW_ACTION:
		nbdone++;
		break;
	case PKG_EVENT_MESSAGE:
		if (messages == NULL)
-
			utstring_new(messages);
-
		utstring_printf(messages, "%s", ev->e_pkg_message.msg);
+
			messages = xstring_new();
+
		fprintf(messages->fp, "%s", ev->e_pkg_message.msg);
		break;
	case PKG_EVENT_CLEANUP_CALLBACK_REGISTER:
		if (!signal_handler_installed) {
@@ -865,23 +871,23 @@ event_callback(void *data, struct pkg_event *ev)
		break;
	case PKG_EVENT_CONFLICTS:
		if (conflicts == NULL) {
-
			utstring_new(conflicts);
+
			conflicts = xstring_new();
		}
-
		pkg_utstring_printf(conflicts, "  - %n-%v",
+
		pkg_fprintf(conflicts->fp, "  - %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);
-
			utstring_printf(conflicts, " [%s]",
+
			fprintf(conflicts->fp, " [%s]",
			    reponame == NULL ? "installed" : reponame);
		}
-
		pkg_utstring_printf(conflicts, " conflicts with %n-%v",
+
		pkg_fprintf(conflicts->fp, " 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);
-
			utstring_printf(conflicts, " [%s]",
+
			fprintf(conflicts->fp, " [%s]",
			    reponame == NULL ? "installed" : reponame);
		}
-
		utstring_printf(conflicts, " on %s\n",
+
		fprintf(conflicts->fp, " on %s\n",
		    ev->e_conflicts.path);
		break;
	default:
modified src/install.c
@@ -254,7 +254,8 @@ exec_install(int argc, char **argv)
		}

		if (messages != NULL) {
-
			printf("%s", utstring_body(messages));
+
			fflush(messages->fp);
+
			printf("%s", messages->buf);
		}
		break;
	}
modified src/pkgcli.h
@@ -30,7 +30,7 @@

#include <search.h>
#include <stdint.h>
-
#include <utstring.h>
+
#include <string.h>
#include <bsd_compat.h>

#define pkg_warnx(fmt, ...) pkg_fprintf(stderr, "%S: " fmt, getprogname(), __VA_ARGS__, -1)
@@ -265,8 +265,8 @@ 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(UT_string *);
-
void job_status_end(UT_string *);
+
void job_status_begin(xstring *);
+
void job_status_end(xstring *);

int event_callback(void *data, struct pkg_event *ev);
int print_pkg(struct pkg *p, void *ctx);
@@ -274,10 +274,9 @@ void progressbar_start(const char *pmsg);
void progressbar_tick(int64_t current, int64_t total);
void progressbar_stop(void);

-
void utstring_flush(UT_string *buf);
void drop_privileges(void);

-
extern UT_string *messages;
+
extern xstring *messages;


/* pkg-query / pkg-rquery */
@@ -289,7 +288,7 @@ struct query_flags {
};

void print_query(struct pkg *pkg, char *qstr, char multiline);
-
int format_sql_condition(const char *str, UT_string *sqlcond,
+
int format_sql_condition(const char *str, xstring *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
@@ -80,101 +80,101 @@ static struct query_flags accepted_query_flags[] = {
};

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

-
	utstring_clear(dest);
+
	xstring_reset(dest);

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

void
print_query(struct pkg *pkg, char *qstr, char multiline)
{
-
	UT_string		*output;
+
	xstring			*output;
	struct pkg_dep		*dep    = NULL;
	struct pkg_option	*option = NULL;
	struct pkg_file		*file   = NULL;
@@ -350,95 +351,95 @@ print_query(struct pkg *pkg, char *qstr, char multiline)
	char			*buf;
	struct pkg_kv		*kv;

-
	utstring_new(output);
+
	output = xstring_new();

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

typedef enum {
@@ -455,82 +456,82 @@ typedef enum {
} state_t;

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

-
	utstring_printf(sqlcond, " WHERE ");
+
	fprintf(sqlcond->fp, " WHERE ");
	while (str[0] != '\0') {
		if (state == NONE) {
			if (str[0] == '%') {
				str++;
				switch (str[0]) {
				case 'n':
-
					utstring_printf(sqlcond, "name");
+
					fprintf(sqlcond->fp, "name");
					state = OPERATOR_STRING;
					break;
				case 'o':
-
					utstring_printf(sqlcond, "origin");
+
					fprintf(sqlcond->fp, "origin");
					state = OPERATOR_STRING;
					break;
				case 'p':
-
					utstring_printf(sqlcond, "prefix");
+
					fprintf(sqlcond->fp, "prefix");
					state = OPERATOR_STRING;
					break;
				case 'm':
-
					utstring_printf(sqlcond, "maintainer");
+
					fprintf(sqlcond->fp, "maintainer");
					state = OPERATOR_STRING;
					break;
				case 'c':
-
					utstring_printf(sqlcond, "comment");
+
					fprintf(sqlcond->fp, "comment");
					state = OPERATOR_STRING;
					break;
				case 'w':
-
					utstring_printf(sqlcond, "www");
+
					fprintf(sqlcond->fp, "www");
					state = OPERATOR_STRING;
					break;
				case 's':
-
					utstring_printf(sqlcond, "flatsize");
+
					fprintf(sqlcond->fp, "flatsize");
					state = OPERATOR_INT;
					break;
				case 'a':
					if (for_remote)
						goto bad_option;
-
					utstring_printf(sqlcond, "automatic");
+
					fprintf(sqlcond->fp, "automatic");
					state = OPERATOR_INT;
					break;
				case 'q':
-
					utstring_printf(sqlcond, "arch");
+
					fprintf(sqlcond->fp, "arch");
					state = OPERATOR_STRING;
					break;
				case 'k':
					if (for_remote)
						goto bad_option;
-
					utstring_printf(sqlcond, "locked");
+
					fprintf(sqlcond->fp, "locked");
					state = OPERATOR_INT;
					break;
				case 'M':
					if (for_remote)
						goto bad_option;
-
					utstring_printf(sqlcond, "message");
+
					fprintf(sqlcond->fp, "message");
					state = OPERATOR_STRING;
					break;
				case 't':
					if (for_remote)
						goto bad_option;
-
					utstring_printf(sqlcond, "time");
+
					fprintf(sqlcond->fp, "time");
					state = OPERATOR_INT;
					break;
				case 'e':
-
					utstring_printf(sqlcond, "desc");
+
					fprintf(sqlcond->fp, "desc");
					state = OPERATOR_STRING;
					break;
				case 'V':
					if (for_remote)
						goto bad_option;
-
					utstring_printf(sqlcond, "vital");
+
					fprintf(sqlcond->fp, "vital");
					state = OPERATOR_INT;
					break;
				case '#': /* FALLTHROUGH */
@@ -539,48 +540,48 @@ format_sql_condition(const char *str, UT_string *sqlcond, bool for_remote)
					str++;
					switch (str[0]) {
						case 'd':
-
							utstring_printf(sqlcond, "(SELECT %s FROM deps AS d WHERE d.package_id=p.id)", sqlop);
+
							fprintf(sqlcond->fp, "(SELECT %s FROM deps AS d WHERE d.package_id=p.id)", sqlop);
							break;
						case 'r':
-
							utstring_printf(sqlcond, "(SELECT %s FROM deps AS d WHERE d.origin=p.origin)", sqlop);
+
							fprintf(sqlcond->fp, "(SELECT %s FROM deps AS d WHERE d.origin=p.origin)", sqlop);
							break;
						case 'C':
-
							utstring_printf(sqlcond, "(SELECT %s FROM pkg_categories AS d WHERE d.package_id=p.id)", sqlop);
+
							fprintf(sqlcond->fp, "(SELECT %s FROM pkg_categories AS d WHERE d.package_id=p.id)", sqlop);
							break;
						case 'F':
							if (for_remote)
								goto bad_option;
-
							utstring_printf(sqlcond, "(SELECT %s FROM files AS d WHERE d.package_id=p.id)", sqlop);
+
							fprintf(sqlcond->fp, "(SELECT %s FROM files AS d WHERE d.package_id=p.id)", sqlop);
							break;
						case 'O':
-
							utstring_printf(sqlcond, "(SELECT %s FROM pkg_option AS d WHERE d.package_id=p.id)", sqlop);
+
							fprintf(sqlcond->fp, "(SELECT %s FROM pkg_option AS d WHERE d.package_id=p.id)", sqlop);
							break;
						case 'D':
							if (for_remote)
								goto bad_option;
-
							utstring_printf(sqlcond, "(SELECT %s FROM pkg_directories AS d WHERE d.package_id=p.id)", sqlop);
+
							fprintf(sqlcond->fp, "(SELECT %s FROM pkg_directories AS d WHERE d.package_id=p.id)", sqlop);
							break;
						case 'L':
-
							utstring_printf(sqlcond, "(SELECT %s FROM pkg_licenses AS d WHERE d.package_id=p.id)", sqlop);
+
							fprintf(sqlcond->fp, "(SELECT %s FROM pkg_licenses AS d WHERE d.package_id=p.id)", sqlop);
							break;
						case 'U':
							if (for_remote)
								goto bad_option;
-
							utstring_printf(sqlcond, "(SELECT %s FROM pkg_users AS d WHERE d.package_id=p.id)", sqlop);
+
							fprintf(sqlcond->fp, "(SELECT %s FROM pkg_users AS d WHERE d.package_id=p.id)", sqlop);
							break;
						case 'G':
							if (for_remote)
								goto bad_option;
-
							utstring_printf(sqlcond, "(SELECT %s FROM pkg_groups AS d WHERE d.package_id=p.id)", sqlop);
+
							fprintf(sqlcond->fp, "(SELECT %s FROM pkg_groups AS d WHERE d.package_id=p.id)", sqlop);
							break;
						case 'B':
-
							utstring_printf(sqlcond, "(SELECT %s FROM pkg_shlibs_required AS d WHERE d.package_id=p.id)", sqlop);
+
							fprintf(sqlcond->fp, "(SELECT %s FROM pkg_shlibs_required AS d WHERE d.package_id=p.id)", sqlop);
							break;
						case 'b':
-
							utstring_printf(sqlcond, "(SELECT %s FROM pkg_shlibs_provided AS d WHERE d.package_id=p.id)", sqlop);
+
							fprintf(sqlcond->fp, "(SELECT %s FROM pkg_shlibs_provided AS d WHERE d.package_id=p.id)", sqlop);
							break;
						case 'A':
-
							utstring_printf(sqlcond, "(SELECT %s FROM pkg_annotation AS d WHERE d.package_id=p.id)", sqlop);
+
							fprintf(sqlcond->fp, "(SELECT %s FROM pkg_annotation AS d WHERE d.package_id=p.id)", sqlop);
							break;
						default:
							goto bad_option;
@@ -596,7 +597,7 @@ bad_option:
				switch (str[0]) {
				case '(':
					bracket_level++;
-
					utstring_printf(sqlcond, "%c", str[0]);
+
					fprintf(sqlcond->fp, "%c", str[0]);
					break;
				case ' ':
				case '\t':
@@ -614,7 +615,7 @@ bad_option:
					return (EPKG_FATAL);
				}
				bracket_level--;
-
				utstring_printf(sqlcond, "%c", str[0]);
+
				fprintf(sqlcond->fp, "%c", str[0]);
				break;
			case ' ':
			case '\t':
@@ -623,7 +624,7 @@ bad_option:
				if (str[1] == '|') {
					str++;
					state = NONE;
-
					utstring_printf(sqlcond, " OR ");
+
					fprintf(sqlcond->fp, " OR ");
					break;
				} else {
					fprintf(stderr, "unexpected character %c\n", str[1]);
@@ -633,7 +634,7 @@ bad_option:
				if (str[1] == '&') {
					str++;
					state = NONE;
-
					utstring_printf(sqlcond, " AND ");
+
					fprintf(sqlcond->fp, " AND ");
					break;
				} else {
					fprintf(stderr, "unexpected character %c\n", str[1]);
@@ -653,17 +654,17 @@ bad_option:
					return (EPKG_FATAL);
				}
				state = NEXT_IS_STRING;
-
				utstring_printf(sqlcond, " GLOB ");
+
				fprintf(sqlcond->fp, " 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;
-
				utstring_printf(sqlcond, "%c", str[0]);
+
				fprintf(sqlcond->fp, "%c", str[0]);
				if (str[1] == '=') {
					str++;
-
					utstring_printf(sqlcond, "%c", str[0]);
+
					fprintf(sqlcond->fp, "%c", str[0]);
				}
			} else if (str[0] == '=') {
				if (state == OPERATOR_STRING) {
@@ -671,17 +672,17 @@ bad_option:
				} else {
					state = NEXT_IS_INT;
				}
-
				utstring_printf(sqlcond, "%c", str[0]);
+
				fprintf(sqlcond->fp, "%c", str[0]);
				if (str[1] == '=') {
					str++;
-
					utstring_printf(sqlcond, "%c", str[0]);
+
					fprintf(sqlcond->fp, "%c", str[0]);
				}
			} else if (str[0] == '!') {
				if (str[1] == '=') {
-
					utstring_printf(sqlcond, "%c", str[0]);
-
					utstring_printf(sqlcond, "%c", str[1]);
+
					fprintf(sqlcond->fp, "%c", str[0]);
+
					fprintf(sqlcond->fp, "%c", str[1]);
				} else if (str[1] == '~') {
-
					utstring_printf(sqlcond, " NOT GLOB ");
+
					fprintf(sqlcond->fp, " NOT GLOB ");
				} else {
					fprintf(stderr, "expecting = or ~ after !\n");
					return (EPKG_FATAL);
@@ -709,14 +710,14 @@ bad_option:
						state = STRING;
						str--;
					}
-
					utstring_printf(sqlcond, "%c", '\'');
+
					fprintf(sqlcond->fp, "%c", '\'');
				} else {
					if (!isdigit(str[0])) {
						fprintf(stderr, "a number is expected, got: %c\n", str[0]);
						return (EPKG_FATAL);
					}
					state = INT;
-
					utstring_printf(sqlcond, "%c", str[0]);
+
					fprintf(sqlcond->fp, "%c", str[0]);
				}
			}
		} else if (state == INT) {
@@ -724,26 +725,26 @@ bad_option:
				state = POST_EXPR;
				str--;
			} else {
-
				utstring_printf(sqlcond, "%c", str[0]);
+
				fprintf(sqlcond->fp, "%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] == '\'')) {
-
				utstring_printf(sqlcond, "%c", '\'');
+
				fprintf(sqlcond->fp, "%c", '\'');
				state = POST_EXPR;
			} else {
-
				utstring_printf(sqlcond, "%c", str[0]);
+
				fprintf(sqlcond->fp, "%c", str[0]);
				if (str[0] == '\'')
-
					utstring_printf(sqlcond, "%c", str[0]);
+
					fprintf(sqlcond->fp, "%c", str[0]);
				else if (str[0] == '%' && for_remote)
-
					utstring_printf(sqlcond, "%c", str[0]);
+
					fprintf(sqlcond->fp, "%c", str[0]);
			}
		}
		str++;
	}
	if (state == STRING) {
-
		utstring_printf(sqlcond, "%c", '\'');
+
		fprintf(sqlcond->fp, "%c", '\'');
		state = POST_EXPR;
	}

@@ -871,7 +872,7 @@ exec_query(int argc, char **argv)
	int			 i;
	char			 multiline = 0;
	char			*condition = NULL;
-
	UT_string		*sqlcond = NULL;
+
	xstring			*sqlcond = NULL;
	const unsigned int	 q_flags_len = NELEM(accepted_query_flags);

	struct option longopts[] = {
@@ -949,9 +950,9 @@ exec_query(int argc, char **argv)
	}

	if (condition != NULL) {
-
		utstring_new(sqlcond);
+
		sqlcond = xstring_new();
		if (format_sql_condition(condition, sqlcond, false) != EPKG_OK) {
-
			utstring_free(sqlcond);
+
			xstring_free(sqlcond);
			return (EX_USAGE);
		}
	}
@@ -980,8 +981,10 @@ 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 = utstring_body(sqlcond);
+
		if (match == MATCH_CONDITION && sqlcond) {
+
			fflush(sqlcond->fp);
+
			condition_sql = sqlcond->buf;
+
		}
		if ((it = pkgdb_query(db, condition_sql, match)) == NULL)
			return (EX_IOERR);

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

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

	pkg_free(pkg);
modified src/rquery.c
@@ -117,7 +117,7 @@ exec_rquery(int argc, char **argv)
	char			 multiline = 0;
	char			*condition = NULL;
	const char		*portsdir;
-
	UT_string		*sqlcond = NULL;
+
	xstring			*sqlcond = NULL;
	const unsigned int	 q_flags_len = NELEM(accepted_rquery_flags);
	const char		*reponame = NULL;
	bool			 onematched = false;
@@ -200,9 +200,9 @@ exec_rquery(int argc, char **argv)
		return (EX_USAGE);

	if (condition != NULL) {
-
		utstring_new(sqlcond);
+
		sqlcond = xstring_new();
		if (format_sql_condition(condition, sqlcond, true) != EPKG_OK) {
-
			utstring_free(sqlcond);
+
			xstring_free(sqlcond);
			return (EX_USAGE);
		}
	}
@@ -210,12 +210,10 @@ exec_rquery(int argc, char **argv)
	ret = pkgdb_access(PKGDB_MODE_READ, PKGDB_DB_REPO);
	if (ret == EPKG_ENOACCESS) {
		warnx("Insufficient privileges to query the package database");
-
		if (sqlcond != NULL)
-
			utstring_free(sqlcond);
+
		xstring_free(sqlcond);
		return (EX_NOPERM);
	} else if (ret != EPKG_OK) {
-
		if (sqlcond != NULL)
-
			utstring_free(sqlcond);
+
		xstring_free(sqlcond);
		return (EX_IOERR);
	}

@@ -223,16 +221,14 @@ exec_rquery(int argc, char **argv)
	old_quiet = quiet;
	quiet = true;
	if (auto_update && (ret = pkgcli_update(false, false, reponame)) != EPKG_OK) {
-
		if (sqlcond != NULL)
-
			utstring_free(sqlcond);
+
		xstring_free(sqlcond);
		return (ret);
	}
	quiet = old_quiet;

	ret = pkgdb_open_all(&db, PKGDB_REMOTE, reponame);
	if (ret != EPKG_OK) {
-
		if (sqlcond != NULL)
-
			utstring_free(sqlcond);
+
		xstring_free(sqlcond);
		return (EX_IOERR);
	}
	drop_privileges();
@@ -242,11 +238,12 @@ 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 = utstring_body(sqlcond);
+
		if (match == MATCH_CONDITION && sqlcond) {
+
			fflush(sqlcond->fp);
+
			condition_sql = sqlcond->buf;
+
		}
		if ((it = pkgdb_repo_query(db, condition_sql, match, reponame)) == NULL) {
-
			if (sqlcond != NULL)
-
				utstring_free(sqlcond);
+
			xstring_free(sqlcond);
			return (EX_IOERR);
		}

@@ -266,8 +263,7 @@ exec_rquery(int argc, char **argv)
			pkgname = argv[i];

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

@@ -290,8 +286,7 @@ exec_rquery(int argc, char **argv)
			retcode = EX_UNAVAILABLE;
	}

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

modified src/upgrade.c
@@ -40,7 +40,7 @@
#include <errno.h>
#include <signal.h>
#include <khash.h>
-
#include <utstring.h>
+
#include <xstring.h>
#include <pkg.h>

#ifdef HAVE_SYS_CAPSICUM_H
@@ -84,7 +84,7 @@ check_vulnerable(struct pkg_audit *audit, struct pkgdb *db, int sock)
	struct pkg		*pkg = NULL;
	kh_pkgs_t		*check = NULL;
	const char		*uid;
-
	UT_string		*sb;
+
	xstring		*sb;
	int				ret;
	FILE			*out;

@@ -153,7 +153,7 @@ check_vulnerable(struct pkg_audit *audit, struct pkgdb *db, int sock)
					pkg_get(pkg, PKG_UNIQUEID, &uid);
					fprintf(out, "%s\n", uid);
					fflush(out);
-
					utstring_free(sb);
+
					xstring_free(sb);
				}
				pkg_free(pkg);
		});
@@ -436,7 +436,8 @@ exec_upgrade(int argc, char **argv)
		}

		if (messages != NULL) {
-
			printf("%s", utstring_body(messages));
+
			fflush(messages->fp);
+
			printf("%s", messages->buf);
		}
		break;
	}
modified src/utils.c
@@ -1023,13 +1023,6 @@ print_jobs_summary(struct pkg_jobs *jobs, const char *msg, ...)
}

void
-
utstring_flush(UT_string *buf)
-
{
-
	printf("%s", utstring_body(buf));
-
	utstring_clear(buf);
-
}
-

-
void
drop_privileges(void)
{
	struct passwd *nobody;
modified src/version.c
@@ -49,7 +49,6 @@
#include <sys/types.h>
#include <sys/stat.h>
#include <khash.h>
-
#include <utstring.h>

#include "pkgcli.h"

@@ -561,7 +560,7 @@ cleanup:
}

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

	close(pfd[1]);

-
	utstring_clear(res);
+
	xstring_reset(res->fp);
	while ((r = read(pfd[0], buf, BUFSIZ)) > 0)
-
		utstring_bincpy(res, buf, r);
+
		fwrite(buf, sizeof(char), r, res->fp);

	close(pfd[0]);
	while (waitpid(pid, &pstat, 0) == -1) {
@@ -607,20 +606,21 @@ exec_buf(UT_string *res, char **argv) {
	if (WEXITSTATUS(pstat) != 0)
		return (-1);

-
	return (utstring_len(res));
+
	fflush(res->fp);
+
	return (strlen(res->buf));
}

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

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

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

-
	results = utstring_body(makecmd);
+
	fflush(makecmd->fp);
+
	results = makecmd->buf;

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

cleanup:
-
	utstring_free(makecmd);
+
	xstring_free(makecmd);

	return (cat);
}
@@ -704,7 +705,7 @@ validate_origin(const char *portsdir, const char *origin)
}

static const char *
-
port_version(UT_string *cmd, const char *portsdir, const char *origin,
+
port_version(xstring *cmd, const char *portsdir, const char *origin,
    const char *pkgname)
{
	char	*output, *walk, *name;
@@ -716,16 +717,18 @@ port_version(UT_string *cmd, const char *portsdir, const char *origin,
	   version from the port itself. */

	if (validate_origin(portsdir, origin)) {
-
		utstring_printf(cmd, "%s/%s", portsdir, origin);
+
		fprintf(cmd->fp, "%s/%s", portsdir, origin);

+
		fflush(cmd->fp);
		argv[0] = "make";
		argv[1] = "-C";
-
		argv[2] = utstring_body(cmd);
+
		argv[2] = cmd->buf;
		argv[3] = "flavors-package-names";
		argv[4] = NULL;

		if (exec_buf(cmd, argv) > 0) {
-
			output = utstring_body(cmd);
+
			fflush(cmd->fp);
+
			output = cmd->buf;
			while ((walk = strsep(&output, "\n")) != NULL) {
				name = walk;
				walk = strrchr(walk, '-');
@@ -751,7 +754,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;
-
	UT_string	*cmd;
+
	xstring		*cmd;
	const char	*name;
	const char	*origin;
	const char	*version;
@@ -777,7 +780,7 @@ do_source_ports(unsigned int opt, char limchar, char *pattern, match_t match,
	if ((it = pkgdb_query(db, pattern, match)) == NULL)
			goto cleanup;

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

	while (pkgdb_it_next(it, &pkg, PKG_LOAD_BASIC) == EPKG_OK) {
		pkg_get(pkg, PKG_NAME, &name, PKG_ORIGIN, &origin);
@@ -794,10 +797,10 @@ do_source_ports(unsigned int opt, char limchar, char *pattern, match_t match,

		version = port_version(cmd, portsdir, origin, name);
		print_version(pkg, "port", version, limchar, opt);
-
		utstring_clear(cmd);
+
		xstring_reset(cmd);
	}

-
	utstring_free(cmd);
+
	xstring_free(cmd);

cleanup:
	pkgdb_release_lock(db, PKGDB_LOCK_READONLY);