690 lines
17 KiB
C
690 lines
17 KiB
C
/** \ingroup rpmcli
|
|
* \file lib/query.c
|
|
* Display tag values from package metadata.
|
|
*/
|
|
|
|
#include "system.h"
|
|
|
|
#ifndef PATH_MAX
|
|
# define PATH_MAX 255
|
|
#endif
|
|
|
|
#include <rpm/rpmcli.h>
|
|
|
|
#include <rpm/header.h>
|
|
#include <rpm/rpmdb.h>
|
|
#include <rpm/rpmfi.h>
|
|
#include <rpm/rpmgi.h>
|
|
#include <rpm/rpmts.h>
|
|
#include <rpm/rpmlog.h>
|
|
#include <rpm/rpmfileutil.h> /* rpmCleanPath */
|
|
|
|
#include "lib/manifest.h"
|
|
|
|
#include "debug.h"
|
|
|
|
|
|
/**
|
|
*/
|
|
static void printFileInfo(const char * name,
|
|
rpm_off_t size, unsigned short mode,
|
|
unsigned int mtime,
|
|
unsigned short rdev, unsigned int nlink,
|
|
const char * owner, const char * group,
|
|
const char * linkto)
|
|
{
|
|
char sizefield[15];
|
|
char ownerfield[8+1], groupfield[8+1];
|
|
char timefield[100];
|
|
time_t when = mtime; /* important if sizeof(int32_t) ! sizeof(time_t) */
|
|
struct tm * tm;
|
|
static time_t now;
|
|
static struct tm nowtm;
|
|
char * perms = rpmPermsString(mode);
|
|
char *link = NULL;
|
|
|
|
/* On first call, grab snapshot of now */
|
|
if (now == 0) {
|
|
now = time(NULL);
|
|
tm = localtime(&now);
|
|
if (tm) nowtm = *tm; /* structure assignment */
|
|
}
|
|
|
|
rstrlcpy(ownerfield, owner, sizeof(ownerfield));
|
|
rstrlcpy(groupfield, group, sizeof(groupfield));
|
|
|
|
/* this is normally right */
|
|
sprintf(sizefield, "%12u", size);
|
|
|
|
/* this knows too much about dev_t */
|
|
|
|
if (S_ISLNK(mode)) {
|
|
rasprintf(&link, "%s -> %s", name, linkto);
|
|
} else if (S_ISCHR(mode)) {
|
|
perms[0] = 'c';
|
|
sprintf(sizefield, "%3u, %3u", ((unsigned)(rdev >> 8) & 0xff),
|
|
((unsigned)rdev & 0xff));
|
|
} else if (S_ISBLK(mode)) {
|
|
perms[0] = 'b';
|
|
sprintf(sizefield, "%3u, %3u", ((unsigned)(rdev >> 8) & 0xff),
|
|
((unsigned)rdev & 0xff));
|
|
}
|
|
|
|
/* Convert file mtime to display format */
|
|
tm = localtime(&when);
|
|
timefield[0] = '\0';
|
|
if (tm != NULL)
|
|
{ const char *fmt;
|
|
if (now > when + 6L * 30L * 24L * 60L * 60L || /* Old. */
|
|
now < when - 60L * 60L) /* In the future. */
|
|
{
|
|
/* The file is fairly old or in the future.
|
|
* POSIX says the cutoff is 6 months old;
|
|
* approximate this by 6*30 days.
|
|
* Allow a 1 hour slop factor for what is considered "the future",
|
|
* to allow for NFS server/client clock disagreement.
|
|
* Show the year instead of the time of day.
|
|
*/
|
|
fmt = "%b %e %Y";
|
|
} else {
|
|
fmt = "%b %e %H:%M";
|
|
}
|
|
(void)strftime(timefield, sizeof(timefield) - 1, fmt, tm);
|
|
}
|
|
|
|
rpmlog(RPMLOG_NOTICE, "%s %4d %-8s%-8s %10s %s %s\n", perms,
|
|
(int)nlink, ownerfield, groupfield, sizefield, timefield,
|
|
link ? link : name);
|
|
free(perms);
|
|
free(link);
|
|
}
|
|
|
|
int showQueryPackage(QVA_t qva, rpmts ts, Header h)
|
|
{
|
|
int scareMem = 0;
|
|
rpmfi fi = NULL;
|
|
int rc = 0; /* XXX FIXME: need real return code */
|
|
int i;
|
|
|
|
if (qva->qva_queryFormat != NULL) {
|
|
const char *errstr;
|
|
char *str = headerFormat(h, qva->qva_queryFormat, &errstr);
|
|
|
|
if ( str != NULL ) {
|
|
rpmlog(RPMLOG_NOTICE, "%s", str);
|
|
free(str);
|
|
} else {
|
|
rpmlog(RPMLOG_ERR, _("incorrect format: %s\n"), errstr);
|
|
}
|
|
}
|
|
|
|
if (!(qva->qva_flags & QUERY_FOR_LIST))
|
|
goto exit;
|
|
|
|
fi = rpmfiNew(ts, h, RPMTAG_BASENAMES, scareMem);
|
|
if (rpmfiFC(fi) <= 0) {
|
|
rpmlog(RPMLOG_NOTICE, _("(contains no files)\n"));
|
|
goto exit;
|
|
}
|
|
|
|
fi = rpmfiInit(fi, 0);
|
|
if (fi != NULL)
|
|
while ((i = rpmfiNext(fi)) >= 0) {
|
|
rpmfileAttrs fflags;
|
|
rpm_mode_t fmode;
|
|
unsigned short frdev;
|
|
rpm_time_t fmtime;
|
|
rpmfileState fstate;
|
|
rpm_off_t fsize;
|
|
const char * fn;
|
|
const char * fuser;
|
|
const char * fgroup;
|
|
const char * flink;
|
|
int32_t fnlink;
|
|
char *buf = NULL;
|
|
|
|
fflags = rpmfiFFlags(fi);
|
|
fmode = rpmfiFMode(fi);
|
|
frdev = rpmfiFRdev(fi);
|
|
fmtime = rpmfiFMtime(fi);
|
|
fstate = rpmfiFState(fi);
|
|
fsize = rpmfiFSize(fi);
|
|
fn = rpmfiFN(fi);
|
|
fuser = rpmfiFUser(fi);
|
|
fgroup = rpmfiFGroup(fi);
|
|
flink = rpmfiFLink(fi);
|
|
fnlink = rpmfiFNlink(fi);
|
|
|
|
/* If querying only docs, skip non-doc files. */
|
|
if ((qva->qva_flags & QUERY_FOR_DOCS) && !(fflags & RPMFILE_DOC))
|
|
continue;
|
|
|
|
/* If querying only configs, skip non-config files. */
|
|
if ((qva->qva_flags & QUERY_FOR_CONFIG) && !(fflags & RPMFILE_CONFIG))
|
|
continue;
|
|
|
|
/* If not querying %ghost, skip ghost files. */
|
|
if ((qva->qva_fflags & RPMFILE_GHOST) && (fflags & RPMFILE_GHOST))
|
|
continue;
|
|
|
|
if (qva->qva_flags & QUERY_FOR_STATE) {
|
|
switch (fstate) {
|
|
case RPMFILE_STATE_NORMAL:
|
|
rstrcat(&buf, _("normal "));
|
|
break;
|
|
case RPMFILE_STATE_REPLACED:
|
|
rstrcat(&buf, _("replaced "));
|
|
break;
|
|
case RPMFILE_STATE_NOTINSTALLED:
|
|
rstrcat(&buf, _("not installed "));
|
|
break;
|
|
case RPMFILE_STATE_NETSHARED:
|
|
rstrcat(&buf, _("net shared "));
|
|
break;
|
|
case RPMFILE_STATE_WRONGCOLOR:
|
|
rstrcat(&buf, _("wrong color "));
|
|
break;
|
|
case RPMFILE_STATE_MISSING:
|
|
rstrcat(&buf, _("(no state) "));
|
|
break;
|
|
default:
|
|
rasprintf(&buf, _("(unknown %3d) "), fstate);
|
|
break;
|
|
}
|
|
}
|
|
|
|
if (qva->qva_flags & QUERY_FOR_DUMPFILES) {
|
|
char *add, *fmd5;
|
|
fmd5 = pgpHexStr(rpmfiMD5(fi), rpmDigestLength(PGPHASHALGO_MD5));
|
|
|
|
rasprintf(&add, "%s %d %d %s 0%o ", fn, (int)fsize, fmtime, fmd5, fmode);
|
|
rstrcat(&buf, add);
|
|
free(add);
|
|
free(fmd5);
|
|
|
|
if (fuser && fgroup) {
|
|
rasprintf(&add, "%s %s", fuser, fgroup);
|
|
rstrcat(&buf, add);
|
|
free(add);
|
|
} else {
|
|
rpmlog(RPMLOG_ERR,
|
|
_("package has not file owner/group lists\n"));
|
|
}
|
|
|
|
rasprintf(&add, " %s %s %u %s",
|
|
fflags & RPMFILE_CONFIG ? "1" : "0",
|
|
fflags & RPMFILE_DOC ? "1" : "0",
|
|
frdev,
|
|
(flink && *flink ? flink : "X"));
|
|
rpmlog(RPMLOG_NOTICE, "%s%s\n", buf, add);
|
|
free(add);
|
|
} else
|
|
if (!rpmIsVerbose()) {
|
|
rpmlog(RPMLOG_NOTICE, "%s%s\n", buf ? buf : "", fn);
|
|
}
|
|
else {
|
|
|
|
/* XXX Adjust directory link count and size for display output. */
|
|
if (S_ISDIR(fmode)) {
|
|
fnlink++;
|
|
fsize = 0;
|
|
}
|
|
|
|
if (fuser && fgroup) {
|
|
if (buf) {
|
|
rpmlog(RPMLOG_NOTICE, "%s", buf);
|
|
}
|
|
printFileInfo(fn, fsize, fmode, fmtime, frdev, fnlink,
|
|
fuser, fgroup, flink);
|
|
} else {
|
|
rpmlog(RPMLOG_ERR,
|
|
_("package has neither file owner or id lists\n"));
|
|
}
|
|
}
|
|
free(buf);
|
|
}
|
|
|
|
rc = 0;
|
|
|
|
exit:
|
|
fi = rpmfiFree(fi);
|
|
return rc;
|
|
}
|
|
|
|
void rpmDisplayQueryTags(FILE * fp)
|
|
{
|
|
const struct headerTagTableEntry_s * t;
|
|
int i, ttype;
|
|
|
|
for (i = 0, t = rpmTagTable; i < rpmTagTableSize; i++, t++) {
|
|
if (t->name == NULL)
|
|
continue;
|
|
if (rpmIsVerbose()) {
|
|
static const char * const tagtypes[] = {
|
|
"", "char", "int8", "int16", "int32", "int64",
|
|
"string", "blob", "argv", "i18nstring"
|
|
};
|
|
fprintf(fp, "%-20s %6d", t->name + 7, t->val);
|
|
ttype = t->type & RPM_MASK_TYPE;
|
|
if (ttype > RPM_NULL_TYPE && ttype <= RPM_MAX_TYPE)
|
|
fprintf(fp, " %s", tagtypes[ttype]);
|
|
} else {
|
|
fprintf(fp, "%s", t->name + 7);
|
|
}
|
|
|
|
fprintf(fp, "\n");
|
|
}
|
|
}
|
|
|
|
static int rpmgiShowMatches(QVA_t qva, rpmts ts)
|
|
{
|
|
rpmgi gi = qva->qva_gi;
|
|
int ec = 0;
|
|
|
|
while (rpmgiNext(gi) == RPMRC_OK) {
|
|
Header h;
|
|
int rc;
|
|
|
|
h = rpmgiHeader(gi);
|
|
if (h == NULL) /* XXX perhaps stricter break instead? */
|
|
continue;
|
|
if ((rc = qva->qva_showPackage(qva, ts, h)) != 0)
|
|
ec = rc;
|
|
if (qva->qva_source == RPMQV_DBOFFSET)
|
|
break;
|
|
}
|
|
return rpmgiNumErrors(gi);
|
|
}
|
|
|
|
int rpmcliShowMatches(QVA_t qva, rpmts ts)
|
|
{
|
|
Header h;
|
|
int ec = 0;
|
|
|
|
while ((h = rpmdbNextIterator(qva->qva_mi)) != NULL) {
|
|
int rc;
|
|
if ((rc = qva->qva_showPackage(qva, ts, h)) != 0)
|
|
ec = rc;
|
|
if (qva->qva_source == RPMQV_DBOFFSET)
|
|
break;
|
|
}
|
|
qva->qva_mi = rpmdbFreeIterator(qva->qva_mi);
|
|
return ec;
|
|
}
|
|
|
|
/* LCL: segfault (realpath annotation?) */
|
|
int rpmQueryVerify(QVA_t qva, rpmts ts, const char * arg)
|
|
{
|
|
int res = 0;
|
|
const char * s;
|
|
int i;
|
|
int provides_checked = 0;
|
|
|
|
(void) rpmdbCheckSignals();
|
|
|
|
if (qva->qva_showPackage == NULL)
|
|
return 1;
|
|
|
|
switch (qva->qva_source) {
|
|
case RPMQV_RPM:
|
|
res = rpmgiShowMatches(qva, ts);
|
|
break;
|
|
|
|
case RPMQV_ALL:
|
|
res = rpmgiShowMatches(qva, ts);
|
|
break;
|
|
|
|
case RPMQV_HDLIST:
|
|
res = rpmgiShowMatches(qva, ts);
|
|
break;
|
|
|
|
case RPMQV_FTSWALK:
|
|
res = rpmgiShowMatches(qva, ts);
|
|
break;
|
|
|
|
case RPMQV_SPECFILE:
|
|
res = ((qva->qva_specQuery != NULL)
|
|
? qva->qva_specQuery(ts, qva, arg) : 1);
|
|
break;
|
|
|
|
case RPMQV_GROUP:
|
|
qva->qva_mi = rpmtsInitIterator(ts, RPMTAG_GROUP, arg, 0);
|
|
if (qva->qva_mi == NULL) {
|
|
rpmlog(RPMLOG_NOTICE,
|
|
_("group %s does not contain any packages\n"), arg);
|
|
res = 1;
|
|
} else
|
|
res = rpmcliShowMatches(qva, ts);
|
|
break;
|
|
|
|
case RPMQV_TRIGGEREDBY:
|
|
qva->qva_mi = rpmtsInitIterator(ts, RPMTAG_TRIGGERNAME, arg, 0);
|
|
if (qva->qva_mi == NULL) {
|
|
rpmlog(RPMLOG_NOTICE, _("no package triggers %s\n"), arg);
|
|
res = 1;
|
|
} else
|
|
res = rpmcliShowMatches(qva, ts);
|
|
break;
|
|
|
|
case RPMQV_PKGID:
|
|
{ unsigned char MD5[16];
|
|
unsigned char * t;
|
|
|
|
for (i = 0, s = arg; *s && isxdigit(*s); s++, i++)
|
|
{};
|
|
if (i != 32) {
|
|
rpmlog(RPMLOG_NOTICE, _("malformed %s: %s\n"), "pkgid", arg);
|
|
return 1;
|
|
}
|
|
|
|
MD5[0] = '\0';
|
|
for (i = 0, t = MD5, s = arg; i < 16; i++, t++, s += 2)
|
|
*t = (rnibble(s[0]) << 4) | rnibble(s[1]);
|
|
|
|
qva->qva_mi = rpmtsInitIterator(ts, RPMTAG_SIGMD5, MD5, sizeof(MD5));
|
|
if (qva->qva_mi == NULL) {
|
|
rpmlog(RPMLOG_NOTICE, _("no package matches %s: %s\n"),
|
|
"pkgid", arg);
|
|
res = 1;
|
|
} else
|
|
res = rpmcliShowMatches(qva, ts);
|
|
} break;
|
|
|
|
case RPMQV_HDRID:
|
|
for (i = 0, s = arg; *s && isxdigit(*s); s++, i++)
|
|
{};
|
|
if (i != 40) {
|
|
rpmlog(RPMLOG_NOTICE, _("malformed %s: %s\n"), "hdrid", arg);
|
|
return 1;
|
|
}
|
|
|
|
qva->qva_mi = rpmtsInitIterator(ts, RPMTAG_SHA1HEADER, arg, 0);
|
|
if (qva->qva_mi == NULL) {
|
|
rpmlog(RPMLOG_NOTICE, _("no package matches %s: %s\n"),
|
|
"hdrid", arg);
|
|
res = 1;
|
|
} else
|
|
res = rpmcliShowMatches(qva, ts);
|
|
break;
|
|
|
|
case RPMQV_FILEID:
|
|
{ unsigned char MD5[16];
|
|
unsigned char * t;
|
|
|
|
for (i = 0, s = arg; *s && isxdigit(*s); s++, i++)
|
|
{};
|
|
if (i != 32) {
|
|
rpmlog(RPMLOG_ERR, _("malformed %s: %s\n"), "fileid", arg);
|
|
return 1;
|
|
}
|
|
|
|
MD5[0] = '\0';
|
|
for (i = 0, t = MD5, s = arg; i < 16; i++, t++, s += 2)
|
|
*t = (rnibble(s[0]) << 4) | rnibble(s[1]);
|
|
|
|
qva->qva_mi = rpmtsInitIterator(ts, RPMTAG_FILEMD5S, MD5, sizeof(MD5));
|
|
if (qva->qva_mi == NULL) {
|
|
rpmlog(RPMLOG_NOTICE, _("no package matches %s: %s\n"),
|
|
"fileid", arg);
|
|
res = 1;
|
|
} else
|
|
res = rpmcliShowMatches(qva, ts);
|
|
} break;
|
|
|
|
case RPMQV_TID:
|
|
{ int mybase = 10;
|
|
const char * myarg = arg;
|
|
char * end = NULL;
|
|
unsigned long iid;
|
|
|
|
/* XXX should be in strtoul */
|
|
if (*myarg == '0') {
|
|
myarg++;
|
|
mybase = 8;
|
|
if (*myarg == 'x') {
|
|
myarg++;
|
|
mybase = 16;
|
|
}
|
|
}
|
|
iid = strtoul(myarg, &end, mybase);
|
|
if ((*end) || (end == arg) || (iid == ULONG_MAX)) {
|
|
rpmlog(RPMLOG_ERR, _("malformed %s: %s\n"), "tid", arg);
|
|
return 1;
|
|
}
|
|
qva->qva_mi = rpmtsInitIterator(ts, RPMTAG_INSTALLTID, &iid, sizeof(iid));
|
|
if (qva->qva_mi == NULL) {
|
|
rpmlog(RPMLOG_NOTICE, _("no package matches %s: %s\n"),
|
|
"tid", arg);
|
|
res = 1;
|
|
} else
|
|
res = rpmcliShowMatches(qva, ts);
|
|
} break;
|
|
|
|
case RPMQV_WHATREQUIRES:
|
|
qva->qva_mi = rpmtsInitIterator(ts, RPMTAG_REQUIRENAME, arg, 0);
|
|
if (qva->qva_mi == NULL) {
|
|
rpmlog(RPMLOG_NOTICE, _("no package requires %s\n"), arg);
|
|
res = 1;
|
|
} else
|
|
res = rpmcliShowMatches(qva, ts);
|
|
break;
|
|
|
|
case RPMQV_WHATPROVIDES:
|
|
if (arg[0] != '/') {
|
|
provides_checked = 1;
|
|
qva->qva_mi = rpmtsInitIterator(ts, RPMTAG_PROVIDENAME, arg, 0);
|
|
if (qva->qva_mi == NULL) {
|
|
rpmlog(RPMLOG_NOTICE, _("no package provides %s\n"), arg);
|
|
res = 1;
|
|
} else
|
|
res = rpmcliShowMatches(qva, ts);
|
|
break;
|
|
}
|
|
case RPMQV_PATH:
|
|
{ char * fn;
|
|
|
|
for (s = arg; *s != '\0'; s++)
|
|
if (!(*s == '.' || *s == '/'))
|
|
break;
|
|
|
|
if (*s == '\0') {
|
|
char fnbuf[PATH_MAX];
|
|
fn = realpath(arg, fnbuf);
|
|
fn = xstrdup( (fn != NULL ? fn : arg) );
|
|
} else if (*arg != '/') {
|
|
char *curDir = rpmGetCwd();
|
|
fn = (char *) rpmGetPath(curDir, "/", arg, NULL);
|
|
curDir = _free(curDir);
|
|
} else
|
|
fn = xstrdup(arg);
|
|
(void) rpmCleanPath(fn);
|
|
|
|
qva->qva_mi = rpmtsInitIterator(ts, RPMTAG_BASENAMES, fn, 0);
|
|
if (qva->qva_mi == NULL && !provides_checked)
|
|
qva->qva_mi = rpmtsInitIterator(ts, RPMTAG_PROVIDENAME, fn, 0);
|
|
|
|
if (qva->qva_mi == NULL) {
|
|
struct stat sb;
|
|
if (lstat(fn, &sb) != 0)
|
|
rpmlog(RPMLOG_ERR, _("file %s: %s\n"), fn, strerror(errno));
|
|
else
|
|
rpmlog(RPMLOG_NOTICE,
|
|
_("file %s is not owned by any package\n"), fn);
|
|
res = 1;
|
|
} else
|
|
res = rpmcliShowMatches(qva, ts);
|
|
|
|
fn = _free(fn);
|
|
} break;
|
|
|
|
case RPMQV_DBOFFSET:
|
|
{ int mybase = 10;
|
|
const char * myarg = arg;
|
|
char * end = NULL;
|
|
unsigned long recOffset;
|
|
|
|
/* XXX should be in strtoul */
|
|
if (*myarg == '0') {
|
|
myarg++;
|
|
mybase = 8;
|
|
if (*myarg == 'x') {
|
|
myarg++;
|
|
mybase = 16;
|
|
}
|
|
}
|
|
recOffset = strtoul(myarg, &end, mybase);
|
|
if ((*end) || (end == arg) || (recOffset == ULONG_MAX)) {
|
|
rpmlog(RPMLOG_NOTICE, _("invalid package number: %s\n"), arg);
|
|
return 1;
|
|
}
|
|
rpmlog(RPMLOG_DEBUG, "package record number: %lu\n", recOffset);
|
|
/* RPMDBI_PACKAGES */
|
|
qva->qva_mi = rpmtsInitIterator(ts, RPMDBI_PACKAGES, &recOffset, sizeof(recOffset));
|
|
if (qva->qva_mi == NULL) {
|
|
rpmlog(RPMLOG_NOTICE,
|
|
_("record %lu could not be read\n"), recOffset);
|
|
res = 1;
|
|
} else
|
|
res = rpmcliShowMatches(qva, ts);
|
|
} break;
|
|
|
|
case RPMQV_PACKAGE:
|
|
{
|
|
int matches = 0;
|
|
rpmdbMatchIterator mi;
|
|
mi = rpmtsInitIterator(ts, RPMDBI_LABEL, arg, 0);
|
|
while (rpmdbNextIterator(mi) != NULL) {
|
|
matches++;
|
|
}
|
|
rpmdbFreeIterator(mi);
|
|
if (! matches) {
|
|
rpmlog(RPMLOG_NOTICE, _("package %s is not installed\n"), arg);
|
|
res = 1;
|
|
} else {
|
|
qva->qva_mi = rpmtsInitIterator(ts, RPMDBI_LABEL, arg, 0);
|
|
res = rpmcliShowMatches(qva, ts);
|
|
}
|
|
break;
|
|
}
|
|
|
|
}
|
|
|
|
return res;
|
|
}
|
|
|
|
int rpmcliArgIter(rpmts ts, QVA_t qva, ARGV_const_t argv)
|
|
{
|
|
rpmRC rpmrc = RPMRC_NOTFOUND;
|
|
int ec = 0;
|
|
|
|
switch (qva->qva_source) {
|
|
case RPMQV_ALL:
|
|
qva->qva_gi = rpmgiNew(ts, RPMDBI_PACKAGES, NULL, 0);
|
|
qva->qva_rc = rpmgiSetArgs(qva->qva_gi, argv, ftsOpts, RPMGI_NONE);
|
|
|
|
if (qva->qva_gi != NULL && (rpmgiGetFlags(qva->qva_gi) & RPMGI_TSADD)) /* Load the ts with headers. */
|
|
while ((rpmrc = rpmgiNext(qva->qva_gi)) == RPMRC_OK)
|
|
{};
|
|
if (rpmrc != RPMRC_NOTFOUND)
|
|
return 1; /* XXX should be no. of failures. */
|
|
|
|
/* FIX: argv can be NULL, cast to pass argv array */
|
|
ec = rpmQueryVerify(qva, ts, (const char *) argv);
|
|
rpmtsEmpty(ts);
|
|
break;
|
|
case RPMQV_RPM:
|
|
qva->qva_gi = rpmgiNew(ts, RPMDBI_ARGLIST, NULL, 0);
|
|
qva->qva_rc = rpmgiSetArgs(qva->qva_gi, argv, ftsOpts, giFlags);
|
|
|
|
if (qva->qva_gi != NULL && (rpmgiGetFlags(qva->qva_gi) & RPMGI_TSADD)) /* Load the ts with headers. */
|
|
while ((rpmrc = rpmgiNext(qva->qva_gi)) == RPMRC_OK)
|
|
{};
|
|
if (rpmrc != RPMRC_NOTFOUND)
|
|
return 1; /* XXX should be no. of failures. */
|
|
|
|
/* FIX: argv can be NULL, cast to pass argv array */
|
|
ec = rpmQueryVerify(qva, ts, NULL);
|
|
rpmtsEmpty(ts);
|
|
break;
|
|
case RPMQV_HDLIST:
|
|
qva->qva_gi = rpmgiNew(ts, RPMDBI_HDLIST, NULL, 0);
|
|
qva->qva_rc = rpmgiSetArgs(qva->qva_gi, argv, ftsOpts, giFlags);
|
|
|
|
if (qva->qva_gi != NULL && (rpmgiGetFlags(qva->qva_gi) & RPMGI_TSADD)) /* Load the ts with headers. */
|
|
while ((rpmrc = rpmgiNext(qva->qva_gi)) == RPMRC_OK)
|
|
{};
|
|
if (rpmrc != RPMRC_NOTFOUND)
|
|
return 1; /* XXX should be no. of failures. */
|
|
|
|
/* FIX: argv can be NULL, cast to pass argv array */
|
|
ec = rpmQueryVerify(qva, ts, NULL);
|
|
rpmtsEmpty(ts);
|
|
break;
|
|
case RPMQV_FTSWALK:
|
|
if (ftsOpts == 0)
|
|
ftsOpts = (RPMGI_COMFOLLOW | RPMGI_LOGICAL | RPMGI_NOSTAT);
|
|
qva->qva_gi = rpmgiNew(ts, RPMDBI_FTSWALK, NULL, 0);
|
|
qva->qva_rc = rpmgiSetArgs(qva->qva_gi, argv, ftsOpts, giFlags);
|
|
|
|
if (qva->qva_gi != NULL && (rpmgiGetFlags(qva->qva_gi) & RPMGI_TSADD)) /* Load the ts with headers. */
|
|
while ((rpmrc = rpmgiNext(qva->qva_gi)) == RPMRC_OK)
|
|
{};
|
|
if (rpmrc != RPMRC_NOTFOUND)
|
|
return 1; /* XXX should be no. of failures. */
|
|
|
|
/* FIX: argv can be NULL, cast to pass argv array */
|
|
ec = rpmQueryVerify(qva, ts, NULL);
|
|
rpmtsEmpty(ts);
|
|
break;
|
|
default:
|
|
qva->qva_gi = rpmgiNew(ts, RPMDBI_ARGLIST, NULL, 0);
|
|
qva->qva_rc = rpmgiSetArgs(qva->qva_gi, argv, ftsOpts,
|
|
(giFlags | (RPMGI_NOGLOB|RPMGI_NOHEADER)));
|
|
while (rpmgiNext(qva->qva_gi) == RPMRC_OK) {
|
|
ec += rpmQueryVerify(qva, ts, rpmgiHdrPath(qva->qva_gi));
|
|
rpmtsEmpty(ts);
|
|
}
|
|
break;
|
|
}
|
|
|
|
qva->qva_gi = rpmgiFree(qva->qva_gi);
|
|
|
|
return ec;
|
|
}
|
|
|
|
int rpmcliQuery(rpmts ts, QVA_t qva, char * const * argv)
|
|
{
|
|
rpmVSFlags vsflags, ovsflags;
|
|
int ec = 0;
|
|
|
|
if (qva->qva_showPackage == NULL)
|
|
qva->qva_showPackage = showQueryPackage;
|
|
|
|
/* If --queryformat unspecified, then set default now. */
|
|
if (!(qva->qva_flags & _QUERY_FOR_BITS) && qva->qva_queryFormat == NULL) {
|
|
char * fmt = rpmExpand("%{?_query_all_fmt}\n", NULL);
|
|
if (fmt == NULL || strlen(fmt) <= 1) {
|
|
fmt = _free(fmt);
|
|
fmt = xstrdup("%{name}-%{version}-%{release}.%{arch}\n");
|
|
}
|
|
qva->qva_queryFormat = fmt;
|
|
}
|
|
|
|
vsflags = rpmExpandNumeric("%{?_vsflags_query}");
|
|
if (qva->qva_flags & VERIFY_DIGEST)
|
|
vsflags |= _RPMVSF_NODIGESTS;
|
|
if (qva->qva_flags & VERIFY_SIGNATURE)
|
|
vsflags |= _RPMVSF_NOSIGNATURES;
|
|
if (qva->qva_flags & VERIFY_HDRCHK)
|
|
vsflags |= RPMVSF_NOHDRCHK;
|
|
|
|
ovsflags = rpmtsSetVSFlags(ts, vsflags);
|
|
ec = rpmcliArgIter(ts, qva, argv);
|
|
vsflags = rpmtsSetVSFlags(ts, ovsflags);
|
|
|
|
if (qva->qva_showPackage == showQueryPackage)
|
|
qva->qva_showPackage = NULL;
|
|
|
|
return ec;
|
|
}
|