Radish alpha
H
rad:z3QDZAW2FAfuLvihrhiyDC9fAD8G9
HardenedBSD Package Manager
Radicle
Git
debug: implement PKG_DEBUG_FLAGS
Baptiste Daroussin committed 2 years ago
commit 9f817aa6cfb6f8cf4070b845158b699108498f9f
parent e482b66
10 files changed +119 -37
modified libpkg/fetch.c
@@ -249,7 +249,7 @@ pkg_fetch_file_to_fd(struct pkg_repo *repo, int dest, struct fetch_item *fi,
	 * Error if using plain http://, https:// etc with SRV
	 */

-
	pkg_debug(1, "Request to fetch %s", fi->url);
+
	pkg_dbg(PKG_DBG_FETCH, "Request to fetch %s", fi->url);
	if (repo == NULL) {
		fakerepo = xcalloc(1, sizeof(struct pkg_repo));
		fakerepo->url = xstrdup(fi->url);
@@ -292,7 +292,7 @@ pkg_fetch_file_to_fd(struct pkg_repo *repo, int dest, struct fetch_item *fi,

	if ((retcode = repo->fetcher->open(repo, fi)) != EPKG_OK)
		goto cleanup;
-
	pkg_debug(1, "Fetch: fetcher used: %s", repo->fetcher->scheme);
+
	pkg_dbg(PKG_DBG_FETCH, "Fetch: fetcher used: %s", repo->fetcher->scheme);

	retcode = repo->fetcher->fetch(repo, dest, fi);
	if (retcode == EPKG_OK)
modified libpkg/fetch_file.c
@@ -95,9 +95,9 @@ stdio_fetch(struct pkg_repo *repo, int dest, struct fetch_item *fi)
		done += r;
		if (fi->size > 0) {
			left -= r;
-
			pkg_debug(4, "Read status: %jd over %jd", (intmax_t)done, (intmax_t)fi->size);
+
			pkg_dbg(PKG_DBG_FETCH, "Read status: %jd over %jd", (intmax_t)done, (intmax_t)fi->size);
		} else
-
			pkg_debug(4, "Read status: %jd", (intmax_t)done);
+
			pkg_dbg(PKG_DBG_FETCH, "Read status: %jd", (intmax_t)done);
		if (fi->size > 0)
			pkg_emit_progress_tick(done, fi->size);
	}
modified libpkg/fetch_libcurl.c
@@ -149,9 +149,9 @@ curl_do_fetch(struct curl_userdata *data, CURL *cl, struct curl_repodata *cr)
	curl_easy_setopt(cl, CURLOPT_FOLLOWLOCATION, 1L);
	curl_easy_setopt(cl, CURLOPT_PRIVATE, &data);

-
	if (ctx.debug_level > 0)
+
	if (ctx.debug_flags & PKG_DBG_FETCH)
		curl_easy_setopt(cl, CURLOPT_VERBOSE, 1L);
-
	if (ctx.debug_level > 1)
+
	if (ctx.debug_flags & PKG_DBG_FETCH)
		curl_easy_setopt(cl, CURLOPT_DEBUGFUNCTION, my_trace);

	/* compat with libfetch */
@@ -212,7 +212,7 @@ http_getmirrors(struct pkg_repo *r, struct curl_repodata *cr)
	size_t cap = 0;
	struct http_mirror *m, *mirrors = NULL;
	CURLU *url;
-
	pkg_debug(1, "CURL> fetching http mirror list if any");
+
	pkg_dbg(PKG_DBG_FETCH, "CURL> fetching http mirror list if any");

	cl = curl_easy_init();
	data.fh = open_memstream(& buf, &cap);
@@ -247,7 +247,7 @@ http_getmirrors(struct pkg_repo *r, struct curl_repodata *cr)
		}
		m = xmalloc(sizeof(*m));
		m->url = url;
-
		pkg_debug(1, "CURL> appending an http mirror: %s", line);
+
		pkg_dbg(PKG_DBG_FETCH, "CURL> appending an http mirror: %s", line);
		LL_APPEND(mirrors, m);
	}
	free(buf);
@@ -287,7 +287,7 @@ int
curl_open(struct pkg_repo *repo, struct fetch_item *fi __unused)
{
	struct curl_repodata *cr;
-
	pkg_debug(1, "curl_open");
+
	pkg_dbg(PKG_DBG_FETCH, "curl_open");

	if (repo->fetch_priv != NULL)
		return (EPKG_OK);
@@ -378,7 +378,7 @@ curl_fetch(struct pkg_repo *repo, int dest, struct fetch_item *fi)
	data.totalsize = fi->size;
	data.url = fi->url;

-
	pkg_debug(1, "curl> fetching %s\n", fi->url);
+
	pkg_dbg(PKG_DBG_FETCH, "curl> fetching %s\n", fi->url);
	retry = pkg_object_int(pkg_config_get("FETCH_RETRY"));
	if (repo->mirror_type == SRV || repo->mirror_type == HTTP) {
		CURLU *cu = curl_url();
@@ -435,16 +435,16 @@ do_retry:
		free(p);
		char *lurl;
		curl_url_get(hu, CURLUPART_URL, &lurl, 0);
-
		pkg_debug(1, "CURL> new http mirror url: %s", lurl);
+
		pkg_dbg(PKG_DBG_FETCH, "CURL> new http mirror url: %s", lurl);
		curl_easy_setopt(cl, CURLOPT_CURLU, hu);
	} else {
-
		pkg_debug(1, "CURL> No mirror set url to %s\n", fi->url);
+
		pkg_dbg(PKG_DBG_FETCH, "CURL> No mirror set url to %s\n", fi->url);
		curl_easy_setopt(cl, CURLOPT_URL, fi->url);
	}
-
	if (ctx.debug_level > 0) {
+
	if (ctx.debug_flags & PKG_DBG_FETCH) {
		const char *lurl = NULL;
		curl_easy_getinfo(cl, CURLINFO_EFFECTIVE_URL, &lurl);
-
		pkg_debug(1, "CURL> attempting to fetch from %s, left retry %ld\n",
+
		pkg_dbg(PKG_DBG_FETCH, "CURL> attempting to fetch from %s, left retry %ld\n",
				lurl, retry);
	}
	curl_easy_setopt(cl, CURLOPT_HTTPAUTH, (long)CURLAUTH_ANY);
modified libpkg/fetch_libfetch.c
@@ -117,7 +117,7 @@ fetch_connect(struct pkg_repo *repo, struct url *u)
	doc = u->doc;
	reldoc = doc + strlen(repourl->doc);
	fetchFreeURL(repourl);
-
	pkg_debug(1, "Fetch > libfetch: connecting");
+
	pkg_dbg(PKG_DBG_FETCH, "Fetch > libfetch: connecting");

	while (repo->fh == NULL) {
		if (repo != NULL && repo->mirror_type == SRV &&
@@ -172,7 +172,7 @@ fetch_connect(struct pkg_repo *repo, struct url *u)
			fputc('v', fetchOpts->fp);

		opts = xstring_get(fetchOpts);
-
		pkg_debug(1,"Fetch: fetching from: %s://%s%s%s%s with opts \"%s\"",
+
		pkg_dbg(PKG_DBG_FETCH, "Fetch: fetching from: %s://%s%s%s%s with opts \"%s\"",
		    u->scheme,
		    u->user,
		    u->user[0] != '\0' ? "@" : "",
@@ -225,7 +225,7 @@ fetch_open(struct pkg_repo *repo, struct url *u, off_t *sz, time_t *t)
{
	int retcode = EPKG_FATAL;

-
	pkg_debug(1, "opening libfetch fetcher");
+
	pkg_dbg(PKG_DBG_FETCH, "opening libfetch fetcher");
	if (repo->fh == NULL)
		retcode = fetch_connect(repo, u);

modified libpkg/fetch_ssh.c
@@ -64,7 +64,7 @@ tcp_connect(struct pkg_repo *repo, struct yuarel *u)
	int sd = -1;
	int retcode;

-
	pkg_debug(1, "TCP> tcp_connect");
+
	pkg_dbg(PKG_DBG_FETCH, "TCP> tcp_connect");
	memset(&hints, 0, sizeof(hints));
	hints.ai_family = PF_UNSPEC;
	if (repo->ip == IPV4)
@@ -114,12 +114,12 @@ tcp_connect(struct pkg_repo *repo, struct yuarel *u)

	if (getline(&line, &linecap, repo->fh) > 0) {
		if (strncmp(line, "ok:", 3) != 0) {
-
			pkg_debug(1, "SSH> server rejected, got: %s", line);
+
			pkg_dbg(PKG_DBG_FETCH, "SSH> server rejected, got: %s", line);
			goto tcp_cleanup;
		}
-
		pkg_debug(1, "SSH> server is: %s", line +4);
+
		pkg_dbg(PKG_DBG_FETCH, "SSH> server is: %s", line +4);
	} else {
-
		pkg_debug(1, "SSH> nothing to read, got: %s", line);
+
		pkg_dbg(PKG_DBG_FETCH, "SSH> nothing to read, got: %s", line);
		goto tcp_cleanup;
	}
	retcode = EPKG_OK;
@@ -182,7 +182,7 @@ ssh_connect(struct pkg_repo *repo, struct yuarel *u)
			fprintf(cmd->fp, "%s@", u->username);
		fprintf(cmd->fp, "%s pkg ssh", u->host);
		cmdline = xstring_get(cmd);
-
		pkg_debug(1, "Fetch: running '%s'", cmdline);
+
		pkg_dbg(PKG_DBG_FETCH, "Fetch: running '%s'", cmdline);
		argv[0] = _PATH_BSHELL;
		argv[1] = "-c";
		argv[2] = cmdline;
@@ -201,7 +201,7 @@ ssh_connect(struct pkg_repo *repo, struct yuarel *u)
		goto ssh_cleanup;
	}

-
	pkg_debug(1, "SSH> connected");
+
	pkg_dbg(PKG_DBG_FETCH, "SSH> connected");

	repo->sshio.in = sshout[0];
	repo->sshio.out = sshin[1];
@@ -215,12 +215,12 @@ ssh_connect(struct pkg_repo *repo, struct yuarel *u)

	if (getline(&line, &linecap, repo->fh) > 0) {
		if (strncmp(line, "ok:", 3) != 0) {
-
			pkg_debug(1, "SSH> server rejected, got: %s", line);
+
			pkg_dbg(PKG_DBG_FETCH, "SSH> server rejected, got: %s", line);
			goto ssh_cleanup;
		}
-
		pkg_debug(1, "SSH> server is: %s", line +4);
+
		pkg_dbg(PKG_DBG_FETCH, "SSH> server is: %s", line +4);
	} else {
-
		pkg_debug(1, "SSH> nothing to read, got: %s", line);
+
		pkg_dbg(PKG_DBG_FETCH, "SSH> nothing to read, got: %s", line);
		goto ssh_cleanup;
	}
	retcode = EPKG_OK;
@@ -252,7 +252,7 @@ pkgprotocol_open(struct pkg_repo *repo, struct fetch_item *fi,
		return (EPKG_FATAL);
	}

-
	pkg_debug(1, "SSH> tcp_open");
+
	pkg_dbg(PKG_DBG_FETCH, "SSH> tcp_open");
	if (repo->fh == NULL)
		retcode = proto_connect(repo, &url);
	else
@@ -261,13 +261,13 @@ pkgprotocol_open(struct pkg_repo *repo, struct fetch_item *fi,
	if (retcode != EPKG_OK)
		return (retcode);

-
	pkg_debug(1, "SSH> get %s %" PRIdMAX "", url.path, (intmax_t)fi->mtime);
+
	pkg_dbg(PKG_DBG_FETCH, "SSH> get %s %" PRIdMAX "", url.path, (intmax_t)fi->mtime);
	fprintf(repo->fh, "get %s %" PRIdMAX "\n", url.path, (intmax_t)fi->mtime);
	if ((linelen = getline(&line, &linecap, repo->fh)) > 0) {
		if (line[linelen -1 ] == '\n')
			line[linelen -1 ] = '\0';

-
		pkg_debug(1, "SSH> recv: %s", line);
+
		pkg_dbg(PKG_DBG_FETCH, "SSH> recv: %s", line);
		if (strncmp(line, "ok:", 3) == 0) {
			fi->size = strtonum(line + 4, 0, LONG_MAX, &errstr);
			if (errstr) {
@@ -414,7 +414,7 @@ ssh_write(void *data, const char *buf, int l)
	iov.iov_base = __DECONST(char *, buf);
	iov.iov_len = l;

-
	pkg_debug(1, "writing data");
+
	pkg_dbg(PKG_DBG_FETCH, "writing data");

	return (ssh_writev(repo->sshio.out, &iov, 1, repo->fetcher->timeout));
}
@@ -428,7 +428,7 @@ ssh_read(void *data, char *buf, int len)
	ssize_t rlen;
	int deltams;

-
	pkg_debug(2, "ssh: start reading");
+
	pkg_dbg(PKG_DBG_FETCH, "ssh: start reading");

	if (repo->fetcher->timeout > 0) {
		gettimeofday(&timeout, NULL);
@@ -442,7 +442,7 @@ ssh_read(void *data, char *buf, int len)

	for (;;) {
		rlen = read(pfd.fd, buf, len);
-
		pkg_debug(2, "read %jd", (intmax_t)rlen);
+
		pkg_dbg(PKG_DBG_FETCH, "read %jd", (intmax_t)rlen);
		if (rlen >= 0) {
			break;
		} else if (rlen == -1) {
@@ -468,17 +468,17 @@ ssh_read(void *data, char *buf, int len)

		errno = 0;
		pfd.revents = 0;
-
		pkg_debug(1, "begin poll()");
+
		pkg_dbg(PKG_DBG_FETCH, "begin poll()");
		if (poll(&pfd, 1, deltams) < 0) {
			if (errno == EINTR)
				continue;
			return (-1);
		}
-
		pkg_debug(1, "end poll()");
+
		pkg_dbg(PKG_DBG_FETCH, "end poll()");

	}

-
	pkg_debug(2, "ssh: have read %jd bytes", (intmax_t)rlen);
+
	pkg_dbg(PKG_DBG_FETCH, "ssh: have read %jd bytes", (intmax_t)rlen);

	return (rlen);
}
modified libpkg/pkg_config.c
@@ -1,5 +1,5 @@
/*
-
 * Copyright (c) 2011-2021 Baptiste Daroussin <bapt@FreeBSD.org>
+
 * Copyright (c) 2011-2024 Baptiste Daroussin <bapt@FreeBSD.org>
 * Copyright (c) 2011-2012 Julien Laffaye <jlaffaye@FreeBSD.org>
 * Copyright (c) 2014 Matthew Seaman <matthew@FreeBSD.org>
 * Copyright (c) 2016 Vsevolod Stakhov <vsevolod@FreeBSD.org>
@@ -507,6 +507,12 @@ static struct config_entry c[] = {
		NULL,
		"patterns of files to not extract from the package",
	},
+
	{
+
		PKG_ARRAY,
+
		"PKG_DEBUG_FLAGS",
+
		NULL,
+
		"debug flags to activate",
+
	},
};

static bool parsed = false;
@@ -989,6 +995,41 @@ type_to_string(int type)
		return ("boolean");
	return ("unknown");
}
+

+
struct pkg_dbg_flags *
+
_find_flag(const char *str)
+
{
+
	for (size_t i = 0; i < NELEM(debug_flags); i++) {
+
		if (STRIEQ(debug_flags[i].name, str))
+
			return (&debug_flags[i]);
+
	}
+
	return (NULL);
+
}
+
static uint64_t
+
config_validate_debug_flags(const ucl_object_t *o)
+
{
+
	ucl_object_iter_t it = NULL;
+
	const ucl_object_t *cur;
+
	int ret = EPKG_OK;
+
	struct pkg_dbg_flags *f;
+

+
	if (o == NULL)
+
		return (ret);
+

+
	while ((cur = ucl_iterate_object(o, &it, true))) {
+
		const char *str = ucl_object_tostring(cur);
+
		f = _find_flag(str);
+
		if (f == NULL) {
+
			pkg_emit_error("Invalid debug flag %s",
+
			    ucl_object_tostring(cur));
+
			ret = EPKG_FATAL;
+
			continue;
+
		}
+
		ctx.debug_flags |= f->flag;
+
	}
+
	return (ret);
+
}
+

int
pkg_ini(const char *path, const char *reposdir, pkg_init_flags flags)
{
@@ -1344,6 +1385,9 @@ pkg_ini(const char *path, const char *reposdir, pkg_init_flags flags)
		connect_evpipe(evpipe);

	ctx.debug_level = pkg_object_int(pkg_config_get("DEBUG_LEVEL"));
+
	err = config_validate_debug_flags(ucl_object_find_key(config, "PKG_DEBUG_FLAGS"));
+
	if (err != EPKG_OK)
+
		goto out;
	ctx.developer_mode = pkg_object_bool(pkg_config_get("DEVELOPER_MODE"));
	ctx.dbdir = pkg_object_string(pkg_config_get("PKG_DBDIR"));
	ctx.cachedir = pkg_object_string(pkg_config_get("PKG_CACHEDIR"));
modified libpkg/pkg_event.c
@@ -993,6 +993,26 @@ pkg_debug(int level, const char *fmt, ...)
}

void
+
pkg_dbg(uint64_t flags, const char *fmt, ...)
+
{
+
	struct pkg_event ev;
+
	va_list ap;
+

+
	if ((ctx.debug_flags & (flags|PKG_DBG_ALL)) == 0)
+
		return;
+

+
	ev.type = PKG_EVENT_DEBUG;
+
	ev.e_debug.level = 1;
+
	va_start(ap, fmt);
+
	vasprintf(&ev.e_debug.msg, fmt, ap);
+
	va_end(ap);
+

+
	pkg_emit_event(&ev);
+
	free(ev.e_debug.msg);
+
}
+

+

+
void
pkg_emit_backup(void)
{
	struct pkg_event ev;
modified libpkg/private/event.h
@@ -1,5 +1,5 @@
/*-
-
 * Copyright (c) 2011-2012 Baptiste Daroussin <bapt@FreeBSD.org>
+
 * Copyright (c) 2011-2024 Baptiste Daroussin <bapt@FreeBSD.org>
 * Copyright (c) 2011-2012 Julien Laffaye <jlaffaye@FreeBSD.org>
 * Copyright (c) 2014 Vsevolod Stakhov <vsevolod@FreeBSD.org>
 * Copyright (c) 2015 Matthew Seaman <matthew@FreeBSD.org>
@@ -50,6 +50,21 @@ void pkg_emit_pkg_errno(pkg_error_t err, const char *func, const char *arg);
	return (EPKG_FATAL);           \
} while (0);

+
typedef enum {
+
	PKG_DBG_NONE = (1UL << 0),
+
	PKG_DBG_FETCH = (1UL << 1),
+
	PKG_DBG_ALL = (1UL << 127),
+
} pkg_debug_flags;
+

+
static struct pkg_dbg_flags {
+
	uint64_t flag;
+
	const char *name;
+
} debug_flags[] = {
+
	{ PKG_DBG_NONE, "none" },
+
	{ PKG_DBG_FETCH, "fetch" },
+
	{ PKG_DBG_ALL, "all" },
+
};
+

void pkg_emit_already_installed(struct pkg *p);
void pkg_emit_fetch_begin(const char *url);
void pkg_emit_fetch_finished(const char *url);
@@ -79,6 +94,7 @@ void pkg_emit_incremental_update(const char *reponame, int processed);
void pkg_emit_backup(void);
void pkg_emit_restore(void);
void pkg_debug(int level, const char *fmt, ...) PKG_FORMAT_ATTRIBUTE(2, 3);
+
void pkg_dbg(uint64_t flag, const char *fmt, ...) PKG_FORMAT_ATTRIBUTE(2, 3);
int pkg_emit_sandbox_call(pkg_sandbox_cb call, int fd, void *ud);
int pkg_emit_sandbox_get_string(pkg_sandbox_cb call, void *ud, char **str, int64_t *len);

modified libpkg/private/pkg.h
@@ -150,6 +150,7 @@ struct pkg_stringlist_iterator {
struct pkg_ctx {
	int eventpipe;
	int64_t debug_level;
+
	uint64_t debug_flags;
	bool developer_mode;
	const char *pkg_rootdir;
	const char *dbdir;
modified libpkg/private/utils.h
@@ -39,6 +39,7 @@
#include <xstring.h>

#define STARTS_WITH(string, needle) (strncasecmp(string, needle, strlen(needle)) == 0)
+
#define STRIEQ(string, needle) (strcasecmp(string, needle) == 0)
#define RELATIVE_PATH(p) (p + (*p == '/' ? 1 : 0))

typedef tll(char *) stringlist_t;