Skip to content

Commit

Permalink
Add rpmtsLogOnce()
Browse files Browse the repository at this point in the history
Allows showing a log message only once.

Use in handleHdrVS. This does not add a new test case but various
existing test cases fail when the NOKEY message is omited or shown
more than once.

Resolves: rpm-software-management#3336
Resolves: rpm-software-management#3333
  • Loading branch information
ffesti committed Oct 17, 2024
1 parent c4c3d79 commit 626c7c6
Show file tree
Hide file tree
Showing 5 changed files with 44 additions and 27 deletions.
10 changes: 10 additions & 0 deletions include/rpm/rpmts.h
Original file line number Diff line number Diff line change
Expand Up @@ -663,6 +663,16 @@ int rpmtsGetNotifyStyle(rpmts ts);
*/
int rpmtsSetChangeCallback(rpmts ts, rpmtsChangeFunction notify, void *data);

/** \ingroup rpmts
* Log messages with the same key just once
* @param ts transaction set
* @param key key to match log messages together
* @param code rpmlogLvl
* @param fmt format string and parameter to render
* @return 0 for the first call with this key value 1 otherwise
*/
int rpmtsLogOnce(rpmts ts, const char * key, int code, const char * fmt, ...) RPM_GNUC_PRINTF(4, 5);

/** \ingroup rpmts
* Create an empty transaction set.
* @return new transaction set
Expand Down
35 changes: 11 additions & 24 deletions lib/package.cc
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@ typedef struct pkgdata_s *pkgdatap;
typedef void (*hdrvsmsg)(struct rpmsinfo_s *sinfo, pkgdatap pkgdata, const char *msg);

struct pkgdata_s {
rpmts ts;
hdrvsmsg msgfunc;
const char *fn;
char *msg;
Expand Down Expand Up @@ -109,28 +110,6 @@ rpmTagVal headerMergeLegacySigs(Header h, Header sigh, char **msg)
return xl->stag;
}

/**
* Remember current key id.
* XXX: This s*** needs to die. Hook it into keyring or sumthin...
* @param keyid signature keyid
* @return 0 if new keyid, otherwise 1
*/
static int stashKeyid(unsigned int keyid)
{
static std::mutex keyid_mutex;
static std::set<unsigned int> keyids;
int seen = 0;

if (keyid == 0)
return 0;

std::lock_guard<std::mutex> lock(keyid_mutex);
auto ret = keyids.insert(keyid);
seen = (ret.second == false);

return seen;
}

static int handleHdrVS(struct rpmsinfo_s *sinfo, void *cbdata)
{
struct pkgdata_s *pkgdata = (struct pkgdata_s *)cbdata;
Expand Down Expand Up @@ -287,14 +266,19 @@ static void loghdrmsg(struct rpmsinfo_s *sinfo, struct pkgdata_s *pkgdata,
const char *msg)
{
int lvl = RPMLOG_DEBUG;
char * signid = NULL;
int printed = 0;
switch (sinfo->rc) {
case RPMRC_OK: /* Signature is OK. */
break;
case RPMRC_NOTTRUSTED: /* Signature is OK, but key is not trusted. */
case RPMRC_NOKEY: /* Public key is unavailable. */
/* XXX Print NOKEY/NOTTRUSTED warning only once. */
if (stashKeyid(sinfo->keyid) == 0)
lvl = RPMLOG_WARNING;
signid = rpmhex(pgpDigParamsSignID(sinfo->sig), PGP_KEYID_LEN);
printed = rpmtsLogOnce(pkgdata->ts, signid, RPMLOG_WARNING, "%s: %s\n", pkgdata->fn, msg);
free(signid);
if (!printed)
goto exit;
break;
case RPMRC_NOTFOUND: /* Signature/digest not present. */
lvl = RPMLOG_WARNING;
Expand All @@ -306,6 +290,8 @@ static void loghdrmsg(struct rpmsinfo_s *sinfo, struct pkgdata_s *pkgdata,
}

rpmlog(lvl, "%s: %s\n", pkgdata->fn, msg);
exit:
;
}

rpmRC rpmReadPackageFile(rpmts ts, FD_t fd, const char * fn, Header * hdrp)
Expand All @@ -319,6 +305,7 @@ rpmRC rpmReadPackageFile(rpmts ts, FD_t fd, const char * fn, Header * hdrp)
rpmKeyring keyring = rpmtsGetKeyring(ts, 1);
struct rpmvs_s *vs = rpmvsCreate(0, vsflags, keyring);
struct pkgdata_s pkgdata = {
.ts = ts,
.msgfunc = loghdrmsg,
.fn = fn ? fn : Fdescr(fd),
.msg = NULL,
Expand Down
21 changes: 21 additions & 0 deletions lib/rpmts.cc
Original file line number Diff line number Diff line change
Expand Up @@ -1260,6 +1260,26 @@ int rpmtsSetChangeCallback(rpmts ts, rpmtsChangeFunction change, void *data)
return 0;
}

int rpmtsLogOnce(rpmts ts, const char * key, int code, const char * fmt, ...)
{
int saved_errno = errno;
va_list ap;
char *msg = NULL;
int seen = 0;
auto ret = ts->logged_once.insert(key);
seen = (ret.second == false);
if (!seen) {
va_start(ap, fmt);
if (rvasprintf(&msg, fmt, ap) >= 0) {
rpmlog(code, msg);
free(msg);
}
va_end(ap);
}
errno = saved_errno;
return seen;
}

tsMembers rpmtsMembers(rpmts ts)
{
return (ts != NULL) ? ts->members : NULL;
Expand Down Expand Up @@ -1368,6 +1388,7 @@ rpmts rpmtsCreate(void)
ts->trigs2run = rpmtriggersCreate(10);

ts->min_writes = (rpmExpandNumeric("%{?_minimize_writes}") > 0);
ts->logged_once = {};

return rpmtsLink(ts);
}
Expand Down
2 changes: 2 additions & 0 deletions lib/rpmts_internal.hh
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
#include <unordered_map>
#include <vector>
#include <atomic>
#include <set>

#include <rpm/rpmts.h>
#include <rpm/rpmstrpool.h>
Expand Down Expand Up @@ -100,6 +101,7 @@ struct rpmts_s {
int min_writes; /*!< macro minimize_writes used */

time_t overrideTime; /*!< Time value used when overriding system clock. */
std::set<std::string> logged_once; /* Messages already logged */
};

/** \ingroup rpmts
Expand Down
3 changes: 0 additions & 3 deletions lib/rpmvs.cc
Original file line number Diff line number Diff line change
Expand Up @@ -196,7 +196,6 @@ static void rpmsinfoInit(const struct vfyinfo_s *vinfo,
char *lints = NULL;
int ec = pgpPrtParams2((const uint8_t *)data, dlen, PGPTAG_SIGNATURE,
&sinfo->sig, &lints);
const uint8_t *signid;
if (ec) {
if (lints) {
rasprintf(&sinfo->msg,
Expand All @@ -214,8 +213,6 @@ static void rpmsinfoInit(const struct vfyinfo_s *vinfo,
free(lints);
}
sinfo->hashalgo = pgpDigParamsAlgo(sinfo->sig, PGPVAL_HASHALGO);
signid = pgpDigParamsSignID(sinfo->sig); /* 8 bytes key id */
sinfo->keyid = signid[4] << 24 | signid[5] << 16 | signid[6] << 8 | signid[7];
} else if (sinfo->type == RPMSIG_DIGEST_TYPE) {
if (td->type == RPM_BIN_TYPE) {
sinfo->dig = rpmhex((const uint8_t *)data, dlen);
Expand Down

0 comments on commit 626c7c6

Please sign in to comment.